| OLD | NEW |
| 1 // Copyright 2006 Google Inc. | 1 // Copyright 2006 Google Inc. |
| 2 // | 2 // |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 // you may not use this file except in compliance with the License. | 4 // you may not use this file except in compliance with the License. |
| 5 // You may obtain a copy of the License at | 5 // You may obtain a copy of the License at |
| 6 // | 6 // |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 // | 8 // |
| 9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 43 * Un-inlined literals, to avoid object creation in IE6. TODO(mesch): | 43 * Un-inlined literals, to avoid object creation in IE6. TODO(mesch): |
| 44 * So far, these are only used here, but we could use them thoughout | 44 * So far, these are only used here, but we could use them thoughout |
| 45 * the code and thus move them to constants.js. | 45 * the code and thus move them to constants.js. |
| 46 */ | 46 */ |
| 47 var CHAR_colon = ':'; | 47 var CHAR_colon = ':'; |
| 48 var REGEXP_semicolon = /\s*;\s*/; | 48 var REGEXP_semicolon = /\s*;\s*/; |
| 49 | 49 |
| 50 | 50 |
| 51 /** | 51 /** |
| 52 * See constructor_() | 52 * See constructor_() |
| 53 * @param {Object|null} opt_data | 53 * @param {Object|null=} opt_data |
| 54 * @param {Object} opt_parent | 54 * @param {Object=} opt_parent |
| 55 * @constructor | 55 * @constructor |
| 56 */ | 56 */ |
| 57 function JsEvalContext(opt_data, opt_parent) { | 57 function JsEvalContext(opt_data, opt_parent) { |
| 58 this.constructor_.apply(this, arguments); | 58 this.constructor_.apply(this, arguments); |
| 59 } | 59 } |
| 60 | 60 |
| 61 /** | 61 /** |
| 62 * Context for processing a jstemplate. The context contains a context | 62 * Context for processing a jstemplate. The context contains a context |
| 63 * object, whose properties can be referred to in jstemplate | 63 * object, whose properties can be referred to in jstemplate |
| 64 * expressions, and it holds the locally defined variables. | 64 * expressions, and it holds the locally defined variables. |
| 65 * | 65 * |
| 66 * @param {Object|null} opt_data The context object. Null if no context. | 66 * @param {Object|null} opt_data The context object. Null if no context. |
| 67 * | 67 * |
| 68 * @param {Object} opt_parent The parent context, from which local | 68 * @param {Object} opt_parent The parent context, from which local |
| 69 * variables are inherited. Normally the context object of the parent | 69 * variables are inherited. Normally the context object of the parent |
| 70 * context is the object whose property the parent object is. Null for the | 70 * context is the object whose property the parent object is. Null for the |
| 71 * context of the root object. | 71 * context of the root object. |
| 72 * @private |
| 72 */ | 73 */ |
| 73 JsEvalContext.prototype.constructor_ = function(opt_data, opt_parent) { | 74 JsEvalContext.prototype.constructor_ = function(opt_data, opt_parent) { |
| 74 var me = this; | 75 var me = this; |
| 75 | 76 |
| 76 /** | |
| 77 * The context for variable definitions in which the jstemplate | |
| 78 * expressions are evaluated. Other than for the local context, | |
| 79 * which replaces the parent context, variable definitions of the | |
| 80 * parent are inherited. The special variable $this points to data_. | |
| 81 * | |
| 82 * If this instance is recycled from the cache, then the property is | |
| 83 * already initialized. | |
| 84 * | |
| 85 * @type {Object} | |
| 86 */ | |
| 87 if (!me.vars_) { | 77 if (!me.vars_) { |
| 78 /** |
| 79 * The context for variable definitions in which the jstemplate |
| 80 * expressions are evaluated. Other than for the local context, |
| 81 * which replaces the parent context, variable definitions of the |
| 82 * parent are inherited. The special variable $this points to data_. |
| 83 * |
| 84 * If this instance is recycled from the cache, then the property is |
| 85 * already initialized. |
| 86 * |
| 87 * @type {Object} |
| 88 */ |
| 88 me.vars_ = {}; | 89 me.vars_ = {}; |
| 89 } | 90 } |
| 90 if (opt_parent) { | 91 if (opt_parent) { |
| 91 // If there is a parent node, inherit local variables from the | 92 // If there is a parent node, inherit local variables from the |
| 92 // parent. | 93 // parent. |
| 93 copyProperties(me.vars_, opt_parent.vars_); | 94 copyProperties(me.vars_, opt_parent.vars_); |
| 94 } else { | 95 } else { |
| 95 // If a root node, inherit global symbols. Since every parent | 96 // If a root node, inherit global symbols. Since every parent |
| 96 // chain has a root with no parent, global variables will be | 97 // chain has a root with no parent, global variables will be |
| 97 // present in the case above too. This means that globals can be | 98 // present in the case above too. This means that globals can be |
| 98 // overridden by locals, as it should be. | 99 // overridden by locals, as it should be. |
| 99 copyProperties(me.vars_, JsEvalContext.globals_); | 100 copyProperties(me.vars_, JsEvalContext.globals_); |
| 100 } | 101 } |
| 101 | 102 |
| 102 /** | 103 /** |
| 103 * The current context object is assigned to the special variable | 104 * The current context object is assigned to the special variable |
| 104 * $this so it is possible to use it in expressions. | 105 * $this so it is possible to use it in expressions. |
| 105 * @type Object | 106 * @type {Object} |
| 106 */ | 107 */ |
| 107 me.vars_[VAR_this] = opt_data; | 108 me.vars_[VAR_this] = opt_data; |
| 108 | 109 |
| 109 /** | 110 /** |
| 110 * The entire context structure is exposed as a variable so it can be | 111 * The entire context structure is exposed as a variable so it can be |
| 111 * passed to javascript invocations through jseval. | 112 * passed to javascript invocations through jseval. |
| 112 */ | 113 */ |
| 113 me.vars_[VAR_context] = me; | 114 me.vars_[VAR_context] = me; |
| 114 | 115 |
| 115 /** | 116 /** |
| 116 * The local context of the input data in which the jstemplate | 117 * The local context of the input data in which the jstemplate |
| 117 * expressions are evaluated. Notice that this is usually an Object, | 118 * expressions are evaluated. Notice that this is usually an Object, |
| 118 * but it can also be a scalar value (and then still the expression | 119 * but it can also be a scalar value (and then still the expression |
| 119 * $this can be used to refer to it). Notice this can even be value, | 120 * $this can be used to refer to it). Notice this can even be value, |
| 120 * undefined or null. Hence, we have to protect jsexec() from using | 121 * undefined or null. Hence, we have to protect jsexec() from using |
| 121 * undefined or null, yet we want $this to reflect the true value of | 122 * undefined or null, yet we want $this to reflect the true value of |
| 122 * the current context. Thus we assign the original value to $this, | 123 * the current context. Thus we assign the original value to $this, |
| 123 * above, but for the expression context we replace null and | 124 * above, but for the expression context we replace null and |
| 124 * undefined by the empty string. | 125 * undefined by the empty string. |
| 125 * | 126 * |
| 126 * @type {Object|null} | 127 * @type {*} |
| 127 */ | 128 */ |
| 128 me.data_ = getDefaultObject(opt_data, STRING_empty); | 129 me.data_ = getDefaultObject(opt_data, STRING_empty); |
| 129 | 130 |
| 130 if (!opt_parent) { | 131 if (!opt_parent) { |
| 131 // If this is a top-level context, create a variable reference to the data | 132 // If this is a top-level context, create a variable reference to the data |
| 132 // to allow for accessing top-level properties of the original context | 133 // to allow for accessing top-level properties of the original context |
| 133 // data from child contexts. | 134 // data from child contexts. |
| 134 me.vars_[VAR_top] = me.data_; | 135 me.vars_[VAR_top] = me.data_; |
| 135 } | 136 } |
| 136 }; | 137 }; |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 257 return ret; | 258 return ret; |
| 258 }; | 259 }; |
| 259 | 260 |
| 260 | 261 |
| 261 /** | 262 /** |
| 262 * Binds a local variable to the given value. If set from jstemplate | 263 * Binds a local variable to the given value. If set from jstemplate |
| 263 * jsvalue expressions, variable names must start with $, but in the | 264 * jsvalue expressions, variable names must start with $, but in the |
| 264 * API they only have to be valid javascript identifier. | 265 * API they only have to be valid javascript identifier. |
| 265 * | 266 * |
| 266 * @param {string} name | 267 * @param {string} name |
| 267 * | 268 * @param {*} value |
| 268 * @param {Object?} value | |
| 269 */ | 269 */ |
| 270 JsEvalContext.prototype.setVariable = function(name, value) { | 270 JsEvalContext.prototype.setVariable = function(name, value) { |
| 271 this.vars_[name] = value; | 271 this.vars_[name] = value; |
| 272 }; | 272 }; |
| 273 | 273 |
| 274 | 274 |
| 275 /** | 275 /** |
| 276 * Returns the value bound to the local variable of the given name, or | 276 * Returns the value bound to the local variable of the given name, or |
| 277 * undefined if it wasn't set. There is no way to distinguish a | 277 * undefined if it wasn't set. There is no way to distinguish a |
| 278 * variable that wasn't set from a variable that was set to | 278 * variable that wasn't set from a variable that was set to |
| 279 * undefined. Used mostly for testing. | 279 * undefined. Used mostly for testing. |
| 280 * | 280 * |
| 281 * @param {string} name | 281 * @param {string} name |
| 282 * | 282 * |
| 283 * @return {Object?} value | 283 * @return {*} value |
| 284 */ | 284 */ |
| 285 JsEvalContext.prototype.getVariable = function(name) { | 285 JsEvalContext.prototype.getVariable = function(name) { |
| 286 return this.vars_[name]; | 286 return this.vars_[name]; |
| 287 }; | 287 }; |
| 288 | 288 |
| 289 | 289 |
| 290 /** | 290 /** |
| 291 * Evaluates a string expression within the scope of this context | 291 * Evaluates a string expression within the scope of this context |
| 292 * and returns the result. | 292 * and returns the result. |
| 293 * | 293 * |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 400 var ret = []; | 400 var ret = []; |
| 401 var values = expr.split(REGEXP_semicolon); | 401 var values = expr.split(REGEXP_semicolon); |
| 402 for (var i = 0, I = jsLength(values); i < I; ++i) { | 402 for (var i = 0, I = jsLength(values); i < I; ++i) { |
| 403 if (values[i]) { | 403 if (values[i]) { |
| 404 var value = jsEvalToFunction(values[i]); | 404 var value = jsEvalToFunction(values[i]); |
| 405 ret.push(value); | 405 ret.push(value); |
| 406 } | 406 } |
| 407 } | 407 } |
| 408 return ret; | 408 return ret; |
| 409 } | 409 } |
| OLD | NEW |