By default ngAnimate prevents child animations from running when a parent is performing an animation.
However there are a cases when an application should allow all child animations to run without blocking
each other. By placing the `ng-animate-children` flag in the template, this effect can now be put to
use within the template.
Closes#7946
BREAKING CHANGE:
You can no longer invoke .bind, .call or .apply on a function in angular expressions.
This is to disallow changing the behaviour of existing functions
in an unforseen fashion.
__proto__ can be used to mess with global prototypes and it's
deprecated. Therefore, blacklisting it seems like a good idea.
BREAKING CHANGE:
The (deprecated) __proto__ propery does not work inside angular expressions
anymore.
It was possible to use `{}.__defineGetter__.call(null, 'alert', (0).valueOf.bind(0))` to set
`window.alert` to a false-ish value, thereby breaking the `isWindow` check, which might lead
to arbitrary code execution in browsers that let you obtain the window object using Array methods.
Prevent that by blacklisting the nasty __{define,lookup}{Getter,Setter}__ properties.
BREAKING CHANGE:
This prevents the use of __{define,lookup}{Getter,Setter}__ inside angular
expressions. If you really need them for some reason, please wrap/bind them to make them
less dangerous, then make them available through the scope object.
It was possible to run arbitrary JS from inside angular expressions using the
`Object.getOwnPropertyDescriptor` method like this since commit 4ab16aaa:
''.sub.call.call(
({})["constructor"].getOwnPropertyDescriptor(''.sub.__proto__, "constructor").value,
null,
"alert(1)"
)()
Fix that by blocking access to `Object` because `Object` isn't accessible
without tricks anyway and it provides some other nasty functions.
BREAKING CHANGE:
This prevents the use of `Object` inside angular expressions.
If you need Object.keys, make it accessible in the scope.
Commit 1d2414c introduced a regression by retrieving the statusText
of an aborted xhr request. This breaks IE9, which throws a c00c023f
error when accessing properties of an aborted xhr request. The fix
is similar to the one in commit 6f1050d.
So far, angular.copy was copying all properties including those from
prototype chain and was losing the whole prototype chain (except for Date,
Regexp, and Array).
Deep copy should exclude properties from the prototype chain because it
is useless to do so. When modified, properties from prototype chain are
overwritten on the object itself and will be deeply copied then.
Moreover, preserving prototype chain allows instanceof operator to be
consistent between the source object and the copy.
Before this change,
var Foo = function() {};
var foo = new Foo();
var fooCopy = angular.copy(foo);
foo instanceof Foo; // => true
fooCopy instanceof Foo; // => false
Now,
foo instanceof Foo; // => true
fooCopy instanceof Foo; // => true
The new behaviour is useful when using $http transformResponse. When
receiving JSON data, we could transform it and instantiate real object
"types" from it. The transformed response is always copied by Angular.
The old behaviour was losing the whole prototype chain and broke all
"types" from third-party libraries depending on instanceof.
Closes#5063Closes#3767Closes#4996
BREAKING CHANGE:
This changes `angular.copy` so that it applies the prototype of the original
object to the copied object. Previously, `angular.copy` would copy properties
of the original object's prototype chain directly onto the copied object.
This means that if you iterate over only the copied object's `hasOwnProperty`
properties, it will no longer contain the properties from the prototype.
This is actually much more reasonable behaviour and it is unlikely that
applications are actually relying on this.
If this behaviour is relied upon, in an app, then one should simply iterate
over all the properties on the object (and its inherited properties) and
not filter them with `hasOwnProperty`.
**Be aware that this change also uses a feature that is not compatible with
IE8.** If you need this to work on IE8 then you would need to provide a polyfill
for `Object.create` and `Object.getPrototypeOf`.
triggerHandler sends dummy events to an element, but although the event includes the preventDefault method, there is no way to see if it was called for the event. This is sometimes important when testing directives that use preventDefault
Closes#8008
$evalAsync triggers a digest, and is unsuitable when it is expected that a digest should not occur.
BREAKING CHANGE
Previously, even if invokeApply was set to false, a $rootScope digest would occur during promise
resolution. This is no longer the case, as promises returned from $timeout and $interval will no
longer trigger $evalAsync (which in turn causes a $digest) if `invokeApply` is false.
Workarounds include manually triggering $scope.$apply(), or returning $q.defer().promise from a
promise callback, and resolving or rejecting it when appropriate.
var interval = $interval(function() {
if (someRequirementFulfilled) {
$interval.cancel(interval);
$scope.$apply();
}
}, 100, 0, false);
or:
var interval = $interval(function (idx) {
// make the magic happen
}, 1000, 10, false);
interval.then(function(idx) {
var deferred = $q.defer();
// do the asynchronous magic --- $evalAsync will cause a digest and cause
// bindings to update.
return deferred.promise;
});
Closes#7999Closes#7103
The shortcut was dropped because it had a lot of unkowns about PATCH.
Since we already know that using PATCH is good
(http://www.mnot.net/blog/2012/09/05/patch), and only IE8 has issues with that,
let's add the shortcut back.
Closes#5894
So far Angular have used the toBoolean function to decide if the parsed value
is truthy. The function made more values falsy than regular JavaScript would,
e.g. strings 'f' and 'no' were both treated as falsy. This creates suble bugs
when backend sends a non-empty string with one of these values and something
suddenly hides in the application
Thanks to lgalfaso for test ideas.
BREAKING CHANGE: values 'f', '0', 'false', 'no', 'n', '[]' are no longer
treated as falsy. Only JavaScript falsy values are now treated as falsy by the
expression parser; there are six of them: false, null, undefined, NaN, 0 and "".
Closes#3969Closes#4277Closes#7960
Calling `jqLite.data()` on a disallowed node type caused an empty object to be added to the
cache. This could lead to memory leaks since we no longer clean up such node types when they are
removed from the DOM.
Closes#7966
We were attaching handlers to comment nodes when setting up bound transclusion
functions. But we don't clean up comments and text nodes when deallocating so
there was a memory leak.
Closes#7913Closes#7942
If an element contains two "element" transcludes then the initial clone
consists of only comment nodes. The concern was that this meant that
the transclude scopes would not be cleaned up.
But it turns out that in the case that there are only comments then the
scope is never attached to anything so we don't need to worry about cleaning
it up.
Later if a concrete element is created as part of the transclude then these
elements will have destroy handlers.
This CL improves mocking support for HTML5 validation, and ensures that it works correctly along
with debounced commission of view values.
Closes#7936Closes#7937
ngRequired added to an email field wasn't working properly. ng-invalid-required
stayed true unless a valid email was entered.
correct behaviour is that it turns to ng-valid-required at first entered key.
Closes#7849
Change HashMap to give $$hashKey also for functions so it will be possible to load multiple module
function instances. In order to prevent problem in angular's test suite, added an option to HashMap
to maintain its own id counter and added cleanup of $$hashKey from all module functions after each
test.
Before this CL, functions were added to the HashMap via toString(), which could potentially return
the same value for different actual instances of a function. This corrects this behaviour by
ensuring that functions are mapped with hashKeys, and ensuring that hashKeys are removed from
functions and objects at the end of tests.
In addition to these changes, the injector uses its own set of UIDs in order to prevent confusingly
breaking tests which expect scopes or ng-repeated items to have specific hash keys.
Closes#7255
Previously, <element ng-attr-foo="{{binding}}" foo="bar"></element>'s "foo" attribute would always
equal "bar", because the bound version was overwritten. This CL corrects this behaviour and ensures
that the ordering of attributes does not have an effect on whether or not ng-attr-bound attributes
do their work.
Closes#7739
Previously non-object literals would be thrown out of Resource responses with isArray===true, or
otherwise converted into Objects (in the case of string literals). The reason for this is because
shallowClearAndCopy iterates over keys, and copies keys into the destination. Iterating over String
keys results in integer keys, with a single-character value.
Not converting non-objects to Resources means that you lose the ability to perform Resource operations
on them. However, they become usable as strings, numbers, or booleans, which is important.
In the future, it would be useful to make these useful as Resources while still retaining their primitive
value usefulness.
Closes#6314Closes#7741
In apps that create lots of scopes (apps with large tables) the uid generation
shows up in the profiler and adds a few milliseconds. Using simple counter
doesn't have this overhead.
I think the initial fear of overflowing and thus using string alphanum sequence
is unjustified because even if an app was to create lots of scopes non-stop,
you could create about 28.6 million scopes per seconds for 10 years before
you would reach a number that can't be accurately represented in JS
BREAKING CHANGE: Scope#$id is now of time number rather than string. Since the
id is primarily being used for debugging purposes this change should not affect
anyone.
If a "replace" directive has an async template, which contains a transclusion
directive at its root node, then outer transclusions were failing to be
passed to this directive. An example would be uses of `ngIf` inside and
outside the template.
Collaborated with @caitp
Closes#7183Closes#7772
When the pattern and ng-pattern attributes are used with an input element
containing a ngModel directive then they should both use the same validator
and the validation errors of the model should be placed on model.$error.pattern.
BREAKING CHANGE:
If an expression is used on ng-pattern (such as `ng-pattern="exp"`) or on the
pattern attribute (something like on `pattern="{{ exp }}"`) and the expression
itself evaluates to a string then the validator will not parse the string as a
literal regular expression object (a value like `/abc/i`). Instead, the entire
string will be created as the regular expression to test against. This means
that any expression flags will not be placed on the RegExp object. To get around
this limitation, use a regular expression object as the value for the expression.
//before
$scope.exp = '/abc/i';
//after
$scope.exp = /abc/i;
Change the error message for a circular dependency to display the full
circle back to the first service being instantiated, so that the problem
is obvious. The previous message stopped one dependency short of the full
circle.
Changes the content of the cdep error message, which may be considered
a breaking change.
Closes#7500
$http was previously checking cookies to find an xsrf-token prior to checking
the cache. This caused a performance penalty of about 2ms, which can be very
significant when loading hundreds of template instances on a page.
Fixes#7717
Sets the ngModel controller property $touched to True and $untouched to False whenever a 'blur' event is triggered over a control with the ngModel directive.
Also adds the $setTouched and $setUntouched methods to the NgModelController.
References #583
Previously, the compiler would throw an error if a directive requested new non-isolate scope
after a directive had requested isolate scope. But it would not error if a directive
requested an isolate scope after a directive had requested a new non-isolate scope.
Since it is invalid to have more than one directive request any kind of scope if one of
them has requested isolate scope, then the compiler should error whatever order the
directives are applied.
This fix addresses this situation by throwing error regardless of order of directives.
BREAKING CHANGE:
Requesting isolate scope and any other scope on a single element is an error.
Before this change, the compiler let two directives request a child scope
and an isolate scope if the compiler applied them in the order of non-isolate
scope directive followed by isolate scope directive.
Now the compiler will error regardless of the order.
If you find that your code is now throwing a `$compile:multidir` error,
check that you do not have directives on the same element that are trying
to request both an isolate and a non-isolate scope and fix your code.
Closes#4402Closes#4421
This adds a scope event notification when a template fails to load.
This can have performance implications, and unfortunately cannot at this moment
be terminated with preventDefault(). But it's nice to be notified when problems
occur!
Closes#5803
When an observer is set to listen on the pattern, minlength or maxlength attributes
via $attrs then the observer will also listen on the ngPattern, ngMinlength and the
ngMaxlength attributes as well.
Closes#7758