Commit
…expression When running an expression with expensive checks, there is a call to `$eval` or `$evalAsync` then that expression is also evaluated using expensive checks Closes: #13850
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -1757,10 +1757,19 @@ function $ParseProvider() { | |||||
csp: noUnsafeEval, | ||||||
expensiveChecks: true | ||||||
}; | ||||||
var runningChecksEnabled = false; | ||||||
|
||||||
return function $parse(exp, interceptorFn, expensiveChecks) { | ||||||
$parse.$$runningExpensiveChecks = function() { | ||||||
return runningChecksEnabled; | ||||||
}; | ||||||
|
||||||
return $parse; | ||||||
|
||||||
function $parse(exp, interceptorFn, expensiveChecks) { | ||||||
var parsedExpression, oneTime, cacheKey; | ||||||
|
||||||
expensiveChecks = expensiveChecks || runningChecksEnabled; | ||||||
|
||||||
switch (typeof exp) { | ||||||
case 'string': | ||||||
exp = exp.trim(); | ||||||
|
@@ -1786,6 +1795,9 @@ function $ParseProvider() { | |||||
} else if (parsedExpression.inputs) { | ||||||
parsedExpression.$$watchDelegate = inputsWatchDelegate; | ||||||
} | ||||||
if (expensiveChecks) { | ||||||
parsedExpression = expensiveChecksInterceptor(parsedExpression); | ||||||
} | ||||||
cache[cacheKey] = parsedExpression; | ||||||
} | ||||||
return addInterceptor(parsedExpression, interceptorFn); | ||||||
|
@@ -1796,7 +1808,30 @@ function $ParseProvider() { | |||||
default: | ||||||
return addInterceptor(noop, interceptorFn); | ||||||
} | ||||||
}; | ||||||
} | ||||||
|
||||||
function expensiveChecksInterceptor(fn) { | ||||||
if (!fn) return fn; | ||||||
expensiveCheckFn.$$watchDelegate = fn.$$watchDelegate; | ||||||
expensiveCheckFn.assign = expensiveChecksInterceptor(fn.assign); | ||||||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
lgalfaso
Author
Contributor
|
||||||
expensiveCheckFn.constant = fn.constant; | ||||||
expensiveCheckFn.literal = fn.literal; | ||||||
for (var i = 0; fn.inputs && i < fn.inputs.length; ++i) { | ||||||
fn.inputs[i] = expensiveChecksInterceptor(fn.inputs[i]); | ||||||
This comment has been minimized.
Sorry, something went wrong.
gkalpak
Member
|
if (inputExpressions.length === 1) { |
This comment has been minimized.
This comment has been minimized.
Sorry, something went wrong.
gkalpak
Jan 28, 2016
Member
Does this mean that we should also do expensiveCheckFn.inputs = fn.inputs
?
This comment has been minimized.
This comment has been minimized.
Sorry, something went wrong.
mattdsteele
Jan 28, 2016
@gkalpak @lgalfaso - I can confirm this is occurring in my application - after updating to 1.5.0-rc.2, there are a few instances where my code is throwing TypeError: 'undefined' is not an object (evaluating 'inputExpressions.length')
. rc.1 and 1.4.x are fine.
I haven't tracked it down fully but it seems to happen when we $compile()
an element with ng-class
on it. I can try to put together a test case to verify, but wanted to let you know sooner rather than later.
Edit - Looks like #13871 solved this - I pulled down the snapshot build and it's resolved the issue.
This comment has been minimized.
This comment has been minimized.
Sorry, something went wrong.
gkalpak
Jan 28, 2016
Member
@mattdsteele, tgx for reporting this and thx for the follow-up. The fix will be included in the next release.
This comment has been minimized.
This comment has been minimized.
Sorry, something went wrong.
manast
Feb 3, 2016
@lgalfaso regarding "Given that we copy $$watchDelegate then there is a chance that $$watchDelegate is inputsWatchDelegate and then if inputs is undefined we will throw here
Line 1865 in acfda10
if (inputExpressions.length === 1) { |
Its not only a potenial bug, we have a product based on angular failing all over the place because of this (worked well with angular 1.5RC).
+1 for a fix.
This comment has been minimized.
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
This comment has been minimized.
Sorry, something went wrong.
Do we really need to pass
fn.assign
throughexpesiveChecksInterceptor()
?Isn't the function already created based on
expensiveChecks
?