3 <script src="../../lib/OpenLayers.js"></script>
4 <script type="text/javascript">
5 function test_initialize(t) {
7 var control = new OpenLayers.Control();
8 control.id = Math.random();
10 var callbacks = {foo: "bar"};
11 var options = {bar: "foo"};
13 var oldInit = OpenLayers.Handler.prototype.initialize;
15 OpenLayers.Handler.prototype.initialize = function(con, call, opt) {
16 t.eq(con.id, control.id,
17 "constructor calls parent with the correct control");
19 "constructor calls parent with the correct callbacks");
21 "constructor calls parent with the correct options");
23 var handler = new OpenLayers.Handler.Feature(control, layer,
26 t.eq(handler.layer, "boo",
27 "layer property properly set");
29 OpenLayers.Handler.prototype.initialize = oldInit;
32 function test_activate(t) {
34 var map = new OpenLayers.Map('map');
35 var control = new OpenLayers.Control();
36 map.addControl(control);
37 var layer = new OpenLayers.Layer();
39 var handler = new OpenLayers.Handler.Feature(control, layer);
40 handler.active = true;
41 var activated = handler.activate();
43 "activate returns false if the handler was already active");
44 handler.active = false;
46 var zIndex = layer.div.style.zIndex;
47 activated = handler.activate();
49 "activate returns true if the handler was not already active");
50 t.eq(parseInt(layer.div.style.zIndex),
51 map.Z_INDEX_BASE['Feature'],
52 "layer z-index properly adjusted");
55 function test_events(t) {
58 var map = new OpenLayers.Map('map');
59 var control = new OpenLayers.Control();
60 map.addControl(control);
61 var layer = new OpenLayers.Layer();
63 var handler = new OpenLayers.Handler.Feature(control, layer);
65 // list below events that should be handled (events) and those
66 // that should not be handled (nonevents) by the handler
67 var events = ["mousedown", "mouseup", "mousemove", "click", "dblclick"];
68 var nonevents = ["mouseout", "resize", "focus", "blur"];
69 map.events.registerPriority = function(type, obj, func) {
71 // Don't listen for setEvent handlers (#902)
72 if (typeof output == "string") {
73 t.eq(OpenLayers.Util.indexOf(nonevents, type), -1,
74 "registered method is not one of the events " +
75 "that should not be handled");
76 t.ok(OpenLayers.Util.indexOf(events, type) > -1,
77 "activate calls registerPriority with browser event: " + type);
78 t.eq(typeof func, "function",
79 "activate calls registerPriority with a function");
81 "activate calls registerPriority with the correct method:"+type);
82 t.eq(obj["CLASS_NAME"], "OpenLayers.Handler.Feature",
83 "activate calls registerPriority with the handler");
87 // set browser event like properties on the handler
88 for(var i=0; i<events.length; ++i) {
91 function setMethod(key) {
92 handler[key] = function() {return key};
95 var activated = handler.activate();
99 function test_geometrytype_limit(t) {
101 var map = new OpenLayers.Map('map');
102 var control = new OpenLayers.Control();
103 map.addControl(control);
104 var layer = new OpenLayers.Layer();
105 var feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(0,0));
106 feature.layer = layer;
107 layer.getFeatureFromEvent = function(evt) { return feature };
109 var handler = new OpenLayers.Handler.Feature(control, layer, {}, {'geometryTypes':['OpenLayers.Geometry.Point']});
111 handler.callback = function(type,featurelist) {
112 t.eq(featurelist[0].id, feature.id, "Correct feature called back on");
114 handler.handle({type: "click"});
115 handler.feature = null;
116 handler.lastFeature = null;
117 handler.callback = function(type,featurelist) {
118 t.fail("Shouldn't have called back on " + featurelist[0].geometry);
120 feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString(0,0));
121 feature.layer = layer;
122 handler.handle("click", {});
125 function test_callbacks(t) {
128 var map = new OpenLayers.Map('map', {controls: []});
129 var control = new OpenLayers.Control();
130 map.addControl(control);
131 var layer = new OpenLayers.Layer();
135 var newFeature, lastFeature;
136 var evtPx = {xy: new OpenLayers.Pixel(Math.random(), Math.random())};
138 // define a callback factory function
139 function getCallback(evt, feature) {
141 t.ok(f == feature, evt + " callback called with proper feature");
145 // override the layer's getFeatureFromEvent func so that it always
146 // returns newFeature
147 layer.getFeatureFromEvent = function(evt) { return newFeature; };
149 var handler = new OpenLayers.Handler.Feature(control, layer, callbacks);
152 // test click in new feature
153 // only 'click' callback should be called
154 handler.feature = null;
156 newFeature = new OpenLayers.Feature.Vector();
157 newFeature.layer = layer;
158 callbacks['click'] = getCallback('click', newFeature);
159 callbacks['clickout'] = getCallback('clickout', lastFeature);
160 evtPx.type = "click";
161 map.events.triggerEvent('click', evtPx);
163 // test click in new feature and out of last feature
164 // both 'click' and 'clickout' callbacks should be called
165 lastFeature = newFeature;
166 newFeature = new OpenLayers.Feature.Vector();
167 newFeature.layer = layer;
168 callbacks['click'] = getCallback('click', newFeature);
169 callbacks['clickout'] = getCallback('clickout', lastFeature);
170 evtPx.type = "click";
171 map.events.triggerEvent('click', evtPx);
173 // test click out of last feature
174 // only 'clickout' callback should be called
175 lastFeature = newFeature;
177 callbacks['click'] = getCallback('click', newFeature);
178 callbacks['clickout'] = getCallback('clickout', lastFeature);
179 evtPx.type = "click";
180 map.events.triggerEvent('click', evtPx);
182 layer.getFeatureFromEvent = function(evt) { t.fail("mousemove called getFeatureFromEvent without any mousemove callbacks"); };
183 evtPx.type = "mousemove";
184 map.events.triggerEvent('mousemove', evtPx);
185 layer.getFeatureFromEvent = function(evt) { return newFeature; };
187 // test over a new feature
188 // only 'over' callback should be called
189 handler.feature = null;
191 newFeature = new OpenLayers.Feature.Vector();
192 newFeature.layer = layer;
193 callbacks['over'] = getCallback('over', newFeature);
194 callbacks['out'] = getCallback('out', lastFeature);
195 evtPx.type = "mousemove";
196 map.events.triggerEvent('mousemove', evtPx);
198 // test over a new feature and out of last feature
199 // both 'over' and 'out' callbacks should be called
200 lastFeature = newFeature;
201 newFeature = new OpenLayers.Feature.Vector();
202 newFeature.layer = layer;
203 callbacks['over'] = getCallback('over', newFeature);
204 callbacks['out'] = getCallback('out', lastFeature);
205 evtPx.type = "mousemove";
206 map.events.triggerEvent('mousemove', evtPx);
208 // test out of last feature
209 // only 'out' callback should be called
210 lastFeature = newFeature;
212 callbacks['over'] = getCallback('over', newFeature);
213 callbacks['out'] = getCallback('out', lastFeature);
214 evtPx.type = "mousemove";
215 map.events.triggerEvent('mousemove', evtPx);
217 // test dblclick on a feature
218 // 'dblclick' callback should be called
219 handler.feature = null;
221 newFeature = new OpenLayers.Feature.Vector();
222 newFeature.layer = layer;
223 callbacks['dblclick'] = getCallback('dblclick', newFeature);
224 evtPx.type = "dblclick";
225 map.events.triggerEvent('dblclick', evtPx);
228 function test_deactivate(t) {
230 var map = new OpenLayers.Map('map');
231 var control = new OpenLayers.Control();
232 map.addControl(control);
233 var layer = new OpenLayers.Layer();
235 var layerIndex = parseInt(layer.div.style.zIndex);
237 var handler = new OpenLayers.Handler.Feature(control, layer);
238 handler.active = false;
239 var deactivated = handler.deactivate();
241 "deactivate returns false if the handler was not already active");
243 handler.active = true;
245 deactivated = handler.deactivate();
247 "deactivate returns true if the handler was active already");
248 t.eq(parseInt(layer.div.style.zIndex),
250 "deactivate sets the layer z-index back");
253 function test_stopHandled(t) {
255 var map = new OpenLayers.Map('map');
256 var control = new OpenLayers.Control();
257 map.addControl(control);
258 var layer = new OpenLayers.Layer();
260 var handler = new OpenLayers.Handler.Feature(control, layer);
262 handler.handle = function(evt) { return /* handled */ true; };
263 var evtPx = {xy: new OpenLayers.Pixel(Math.random(), Math.random())};
264 map.events.register("click", map, function(e) {
265 t.ok(!handler.stopClick, "clicks propagate with stopClick set to false" );
267 map.events.register("mousedown", map, function(e) {
268 t.ok(!handler.stopDown, "mousedown propagate with stopDown set to false" );
270 map.events.register("mouseup", map, function(e) {
271 t.ok(!handler.stopUp, "mouseup propagate with stopUp set to false" );
275 map.events.triggerEvent('click', evtPx);
277 map.events.triggerEvent('mousedown', evtPx);
279 map.events.triggerEvent('mousedown', evtPx);
282 handler.stopClick = false;
283 map.events.triggerEvent('click', evtPx);
285 handler.stopDown = false;
286 map.events.triggerEvent('mousedown', evtPx);
288 handler.stopUp = false;
289 map.events.triggerEvent('mouseup', evtPx);
294 function test_destroyed_feature(t) {
298 var map = new OpenLayers.Map('map');
299 var control = new OpenLayers.Control();
300 map.addControl(control);
301 var layer = new OpenLayers.Layer();
302 layer.removeFeatures = function() {};
304 var handler = new OpenLayers.Handler.Feature(control, layer);
305 var feature, count, lastType, lastHandled;
306 handler.callback = function(type, features) {
309 lastHandled = features;
313 * Test that a destroyed feature doesn't get sent to the "click" callback
317 feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(0,0));
318 feature.layer = layer;
319 // mock click on a feature
320 layer.getFeatureFromEvent = function(evt) {return feature};
321 handler.handle({type: "click"});
322 // confirm that feature was handled
323 t.eq(count, 1, "[click] callback called once");
324 t.eq(lastType, "click", "[click] correct callback type");
325 t.eq(lastHandled[0].id, feature.id, "[click] correct feature sent to callback");
327 // now destroy the feature and confirm that the callback is not called again
329 handler.handle({type: "click"});
331 t.ok(true, "[click] callback not called after destroy");
333 t.fail("[click] callback called after destroy: " + lastType);
337 * Test that a destroyed feature doesn't get sent to the "clickout" callback
340 handler.deactivate();
342 feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(0,0));
343 feature.layer = layer;
345 // mock a click on a feature
346 layer.getFeatureFromEvent = function(evt) {return feature};
347 handler.handle({type: "click"});
348 // confirm that callback got feature
349 t.eq(count, 1, "[clickout] callback called once on in");
350 t.eq(lastType, "click", "[clickout] click callback called on in");
351 t.eq(lastHandled.length, 1, "[clickout] callback called with one feature");
352 t.eq(lastHandled[0].id, feature.id, "[clickout] callback called with correct feature");
354 // now mock a click off a destroyed feature
356 layer.getFeatureFromEvent = function(evt) {return null};
357 handler.handle({type: "click"});
358 // confirm that callback does not get called
360 t.ok(true, "[clickout] callback not called when clicking out of a destroyed feature");
362 t.fail("[clickout] callback called when clicking out of a destroyed feature: " + lastType);
366 * Test that a destroyed feature doesn't get sent to the "over" callback
369 handler.deactivate();
371 feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(0,0));
372 feature.layer = layer;
373 // mock mousemove over a feature
374 layer.getFeatureFromEvent = function(evt) {return feature};
375 handler.handle({type: "mousemove"});
376 // confirm that feature was handled
377 t.eq(count, 1, "[over] callback called once");
378 t.eq(lastType, "over", "[over] correct callback type");
379 t.eq(lastHandled[0].id, feature.id, "[over] correct feature sent to callback");
381 // now destroy the feature and confirm that the callback is not called again
383 handler.handle({type: "mousemove"});
385 t.ok(true, "[over] callback not called after destroy");
387 t.fail("[over] callback called after destroy: " + lastType);
391 * Test that a destroyed feature doesn't get sent to the "out" callback
394 handler.deactivate();
396 feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(0,0));
397 feature.layer = layer;
399 // mock a mousemove over a feature
400 layer.getFeatureFromEvent = function(evt) {return feature};
401 handler.handle({type: "mousemove"});
402 // confirm that callback got feature
403 t.eq(count, 1, "[out] callback called once on over");
404 t.eq(lastType, "over", "[out] click callback called on over");
405 t.eq(lastHandled.length, 1, "[out] callback called with one feature");
406 t.eq(lastHandled[0].id, feature.id, "[out] callback called with correct feature");
408 // now mock a click off a destroyed feature
410 layer.getFeatureFromEvent = function(evt) {return null};
411 handler.handle({type: "mousemove"});
412 // confirm that callback does not get called
414 t.ok(true, "[out] callback not called when moving out of a destroyed feature");
416 t.fail("[out] callback called when moving out of a destroyed feature: " + lastType);
422 function test_click_tolerance(t) {
425 var map, control, layer, feature, evtPx;
426 var clicks, callbacks, handler;
428 map = new OpenLayers.Map('map', {controls: []});
429 control = new OpenLayers.Control();
430 map.addControl(control);
431 layer = new OpenLayers.Layer();
434 feature = new OpenLayers.Feature.Vector();
435 feature.layer = layer;
438 xy: new OpenLayers.Pixel(Math.random(), Math.random()),
442 // override the layer's getFeatureFromEvent func so that it always
443 // returns newFeature
444 layer.getFeatureFromEvent = function(evt) { return feature; };
452 handler = new OpenLayers.Handler.Feature(
453 control, layer, callbacks, {clickTolerance: 4});
455 handler.down = {x: 0, y: 0};
457 // distance between down and up is 1, which is
458 // lower than clickTolerance so "click" should trigger
459 handler.up = {x: 1, y: 0};
461 map.events.triggerEvent("click", evtPx);
462 t.eq(clicks, 1, "click callback triggers when tolerance is not reached (lower than)");
464 // distance between down and up is 4, which is
465 // equal to clickTolerance so "click" should trigger
466 handler.up = {x: 0, y: 4};
468 map.events.triggerEvent("click", evtPx);
469 t.eq(clicks, 1, "click callback triggers when tolerance is not reached (equal to)");
471 // distance between down and up is 5, which is
472 // greater than clickTolerance so "click" should not trigger
473 handler.up = {x: 5, y: 0};
475 map.events.triggerEvent("click", evtPx);
476 t.eq(clicks, 0, "click callback does not trigger when tolerance is reached");
482 <div id="map" style="width: 300px; height: 150px;"/>