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
This commit is contained in:
Vojta Jina 2012-03-07 17:07:25 -08:00
parent b348347dad
commit b3750103cc
2 changed files with 35 additions and 20 deletions

View file

@ -146,7 +146,7 @@ function lex(text){
function readIdent() { function readIdent() {
var ident = "", var ident = "",
start = index, start = index,
fn, lastDot, peekIndex, methodName, getter; lastDot, peekIndex, methodName;
while (index < text.length) { while (index < text.length) {
var ch = text.charAt(index); var ch = text.charAt(index);
@ -178,23 +178,26 @@ function lex(text){
} }
} }
fn = OPERATORS[ident];
getter = getterFn(ident); var token = {
tokens.push({
index:start, index:start,
text:ident, text:ident
json: fn, };
fn:fn||extend(
function(self, locals) { if (OPERATORS.hasOwnProperty(ident)) {
return (getter(self, locals)); token.fn = token.json = OPERATORS[ident];
}, } else {
{ var getter = getterFn(ident);
assign:function(self, value){ token.fn = extend(function(self, locals) {
return setter(self, ident, value); return (getter(self, locals));
} }, {
} assign: function(self, value) {
) return setter(self, ident, value);
}); }
});
}
tokens.push(token);
if (methodName) { if (methodName) {
tokens.push({ tokens.push({
@ -701,10 +704,11 @@ function getter(obj, path, bindFnToScope) {
var getterFnCache = {}; var getterFnCache = {};
function getterFn(path) { function getterFn(path) {
var fn = getterFnCache[path]; if (getterFnCache.hasOwnProperty(path)) {
if (fn) return fn; return getterFnCache[path];
}
var code = 'var l, fn, p;\n'; var fn, code = 'var l, fn, p;\n';
forEach(path.split('.'), function(key, index) { forEach(path.split('.'), function(key, index) {
code += 'if(!s) return s;\n' + code += 'if(!s) return s;\n' +
'l=s;\n' + 'l=s;\n' +

View file

@ -227,6 +227,17 @@ describe('parser', function() {
expect(scope.$eval("x.y.z", scope)).not.toBeDefined(); 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() { it('should evaluate grouped expressions', function() {
expect(scope.$eval("(1+2)*3")).toEqual((1+2)*3); expect(scope.$eval("(1+2)*3")).toEqual((1+2)*3);
}); });