diff options
| author | Vojta Jina | 2012-03-07 17:07:25 -0800 |
|---|---|---|
| committer | Vojta Jina | 2012-03-08 11:39:03 -0800 |
| commit | b3750103cc2c696b4ecadd7eebc55a76fd528bce (patch) | |
| tree | f2f2cfc9e330db8a4615b61999c4391ef7040e4e | |
| parent | b348347dadfa0abe3442ff0bdbc52d8077621e95 (diff) | |
| download | angular.js-b3750103cc2c696b4ecadd7eebc55a76fd528bce.tar.bz2 | |
fix($parse): Allow property names that collide with native object properties
I.e. constructor, toString, or watch on FF
(https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/watch)
+ optimize parser a bit to not create getter function for operators
| -rw-r--r-- | src/service/parse.js | 44 | ||||
| -rw-r--r-- | test/service/parseSpec.js | 11 |
2 files changed, 35 insertions, 20 deletions
diff --git a/src/service/parse.js b/src/service/parse.js index f7324ea6..47c5188e 100644 --- a/src/service/parse.js +++ b/src/service/parse.js @@ -146,7 +146,7 @@ function lex(text){ function readIdent() { var ident = "", start = index, - fn, lastDot, peekIndex, methodName, getter; + lastDot, peekIndex, methodName; while (index < text.length) { var ch = text.charAt(index); @@ -178,23 +178,26 @@ function lex(text){ } } - fn = OPERATORS[ident]; - getter = getterFn(ident); - tokens.push({ + + var token = { index:start, - text:ident, - json: fn, - fn:fn||extend( - function(self, locals) { - return (getter(self, locals)); - }, - { - assign:function(self, value){ - return setter(self, ident, value); - } - } - ) - }); + text:ident + }; + + if (OPERATORS.hasOwnProperty(ident)) { + token.fn = token.json = OPERATORS[ident]; + } else { + var getter = getterFn(ident); + token.fn = extend(function(self, locals) { + return (getter(self, locals)); + }, { + assign: function(self, value) { + return setter(self, ident, value); + } + }); + } + + tokens.push(token); if (methodName) { tokens.push({ @@ -701,10 +704,11 @@ function getter(obj, path, bindFnToScope) { var getterFnCache = {}; function getterFn(path) { - var fn = getterFnCache[path]; - if (fn) return fn; + if (getterFnCache.hasOwnProperty(path)) { + return getterFnCache[path]; + } - var code = 'var l, fn, p;\n'; + var fn, code = 'var l, fn, p;\n'; forEach(path.split('.'), function(key, index) { code += 'if(!s) return s;\n' + 'l=s;\n' + diff --git a/test/service/parseSpec.js b/test/service/parseSpec.js index cf3f2aa5..c98b180c 100644 --- a/test/service/parseSpec.js +++ b/test/service/parseSpec.js @@ -227,6 +227,17 @@ describe('parser', function() { expect(scope.$eval("x.y.z", scope)).not.toBeDefined(); }); + it('should support property names that colide with native object properties', function() { + // regression + scope.watch = 1; + scope.constructor = 2; + scope.toString = 3; + + expect(scope.$eval('watch', scope)).toBe(1); + expect(scope.$eval('constructor', scope)).toBe(2); + expect(scope.$eval('toString', scope)).toBe(3); + }); + it('should evaluate grouped expressions', function() { expect(scope.$eval("(1+2)*3")).toEqual((1+2)*3); }); |
