Commit Graph

1987 Commits

Author SHA1 Message Date
Lucas Galfaso
6303c3dcf6 fix($compile): Resolve leak with asynchronous compilation
Stop an asynchronous compilation when this is performed on an
already destroyed scope

Closes #9199
Closes #9079
Closes #8504
Closes #9197
2014-09-29 12:47:21 +01:00
Lucas Galfaso
cd2cfafcab refactor($scope): prevent multiple calls to listener on $destroy
Prevent isolated scopes from having listeners that get called
multiple times when on `$destroy`
2014-09-29 12:41:36 +01:00
Georgios Kalpakas
eb935e6be0 test($http): fix typo in spec name
'applyAapply' -> 'applyAsync'.

Closes #9323
2014-09-28 20:33:05 -04:00
Jason Bedard
b119251827 perf($rootScope): moving internal queues out of the Scope instances
Closes #9071
2014-09-27 08:19:15 -07:00
Jason Bedard
5572b40b15 refactor($parse): change 'this' to a $parse keyword instead of scope field
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
2014-09-27 08:13:14 -07:00
Peter Bacon Darwin
fb0c77f0b6 fix($compile): connect transclude scopes to their containing scope to prevent memory leaks
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 #9095
Closes #9281
2014-09-26 21:38:17 +01:00
Peter Bacon Darwin
6417a3e9eb feat(Scope): allow the parent of a new scope to be specified on creation
This enables us to place transclude scopes more accurately in the scope hierarchy.
2014-09-26 21:38:02 +01:00
Caitlin Potter
07e3abc7dd feat($compile): optionally get controllers from ancestors only
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 #4518
Closes #4540
Closes #8240
Closes #8511
2014-09-26 16:32:26 -04:00
Michał Gołębiowski
8202c4dcea chore(Angular): drop support for Opera < 15
Closes #8589
2014-09-26 11:32:11 -07:00
Georgios Kalpakas
a8fe2cc345 test(input): test that number validates with unspecified viewValue
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
2014-09-25 09:53:45 -04:00
Caitlin Potter
b9e899c8b2 test(ngModel): rename test to better reflect what is being tested
I meant to do this in before 92f05e5a59 landed, sorry u_u
2014-09-24 18:04:37 -04:00
Caitlin Potter
92f05e5a59 fix(ngModel): do not parse undefined viewValue when validating
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 #9106
Closes #9260
2014-09-24 18:00:20 -04:00
Caitlin Potter
729c238e19 feat(input): support dynamic element validation
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 #4791
Closes #1404
2014-09-23 16:03:53 -04:00
Jeff Cross
dc3de7fb7a feat($location): add ability to opt-out of <base/> tag requirement in html5Mode
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
2014-09-23 11:34:24 -07:00
Shahar Talmi
fd8997551f feat(formController): add $setUntouched to propagate untouched state
Closes #9050
2014-09-23 13:48:39 -04:00
Shahar Talmi
4b83f6ca2c fix(ngModel): support milliseconds in time and datetime
Closes #8874
2014-09-22 14:50:08 -07:00
Rouven Weßling
a591e8b8d3 perf(map): use Array.prototype.map
Replace helper functions with the native ES5 method
2014-09-22 14:09:48 -07:00
Brian Ford
ad28baaa6c refactor(ngAria): bind to ngModel rather than form types 2014-09-19 15:31:48 -07:00
Ciro Nunes
f0ee335311 test(injector): allow service names with a single underscore
Closes #9024
2014-09-19 22:24:48 +01:00
Subra
d1434c999a feat(ngAria): add an ngAria module to make a11y easier
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
2014-09-18 16:17:14 -07:00
Brian Ford
4627410245 fix(select): update option labels when model changes
Closes #9025
2014-09-16 12:36:05 -07:00
Jason Bedard
fca6be7127 perf($parse): execute watched expressions only when the inputs change
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 #9006
Closes #9082
2014-09-16 14:12:58 +02:00
Stephen Bunch
fd2d6c02f9 feat(ngInclude): add template url parameter to events
The 'src` (i.e. the url of the template to load) is now provided to the
`$includeContentRequested`, `$includeContentLoaded` and `$includeContentError`
events.

Closes #8453
Closes #8454
2014-09-16 12:25:33 +01:00
Caitlin Potter
e7ac08a061 fix($compile): update '@'-bindings in controller when bindToController is true
'@'-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 #9052
Closes #9077
2014-09-14 12:12:15 -04:00
Michael Benford
7ffe524171 test(jqLite): Refactor test for isDefaultPrevent
Refactor the spec for isDefaultPrevent method so it fails if the
existing expectations aren't executed.
2014-09-13 15:11:54 -05:00
Michael Benford
30354c58fe fix(jqLite): fix event.stopImmediatePropagation() so it works as expected
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
2014-09-13 15:11:49 -05:00
Caitlin Potter
d13b4bd1f5 fix($parse): ensure CSP assignable expressions have assign()
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
2014-09-12 14:47:58 -04:00
Caitlin Potter
a3962f0df3 fix(ngResource): make badcfg error message more helpful
The error message should help identify the problem. To do so, more details need to be provided.

Closes #9005
Closes #9010
2014-09-10 18:31:08 -04:00
Reuben Doetsch
1c8a7459c9 feat(limitTo): support numeric input to limitTo
Closes #8926
2014-09-10 15:19:30 -07:00
Brian Ford
1a1ef62903 fix(ngModel): do not reset bound date objects
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
2014-09-10 14:19:28 -07:00
Tobias Bosch
3e51b84bc1 fix(input): always pass in the model value to ctrl.$isEmpty
Fixes #5164
Closes #9017
2014-09-10 11:45:36 -07:00
Jason Bedard
56f09f0b44 perf($compile): move $$isolateBinding creation to directive factory instead of on each link 2014-09-10 11:29:17 -07:00
Tobias Bosch
9314719d1e fix(ngModel): don’t clear the model when an external validator failed
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 #8357
Fixes #8080
2014-09-10 11:16:42 -07:00
Shahar Talmi
3c538c1d21 feat(ngModelOptions): add allowInvalid option
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 #8290
Closes #8313
2014-09-09 13:48:17 -07:00
Tobias Bosch
64c3b745fb fix(ngModel): update model value with async validators correctly
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.
2014-09-09 13:46:28 -07:00
Tobias Bosch
f94d551529 fix(ngModel): render immediately also with async validators 2014-09-09 13:46:28 -07:00
Tobias Bosch
9ad7d745ab refactor(ngModel): remove $$invalidModelValue and refactor methods
- 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
2014-09-09 13:46:24 -07:00
Jason Bedard
b3b476db7d perf($parse): remove getterFn wrapper for internal use
Closes #8901
2014-09-09 22:15:23 +02:00
Jeff Cross
06fa2868de revert: "fix($compile): render nested transclusion at the root of a template"
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.
2014-09-09 11:05:34 -07:00
Chirayu Krishnappa
bd8ad0fbe8 fix($parse): disallow passing Function to Array.sort
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.
2014-09-09 10:39:39 -07:00
Caitlin Potter
6639ca9d6b fix(ngInclude): correctly add svg-namespaced template content
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 #7538
Closes #8981
Closes #8997
2014-09-09 12:45:15 -04:00
Igor Minar
ed63733000 fix(ngRepeat): preserve original position of elements that are being animated away
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 #8918
Closes #8994
2014-09-09 16:19:47 +02:00
Igor Minar
f33a938545 chore(testabilityPatch): fix the dump fn so that it works with karma's debug.html 2014-09-09 16:19:47 +02:00
Igor Minar
01ef12884b test(animateSpec): remove unused variables 2014-09-09 16:19:46 +02:00
Igor Minar
732d72d991 test(ngRepeat): move an existing test into the right describe block 2014-09-09 16:19:46 +02:00
Tobias Bosch
6046e14bd2 refactor(ngModelController,formController): centralize and simplify logic
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
2014-09-08 15:10:02 -07:00
Jason Bedard
df9e60c8e7 feat(angular.forEach): add the array/object as the 3rd param like the native array forEach
Closes #7902
2014-09-08 17:06:16 +02:00
Shahar Talmi
e322cd9b3b fix(ngModelOptions): do not trigger digest on setViewValue if debouncing
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 #8814
Closes #8850
Closes #8911
2014-09-05 20:15:34 +01:00
Caitlin Potter
b3b672130d fix(ngAnimate): support removing classes from SVG elements when using jQuery
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 #8872
Closes #8893
2014-09-05 13:51:17 -04:00
Vitali Tsevan
cbdaabfb59 fix(orderBy): allow arrayLike objects to be ordered
Closes #8944
2014-09-05 11:56:09 +01:00