angularjs-rails 1.5.8 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
[](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)
|