3 <script src="../../lib/OpenLayers.js"></script>
4 <script type="text/javascript">
6 function test_initialize(t) {
9 styleMap: {createSymbolizer: function(){}},
18 var control = new OpenLayers.Control.ModifyFeature(layer, options);
20 t.ok(control.layer == layer,
21 "constructor sets layer correctly");
22 t.eq(control.selectControl.geometryTypes, "bar",
23 "constructor sets options correctly on feature handler");
24 t.eq(control.mode, OpenLayers.Control.ModifyFeature.RESHAPE,
25 "constructor initializes modification mode correctly");
29 function test_destroy(t) {
31 var map = new OpenLayers.Map("map");
32 var layer = new OpenLayers.Layer.Vector();
34 var control = new OpenLayers.Control.ModifyFeature(layer);
35 control.selectControl.destroy = function() {
37 "control.destroy calls destroy on select control");
39 control.dragControl.destroy = function() {
41 "control.destroy calls destroy on feature handler");
47 function test_activate(t) {
49 var map = new OpenLayers.Map("map");
50 var layer = new OpenLayers.Layer.Vector();
52 var control = new OpenLayers.Control.ModifyFeature(layer);
53 map.addControl(control);
54 t.ok(!control.selectControl.active,
55 "select control is not active prior to activating control");
57 t.ok(control.selectControl.active,
58 "select control is active after activating control");
63 function test_initDeleteCodes(t) {
65 var layer = new OpenLayers.Layer.Vector();
66 var control = new OpenLayers.Control.ModifyFeature(layer, {'deleteCodes': 46});
67 t.eq(control.deleteCodes[0], 46, "Delete code properly turned into an array.");
68 var control = new OpenLayers.Control.ModifyFeature(layer);
69 t.eq(control.deleteCodes[0], 46, "Default deleteCodes include delete");
70 t.eq(control.deleteCodes[1], 68, "Default deleteCodes include 'd'");
76 function test_handleKeypress(t) {
80 * There are two things that we want to test here
81 * 1) test that control.deleteCodes are respected
82 * 3) test that a vertex is properly deleted
84 * In the future, feature deletion may be added to the control.
87 var layer = new OpenLayers.Layer.Vector();
88 var control = new OpenLayers.Control.ModifyFeature(layer);
91 control.deleteCodes = [delKey, dKey];
93 // test that a polygon vertex is deleted for all delete codes
94 var point = new OpenLayers.Feature.Vector(
95 new OpenLayers.Geometry.Point()
97 var poly = new OpenLayers.Feature.Vector(
98 new OpenLayers.Geometry.Polygon()
101 // mock up vertex deletion
102 control.dragControl.feature = point;
103 control.feature = poly;
104 control.vertices = [point];
105 point.geometry.parent = {
106 removeComponent: function(geometry) {
107 t.eq(geometry.id, point.geometry.id,
108 "vertex deletion: removeComponent called on parent with proper geometry");
111 layer.events.on({"featuremodified": function(event) {
112 t.eq(event.feature.id, poly.id, "vertex deletion: featuremodifed triggered");
114 layer.drawFeature = function(feature) {
115 t.eq(feature.id, poly.id,
116 "vertex deletion: drawFeature called with the proper feature");
118 control.resetVertices = function() {
119 t.ok(true, "vertex deletion: resetVertices called");
121 control.onModification = function(feature) {
122 t.eq(feature.id, poly.id,
123 "vertex deletion: onModification called with the proper feature");
125 // run the above four tests twice
126 control.handleKeypress({keyCode:delKey});
127 control.handleKeypress({keyCode:dKey});
128 t.eq(control.feature.state, OpenLayers.State.UPDATE, "feature state set to update");
130 // now make sure nothing happens if the vertex is mid-drag
131 control.dragControl.handlers.drag.dragging = true;
132 control.handleKeypress({keyCode:delKey});
140 function test_onUnSelect(t) {
142 var layer = new OpenLayers.Layer.Vector();
143 var control = new OpenLayers.Control.ModifyFeature(layer);
144 var fakeFeature = {'id':'myid'};
145 control.vertices = 'a';
146 control.virtualVertices = 'b';
147 control.features = true;
148 layer.events.on({"afterfeaturemodified": function(event) {
149 t.eq(event.feature, fakeFeature, "afterfeaturemodified triggered");
151 control.dragControl.deactivate = function() { t.ok(true, "Deactivate called on drag control"); }
152 control.onModificationEnd = function (feature) { t.eq(feature.id, fakeFeature.id, "onModificationEnd got feature.") }
153 layer.removeFeatures = function(verts) {
154 t.ok(verts == 'a', "Normal verts removed correctly");
156 layer.destroyFeatures = function(verts) {
157 t.ok(verts == 'b', "Virtual verts destroyed correctly");
159 control.unselectFeature(fakeFeature);
160 t.eq(control.feature, null, "feature is set to null");
162 layer.destroyFeatures = function() {};
167 function test_stop_modification(t) {
169 var map = new OpenLayers.Map('map');
170 var layer = new OpenLayers.Layer.Vector("Vectors!", {isBaseLayer: true});
171 var feature = new OpenLayers.Feature.Vector(
172 new OpenLayers.Geometry.Point(0, 0)
174 layer.addFeatures([feature]);
176 map.setCenter(new OpenLayers.LonLat(0, 0));
179 // If a feature is to be modified, control.selectFeature gets called.
180 // We want this test to fail if selectFeature gets called.
181 var modified = false;
182 var _ = OpenLayers.Control.ModifyFeature.prototype.selectFeature;
183 OpenLayers.Control.ModifyFeature.prototype.selectFeature = function() {
187 var control = new OpenLayers.Control.ModifyFeature(layer);
188 map.addControl(control);
191 // register a listener that will stop feature modification
192 layer.events.on({"beforefeaturemodified": function() {return false}});
194 // we can initiate feature modification by selecting a feature with
195 // the control's select feature control
196 control.selectControl.select(feature);
199 t.fail("selectFeature called, prepping feature for modification");
201 t.ok(true, "the beforefeaturemodified listener stopped feature modification");
204 OpenLayers.Control.ModifyFeature.prototype.selectFeature = _;
207 function test_selectFeature(t) {
209 var map = new OpenLayers.Map('map');
210 var layer = new OpenLayers.Layer.Vector("Vectors!", {isBaseLayer: true});
212 map.setCenter(new OpenLayers.LonLat(0, 0));
213 var control = new OpenLayers.Control.ModifyFeature(layer);
214 control.vertices = [];
215 control.virtualVertices = [];
216 var callback = function(obj) {
217 t.ok(obj.feature == fakeFeature, "beforefeaturemodified triggered");
219 layer.events.on({"beforefeaturemodified": callback});
220 control.dragControl.activate = function() { t.ok(true, "drag Control activated"); }
221 control.onModificationStart = function(feature) { t.eq(feature.id, fakeFeature.id, "On Modification Start called with correct feature."); }
225 control.collectVertices = function() { t.fail("Collect vertices called when geom is a point"); }
226 var fakeFeature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(0, 0));
228 // Points don't call collectVertices
229 control.selectFeature(fakeFeature);
231 control.collectVertices = function() {
232 t.ok(true, "collectVertices called");
234 this.virtualVertices = 'd';
235 layer.addFeatures(this.vertices);
236 layer.addFeatures(this.virtualVertices);
239 layer.addFeatures = function(features) {
240 t.ok(features == 'a' || features == 'd', "features passed correctly");
243 fakeFeature.geometry = new OpenLayers.Geometry.Polygon([
244 new OpenLayers.Geometry.LinearRing([
245 new OpenLayers.Geometry.Point(0, 0),
246 new OpenLayers.Geometry.Point(1, 1)
250 // OnSelect calls collectVertices and passes features to layer
251 control.selectFeature(fakeFeature);
253 control.vertices = ['a'];
254 control.virtualVertices = ['b'];
256 layer.addFeatures = function(features) {}
258 layer.removeFeatures = function(features) {
259 t.eq(features.length, 1, "Correct feature length passed in");
262 // Features are removed whenever they exist
263 control.selectFeature(fakeFeature);
267 // layer.destroy() will call removeFeatures with an empty array, make
268 // removeFeatures reference an empty function to prevent the above
270 layer.removeFeatures = function(features) {};
274 function test_resetVertices(t) {
276 var layer = new OpenLayers.Layer.Vector();
277 var control = new OpenLayers.Control.ModifyFeature(layer);
278 var point = new OpenLayers.Geometry.Point(5,6);
279 var point2 = new OpenLayers.Geometry.Point(7,8);
280 var point3 = new OpenLayers.Geometry.Point(9,10);
282 control.feature = new OpenLayers.Feature.Vector(point);
283 control.resetVertices();
284 t.eq(control.vertices.length, 0, "Correct vertices length");
285 t.eq(control.virtualVertices.length, 0, "Correct virtual vertices length.");
287 var multiPoint = new OpenLayers.Geometry.MultiPoint([point, point2]);
288 control.feature = new OpenLayers.Feature.Vector(multiPoint);
289 control.resetVertices();
290 t.eq(control.vertices.length, 2, "Correct vertices length with multipoint");
291 t.eq(control.virtualVertices.length, 0, "Correct virtual vertices length (multipoint).");
293 var line = new OpenLayers.Geometry.LineString([point, point2]);
294 control.feature = new OpenLayers.Feature.Vector(line);
295 control.resetVertices();
296 t.eq(control.vertices.length, 2, "Correct vertices length with line");
297 t.eq(control.virtualVertices.length, 1, "Correct virtual vertices length (linestring).");
299 var polygon = new OpenLayers.Geometry.Polygon([new OpenLayers.Geometry.LinearRing([point, point2, point3])]);
300 control.feature = new OpenLayers.Feature.Vector(polygon);
301 control.resetVertices();
302 t.eq(control.vertices.length, 3, "Correct vertices length with polygon");
303 t.eq(control.virtualVertices.length, 3, "Correct virtual vertices length (polygon).");
305 control.mode = OpenLayers.Control.ModifyFeature.DRAG;
306 control.resetVertices();
307 t.ok(control.dragHandle != null, "Drag handle is set");
308 t.eq(control.vertices.length, 0, "Correct vertices length with polygon (DRAG)");
310 control.mode = OpenLayers.Control.ModifyFeature.ROTATE;
311 control.resetVertices();
312 t.ok(control.radiusHandle != null, "Radius handle is set");
313 t.eq(control.vertices.length, 0, "Correct vertices length with polygon (ROTATE)");
315 control.mode = OpenLayers.Control.ModifyFeature.RESIZE;
316 control.resetVertices();
317 t.ok(control.radiusHandle != null, "Radius handle is set");
318 t.eq(control.vertices.length, 0, "Correct vertices length with polygon (RESIZE)");
320 control.mode = OpenLayers.Control.ModifyFeature.RESHAPE;
321 control.resetVertices();
322 t.ok(control.radiusHandle == null, "Radius handle is not set (RESHAPE)");
323 t.eq(control.vertices.length, 3, "Correct vertices length with polygon (RESHAPE)");
324 t.eq(control.virtualVertices.length, 3, "Correct virtual vertices length (RESHAPE)");
326 control.mode = OpenLayers.Control.ModifyFeature.RESIZE | OpenLayers.Control.ModifyFeature.RESHAPE;
327 control.resetVertices();
328 t.ok(control.radiusHandle != null, "Radius handle is set (RESIZE|RESHAPE)");
329 t.eq(control.vertices.length, 0, "No vertices when both resizing and reshaping (RESIZE|RESHAPE)");
330 t.eq(control.virtualVertices.length, 0, "No virtual vertices when both resizing and reshaping (RESIZE|RESHAPE)");
332 control.dragControl.feature = new OpenLayers.Feature.Vector(polygon);
333 control.dragControl.map = {};
334 control.dragControl.map.div = {};
335 control.dragControl.map.div.style = {};
336 control.dragControl.map.viewPortDiv = "foo";
337 control.dragControl.handlers.drag.deactivate = function() {
340 control.resetVertices();
341 t.ok(!control.dragControl.handlers.drag.active, "resetVertices deactivates drag handler");
342 control.dragControl.map = null;
348 function test_dragVertex(t) {
350 var map = new OpenLayers.Map("map", {
353 var layer = new OpenLayers.Layer.Vector("foo", {
354 maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),
359 var control = new OpenLayers.Control.ModifyFeature(layer);
360 map.addControl(control);
363 map.zoomToMaxExtent();
367 "vertexmodified": function(event) {
372 // pretend to drag a point
373 var feature = new OpenLayers.Feature.Vector(
374 new OpenLayers.Geometry.Point(0, 0)
376 control.feature = feature;
377 var pixel = new OpenLayers.Pixel(-100, 100);
378 control.dragVertex(feature, pixel);
379 t.eq(log.event.type, "vertexmodified", "[drag point] vertexmodified triggered");
380 t.geom_eq(log.event.vertex, feature.geometry, "[drag point] listeners receive correct vertex");
381 t.eq(log.event.feature.id, feature.id, "[drag point] listeners receive correct feature");
382 t.ok(log.event.pixel === pixel, "[drag point] listeners receive correct pixel");
384 // pretend to drag vertex of a linestring
385 var vert = new OpenLayers.Feature.Vector(
386 new OpenLayers.Geometry.Point(0, 0)
388 var feature = new OpenLayers.Feature.Vector(
389 new OpenLayers.Geometry.LineString([
390 vert.geometry, new OpenLayers.Geometry.Point(10, 0)
393 control.feature = feature;
394 var pixel = new OpenLayers.Pixel(-100, 100);
395 control.dragVertex(vert, pixel);
396 t.eq(log.event.type, "vertexmodified", "[drag vertex] vertexmodified triggered");
397 t.geom_eq(log.event.vertex, vert.geometry, "[drag vertex] listeners receive correct vertex");
398 t.eq(log.event.feature.id, feature.id, "[drag vertex] listeners receive correct feature");
399 t.ok(log.event.pixel === pixel, "[drag vertex] listeners receive correct pixel");
405 function test_onDrag(t) {
407 t.ok(true, "onDrag not tested yet.");
410 function test_dragComplete(t) {
412 var layer = new OpenLayers.Layer.Vector();
413 var control = new OpenLayers.Control.ModifyFeature(layer);
416 'geometry': { 'id':'myGeom'},
419 layer.addFeatures = function (verts) {
420 t.ok(verts == 'virtual' || verts == 'normal', verts + " verts correct");
422 layer.removeFeatures = function (verts) {
423 t.ok(verts == 'previous virtual' || verts == 'previous normal', verts + " verts correct");
425 layer.events.on({"featuremodified": function(event) {
426 t.eq(event.feature, fakeFeature, "featuremodified triggered");
428 control.onModification = function(feat) {
429 t.eq(feat.id, fakeFeature.id, "onModification gets correct feat");
431 control.collectVertices = function() {
432 t.ok(true, "collectVertices called");
433 this.vertices = 'normal';
434 this.virtualVertices = 'virtual';
435 layer.addFeatures(this.vertices);
436 layer.addFeatures(this.virtualVertices);
438 control.feature = fakeFeature;
439 control.vertices = 'previous normal';
440 control.virtualVertices = 'previous virtual';
441 control.dragComplete();
442 t.eq(fakeFeature.state, OpenLayers.State.UPDATE, "feature state set to UPDATE");
446 // layer.destroy() will call removeFeatures with an empty array, make
447 // removeFeatures reference an empty function to prevent the above
449 layer.removeFeatures = function(verts) {};
453 function test_deactivate(t) {
455 var map = new OpenLayers.Map("map");
456 var layer = new OpenLayers.Layer.Vector();
458 var control = new OpenLayers.Control.ModifyFeature(layer);
459 map.addControl(control);
461 control.selectControl.deactivate = function() {
463 "control.deactivate calls deactivate on select control");
465 control.dragControl.deactivate = function() {
467 "control.deactivate calls deactivate on drag control");
469 control.active = true;
470 control.deactivate();
475 function test_onModificationStart(t) {
477 var map = new OpenLayers.Map("map");
478 var layer = new OpenLayers.Layer.Vector();
480 var control = new OpenLayers.Control.ModifyFeature(layer);
481 map.addControl(control);
484 // make sure onModificationStart is called on feature selection
485 var testFeature = new OpenLayers.Feature.Vector(
486 new OpenLayers.Geometry.Point(Math.random(), Math.random())
488 control.onModificationStart = function(feature) {
489 t.eq(feature.id, testFeature.id,
490 "onModificationStart called with the right feature");
492 control.selectFeature(testFeature);
497 function test_onModification(t) {
499 var map = new OpenLayers.Map("map");
500 var layer = new OpenLayers.Layer.Vector();
502 var control = new OpenLayers.Control.ModifyFeature(layer);
503 map.addControl(control);
506 // make sure onModification is called on drag complete
507 var point = new OpenLayers.Feature.Vector(
508 new OpenLayers.Geometry.Point(Math.random(), Math.random())
510 control.feature = point;
511 control.onModification = function(feature) {
512 t.eq(feature.id, point.id,
513 "onModification called with the right feature on drag complete");
515 control.dragComplete();
517 // make sure onModification is called on vertex deletion
518 var poly = new OpenLayers.Feature.Vector(
519 new OpenLayers.Geometry.Polygon()
521 var oldDraw = layer.drawFeature;
522 layer.drawFeature = function() {
525 control.feature = poly;
526 control.vertices = [point];
527 layer.events.on({"featuremodified": function(event) {
528 t.eq(event.feature.id, poly.id, "featuremodified triggered");
530 control.onModification = function(feature) {
531 t.eq(feature.id, poly.id,
532 "onModification called with the right feature on vertex delete");
534 point.geometry.parent = poly.geometry;
535 control.dragControl.feature = point;
536 control.handleKeypress({keyCode:46});
537 layer.drawFeature = oldDraw;
542 function test_onModificationEnd(t) {
544 var map = new OpenLayers.Map("map");
545 var layer = new OpenLayers.Layer.Vector();
547 var control = new OpenLayers.Control.ModifyFeature(layer);
548 map.addControl(control);
551 // make sure onModificationEnd is called on unselect feature
552 var testFeature = new OpenLayers.Feature.Vector(
553 new OpenLayers.Geometry.Point(Math.random(), Math.random())
555 layer.events.on({"afterfeaturemodified": function(event) {
556 t.eq(event.feature.id, testFeature.id, "afterfeaturemodified triggered");
557 t.eq(event.modified, false, "afterfeaturemodified event given proper modified property (false - feature was not modified in this case)");
559 control.onModificationEnd = function(feature) {
560 t.eq(feature.id, testFeature.id,
561 "onModificationEnd called with the right feature");
563 control.unselectFeature(testFeature);
568 function test_events(t) {
570 var map = new OpenLayers.Map("map");
571 var layer = new OpenLayers.Layer.Vector();
573 var control = new OpenLayers.Control.ModifyFeature(layer);
574 map.addControl(control);
577 // make sure onModificationStart is called on feature selection
578 var testFeature = new OpenLayers.Feature.Vector(
579 new OpenLayers.Geometry.Point(Math.random(), Math.random())
582 // test that beforefeatureselected is triggered
583 function handle_beforefeatureselected(event) {
584 t.ok(event.feature == testFeature, "beforefeatureselected called with the correct feature");
587 "beforefeatureselected": handle_beforefeatureselected
589 layer.events.triggerEvent("beforefeatureselected", {
593 "beforefeatureselected": handle_beforefeatureselected
596 // test that beforefeatureselected is triggered
597 function handle_featureselected(event) {
598 t.ok(event.feature == testFeature, "featureselected called with the correct feature");
601 "featureselected": handle_featureselected
603 layer.events.triggerEvent("featureselected", {
607 "featureselected": handle_featureselected
618 <div id="map" style="width: 400px; height: 250px;"/>