Conditionally adds various aria attributes to the built in directives.
This module currently hooks into ng-show/hide, input, textarea and
button as a basic level of support for a11y.
Closes#5486 and #1600
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
Note that this change means that anyone watching `$viewValue` will have to
wait for a new digest before they are aware that it has been updated.
Closes#8814Closes#8850Closes#8911
Fixes a regression in ngAnimate introduced in 2f4437b3, whereby SVG elements would not be able to
have classes removed by ngAnimate methods when jQuery was loaded (without also including libraries
which patch jQuery to support SVG elements, such as jquery-svgdom.js).
This fix exports jqLiteHasClass as a private method `$$hasClass` on the `angular` global object,
which enables ngAnimate to use this SVG-safe method for testing if the class is available.
Closes#8872Closes#8893
Due to the nature of how date objects are rendered when JSON.stringify
is called, the resulting string contains two sets of quotes surrounding
it. This commit fixes that issue.
Closes#6755
With this fix ngModel will treat ngMin as a min error and ngMax as a max error.
This also means that when either of these two values is changed then ngModel will
revaliate itself.
As of this fix if the max or min value is changed via scope or by another ngModel
then it will trigger the model containing the min/max attributes to revalidate itself.
Closes#2404
Previously when a negative number was rounded to 0 by the number filter
it would be formated as a negative number. This means something like
{{ -0.01 | number: 1 }} would output -0.0. Now it will ouput 0.0
instead.
Closes#8489
You must now pass `keys` to the function in a config object.
This bug in the test became apparent because in newer browsers, arrays
have a function called `keys()` and this was causing browserTrigger to
fail. Previously it was quietly passing this test despite being wrong.
Calling `$$clearControlValidity` on the parent of a nested form caused the parent form
to look like there are no more errors on the nested form even if it still had some
inputs with errors. there is no need to call this method recursively since `$setValidity`
will propagate the new validity state well enough.
Closes#8863
BREAKING CHANGE:
Ever since 0df93fd, tagged in v1.0.0rc1, the ngSwitch directive has had an undocumented `change`
attribute, used for evaluating a scope expression when the switch value changes.
While it's unlikely, applications which may be using this feature should work around the removal
by adding a custom directive which will perform the eval instead. Directive controllers are
re-instantiated when being transcluded, so by putting the attribute on each item that you want
to be notified of a change to, you can more or less emulate the old behaviour.
Example:
```js
angular.module("switchChangeWorkaround", []).
directive("onSwitchChanged", function() {
return {
linke: function($scope, $attrs) {
$scope.$parent.$eval($attrs.change);
}
};
});
```
```html
<div ng-switch="switcher">
<div ng-switch-when="a" on-switch-changed="doSomethingInParentScope()"></div>
<div ng-switch-when="b" on-switch-changed="doSomethingInParentScope()"></div>
</div>
```
Closes#8858Closes#8822
Set the default value for the base tag in the mock browser to `/`,
as we now always require a base tag to be present for html5 mode.
Fixes#8866Closes#8889
BREAKING CHANGE (since 1.2.0 and 1.3.0-beta.1):
Angular now requires a `<base>` tag when html5 mode of `$location` is enabled. Reasoning:
Using html5 mode without a `<base href="...">` tag makes relative links for images, links, ...
relative to the current url if the browser supports
the history API. However, if the browser does not support the history API Angular falls back to using the `#`,
and then all those relative links would be broken.
The `<base>` tag is also needed when a deep url is loaded from the server, e.g. `http://server/some/page/url`.
In that case, Angular needs to decide which part of the url is the base of the application, and which part
is path inside of the application.
To summarize: Now all relative links are always relative to the `<base>` tag.
Exception (also a breaking change):
Link tags whose `href` attribute starts with a `#` will only change the hash of the url, but nothing else
(e.g. `<a href="#someAnchor">`). This is to make it easy to scroll to anchors inside a document.
Related to #6162Closes#8492
BREAKING CHANGE (since 1.2.17 and 1.3.0-beta.10):
In html5 mode without a `<base>` tag on older browser that don't support the history API
relative paths were adding up. E.g. clicking on `<a href="page1">` and then on `<a href="page2">`
would produce `$location.path()==='/page1/page2'. The code that introduced this behavior was removed
and Angular now also requires a `<base>` tag to be present when using html5 mode.
Closes#8172, #8233