diff options
| author | Misko Hevery | 2011-11-03 13:53:37 -0700 |
|---|---|---|
| committer | Misko Hevery | 2011-11-14 16:39:33 -0800 |
| commit | 7c11531902986405e9443c30dd0c654f86c31ca3 (patch) | |
| tree | b81c6ecdd2f4c6fc71b16ecd26044690f13228da /src | |
| parent | c6d2549a5255822290853aae8d922848b81bed62 (diff) | |
| download | angular.js-7c11531902986405e9443c30dd0c654f86c31ca3.tar.bz2 | |
refactor(parser): turn parser into a service (keep compatibility hack)
Diffstat (limited to 'src')
| -rw-r--r-- | src/Angular.js | 1 | ||||
| -rw-r--r-- | src/JSON.js | 2 | ||||
| -rw-r--r-- | src/directives.js | 7 | ||||
| -rw-r--r-- | src/service/formFactory.js | 11 | ||||
| -rw-r--r-- | src/service/parse.js | 57 | ||||
| -rw-r--r-- | src/service/scope.js | 9 |
6 files changed, 48 insertions, 39 deletions
diff --git a/src/Angular.js b/src/Angular.js index 931a3e5a..d8a726c0 100644 --- a/src/Angular.js +++ b/src/Angular.js @@ -1059,6 +1059,7 @@ function ngModule($provide, $injector) { $provide.service('$location', $LocationProvider); $provide.service('$locationConfig', $LocationConfigProvider); $provide.service('$log', $LogProvider); + $provide.service('$parse', $ParseProvider); $provide.service('$resource', $ResourceProvider); $provide.service('$route', $RouteProvider); $provide.service('$routeParams', $RouteParamsProvider); diff --git a/src/JSON.js b/src/JSON.js index d0ded009..51a12860 100644 --- a/src/JSON.js +++ b/src/JSON.js @@ -41,7 +41,7 @@ function fromJson(json, useNative) { if (useNative && window.JSON && window.JSON.parse) { obj = JSON.parse(json); } else { - obj = parser(json, true).primary()(); + obj = parseJson(json, true)(); } return transformDates(obj); } catch (e) { diff --git a/src/directives.js b/src/directives.js index daa42048..20235f64 100644 --- a/src/directives.js +++ b/src/directives.js @@ -235,9 +235,10 @@ angularDirective("ng:controller", function(expression){ */ angularDirective("ng:bind", function(expression, element){ element.addClass('ng-binding'); - var exprFn = parser(expression).statements(); - return ['$exceptionHandler', '$element', function($exceptionHandler, element) { - var lastValue = Number.NaN; + return ['$exceptionHandler', '$parse', '$element', function($exceptionHandler, $parse, element) { + var exprFn = parser(expression), + lastValue = Number.NaN; + this.$watch(function(scope) { // TODO(misko): remove error handling https://github.com/angular/angular.js/issues/347 var value, html, isHtml, isDomElement, diff --git a/src/service/formFactory.js b/src/service/formFactory.js index c9cb9c53..972b46ee 100644 --- a/src/service/formFactory.js +++ b/src/service/formFactory.js @@ -98,8 +98,9 @@ */ function $FormFactoryProvider() { - this.$get = ['$rootScope', function($rootScope) { - + var $parse; + this.$get = ['$rootScope', '$parse', function($rootScope, $parse_) { + $parse = $parse_; /** * @ngdoc proprety * @name rootForm @@ -352,10 +353,14 @@ function $FormFactoryProvider() { modelScope = params.scope, onChange = params.onChange, alias = params.alias, - scopeGet = parser(params.model).assignable(), + scopeGet = $parse(params.model), scopeSet = scopeGet.assign, widget = this.$new(params.controller, params.controllerArgs); + if (!scopeSet) { + throw Error("Expression '" + params.model + "' is not assignable!"); + }; + widget.$error = {}; // Set the state to something we know will change to get the process going. widget.$modelValue = Number.NaN; diff --git a/src/service/parse.js b/src/service/parse.js index f7b24a3c..465f416e 100644 --- a/src/service/parse.js +++ b/src/service/parse.js @@ -219,6 +219,7 @@ function lex(text){ function parser(text, json){ var ZERO = valueFn(0), + value, tokens = lex(text), assignment = _assignment, assignable = logicalOR, @@ -240,24 +241,14 @@ function parser(text, json){ functionIdent = pipeFunction = function() { throwError("is not valid json", {text:text, index:0}); }; + value = primary(); + } else { + value = statements(); } - //TODO: Shouldn't all of the public methods have assertAllConsumed? - //TODO: I think these should be public as part of the parser api instead of scope.$eval(). - return { - assignable: assertConsumed(assignable), - primary: assertConsumed(primary), - statements: assertConsumed(statements) - }; - - function assertConsumed(fn) { - return function() { - var value = fn(); - if (tokens.length !== 0) { - throwError("is an unexpected token", tokens[0]); - } - return value; - }; + if (tokens.length !== 0) { + throwError("is an unexpected token", tokens[0]); } + return value; /////////////////////////////////// function throwError(msg, token) { @@ -680,7 +671,6 @@ function getter(obj, path, bindFnToScope) { } var getterFnCache = {}, - compileCache = {}, JS_KEYWORDS = {}; forEach( @@ -727,13 +717,28 @@ function getterFn(path) { /////////////////////////////////// -// TODO(misko): Deprecate? Remove! -// I think that compilation should be a service. -function expressionCompile(exp) { - if (isFunction(exp)) return exp; - var fn = compileCache[exp]; - if (!fn) { - fn = compileCache[exp] = parser(exp).statements(); - } - return fn; +function $ParseProvider() { + var cache = {}; + this.$get = ['$injector', function($injector) { + return function(exp) { + switch(typeof exp) { + case 'string': + return cache.hasOwnProperty(exp) + ? cache[exp] + : cache[exp] = parser(exp); + case 'function': + return exp; + default: + return noop; + } + }; + }]; } + +// This is a special access for JSON parser which bypasses the injector +var parseJson = function(json) { + return parser(json, true); +}; + +// TODO(misko): temporary hack, until we get rid of the type augmentation +var expressionCompile = new $ParseProvider().$get[1](null); diff --git a/src/service/scope.js b/src/service/scope.js index 8c7926de..ade2d82e 100644 --- a/src/service/scope.js +++ b/src/service/scope.js @@ -25,8 +25,8 @@ * are expensive to construct. */ function $RootScopeProvider(){ - this.$get = ['$injector', '$exceptionHandler', - function( $injector, $exceptionHandler){ + this.$get = ['$injector', '$exceptionHandler', '$parse', + function( $injector, $exceptionHandler, $parse){ /** * @ngdoc function * @name angular.scope @@ -416,10 +416,7 @@ function $RootScopeProvider(){ * @returns {*} The result of evaluating the expression. */ $eval: function(expr) { - var fn = isString(expr) - ? expressionCompile(expr) - : expr || noop; - return fn(this); + return $parse(expr)(this); }, /** |
