Previously, domain parts which began with or ended with a dash, would be accepted as valid. This CL matches Angular's email validation with that of Chromium and Firefox.
Closes#6026
Previously, properties (typically functions) in the prototype chain (Object.prototype) would shadow
query parameters, and cause them to be serialized incorrectly.
This CL guards against this by using hasOwnProperty() to ensure that only own properties are a concern.
Closes#8070Fixes#8068
If `$validate` is invoked when the model is already invalid, `$validate`
should pass `$$invalidModelValue` to the validators, not `$modelValue`.
Moreover, if `$validate` is invoked and it is found that the invalid model
has become valid, this previously invalid model should be assigned to
`$modelValue`.
Lastly, if `$validate` is invoked and it is found that the model has
become invalid, the previously valid model should be assigned to
`$$invalidModelValue`.
Closes#7836Closes#7837
Use the new options from the reporter to add more logging to end to end tests,
and increase the Jasmine test timeout from 30 seconds to 60 seconds to allow for
legitimately long-lasting tests.
ngTrueValue and ngFalseValue now support parsed expressions which the parser determines to be constant values.
BREAKING CHANGE:
Previously, these attributes would always be treated as strings. However, they are now parsed as
expressions, and will throw if an expression is non-constant.
To convert non-constant strings into constant expressions, simply wrap them in an extra pair of quotes, like so:
<input type="checkbox" ng-model="..." ng-true-value="'truthyValue'">
Closes#8041Closes#5346Closes#1199
When multiple classes are added/removed in parallel then $animate only closes off the
last animation when the fallback timer has expired. Now all animations are closed off.
Fixes#7766
Currently it is possible to use `ngModelOptions` to pend model updates until form is submitted, but in case the user wants to reset the form back to its original values he must call `$rollbackViewValue` on each input control in the form. This commit adds a `$rollbackViewValue` on the form controller in order to make this operation easier, similarly to `$commitViewValue`.
Closes#7595
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;