diff options
Diffstat (limited to 'src/Scope.js')
| -rw-r--r-- | src/Scope.js | 74 |
1 files changed, 50 insertions, 24 deletions
diff --git a/src/Scope.js b/src/Scope.js index fe0b6ce3..637fc25e 100644 --- a/src/Scope.js +++ b/src/Scope.js @@ -43,31 +43,55 @@ function setter(instance, path, value){ return value; } +/////////////////////////////////// + +var getterFnCache = {}; +function getterFn(path){ + var fn = getterFnCache[path]; + if (fn) return fn; + + var code = 'function (self){\n'; + code += ' var last, fn, type;\n'; + foreach(path.split('.'), function(key) { + key = (key == 'this') ? '["this"]' : '.' + key; + code += ' if(!self) return self;\n'; + code += ' last = self;\n'; + code += ' self = self' + key + ';\n'; + code += ' if(typeof self == "function") \n'; + code += ' self = function(){ return last'+key+'.apply(last, arguments); };\n'; + if (key.charAt(1) == '$') { + // special code for super-imposed functions + var name = key.substr(2); + code += ' if(!self) {\n'; + code += ' type = angular.Global.typeOf(last);\n'; + code += ' fn = (angular[type.charAt(0).toUpperCase() + type.substring(1)]||{})["' + name + '"];\n'; + code += ' if (fn)\n'; + code += ' self = function(){ return fn.apply(last, [last].concat(slice.call(arguments, 0, arguments.length))); };\n'; + code += ' }\n'; + } + }); + code += ' return self;\n}'; + fn = eval('(' + code + ')'); + fn.toString = function(){ return code; }; + + return getterFnCache[path] = fn; +} + +/////////////////////////////////// + var compileCache = {}; function expressionCompile(exp){ if (isFunction(exp)) return exp; - var expFn = compileCache[exp]; - if (!expFn) { + var fn = compileCache[exp]; + if (!fn) { var parser = new Parser(exp); - expFn = parser.statements(); + var fnSelf = parser.statements(); parser.assertAllConsumed(); - compileCache[exp] = expFn; + fn = compileCache[exp] = extend( + function(){ return fnSelf(this);}, + {fnSelf: fnSelf}); } - return parserNewScopeAdapter(expFn); -} - -// return expFn -// TODO(remove this hack) -function parserNewScopeAdapter(fn) { - return function(){ - return fn({ - state: this, - scope: { - set: this.$set, - get: this.$get - } - }); - }; + return fn; } function rethrow(e) { throw e; } @@ -100,11 +124,13 @@ function createScope(parent, services, existing) { if (exp !== undefined) { return expressionCompile(exp).apply(instance, slice.call(arguments, 1, arguments.length)); } else { - foreach(evalLists.sorted, function(list) { - foreach(list, function(eval) { - instance.$tryEval(eval.fn, eval.handler); - }); - }); + for ( var i = 0, iSize = evalLists.sorted.length; i < iSize; i++) { + for ( var queue = evalLists.sorted[i], + jSize = queue.length, + j= 0; j < jSize; j++) { + instance.$tryEval(queue[j].fn, queue[j].handler); + } + } } }, |
