angularjs-rails 1.2.25 → 1.2.26

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 22a02c7166df12ce4d4bba554f460a9364498e95
4
- data.tar.gz: 357db766a4b59bc5bcd83ef50d348f46dfce73e5
3
+ metadata.gz: edc80934126c7bb8e08926262373f206bddf9ad0
4
+ data.tar.gz: 22c50ed2a0f707116afb01e01b7e0290565bebf8
5
5
  SHA512:
6
- metadata.gz: 266734323960a9c09bdbaed3ba4504481446db1fa95f68f88c780ae62fec2d19c68500d32e126c2851e6b9ae9305d5bdd4e1a8464a4b97c453a4e881a6cbd2c5
7
- data.tar.gz: 9d0ac0816788e21338ce9d812ff33e830d8303c4783de146a20b6a48ef44532fdec92ef77b545ed6cc1c8b1e4b9a727097d3cb8385c52af076150cf69d9469cd
6
+ metadata.gz: 10b94b7f399eef907f3cbbef83bc0ffe1f961334b23b9d498f03f9a213d91577b47cc92f883efe2da1ab762728dbb478ac09845d477ad850f8e1ccf46c04f236
7
+ data.tar.gz: 7c4af8a50c83d720781394c49862756896832d3c5dcd66b0eced5934ae95f3ffce1b17cdbb437bc636da2a590c9dccbcb8ce20e78fae3a4c89047b65d390fac4
@@ -1,6 +1,6 @@
1
1
  module AngularJS
2
2
  module Rails
3
- VERSION = "1.2.25"
4
- UNSTABLE_VERSION = "1.3.0-rc.3"
3
+ VERSION = "1.2.26"
4
+ UNSTABLE_VERSION = "1.3.0-rc.5"
5
5
  end
6
6
  end
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.2.25
2
+ * @license AngularJS v1.2.26
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.2.25
2
+ * @license AngularJS v1.2.26
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.2.25
2
+ * @license AngularJS v1.2.26
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -69,7 +69,7 @@ function minErr(module) {
69
69
  return match;
70
70
  });
71
71
 
72
- message = message + '\nhttp://errors.angularjs.org/1.2.25/' +
72
+ message = message + '\nhttp://errors.angularjs.org/1.2.26/' +
73
73
  (module ? module + '/' : '') + code;
74
74
  for (i = 2; i < arguments.length; i++) {
75
75
  message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.2.25
2
+ * @license AngularJS v1.2.26
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.2.25
2
+ * @license AngularJS v1.2.26
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.2.25
2
+ * @license AngularJS v1.2.26
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -270,9 +270,6 @@ function $RouteProvider(){
270
270
  * This example shows how changing the URL hash causes the `$route` to match a route against the
271
271
  * URL, and the `ngView` pulls in the partial.
272
272
  *
273
- * Note that this example is using {@link ng.directive:script inlined templates}
274
- * to get it working on jsfiddle as well.
275
- *
276
273
  * <example name="$route-service" module="ngRouteExample"
277
274
  * deps="angular-route.js" fixBase="true">
278
275
  * <file name="index.html">
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.2.25
2
+ * @license AngularJS v1.2.26
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -9790,7 +9790,7 @@ if ( typeof module === "object" && module && typeof module.exports === "object"
9790
9790
  })( window );
9791
9791
 
9792
9792
  /**
9793
- * @license AngularJS v1.2.25
9793
+ * @license AngularJS v1.2.26
9794
9794
  * (c) 2010-2014 Google, Inc. http://angularjs.org
9795
9795
  * License: MIT
9796
9796
  */
@@ -9860,7 +9860,7 @@ function minErr(module) {
9860
9860
  return match;
9861
9861
  });
9862
9862
 
9863
- message = message + '\nhttp://errors.angularjs.org/1.2.25/' +
9863
+ message = message + '\nhttp://errors.angularjs.org/1.2.26/' +
9864
9864
  (module ? module + '/' : '') + code;
9865
9865
  for (i = 2; i < arguments.length; i++) {
9866
9866
  message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
@@ -10209,7 +10209,7 @@ function setHashKey(obj, h) {
10209
10209
  * @kind function
10210
10210
  *
10211
10211
  * @description
10212
- * Extends the destination object `dst` by copying all of the properties from the `src` object(s)
10212
+ * Extends the destination object `dst` by copying own enumerable properties from the `src` object(s)
10213
10213
  * to `dst`. You can specify multiple `src` objects.
10214
10214
  *
10215
10215
  * @param {Object} dst Destination object.
@@ -11779,11 +11779,11 @@ function setupModuleLoader(window) {
11779
11779
  * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
11780
11780
  */
11781
11781
  var version = {
11782
- full: '1.2.25', // all of these placeholder strings will be replaced by grunt's
11782
+ full: '1.2.26', // all of these placeholder strings will be replaced by grunt's
11783
11783
  major: 1, // package task
11784
11784
  minor: 2,
11785
- dot: 25,
11786
- codeName: 'hypnotic-gesticulation'
11785
+ dot: 26,
11786
+ codeName: 'captivating-disinterest'
11787
11787
  };
11788
11788
 
11789
11789
 
@@ -15321,7 +15321,7 @@ function $TemplateCacheProvider() {
15321
15321
  * }
15322
15322
  * ```
15323
15323
  *
15324
- * Below is an example using `$compileProvider`.
15324
+ * ## Example
15325
15325
  *
15326
15326
  * <div class="alert alert-warning">
15327
15327
  * **Note**: Typically directives are registered with `module.directive`. The example below is
@@ -17829,12 +17829,13 @@ function $HttpProvider() {
17829
17829
  expect(data.getText()).toMatch(/Hello, \$http!/);
17830
17830
  });
17831
17831
 
17832
- it('should make a JSONP request to angularjs.org', function() {
17833
- sampleJsonpBtn.click();
17834
- fetchBtn.click();
17835
- expect(status.getText()).toMatch('200');
17836
- expect(data.getText()).toMatch(/Super Hero!/);
17837
- });
17832
+ // Commented out due to flakes. See https://github.com/angular/angular.js/issues/9185
17833
+ // it('should make a JSONP request to angularjs.org', function() {
17834
+ // sampleJsonpBtn.click();
17835
+ // fetchBtn.click();
17836
+ // expect(status.getText()).toMatch('200');
17837
+ // expect(data.getText()).toMatch(/Super Hero!/);
17838
+ // });
17838
17839
 
17839
17840
  it('should make JSONP request to invalid URL and invoke the error handler',
17840
17841
  function() {
@@ -25177,9 +25178,9 @@ var uppercaseFilter = valueFn(uppercase);
25177
25178
  }]);
25178
25179
  </script>
25179
25180
  <div ng-controller="ExampleController">
25180
- Limit {{numbers}} to: <input type="integer" ng-model="numLimit">
25181
+ Limit {{numbers}} to: <input type="number" step="1" ng-model="numLimit">
25181
25182
  <p>Output numbers: {{ numbers | limitTo:numLimit }}</p>
25182
- Limit {{letters}} to: <input type="integer" ng-model="letterLimit">
25183
+ Limit {{letters}} to: <input type="number" step="1" ng-model="letterLimit">
25183
25184
  <p>Output letters: {{ letters | limitTo:letterLimit }}</p>
25184
25185
  </div>
25185
25186
  </file>
@@ -25196,14 +25197,15 @@ var uppercaseFilter = valueFn(uppercase);
25196
25197
  expect(limitedLetters.getText()).toEqual('Output letters: abc');
25197
25198
  });
25198
25199
 
25199
- it('should update the output when -3 is entered', function() {
25200
- numLimitInput.clear();
25201
- numLimitInput.sendKeys('-3');
25202
- letterLimitInput.clear();
25203
- letterLimitInput.sendKeys('-3');
25204
- expect(limitedNumbers.getText()).toEqual('Output numbers: [7,8,9]');
25205
- expect(limitedLetters.getText()).toEqual('Output letters: ghi');
25206
- });
25200
+ // There is a bug in safari and protractor that doesn't like the minus key
25201
+ // it('should update the output when -3 is entered', function() {
25202
+ // numLimitInput.clear();
25203
+ // numLimitInput.sendKeys('-3');
25204
+ // letterLimitInput.clear();
25205
+ // letterLimitInput.sendKeys('-3');
25206
+ // expect(limitedNumbers.getText()).toEqual('Output numbers: [7,8,9]');
25207
+ // expect(limitedLetters.getText()).toEqual('Output letters: ghi');
25208
+ // });
25207
25209
 
25208
25210
  it('should not exceed the maximum size of input array', function() {
25209
25211
  numLimitInput.clear();
@@ -28605,6 +28607,7 @@ var ngCloakDirective = ngDirective({
28605
28607
  *
28606
28608
  * @element ANY
28607
28609
  * @scope
28610
+ * @priority 500
28608
28611
  * @param {expression} ngController Name of a globally accessible constructor function or an
28609
28612
  * {@link guide/expression expression} that on the current scope evaluates to a
28610
28613
  * constructor function. The controller instance can be published into a scope property
@@ -31717,6 +31720,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
31717
31720
  id: option.id,
31718
31721
  selected: option.selected
31719
31722
  });
31723
+ selectCtrl.addOption(option.label, element);
31720
31724
  if (lastElement) {
31721
31725
  lastElement.after(element);
31722
31726
  } else {
@@ -31728,7 +31732,9 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
31728
31732
  // remove any excessive OPTIONs in a group
31729
31733
  index++; // increment since the existingOptions[0] is parent element not OPTION
31730
31734
  while(existingOptions.length > index) {
31731
- existingOptions.pop().element.remove();
31735
+ option = existingOptions.pop();
31736
+ selectCtrl.removeOption(option.label);
31737
+ option.element.remove();
31732
31738
  }
31733
31739
  }
31734
31740
  // remove any excessive OPTGROUPs from select
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.2.25
2
+ * @license AngularJS v1.2.26
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.2.25
2
+ * @license AngularJS v1.2.26
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -68,7 +68,7 @@ function minErr(module) {
68
68
  return match;
69
69
  });
70
70
 
71
- message = message + '\nhttp://errors.angularjs.org/1.2.25/' +
71
+ message = message + '\nhttp://errors.angularjs.org/1.2.26/' +
72
72
  (module ? module + '/' : '') + code;
73
73
  for (i = 2; i < arguments.length; i++) {
74
74
  message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
@@ -417,7 +417,7 @@ function setHashKey(obj, h) {
417
417
  * @kind function
418
418
  *
419
419
  * @description
420
- * Extends the destination object `dst` by copying all of the properties from the `src` object(s)
420
+ * Extends the destination object `dst` by copying own enumerable properties from the `src` object(s)
421
421
  * to `dst`. You can specify multiple `src` objects.
422
422
  *
423
423
  * @param {Object} dst Destination object.
@@ -1987,11 +1987,11 @@ function setupModuleLoader(window) {
1987
1987
  * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
1988
1988
  */
1989
1989
  var version = {
1990
- full: '1.2.25', // all of these placeholder strings will be replaced by grunt's
1990
+ full: '1.2.26', // all of these placeholder strings will be replaced by grunt's
1991
1991
  major: 1, // package task
1992
1992
  minor: 2,
1993
- dot: 25,
1994
- codeName: 'hypnotic-gesticulation'
1993
+ dot: 26,
1994
+ codeName: 'captivating-disinterest'
1995
1995
  };
1996
1996
 
1997
1997
 
@@ -5529,7 +5529,7 @@ function $TemplateCacheProvider() {
5529
5529
  * }
5530
5530
  * ```
5531
5531
  *
5532
- * Below is an example using `$compileProvider`.
5532
+ * ## Example
5533
5533
  *
5534
5534
  * <div class="alert alert-warning">
5535
5535
  * **Note**: Typically directives are registered with `module.directive`. The example below is
@@ -8037,12 +8037,13 @@ function $HttpProvider() {
8037
8037
  expect(data.getText()).toMatch(/Hello, \$http!/);
8038
8038
  });
8039
8039
 
8040
- it('should make a JSONP request to angularjs.org', function() {
8041
- sampleJsonpBtn.click();
8042
- fetchBtn.click();
8043
- expect(status.getText()).toMatch('200');
8044
- expect(data.getText()).toMatch(/Super Hero!/);
8045
- });
8040
+ // Commented out due to flakes. See https://github.com/angular/angular.js/issues/9185
8041
+ // it('should make a JSONP request to angularjs.org', function() {
8042
+ // sampleJsonpBtn.click();
8043
+ // fetchBtn.click();
8044
+ // expect(status.getText()).toMatch('200');
8045
+ // expect(data.getText()).toMatch(/Super Hero!/);
8046
+ // });
8046
8047
 
8047
8048
  it('should make JSONP request to invalid URL and invoke the error handler',
8048
8049
  function() {
@@ -15385,9 +15386,9 @@ var uppercaseFilter = valueFn(uppercase);
15385
15386
  }]);
15386
15387
  </script>
15387
15388
  <div ng-controller="ExampleController">
15388
- Limit {{numbers}} to: <input type="integer" ng-model="numLimit">
15389
+ Limit {{numbers}} to: <input type="number" step="1" ng-model="numLimit">
15389
15390
  <p>Output numbers: {{ numbers | limitTo:numLimit }}</p>
15390
- Limit {{letters}} to: <input type="integer" ng-model="letterLimit">
15391
+ Limit {{letters}} to: <input type="number" step="1" ng-model="letterLimit">
15391
15392
  <p>Output letters: {{ letters | limitTo:letterLimit }}</p>
15392
15393
  </div>
15393
15394
  </file>
@@ -15404,14 +15405,15 @@ var uppercaseFilter = valueFn(uppercase);
15404
15405
  expect(limitedLetters.getText()).toEqual('Output letters: abc');
15405
15406
  });
15406
15407
 
15407
- it('should update the output when -3 is entered', function() {
15408
- numLimitInput.clear();
15409
- numLimitInput.sendKeys('-3');
15410
- letterLimitInput.clear();
15411
- letterLimitInput.sendKeys('-3');
15412
- expect(limitedNumbers.getText()).toEqual('Output numbers: [7,8,9]');
15413
- expect(limitedLetters.getText()).toEqual('Output letters: ghi');
15414
- });
15408
+ // There is a bug in safari and protractor that doesn't like the minus key
15409
+ // it('should update the output when -3 is entered', function() {
15410
+ // numLimitInput.clear();
15411
+ // numLimitInput.sendKeys('-3');
15412
+ // letterLimitInput.clear();
15413
+ // letterLimitInput.sendKeys('-3');
15414
+ // expect(limitedNumbers.getText()).toEqual('Output numbers: [7,8,9]');
15415
+ // expect(limitedLetters.getText()).toEqual('Output letters: ghi');
15416
+ // });
15415
15417
 
15416
15418
  it('should not exceed the maximum size of input array', function() {
15417
15419
  numLimitInput.clear();
@@ -18813,6 +18815,7 @@ var ngCloakDirective = ngDirective({
18813
18815
  *
18814
18816
  * @element ANY
18815
18817
  * @scope
18818
+ * @priority 500
18816
18819
  * @param {expression} ngController Name of a globally accessible constructor function or an
18817
18820
  * {@link guide/expression expression} that on the current scope evaluates to a
18818
18821
  * constructor function. The controller instance can be published into a scope property
@@ -21925,6 +21928,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
21925
21928
  id: option.id,
21926
21929
  selected: option.selected
21927
21930
  });
21931
+ selectCtrl.addOption(option.label, element);
21928
21932
  if (lastElement) {
21929
21933
  lastElement.after(element);
21930
21934
  } else {
@@ -21936,7 +21940,9 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
21936
21940
  // remove any excessive OPTIONs in a group
21937
21941
  index++; // increment since the existingOptions[0] is parent element not OPTION
21938
21942
  while(existingOptions.length > index) {
21939
- existingOptions.pop().element.remove();
21943
+ option = existingOptions.pop();
21944
+ selectCtrl.removeOption(option.label);
21945
+ option.element.remove();
21940
21946
  }
21941
21947
  }
21942
21948
  // remove any excessive OPTGROUPs from select
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.3.0-rc.3
2
+ * @license AngularJS v1.3.0-rc.5
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -227,7 +227,7 @@
227
227
  *
228
228
  * ### CSS Staggering Animations
229
229
  * A Staggering animation is a collection of animations that are issued with a slight delay in between each successive operation resulting in a
230
- * curtain-like effect. The ngAnimate module, as of 1.2.0, supports staggering animations and the stagger effect can be
230
+ * curtain-like effect. The ngAnimate module (versions >=1.2) supports staggering animations and the stagger effect can be
231
231
  * performed by creating a **ng-EVENT-stagger** CSS class and attaching that class to the base CSS class used for
232
232
  * the animation. The style property expected within the stagger class can either be a **transition-delay** or an
233
233
  * **animation-delay** property (or both if your animation contains both transitions and keyframe animations).
@@ -383,6 +383,7 @@ angular.module('ngAnimate', ['ng'])
383
383
  var forEach = angular.forEach;
384
384
  var selectors = $animateProvider.$$selectors;
385
385
  var isArray = angular.isArray;
386
+ var isString = angular.isString;
386
387
 
387
388
  var ELEMENT_NODE = 1;
388
389
  var NG_ANIMATE_STATE = '$$ngAnimateState';
@@ -473,34 +474,32 @@ angular.module('ngAnimate', ['ng'])
473
474
  return defer.promise;
474
475
  }
475
476
 
477
+ function parseAnimateOptions(options) {
478
+ // some plugin code may still be passing in the callback
479
+ // function as the last param for the $animate methods so
480
+ // it's best to only allow string or array values for now
481
+ if (isArray(options)) return options;
482
+ if (isString(options)) return [options];
483
+ }
484
+
476
485
  function resolveElementClasses(element, cache, runningAnimations) {
477
486
  runningAnimations = runningAnimations || {};
478
- var map = {};
479
-
480
- forEach(cache.add, function(className) {
481
- if (className && className.length) {
482
- map[className] = map[className] || 0;
483
- map[className]++;
484
- }
485
- });
486
-
487
- forEach(cache.remove, function(className) {
488
- if (className && className.length) {
489
- map[className] = map[className] || 0;
490
- map[className]--;
491
- }
492
- });
493
487
 
494
- var lookup = [];
488
+ var lookup = {};
495
489
  forEach(runningAnimations, function(data, selector) {
496
490
  forEach(selector.split(' '), function(s) {
497
491
  lookup[s]=data;
498
492
  });
499
493
  });
500
494
 
495
+ var hasClasses = Object.create(null);
496
+ forEach((element.attr('class') || '').split(/\s+/), function(className) {
497
+ hasClasses[className] = true;
498
+ });
499
+
501
500
  var toAdd = [], toRemove = [];
502
- forEach(map, function(status, className) {
503
- var hasClass = angular.$$hasClass(element[0], className);
501
+ forEach(cache.classes, function(status, className) {
502
+ var hasClass = hasClasses[className];
504
503
  var matchingAnimation = lookup[className] || {};
505
504
 
506
505
  // When addClass and removeClass is called then $animate will check to
@@ -511,12 +510,12 @@ angular.module('ngAnimate', ['ng'])
511
510
  // Once an animation is allowed then the code will also check to see if
512
511
  // there exists any on-going animation that is already adding or remvoing
513
512
  // the matching CSS class.
514
- if (status < 0) {
513
+ if (status === false) {
515
514
  //does it have the class or will it have the class
516
515
  if (hasClass || matchingAnimation.event == 'addClass') {
517
516
  toRemove.push(className);
518
517
  }
519
- } else if (status > 0) {
518
+ } else if (status === true) {
520
519
  //is the class missing or will it be removed?
521
520
  if (!hasClass || matchingAnimation.event == 'removeClass') {
522
521
  toAdd.push(className);
@@ -800,7 +799,8 @@ angular.module('ngAnimate', ['ng'])
800
799
  * @param {DOMElement} afterElement the sibling element (which is the previous element) of the element that will be the focus of the enter animation
801
800
  * @return {Promise} the animation callback promise
802
801
  */
803
- enter : function(element, parentElement, afterElement) {
802
+ enter : function(element, parentElement, afterElement, options) {
803
+ options = parseAnimateOptions(options);
804
804
  element = angular.element(element);
805
805
  parentElement = prepareElement(parentElement);
806
806
  afterElement = prepareElement(afterElement);
@@ -808,7 +808,7 @@ angular.module('ngAnimate', ['ng'])
808
808
  classBasedAnimationsBlocked(element, true);
809
809
  $delegate.enter(element, parentElement, afterElement);
810
810
  return runAnimationPostDigest(function(done) {
811
- return performAnimation('enter', 'ng-enter', stripCommentsFromElement(element), parentElement, afterElement, noop, done);
811
+ return performAnimation('enter', 'ng-enter', stripCommentsFromElement(element), parentElement, afterElement, noop, options, done);
812
812
  });
813
813
  },
814
814
 
@@ -842,16 +842,16 @@ angular.module('ngAnimate', ['ng'])
842
842
  * @param {DOMElement} element the element that will be the focus of the leave animation
843
843
  * @return {Promise} the animation callback promise
844
844
  */
845
- leave : function(element) {
845
+ leave : function(element, options) {
846
+ options = parseAnimateOptions(options);
846
847
  element = angular.element(element);
847
848
 
848
849
  cancelChildAnimations(element);
849
850
  classBasedAnimationsBlocked(element, true);
850
- this.enabled(false, element);
851
851
  return runAnimationPostDigest(function(done) {
852
852
  return performAnimation('leave', 'ng-leave', stripCommentsFromElement(element), null, null, function() {
853
853
  $delegate.leave(element);
854
- }, done);
854
+ }, options, done);
855
855
  });
856
856
  },
857
857
 
@@ -888,7 +888,8 @@ angular.module('ngAnimate', ['ng'])
888
888
  * @param {DOMElement} afterElement the sibling element (which is the previous element) of the element that will be the focus of the move animation
889
889
  * @return {Promise} the animation callback promise
890
890
  */
891
- move : function(element, parentElement, afterElement) {
891
+ move : function(element, parentElement, afterElement, options) {
892
+ options = parseAnimateOptions(options);
892
893
  element = angular.element(element);
893
894
  parentElement = prepareElement(parentElement);
894
895
  afterElement = prepareElement(afterElement);
@@ -897,7 +898,7 @@ angular.module('ngAnimate', ['ng'])
897
898
  classBasedAnimationsBlocked(element, true);
898
899
  $delegate.move(element, parentElement, afterElement);
899
900
  return runAnimationPostDigest(function(done) {
900
- return performAnimation('move', 'ng-move', stripCommentsFromElement(element), parentElement, afterElement, noop, done);
901
+ return performAnimation('move', 'ng-move', stripCommentsFromElement(element), parentElement, afterElement, noop, options, done);
901
902
  });
902
903
  },
903
904
 
@@ -930,8 +931,8 @@ angular.module('ngAnimate', ['ng'])
930
931
  * @param {string} className the CSS class that will be added to the element and then animated
931
932
  * @return {Promise} the animation callback promise
932
933
  */
933
- addClass : function(element, className) {
934
- return this.setClass(element, className, []);
934
+ addClass : function(element, className, options) {
935
+ return this.setClass(element, className, [], options);
935
936
  },
936
937
 
937
938
  /**
@@ -963,8 +964,8 @@ angular.module('ngAnimate', ['ng'])
963
964
  * @param {string} className the CSS class that will be animated and then removed from the element
964
965
  * @return {Promise} the animation callback promise
965
966
  */
966
- removeClass : function(element, className) {
967
- return this.setClass(element, [], className);
967
+ removeClass : function(element, className, options) {
968
+ return this.setClass(element, [], className, options);
968
969
  },
969
970
 
970
971
  /**
@@ -994,33 +995,68 @@ angular.module('ngAnimate', ['ng'])
994
995
  * CSS classes have been set on the element
995
996
  * @return {Promise} the animation callback promise
996
997
  */
997
- setClass : function(element, add, remove) {
998
+ setClass : function(element, add, remove, options) {
999
+ options = parseAnimateOptions(options);
1000
+
998
1001
  var STORAGE_KEY = '$$animateClasses';
999
1002
  element = angular.element(element);
1000
1003
  element = stripCommentsFromElement(element);
1001
1004
 
1002
1005
  if (classBasedAnimationsBlocked(element)) {
1003
- return $delegate.setClass(element, add, remove);
1006
+ // TODO(@caitp/@matsko): Don't use private/undocumented API here --- we should not be
1007
+ // changing the DOM synchronously in this case. The `true` parameter must eventually be
1008
+ // removed.
1009
+ return $delegate.setClass(element, add, remove, true);
1010
+ }
1011
+
1012
+ // we're using a combined array for both the add and remove
1013
+ // operations since the ORDER OF addClass and removeClass matters
1014
+ var classes, cache = element.data(STORAGE_KEY);
1015
+ var hasCache = !!cache;
1016
+ if (!cache) {
1017
+ cache = {};
1018
+ cache.classes = {};
1004
1019
  }
1020
+ classes = cache.classes;
1005
1021
 
1006
1022
  add = isArray(add) ? add : add.split(' ');
1023
+ forEach(add, function(c) {
1024
+ if (c && c.length) {
1025
+ classes[c] = true;
1026
+ }
1027
+ });
1028
+
1007
1029
  remove = isArray(remove) ? remove : remove.split(' ');
1030
+ forEach(remove, function(c) {
1031
+ if (c && c.length) {
1032
+ classes[c] = false;
1033
+ }
1034
+ });
1008
1035
 
1009
- var cache = element.data(STORAGE_KEY);
1010
- if (cache) {
1011
- cache.add = cache.add.concat(add);
1012
- cache.remove = cache.remove.concat(remove);
1036
+ if (hasCache) {
1037
+ if (options && cache.options) {
1038
+ cache.options = cache.options.concat(options);
1039
+ }
1013
1040
 
1014
1041
  //the digest cycle will combine all the animations into one function
1015
1042
  return cache.promise;
1016
1043
  } else {
1017
1044
  element.data(STORAGE_KEY, cache = {
1018
- add : add,
1019
- remove : remove
1045
+ classes : classes,
1046
+ options : options
1020
1047
  });
1021
1048
  }
1022
1049
 
1023
1050
  return cache.promise = runAnimationPostDigest(function(done) {
1051
+ var parentElement = element.parent();
1052
+ var elementNode = extractElementNode(element);
1053
+ var parentNode = elementNode.parentNode;
1054
+ // TODO(matsko): move this code into the animationsDisabled() function once #8092 is fixed
1055
+ if (!parentNode || parentNode['$$NG_REMOVED'] || elementNode['$$NG_REMOVED']) {
1056
+ done();
1057
+ return;
1058
+ }
1059
+
1024
1060
  var cache = element.data(STORAGE_KEY);
1025
1061
  element.removeData(STORAGE_KEY);
1026
1062
 
@@ -1028,9 +1064,10 @@ angular.module('ngAnimate', ['ng'])
1028
1064
  var classes = resolveElementClasses(element, cache, state.active);
1029
1065
  return !classes
1030
1066
  ? done()
1031
- : performAnimation('setClass', classes, element, null, null, function() {
1032
- $delegate.setClass(element, classes[0], classes[1]);
1033
- }, done);
1067
+ : performAnimation('setClass', classes, element, parentElement, null, function() {
1068
+ if (classes[0]) $delegate.$$addClassImmediately(element, classes[0]);
1069
+ if (classes[1]) $delegate.$$removeClassImmediately(element, classes[1]);
1070
+ }, cache.options, done);
1034
1071
  });
1035
1072
  },
1036
1073
 
@@ -1092,7 +1129,7 @@ angular.module('ngAnimate', ['ng'])
1092
1129
  CSS code. Element, parentElement and afterElement are provided DOM elements for the animation
1093
1130
  and the onComplete callback will be fired once the animation is fully complete.
1094
1131
  */
1095
- function performAnimation(animationEvent, className, element, parentElement, afterElement, domOperation, doneCallback) {
1132
+ function performAnimation(animationEvent, className, element, parentElement, afterElement, domOperation, options, doneCallback) {
1096
1133
 
1097
1134
  var noopCancel = noop;
1098
1135
  var runner = animationRunner(element, animationEvent, className);
@@ -1200,6 +1237,11 @@ angular.module('ngAnimate', ['ng'])
1200
1237
  //the ng-animate class does nothing, but it's here to allow for
1201
1238
  //parent animations to find and cancel child animations when needed
1202
1239
  element.addClass(NG_ANIMATE_CLASS_NAME);
1240
+ if (isArray(options)) {
1241
+ forEach(options, function(className) {
1242
+ element.addClass(className);
1243
+ });
1244
+ }
1203
1245
 
1204
1246
  var localAnimationCount = globalAnimationCounter++;
1205
1247
  totalActiveAnimations++;
@@ -1269,8 +1311,15 @@ angular.module('ngAnimate', ['ng'])
1269
1311
  function closeAnimation() {
1270
1312
  if (!closeAnimation.hasBeenRun) {
1271
1313
  closeAnimation.hasBeenRun = true;
1314
+ if (isArray(options)) {
1315
+ forEach(options, function(className) {
1316
+ element.removeClass(className);
1317
+ });
1318
+ }
1319
+
1272
1320
  var data = element.data(NG_ANIMATE_STATE);
1273
1321
  if (data) {
1322
+
1274
1323
  /* only structural animations wait for reflow before removing an
1275
1324
  animation, but class-based animations don't. An example of this
1276
1325
  failing would be when a parent HTML tag has a ng-class attribute
@@ -1425,6 +1474,16 @@ angular.module('ngAnimate', ['ng'])
1425
1474
  var parentCounter = 0;
1426
1475
  var animationReflowQueue = [];
1427
1476
  var cancelAnimationReflow;
1477
+ function clearCacheAfterReflow() {
1478
+ if (!cancelAnimationReflow) {
1479
+ cancelAnimationReflow = $$animateReflow(function() {
1480
+ animationReflowQueue = [];
1481
+ cancelAnimationReflow = null;
1482
+ lookupCache = {};
1483
+ });
1484
+ }
1485
+ }
1486
+
1428
1487
  function afterReflow(element, callback) {
1429
1488
  if (cancelAnimationReflow) {
1430
1489
  cancelAnimationReflow();
@@ -1525,7 +1584,7 @@ angular.module('ngAnimate', ['ng'])
1525
1584
 
1526
1585
  function parseMaxTime(str) {
1527
1586
  var maxValue = 0;
1528
- var values = angular.isString(str) ?
1587
+ var values = isString(str) ?
1529
1588
  str.split(/\s*,\s*/) :
1530
1589
  [];
1531
1590
  forEach(values, function(value) {
@@ -1770,6 +1829,7 @@ angular.module('ngAnimate', ['ng'])
1770
1829
  //to perform at all
1771
1830
  var preReflowCancellation = animateBefore(animationEvent, element, className);
1772
1831
  if (!preReflowCancellation) {
1832
+ clearCacheAfterReflow();
1773
1833
  animationComplete();
1774
1834
  return;
1775
1835
  }
@@ -1826,6 +1886,7 @@ angular.module('ngAnimate', ['ng'])
1826
1886
  afterReflow(element, animationCompleted);
1827
1887
  return cancellationMethod;
1828
1888
  }
1889
+ clearCacheAfterReflow();
1829
1890
  animationCompleted();
1830
1891
  },
1831
1892
 
@@ -1835,6 +1896,7 @@ angular.module('ngAnimate', ['ng'])
1835
1896
  afterReflow(element, animationCompleted);
1836
1897
  return cancellationMethod;
1837
1898
  }
1899
+ clearCacheAfterReflow();
1838
1900
  animationCompleted();
1839
1901
  },
1840
1902
 
@@ -1844,6 +1906,7 @@ angular.module('ngAnimate', ['ng'])
1844
1906
  afterReflow(element, animationCompleted);
1845
1907
  return cancellationMethod;
1846
1908
  }
1909
+ clearCacheAfterReflow();
1847
1910
  animationCompleted();
1848
1911
  },
1849
1912