With this change, expressions like "firstName + ' ' + lastName | uppercase"
will be analyzed and only the inputs for the expression will be watched
(in this case "firstName" and "lastName"). Only when at least one of the inputs
change, the expression will be evaluated.
This change speeds up simple expressions like `firstName | noop` by ~15%
and more complex expressions like `startDate | date` by ~2500%.
BREAKING CHANGE: all filters are assumed to be stateless functions
Previously it was a good practice to make all filters stateless, but now
it's a requirement in order for the model change-observation to pick up
all changes.
If an existing filter is statefull, it can be flagged as such but keep in
mind that this will result in a significant performance-penalty (or rather
lost opportunity to benefit from a major perf improvement) that will
affect the $digest duration.
To flag a filter as stateful do the following:
myApp.filter('myFilter', function() {
function myFilter(input) { ... };
myFilter.$stateful = true;
return myFilter;
});
Closes#9006Closes#9082
The 'src` (i.e. the url of the template to load) is now provided to the
`$includeContentRequested`, `$includeContentLoaded` and `$includeContentError`
events.
Closes#8453Closes#8454
'@'-bindings were previously updating the scope when they ought to have been
updating the controller (requested via `bindToController: true` + controllerAs).
It's a one-line fix + test case.
Closes#9052Closes#9077
jqLite doesn't override the default implementation of event.stopImmediatePropagation()
and so it doesn't work as expected, i.e, it doesn't prevent the rest of the event
handlers from being executed.
Closes#4833
Fixes regression where the `assign()` method was not added to chains of identifiers in CSP mode,
introduced originally in b3b476d.
Also fixes the $parse test suite to ensure that CSP code paths are taken when they're expected to be
taken.
Closes#9048
Previously, if you bound a `Date` object to `<input type="time">`,
whenever you changed the time, the day, month, and year fields of
the new resulting bound `Date` object would be reset. Now fields
not modified by bound time input elements are copied to the new
resulting object.
Same for input types of `month`, `week`, etc.
Closes#6666
Calling `ctrl.$setValidity()` with a an error key that
does not belong to a validator in `ctrl.$validator` should
not result in setting the model to `undefined` on the next
input change. This bug was introduced in 1.3.0-beta.12.
Closes#8357Fixes#8080
This option allows to write invalid values to the model instead of having them become undefined.
Use this together with calling `ctrl.$setValidity` directly for displaying errors
from serverside validation.
Closes#8290Closes#8313
If the view value changed in the first digest and there are async validators,
the view value was never applied to the model after the validators were
resolved. Only important for tests.
- define `ngModelGet` and `ngModelSet` to already use
the getter/setter semantics, so the rest of the code does
not need to care about it.
- remove `ctrl.$$invalidModelValue` to simplify the internal logic
This reverts commit 6d1e7cdc51.
This commit was causing breakages because of its assumption that transcluded
content would be handled predictably, i.e. with ngTransclude, whereas many
use cases involve manipulating transcluded content in linking functions.
Fix the following exploit:
hasOwnProperty.constructor.prototype.valueOf = valueOf.call;
["a", "alert(1)"].sort(hasOwnProperty.constructor);
The exploit:
• 1. Array.sort takes a comparison function and passes it 2 parameters to compare.
2. It then calls .valueOf() if the result is not a primitive.
• The Function object conveniently accepts two string arguments so we can use this
to construct a function. However, this doesn't do much unless we can execute it.
• We set the valueOf function on Function.prototype to Function.prototype.call.
This causes the function that we constructed to be executed when sort calls
.valueOf() on the result of the comparison.
The fix is in two parts.
• Disallow passing unsafe objects to function calls as parameters.
• Do not traverse the Function object when setting a path.
It is now possible for ngInclude to correctly load SVG content in non-blink browsers, which do not
sort out the namespace when parsing HTML.
Closes#7538Closes#8981Closes#8997
During the recent refactoring a typo was made that broke code that detects if we are
already removed from the DOM (animation has completed).
Closes#8918Closes#8994
The previous logic for async validation in
`ngModelController` and `formController` was not maintainable:
- control logic is in multiple parts, e.g. `ctrl.$setValidity`
waits for end of promises and continuous the control flow
for async validation
- logic for updating the flags `ctrl.$error`, `ctrl.$pending`, `ctrl.$valid`
is super complicated, especially in `formController`
This refactoring makes the following changes:
- simplify async validation: centralize control logic
into one method in `ngModelController`:
* remove counters `invalidCount` and `pendingCount`
* use a flag `currentValidationRunId` to separate
async validator runs from each other
* use `$q.all` to determine when all async validators are done
- centralize way how `ctrl.$modelValue` and `ctrl.$invalidModelValue`
is updated
- simplify `ngModelController/formCtrl.$setValidity` and merge
`$$setPending/$$clearControlValidity/$$clearValidity/$$clearPending`
into one method, that is used by `ngModelController` AND
`formController`
* remove diff calculation, always calculate the correct state anew,
only cache the css classes that have been set to not
trigger too many css animations.
* remove fields from `ctrl.$error` that are valid and add private `ctrl.$$success`:
allows to correctly separate states for valid, invalid, skipped and pending,
especially transitively across parent forms.
- fix bug in `ngModelController`:
* only read out `input.validity.badInput`, but not
`input.validity.typeMismatch`,
to determine parser error: We still want our `email`
validator to run event when the model is validated.
- fix bugs in tests that were found as the logic is now consistent between
`ngModelController` and `formController`
BREAKING CHANGE:
- `ctrl.$error` does no more contain entries for validators that were
successful.
- `ctrl.$setValidity` now differentiates between `true`, `false`,
`undefined` and `null`, instead of previously only truthy vs falsy.
Closes#8941