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"
+ );
}