angularjs-rails 1.5.8 → 1.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +6 -1
- data/lib/angularjs-rails/engine.rb +1 -1
- data/lib/angularjs-rails/version.rb +1 -1
- data/vendor/assets/javascripts/angular-animate.js +426 -293
- data/vendor/assets/javascripts/angular-aria.js +64 -43
- data/vendor/assets/javascripts/angular-cookies.js +24 -93
- data/vendor/assets/javascripts/angular-loader.js +190 -36
- data/vendor/assets/javascripts/angular-message-format.js +72 -84
- data/vendor/assets/javascripts/angular-messages.js +158 -68
- data/vendor/assets/javascripts/angular-mocks.js +1033 -402
- data/vendor/assets/javascripts/angular-parse-ext.js +14 -10
- data/vendor/assets/javascripts/angular-resource.js +317 -269
- data/vendor/assets/javascripts/angular-route.js +329 -132
- data/vendor/assets/javascripts/angular-sanitize.js +268 -93
- data/vendor/assets/javascripts/angular-touch.js +46 -413
- data/vendor/assets/javascripts/angular.js +9213 -4485
- metadata +2 -3
- data/vendor/assets/javascripts/angular-scenario.js +0 -44134
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b29491e1b540e7e1d87b0d88f3fbb5b4c9323ad1
|
4
|
+
data.tar.gz: b13e9fd5f9ac54ddf962b54cb69b14b5b2c5b0ad
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 10e912a2d702bf2ad0b87351940ae8e36fd4c6c5af5293c451dfb08ffc5184b171c66e4f527c378203a1519f28e91c2222d9f46ac700ac1b2956eaace08fa3ff
|
7
|
+
data.tar.gz: ea1946717238ceb9794c24141d470c49a681ad3937df953ebbb58d1270c025df4aeb073c61de03863a14f7a928d516c2a9a9baeb47bbbcd82aa41b10f2bc0c5e
|
data/README.md
CHANGED
@@ -2,6 +2,11 @@
|
|
2
2
|
|
3
3
|
angularjs-rails wraps the [Angular.js](http://angularjs.org) library for use in Rails 3.1 and above. Assets will minify automatically during production.
|
4
4
|
|
5
|
+
**If you find this gem useful, please consider donating - your contributions will help me keep this gem updated.**
|
6
|
+
|
7
|
+
[![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=NCT7TZEFY2T9Y)
|
8
|
+
|
9
|
+
|
5
10
|
## Usage
|
6
11
|
|
7
12
|
Add the following to your Gemfile:
|
@@ -29,4 +34,4 @@ The major, minor, and patch version numbers will always represent the Angular.js
|
|
29
34
|
|
30
35
|
## IMPORTANT: Requesting upgrades for new Angular.js versions
|
31
36
|
|
32
|
-
|
37
|
+
To request that the latest version of Angular.JS be pushed as a gem to RubyGems, please create a new issue instead of pull requests.
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.
|
3
|
-
* (c) 2010-
|
2
|
+
* @license AngularJS v1.8.0
|
3
|
+
* (c) 2010-2020 Google, Inc. http://angularjs.org
|
4
4
|
* License: MIT
|
5
5
|
*/
|
6
6
|
(function(window, angular) {'use strict';
|
@@ -29,7 +29,7 @@ var CSS_PREFIX = '', TRANSITION_PROP, TRANSITIONEND_EVENT, ANIMATION_PROP, ANIMA
|
|
29
29
|
// Also, the only modern browser that uses vendor prefixes for transitions/keyframes is webkit
|
30
30
|
// therefore there is no reason to test anymore for other vendor prefixes:
|
31
31
|
// http://caniuse.com/#search=transition
|
32
|
-
if ((window.ontransitionend ===
|
32
|
+
if ((window.ontransitionend === undefined) && (window.onwebkittransitionend !== undefined)) {
|
33
33
|
CSS_PREFIX = '-webkit-';
|
34
34
|
TRANSITION_PROP = 'WebkitTransition';
|
35
35
|
TRANSITIONEND_EVENT = 'webkitTransitionEnd transitionend';
|
@@ -38,7 +38,7 @@ if ((window.ontransitionend === void 0) && (window.onwebkittransitionend !== voi
|
|
38
38
|
TRANSITIONEND_EVENT = 'transitionend';
|
39
39
|
}
|
40
40
|
|
41
|
-
if ((window.onanimationend ===
|
41
|
+
if ((window.onanimationend === undefined) && (window.onwebkitanimationend !== undefined)) {
|
42
42
|
CSS_PREFIX = '-webkit-';
|
43
43
|
ANIMATION_PROP = 'WebkitAnimation';
|
44
44
|
ANIMATIONEND_EVENT = 'webkitAnimationEnd animationend';
|
@@ -63,7 +63,7 @@ var TRANSITION_DURATION_PROP = TRANSITION_PROP + DURATION_KEY;
|
|
63
63
|
var ngMinErr = angular.$$minErr('ng');
|
64
64
|
function assertArg(arg, name, reason) {
|
65
65
|
if (!arg) {
|
66
|
-
throw ngMinErr('areq',
|
66
|
+
throw ngMinErr('areq', 'Argument \'{0}\' is {1}', (name || '?'), (reason || 'required'));
|
67
67
|
}
|
68
68
|
return arg;
|
69
69
|
}
|
@@ -139,7 +139,7 @@ function extractElementNode(element) {
|
|
139
139
|
if (!element[0]) return element;
|
140
140
|
for (var i = 0; i < element.length; i++) {
|
141
141
|
var elm = element[i];
|
142
|
-
if (elm.nodeType
|
142
|
+
if (elm.nodeType === ELEMENT_NODE) {
|
143
143
|
return elm;
|
144
144
|
}
|
145
145
|
}
|
@@ -306,7 +306,7 @@ function getDomNode(element) {
|
|
306
306
|
return (element instanceof jqLite) ? element[0] : element;
|
307
307
|
}
|
308
308
|
|
309
|
-
function applyGeneratedPreparationClasses(element, event, options) {
|
309
|
+
function applyGeneratedPreparationClasses($$jqLite, element, event, options) {
|
310
310
|
var classes = '';
|
311
311
|
if (event) {
|
312
312
|
classes = pendClasses(event, EVENT_CLASS_PREFIX, true);
|
@@ -334,15 +334,6 @@ function clearGeneratedClasses(element, options) {
|
|
334
334
|
}
|
335
335
|
}
|
336
336
|
|
337
|
-
function blockTransitions(node, duration) {
|
338
|
-
// we use a negative delay value since it performs blocking
|
339
|
-
// yet it doesn't kill any existing transitions running on the
|
340
|
-
// same element which makes this safe for class-based animations
|
341
|
-
var value = duration ? '-' + duration + 's' : '';
|
342
|
-
applyInlineStyle(node, [TRANSITION_DELAY_PROP, value]);
|
343
|
-
return [TRANSITION_DELAY_PROP, value];
|
344
|
-
}
|
345
|
-
|
346
337
|
function blockKeyframeAnimations(node, applyBlock) {
|
347
338
|
var value = applyBlock ? 'paused' : '';
|
348
339
|
var key = ANIMATION_PROP + ANIMATION_PLAYSTATE_KEY;
|
@@ -362,6 +353,17 @@ function concatWithSpace(a,b) {
|
|
362
353
|
return a + ' ' + b;
|
363
354
|
}
|
364
355
|
|
356
|
+
var helpers = {
|
357
|
+
blockTransitions: function(node, duration) {
|
358
|
+
// we use a negative delay value since it performs blocking
|
359
|
+
// yet it doesn't kill any existing transitions running on the
|
360
|
+
// same element which makes this safe for class-based animations
|
361
|
+
var value = duration ? '-' + duration + 's' : '';
|
362
|
+
applyInlineStyle(node, [TRANSITION_DELAY_PROP, value]);
|
363
|
+
return [TRANSITION_DELAY_PROP, value];
|
364
|
+
}
|
365
|
+
};
|
366
|
+
|
365
367
|
var $$rAFSchedulerFactory = ['$$rAF', function($$rAF) {
|
366
368
|
var queue, cancelFn;
|
367
369
|
|
@@ -423,7 +425,7 @@ var $$rAFSchedulerFactory = ['$$rAF', function($$rAF) {
|
|
423
425
|
* of the children's parents are currently animating. By default, when an element has an active `enter`, `leave`, or `move`
|
424
426
|
* (structural) animation, child elements that also have an active structural animation are not animated.
|
425
427
|
*
|
426
|
-
* Note that even if `
|
428
|
+
* Note that even if `ngAnimateChildren` is set, no child animations will run when the parent element is removed from the DOM (`leave` animation).
|
427
429
|
*
|
428
430
|
*
|
429
431
|
* @param {string} ngAnimateChildren If the value is empty, `true` or `on`,
|
@@ -432,7 +434,7 @@ var $$rAFSchedulerFactory = ['$$rAF', function($$rAF) {
|
|
432
434
|
* @example
|
433
435
|
* <example module="ngAnimateChildren" name="ngAnimateChildren" deps="angular-animate.js" animations="true">
|
434
436
|
<file name="index.html">
|
435
|
-
<div ng-controller="
|
437
|
+
<div ng-controller="MainController as main">
|
436
438
|
<label>Show container? <input type="checkbox" ng-model="main.enterElement" /></label>
|
437
439
|
<label>Animate children? <input type="checkbox" ng-model="main.animateChildren" /></label>
|
438
440
|
<hr>
|
@@ -482,7 +484,7 @@ var $$rAFSchedulerFactory = ['$$rAF', function($$rAF) {
|
|
482
484
|
</file>
|
483
485
|
<file name="script.js">
|
484
486
|
angular.module('ngAnimateChildren', ['ngAnimate'])
|
485
|
-
.controller('
|
487
|
+
.controller('MainController', function MainController() {
|
486
488
|
this.animateChildren = false;
|
487
489
|
this.enterElement = false;
|
488
490
|
});
|
@@ -510,6 +512,8 @@ var $$AnimateChildrenDirective = ['$interpolate', function($interpolate) {
|
|
510
512
|
};
|
511
513
|
}];
|
512
514
|
|
515
|
+
/* exported $AnimateCssProvider */
|
516
|
+
|
513
517
|
var ANIMATE_TIMER_KEY = '$$animateCss';
|
514
518
|
|
515
519
|
/**
|
@@ -526,11 +530,11 @@ var ANIMATE_TIMER_KEY = '$$animateCss';
|
|
526
530
|
* Note that only browsers that support CSS transitions and/or keyframe animations are capable of
|
527
531
|
* rendering animations triggered via `$animateCss` (bad news for IE9 and lower).
|
528
532
|
*
|
529
|
-
* ##
|
533
|
+
* ## General Use
|
530
534
|
* Once again, `$animateCss` is designed to be used inside of a registered JavaScript animation that
|
531
535
|
* is powered by ngAnimate. It is possible to use `$animateCss` directly inside of a directive, however,
|
532
536
|
* any automatic control over cancelling animations and/or preventing animations from being run on
|
533
|
-
* child elements will not be handled by
|
537
|
+
* child elements will not be handled by AngularJS. For this to work as expected, please use `$animate` to
|
534
538
|
* trigger the animation and then setup a JavaScript animation that injects `$animateCss` to trigger
|
535
539
|
* the CSS animation.
|
536
540
|
*
|
@@ -727,7 +731,6 @@ var ANIMATE_TIMER_KEY = '$$animateCss';
|
|
727
731
|
* * `end` - This method will cancel the animation and remove all applied CSS classes and styles.
|
728
732
|
*/
|
729
733
|
var ONE_SECOND = 1000;
|
730
|
-
var BASE_TEN = 10;
|
731
734
|
|
732
735
|
var ELAPSED_TIME_MAX_DECIMAL_PLACES = 3;
|
733
736
|
var CLOSING_TIME_BUFFER = 1.5;
|
@@ -789,7 +792,7 @@ function parseMaxTime(str) {
|
|
789
792
|
forEach(values, function(value) {
|
790
793
|
// it's always safe to consider only second values and omit `ms` values since
|
791
794
|
// getComputedStyle will always handle the conversion for us
|
792
|
-
if (value.charAt(value.length - 1)
|
795
|
+
if (value.charAt(value.length - 1) === 's') {
|
793
796
|
value = value.substring(0, value.length - 1);
|
794
797
|
}
|
795
798
|
value = parseFloat(value) || 0;
|
@@ -813,33 +816,6 @@ function getCssTransitionDurationStyle(duration, applyOnlyDuration) {
|
|
813
816
|
return [style, value];
|
814
817
|
}
|
815
818
|
|
816
|
-
function createLocalCacheLookup() {
|
817
|
-
var cache = Object.create(null);
|
818
|
-
return {
|
819
|
-
flush: function() {
|
820
|
-
cache = Object.create(null);
|
821
|
-
},
|
822
|
-
|
823
|
-
count: function(key) {
|
824
|
-
var entry = cache[key];
|
825
|
-
return entry ? entry.total : 0;
|
826
|
-
},
|
827
|
-
|
828
|
-
get: function(key) {
|
829
|
-
var entry = cache[key];
|
830
|
-
return entry && entry.value;
|
831
|
-
},
|
832
|
-
|
833
|
-
put: function(key, value) {
|
834
|
-
if (!cache[key]) {
|
835
|
-
cache[key] = { total: 1, value: value };
|
836
|
-
} else {
|
837
|
-
cache[key].total++;
|
838
|
-
}
|
839
|
-
}
|
840
|
-
};
|
841
|
-
}
|
842
|
-
|
843
819
|
// we do not reassign an already present style value since
|
844
820
|
// if we detect the style property value again we may be
|
845
821
|
// detecting styles that were added via the `from` styles.
|
@@ -857,27 +833,17 @@ function registerRestorableStyles(backup, node, properties) {
|
|
857
833
|
});
|
858
834
|
}
|
859
835
|
|
860
|
-
var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
861
|
-
var gcsLookup = createLocalCacheLookup();
|
862
|
-
var gcsStaggerLookup = createLocalCacheLookup();
|
836
|
+
var $AnimateCssProvider = ['$animateProvider', /** @this */ function($animateProvider) {
|
863
837
|
|
864
|
-
this.$get = ['$window', '$$jqLite', '$$AnimateRunner', '$timeout',
|
838
|
+
this.$get = ['$window', '$$jqLite', '$$AnimateRunner', '$timeout', '$$animateCache',
|
865
839
|
'$$forceReflow', '$sniffer', '$$rAFScheduler', '$$animateQueue',
|
866
|
-
function($window, $$jqLite, $$AnimateRunner, $timeout,
|
840
|
+
function($window, $$jqLite, $$AnimateRunner, $timeout, $$animateCache,
|
867
841
|
$$forceReflow, $sniffer, $$rAFScheduler, $$animateQueue) {
|
868
842
|
|
869
843
|
var applyAnimationClasses = applyAnimationClassesFactory($$jqLite);
|
870
844
|
|
871
|
-
|
872
|
-
|
873
|
-
var KEY = "$$ngAnimateParentKey";
|
874
|
-
var parentNode = node.parentNode;
|
875
|
-
var parentID = parentNode[KEY] || (parentNode[KEY] = ++parentCounter);
|
876
|
-
return parentID + '-' + node.getAttribute('class') + '-' + extraClasses;
|
877
|
-
}
|
878
|
-
|
879
|
-
function computeCachedCssStyles(node, className, cacheKey, properties) {
|
880
|
-
var timings = gcsLookup.get(cacheKey);
|
845
|
+
function computeCachedCssStyles(node, className, cacheKey, allowNoDuration, properties) {
|
846
|
+
var timings = $$animateCache.get(cacheKey);
|
881
847
|
|
882
848
|
if (!timings) {
|
883
849
|
timings = computeCssStyles($window, node, properties);
|
@@ -886,20 +852,26 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
|
886
852
|
}
|
887
853
|
}
|
888
854
|
|
855
|
+
// if a css animation has no duration we
|
856
|
+
// should mark that so that repeated addClass/removeClass calls are skipped
|
857
|
+
var hasDuration = allowNoDuration || (timings.transitionDuration > 0 || timings.animationDuration > 0);
|
858
|
+
|
889
859
|
// we keep putting this in multiple times even though the value and the cacheKey are the same
|
890
860
|
// because we're keeping an internal tally of how many duplicate animations are detected.
|
891
|
-
|
861
|
+
$$animateCache.put(cacheKey, timings, hasDuration);
|
862
|
+
|
892
863
|
return timings;
|
893
864
|
}
|
894
865
|
|
895
866
|
function computeCachedCssStaggerStyles(node, className, cacheKey, properties) {
|
896
867
|
var stagger;
|
868
|
+
var staggerCacheKey = 'stagger-' + cacheKey;
|
897
869
|
|
898
870
|
// if we have one or more existing matches of matching elements
|
899
871
|
// containing the same parent + CSS styles (which is how cacheKey works)
|
900
872
|
// then staggering is possible
|
901
|
-
if (
|
902
|
-
stagger =
|
873
|
+
if ($$animateCache.count(cacheKey) > 0) {
|
874
|
+
stagger = $$animateCache.get(staggerCacheKey);
|
903
875
|
|
904
876
|
if (!stagger) {
|
905
877
|
var staggerClassName = pendClasses(className, '-stagger');
|
@@ -914,20 +886,18 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
|
914
886
|
|
915
887
|
$$jqLite.removeClass(node, staggerClassName);
|
916
888
|
|
917
|
-
|
889
|
+
$$animateCache.put(staggerCacheKey, stagger, true);
|
918
890
|
}
|
919
891
|
}
|
920
892
|
|
921
893
|
return stagger || {};
|
922
894
|
}
|
923
895
|
|
924
|
-
var cancelLastRAFRequest;
|
925
896
|
var rafWaitQueue = [];
|
926
897
|
function waitUntilQuiet(callback) {
|
927
898
|
rafWaitQueue.push(callback);
|
928
899
|
$$rAFScheduler.waitUntilQuiet(function() {
|
929
|
-
|
930
|
-
gcsStaggerLookup.flush();
|
900
|
+
$$animateCache.flush();
|
931
901
|
|
932
902
|
// DO NOT REMOVE THIS LINE OR REFACTOR OUT THE `pageWidth` variable.
|
933
903
|
// PLEASE EXAMINE THE `$$forceReflow` service to understand why.
|
@@ -942,8 +912,8 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
|
942
912
|
});
|
943
913
|
}
|
944
914
|
|
945
|
-
function computeTimings(node, className, cacheKey) {
|
946
|
-
var timings = computeCachedCssStyles(node, className, cacheKey, DETECT_CSS_PROPERTIES);
|
915
|
+
function computeTimings(node, className, cacheKey, allowNoDuration) {
|
916
|
+
var timings = computeCachedCssStyles(node, className, cacheKey, allowNoDuration, DETECT_CSS_PROPERTIES);
|
947
917
|
var aD = timings.animationDelay;
|
948
918
|
var tD = timings.transitionDelay;
|
949
919
|
timings.maxDelay = aD && tD
|
@@ -1030,7 +1000,6 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
|
1030
1000
|
|
1031
1001
|
var preparationClasses = [structuralClassName, addRemoveClassName].join(' ').trim();
|
1032
1002
|
var fullClassName = classes + ' ' + preparationClasses;
|
1033
|
-
var activeClasses = pendClasses(preparationClasses, ACTIVE_CLASS_SUFFIX);
|
1034
1003
|
var hasToStyles = styles.to && Object.keys(styles.to).length > 0;
|
1035
1004
|
var containsKeyframeAnimation = (options.keyframeStyle || '').length > 0;
|
1036
1005
|
|
@@ -1043,7 +1012,12 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
|
1043
1012
|
return closeAndReturnNoopAnimator();
|
1044
1013
|
}
|
1045
1014
|
|
1046
|
-
var cacheKey,
|
1015
|
+
var stagger, cacheKey = $$animateCache.cacheKey(node, method, options.addClass, options.removeClass);
|
1016
|
+
if ($$animateCache.containsCachedAnimationWithoutDuration(cacheKey)) {
|
1017
|
+
preparationClasses = null;
|
1018
|
+
return closeAndReturnNoopAnimator();
|
1019
|
+
}
|
1020
|
+
|
1047
1021
|
if (options.stagger > 0) {
|
1048
1022
|
var staggerVal = parseFloat(options.stagger);
|
1049
1023
|
stagger = {
|
@@ -1053,7 +1027,6 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
|
1053
1027
|
animationDuration: 0
|
1054
1028
|
};
|
1055
1029
|
} else {
|
1056
|
-
cacheKey = gcsHashFn(node, fullClassName);
|
1057
1030
|
stagger = computeCachedCssStaggerStyles(node, preparationClasses, cacheKey, DETECT_STAGGER_CSS_PROPERTIES);
|
1058
1031
|
}
|
1059
1032
|
|
@@ -1087,7 +1060,7 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
|
1087
1060
|
var itemIndex = stagger
|
1088
1061
|
? options.staggerIndex >= 0
|
1089
1062
|
? options.staggerIndex
|
1090
|
-
:
|
1063
|
+
: $$animateCache.count(cacheKey)
|
1091
1064
|
: 0;
|
1092
1065
|
|
1093
1066
|
var isFirst = itemIndex === 0;
|
@@ -1099,10 +1072,10 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
|
1099
1072
|
// that if there is no transition defined then nothing will happen and this will also allow
|
1100
1073
|
// other transitions to be stacked on top of each other without any chopping them out.
|
1101
1074
|
if (isFirst && !options.skipBlocking) {
|
1102
|
-
blockTransitions(node, SAFE_FAST_FORWARD_DURATION_VALUE);
|
1075
|
+
helpers.blockTransitions(node, SAFE_FAST_FORWARD_DURATION_VALUE);
|
1103
1076
|
}
|
1104
1077
|
|
1105
|
-
var timings = computeTimings(node, fullClassName, cacheKey);
|
1078
|
+
var timings = computeTimings(node, fullClassName, cacheKey, !isStructural);
|
1106
1079
|
var relativeDelay = timings.maxDelay;
|
1107
1080
|
maxDelay = Math.max(relativeDelay, 0);
|
1108
1081
|
maxDuration = timings.maxDuration;
|
@@ -1110,7 +1083,7 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
|
1110
1083
|
var flags = {};
|
1111
1084
|
flags.hasTransitions = timings.transitionDuration > 0;
|
1112
1085
|
flags.hasAnimations = timings.animationDuration > 0;
|
1113
|
-
flags.hasTransitionAll = flags.hasTransitions && timings.transitionProperty
|
1086
|
+
flags.hasTransitionAll = flags.hasTransitions && timings.transitionProperty === 'all';
|
1114
1087
|
flags.applyTransitionDuration = hasToStyles && (
|
1115
1088
|
(flags.hasTransitions && !flags.hasTransitionAll)
|
1116
1089
|
|| (flags.hasAnimations && !flags.hasTransitions));
|
@@ -1140,9 +1113,11 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
|
1140
1113
|
return closeAndReturnNoopAnimator();
|
1141
1114
|
}
|
1142
1115
|
|
1116
|
+
var activeClasses = pendClasses(preparationClasses, ACTIVE_CLASS_SUFFIX);
|
1117
|
+
|
1143
1118
|
if (options.delay != null) {
|
1144
1119
|
var delayStyle;
|
1145
|
-
if (typeof options.delay !==
|
1120
|
+
if (typeof options.delay !== 'boolean') {
|
1146
1121
|
delayStyle = parseFloat(options.delay);
|
1147
1122
|
// number in options.delay means we have to recalculate the delay for the closing timeout
|
1148
1123
|
maxDelay = Math.max(delayStyle, 0);
|
@@ -1183,7 +1158,7 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
|
1183
1158
|
if (flags.blockTransition || flags.blockKeyframeAnimation) {
|
1184
1159
|
applyBlocking(maxDuration);
|
1185
1160
|
} else if (!options.skipBlocking) {
|
1186
|
-
blockTransitions(node, false);
|
1161
|
+
helpers.blockTransitions(node, false);
|
1187
1162
|
}
|
1188
1163
|
|
1189
1164
|
// TODO(matsko): for 1.5 change this code to have an animator object for better debugging
|
@@ -1220,20 +1195,23 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
|
1220
1195
|
close(true);
|
1221
1196
|
}
|
1222
1197
|
|
1223
|
-
function close(rejected) {
|
1198
|
+
function close(rejected) {
|
1224
1199
|
// if the promise has been called already then we shouldn't close
|
1225
1200
|
// the animation again
|
1226
1201
|
if (animationClosed || (animationCompleted && animationPaused)) return;
|
1227
1202
|
animationClosed = true;
|
1228
1203
|
animationPaused = false;
|
1229
1204
|
|
1230
|
-
if (!options.$$skipPreparationClasses) {
|
1205
|
+
if (preparationClasses && !options.$$skipPreparationClasses) {
|
1231
1206
|
$$jqLite.removeClass(element, preparationClasses);
|
1232
1207
|
}
|
1233
|
-
|
1208
|
+
|
1209
|
+
if (activeClasses) {
|
1210
|
+
$$jqLite.removeClass(element, activeClasses);
|
1211
|
+
}
|
1234
1212
|
|
1235
1213
|
blockKeyframeAnimations(node, false);
|
1236
|
-
blockTransitions(node, false);
|
1214
|
+
helpers.blockTransitions(node, false);
|
1237
1215
|
|
1238
1216
|
forEach(temporaryStyles, function(entry) {
|
1239
1217
|
// There is only one way to remove inline style properties entirely from elements.
|
@@ -1247,8 +1225,11 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
|
1247
1225
|
|
1248
1226
|
if (Object.keys(restoreStyles).length) {
|
1249
1227
|
forEach(restoreStyles, function(value, prop) {
|
1250
|
-
|
1251
|
-
|
1228
|
+
if (value) {
|
1229
|
+
node.style.setProperty(prop, value);
|
1230
|
+
} else {
|
1231
|
+
node.style.removeProperty(prop);
|
1232
|
+
}
|
1252
1233
|
});
|
1253
1234
|
}
|
1254
1235
|
|
@@ -1281,7 +1262,7 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
|
1281
1262
|
|
1282
1263
|
function applyBlocking(duration) {
|
1283
1264
|
if (flags.blockTransition) {
|
1284
|
-
blockTransitions(node, duration);
|
1265
|
+
helpers.blockTransitions(node, duration);
|
1285
1266
|
}
|
1286
1267
|
|
1287
1268
|
if (flags.blockKeyframeAnimation) {
|
@@ -1312,6 +1293,12 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
|
1312
1293
|
event.stopPropagation();
|
1313
1294
|
var ev = event.originalEvent || event;
|
1314
1295
|
|
1296
|
+
if (ev.target !== node) {
|
1297
|
+
// Since TransitionEvent / AnimationEvent bubble up,
|
1298
|
+
// we have to ignore events by finished child animations
|
1299
|
+
return;
|
1300
|
+
}
|
1301
|
+
|
1315
1302
|
// we now always use `Date.now()` due to the recent changes with
|
1316
1303
|
// event.timeStamp in Firefox, Webkit and Chrome (see #13494 for more info)
|
1317
1304
|
var timeStamp = ev.$manualTimeStamp || Date.now();
|
@@ -1351,9 +1338,11 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
|
1351
1338
|
animationPaused = !playAnimation;
|
1352
1339
|
if (timings.animationDuration) {
|
1353
1340
|
var value = blockKeyframeAnimations(node, animationPaused);
|
1354
|
-
animationPaused
|
1355
|
-
|
1356
|
-
|
1341
|
+
if (animationPaused) {
|
1342
|
+
temporaryStyles.push(value);
|
1343
|
+
} else {
|
1344
|
+
removeFromArray(temporaryStyles, value);
|
1345
|
+
}
|
1357
1346
|
}
|
1358
1347
|
} else if (animationPaused && playAnimation) {
|
1359
1348
|
animationPaused = false;
|
@@ -1402,10 +1391,10 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
|
1402
1391
|
$$jqLite.addClass(element, activeClasses);
|
1403
1392
|
|
1404
1393
|
if (flags.recalculateTimingStyles) {
|
1405
|
-
fullClassName = node.
|
1406
|
-
cacheKey =
|
1394
|
+
fullClassName = node.getAttribute('class') + ' ' + preparationClasses;
|
1395
|
+
cacheKey = $$animateCache.cacheKey(node, method, options.addClass, options.removeClass);
|
1407
1396
|
|
1408
|
-
timings = computeTimings(node, fullClassName, cacheKey);
|
1397
|
+
timings = computeTimings(node, fullClassName, cacheKey, false);
|
1409
1398
|
relativeDelay = timings.maxDelay;
|
1410
1399
|
maxDelay = Math.max(relativeDelay, 0);
|
1411
1400
|
maxDuration = timings.maxDuration;
|
@@ -1420,7 +1409,7 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
|
1420
1409
|
}
|
1421
1410
|
|
1422
1411
|
if (flags.applyAnimationDelay) {
|
1423
|
-
relativeDelay = typeof options.delay !==
|
1412
|
+
relativeDelay = typeof options.delay !== 'boolean' && truthyTimingValue(options.delay)
|
1424
1413
|
? parseFloat(options.delay)
|
1425
1414
|
: relativeDelay;
|
1426
1415
|
|
@@ -1512,7 +1501,7 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
|
1512
1501
|
}];
|
1513
1502
|
}];
|
1514
1503
|
|
1515
|
-
var $$AnimateCssDriverProvider = ['$$animationProvider', function($$animationProvider) {
|
1504
|
+
var $$AnimateCssDriverProvider = ['$$animationProvider', /** @this */ function($$animationProvider) {
|
1516
1505
|
$$animationProvider.drivers.push('$$animateCssDriver');
|
1517
1506
|
|
1518
1507
|
var NG_ANIMATE_SHIM_CLASS_NAME = 'ng-animate-shim';
|
@@ -1541,8 +1530,6 @@ var $$AnimateCssDriverProvider = ['$$animationProvider', function($$animationPro
|
|
1541
1530
|
isDocumentFragment(rootNode) || bodyNode.contains(rootNode) ? rootNode : bodyNode
|
1542
1531
|
);
|
1543
1532
|
|
1544
|
-
var applyAnimationClasses = applyAnimationClassesFactory($$jqLite);
|
1545
|
-
|
1546
1533
|
return function initDriverFn(animationDetails) {
|
1547
1534
|
return animationDetails.from && animationDetails.to
|
1548
1535
|
? prepareFromToAnchorAnimation(animationDetails.from,
|
@@ -1784,7 +1771,7 @@ var $$AnimateCssDriverProvider = ['$$animationProvider', function($$animationPro
|
|
1784
1771
|
// TODO(matsko): add documentation
|
1785
1772
|
// by the time...
|
1786
1773
|
|
1787
|
-
var $$AnimateJsProvider = ['$animateProvider', function($animateProvider) {
|
1774
|
+
var $$AnimateJsProvider = ['$animateProvider', /** @this */ function($animateProvider) {
|
1788
1775
|
this.$get = ['$injector', '$$AnimateRunner', '$$jqLite',
|
1789
1776
|
function($injector, $$AnimateRunner, $$jqLite) {
|
1790
1777
|
|
@@ -1823,7 +1810,7 @@ var $$AnimateJsProvider = ['$animateProvider', function($animateProvider) {
|
|
1823
1810
|
var before, after;
|
1824
1811
|
if (animations.length) {
|
1825
1812
|
var afterFn, beforeFn;
|
1826
|
-
if (event
|
1813
|
+
if (event === 'leave') {
|
1827
1814
|
beforeFn = 'leave';
|
1828
1815
|
afterFn = 'afterLeave'; // TODO(matsko): get rid of this
|
1829
1816
|
} else {
|
@@ -2008,7 +1995,7 @@ var $$AnimateJsProvider = ['$animateProvider', function($animateProvider) {
|
|
2008
1995
|
function packageAnimations(element, event, options, animations, fnName) {
|
2009
1996
|
var operations = groupEventedAnimations(element, event, options, animations, fnName);
|
2010
1997
|
if (operations.length === 0) {
|
2011
|
-
var a,b;
|
1998
|
+
var a, b;
|
2012
1999
|
if (fnName === 'beforeSetClass') {
|
2013
2000
|
a = groupEventedAnimations(element, 'removeClass', options, animations, 'beforeRemoveClass');
|
2014
2001
|
b = groupEventedAnimations(element, 'addClass', options, animations, 'beforeAddClass');
|
@@ -2036,11 +2023,19 @@ var $$AnimateJsProvider = ['$animateProvider', function($animateProvider) {
|
|
2036
2023
|
});
|
2037
2024
|
}
|
2038
2025
|
|
2039
|
-
runners.length
|
2026
|
+
if (runners.length) {
|
2027
|
+
$$AnimateRunner.all(runners, callback);
|
2028
|
+
} else {
|
2029
|
+
callback();
|
2030
|
+
}
|
2040
2031
|
|
2041
2032
|
return function endFn(reject) {
|
2042
2033
|
forEach(runners, function(runner) {
|
2043
|
-
|
2034
|
+
if (reject) {
|
2035
|
+
runner.cancel();
|
2036
|
+
} else {
|
2037
|
+
runner.end();
|
2038
|
+
}
|
2044
2039
|
});
|
2045
2040
|
};
|
2046
2041
|
};
|
@@ -2050,7 +2045,7 @@ var $$AnimateJsProvider = ['$animateProvider', function($animateProvider) {
|
|
2050
2045
|
function lookupAnimations(classes) {
|
2051
2046
|
classes = isArray(classes) ? classes : classes.split(' ');
|
2052
2047
|
var matches = [], flagMap = {};
|
2053
|
-
for (var i=0; i < classes.length; i++) {
|
2048
|
+
for (var i = 0; i < classes.length; i++) {
|
2054
2049
|
var klass = classes[i],
|
2055
2050
|
animationFactory = $animateProvider.$$registeredAnimations[klass];
|
2056
2051
|
if (animationFactory && !flagMap[klass]) {
|
@@ -2063,7 +2058,7 @@ var $$AnimateJsProvider = ['$animateProvider', function($animateProvider) {
|
|
2063
2058
|
}];
|
2064
2059
|
}];
|
2065
2060
|
|
2066
|
-
var $$AnimateJsDriverProvider = ['$$animationProvider', function($$animationProvider) {
|
2061
|
+
var $$AnimateJsDriverProvider = ['$$animationProvider', /** @this */ function($$animationProvider) {
|
2067
2062
|
$$animationProvider.drivers.push('$$animateJsDriver');
|
2068
2063
|
this.$get = ['$$animateJs', '$$AnimateRunner', function($$animateJs, $$AnimateRunner) {
|
2069
2064
|
return function initDriverFn(animationDetails) {
|
@@ -2125,7 +2120,7 @@ var $$AnimateJsDriverProvider = ['$$animationProvider', function($$animationProv
|
|
2125
2120
|
|
2126
2121
|
var NG_ANIMATE_ATTR_NAME = 'data-ng-animate';
|
2127
2122
|
var NG_ANIMATE_PIN_DATA = '$ngAnimatePin';
|
2128
|
-
var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
2123
|
+
var $$AnimateQueueProvider = ['$animateProvider', /** @this */ function($animateProvider) {
|
2129
2124
|
var PRE_DIGEST_STATE = 1;
|
2130
2125
|
var RUNNING_STATE = 2;
|
2131
2126
|
var ONE_SPACE = ' ';
|
@@ -2136,6 +2131,15 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
2136
2131
|
join: []
|
2137
2132
|
};
|
2138
2133
|
|
2134
|
+
function getEventData(options) {
|
2135
|
+
return {
|
2136
|
+
addClass: options.addClass,
|
2137
|
+
removeClass: options.removeClass,
|
2138
|
+
from: options.from,
|
2139
|
+
to: options.to
|
2140
|
+
};
|
2141
|
+
}
|
2142
|
+
|
2139
2143
|
function makeTruthyCssClassMap(classString) {
|
2140
2144
|
if (!classString) {
|
2141
2145
|
return null;
|
@@ -2159,9 +2163,9 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
2159
2163
|
}
|
2160
2164
|
}
|
2161
2165
|
|
2162
|
-
function isAllowed(ruleType,
|
2166
|
+
function isAllowed(ruleType, currentAnimation, previousAnimation) {
|
2163
2167
|
return rules[ruleType].some(function(fn) {
|
2164
|
-
return fn(
|
2168
|
+
return fn(currentAnimation, previousAnimation);
|
2165
2169
|
});
|
2166
2170
|
}
|
2167
2171
|
|
@@ -2171,40 +2175,40 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
2171
2175
|
return and ? a && b : a || b;
|
2172
2176
|
}
|
2173
2177
|
|
2174
|
-
rules.join.push(function(
|
2178
|
+
rules.join.push(function(newAnimation, currentAnimation) {
|
2175
2179
|
// if the new animation is class-based then we can just tack that on
|
2176
2180
|
return !newAnimation.structural && hasAnimationClasses(newAnimation);
|
2177
2181
|
});
|
2178
2182
|
|
2179
|
-
rules.skip.push(function(
|
2183
|
+
rules.skip.push(function(newAnimation, currentAnimation) {
|
2180
2184
|
// there is no need to animate anything if no classes are being added and
|
2181
2185
|
// there is no structural animation that will be triggered
|
2182
2186
|
return !newAnimation.structural && !hasAnimationClasses(newAnimation);
|
2183
2187
|
});
|
2184
2188
|
|
2185
|
-
rules.skip.push(function(
|
2189
|
+
rules.skip.push(function(newAnimation, currentAnimation) {
|
2186
2190
|
// why should we trigger a new structural animation if the element will
|
2187
2191
|
// be removed from the DOM anyway?
|
2188
|
-
return currentAnimation.event
|
2192
|
+
return currentAnimation.event === 'leave' && newAnimation.structural;
|
2189
2193
|
});
|
2190
2194
|
|
2191
|
-
rules.skip.push(function(
|
2195
|
+
rules.skip.push(function(newAnimation, currentAnimation) {
|
2192
2196
|
// if there is an ongoing current animation then don't even bother running the class-based animation
|
2193
2197
|
return currentAnimation.structural && currentAnimation.state === RUNNING_STATE && !newAnimation.structural;
|
2194
2198
|
});
|
2195
2199
|
|
2196
|
-
rules.cancel.push(function(
|
2200
|
+
rules.cancel.push(function(newAnimation, currentAnimation) {
|
2197
2201
|
// there can never be two structural animations running at the same time
|
2198
2202
|
return currentAnimation.structural && newAnimation.structural;
|
2199
2203
|
});
|
2200
2204
|
|
2201
|
-
rules.cancel.push(function(
|
2205
|
+
rules.cancel.push(function(newAnimation, currentAnimation) {
|
2202
2206
|
// if the previous animation is already running, but the new animation will
|
2203
2207
|
// be triggered, but the new animation is structural
|
2204
2208
|
return currentAnimation.state === RUNNING_STATE && newAnimation.structural;
|
2205
2209
|
});
|
2206
2210
|
|
2207
|
-
rules.cancel.push(function(
|
2211
|
+
rules.cancel.push(function(newAnimation, currentAnimation) {
|
2208
2212
|
// cancel the animation if classes added / removed in both animation cancel each other out,
|
2209
2213
|
// but only if the current animation isn't structural
|
2210
2214
|
|
@@ -2223,15 +2227,21 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
2223
2227
|
return hasMatchingClasses(nA, cR) || hasMatchingClasses(nR, cA);
|
2224
2228
|
});
|
2225
2229
|
|
2226
|
-
this.$get = ['$$rAF', '$rootScope', '$rootElement', '$document', '$$
|
2230
|
+
this.$get = ['$$rAF', '$rootScope', '$rootElement', '$document', '$$Map',
|
2227
2231
|
'$$animation', '$$AnimateRunner', '$templateRequest', '$$jqLite', '$$forceReflow',
|
2228
|
-
|
2229
|
-
|
2232
|
+
'$$isDocumentHidden',
|
2233
|
+
function($$rAF, $rootScope, $rootElement, $document, $$Map,
|
2234
|
+
$$animation, $$AnimateRunner, $templateRequest, $$jqLite, $$forceReflow,
|
2235
|
+
$$isDocumentHidden) {
|
2230
2236
|
|
2231
|
-
var activeAnimationsLookup = new $$
|
2232
|
-
var disabledElementsLookup = new $$
|
2237
|
+
var activeAnimationsLookup = new $$Map();
|
2238
|
+
var disabledElementsLookup = new $$Map();
|
2233
2239
|
var animationsEnabled = null;
|
2234
2240
|
|
2241
|
+
function removeFromDisabledElementsLookup(evt) {
|
2242
|
+
disabledElementsLookup.delete(evt.target);
|
2243
|
+
}
|
2244
|
+
|
2235
2245
|
function postDigestTaskFactory() {
|
2236
2246
|
var postDigestCalled = false;
|
2237
2247
|
return function(fn) {
|
@@ -2281,14 +2291,17 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
2281
2291
|
|
2282
2292
|
var callbackRegistry = Object.create(null);
|
2283
2293
|
|
2284
|
-
// remember that the classNameFilter
|
2285
|
-
// stage therefore we can optimize here and setup
|
2294
|
+
// remember that the `customFilter`/`classNameFilter` are set during the
|
2295
|
+
// provider/config stage therefore we can optimize here and setup helper functions
|
2296
|
+
var customFilter = $animateProvider.customFilter();
|
2286
2297
|
var classNameFilter = $animateProvider.classNameFilter();
|
2287
|
-
var
|
2288
|
-
|
2289
|
-
|
2290
|
-
|
2291
|
-
|
2298
|
+
var returnTrue = function() { return true; };
|
2299
|
+
|
2300
|
+
var isAnimatableByFilter = customFilter || returnTrue;
|
2301
|
+
var isAnimatableClassName = !classNameFilter ? returnTrue : function(node, options) {
|
2302
|
+
var className = [node.getAttribute('class'), options.addClass, options.removeClass].join(' ');
|
2303
|
+
return classNameFilter.test(className);
|
2304
|
+
};
|
2292
2305
|
|
2293
2306
|
var applyAnimationClasses = applyAnimationClassesFactory($$jqLite);
|
2294
2307
|
|
@@ -2297,16 +2310,12 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
2297
2310
|
}
|
2298
2311
|
|
2299
2312
|
// IE9-11 has no method "contains" in SVG element and in Node.prototype. Bug #10259.
|
2300
|
-
var contains = window.Node.prototype.contains || function(arg) {
|
2301
|
-
//
|
2313
|
+
var contains = window.Node.prototype.contains || /** @this */ function(arg) {
|
2314
|
+
// eslint-disable-next-line no-bitwise
|
2302
2315
|
return this === arg || !!(this.compareDocumentPosition(arg) & 16);
|
2303
|
-
// jshint bitwise: true
|
2304
2316
|
};
|
2305
2317
|
|
2306
|
-
function findCallbacks(
|
2307
|
-
var targetNode = getDomNode(element);
|
2308
|
-
var targetParentNode = getDomNode(parent);
|
2309
|
-
|
2318
|
+
function findCallbacks(targetParentNode, targetNode, event) {
|
2310
2319
|
var matches = [];
|
2311
2320
|
var entries = callbackRegistry[event];
|
2312
2321
|
if (entries) {
|
@@ -2331,11 +2340,11 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
2331
2340
|
});
|
2332
2341
|
}
|
2333
2342
|
|
2334
|
-
function cleanupEventListeners(phase,
|
2335
|
-
if (phase === 'close' && !
|
2343
|
+
function cleanupEventListeners(phase, node) {
|
2344
|
+
if (phase === 'close' && !node.parentNode) {
|
2336
2345
|
// If the element is not attached to a parentNode, it has been removed by
|
2337
2346
|
// the domOperation, and we can safely remove the event callbacks
|
2338
|
-
$animate.off(
|
2347
|
+
$animate.off(node);
|
2339
2348
|
}
|
2340
2349
|
}
|
2341
2350
|
|
@@ -2416,7 +2425,12 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
2416
2425
|
bool = !disabledElementsLookup.get(node);
|
2417
2426
|
} else {
|
2418
2427
|
// (element, bool) - Element setter
|
2419
|
-
disabledElementsLookup.
|
2428
|
+
if (!disabledElementsLookup.has(node)) {
|
2429
|
+
// The element is added to the map for the first time.
|
2430
|
+
// Create a listener to remove it on `$destroy` (to avoid memory leak).
|
2431
|
+
jqLite(element).on('$destroy', removeFromDisabledElementsLookup);
|
2432
|
+
}
|
2433
|
+
disabledElementsLookup.set(node, !bool);
|
2420
2434
|
}
|
2421
2435
|
}
|
2422
2436
|
}
|
@@ -2427,18 +2441,15 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
2427
2441
|
|
2428
2442
|
return $animate;
|
2429
2443
|
|
2430
|
-
function queueAnimation(
|
2444
|
+
function queueAnimation(originalElement, event, initialOptions) {
|
2431
2445
|
// we always make a copy of the options since
|
2432
2446
|
// there should never be any side effects on
|
2433
2447
|
// the input data when running `$animateCss`.
|
2434
2448
|
var options = copy(initialOptions);
|
2435
2449
|
|
2436
|
-
var
|
2437
|
-
|
2438
|
-
|
2439
|
-
node = getDomNode(element);
|
2440
|
-
parent = element.parent();
|
2441
|
-
}
|
2450
|
+
var element = stripCommentsFromElement(originalElement);
|
2451
|
+
var node = getDomNode(element);
|
2452
|
+
var parentNode = node && node.parentNode;
|
2442
2453
|
|
2443
2454
|
options = prepareAnimationOptions(options);
|
2444
2455
|
|
@@ -2473,49 +2484,45 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
2473
2484
|
options.to = null;
|
2474
2485
|
}
|
2475
2486
|
|
2476
|
-
//
|
2477
|
-
// a
|
2478
|
-
//
|
2479
|
-
if (!
|
2480
|
-
|
2481
|
-
|
2482
|
-
|
2483
|
-
|
2484
|
-
var className = [node.className, options.addClass, options.removeClass].join(' ');
|
2485
|
-
if (!isAnimatableClassName(className)) {
|
2487
|
+
// If animations are hard-disabled for the whole application there is no need to continue.
|
2488
|
+
// There are also situations where a directive issues an animation for a jqLite wrapper that
|
2489
|
+
// contains only comment nodes. In this case, there is no way we can perform an animation.
|
2490
|
+
if (!animationsEnabled ||
|
2491
|
+
!node ||
|
2492
|
+
!isAnimatableByFilter(node, event, initialOptions) ||
|
2493
|
+
!isAnimatableClassName(node, options)) {
|
2486
2494
|
close();
|
2487
2495
|
return runner;
|
2488
2496
|
}
|
2489
2497
|
|
2490
2498
|
var isStructural = ['enter', 'move', 'leave'].indexOf(event) >= 0;
|
2491
2499
|
|
2492
|
-
var documentHidden =
|
2500
|
+
var documentHidden = $$isDocumentHidden();
|
2493
2501
|
|
2494
|
-
//
|
2495
|
-
//
|
2496
|
-
// past this point if not enabled
|
2502
|
+
// This is a hard disable of all animations the element itself, therefore there is no need to
|
2503
|
+
// continue further past this point if not enabled
|
2497
2504
|
// Animations are also disabled if the document is currently hidden (page is not visible
|
2498
2505
|
// to the user), because browsers slow down or do not flush calls to requestAnimationFrame
|
2499
|
-
var skipAnimations =
|
2506
|
+
var skipAnimations = documentHidden || disabledElementsLookup.get(node);
|
2500
2507
|
var existingAnimation = (!skipAnimations && activeAnimationsLookup.get(node)) || {};
|
2501
2508
|
var hasExistingAnimation = !!existingAnimation.state;
|
2502
2509
|
|
2503
2510
|
// there is no point in traversing the same collection of parent ancestors if a followup
|
2504
2511
|
// animation will be run on the same element that already did all that checking work
|
2505
|
-
if (!skipAnimations && (!hasExistingAnimation || existingAnimation.state
|
2506
|
-
skipAnimations = !areAnimationsAllowed(
|
2512
|
+
if (!skipAnimations && (!hasExistingAnimation || existingAnimation.state !== PRE_DIGEST_STATE)) {
|
2513
|
+
skipAnimations = !areAnimationsAllowed(node, parentNode, event);
|
2507
2514
|
}
|
2508
2515
|
|
2509
2516
|
if (skipAnimations) {
|
2510
2517
|
// Callbacks should fire even if the document is hidden (regression fix for issue #14120)
|
2511
|
-
if (documentHidden) notifyProgress(runner, event, 'start');
|
2518
|
+
if (documentHidden) notifyProgress(runner, event, 'start', getEventData(options));
|
2512
2519
|
close();
|
2513
|
-
if (documentHidden) notifyProgress(runner, event, 'close');
|
2520
|
+
if (documentHidden) notifyProgress(runner, event, 'close', getEventData(options));
|
2514
2521
|
return runner;
|
2515
2522
|
}
|
2516
2523
|
|
2517
2524
|
if (isStructural) {
|
2518
|
-
closeChildAnimations(
|
2525
|
+
closeChildAnimations(node);
|
2519
2526
|
}
|
2520
2527
|
|
2521
2528
|
var newAnimation = {
|
@@ -2530,7 +2537,7 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
2530
2537
|
};
|
2531
2538
|
|
2532
2539
|
if (hasExistingAnimation) {
|
2533
|
-
var skipAnimationFlag = isAllowed('skip',
|
2540
|
+
var skipAnimationFlag = isAllowed('skip', newAnimation, existingAnimation);
|
2534
2541
|
if (skipAnimationFlag) {
|
2535
2542
|
if (existingAnimation.state === RUNNING_STATE) {
|
2536
2543
|
close();
|
@@ -2540,7 +2547,7 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
2540
2547
|
return existingAnimation.runner;
|
2541
2548
|
}
|
2542
2549
|
}
|
2543
|
-
var cancelAnimationFlag = isAllowed('cancel',
|
2550
|
+
var cancelAnimationFlag = isAllowed('cancel', newAnimation, existingAnimation);
|
2544
2551
|
if (cancelAnimationFlag) {
|
2545
2552
|
if (existingAnimation.state === RUNNING_STATE) {
|
2546
2553
|
// this will end the animation right away and it is safe
|
@@ -2562,12 +2569,12 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
2562
2569
|
// a joined animation means that this animation will take over the existing one
|
2563
2570
|
// so an example would involve a leave animation taking over an enter. Then when
|
2564
2571
|
// the postDigest kicks in the enter will be ignored.
|
2565
|
-
var joinAnimationFlag = isAllowed('join',
|
2572
|
+
var joinAnimationFlag = isAllowed('join', newAnimation, existingAnimation);
|
2566
2573
|
if (joinAnimationFlag) {
|
2567
2574
|
if (existingAnimation.state === RUNNING_STATE) {
|
2568
2575
|
normalizeAnimationDetails(element, newAnimation);
|
2569
2576
|
} else {
|
2570
|
-
applyGeneratedPreparationClasses(element, isStructural ? event : null, options);
|
2577
|
+
applyGeneratedPreparationClasses($$jqLite, element, isStructural ? event : null, options);
|
2571
2578
|
|
2572
2579
|
event = newAnimation.event = existingAnimation.event;
|
2573
2580
|
options = mergeAnimationDetails(element, existingAnimation, newAnimation);
|
@@ -2596,7 +2603,7 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
2596
2603
|
|
2597
2604
|
if (!isValidAnimation) {
|
2598
2605
|
close();
|
2599
|
-
clearElementAnimationState(
|
2606
|
+
clearElementAnimationState(node);
|
2600
2607
|
return runner;
|
2601
2608
|
}
|
2602
2609
|
|
@@ -2604,9 +2611,18 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
2604
2611
|
var counter = (existingAnimation.counter || 0) + 1;
|
2605
2612
|
newAnimation.counter = counter;
|
2606
2613
|
|
2607
|
-
markElementAnimationState(
|
2614
|
+
markElementAnimationState(node, PRE_DIGEST_STATE, newAnimation);
|
2608
2615
|
|
2609
2616
|
$rootScope.$$postDigest(function() {
|
2617
|
+
// It is possible that the DOM nodes inside `originalElement` have been replaced. This can
|
2618
|
+
// happen if the animated element is a transcluded clone and also has a `templateUrl`
|
2619
|
+
// directive on it. Therefore, we must recreate `element` in order to interact with the
|
2620
|
+
// actual DOM nodes.
|
2621
|
+
// Note: We still need to use the old `node` for certain things, such as looking up in
|
2622
|
+
// HashMaps where it was used as the key.
|
2623
|
+
|
2624
|
+
element = stripCommentsFromElement(originalElement);
|
2625
|
+
|
2610
2626
|
var animationDetails = activeAnimationsLookup.get(node);
|
2611
2627
|
var animationCancelled = !animationDetails;
|
2612
2628
|
animationDetails = animationDetails || {};
|
@@ -2645,7 +2661,7 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
2645
2661
|
// isn't allowed to animate from here then we need to clear the state of the element
|
2646
2662
|
// so that any future animations won't read the expired animation data.
|
2647
2663
|
if (!isValidAnimation) {
|
2648
|
-
clearElementAnimationState(
|
2664
|
+
clearElementAnimationState(node);
|
2649
2665
|
}
|
2650
2666
|
|
2651
2667
|
return;
|
@@ -2657,21 +2673,21 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
2657
2673
|
? 'setClass'
|
2658
2674
|
: animationDetails.event;
|
2659
2675
|
|
2660
|
-
markElementAnimationState(
|
2676
|
+
markElementAnimationState(node, RUNNING_STATE);
|
2661
2677
|
var realRunner = $$animation(element, event, animationDetails.options);
|
2662
2678
|
|
2663
2679
|
// this will update the runner's flow-control events based on
|
2664
2680
|
// the `realRunner` object.
|
2665
2681
|
runner.setHost(realRunner);
|
2666
|
-
notifyProgress(runner, event, 'start',
|
2682
|
+
notifyProgress(runner, event, 'start', getEventData(options));
|
2667
2683
|
|
2668
2684
|
realRunner.done(function(status) {
|
2669
2685
|
close(!status);
|
2670
2686
|
var animationDetails = activeAnimationsLookup.get(node);
|
2671
2687
|
if (animationDetails && animationDetails.counter === counter) {
|
2672
|
-
clearElementAnimationState(
|
2688
|
+
clearElementAnimationState(node);
|
2673
2689
|
}
|
2674
|
-
notifyProgress(runner, event, 'close',
|
2690
|
+
notifyProgress(runner, event, 'close', getEventData(options));
|
2675
2691
|
});
|
2676
2692
|
});
|
2677
2693
|
|
@@ -2679,7 +2695,7 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
2679
2695
|
|
2680
2696
|
function notifyProgress(runner, event, phase, data) {
|
2681
2697
|
runInNextPostDigestOrNow(function() {
|
2682
|
-
var callbacks = findCallbacks(
|
2698
|
+
var callbacks = findCallbacks(parentNode, node, event);
|
2683
2699
|
if (callbacks.length) {
|
2684
2700
|
// do not optimize this call here to RAF because
|
2685
2701
|
// we don't know how heavy the callback code here will
|
@@ -2689,16 +2705,16 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
2689
2705
|
forEach(callbacks, function(callback) {
|
2690
2706
|
callback(element, phase, data);
|
2691
2707
|
});
|
2692
|
-
cleanupEventListeners(phase,
|
2708
|
+
cleanupEventListeners(phase, node);
|
2693
2709
|
});
|
2694
2710
|
} else {
|
2695
|
-
cleanupEventListeners(phase,
|
2711
|
+
cleanupEventListeners(phase, node);
|
2696
2712
|
}
|
2697
2713
|
});
|
2698
2714
|
runner.progress(event, phase, data);
|
2699
2715
|
}
|
2700
2716
|
|
2701
|
-
function close(reject) {
|
2717
|
+
function close(reject) {
|
2702
2718
|
clearGeneratedClasses(element, options);
|
2703
2719
|
applyAnimationClasses(element, options);
|
2704
2720
|
applyAnimationStyles(element, options);
|
@@ -2707,11 +2723,10 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
2707
2723
|
}
|
2708
2724
|
}
|
2709
2725
|
|
2710
|
-
function closeChildAnimations(
|
2711
|
-
var node = getDomNode(element);
|
2726
|
+
function closeChildAnimations(node) {
|
2712
2727
|
var children = node.querySelectorAll('[' + NG_ANIMATE_ATTR_NAME + ']');
|
2713
2728
|
forEach(children, function(child) {
|
2714
|
-
var state = parseInt(child.getAttribute(NG_ANIMATE_ATTR_NAME));
|
2729
|
+
var state = parseInt(child.getAttribute(NG_ANIMATE_ATTR_NAME), 10);
|
2715
2730
|
var animationDetails = activeAnimationsLookup.get(child);
|
2716
2731
|
if (animationDetails) {
|
2717
2732
|
switch (state) {
|
@@ -2719,21 +2734,16 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
2719
2734
|
animationDetails.runner.end();
|
2720
2735
|
/* falls through */
|
2721
2736
|
case PRE_DIGEST_STATE:
|
2722
|
-
activeAnimationsLookup.
|
2737
|
+
activeAnimationsLookup.delete(child);
|
2723
2738
|
break;
|
2724
2739
|
}
|
2725
2740
|
}
|
2726
2741
|
});
|
2727
2742
|
}
|
2728
2743
|
|
2729
|
-
function clearElementAnimationState(
|
2730
|
-
var node = getDomNode(element);
|
2744
|
+
function clearElementAnimationState(node) {
|
2731
2745
|
node.removeAttribute(NG_ANIMATE_ATTR_NAME);
|
2732
|
-
activeAnimationsLookup.
|
2733
|
-
}
|
2734
|
-
|
2735
|
-
function isMatchingElement(nodeOrElmA, nodeOrElmB) {
|
2736
|
-
return getDomNode(nodeOrElmA) === getDomNode(nodeOrElmB);
|
2746
|
+
activeAnimationsLookup.delete(node);
|
2737
2747
|
}
|
2738
2748
|
|
2739
2749
|
/**
|
@@ -2743,54 +2753,54 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
2743
2753
|
* c) the element is not a child of the body
|
2744
2754
|
* d) the element is not a child of the $rootElement
|
2745
2755
|
*/
|
2746
|
-
function areAnimationsAllowed(
|
2747
|
-
var
|
2748
|
-
var
|
2749
|
-
|
2756
|
+
function areAnimationsAllowed(node, parentNode, event) {
|
2757
|
+
var bodyNode = $document[0].body;
|
2758
|
+
var rootNode = getDomNode($rootElement);
|
2759
|
+
|
2760
|
+
var bodyNodeDetected = (node === bodyNode) || node.nodeName === 'HTML';
|
2761
|
+
var rootNodeDetected = (node === rootNode);
|
2750
2762
|
var parentAnimationDetected = false;
|
2763
|
+
var elementDisabled = disabledElementsLookup.get(node);
|
2751
2764
|
var animateChildren;
|
2752
|
-
var elementDisabled = disabledElementsLookup.get(getDomNode(element));
|
2753
2765
|
|
2754
|
-
var parentHost = jqLite.data(
|
2766
|
+
var parentHost = jqLite.data(node, NG_ANIMATE_PIN_DATA);
|
2755
2767
|
if (parentHost) {
|
2756
|
-
|
2768
|
+
parentNode = getDomNode(parentHost);
|
2757
2769
|
}
|
2758
2770
|
|
2759
|
-
|
2760
|
-
|
2761
|
-
|
2762
|
-
if (!rootElementDetected) {
|
2763
|
-
// angular doesn't want to attempt to animate elements outside of the application
|
2771
|
+
while (parentNode) {
|
2772
|
+
if (!rootNodeDetected) {
|
2773
|
+
// AngularJS doesn't want to attempt to animate elements outside of the application
|
2764
2774
|
// therefore we need to ensure that the rootElement is an ancestor of the current element
|
2765
|
-
|
2775
|
+
rootNodeDetected = (parentNode === rootNode);
|
2766
2776
|
}
|
2767
2777
|
|
2768
|
-
if (
|
2778
|
+
if (parentNode.nodeType !== ELEMENT_NODE) {
|
2769
2779
|
// no point in inspecting the #document element
|
2770
2780
|
break;
|
2771
2781
|
}
|
2772
2782
|
|
2773
|
-
var details = activeAnimationsLookup.get(
|
2783
|
+
var details = activeAnimationsLookup.get(parentNode) || {};
|
2774
2784
|
// either an enter, leave or move animation will commence
|
2775
2785
|
// therefore we can't allow any animations to take place
|
2776
2786
|
// but if a parent animation is class-based then that's ok
|
2777
2787
|
if (!parentAnimationDetected) {
|
2778
|
-
var
|
2788
|
+
var parentNodeDisabled = disabledElementsLookup.get(parentNode);
|
2779
2789
|
|
2780
|
-
if (
|
2790
|
+
if (parentNodeDisabled === true && elementDisabled !== false) {
|
2781
2791
|
// disable animations if the user hasn't explicitly enabled animations on the
|
2782
2792
|
// current element
|
2783
2793
|
elementDisabled = true;
|
2784
2794
|
// element is disabled via parent element, no need to check anything else
|
2785
2795
|
break;
|
2786
|
-
} else if (
|
2796
|
+
} else if (parentNodeDisabled === false) {
|
2787
2797
|
elementDisabled = false;
|
2788
2798
|
}
|
2789
2799
|
parentAnimationDetected = details.structural;
|
2790
2800
|
}
|
2791
2801
|
|
2792
2802
|
if (isUndefined(animateChildren) || animateChildren === true) {
|
2793
|
-
var value = jqLite.data(
|
2803
|
+
var value = jqLite.data(parentNode, NG_ANIMATE_CHILDREN_DATA);
|
2794
2804
|
if (isDefined(value)) {
|
2795
2805
|
animateChildren = value;
|
2796
2806
|
}
|
@@ -2799,57 +2809,115 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
2799
2809
|
// there is no need to continue traversing at this point
|
2800
2810
|
if (parentAnimationDetected && animateChildren === false) break;
|
2801
2811
|
|
2802
|
-
if (!
|
2812
|
+
if (!bodyNodeDetected) {
|
2803
2813
|
// we also need to ensure that the element is or will be a part of the body element
|
2804
2814
|
// otherwise it is pointless to even issue an animation to be rendered
|
2805
|
-
|
2815
|
+
bodyNodeDetected = (parentNode === bodyNode);
|
2806
2816
|
}
|
2807
2817
|
|
2808
|
-
if (
|
2818
|
+
if (bodyNodeDetected && rootNodeDetected) {
|
2809
2819
|
// If both body and root have been found, any other checks are pointless,
|
2810
2820
|
// as no animation data should live outside the application
|
2811
2821
|
break;
|
2812
2822
|
}
|
2813
2823
|
|
2814
|
-
if (!
|
2815
|
-
// If
|
2816
|
-
parentHost = jqLite.data(
|
2824
|
+
if (!rootNodeDetected) {
|
2825
|
+
// If `rootNode` is not detected, check if `parentNode` is pinned to another element
|
2826
|
+
parentHost = jqLite.data(parentNode, NG_ANIMATE_PIN_DATA);
|
2817
2827
|
if (parentHost) {
|
2818
2828
|
// The pin target element becomes the next parent element
|
2819
|
-
|
2829
|
+
parentNode = getDomNode(parentHost);
|
2820
2830
|
continue;
|
2821
2831
|
}
|
2822
2832
|
}
|
2823
2833
|
|
2824
|
-
|
2834
|
+
parentNode = parentNode.parentNode;
|
2825
2835
|
}
|
2826
2836
|
|
2827
2837
|
var allowAnimation = (!parentAnimationDetected || animateChildren) && elementDisabled !== true;
|
2828
|
-
return allowAnimation &&
|
2838
|
+
return allowAnimation && rootNodeDetected && bodyNodeDetected;
|
2829
2839
|
}
|
2830
2840
|
|
2831
|
-
function markElementAnimationState(
|
2841
|
+
function markElementAnimationState(node, state, details) {
|
2832
2842
|
details = details || {};
|
2833
2843
|
details.state = state;
|
2834
2844
|
|
2835
|
-
var node = getDomNode(element);
|
2836
2845
|
node.setAttribute(NG_ANIMATE_ATTR_NAME, state);
|
2837
2846
|
|
2838
2847
|
var oldValue = activeAnimationsLookup.get(node);
|
2839
2848
|
var newValue = oldValue
|
2840
2849
|
? extend(oldValue, details)
|
2841
2850
|
: details;
|
2842
|
-
activeAnimationsLookup.
|
2851
|
+
activeAnimationsLookup.set(node, newValue);
|
2843
2852
|
}
|
2844
2853
|
}];
|
2845
2854
|
}];
|
2846
2855
|
|
2847
|
-
|
2856
|
+
/** @this */
|
2857
|
+
var $$AnimateCacheProvider = function() {
|
2858
|
+
|
2859
|
+
var KEY = '$$ngAnimateParentKey';
|
2860
|
+
var parentCounter = 0;
|
2861
|
+
var cache = Object.create(null);
|
2862
|
+
|
2863
|
+
this.$get = [function() {
|
2864
|
+
return {
|
2865
|
+
cacheKey: function(node, method, addClass, removeClass) {
|
2866
|
+
var parentNode = node.parentNode;
|
2867
|
+
var parentID = parentNode[KEY] || (parentNode[KEY] = ++parentCounter);
|
2868
|
+
var parts = [parentID, method, node.getAttribute('class')];
|
2869
|
+
if (addClass) {
|
2870
|
+
parts.push(addClass);
|
2871
|
+
}
|
2872
|
+
if (removeClass) {
|
2873
|
+
parts.push(removeClass);
|
2874
|
+
}
|
2875
|
+
return parts.join(' ');
|
2876
|
+
},
|
2877
|
+
|
2878
|
+
containsCachedAnimationWithoutDuration: function(key) {
|
2879
|
+
var entry = cache[key];
|
2880
|
+
|
2881
|
+
// nothing cached, so go ahead and animate
|
2882
|
+
// otherwise it should be a valid animation
|
2883
|
+
return (entry && !entry.isValid) || false;
|
2884
|
+
},
|
2885
|
+
|
2886
|
+
flush: function() {
|
2887
|
+
cache = Object.create(null);
|
2888
|
+
},
|
2889
|
+
|
2890
|
+
count: function(key) {
|
2891
|
+
var entry = cache[key];
|
2892
|
+
return entry ? entry.total : 0;
|
2893
|
+
},
|
2894
|
+
|
2895
|
+
get: function(key) {
|
2896
|
+
var entry = cache[key];
|
2897
|
+
return entry && entry.value;
|
2898
|
+
},
|
2899
|
+
|
2900
|
+
put: function(key, value, isValid) {
|
2901
|
+
if (!cache[key]) {
|
2902
|
+
cache[key] = { total: 1, value: value, isValid: isValid };
|
2903
|
+
} else {
|
2904
|
+
cache[key].total++;
|
2905
|
+
cache[key].value = value;
|
2906
|
+
}
|
2907
|
+
}
|
2908
|
+
};
|
2909
|
+
}];
|
2910
|
+
};
|
2911
|
+
|
2912
|
+
/* exported $$AnimationProvider */
|
2913
|
+
|
2914
|
+
var $$AnimationProvider = ['$animateProvider', /** @this */ function($animateProvider) {
|
2848
2915
|
var NG_ANIMATE_REF_ATTR = 'ng-animate-ref';
|
2849
2916
|
|
2850
2917
|
var drivers = this.drivers = [];
|
2851
2918
|
|
2852
2919
|
var RUNNER_STORAGE_KEY = '$$animationRunner';
|
2920
|
+
var PREPARE_CLASSES_KEY = '$$animatePrepareClasses';
|
2853
2921
|
|
2854
2922
|
function setRunner(element, runner) {
|
2855
2923
|
element.data(RUNNER_STORAGE_KEY, runner);
|
@@ -2863,22 +2931,23 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
|
|
2863
2931
|
return element.data(RUNNER_STORAGE_KEY);
|
2864
2932
|
}
|
2865
2933
|
|
2866
|
-
this.$get = ['$$jqLite', '$rootScope', '$injector', '$$AnimateRunner', '$$
|
2867
|
-
function($$jqLite, $rootScope, $injector, $$AnimateRunner, $$
|
2934
|
+
this.$get = ['$$jqLite', '$rootScope', '$injector', '$$AnimateRunner', '$$Map', '$$rAFScheduler', '$$animateCache',
|
2935
|
+
function($$jqLite, $rootScope, $injector, $$AnimateRunner, $$Map, $$rAFScheduler, $$animateCache) {
|
2868
2936
|
|
2869
2937
|
var animationQueue = [];
|
2870
2938
|
var applyAnimationClasses = applyAnimationClassesFactory($$jqLite);
|
2871
2939
|
|
2872
2940
|
function sortAnimations(animations) {
|
2873
2941
|
var tree = { children: [] };
|
2874
|
-
var i, lookup = new $$
|
2942
|
+
var i, lookup = new $$Map();
|
2875
2943
|
|
2876
|
-
// this is done first beforehand so that the
|
2944
|
+
// this is done first beforehand so that the map
|
2877
2945
|
// is filled with a list of the elements that will be animated
|
2878
2946
|
for (i = 0; i < animations.length; i++) {
|
2879
2947
|
var animation = animations[i];
|
2880
|
-
lookup.
|
2948
|
+
lookup.set(animation.domNode, animations[i] = {
|
2881
2949
|
domNode: animation.domNode,
|
2950
|
+
element: animation.element,
|
2882
2951
|
fn: animation.fn,
|
2883
2952
|
children: []
|
2884
2953
|
});
|
@@ -2896,7 +2965,7 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
|
|
2896
2965
|
|
2897
2966
|
var elementNode = entry.domNode;
|
2898
2967
|
var parentNode = elementNode.parentNode;
|
2899
|
-
lookup.
|
2968
|
+
lookup.set(elementNode, entry);
|
2900
2969
|
|
2901
2970
|
var parentEntry;
|
2902
2971
|
while (parentNode) {
|
@@ -2935,7 +3004,7 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
|
|
2935
3004
|
result.push(row);
|
2936
3005
|
row = [];
|
2937
3006
|
}
|
2938
|
-
row.push(entry
|
3007
|
+
row.push(entry);
|
2939
3008
|
entry.children.forEach(function(childEntry) {
|
2940
3009
|
nextLevelEntries++;
|
2941
3010
|
queue.push(childEntry);
|
@@ -2970,8 +3039,6 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
|
|
2970
3039
|
return runner;
|
2971
3040
|
}
|
2972
3041
|
|
2973
|
-
setRunner(element, runner);
|
2974
|
-
|
2975
3042
|
var classes = mergeClasses(element.attr('class'), mergeClasses(options.addClass, options.removeClass));
|
2976
3043
|
var tempClasses = options.tempClasses;
|
2977
3044
|
if (tempClasses) {
|
@@ -2979,12 +3046,12 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
|
|
2979
3046
|
options.tempClasses = null;
|
2980
3047
|
}
|
2981
3048
|
|
2982
|
-
var prepareClassName;
|
2983
3049
|
if (isStructural) {
|
2984
|
-
|
2985
|
-
$$jqLite.addClass(element, prepareClassName);
|
3050
|
+
element.data(PREPARE_CLASSES_KEY, 'ng-' + event + PREPARE_CLASS_SUFFIX);
|
2986
3051
|
}
|
2987
3052
|
|
3053
|
+
setRunner(element, runner);
|
3054
|
+
|
2988
3055
|
animationQueue.push({
|
2989
3056
|
// this data is used by the postDigest code and passed into
|
2990
3057
|
// the driver step function
|
@@ -3024,16 +3091,31 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
|
|
3024
3091
|
var toBeSortedAnimations = [];
|
3025
3092
|
|
3026
3093
|
forEach(groupedAnimations, function(animationEntry) {
|
3094
|
+
var element = animationEntry.from ? animationEntry.from.element : animationEntry.element;
|
3095
|
+
var extraClasses = options.addClass;
|
3096
|
+
|
3097
|
+
extraClasses = (extraClasses ? (extraClasses + ' ') : '') + NG_ANIMATE_CLASSNAME;
|
3098
|
+
var cacheKey = $$animateCache.cacheKey(element[0], animationEntry.event, extraClasses, options.removeClass);
|
3099
|
+
|
3027
3100
|
toBeSortedAnimations.push({
|
3028
|
-
|
3101
|
+
element: element,
|
3102
|
+
domNode: getDomNode(element),
|
3029
3103
|
fn: function triggerAnimationStart() {
|
3104
|
+
var startAnimationFn, closeFn = animationEntry.close;
|
3105
|
+
|
3106
|
+
// in the event that we've cached the animation status for this element
|
3107
|
+
// and it's in fact an invalid animation (something that has duration = 0)
|
3108
|
+
// then we should skip all the heavy work from here on
|
3109
|
+
if ($$animateCache.containsCachedAnimationWithoutDuration(cacheKey)) {
|
3110
|
+
closeFn();
|
3111
|
+
return;
|
3112
|
+
}
|
3113
|
+
|
3030
3114
|
// it's important that we apply the `ng-animate` CSS class and the
|
3031
3115
|
// temporary classes before we do any driver invoking since these
|
3032
3116
|
// CSS classes may be required for proper CSS detection.
|
3033
3117
|
animationEntry.beforeStart();
|
3034
3118
|
|
3035
|
-
var startAnimationFn, closeFn = animationEntry.close;
|
3036
|
-
|
3037
3119
|
// in the event that the element was removed before the digest runs or
|
3038
3120
|
// during the RAF sequencing then we should not trigger the animation.
|
3039
3121
|
var targetElement = animationEntry.anchors
|
@@ -3063,7 +3145,32 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
|
|
3063
3145
|
// we need to sort each of the animations in order of parent to child
|
3064
3146
|
// relationships. This ensures that the child classes are applied at the
|
3065
3147
|
// right time.
|
3066
|
-
|
3148
|
+
var finalAnimations = sortAnimations(toBeSortedAnimations);
|
3149
|
+
for (var i = 0; i < finalAnimations.length; i++) {
|
3150
|
+
var innerArray = finalAnimations[i];
|
3151
|
+
for (var j = 0; j < innerArray.length; j++) {
|
3152
|
+
var entry = innerArray[j];
|
3153
|
+
var element = entry.element;
|
3154
|
+
|
3155
|
+
// the RAFScheduler code only uses functions
|
3156
|
+
finalAnimations[i][j] = entry.fn;
|
3157
|
+
|
3158
|
+
// the first row of elements shouldn't have a prepare-class added to them
|
3159
|
+
// since the elements are at the top of the animation hierarchy and they
|
3160
|
+
// will be applied without a RAF having to pass...
|
3161
|
+
if (i === 0) {
|
3162
|
+
element.removeData(PREPARE_CLASSES_KEY);
|
3163
|
+
continue;
|
3164
|
+
}
|
3165
|
+
|
3166
|
+
var prepareClassName = element.data(PREPARE_CLASSES_KEY);
|
3167
|
+
if (prepareClassName) {
|
3168
|
+
$$jqLite.addClass(element, prepareClassName);
|
3169
|
+
}
|
3170
|
+
}
|
3171
|
+
}
|
3172
|
+
|
3173
|
+
$$rAFScheduler(finalAnimations);
|
3067
3174
|
});
|
3068
3175
|
|
3069
3176
|
return runner;
|
@@ -3201,10 +3308,10 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
|
|
3201
3308
|
}
|
3202
3309
|
|
3203
3310
|
function beforeStart() {
|
3204
|
-
|
3205
|
-
|
3206
|
-
|
3207
|
-
|
3311
|
+
tempClasses = (tempClasses ? (tempClasses + ' ') : '') + NG_ANIMATE_CLASSNAME;
|
3312
|
+
$$jqLite.addClass(element, tempClasses);
|
3313
|
+
|
3314
|
+
var prepareClassName = element.data(PREPARE_CLASSES_KEY);
|
3208
3315
|
if (prepareClassName) {
|
3209
3316
|
$$jqLite.removeClass(element, prepareClassName);
|
3210
3317
|
prepareClassName = null;
|
@@ -3232,7 +3339,7 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
|
|
3232
3339
|
}
|
3233
3340
|
}
|
3234
3341
|
|
3235
|
-
function close(rejected) {
|
3342
|
+
function close(rejected) {
|
3236
3343
|
element.off('$destroy', handleDestroyedElement);
|
3237
3344
|
removeRunner(element);
|
3238
3345
|
|
@@ -3244,7 +3351,6 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
|
|
3244
3351
|
$$jqLite.removeClass(element, tempClasses);
|
3245
3352
|
}
|
3246
3353
|
|
3247
|
-
element.removeClass(NG_ANIMATE_CLASSNAME);
|
3248
3354
|
runner.complete(!rejected);
|
3249
3355
|
}
|
3250
3356
|
};
|
@@ -3338,12 +3444,13 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
|
|
3338
3444
|
* </file>
|
3339
3445
|
* </example>
|
3340
3446
|
*/
|
3341
|
-
var ngAnimateSwapDirective = ['$animate',
|
3447
|
+
var ngAnimateSwapDirective = ['$animate', function($animate) {
|
3342
3448
|
return {
|
3343
3449
|
restrict: 'A',
|
3344
3450
|
transclude: 'element',
|
3345
3451
|
terminal: true,
|
3346
|
-
priority:
|
3452
|
+
priority: 550, // We use 550 here to ensure that the directive is caught before others,
|
3453
|
+
// but after `ngIf` (at priority 600).
|
3347
3454
|
link: function(scope, $element, attrs, ctrl, $transclude) {
|
3348
3455
|
var previousElement, previousScope;
|
3349
3456
|
scope.$watchCollection(attrs.ngAnimateSwap || attrs['for'], function(value) {
|
@@ -3355,10 +3462,10 @@ var ngAnimateSwapDirective = ['$animate', '$rootScope', function($animate, $root
|
|
3355
3462
|
previousScope = null;
|
3356
3463
|
}
|
3357
3464
|
if (value || value === 0) {
|
3358
|
-
|
3359
|
-
|
3360
|
-
|
3361
|
-
$animate.enter(
|
3465
|
+
$transclude(function(clone, childScope) {
|
3466
|
+
previousElement = clone;
|
3467
|
+
previousScope = childScope;
|
3468
|
+
$animate.enter(clone, null, $element);
|
3362
3469
|
});
|
3363
3470
|
}
|
3364
3471
|
});
|
@@ -3372,11 +3479,9 @@ var ngAnimateSwapDirective = ['$animate', '$rootScope', function($animate, $root
|
|
3372
3479
|
* @description
|
3373
3480
|
*
|
3374
3481
|
* The `ngAnimate` module provides support for CSS-based animations (keyframes and transitions) as well as JavaScript-based animations via
|
3375
|
-
* callback hooks. Animations are not enabled by default, however, by including `ngAnimate` the animation hooks are enabled for an
|
3482
|
+
* callback hooks. Animations are not enabled by default, however, by including `ngAnimate` the animation hooks are enabled for an AngularJS app.
|
3376
3483
|
*
|
3377
|
-
*
|
3378
|
-
*
|
3379
|
-
* # Usage
|
3484
|
+
* ## Usage
|
3380
3485
|
* Simply put, there are two ways to make use of animations when ngAnimate is used: by using **CSS** and **JavaScript**. The former works purely based
|
3381
3486
|
* using CSS (by using matching CSS selectors/styles) and the latter triggers animations that are registered via `module.animation()`. For
|
3382
3487
|
* both CSS and JS animations the sole requirement is to have a matching `CSS class` that exists both in the registered animation and within
|
@@ -3385,25 +3490,33 @@ var ngAnimateSwapDirective = ['$animate', '$rootScope', function($animate, $root
|
|
3385
3490
|
* ## Directive Support
|
3386
3491
|
* The following directives are "animation aware":
|
3387
3492
|
*
|
3388
|
-
* | Directive
|
3389
|
-
*
|
3390
|
-
* | {@link ng.directive:
|
3391
|
-
* | {@link
|
3392
|
-
* | {@link ng.directive:
|
3393
|
-
* | {@link ng.directive:
|
3394
|
-
* | {@link ng.directive:
|
3395
|
-
* | {@link ng.directive:
|
3396
|
-
* | {@link ng.directive:
|
3397
|
-
* | {@link ng.directive:
|
3398
|
-
* | {@link module:ngMessages#animations
|
3399
|
-
* | {@link module:ngMessages#animations
|
3400
|
-
*
|
3401
|
-
*
|
3493
|
+
* | Directive | Supported Animations |
|
3494
|
+
* |-------------------------------------------------------------------------------|---------------------------------------------------------------------------|
|
3495
|
+
* | {@link ng.directive:form#animations form / ngForm} | add and remove ({@link ng.directive:form#css-classes various classes}) |
|
3496
|
+
* | {@link ngAnimate.directive:ngAnimateSwap#animations ngAnimateSwap} | enter and leave |
|
3497
|
+
* | {@link ng.directive:ngClass#animations ngClass / {{class}​}} | add and remove |
|
3498
|
+
* | {@link ng.directive:ngClassEven#animations ngClassEven} | add and remove |
|
3499
|
+
* | {@link ng.directive:ngClassOdd#animations ngClassOdd} | add and remove |
|
3500
|
+
* | {@link ng.directive:ngHide#animations ngHide} | add and remove (the `ng-hide` class) |
|
3501
|
+
* | {@link ng.directive:ngIf#animations ngIf} | enter and leave |
|
3502
|
+
* | {@link ng.directive:ngInclude#animations ngInclude} | enter and leave |
|
3503
|
+
* | {@link module:ngMessages#animations ngMessage / ngMessageExp} | enter and leave |
|
3504
|
+
* | {@link module:ngMessages#animations ngMessages} | add and remove (the `ng-active`/`ng-inactive` classes) |
|
3505
|
+
* | {@link ng.directive:ngModel#animations ngModel} | add and remove ({@link ng.directive:ngModel#css-classes various classes}) |
|
3506
|
+
* | {@link ng.directive:ngRepeat#animations ngRepeat} | enter, leave, and move |
|
3507
|
+
* | {@link ng.directive:ngShow#animations ngShow} | add and remove (the `ng-hide` class) |
|
3508
|
+
* | {@link ng.directive:ngSwitch#animations ngSwitch} | enter and leave |
|
3509
|
+
* | {@link ngRoute.directive:ngView#animations ngView} | enter and leave |
|
3510
|
+
*
|
3511
|
+
* (More information can be found by visiting the documentation associated with each directive.)
|
3512
|
+
*
|
3513
|
+
* For a full breakdown of the steps involved during each animation event, refer to the
|
3514
|
+
* {@link ng.$animate `$animate` API docs}.
|
3402
3515
|
*
|
3403
3516
|
* ## CSS-based Animations
|
3404
3517
|
*
|
3405
3518
|
* CSS-based animations with ngAnimate are unique since they require no JavaScript code at all. By using a CSS class that we reference between our HTML
|
3406
|
-
* and CSS code we can create an animation that will be picked up by
|
3519
|
+
* and CSS code we can create an animation that will be picked up by AngularJS when an underlying directive performs an operation.
|
3407
3520
|
*
|
3408
3521
|
* The example below shows how an `enter` animation can be made possible on an element using `ng-if`:
|
3409
3522
|
*
|
@@ -3543,6 +3656,10 @@ var ngAnimateSwapDirective = ['$animate', '$rootScope', function($animate, $root
|
|
3543
3656
|
* /* As of 1.4.4, this must always be set: it signals ngAnimate
|
3544
3657
|
* to not accidentally inherit a delay property from another CSS class */
|
3545
3658
|
* transition-duration: 0s;
|
3659
|
+
*
|
3660
|
+
* /* if you are using animations instead of transitions you should configure as follows:
|
3661
|
+
* animation-delay: 0.1s;
|
3662
|
+
* animation-duration: 0s; */
|
3546
3663
|
* }
|
3547
3664
|
* .my-animation.ng-enter.ng-enter-active {
|
3548
3665
|
* /* standard transition styles */
|
@@ -3631,9 +3748,22 @@ var ngAnimateSwapDirective = ['$animate', '$rootScope', function($animate, $root
|
|
3631
3748
|
* .message.ng-enter-prepare {
|
3632
3749
|
* opacity: 0;
|
3633
3750
|
* }
|
3634
|
-
*
|
3635
3751
|
* ```
|
3636
3752
|
*
|
3753
|
+
* ### Animating between value changes
|
3754
|
+
*
|
3755
|
+
* Sometimes you need to animate between different expression states, whose values
|
3756
|
+
* don't necessary need to be known or referenced in CSS styles.
|
3757
|
+
* Unless possible with another {@link ngAnimate#directive-support "animation aware" directive},
|
3758
|
+
* that specific use case can always be covered with {@link ngAnimate.directive:ngAnimateSwap} as
|
3759
|
+
* can be seen in {@link ngAnimate.directive:ngAnimateSwap#examples this example}.
|
3760
|
+
*
|
3761
|
+
* Note that {@link ngAnimate.directive:ngAnimateSwap} is a *structural directive*, which means it
|
3762
|
+
* creates a new instance of the element (including any other/child directives it may have) and
|
3763
|
+
* links it to a new scope every time *swap* happens. In some cases this might not be desirable
|
3764
|
+
* (e.g. for performance reasons, or when you wish to retain internal state on the original
|
3765
|
+
* element instance).
|
3766
|
+
*
|
3637
3767
|
* ## JavaScript-based Animations
|
3638
3768
|
*
|
3639
3769
|
* ngAnimate also allows for animations to be consumed by JavaScript code. The approach is similar to CSS-based animations (where there is a shared
|
@@ -3658,7 +3788,7 @@ var ngAnimateSwapDirective = ['$animate', '$rootScope', function($animate, $root
|
|
3658
3788
|
* enter: function(element, doneFn) {
|
3659
3789
|
* jQuery(element).fadeIn(1000, doneFn);
|
3660
3790
|
*
|
3661
|
-
* // remember to call doneFn so that
|
3791
|
+
* // remember to call doneFn so that AngularJS
|
3662
3792
|
* // knows that the animation has concluded
|
3663
3793
|
* },
|
3664
3794
|
*
|
@@ -3706,7 +3836,7 @@ var ngAnimateSwapDirective = ['$animate', '$rootScope', function($animate, $root
|
|
3706
3836
|
*
|
3707
3837
|
* ## CSS + JS Animations Together
|
3708
3838
|
*
|
3709
|
-
* AngularJS 1.4 and higher has taken steps to make the amalgamation of CSS and JS animations more flexible. However, unlike earlier versions of
|
3839
|
+
* AngularJS 1.4 and higher has taken steps to make the amalgamation of CSS and JS animations more flexible. However, unlike earlier versions of AngularJS,
|
3710
3840
|
* defining CSS and JS animations to work off of the same CSS class will not work anymore. Therefore the example below will only result in **JS animations taking
|
3711
3841
|
* charge of the animation**:
|
3712
3842
|
*
|
@@ -3898,7 +4028,7 @@ var ngAnimateSwapDirective = ['$animate', '$rootScope', function($animate, $root
|
|
3898
4028
|
deps="angular-animate.js;angular-route.js"
|
3899
4029
|
animations="true">
|
3900
4030
|
<file name="index.html">
|
3901
|
-
<a href="
|
4031
|
+
<a href="#!/">Home</a>
|
3902
4032
|
<hr />
|
3903
4033
|
<div class="view-container">
|
3904
4034
|
<div ng-view class="view"></div>
|
@@ -3918,22 +4048,23 @@ var ngAnimateSwapDirective = ['$animate', '$rootScope', function($animate, $root
|
|
3918
4048
|
}])
|
3919
4049
|
.run(['$rootScope', function($rootScope) {
|
3920
4050
|
$rootScope.records = [
|
3921
|
-
{ id:1, title:
|
3922
|
-
{ id:2, title:
|
3923
|
-
{ id:3, title:
|
3924
|
-
{ id:4, title:
|
3925
|
-
{ id:5, title:
|
3926
|
-
{ id:6, title:
|
3927
|
-
{ id:7, title:
|
3928
|
-
{ id:8, title:
|
3929
|
-
{ id:9, title:
|
3930
|
-
{ id:10, title:
|
4051
|
+
{ id: 1, title: 'Miss Beulah Roob' },
|
4052
|
+
{ id: 2, title: 'Trent Morissette' },
|
4053
|
+
{ id: 3, title: 'Miss Ava Pouros' },
|
4054
|
+
{ id: 4, title: 'Rod Pouros' },
|
4055
|
+
{ id: 5, title: 'Abdul Rice' },
|
4056
|
+
{ id: 6, title: 'Laurie Rutherford Sr.' },
|
4057
|
+
{ id: 7, title: 'Nakia McLaughlin' },
|
4058
|
+
{ id: 8, title: 'Jordon Blanda DVM' },
|
4059
|
+
{ id: 9, title: 'Rhoda Hand' },
|
4060
|
+
{ id: 10, title: 'Alexandrea Sauer' }
|
3931
4061
|
];
|
3932
4062
|
}])
|
3933
4063
|
.controller('HomeController', [function() {
|
3934
4064
|
//empty
|
3935
4065
|
}])
|
3936
|
-
.controller('ProfileController', ['$rootScope', '$routeParams',
|
4066
|
+
.controller('ProfileController', ['$rootScope', '$routeParams',
|
4067
|
+
function ProfileController($rootScope, $routeParams) {
|
3937
4068
|
var index = parseInt($routeParams.id, 10);
|
3938
4069
|
var record = $rootScope.records[index - 1];
|
3939
4070
|
|
@@ -3945,7 +4076,7 @@ var ngAnimateSwapDirective = ['$animate', '$rootScope', function($animate, $root
|
|
3945
4076
|
<h2>Welcome to the home page</h1>
|
3946
4077
|
<p>Please click on an element</p>
|
3947
4078
|
<a class="record"
|
3948
|
-
ng-href="
|
4079
|
+
ng-href="#!/profile/{{ record.id }}"
|
3949
4080
|
ng-animate-ref="{{ record.id }}"
|
3950
4081
|
ng-repeat="record in records">
|
3951
4082
|
{{ record.title }}
|
@@ -4021,7 +4152,7 @@ var ngAnimateSwapDirective = ['$animate', '$rootScope', function($animate, $root
|
|
4021
4152
|
*
|
4022
4153
|
* ## Using $animate in your directive code
|
4023
4154
|
*
|
4024
|
-
* So far we've explored how to feed in animations into an
|
4155
|
+
* So far we've explored how to feed in animations into an AngularJS application, but how do we trigger animations within our own directives in our application?
|
4025
4156
|
* By injecting the `$animate` service into our directive code, we can trigger structural and class-based hooks which can then be consumed by animations. Let's
|
4026
4157
|
* imagine we have a greeting box that shows and hides itself when the data changes
|
4027
4158
|
*
|
@@ -4064,7 +4195,7 @@ var ngAnimateSwapDirective = ['$animate', '$rootScope', function($animate, $root
|
|
4064
4195
|
* });
|
4065
4196
|
* ```
|
4066
4197
|
*
|
4067
|
-
* (Note that earlier versions of
|
4198
|
+
* (Note that earlier versions of AngularJS prior to v1.4 required the promise code to be wrapped using `$scope.$apply(...)`. This is not the case
|
4068
4199
|
* anymore.)
|
4069
4200
|
*
|
4070
4201
|
* In addition to the animation promise, we can also make use of animation-related callbacks within our directives and controller code by registering
|
@@ -4079,7 +4210,7 @@ var ngAnimateSwapDirective = ['$animate', '$rootScope', function($animate, $root
|
|
4079
4210
|
* }])
|
4080
4211
|
* ```
|
4081
4212
|
*
|
4082
|
-
* (Note that you will need to trigger a digest within the callback to get
|
4213
|
+
* (Note that you will need to trigger a digest within the callback to get AngularJS to notice any scope-related changes.)
|
4083
4214
|
*/
|
4084
4215
|
|
4085
4216
|
var copy;
|
@@ -4106,7 +4237,7 @@ var noop;
|
|
4106
4237
|
* Click here {@link ng.$animate to learn more about animations with `$animate`}.
|
4107
4238
|
*/
|
4108
4239
|
angular.module('ngAnimate', [], function initAngularHelpers() {
|
4109
|
-
// Access helpers from
|
4240
|
+
// Access helpers from AngularJS core.
|
4110
4241
|
// Do it inside a `config` block to ensure `window.angular` is available.
|
4111
4242
|
noop = angular.noop;
|
4112
4243
|
copy = angular.copy;
|
@@ -4121,12 +4252,14 @@ angular.module('ngAnimate', [], function initAngularHelpers() {
|
|
4121
4252
|
isFunction = angular.isFunction;
|
4122
4253
|
isElement = angular.isElement;
|
4123
4254
|
})
|
4255
|
+
.info({ angularVersion: '1.8.0' })
|
4124
4256
|
.directive('ngAnimateSwap', ngAnimateSwapDirective)
|
4125
4257
|
|
4126
4258
|
.directive('ngAnimateChildren', $$AnimateChildrenDirective)
|
4127
4259
|
.factory('$$rAFScheduler', $$rAFSchedulerFactory)
|
4128
4260
|
|
4129
4261
|
.provider('$$animateQueue', $$AnimateQueueProvider)
|
4262
|
+
.provider('$$animateCache', $$AnimateCacheProvider)
|
4130
4263
|
.provider('$$animation', $$AnimationProvider)
|
4131
4264
|
|
4132
4265
|
.provider('$animateCss', $AnimateCssProvider)
|