diff --git a/examples/styles-context.html b/examples/styles-context.html new file mode 100644 index 0000000000..4849cfc540 --- /dev/null +++ b/examples/styles-context.html @@ -0,0 +1,216 @@ + + + OpenLayers Vector Styles + + + + + + +

Feature Styles Example

+ +
+ +

+ Shows how to create a feature styles. +

+ +
+ +
+

Features in the northern hemisphere are styled according to their + "type" attribute. This is accomplished with a simple template that + is evaluated with the feature attributes as context.

+

Features in the sourthern hemisphere are styled according to a + combination of their attributes and non-attribute properties. This + is accomplished using an advanced template that calls functions + on the context object passed to the Style constructor.

+
+ + + + + OpenLayers Vector Styles + + + + + + +

Feature Styles Example

+ +
+ +

+ Shows how to create a feature styles. +

+ +
+ +
+

Features in the northern hemisphere are styled according to their + "type" attribute. This is accomplished with a simple template that + is evaluated with the feature attributes as context.

+

Features in the sourthern hemisphere are styled according to a + combination of their attributes and non-attribute properties. This + is accomplished using an advanced template that calls functions + on the context object passed to the Style constructor.

+
+ + diff --git a/lib/OpenLayers/BaseTypes.js b/lib/OpenLayers/BaseTypes.js index b0fdfaea93..939753efe4 100644 --- a/lib/OpenLayers/BaseTypes.js +++ b/lib/OpenLayers/BaseTypes.js @@ -106,22 +106,31 @@ OpenLayers.String = { * context - {Object} An optional object with properties corresponding * to the tokens in the format string. If no context is sent, the * window object will be used. + * args - {Array} Optional arguments to pass to any functions found in + * the context. If a context property is a function, the token + * will be replaced by the return from the function called with + * these arguments. * * Returns: * {String} A string with tokens replaced from the context object. */ - format: function(template, context) { + format: function(template, context, args) { if(!context) { context = window; } var tokens = template.split("${"); - var item, last; + var item, last, replacement; for(var i=1; i 0) { - tokens[i] = context[item.substring(0, last)] + - item.substring(++last); + if(last > 0) { + replacement = context[item.substring(0, last)]; + if(typeof replacement == "function") { + replacement = args ? + replacement.apply(null, args) : + replacement(); + } + tokens[i] = replacement + item.substring(++last); } else { tokens[i] = "${" + item; } diff --git a/lib/OpenLayers/Style.js b/lib/OpenLayers/Style.js index 40d9ac8c59..4db67448fa 100644 --- a/lib/OpenLayers/Style.js +++ b/lib/OpenLayers/Style.js @@ -196,7 +196,7 @@ OpenLayers.Style = OpenLayers.Class({ var context = this.context || feature.attributes || feature.data; for (var i in this.propertyStyles) { - style[i] = OpenLayers.Style.createLiteral(style[i], context); + style[i] = OpenLayers.Style.createLiteral(style[i], context, feature); } return style; }, @@ -315,20 +315,22 @@ OpenLayers.Style = OpenLayers.Class({ * into a Literal, taking the property values from the passed features. * * Parameters: - * value {String} value to parse. If this string contains a construct like + * value - {String} value to parse. If this string contains a construct like * "foo ${bar}", then "foo " will be taken as literal, and "${bar}" * will be replaced by the value of the "bar" attribute of the passed * feature. - * context {Object} context to take attribute values from + * context - {Object} context to take attribute values from + * feature - {OpenLayers.Feature.Vector} The feature that will be passed + * to for evaluating functions in the context. * * Returns: * {String} the parsed value. In the example of the value parameter above, the * result would be "foo valueOfBar", assuming that the passed feature has an * attribute named "bar" with the value "valueOfBar". */ -OpenLayers.Style.createLiteral = function(value, context) { +OpenLayers.Style.createLiteral = function(value, context, feature) { if (typeof value == "string" && value.indexOf("${") != -1) { - value = OpenLayers.String.format(value, context) + value = OpenLayers.String.format(value, context, [feature]); value = isNaN(value) ? value : parseFloat(value); } return value; diff --git a/tests/test_BaseTypes.html b/tests/test_BaseTypes.html index d9f071ebd7..ea56192ea2 100644 --- a/tests/test_BaseTypes.html +++ b/tests/test_BaseTypes.html @@ -89,7 +89,7 @@ "", "${ ", "${", " ${", "${${", "${}", "${${}}", " ${ ${", "}", "${${} }" ] - t.plan(4 + unchanged.length); + t.plan(6 + unchanged.length); var format = OpenLayers.String.format; @@ -114,6 +114,31 @@ var context = {bar: "foo", foo: "bar"}; t.eq(format("a ${bar} is a ${foo}", context), "a foo is a bar", "multiple properties replaced correctly"); + + // test context with properties that are functions + var context = { + bar: "church", + getDrunk: function() { + return arguments[0]; + } + }; + t.eq( + format("I go to the ${bar} to ${getDrunk}.", context, ["eat pretzels"]), + "I go to the church to eat pretzels.", + "function correctly called in context with arguments" + ); + + // test that things don't break + var context = { + meaning: function(truth) { + return truth; + } + }; + t.eq( + format("In life, truth is ${meaning}.", context), + "In life, truth is undefined.", + "still works if arguments are not supplied" + ); }