rails-angularjs 1.4.9 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/lib/rails-angularjs/version.rb +1 -1
  4. data/vendor/assets/javascripts/angular-animate.js +296 -48
  5. data/vendor/assets/javascripts/angular-animate.min.js +52 -51
  6. data/vendor/assets/javascripts/angular-animate.min.js.map +3 -3
  7. data/vendor/assets/javascripts/angular-aria.js +51 -51
  8. data/vendor/assets/javascripts/angular-aria.min.js +10 -10
  9. data/vendor/assets/javascripts/angular-aria.min.js.map +2 -2
  10. data/vendor/assets/javascripts/angular-cookies.js +9 -8
  11. data/vendor/assets/javascripts/angular-cookies.min.js +2 -2
  12. data/vendor/assets/javascripts/angular-cookies.min.js.map +1 -1
  13. data/vendor/assets/javascripts/angular-loader.js +16 -3
  14. data/vendor/assets/javascripts/angular-loader.min.js +5 -5
  15. data/vendor/assets/javascripts/angular-loader.min.js.map +2 -2
  16. data/vendor/assets/javascripts/angular-message-format.js +2 -2
  17. data/vendor/assets/javascripts/angular-message-format.min.js +2 -2
  18. data/vendor/assets/javascripts/angular-messages.js +7 -5
  19. data/vendor/assets/javascripts/angular-messages.min.js +8 -8
  20. data/vendor/assets/javascripts/angular-messages.min.js.map +2 -2
  21. data/vendor/assets/javascripts/angular-mocks.js +323 -30
  22. data/vendor/assets/javascripts/angular-resource.js +116 -42
  23. data/vendor/assets/javascripts/angular-resource.min.js +11 -10
  24. data/vendor/assets/javascripts/angular-resource.min.js.map +3 -3
  25. data/vendor/assets/javascripts/angular-route.js +36 -11
  26. data/vendor/assets/javascripts/angular-route.min.js +11 -11
  27. data/vendor/assets/javascripts/angular-route.min.js.map +2 -2
  28. data/vendor/assets/javascripts/angular-sanitize.js +280 -246
  29. data/vendor/assets/javascripts/angular-sanitize.min.js +11 -12
  30. data/vendor/assets/javascripts/angular-sanitize.min.js.map +3 -3
  31. data/vendor/assets/javascripts/angular-scenario.js +1227 -456
  32. data/vendor/assets/javascripts/angular-touch.js +114 -12
  33. data/vendor/assets/javascripts/angular-touch.min.js +10 -9
  34. data/vendor/assets/javascripts/angular-touch.min.js.map +3 -3
  35. data/vendor/assets/javascripts/angular.js +1227 -456
  36. data/vendor/assets/javascripts/angular.min.js +302 -293
  37. data/vendor/assets/javascripts/angular.min.js.map +3 -3
  38. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: edae6d55b2ccd655d6c2fbd457350d0d64969b3b
4
- data.tar.gz: e1cb5db640de120e2231810cf0cf320cf20a60ed
3
+ metadata.gz: fb36ced29647ae12ccc40b49370e4645e36e3af9
4
+ data.tar.gz: 11380730225c3b45fdf391b099ff6cad506f2fbd
5
5
  SHA512:
6
- metadata.gz: 20b62ac45319421bfb0f6a806b593da9d368ff4ef5282e7b3a46e886f386184aaec04575c1b67eafcebf79956c3cf9412317f906e9ee9fb7c9070da0c304739c
7
- data.tar.gz: bb0f590f9ee11eb68a21d48373683ca00a9334d487f8e628266bb9a2af9520074403857cbe8014cb45278dba6e16277aa9eea8bd778f7e68895a096136f14748
6
+ metadata.gz: ae99240f98d4304ac08b246dd3dc8b3403b30f214607c6d34e713ff0349ee6e9e3320789f3d6e61522be2faf12185d5bda9d6befd582d486770f4009f99d1382
7
+ data.tar.gz: 86b09039fcc61e234928e9607cc7a2fc10488f1a94949a225f4d92e14c92beb6f7d29b5ea793cfcf87096d14053848d5bd68c5a36b1dc65bca3b468e6bafcd4e
data/README.md CHANGED
@@ -27,4 +27,4 @@ For minified version just add .min to file name:
27
27
 
28
28
  ## Versioning
29
29
 
30
- Current AngularJS version: 1.4.9
30
+ Current AngularJS version: 1.5.0
@@ -1,3 +1,3 @@
1
1
  module RailsAngularJS
2
- VERSION = "1.4.9"
2
+ VERSION = "1.5.0"
3
3
  end
@@ -1,6 +1,6 @@
1
1
  /**
2
- * @license AngularJS v1.4.9
3
- * (c) 2010-2015 Google, Inc. http://angularjs.org
2
+ * @license AngularJS v1.5.0
3
+ * (c) 2010-2016 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
6
6
  (function(window, angular, undefined) {'use strict';
@@ -26,6 +26,7 @@ var ADD_CLASS_SUFFIX = '-add';
26
26
  var REMOVE_CLASS_SUFFIX = '-remove';
27
27
  var EVENT_CLASS_PREFIX = 'ng-';
28
28
  var ACTIVE_CLASS_SUFFIX = '-active';
29
+ var PREPARE_CLASS_SUFFIX = '-prepare';
29
30
 
30
31
  var NG_ANIMATE_CLASSNAME = 'ng-animate';
31
32
  var NG_ANIMATE_CHILDREN_DATA = '$$ngAnimateChildren';
@@ -222,7 +223,10 @@ function applyAnimationToStyles(element, options) {
222
223
  }
223
224
  }
224
225
 
225
- function mergeAnimationOptions(element, target, newOptions) {
226
+ function mergeAnimationDetails(element, oldAnimation, newAnimation) {
227
+ var target = oldAnimation.options || {};
228
+ var newOptions = newAnimation.options || {};
229
+
226
230
  var toAdd = (target.addClass || '') + ' ' + (newOptions.addClass || '');
227
231
  var toRemove = (target.removeClass || '') + ' ' + (newOptions.removeClass || '');
228
232
  var classes = resolveElementClasses(element.attr('class'), toAdd, toRemove);
@@ -254,6 +258,9 @@ function mergeAnimationOptions(element, target, newOptions) {
254
258
  target.removeClass = null;
255
259
  }
256
260
 
261
+ oldAnimation.addClass = target.addClass;
262
+ oldAnimation.removeClass = target.removeClass;
263
+
257
264
  return target;
258
265
  }
259
266
 
@@ -389,7 +396,7 @@ var $$rAFSchedulerFactory = ['$$rAF', function($$rAF) {
389
396
  queue = scheduler.queue = [];
390
397
 
391
398
  /* waitUntilQuiet does two things:
392
- * 1. It will run the FINAL `fn` value only when an uncancelled RAF has passed through
399
+ * 1. It will run the FINAL `fn` value only when an uncanceled RAF has passed through
393
400
  * 2. It will delay the next wave of tasks from running until the quiet `fn` has run.
394
401
  *
395
402
  * The motivation here is that animation code can request more time from the scheduler
@@ -424,16 +431,101 @@ var $$rAFSchedulerFactory = ['$$rAF', function($$rAF) {
424
431
  }
425
432
  }];
426
433
 
427
- var $$AnimateChildrenDirective = [function() {
428
- return function(scope, element, attrs) {
429
- var val = attrs.ngAnimateChildren;
430
- if (angular.isString(val) && val.length === 0) { //empty attribute
431
- element.data(NG_ANIMATE_CHILDREN_DATA, true);
432
- } else {
433
- attrs.$observe('ngAnimateChildren', function(value) {
434
+ /**
435
+ * @ngdoc directive
436
+ * @name ngAnimateChildren
437
+ * @restrict AE
438
+ * @element ANY
439
+ *
440
+ * @description
441
+ *
442
+ * ngAnimateChildren allows you to specify that children of this element should animate even if any
443
+ * of the children's parents are currently animating. By default, when an element has an active `enter`, `leave`, or `move`
444
+ * (structural) animation, child elements that also have an active structural animation are not animated.
445
+ *
446
+ * Note that even if `ngAnimteChildren` is set, no child animations will run when the parent element is removed from the DOM (`leave` animation).
447
+ *
448
+ *
449
+ * @param {string} ngAnimateChildren If the value is empty, `true` or `on`,
450
+ * then child animations are allowed. If the value is `false`, child animations are not allowed.
451
+ *
452
+ * @example
453
+ * <example module="ngAnimateChildren" name="ngAnimateChildren" deps="angular-animate.js" animations="true">
454
+ <file name="index.html">
455
+ <div ng-controller="mainController as main">
456
+ <label>Show container? <input type="checkbox" ng-model="main.enterElement" /></label>
457
+ <label>Animate children? <input type="checkbox" ng-model="main.animateChildren" /></label>
458
+ <hr>
459
+ <div ng-animate-children="{{main.animateChildren}}">
460
+ <div ng-if="main.enterElement" class="container">
461
+ List of items:
462
+ <div ng-repeat="item in [0, 1, 2, 3]" class="item">Item {{item}}</div>
463
+ </div>
464
+ </div>
465
+ </div>
466
+ </file>
467
+ <file name="animations.css">
468
+
469
+ .container.ng-enter,
470
+ .container.ng-leave {
471
+ transition: all ease 1.5s;
472
+ }
473
+
474
+ .container.ng-enter,
475
+ .container.ng-leave-active {
476
+ opacity: 0;
477
+ }
478
+
479
+ .container.ng-leave,
480
+ .container.ng-enter-active {
481
+ opacity: 1;
482
+ }
483
+
484
+ .item {
485
+ background: firebrick;
486
+ color: #FFF;
487
+ margin-bottom: 10px;
488
+ }
489
+
490
+ .item.ng-enter,
491
+ .item.ng-leave {
492
+ transition: transform 1.5s ease;
493
+ }
494
+
495
+ .item.ng-enter {
496
+ transform: translateX(50px);
497
+ }
498
+
499
+ .item.ng-enter-active {
500
+ transform: translateX(0);
501
+ }
502
+ </file>
503
+ <file name="script.js">
504
+ angular.module('ngAnimateChildren', ['ngAnimate'])
505
+ .controller('mainController', function() {
506
+ this.animateChildren = false;
507
+ this.enterElement = false;
508
+ });
509
+ </file>
510
+ </example>
511
+ */
512
+ var $$AnimateChildrenDirective = ['$interpolate', function($interpolate) {
513
+ return {
514
+ link: function(scope, element, attrs) {
515
+ var val = attrs.ngAnimateChildren;
516
+ if (angular.isString(val) && val.length === 0) { //empty attribute
517
+ element.data(NG_ANIMATE_CHILDREN_DATA, true);
518
+ } else {
519
+ // Interpolate and set the value, so that it is available to
520
+ // animations that run right after compilation
521
+ setData($interpolate(val)(scope));
522
+ attrs.$observe('ngAnimateChildren', setData);
523
+ }
524
+
525
+ function setData(value) {
434
526
  value = value === 'on' || value === 'true';
435
527
  element.data(NG_ANIMATE_CHILDREN_DATA, value);
436
- });
528
+ }
437
529
  }
438
530
  };
439
531
  }];
@@ -605,7 +697,7 @@ var ANIMATE_TIMER_KEY = '$$animateCss';
605
697
  * ```
606
698
  *
607
699
  * To actually start the animation we need to run `animation.start()` which will then return a promise that we can hook into to detect when the animation ends.
608
- * If we choose not to run the animation then we MUST run `animation.end()` to perform a cleanup on the element (since some CSS classes and stlyes may have been
700
+ * If we choose not to run the animation then we MUST run `animation.end()` to perform a cleanup on the element (since some CSS classes and styles may have been
609
701
  * applied to the element during the preparation phase). Note that all other properties such as duration, delay, transitions and keyframes are just properties
610
702
  * and that changing them will not reconfigure the parameters of the animation.
611
703
  *
@@ -642,11 +734,11 @@ var ANIMATE_TIMER_KEY = '$$animateCss';
642
734
  * * `stagger` - A numeric time value representing the delay between successively animated elements
643
735
  * ({@link ngAnimate#css-staggering-animations Click here to learn how CSS-based staggering works in ngAnimate.})
644
736
  * * `staggerIndex` - The numeric index representing the stagger item (e.g. a value of 5 is equal to the sixth item in the stagger; therefore when a
645
- * * `stagger` option value of `0.1` is used then there will be a stagger delay of `600ms`)
646
- * * `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.)
737
+ * `stagger` option value of `0.1` is used then there will be a stagger delay of `600ms`)
738
+ * * `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 occurring on the classes being added and removed.)
647
739
  * * `cleanupStyles` - Whether or not the provided `from` and `to` styles will be removed once
648
740
  * the animation is closed. This is useful for when the styles are used purely for the sake of
649
- * the animation and do not have a lasting visual effect on the element (e.g. a colapse and open animation).
741
+ * the animation and do not have a lasting visual effect on the element (e.g. a collapse and open animation).
650
742
  * By default this value is set to `false`.
651
743
  *
652
744
  * @return {object} an object with start and end methods and details about the animation.
@@ -699,7 +791,7 @@ function computeCssStyles($window, element, properties) {
699
791
  }
700
792
 
701
793
  // by setting this to null in the event that the delay is not set or is set directly as 0
702
- // then we can still allow for zegative values to be used later on and not mistake this
794
+ // then we can still allow for negative values to be used later on and not mistake this
703
795
  // value for being greater than any other negative value.
704
796
  if (val === 0) {
705
797
  val = null;
@@ -815,7 +907,7 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
815
907
  }
816
908
 
817
909
  // we keep putting this in multiple times even though the value and the cacheKey are the same
818
- // because we're keeping an interal tally of how many duplicate animations are detected.
910
+ // because we're keeping an internal tally of how many duplicate animations are detected.
819
911
  gcsLookup.put(cacheKey, timings);
820
912
  return timings;
821
913
  }
@@ -1194,6 +1286,13 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
1194
1286
  element.off(events.join(' '), onAnimationProgress);
1195
1287
  }
1196
1288
 
1289
+ //Cancel the fallback closing timeout and remove the timer data
1290
+ var animationTimerData = element.data(ANIMATE_TIMER_KEY);
1291
+ if (animationTimerData) {
1292
+ $timeout.cancel(animationTimerData[0].timer);
1293
+ element.removeData(ANIMATE_TIMER_KEY);
1294
+ }
1295
+
1197
1296
  // if the preparation function fails then the promise is not setup
1198
1297
  if (runner) {
1199
1298
  runner.complete(!rejected);
@@ -1282,9 +1381,9 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
1282
1381
  }
1283
1382
  };
1284
1383
 
1285
- // checking the stagger duration prevents an accidently cascade of the CSS delay style
1384
+ // checking the stagger duration prevents an accidentally cascade of the CSS delay style
1286
1385
  // being inherited from the parent. If the transition duration is zero then we can safely
1287
- // rely that the delay value is an intential stagger delay style.
1386
+ // rely that the delay value is an intentional stagger delay style.
1288
1387
  var maxStagger = itemIndex > 0
1289
1388
  && ((timings.transitionDuration && stagger.transitionDuration === 0) ||
1290
1389
  (timings.animationDuration && stagger.animationDuration === 0))
@@ -1457,7 +1556,7 @@ var $$AnimateCssDriverProvider = ['$$animationProvider', function($$animationPro
1457
1556
 
1458
1557
  var rootBodyElement = jqLite(
1459
1558
  // this is to avoid using something that exists outside of the body
1460
- // we also special case the doc fragement case because our unit test code
1559
+ // we also special case the doc fragment case because our unit test code
1461
1560
  // appends the $rootElement to the body after the app has been bootstrapped
1462
1561
  isDocumentFragment(rootNode) || bodyNode.contains(rootNode) ? rootNode : bodyNode
1463
1562
  );
@@ -1557,7 +1656,7 @@ var $$AnimateCssDriverProvider = ['$$animationProvider', function($$animationPro
1557
1656
  var coords = getDomNode(anchor).getBoundingClientRect();
1558
1657
 
1559
1658
  // we iterate directly since safari messes up and doesn't return
1560
- // all the keys for the coods object when iterated
1659
+ // all the keys for the coords object when iterated
1561
1660
  forEach(['width','height','top','left'], function(key) {
1562
1661
  var value = coords[key];
1563
1662
  switch (key) {
@@ -2086,22 +2185,21 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
2086
2185
  });
2087
2186
  }
2088
2187
 
2089
- function hasAnimationClasses(options, and) {
2090
- options = options || {};
2091
- var a = (options.addClass || '').length > 0;
2092
- var b = (options.removeClass || '').length > 0;
2188
+ function hasAnimationClasses(animation, and) {
2189
+ var a = (animation.addClass || '').length > 0;
2190
+ var b = (animation.removeClass || '').length > 0;
2093
2191
  return and ? a && b : a || b;
2094
2192
  }
2095
2193
 
2096
2194
  rules.join.push(function(element, newAnimation, currentAnimation) {
2097
2195
  // if the new animation is class-based then we can just tack that on
2098
- return !newAnimation.structural && hasAnimationClasses(newAnimation.options);
2196
+ return !newAnimation.structural && hasAnimationClasses(newAnimation);
2099
2197
  });
2100
2198
 
2101
2199
  rules.skip.push(function(element, newAnimation, currentAnimation) {
2102
2200
  // there is no need to animate anything if no classes are being added and
2103
2201
  // there is no structural animation that will be triggered
2104
- return !newAnimation.structural && !hasAnimationClasses(newAnimation.options);
2202
+ return !newAnimation.structural && !hasAnimationClasses(newAnimation);
2105
2203
  });
2106
2204
 
2107
2205
  rules.skip.push(function(element, newAnimation, currentAnimation) {
@@ -2127,19 +2225,17 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
2127
2225
  });
2128
2226
 
2129
2227
  rules.cancel.push(function(element, newAnimation, currentAnimation) {
2130
-
2131
-
2132
- var nA = newAnimation.options.addClass;
2133
- var nR = newAnimation.options.removeClass;
2134
- var cA = currentAnimation.options.addClass;
2135
- var cR = currentAnimation.options.removeClass;
2228
+ var nA = newAnimation.addClass;
2229
+ var nR = newAnimation.removeClass;
2230
+ var cA = currentAnimation.addClass;
2231
+ var cR = currentAnimation.removeClass;
2136
2232
 
2137
2233
  // early detection to save the global CPU shortage :)
2138
2234
  if ((isUndefined(nA) && isUndefined(nR)) || (isUndefined(cA) && isUndefined(cR))) {
2139
2235
  return false;
2140
2236
  }
2141
2237
 
2142
- return (hasMatchingClasses(nA, cR)) || (hasMatchingClasses(nR, cA));
2238
+ return hasMatchingClasses(nA, cR) || hasMatchingClasses(nR, cA);
2143
2239
  });
2144
2240
 
2145
2241
  this.$get = ['$$rAF', '$rootScope', '$rootElement', '$document', '$$HashMap',
@@ -2211,8 +2307,8 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
2211
2307
 
2212
2308
  var applyAnimationClasses = applyAnimationClassesFactory($$jqLite);
2213
2309
 
2214
- function normalizeAnimationOptions(element, options) {
2215
- return mergeAnimationOptions(element, options, {});
2310
+ function normalizeAnimationDetails(element, animation) {
2311
+ return mergeAnimationDetails(element, animation, {});
2216
2312
  }
2217
2313
 
2218
2314
  // IE9-11 has no method "contains" in SVG element and in Node.prototype. Bug #10259.
@@ -2406,6 +2502,8 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
2406
2502
  structural: isStructural,
2407
2503
  element: element,
2408
2504
  event: event,
2505
+ addClass: options.addClass,
2506
+ removeClass: options.removeClass,
2409
2507
  close: close,
2410
2508
  options: options,
2411
2509
  runner: runner
@@ -2418,11 +2516,10 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
2418
2516
  close();
2419
2517
  return runner;
2420
2518
  } else {
2421
- mergeAnimationOptions(element, existingAnimation.options, options);
2519
+ mergeAnimationDetails(element, existingAnimation, newAnimation);
2422
2520
  return existingAnimation.runner;
2423
2521
  }
2424
2522
  }
2425
-
2426
2523
  var cancelAnimationFlag = isAllowed('cancel', element, newAnimation, existingAnimation);
2427
2524
  if (cancelAnimationFlag) {
2428
2525
  if (existingAnimation.state === RUNNING_STATE) {
@@ -2437,7 +2534,8 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
2437
2534
  existingAnimation.close();
2438
2535
  } else {
2439
2536
  // this will merge the new animation options into existing animation options
2440
- mergeAnimationOptions(element, existingAnimation.options, newAnimation.options);
2537
+ mergeAnimationDetails(element, existingAnimation, newAnimation);
2538
+
2441
2539
  return existingAnimation.runner;
2442
2540
  }
2443
2541
  } else {
@@ -2447,12 +2545,12 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
2447
2545
  var joinAnimationFlag = isAllowed('join', element, newAnimation, existingAnimation);
2448
2546
  if (joinAnimationFlag) {
2449
2547
  if (existingAnimation.state === RUNNING_STATE) {
2450
- normalizeAnimationOptions(element, options);
2548
+ normalizeAnimationDetails(element, newAnimation);
2451
2549
  } else {
2452
2550
  applyGeneratedPreparationClasses(element, isStructural ? event : null, options);
2453
2551
 
2454
2552
  event = newAnimation.event = existingAnimation.event;
2455
- options = mergeAnimationOptions(element, existingAnimation.options, newAnimation.options);
2553
+ options = mergeAnimationDetails(element, existingAnimation, newAnimation);
2456
2554
 
2457
2555
  //we return the same runner since only the option values of this animation will
2458
2556
  //be fed into the `existingAnimation`.
@@ -2463,7 +2561,7 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
2463
2561
  } else {
2464
2562
  // normalization in this case means that it removes redundant CSS classes that
2465
2563
  // already exist (addClass) or do not exist (removeClass) on the element
2466
- normalizeAnimationOptions(element, options);
2564
+ normalizeAnimationDetails(element, newAnimation);
2467
2565
  }
2468
2566
 
2469
2567
  // when the options are merged and cleaned up we may end up not having to do
@@ -2473,7 +2571,7 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
2473
2571
  if (!isValidAnimation) {
2474
2572
  // animate (from/to) can be quickly checked first, otherwise we check if any classes are present
2475
2573
  isValidAnimation = (newAnimation.event === 'animate' && Object.keys(newAnimation.options.to || {}).length > 0)
2476
- || hasAnimationClasses(newAnimation.options);
2574
+ || hasAnimationClasses(newAnimation);
2477
2575
  }
2478
2576
 
2479
2577
  if (!isValidAnimation) {
@@ -2503,7 +2601,7 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
2503
2601
  var isValidAnimation = parentElement.length > 0
2504
2602
  && (animationDetails.event === 'animate'
2505
2603
  || animationDetails.structural
2506
- || hasAnimationClasses(animationDetails.options));
2604
+ || hasAnimationClasses(animationDetails));
2507
2605
 
2508
2606
  // this means that the previous animation was cancelled
2509
2607
  // even if the follow-up animation is the same event
@@ -2535,7 +2633,7 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
2535
2633
 
2536
2634
  // this combined multiple class to addClass / removeClass into a setClass event
2537
2635
  // so long as a structural event did not take over the animation
2538
- event = !animationDetails.structural && hasAnimationClasses(animationDetails.options, true)
2636
+ event = !animationDetails.structural && hasAnimationClasses(animationDetails, true)
2539
2637
  ? 'setClass'
2540
2638
  : animationDetails.event;
2541
2639
 
@@ -2857,6 +2955,12 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
2857
2955
  options.tempClasses = null;
2858
2956
  }
2859
2957
 
2958
+ var prepareClassName;
2959
+ if (isStructural) {
2960
+ prepareClassName = 'ng-' + event + PREPARE_CLASS_SUFFIX;
2961
+ $$jqLite.addClass(element, prepareClassName);
2962
+ }
2963
+
2860
2964
  animationQueue.push({
2861
2965
  // this data is used by the postDigest code and passed into
2862
2966
  // the driver step function
@@ -3021,7 +3125,7 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
3021
3125
  };
3022
3126
 
3023
3127
  // the anchor animations require that the from and to elements both have at least
3024
- // one shared CSS class which effictively marries the two elements together to use
3128
+ // one shared CSS class which effectively marries the two elements together to use
3025
3129
  // the same animation driver and to properly sequence the anchor animation.
3026
3130
  if (group.classes.length) {
3027
3131
  preparedAnimations.push(group);
@@ -3079,6 +3183,10 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
3079
3183
  if (tempClasses) {
3080
3184
  $$jqLite.addClass(element, tempClasses);
3081
3185
  }
3186
+ if (prepareClassName) {
3187
+ $$jqLite.removeClass(element, prepareClassName);
3188
+ prepareClassName = null;
3189
+ }
3082
3190
  }
3083
3191
 
3084
3192
  function updateAnimationRunners(animation, newRunner) {
@@ -3120,8 +3228,118 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
3120
3228
  }];
3121
3229
  }];
3122
3230
 
3231
+ /**
3232
+ * @ngdoc directive
3233
+ * @name ngAnimateSwap
3234
+ * @restrict A
3235
+ * @scope
3236
+ *
3237
+ * @description
3238
+ *
3239
+ * ngAnimateSwap is a animation-oriented directive that allows for the container to
3240
+ * be removed and entered in whenever the associated expression changes. A
3241
+ * common usecase for this directive is a rotating banner component which
3242
+ * contains one image being present at a time. When the active image changes
3243
+ * then the old image will perform a `leave` animation and the new element
3244
+ * will be inserted via an `enter` animation.
3245
+ *
3246
+ * @example
3247
+ * <example name="ngAnimateSwap-directive" module="ngAnimateSwapExample"
3248
+ * deps="angular-animate.js"
3249
+ * animations="true" fixBase="true">
3250
+ * <file name="index.html">
3251
+ * <div class="container" ng-controller="AppCtrl">
3252
+ * <div ng-animate-swap="number" class="cell swap-animation" ng-class="colorClass(number)">
3253
+ * {{ number }}
3254
+ * </div>
3255
+ * </div>
3256
+ * </file>
3257
+ * <file name="script.js">
3258
+ * angular.module('ngAnimateSwapExample', ['ngAnimate'])
3259
+ * .controller('AppCtrl', ['$scope', '$interval', function($scope, $interval) {
3260
+ * $scope.number = 0;
3261
+ * $interval(function() {
3262
+ * $scope.number++;
3263
+ * }, 1000);
3264
+ *
3265
+ * var colors = ['red','blue','green','yellow','orange'];
3266
+ * $scope.colorClass = function(number) {
3267
+ * return colors[number % colors.length];
3268
+ * };
3269
+ * }]);
3270
+ * </file>
3271
+ * <file name="animations.css">
3272
+ * .container {
3273
+ * height:250px;
3274
+ * width:250px;
3275
+ * position:relative;
3276
+ * overflow:hidden;
3277
+ * border:2px solid black;
3278
+ * }
3279
+ * .container .cell {
3280
+ * font-size:150px;
3281
+ * text-align:center;
3282
+ * line-height:250px;
3283
+ * position:absolute;
3284
+ * top:0;
3285
+ * left:0;
3286
+ * right:0;
3287
+ * border-bottom:2px solid black;
3288
+ * }
3289
+ * .swap-animation.ng-enter, .swap-animation.ng-leave {
3290
+ * transition:0.5s linear all;
3291
+ * }
3292
+ * .swap-animation.ng-enter {
3293
+ * top:-250px;
3294
+ * }
3295
+ * .swap-animation.ng-enter-active {
3296
+ * top:0px;
3297
+ * }
3298
+ * .swap-animation.ng-leave {
3299
+ * top:0px;
3300
+ * }
3301
+ * .swap-animation.ng-leave-active {
3302
+ * top:250px;
3303
+ * }
3304
+ * .red { background:red; }
3305
+ * .green { background:green; }
3306
+ * .blue { background:blue; }
3307
+ * .yellow { background:yellow; }
3308
+ * .orange { background:orange; }
3309
+ * </file>
3310
+ * </example>
3311
+ */
3312
+ var ngAnimateSwapDirective = ['$animate', '$rootScope', function($animate, $rootScope) {
3313
+ return {
3314
+ restrict: 'A',
3315
+ transclude: 'element',
3316
+ terminal: true,
3317
+ priority: 600, // we use 600 here to ensure that the directive is caught before others
3318
+ link: function(scope, $element, attrs, ctrl, $transclude) {
3319
+ var previousElement, previousScope;
3320
+ scope.$watchCollection(attrs.ngAnimateSwap || attrs['for'], function(value) {
3321
+ if (previousElement) {
3322
+ $animate.leave(previousElement);
3323
+ }
3324
+ if (previousScope) {
3325
+ previousScope.$destroy();
3326
+ previousScope = null;
3327
+ }
3328
+ if (value || value === 0) {
3329
+ previousScope = scope.$new();
3330
+ $transclude(previousScope, function(element) {
3331
+ previousElement = element;
3332
+ $animate.enter(element, null, $element);
3333
+ });
3334
+ }
3335
+ });
3336
+ }
3337
+ };
3338
+ }];
3339
+
3123
3340
  /* global angularAnimateModule: true,
3124
3341
 
3342
+ ngAnimateSwapDirective,
3125
3343
  $$AnimateAsyncRunFactory,
3126
3344
  $$rAFSchedulerFactory,
3127
3345
  $$AnimateChildrenDirective,
@@ -3373,11 +3591,39 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
3373
3591
  * the CSS class once an animation has completed.)
3374
3592
  *
3375
3593
  *
3594
+ * ### The `ng-[event]-prepare` class
3595
+ *
3596
+ * This is a special class that can be used to prevent unwanted flickering / flash of content before
3597
+ * the actual animation starts. The class is added as soon as an animation is initialized, but removed
3598
+ * before the actual animation starts (after waiting for a $digest).
3599
+ * It is also only added for *structural* animations (`enter`, `move`, and `leave`).
3600
+ *
3601
+ * In practice, flickering can appear when nesting elements with structural animations such as `ngIf`
3602
+ * into elements that have class-based animations such as `ngClass`.
3603
+ *
3604
+ * ```html
3605
+ * <div ng-class="{red: myProp}">
3606
+ * <div ng-class="{blue: myProp}">
3607
+ * <div class="message" ng-if="myProp"></div>
3608
+ * </div>
3609
+ * </div>
3610
+ * ```
3611
+ *
3612
+ * It is possible that during the `enter` animation, the `.message` div will be briefly visible before it starts animating.
3613
+ * In that case, you can add styles to the CSS that make sure the element stays hidden before the animation starts:
3614
+ *
3615
+ * ```css
3616
+ * .message.ng-enter-prepare {
3617
+ * opacity: 0;
3618
+ * }
3619
+ *
3620
+ * ```
3621
+ *
3376
3622
  * ## JavaScript-based Animations
3377
3623
  *
3378
3624
  * ngAnimate also allows for animations to be consumed by JavaScript code. The approach is similar to CSS-based animations (where there is a shared
3379
3625
  * CSS class that is referenced in our HTML code) but in addition we need to register the JavaScript animation on the module. By making use of the
3380
- * `module.animation()` module function we can register the ainmation.
3626
+ * `module.animation()` module function we can register the animation.
3381
3627
  *
3382
3628
  * Let's see an example of a enter/leave animation using `ngRepeat`:
3383
3629
  *
@@ -3857,6 +4103,8 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
3857
4103
  * Click here {@link ng.$animate to learn more about animations with `$animate`}.
3858
4104
  */
3859
4105
  angular.module('ngAnimate', [])
4106
+ .directive('ngAnimateSwap', ngAnimateSwapDirective)
4107
+
3860
4108
  .directive('ngAnimateChildren', $$AnimateChildrenDirective)
3861
4109
  .factory('$$rAFScheduler', $$rAFSchedulerFactory)
3862
4110