rails-angularjs 1.4.0.pre.rc.1 → 1.4.0.pre.rc.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rails-angularjs/version.rb +1 -1
  3. data/vendor/assets/javascripts/angular-animate.js +247 -159
  4. data/vendor/assets/javascripts/angular-animate.min.js +45 -44
  5. data/vendor/assets/javascripts/angular-animate.min.js.map +3 -3
  6. data/vendor/assets/javascripts/angular-aria.js +1 -1
  7. data/vendor/assets/javascripts/angular-aria.min.js +1 -1
  8. data/vendor/assets/javascripts/angular-cookies.js +1 -1
  9. data/vendor/assets/javascripts/angular-cookies.min.js +1 -1
  10. data/vendor/assets/javascripts/angular-loader.js +2 -2
  11. data/vendor/assets/javascripts/angular-loader.min.js +2 -2
  12. data/vendor/assets/javascripts/angular-message-format.js +1 -1
  13. data/vendor/assets/javascripts/angular-message-format.min.js +1 -1
  14. data/vendor/assets/javascripts/angular-messages.js +1 -1
  15. data/vendor/assets/javascripts/angular-messages.min.js +1 -1
  16. data/vendor/assets/javascripts/angular-mocks.js +1 -1
  17. data/vendor/assets/javascripts/angular-resource.js +3 -3
  18. data/vendor/assets/javascripts/angular-resource.min.js +8 -8
  19. data/vendor/assets/javascripts/angular-resource.min.js.map +1 -1
  20. data/vendor/assets/javascripts/angular-route.js +1 -1
  21. data/vendor/assets/javascripts/angular-route.min.js +1 -1
  22. data/vendor/assets/javascripts/angular-sanitize.js +1 -1
  23. data/vendor/assets/javascripts/angular-sanitize.min.js +1 -1
  24. data/vendor/assets/javascripts/angular-scenario.js +316 -143
  25. data/vendor/assets/javascripts/angular-touch.js +12 -10
  26. data/vendor/assets/javascripts/angular-touch.min.js +8 -8
  27. data/vendor/assets/javascripts/angular-touch.min.js.map +2 -2
  28. data/vendor/assets/javascripts/angular.js +316 -143
  29. data/vendor/assets/javascripts/angular.min.js +267 -265
  30. data/vendor/assets/javascripts/angular.min.js.map +3 -3
  31. metadata +2 -3
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.4.0-rc.1
2
+ * @license AngularJS v1.4.0-rc.2
3
3
  * (c) 2010-2015 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -21,6 +21,7 @@ var isElement = angular.isElement;
21
21
  var ELEMENT_NODE = 1;
22
22
  var COMMENT_NODE = 8;
23
23
 
24
+ var NG_ANIMATE_CLASSNAME = 'ng-animate';
24
25
  var NG_ANIMATE_CHILDREN_DATA = '$$ngAnimateChildren';
25
26
 
26
27
  var isPromiseLike = function(p) {
@@ -77,18 +78,29 @@ function removeFromArray(arr, val) {
77
78
  }
78
79
 
79
80
  function stripCommentsFromElement(element) {
80
- if (element.nodeType === ELEMENT_NODE) {
81
- return jqLite(element);
81
+ if (element instanceof jqLite) {
82
+ switch (element.length) {
83
+ case 0:
84
+ return [];
85
+ break;
86
+
87
+ case 1:
88
+ // there is no point of stripping anything if the element
89
+ // is the only element within the jqLite wrapper.
90
+ // (it's important that we retain the element instance.)
91
+ if (element[0].nodeType === ELEMENT_NODE) {
92
+ return element;
93
+ }
94
+ break;
95
+
96
+ default:
97
+ return jqLite(extractElementNode(element));
98
+ break;
99
+ }
82
100
  }
83
- if (element.length === 0) return [];
84
101
 
85
- // there is no point of stripping anything if the element
86
- // is the only element within the jqLite wrapper.
87
- // (it's important that we retain the element instance.)
88
- if (element.length === 1) {
89
- return element[0].nodeType === ELEMENT_NODE && element;
90
- } else {
91
- return jqLite(extractElementNode(element));
102
+ if (element.nodeType === ELEMENT_NODE) {
103
+ return jqLite(element);
92
104
  }
93
105
  }
94
106
 
@@ -240,6 +252,10 @@ function resolveElementClasses(existing, toAdd, toRemove) {
240
252
  return classes;
241
253
  }
242
254
 
255
+ function getDomNode(element) {
256
+ return (element instanceof angular.element) ? element[0] : element;
257
+ }
258
+
243
259
  var $$AnimateChildrenDirective = [function() {
244
260
  return function(scope, element, attrs) {
245
261
  var val = attrs.ngAnimateChildren;
@@ -293,16 +309,11 @@ var $$AnimateChildrenDirective = [function() {
293
309
  * return {
294
310
  * enter: function(element, doneFn) {
295
311
  * var height = element[0].offsetHeight;
296
- * var animation = $animateCss(element, {
312
+ * return $animateCss(element, {
297
313
  * from: { height:'0px' },
298
314
  * to: { height:height + 'px' },
299
315
  * duration: 1 // one second
300
316
  * });
301
- *
302
- * // if no possible animation can be triggered due
303
- * // to the combination of options then `animation`
304
- * // will be returned as undefined
305
- * animation.start().done(doneFn);
306
317
  * }
307
318
  * }
308
319
  * }]);
@@ -325,18 +336,13 @@ var $$AnimateChildrenDirective = [function() {
325
336
  * return {
326
337
  * enter: function(element, doneFn) {
327
338
  * var height = element[0].offsetHeight;
328
- * var animation = $animateCss(element, {
339
+ * return $animateCss(element, {
329
340
  * addClass: 'red large-text pulse-twice',
330
341
  * easing: 'ease-out',
331
342
  * from: { height:'0px' },
332
343
  * to: { height:height + 'px' },
333
344
  * duration: 1 // one second
334
345
  * });
335
- *
336
- * // if no possible animation can be triggered due
337
- * // to the combination of options then `animation`
338
- * // will be returned as undefined
339
- * animation.start().done(doneFn);
340
346
  * }
341
347
  * }
342
348
  * }]);
@@ -376,10 +382,11 @@ var $$AnimateChildrenDirective = [function() {
376
382
  * styles using the `from` and `to` properties.
377
383
  *
378
384
  * ```js
379
- * var animation = $animateCss(element, {
385
+ * var animator = $animateCss(element, {
380
386
  * from: { background:'red' },
381
387
  * to: { background:'blue' }
382
388
  * });
389
+ * animator.start();
383
390
  * ```
384
391
  *
385
392
  * ```css
@@ -412,10 +419,10 @@ var $$AnimateChildrenDirective = [function() {
412
419
  * added and removed on the element). Once `$animateCss` is called it will return an object with the following properties:
413
420
  *
414
421
  * ```js
415
- * var animation = $animateCss(element, { ... });
422
+ * var animator = $animateCss(element, { ... });
416
423
  * ```
417
424
  *
418
- * Now what do the contents of our `animation` variable look like:
425
+ * Now what do the contents of our `animator` variable look like:
419
426
  *
420
427
  * ```js
421
428
  * {
@@ -432,26 +439,14 @@ var $$AnimateChildrenDirective = [function() {
432
439
  * applied to the element during the preparation phase). Note that all other properties such as duration, delay, transitions and keyframes are just properties
433
440
  * and that changing them will not reconfigure the parameters of the animation.
434
441
  *
435
- * By calling `animation.start()` we do get back a promise, however, due to the nature of animations we may not want to tap into the default behaviour of
436
- * animations (since they cause a digest to occur which may slow down the animation performance-wise). Therefore instead of calling `then` to capture when
437
- * the animation ends be sure to call `done(callback)` (this is the recommended way to use `$animateCss` within JavaScript-animations).
438
- *
439
- * The example below should put this into perspective:
442
+ * ### runner.done() vs runner.then()
443
+ * It is documented that `animation.start()` will return a promise object and this is true, however, there is also an additional method available on the
444
+ * runner called `.done(callbackFn)`. The done method works the same as `.finally(callbackFn)`, however, it does **not trigger a digest to occur**.
445
+ * Therefore, for performance reasons, it's always best to use `runner.done(callback)` instead of `runner.then()`, `runner.catch()` or `runner.finally()`
446
+ * unless you really need a digest to kick off afterwards.
440
447
  *
441
- * ```js
442
- * var animation = $animateCss(element, { ... });
443
- *
444
- * // remember that if there is no CSS animation detected on the element
445
- * // then the value returned from $animateCss will be null
446
- * if (animation) {
447
- * animation.start().done(function() {
448
- * // yaay the animation is over
449
- * doneCallback();
450
- * });
451
- * } else {
452
- * doneCallback();
453
- * }
454
- * ```
448
+ * Keep in mind that, to make this easier, ngAnimate has tweaked the JS animations API to recognize when a runner instance is returned from $animateCss
449
+ * (so there is no need to call `runner.done(doneFn)` inside of your JavaScript animation code). Check the [animation code above](#usage) to see how this works.
455
450
  *
456
451
  * @param {DOMElement} element the element that will be animated
457
452
  * @param {object} options the animation-related options that will be applied during the animation
@@ -477,7 +472,7 @@ var $$AnimateChildrenDirective = [function() {
477
472
  * `stagger` option value of `0.1` is used then there will be a stagger delay of `600ms`)
478
473
  * `applyClassesEarly` - Whether or not the classes being added or removed will be used when detecting the animation. This is set by `$animate` when enter/leave/move animations are fired to ensure that the CSS classes are resolved in time. (Note that this will prevent any transitions from occuring on the classes being added and removed.)
479
474
  *
480
- * @return {null|object} an object with a start method and details about the animation. If no animation is detected then a value of `null` will be returned.
475
+ * @return {object} an object with start and end methods and details about the animation.
481
476
  *
482
477
  * * `start` - The method to start the animation. This will return a `Promise` when called.
483
478
  * * `end` - This method will cancel the animation and remove all applied CSS classes and styles.
@@ -726,7 +721,7 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
726
721
  return stagger || {};
727
722
  }
728
723
 
729
- var bod = $document[0].body;
724
+ var bod = getDomNode($document).body;
730
725
  var cancelLastRAFRequest;
731
726
  var rafWaitQueue = [];
732
727
  function waitUntilQuiet(callback) {
@@ -775,7 +770,7 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
775
770
  }
776
771
 
777
772
  function init(element, options) {
778
- var node = element[0];
773
+ var node = getDomNode(element);
779
774
  options = prepareAnimationOptions(options);
780
775
 
781
776
  var temporaryStyles = [];
@@ -792,8 +787,7 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
792
787
  var maxDurationTime;
793
788
 
794
789
  if (options.duration === 0 || (!$sniffer.animations && !$sniffer.transitions)) {
795
- close();
796
- return;
790
+ return closeAndReturnNoopAnimator();
797
791
  }
798
792
 
799
793
  var method = options.event && isArray(options.event)
@@ -840,8 +834,7 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
840
834
  // there is no way we can trigger an animation since no styles and
841
835
  // no classes are being applied which would then trigger a transition
842
836
  if (!hasToStyles && !setupClasses) {
843
- close();
844
- return false;
837
+ return closeAndReturnNoopAnimator();
845
838
  }
846
839
 
847
840
  var cacheKey, stagger;
@@ -936,8 +929,7 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
936
929
  }
937
930
 
938
931
  if (maxDuration === 0 && !flags.recalculateTimingStyles) {
939
- close();
940
- return false;
932
+ return closeAndReturnNoopAnimator();
941
933
  }
942
934
 
943
935
  // we need to recalculate the delay value since we used a pre-emptive negative
@@ -965,6 +957,7 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
965
957
 
966
958
  // TODO(matsko): for 1.5 change this code to have an animator object for better debugging
967
959
  return {
960
+ $$willAnimate: true,
968
961
  end: endFn,
969
962
  start: function() {
970
963
  if (animationClosed) return;
@@ -1044,6 +1037,23 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
1044
1037
  }
1045
1038
  }
1046
1039
 
1040
+ function closeAndReturnNoopAnimator() {
1041
+ runner = new $$AnimateRunner({
1042
+ end: endFn,
1043
+ cancel: cancelFn
1044
+ });
1045
+
1046
+ close();
1047
+
1048
+ return {
1049
+ $$willAnimate: false,
1050
+ start: function() {
1051
+ return runner;
1052
+ },
1053
+ end: endFn
1054
+ };
1055
+ }
1056
+
1047
1057
  function start() {
1048
1058
  if (animationClosed) return;
1049
1059
 
@@ -1220,8 +1230,7 @@ var $$AnimateCssDriverProvider = ['$$animationProvider', function($$animationPro
1220
1230
  $$animationProvider.drivers.push('$$animateCssDriver');
1221
1231
 
1222
1232
  var NG_ANIMATE_SHIM_CLASS_NAME = 'ng-animate-shim';
1223
- var NG_ANIMATE_ANCHOR_CLASS_NAME = 'ng-animate-anchor';
1224
- var NG_ANIMATE_ANCHOR_SUFFIX = '-anchor';
1233
+ var NG_ANIMATE_ANCHOR_CLASS_NAME = 'ng-anchor';
1225
1234
 
1226
1235
  var NG_OUT_ANCHOR_CLASS_NAME = 'ng-anchor-out';
1227
1236
  var NG_IN_ANCHOR_CLASS_NAME = 'ng-anchor-in';
@@ -1232,8 +1241,8 @@ var $$AnimateCssDriverProvider = ['$$animationProvider', function($$animationPro
1232
1241
  // only browsers that support these properties can render animations
1233
1242
  if (!$sniffer.animations && !$sniffer.transitions) return noop;
1234
1243
 
1235
- var bodyNode = $document[0].body;
1236
- var rootNode = $rootElement[0];
1244
+ var bodyNode = getDomNode($document).body;
1245
+ var rootNode = getDomNode($rootElement);
1237
1246
 
1238
1247
  var rootBodyElement = jqLite(bodyNode.parentNode === rootNode ? bodyNode : rootNode);
1239
1248
 
@@ -1260,15 +1269,13 @@ var $$AnimateCssDriverProvider = ['$$animationProvider', function($$animationPro
1260
1269
  }
1261
1270
 
1262
1271
  function prepareAnchoredAnimation(classes, outAnchor, inAnchor) {
1263
- var clone = jqLite(outAnchor[0].cloneNode(true));
1264
- var startingClasses = filterCssClasses(clone.attr('class') || '');
1265
- var anchorClasses = pendClasses(classes, NG_ANIMATE_ANCHOR_SUFFIX);
1272
+ var clone = jqLite(getDomNode(outAnchor).cloneNode(true));
1273
+ var startingClasses = filterCssClasses(getClassVal(clone));
1266
1274
 
1267
1275
  outAnchor.addClass(NG_ANIMATE_SHIM_CLASS_NAME);
1268
1276
  inAnchor.addClass(NG_ANIMATE_SHIM_CLASS_NAME);
1269
1277
 
1270
1278
  clone.addClass(NG_ANIMATE_ANCHOR_CLASS_NAME);
1271
- clone.addClass(anchorClasses);
1272
1279
 
1273
1280
  rootBodyElement.append(clone);
1274
1281
 
@@ -1329,7 +1336,7 @@ var $$AnimateCssDriverProvider = ['$$animationProvider', function($$animationPro
1329
1336
  function calculateAnchorStyles(anchor) {
1330
1337
  var styles = {};
1331
1338
 
1332
- var coords = anchor[0].getBoundingClientRect();
1339
+ var coords = getDomNode(anchor).getBoundingClientRect();
1333
1340
 
1334
1341
  // we iterate directly since safari messes up and doesn't return
1335
1342
  // all the keys for the coods object when iterated
@@ -1349,22 +1356,36 @@ var $$AnimateCssDriverProvider = ['$$animationProvider', function($$animationPro
1349
1356
  }
1350
1357
 
1351
1358
  function prepareOutAnimation() {
1352
- return $animateCss(clone, {
1359
+ var animator = $animateCss(clone, {
1353
1360
  addClass: NG_OUT_ANCHOR_CLASS_NAME,
1354
1361
  delay: true,
1355
1362
  from: calculateAnchorStyles(outAnchor)
1356
1363
  });
1364
+
1365
+ // read the comment within `prepareRegularAnimation` to understand
1366
+ // why this check is necessary
1367
+ return animator.$$willAnimate ? animator : null;
1368
+ }
1369
+
1370
+ function getClassVal(element) {
1371
+ return element.attr('class') || '';
1357
1372
  }
1358
1373
 
1359
1374
  function prepareInAnimation() {
1360
- var endingClasses = filterCssClasses(inAnchor.attr('class'));
1361
- var classes = getUniqueValues(endingClasses, startingClasses);
1362
- return $animateCss(clone, {
1375
+ var endingClasses = filterCssClasses(getClassVal(inAnchor));
1376
+ var toAdd = getUniqueValues(endingClasses, startingClasses);
1377
+ var toRemove = getUniqueValues(startingClasses, endingClasses);
1378
+
1379
+ var animator = $animateCss(clone, {
1363
1380
  to: calculateAnchorStyles(inAnchor),
1364
- addClass: NG_IN_ANCHOR_CLASS_NAME + ' ' + classes,
1365
- removeClass: NG_OUT_ANCHOR_CLASS_NAME + ' ' + startingClasses,
1381
+ addClass: NG_IN_ANCHOR_CLASS_NAME + ' ' + toAdd,
1382
+ removeClass: NG_OUT_ANCHOR_CLASS_NAME + ' ' + toRemove,
1366
1383
  delay: true
1367
1384
  });
1385
+
1386
+ // read the comment within `prepareRegularAnimation` to understand
1387
+ // why this check is necessary
1388
+ return animator.$$willAnimate ? animator : null;
1368
1389
  }
1369
1390
 
1370
1391
  function end() {
@@ -1445,7 +1466,13 @@ var $$AnimateCssDriverProvider = ['$$animationProvider', function($$animationPro
1445
1466
  options.onDone = animationDetails.domOperation;
1446
1467
  }
1447
1468
 
1448
- return $animateCss(element, options);
1469
+ var animator = $animateCss(element, options);
1470
+
1471
+ // the driver lookup code inside of $$animation attempts to spawn a
1472
+ // driver one by one until a driver returns a.$$willAnimate animator object.
1473
+ // $animateCss will always return an object, however, it will pass in
1474
+ // a flag as a hint as to whether an animation was detected or not
1475
+ return animator.$$willAnimate ? animator : null;
1449
1476
  }
1450
1477
  }];
1451
1478
  }];
@@ -1595,9 +1622,20 @@ var $$AnimateJsProvider = ['$animateProvider', function($animateProvider) {
1595
1622
  args.push(options);
1596
1623
 
1597
1624
  var value = fn.apply(fn, args);
1625
+ if (value) {
1626
+ if (isFunction(value.start)) {
1627
+ value = value.start();
1628
+ }
1598
1629
 
1599
- // optional onEnd / onCancel callback
1600
- return isFunction(value) ? value : noop;
1630
+ if (value instanceof $$AnimateRunner) {
1631
+ value.done(onDone);
1632
+ } else if (isFunction(value)) {
1633
+ // optional onEnd / onCancel callback
1634
+ return value;
1635
+ }
1636
+ }
1637
+
1638
+ return noop;
1601
1639
  }
1602
1640
 
1603
1641
  function groupEventedAnimations(element, event, options, animations, fnName) {
@@ -1876,7 +1914,7 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
1876
1914
  }
1877
1915
 
1878
1916
  function findCallbacks(element, event) {
1879
- var targetNode = element[0];
1917
+ var targetNode = getDomNode(element);
1880
1918
 
1881
1919
  var matches = [];
1882
1920
  var entries = callbackRegistry[event];
@@ -1957,7 +1995,7 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
1957
1995
  // (bool) - Global setter
1958
1996
  bool = animationsEnabled = !!element;
1959
1997
  } else {
1960
- var node = element.length ? element[0] : element;
1998
+ var node = getDomNode(element);
1961
1999
  var recordExists = disabledElementsLookup.get(node);
1962
2000
 
1963
2001
  if (argCount === 1) {
@@ -1980,11 +2018,14 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
1980
2018
  };
1981
2019
 
1982
2020
  function queueAnimation(element, event, options) {
2021
+ var node, parent;
1983
2022
  element = stripCommentsFromElement(element);
1984
- var node = element[0];
2023
+ if (element) {
2024
+ node = getDomNode(element);
2025
+ parent = element.parent();
2026
+ }
1985
2027
 
1986
2028
  options = prepareAnimationOptions(options);
1987
- var parent = element.parent();
1988
2029
 
1989
2030
  // we create a fake runner with a working promise.
1990
2031
  // These methods will become available after the digest has passed
@@ -1994,7 +2035,7 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
1994
2035
  // a jqLite wrapper that contains only comment nodes... If this
1995
2036
  // happens then there is no way we can perform an animation
1996
2037
  if (!node) {
1997
- runner.end();
2038
+ close();
1998
2039
  return runner;
1999
2040
  }
2000
2041
 
@@ -2167,7 +2208,7 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
2167
2208
  close(!status);
2168
2209
  var animationDetails = activeAnimationsLookup.get(node);
2169
2210
  if (animationDetails && animationDetails.counter === counter) {
2170
- clearElementAnimationState(element);
2211
+ clearElementAnimationState(getDomNode(element));
2171
2212
  }
2172
2213
  notifyProgress(runner, event, 'close', {});
2173
2214
  });
@@ -2194,7 +2235,7 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
2194
2235
  }
2195
2236
 
2196
2237
  function closeChildAnimations(element) {
2197
- var node = element[0];
2238
+ var node = getDomNode(element);
2198
2239
  var children = node.querySelectorAll('[' + NG_ANIMATE_ATTR_NAME + ']');
2199
2240
  forEach(children, function(child) {
2200
2241
  var state = parseInt(child.getAttribute(NG_ANIMATE_ATTR_NAME));
@@ -2213,19 +2254,17 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
2213
2254
  }
2214
2255
 
2215
2256
  function clearElementAnimationState(element) {
2216
- element = element.length ? element[0] : element;
2217
- element.removeAttribute(NG_ANIMATE_ATTR_NAME);
2218
- activeAnimationsLookup.remove(element);
2257
+ var node = getDomNode(element);
2258
+ node.removeAttribute(NG_ANIMATE_ATTR_NAME);
2259
+ activeAnimationsLookup.remove(node);
2219
2260
  }
2220
2261
 
2221
- function isMatchingElement(a,b) {
2222
- a = a.length ? a[0] : a;
2223
- b = b.length ? b[0] : b;
2224
- return a === b;
2262
+ function isMatchingElement(nodeOrElmA, nodeOrElmB) {
2263
+ return getDomNode(nodeOrElmA) === getDomNode(nodeOrElmB);
2225
2264
  }
2226
2265
 
2227
2266
  function closeParentClassBasedAnimations(startingElement) {
2228
- var parentNode = startingElement[0];
2267
+ var parentNode = getDomNode(startingElement);
2229
2268
  do {
2230
2269
  if (!parentNode || parentNode.nodeType !== ELEMENT_NODE) break;
2231
2270
 
@@ -2251,7 +2290,7 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
2251
2290
  }
2252
2291
  }
2253
2292
 
2254
- function areAnimationsAllowed(element, parent, event) {
2293
+ function areAnimationsAllowed(element, parentElement, event) {
2255
2294
  var bodyElementDetected = false;
2256
2295
  var rootElementDetected = false;
2257
2296
  var parentAnimationDetected = false;
@@ -2259,17 +2298,17 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
2259
2298
 
2260
2299
  var parentHost = element.data(NG_ANIMATE_PIN_DATA);
2261
2300
  if (parentHost) {
2262
- parent = parentHost;
2301
+ parentElement = parentHost;
2263
2302
  }
2264
2303
 
2265
- while (parent && parent.length) {
2304
+ while (parentElement && parentElement.length) {
2266
2305
  if (!rootElementDetected) {
2267
2306
  // angular doesn't want to attempt to animate elements outside of the application
2268
2307
  // therefore we need to ensure that the rootElement is an ancestor of the current element
2269
- rootElementDetected = isMatchingElement(parent, $rootElement);
2308
+ rootElementDetected = isMatchingElement(parentElement, $rootElement);
2270
2309
  }
2271
2310
 
2272
- var parentNode = parent[0];
2311
+ var parentNode = parentElement[0];
2273
2312
  if (parentNode.nodeType !== ELEMENT_NODE) {
2274
2313
  // no point in inspecting the #document element
2275
2314
  break;
@@ -2284,7 +2323,7 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
2284
2323
  }
2285
2324
 
2286
2325
  if (isUndefined(animateChildren) || animateChildren === true) {
2287
- var value = parent.data(NG_ANIMATE_CHILDREN_DATA);
2326
+ var value = parentElement.data(NG_ANIMATE_CHILDREN_DATA);
2288
2327
  if (isDefined(value)) {
2289
2328
  animateChildren = value;
2290
2329
  }
@@ -2296,11 +2335,11 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
2296
2335
  if (!rootElementDetected) {
2297
2336
  // angular doesn't want to attempt to animate elements outside of the application
2298
2337
  // therefore we need to ensure that the rootElement is an ancestor of the current element
2299
- rootElementDetected = isMatchingElement(parent, $rootElement);
2338
+ rootElementDetected = isMatchingElement(parentElement, $rootElement);
2300
2339
  if (!rootElementDetected) {
2301
- parentHost = parent.data(NG_ANIMATE_PIN_DATA);
2340
+ parentHost = parentElement.data(NG_ANIMATE_PIN_DATA);
2302
2341
  if (parentHost) {
2303
- parent = parentHost;
2342
+ parentElement = parentHost;
2304
2343
  }
2305
2344
  }
2306
2345
  }
@@ -2308,10 +2347,10 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
2308
2347
  if (!bodyElementDetected) {
2309
2348
  // we also need to ensure that the element is or will be apart of the body element
2310
2349
  // otherwise it is pointless to even issue an animation to be rendered
2311
- bodyElementDetected = isMatchingElement(parent, bodyElement);
2350
+ bodyElementDetected = isMatchingElement(parentElement, bodyElement);
2312
2351
  }
2313
2352
 
2314
- parent = parent.parent();
2353
+ parentElement = parentElement.parent();
2315
2354
  }
2316
2355
 
2317
2356
  var allowAnimation = !parentAnimationDetected || animateChildren;
@@ -2322,14 +2361,14 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
2322
2361
  details = details || {};
2323
2362
  details.state = state;
2324
2363
 
2325
- element = element.length ? element[0] : element;
2326
- element.setAttribute(NG_ANIMATE_ATTR_NAME, state);
2364
+ var node = getDomNode(element);
2365
+ node.setAttribute(NG_ANIMATE_ATTR_NAME, state);
2327
2366
 
2328
- var oldValue = activeAnimationsLookup.get(element);
2367
+ var oldValue = activeAnimationsLookup.get(node);
2329
2368
  var newValue = oldValue
2330
2369
  ? extend(oldValue, details)
2331
2370
  : details;
2332
- activeAnimationsLookup.put(element, newValue);
2371
+ activeAnimationsLookup.put(node, newValue);
2333
2372
  }
2334
2373
  }];
2335
2374
  }];
@@ -2485,7 +2524,6 @@ var $$AnimateRunnerFactory = ['$q', '$$rAFMutex', function($q, $$rAFMutex) {
2485
2524
  }];
2486
2525
 
2487
2526
  var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
2488
- var NG_ANIMATE_CLASSNAME = 'ng-animate';
2489
2527
  var NG_ANIMATE_REF_ATTR = 'ng-animate-ref';
2490
2528
 
2491
2529
  var drivers = this.drivers = [];
@@ -2546,7 +2584,7 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
2546
2584
  event: event,
2547
2585
  structural: isStructural,
2548
2586
  options: options,
2549
- start: start,
2587
+ beforeStart: beforeStart,
2550
2588
  close: close
2551
2589
  });
2552
2590
 
@@ -2572,15 +2610,19 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
2572
2610
  animationQueue.length = 0;
2573
2611
 
2574
2612
  forEach(groupAnimations(animations), function(animationEntry) {
2575
- var startFn = animationEntry.start;
2576
- var closeFn = animationEntry.close;
2613
+ // it's important that we apply the `ng-animate` CSS class and the
2614
+ // temporary classes before we do any driver invoking since these
2615
+ // CSS classes may be required for proper CSS detection.
2616
+ animationEntry.beforeStart();
2617
+
2577
2618
  var operation = invokeFirstDriver(animationEntry);
2578
- var startAnimation = operation && operation.start; /// TODO(matsko): only recognize operation.start()
2579
- if (!startAnimation) {
2619
+ var triggerAnimationStart = operation && operation.start; /// TODO(matsko): only recognize operation.start()
2620
+
2621
+ var closeFn = animationEntry.close;
2622
+ if (!triggerAnimationStart) {
2580
2623
  closeFn();
2581
2624
  } else {
2582
- startFn();
2583
- var animationRunner = startAnimation();
2625
+ var animationRunner = triggerAnimationStart();
2584
2626
  animationRunner.done(function(status) {
2585
2627
  closeFn(!status);
2586
2628
  });
@@ -2612,7 +2654,7 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
2612
2654
  var refLookup = {};
2613
2655
  forEach(animations, function(animation, index) {
2614
2656
  var element = animation.element;
2615
- var node = element[0];
2657
+ var node = getDomNode(element);
2616
2658
  var event = animation.event;
2617
2659
  var enterOrMove = ['enter', 'move'].indexOf(event) >= 0;
2618
2660
  var anchorNodes = animation.structural ? getAnchorNodes(node) : [];
@@ -2657,9 +2699,9 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
2657
2699
  if (!anchorGroups[lookupKey]) {
2658
2700
  var group = anchorGroups[lookupKey] = {
2659
2701
  // TODO(matsko): double-check this code
2660
- start: function() {
2661
- fromAnimation.start();
2662
- toAnimation.start();
2702
+ beforeStart: function() {
2703
+ fromAnimation.beforeStart();
2704
+ toAnimation.beforeStart();
2663
2705
  },
2664
2706
  close: function() {
2665
2707
  fromAnimation.close();
@@ -2725,7 +2767,7 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
2725
2767
  }
2726
2768
  }
2727
2769
 
2728
- function start() {
2770
+ function beforeStart() {
2729
2771
  element.addClass(NG_ANIMATE_CLASSNAME);
2730
2772
  if (tempClasses) {
2731
2773
  $$jqLite.addClass(element, tempClasses);
@@ -2995,6 +3037,35 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
2995
3037
  *
2996
3038
  * Stagger animations are currently only supported within CSS-defined animations.
2997
3039
  *
3040
+ * ### The `ng-animate` CSS class
3041
+ *
3042
+ * When ngAnimate is animating an element it will apply the `ng-animate` CSS class to the element for the duration of the animation.
3043
+ * This is a temporary CSS class and it will be removed once the animation is over (for both JavaScript and CSS-based animations).
3044
+ *
3045
+ * Therefore, animations can be applied to an element using this temporary class directly via CSS.
3046
+ *
3047
+ * ```css
3048
+ * .zipper.ng-animate {
3049
+ * transition:0.5s linear all;
3050
+ * }
3051
+ * .zipper.ng-enter {
3052
+ * opacity:0;
3053
+ * }
3054
+ * .zipper.ng-enter.ng-enter-active {
3055
+ * opacity:1;
3056
+ * }
3057
+ * .zipper.ng-leave {
3058
+ * opacity:1;
3059
+ * }
3060
+ * .zipper.ng-leave.ng-leave-active {
3061
+ * opacity:0;
3062
+ * }
3063
+ * ```
3064
+ *
3065
+ * (Note that the `ng-animate` CSS class is reserved and it cannot be applied on an element directly since ngAnimate will always remove
3066
+ * the CSS class once an animation has completed.)
3067
+ *
3068
+ *
2998
3069
  * ## JavaScript-based Animations
2999
3070
  *
3000
3071
  * ngAnimate also allows for animations to be consumed by JavaScript code. The approach is similar to CSS-based animations (where there is a shared
@@ -3105,17 +3176,12 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
3105
3176
  * myModule.animation('.slide', ['$animateCss', function($animateCss) {
3106
3177
  * return {
3107
3178
  * enter: function(element, doneFn) {
3108
- * var animation = $animateCss(element, {
3109
- * event: 'enter'
3110
- * });
3111
- *
3112
- * if (animation) {
3113
- * // this will trigger `.slide.ng-enter` and `.slide.ng-enter-active`.
3114
- * var runner = animation.start();
3115
- * runner.done(doneFn);
3116
- * } else { //no CSS animation was detected
3117
- * doneFn();
3118
- * }
3179
+ * // this will trigger `.slide.ng-enter` and `.slide.ng-enter-active`.
3180
+ * var runner = $animateCss(element, {
3181
+ * event: 'enter',
3182
+ * structural: true
3183
+ * }).start();
3184
+ * runner.done(doneFn);
3119
3185
  * }
3120
3186
  * }
3121
3187
  * }]
@@ -3131,18 +3197,14 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
3131
3197
  * myModule.animation('.slide', ['$animateCss', function($animateCss) {
3132
3198
  * return {
3133
3199
  * enter: function(element, doneFn) {
3134
- * var animation = $animateCss(element, {
3200
+ * var runner = $animateCss(element, {
3135
3201
  * event: 'enter',
3136
3202
  * addClass: 'maroon-setting',
3137
3203
  * from: { height:0 },
3138
3204
  * to: { height: 200 }
3139
- * });
3205
+ * }).start();
3140
3206
  *
3141
- * if (animation) {
3142
- * animation.start().done(doneFn);
3143
- * } else {
3144
- * doneFn();
3145
- * }
3207
+ * runner.done(doneFn);
3146
3208
  * }
3147
3209
  * }
3148
3210
  * }]
@@ -3170,10 +3232,12 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
3170
3232
  * called `ng-animate-ref`.
3171
3233
  *
3172
3234
  * Let's say for example we have two views that are managed by `ng-view` and we want to show
3173
- * that there is a relationship between two components situated in different views. By using the
3235
+ * that there is a relationship between two components situated in within these views. By using the
3174
3236
  * `ng-animate-ref` attribute we can identify that the two components are paired together and we
3175
3237
  * can then attach an animation, which is triggered when the view changes.
3176
3238
  *
3239
+ * Say for example we have the following template code:
3240
+ *
3177
3241
  * ```html
3178
3242
  * <!-- index.html -->
3179
3243
  * <div ng-view class="view-animation">
@@ -3181,46 +3245,70 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
3181
3245
  *
3182
3246
  * <!-- home.html -->
3183
3247
  * <a href="#/banner-page">
3184
- * <img src="./banner.jpg" ng-animate-ref="banner">
3248
+ * <img src="./banner.jpg" class="banner" ng-animate-ref="banner">
3185
3249
  * </a>
3186
3250
  *
3187
3251
  * <!-- banner-page.html -->
3188
- * <img src="./banner.jpg" ng-animate-ref="banner">
3252
+ * <img src="./banner.jpg" class="banner" ng-animate-ref="banner">
3189
3253
  * ```
3190
3254
  *
3191
3255
  * Now, when the view changes (once the link is clicked), ngAnimate will examine the
3192
3256
  * HTML contents to see if there is a match reference between any components in the view
3193
- * that is leaving and the view that is entering. It will then attempt to trigger a CSS
3194
- * animation on the `.view-animation-anchor` CSS class (notice how `.view-animation` is
3195
- * a shared CSS class on the ng-view element? This means that view-animation will apply to
3196
- * both the enter and leave animations).
3257
+ * that is leaving and the view that is entering. It will scan both the view which is being
3258
+ * removed (leave) and inserted (enter) to see if there are any paired DOM elements that
3259
+ * contain a matching ref value.
3197
3260
  *
3198
- * The two images match since they share the same ref value. ngAnimate will now apply a
3199
- * suffixed version of each of the shared CSS classes with `-anchor`. Therefore we will
3200
- * have a shared class of `view-animation-anchor` which we can use to setup our transition animation.
3261
+ * The two images match since they share the same ref value. ngAnimate will now create a
3262
+ * transport element (which is a clone of the first image element) and it will then attempt
3263
+ * to animate to the position of the second image element in the next view. For the animation to
3264
+ * work a special CSS class called `ng-anchor` will be added to the transported element.
3201
3265
  *
3202
- * We can now attach a transition onto the `.view-animation-anchor` CSS class and then
3266
+ * We can now attach a transition onto the `.banner.ng-anchor` CSS class and then
3203
3267
  * ngAnimate will handle the entire transition for us as well as the addition and removal of
3204
3268
  * any changes of CSS classes between the elements:
3205
3269
  *
3206
3270
  * ```css
3207
- * .view-animation-anchor {
3271
+ * .banner.ng-anchor {
3208
3272
  * /&#42; this animation will last for 1 second since there are
3209
3273
  * two phases to the animation (an `in` and an `out` phase) &#42;/
3210
3274
  * transition:0.5s linear all;
3211
3275
  * }
3212
3276
  * ```
3213
3277
  *
3214
- * There are two stages for an anchor animation: `out` and `in`. The `out` stage happens first and that
3215
- * is when the element is animated away from its origin. Once that animation is over then the `in` stage
3216
- * occurs which animates the element to its destination. The reason why there are two animations is to
3217
- * give enough time for the enter animation on the new element to be ready.
3278
+ * We also **must** include animations for the views that are being entered and removed
3279
+ * (otherwise anchoring wouldn't be possible since the new view would be inserted right away).
3280
+ *
3281
+ * ```css
3282
+ * .view-animation.ng-enter, .view-animation.ng-leave {
3283
+ * transition:0.5s linear all;
3284
+ * position:fixed;
3285
+ * left:0;
3286
+ * top:0;
3287
+ * width:100%;
3288
+ * }
3289
+ * .view-animation.ng-enter {
3290
+ * transform:translateX(100%);
3291
+ * }
3292
+ * .view-animation.ng-leave,
3293
+ * .view-animation.ng-enter.ng-enter-active {
3294
+ * transform:translateX(0%);
3295
+ * }
3296
+ * .view-animation.ng-leave.ng-leave-active {
3297
+ * transform:translateX(-100%);
3298
+ * }
3299
+ * ```
3300
+ *
3301
+ * Now we can jump back to the anchor animation. When the animation happens, there are two stages that occur:
3302
+ * an `out` and an `in` stage. The `out` stage happens first and that is when the element is animated away
3303
+ * from its origin. Once that animation is over then the `in` stage occurs which animates the
3304
+ * element to its destination. The reason why there are two animations is to give enough time
3305
+ * for the enter animation on the new element to be ready.
3218
3306
  *
3219
3307
  * The example above sets up a transition for both the in and out phases, but we can also target the out or
3220
3308
  * in phases directly via `ng-anchor-out` and `ng-anchor-in`.
3221
3309
  *
3222
3310
  * ```css
3223
- * .view-animation-anchor.ng-anchor-out {
3311
+ * .banner.ng-anchor-out {
3224
3312
  * transition: 0.5s linear all;
3225
3313
  *
3226
3314
  * /&#42; the scale will be applied during the out animation,
@@ -3228,7 +3316,7 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
3228
3316
  * transform: scale(1.2);
3229
3317
  * }
3230
3318
  *
3231
- * .view-animation-anchor.ng-anchor-in {
3319
+ * .banner.ng-anchor-in {
3232
3320
  * transition: 1s linear all;
3233
3321
  * }
3234
3322
  * ```
@@ -3322,21 +3410,21 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
3322
3410
  width:100%;
3323
3411
  min-height:500px;
3324
3412
  }
3325
- .view.ng-enter {
3413
+ .view.ng-enter, .view.ng-leave,
3414
+ .record.ng-anchor {
3326
3415
  transition:0.5s linear all;
3416
+ }
3417
+ .view.ng-enter {
3327
3418
  transform:translateX(100%);
3328
3419
  }
3329
- .view.ng-enter.ng-enter-active {
3420
+ .view.ng-enter.ng-enter-active, .view.ng-leave {
3330
3421
  transform:translateX(0%);
3331
3422
  }
3332
- .view.ng-leave {
3333
- transition:0.5s linear all;
3334
- }
3335
3423
  .view.ng-leave.ng-leave-active {
3336
3424
  transform:translateX(-100%);
3337
3425
  }
3338
- .view-anchor {
3339
- transition:0.5s linear all;
3426
+ .record.ng-anchor-out {
3427
+ background:red;
3340
3428
  }
3341
3429
  </file>
3342
3430
  </example>
@@ -3372,7 +3460,7 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
3372
3460
  * imagine we have a greeting box that shows and hides itself when the data changes
3373
3461
  *
3374
3462
  * ```html
3375
- * <greeing-box active="onOrOff">Hi there</greeting-box>
3463
+ * <greeting-box active="onOrOff">Hi there</greeting-box>
3376
3464
  * ```
3377
3465
  *
3378
3466
  * ```js