aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Angular.js1
-rw-r--r--src/JSON.js2
-rw-r--r--src/directives.js7
-rw-r--r--src/service/formFactory.js11
-rw-r--r--src/service/parse.js57
-rw-r--r--src/service/scope.js9
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);
},
/**