From 576e931dace0dfc4678e18b7f8ad06f6163b74ba Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Tue, 17 Mar 2009 16:08:12 +0000 Subject: [PATCH] Adding support for cloning rules and filters. r=ahocevar (closes #1919) git-svn-id: http://svn.openlayers.org/trunk/openlayers@9071 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf --- lib/OpenLayers/Filter.js | 13 ++++++++- lib/OpenLayers/Filter/Comparison.js | 11 ++++++++ lib/OpenLayers/Filter/FeatureId.js | 14 ++++++++++ lib/OpenLayers/Filter/Logical.js | 18 ++++++++++++ lib/OpenLayers/Filter/Spatial.js | 13 +++++++++ lib/OpenLayers/Rule.js | 30 ++++++++++++++++++-- tests/Filter/Comparison.html | 23 +++++++++++++++ tests/Filter/FeatureId.html | 20 ++++++++++++++ tests/Filter/Logical.html | 34 +++++++++++++++++++++++ tests/Filter/Spatial.html | 25 +++++++++++++++++ tests/Rule.html | 43 +++++++++++++++++++++++++++++ 11 files changed, 241 insertions(+), 3 deletions(-) diff --git a/lib/OpenLayers/Filter.js b/lib/OpenLayers/Filter.js index 777ab4fbd3..31cbcd36ba 100644 --- a/lib/OpenLayers/Filter.js +++ b/lib/OpenLayers/Filter.js @@ -51,5 +51,16 @@ OpenLayers.Filter = OpenLayers.Class({ return true; }, + /** + * APIMethod: clone + * Clones this filter. Should be implementted by subclasses. + * + * Returns: + * {} Clone of this filter. + */ + clone: function() { + return null; + }, + CLASS_NAME: "OpenLayers.Filter" -}); \ No newline at end of file +}); diff --git a/lib/OpenLayers/Filter/Comparison.js b/lib/OpenLayers/Filter/Comparison.js index 71978abf8f..b8d4e92a42 100644 --- a/lib/OpenLayers/Filter/Comparison.js +++ b/lib/OpenLayers/Filter/Comparison.js @@ -230,6 +230,17 @@ OpenLayers.Filter.Comparison = OpenLayers.Class(OpenLayers.Filter, { return value; }, + /** + * APIMethod: clone + * Clones this filter. + * + * Returns: + * {} Clone of this filter. + */ + clone: function() { + return OpenLayers.Util.extend(new OpenLayers.Filter.Comparison(), this); + }, + CLASS_NAME: "OpenLayers.Filter.Comparison" }); diff --git a/lib/OpenLayers/Filter/FeatureId.js b/lib/OpenLayers/Filter/FeatureId.js index e052e1956c..9574dd5f76 100644 --- a/lib/OpenLayers/Filter/FeatureId.js +++ b/lib/OpenLayers/Filter/FeatureId.js @@ -62,5 +62,19 @@ OpenLayers.Filter.FeatureId = OpenLayers.Class(OpenLayers.Filter, { return false; }, + /** + * APIMethod: clone + * Clones this filter. + * + * Returns: + * {} Clone of this filter. + */ + clone: function() { + var filter = new OpenLayers.Filter.FeatureId(); + OpenLayers.Util.extend(filter, this); + filter.fids = this.fids.slice(); + return filter; + }, + CLASS_NAME: "OpenLayers.Filter.FeatureId" }); diff --git a/lib/OpenLayers/Filter/Logical.js b/lib/OpenLayers/Filter/Logical.js index 60661f6a69..a438af45a5 100644 --- a/lib/OpenLayers/Filter/Logical.js +++ b/lib/OpenLayers/Filter/Logical.js @@ -90,6 +90,24 @@ OpenLayers.Filter.Logical = OpenLayers.Class(OpenLayers.Filter, { } }, + /** + * APIMethod: clone + * Clones this filter. + * + * Returns: + * {} Clone of this filter. + */ + clone: function() { + var filters = []; + for(var i=0, len=this.filters.length; i} Clone of this filter. + */ + clone: function() { + var options = OpenLayers.Util.applyDefaults({ + value: this.value && this.value.clone && this.value.clone() + }, this); + return new OpenLayers.Filter.Spatial(options); + }, CLASS_NAME: "OpenLayers.Filter.Spatial" }); diff --git a/lib/OpenLayers/Rule.js b/lib/OpenLayers/Rule.js index f1fb695192..43732f0a8c 100644 --- a/lib/OpenLayers/Rule.js +++ b/lib/OpenLayers/Rule.js @@ -101,10 +101,9 @@ OpenLayers.Rule = OpenLayers.Class({ * {} */ initialize: function(options) { - this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + "_"); this.symbolizer = {}; - OpenLayers.Util.extend(this, options); + this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + "_"); }, /** @@ -178,6 +177,33 @@ OpenLayers.Rule = OpenLayers.Class({ } return context; }, + + /** + * APIMethod: clone + * Clones this rule. + * + * Returns: + * {} Clone of this rule. + */ + clone: function() { + var options = OpenLayers.Util.extend({}, this); + // clone symbolizer + options.symbolizer = {}; + for(var key in this.symbolizer) { + value = this.symbolizer[key]; + type = typeof value; + if(type === "object") { + options.symbolizer[key] = OpenLayers.Util.extend({}, value); + } else if(type === "string") { + options.symbolizer[key] = value; + } + } + // clone filter + options.filter = this.filter && this.filter.clone(); + // clone context + options.context = this.context && OpenLayers.Util.extend({}, this.context); + return new OpenLayers.Rule(options); + }, CLASS_NAME: "OpenLayers.Rule" }); \ No newline at end of file diff --git a/tests/Filter/Comparison.html b/tests/Filter/Comparison.html index dbc142d733..b7c0cb15ef 100644 --- a/tests/Filter/Comparison.html +++ b/tests/Filter/Comparison.html @@ -175,6 +175,29 @@ } } + + function test_clone(t) { + + t.plan(3); + + var filter = new OpenLayers.Filter.Comparison({ + type: OpenLayers.Filter.Comparison.EQUAL_TO, + property: "prop", + value: "val" + }); + + var clone = filter.clone(); + + // modify the original + filter.type = OpenLayers.Filter.Comparison.NOT_EQUAL_TO; + + t.eq(clone.type, OpenLayers.Filter.Comparison.EQUAL_TO, "clone has proper type"); + t.eq(clone.property, "prop", "clone has proper property"); + t.eq(clone.value, "val", "clone has proper value"); + + filter.destroy(); + + } diff --git a/tests/Filter/FeatureId.html b/tests/Filter/FeatureId.html index bc201abdac..0adeba7a93 100644 --- a/tests/Filter/FeatureId.html +++ b/tests/Filter/FeatureId.html @@ -40,6 +40,26 @@ feature.destroy(); } } + + function test_clone(t) { + + t.plan(1); + + var filter = new OpenLayers.Filter.FeatureId({ + fids: [1, 2, 3] + }); + + var clone = filter.clone(); + + // modify the original + filter.fids.push(4); + + t.eq(clone.fids.length, 3, "clone has proper fids length"); + + filter.destroy(); + + } + diff --git a/tests/Filter/Logical.html b/tests/Filter/Logical.html index 1cee997de3..675472a10d 100644 --- a/tests/Filter/Logical.html +++ b/tests/Filter/Logical.html @@ -34,6 +34,40 @@ t.eq(filter.evaluate(feature.attributes), false, "feature evaluates to false correctly."); } + + function test_clone(t) { + + t.plan(2); + + var filter = new OpenLayers.Filter.Logical({ + type: OpenLayers.Filter.Logical.AND, + filters: [ + new OpenLayers.Filter.Comparison({ + type: OpenLayers.Filter.Comparison.EQUAL_TO, + property: "prop1", + value: "val1" + }), + new OpenLayers.Filter.Comparison({ + type: OpenLayers.Filter.Comparison.NOT_EQUAL_TO, + property: "prop2", + value: "val2" + }) + ] + }); + + var clone = filter.clone(); + + // modify the original + filter.type = OpenLayers.Filter.Logical.OR; + filter.filters[0].value = "nada"; + + t.eq(clone.type, OpenLayers.Filter.Logical.AND, "clone has proper type"); + t.eq(clone.filters[0].value, "val1", "clone has cloned child filters"); + + filter.destroy(); + + } + diff --git a/tests/Filter/Spatial.html b/tests/Filter/Spatial.html index 302650869e..0dbd82b103 100644 --- a/tests/Filter/Spatial.html +++ b/tests/Filter/Spatial.html @@ -71,6 +71,31 @@ t.eq(res, false, "evaluates returns correct value when feature does not intersect bounds"); } + + function test_clone(t) { + + t.plan(2); + + var bounds = new OpenLayers.Bounds(0, 0, 10, 10); + var filter = new OpenLayers.Filter.Spatial({ + type: OpenLayers.Filter.Spatial.BBOX, + value: bounds + }); + + var clone = filter.clone(); + + // modify the original + filter.value.bottom = -100; + + t.eq(clone.type, OpenLayers.Filter.Spatial.BBOX, "clone has proper type"); + t.eq(clone.value.toBBOX(), "0,0,10,10", "clone has proper value"); + + filter.destroy(); + clone.destroy(); + + } + + diff --git a/tests/Rule.html b/tests/Rule.html index d27d88a7cf..9c5a46539f 100644 --- a/tests/Rule.html +++ b/tests/Rule.html @@ -40,6 +40,49 @@ t.eq(context.foobar, "world", "value returned by getContext is correct" + " if a context is given in constructor options"); } + + function test_clone(t) { + + t.plan(7); + + var rule = new OpenLayers.Rule({ + name: "test rule", + minScaleDenominator: 10, + maxScaleDenominator: 20, + filter: new OpenLayers.Filter.Comparison({ + type: OpenLayers.Filter.Comparison.EQUAL_TO, + property: "prop", + value: "value" + }), + symbolizer: { + fillColor: "black" + }, + context: { + foo: "bar" + } + }); + var clone = rule.clone(); + t.eq(clone.name, "test rule", "name copied"); + t.eq(clone.minScaleDenominator, 10, "minScaleDenominator copied"); + t.eq(clone.filter.type, OpenLayers.Filter.Comparison.EQUAL_TO, "clone has correct filter type"); + + // modify original + rule.filter.property = "new"; + rule.symbolizer.fillColor = "white"; + rule.context.foo = "baz"; + + // confirm that clone didn't change + t.eq(clone.filter.property, "prop", "clone has clone of filter"); + t.eq(clone.symbolizer.fillColor, "black", "clone has clone of symbolizer"); + t.eq(clone.context.foo, "bar", "clone has clone of context"); + + // confirm that ids are different + t.ok(clone.id !== rule.id, "clone has different id"); + + rule.destroy(); + clone.destroy(); + + } function test_Rule_destroy(t) { t.plan(1);