]> dev.renevier.net Git - syp.git/blob - openlayers/tests/Handler/Feature.html
fixes notices
[syp.git] / openlayers / tests / Handler / Feature.html
1 <html>
2 <head>
3   <script src="../../lib/OpenLayers.js"></script>
4   <script type="text/javascript">
5     function test_initialize(t) {
6         t.plan(4);
7         var control = new OpenLayers.Control();
8         control.id = Math.random();
9         var layer = "boo";
10         var callbacks = {foo: "bar"};
11         var options = {bar: "foo"};
12         
13         var oldInit = OpenLayers.Handler.prototype.initialize;
14         
15         OpenLayers.Handler.prototype.initialize = function(con, call, opt) {
16             t.eq(con.id, control.id,
17                  "constructor calls parent with the correct control");
18             t.eq(call, callbacks,
19                  "constructor calls parent with the correct callbacks");
20             t.eq(opt, options,
21                  "constructor calls parent with the correct options");
22         }
23         var handler = new OpenLayers.Handler.Feature(control, layer,
24                                                      callbacks, options);
25         
26         t.eq(handler.layer, "boo",
27              "layer property properly set");
28
29         OpenLayers.Handler.prototype.initialize = oldInit;
30     }
31
32     function test_activate(t) {
33         t.plan(3);
34         var map = new OpenLayers.Map('map');
35         var control = new OpenLayers.Control();
36         map.addControl(control);
37         var layer = new OpenLayers.Layer();
38         map.addLayer(layer);
39         var handler = new OpenLayers.Handler.Feature(control, layer);
40         handler.active = true;
41         var activated = handler.activate();
42         t.ok(!activated,
43              "activate returns false if the handler was already active");
44         handler.active = false;
45         
46         var zIndex = layer.div.style.zIndex;
47         activated = handler.activate();
48         t.ok(activated,
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");
53         
54     }
55     function test_events(t) {
56         t.plan(25);
57         
58         var map = new OpenLayers.Map('map');
59         var control = new OpenLayers.Control();
60         map.addControl(control);
61         var layer = new OpenLayers.Layer();
62         map.addLayer(layer);
63         var handler = new OpenLayers.Handler.Feature(control, layer);
64  
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) {
70             var output = 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");
80                 t.eq(func(), type,
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");
84             }     
85         }
86         
87         // set browser event like properties on the handler
88         for(var i=0; i<events.length; ++i) {
89             setMethod(events[i]);
90         }
91         function setMethod(key) {
92             handler[key] = function() {return key};
93         }
94  
95         var activated = handler.activate();
96  
97     }
98  
99     function test_geometrytype_limit(t) {
100         t.plan(1);
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 };
108         map.addLayer(layer);
109         var handler = new OpenLayers.Handler.Feature(control, layer, {}, {'geometryTypes':['OpenLayers.Geometry.Point']});
110         handler.activate();
111         handler.callback = function(type,featurelist) {
112             t.eq(featurelist[0].id, feature.id, "Correct feature called back on");
113         }
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);
119         }    
120         feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString(0,0));
121         feature.layer = layer;
122         handler.handle("click", {}); 
123     }
124
125     function test_callbacks(t) {
126         t.plan(9);
127         
128         var map = new OpenLayers.Map('map', {controls: []});
129         var control = new OpenLayers.Control();
130         map.addControl(control);
131         var layer = new OpenLayers.Layer();
132         map.addLayer(layer);
133  
134         var callbacks = {};
135         var newFeature, lastFeature;
136         var evtPx = {xy: new OpenLayers.Pixel(Math.random(), Math.random())};
137  
138         // define a callback factory function
139         function getCallback(evt, feature) {
140             return function(f) {
141                 t.ok(f == feature, evt + " callback called with proper feature");
142             };
143         }
144  
145         // override the layer's getFeatureFromEvent func so that it always
146         // returns newFeature
147         layer.getFeatureFromEvent = function(evt) { return newFeature; };
148  
149         var handler = new OpenLayers.Handler.Feature(control, layer, callbacks);
150         handler.activate();
151
152         // test click in new feature
153         // only 'click' callback should be called
154         handler.feature = null;
155         lastFeature = 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);
162
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);
172
173         // test click out of last feature
174         // only 'clickout' callback should be called
175         lastFeature = newFeature;
176         newFeature = null;
177         callbacks['click'] = getCallback('click', newFeature);
178         callbacks['clickout'] = getCallback('clickout', lastFeature);
179         evtPx.type = "click";
180         map.events.triggerEvent('click', evtPx);
181
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; };
186         
187         // test over a new feature
188         // only 'over' callback should be called
189         handler.feature = null;
190         lastFeature = 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);
197
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);
207
208         // test out of last feature
209         // only 'out' callback should be called
210         lastFeature = newFeature;
211         newFeature = null;
212         callbacks['over'] = getCallback('over', newFeature);
213         callbacks['out'] = getCallback('out', lastFeature);
214         evtPx.type = "mousemove";
215         map.events.triggerEvent('mousemove', evtPx);
216
217         // test dblclick on a feature
218         // 'dblclick' callback should be called
219         handler.feature = null;
220         lastFeature = 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);
226     }
227
228     function test_deactivate(t) {
229         t.plan(3);
230         var map = new OpenLayers.Map('map');
231         var control = new OpenLayers.Control();
232         map.addControl(control);
233         var layer = new OpenLayers.Layer();
234         map.addLayer(layer);
235         var layerIndex = parseInt(layer.div.style.zIndex);
236         
237         var handler = new OpenLayers.Handler.Feature(control, layer);
238         handler.active = false;
239         var deactivated = handler.deactivate();
240         t.ok(!deactivated,
241              "deactivate returns false if the handler was not already active");
242         
243         handler.active = true;
244
245         deactivated = handler.deactivate();
246         t.ok(deactivated,
247              "deactivate returns true if the handler was active already");
248         t.eq(parseInt(layer.div.style.zIndex),
249              layerIndex,
250              "deactivate sets the layer z-index back");
251     }
252
253     function test_stopHandled(t) {
254         t.plan(3);
255         var map = new OpenLayers.Map('map');
256         var control = new OpenLayers.Control();
257         map.addControl(control);
258         var layer = new OpenLayers.Layer();
259         map.addLayer(layer);
260         var handler = new OpenLayers.Handler.Feature(control, layer);
261         handler.activate();
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" );
266         });
267         map.events.register("mousedown", map, function(e) {
268             t.ok(!handler.stopDown, "mousedown propagate with stopDown set to false" );
269         });
270         map.events.register("mouseup", map, function(e) {
271             t.ok(!handler.stopUp, "mouseup propagate with stopUp set to false" );
272         });
273
274         // 0 test
275         map.events.triggerEvent('click', evtPx);
276         // 0 test
277         map.events.triggerEvent('mousedown', evtPx);
278         // 0 test
279         map.events.triggerEvent('mousedown', evtPx);
280
281         // 1 test
282         handler.stopClick = false;
283         map.events.triggerEvent('click', evtPx);
284         // 1 test
285         handler.stopDown = false;
286         map.events.triggerEvent('mousedown', evtPx);
287         // 1 test
288         handler.stopUp = false;
289         map.events.triggerEvent('mouseup', evtPx);
290         
291         // 3 tests total
292     }
293
294     function test_destroyed_feature(t) {
295         t.plan(18);
296         
297         // setup
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() {};
303         map.addLayer(layer);
304         var handler = new OpenLayers.Handler.Feature(control, layer);
305         var feature, count, lastType, lastHandled;
306         handler.callback = function(type, features) {
307             ++count;
308             lastType = type;
309             lastHandled = features;
310         }
311
312         /**
313          * Test that a destroyed feature doesn't get sent to the "click" callback
314          */
315         count = 0;
316         handler.activate();
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");
326         
327         // now destroy the feature and confirm that the callback is not called again
328         feature.destroy();
329         handler.handle({type: "click"});
330         if(count === 1) {
331             t.ok(true, "[click] callback not called after destroy");
332         } else {
333             t.fail("[click] callback called after destroy: " + lastType);
334         }
335         
336         /**
337          * Test that a destroyed feature doesn't get sent to the "clickout" callback
338          */
339         count = 0;
340         handler.deactivate();
341         handler.activate();
342         feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(0,0));
343         feature.layer = layer;
344
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");
353
354         // now mock a click off a destroyed feature
355         feature.destroy();
356         layer.getFeatureFromEvent = function(evt) {return null};
357         handler.handle({type: "click"});
358         // confirm that callback does not get called
359         if(count === 1) {
360             t.ok(true, "[clickout] callback not called when clicking out of a destroyed feature");
361         } else {
362             t.fail("[clickout] callback called when clicking out of a destroyed feature: " + lastType);
363         }
364         
365         /**
366          * Test that a destroyed feature doesn't get sent to the "over" callback
367          */
368         count = 0;
369         handler.deactivate();
370         handler.activate();
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");
380         
381         // now destroy the feature and confirm that the callback is not called again
382         feature.destroy();
383         handler.handle({type: "mousemove"});
384         if(count === 1) {
385             t.ok(true, "[over] callback not called after destroy");
386         } else {
387             t.fail("[over] callback called after destroy: " + lastType);
388         }
389
390         /**
391          * Test that a destroyed feature doesn't get sent to the "out" callback
392          */
393         count = 0;
394         handler.deactivate();
395         handler.activate();
396         feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(0,0));
397         feature.layer = layer;
398
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");
407
408         // now mock a click off a destroyed feature
409         feature.destroy();
410         layer.getFeatureFromEvent = function(evt) {return null};
411         handler.handle({type: "mousemove"});
412         // confirm that callback does not get called
413         if(count === 1) {
414             t.ok(true, "[out] callback not called when moving out of a destroyed feature");
415         } else {
416             t.fail("[out] callback called when moving out of a destroyed feature: " + lastType);
417         }
418         
419         handler.destroy();
420     }
421
422     function test_click_tolerance(t) {
423         t.plan(3);
424
425         var map, control, layer, feature, evtPx;
426         var clicks, callbacks, handler;
427
428         map = new OpenLayers.Map('map', {controls: []});
429         control = new OpenLayers.Control();
430         map.addControl(control);
431         layer = new OpenLayers.Layer();
432         map.addLayer(layer);
433  
434         feature = new OpenLayers.Feature.Vector();
435         feature.layer = layer;
436
437         evtPx = {
438             xy: new OpenLayers.Pixel(Math.random(), Math.random()),
439             type: "click"
440         };
441  
442         // override the layer's getFeatureFromEvent func so that it always
443         // returns newFeature
444         layer.getFeatureFromEvent = function(evt) { return feature; };
445
446         callbacks = {
447             click: function() {
448                 clicks++;
449             }
450         };
451  
452         handler = new OpenLayers.Handler.Feature(
453             control, layer, callbacks, {clickTolerance: 4});
454         handler.activate();
455         handler.down = {x: 0, y: 0};
456
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};
460         clicks = 0;
461         map.events.triggerEvent("click", evtPx);
462         t.eq(clicks, 1, "click callback triggers when tolerance is not reached (lower than)");
463
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};
467         clicks = 0;
468         map.events.triggerEvent("click", evtPx);
469         t.eq(clicks, 1, "click callback triggers when tolerance is not reached (equal to)");
470
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};
474         clicks = 0;
475         map.events.triggerEvent("click", evtPx);
476         t.eq(clicks, 0, "click callback does not trigger when tolerance is reached");
477     }
478
479   </script>
480 </head>
481 <body>
482     <div id="map" style="width: 300px; height: 150px;"/>
483 </body>
484 </html>