IE10/11 have the following problem: When changing the url hash
via `history.pushState()` and then reverting the hash via direct
changes to `location.href` (or via a link) does not fire a
`hashchange` nor `popstate` event.
This commit changes the default behavior as follows:
Uses `location.href`/`location.replace` if the new url differs from
the previous url only in the hash fragment or the browser
does not support history API.
Use `history.pushState`/ `history.replaceState` otherwise.
Fixes#9143Closes#9406
This fixes the case when a directive that uses `templateUrl`
is used somewhere in the children
of a transcluding directive like `ng-repeat`.
Fixes#9344
Related to #8808Closes#9415
Because the regex that tests the `require` value will match more than just `^^?`,
it is important to test other common ways to specify a controller requirement
to ensure that a breaking change isn't introduced inadvertently. This adds a test
for `?^^`.
Closes#9389Closes#9390
Previously, builtin parsers/formatters for e.g. `input[date]`
or `input[number]` were added in the post linking phase to `ngModelController`,
which in most cases was after a custom formatter/parser was registered.
This commit registers builtin parsers/formatters already
in the pre linking phase. With that builtin
parsers run first, and builtin formatters run last.
Closes#9218Closes#9358
Similar to `input[number]` Angular will throw if the model value
for a `input[date]` is not a `Date` object.
For `Invalid Date`s (dates whose `getTime()` is `NaN`) `input[date]`
will render an empty string.
Closes#8949Closes#9375
the tracking depended on a local flag variable, which was susceptible to corruption due to
race conditions.
using promises ensures that the previousLeaveAnimation is nulled out only if it hasn't been
canceled yet.
Closes#9355Closes#7606Closes#9374
Prevent accidentally treating a builtin function from Object.prototype as the binding object, and thus
preventing the compiler from throwing when using attribute binding names which match a property of the
Object prototype.
Closes#9343Closes#9345
BREAKING CHANGE:
- $scope['this'] no longer exits on the $scope object
- $parse-ed expressions no longer allow chaining 'this' such as this['this'] or $parent['this']
- 'this' in $parse-ed expressions can no longer be overriden, if a variable named 'this' is put on the scope it must be accessed using this['this']
Closes#9105
Transcluded scopes are now connected to the scope in which they are created
via their `$parent` property. This means that they will be automatically destroyed
when their "containing" scope is destroyed, without having to resort to listening
for a `$destroy` event on various DOM elements or other scopes.
Previously, transclude scope not only inherited prototypically from the scope from
which they were transcluded but they were also still owned by that "outer" scope.
This meant that there were scenarios where the "real" container scope/element was
destroyed but the transclude scope was not, leading to memory leaks.
The original strategy for dealing with this was to attach a `$destroy` event handler
to the DOM elements in the transcluded content, so that if the elements were removed
from the DOM then their associated transcluded scope would be destroyed.
This didn't work for transclude contents that didn't contain any elements - most
importantly in the case of the transclude content containing an element transclude
directive at its root, since the compiler swaps out this element for a comment
before a destroy handler could be attached.
BREAKING CHANGE:
`$transclude` functions no longer attach `$destroy` event handlers to the
transcluded content, and so the associated transclude scope will not automatically
be destroyed if you remove a transcluded element from the DOM using direct DOM
manipulation such as the jquery `remove()` method.
If you want to explicitly remove DOM elements inside your directive that have
been compiled, and so potentially contain child (and transcluded) scopes, then
it is your responsibility to get hold of the scope and destroy it at the same time.
The suggested approach is to create a new child scope of your own around any DOM
elements that you wish to manipulate in this way and destroy those scopes if you
remove their contents - any child scopes will then be destroyed and cleaned up
automatically.
Note that all the built-in directives that manipulate the DOM (ngIf, ngRepeat,
ngSwitch, etc) already follow this best practice, so if you only use these for
manipulating the DOM then you do not have to worry about this change.
Closes#9095Closes#9281
Implement option to strengthen require '^' operator, by adding another '^'.
When a second '^' is used, the controller will only search parent nodes for the
matching controller, and will throw or return null if not found, depending on
whether or not the requirement is optional.
Closes#4518Closes#4540Closes#8240Closes#8511
Adds an additional test verifying that a number which is not required will validate successfully
when ngModelCtrl.$validate() is called. Before 92f05e5 landed, this would have failed because of
a parse error.
Closes#9193
Previously, if a viewValue had not yet been set on the element, it could incorrectly produce a
parse error.
This change prevents the parsers from running if a view value has not yet been committed.
Closes#9106Closes#9260
Interpolates the form and form control attribute name, so that dynamic form controls (such as those
rendered in an ngRepeat) will always have their expected interpolated name.
The control will be present in its parent form controller with the interpolated property name, and
this name can change when the interpolated value changes.
Closes#4791Closes#1404
This feature allows disabling Angular's requirement of using a <base/> tag
when using location in html5Mode, for applications that do not require
using $location in html5Mode in IE9. To accomplish this, the $locationProvider.html5Mode
method has been changed to accept a definition object which can optionally set a
requireBase property to false, removing the requirement of a <base> tag being present
when html5Mode is enabled.
BREAKING CHANGE: The $location.html5Mode API has changed to allow enabling html5Mode by
passing an object (as well as still supporting passing a boolean). Symmetrically, the
method now returns an object instead of a boolean value.
To migrate, follow the code example below:
Before:
var mode = $locationProvider.html5Mode();
After:
var mode = $locationProvider.html5Mode().enabled;
Fixes#8934
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.