rails-angularjs 1.4.3 → 1.4.9
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 +5 -1
- data/lib/rails-angularjs/version.rb +1 -1
- data/vendor/assets/javascripts/angular-animate.js +697 -545
- data/vendor/assets/javascripts/angular-animate.min.js +50 -47
- data/vendor/assets/javascripts/angular-animate.min.js.map +3 -3
- data/vendor/assets/javascripts/angular-aria.js +42 -37
- data/vendor/assets/javascripts/angular-aria.min.js +9 -8
- data/vendor/assets/javascripts/angular-aria.min.js.map +3 -3
- data/vendor/assets/javascripts/angular-cookies.js +3 -3
- data/vendor/assets/javascripts/angular-cookies.min.js +4 -4
- data/vendor/assets/javascripts/angular-cookies.min.js.map +2 -2
- data/vendor/assets/javascripts/angular-csp.css +21 -0
- data/vendor/assets/javascripts/angular-loader.js +34 -6
- data/vendor/assets/javascripts/angular-loader.min.js +2 -2
- data/vendor/assets/javascripts/angular-loader.min.js.map +1 -1
- data/vendor/assets/javascripts/angular-message-format.js +1 -1
- data/vendor/assets/javascripts/angular-message-format.min.js +1 -1
- data/vendor/assets/javascripts/angular-messages.js +9 -2
- data/vendor/assets/javascripts/angular-messages.min.js +7 -6
- data/vendor/assets/javascripts/angular-messages.min.js.map +3 -3
- data/vendor/assets/javascripts/angular-mocks.js +152 -39
- data/vendor/assets/javascripts/angular-resource.js +36 -11
- data/vendor/assets/javascripts/angular-resource.min.js +9 -8
- data/vendor/assets/javascripts/angular-resource.min.js.map +3 -3
- data/vendor/assets/javascripts/angular-route.js +1 -2
- data/vendor/assets/javascripts/angular-route.min.js +1 -1
- data/vendor/assets/javascripts/angular-route.min.js.map +1 -1
- data/vendor/assets/javascripts/angular-sanitize.js +2 -2
- data/vendor/assets/javascripts/angular-sanitize.min.js +1 -1
- data/vendor/assets/javascripts/angular-scenario.js +2497 -1191
- data/vendor/assets/javascripts/angular-touch.js +2 -3
- data/vendor/assets/javascripts/angular-touch.min.js +1 -1
- data/vendor/assets/javascripts/angular-touch.min.js.map +1 -1
- data/vendor/assets/javascripts/angular.js +2489 -1196
- data/vendor/assets/javascripts/angular.min.js +293 -285
- data/vendor/assets/javascripts/angular.min.js.map +3 -3
- metadata +4 -3
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.4.
|
2
|
+
* @license AngularJS v1.4.9
|
3
3
|
* (c) 2010-2015 Google, Inc. http://angularjs.org
|
4
4
|
* License: MIT
|
5
5
|
*/
|
@@ -7,6 +7,7 @@
|
|
7
7
|
|
8
8
|
/* jshint ignore:start */
|
9
9
|
var noop = angular.noop;
|
10
|
+
var copy = angular.copy;
|
10
11
|
var extend = angular.extend;
|
11
12
|
var jqLite = angular.element;
|
12
13
|
var forEach = angular.forEach;
|
@@ -21,13 +22,62 @@ var isElement = angular.isElement;
|
|
21
22
|
var ELEMENT_NODE = 1;
|
22
23
|
var COMMENT_NODE = 8;
|
23
24
|
|
25
|
+
var ADD_CLASS_SUFFIX = '-add';
|
26
|
+
var REMOVE_CLASS_SUFFIX = '-remove';
|
27
|
+
var EVENT_CLASS_PREFIX = 'ng-';
|
28
|
+
var ACTIVE_CLASS_SUFFIX = '-active';
|
29
|
+
|
24
30
|
var NG_ANIMATE_CLASSNAME = 'ng-animate';
|
25
31
|
var NG_ANIMATE_CHILDREN_DATA = '$$ngAnimateChildren';
|
26
32
|
|
33
|
+
// Detect proper transitionend/animationend event names.
|
34
|
+
var CSS_PREFIX = '', TRANSITION_PROP, TRANSITIONEND_EVENT, ANIMATION_PROP, ANIMATIONEND_EVENT;
|
35
|
+
|
36
|
+
// If unprefixed events are not supported but webkit-prefixed are, use the latter.
|
37
|
+
// Otherwise, just use W3C names, browsers not supporting them at all will just ignore them.
|
38
|
+
// Note: Chrome implements `window.onwebkitanimationend` and doesn't implement `window.onanimationend`
|
39
|
+
// but at the same time dispatches the `animationend` event and not `webkitAnimationEnd`.
|
40
|
+
// Register both events in case `window.onanimationend` is not supported because of that,
|
41
|
+
// do the same for `transitionend` as Safari is likely to exhibit similar behavior.
|
42
|
+
// Also, the only modern browser that uses vendor prefixes for transitions/keyframes is webkit
|
43
|
+
// therefore there is no reason to test anymore for other vendor prefixes:
|
44
|
+
// http://caniuse.com/#search=transition
|
45
|
+
if (isUndefined(window.ontransitionend) && isDefined(window.onwebkittransitionend)) {
|
46
|
+
CSS_PREFIX = '-webkit-';
|
47
|
+
TRANSITION_PROP = 'WebkitTransition';
|
48
|
+
TRANSITIONEND_EVENT = 'webkitTransitionEnd transitionend';
|
49
|
+
} else {
|
50
|
+
TRANSITION_PROP = 'transition';
|
51
|
+
TRANSITIONEND_EVENT = 'transitionend';
|
52
|
+
}
|
53
|
+
|
54
|
+
if (isUndefined(window.onanimationend) && isDefined(window.onwebkitanimationend)) {
|
55
|
+
CSS_PREFIX = '-webkit-';
|
56
|
+
ANIMATION_PROP = 'WebkitAnimation';
|
57
|
+
ANIMATIONEND_EVENT = 'webkitAnimationEnd animationend';
|
58
|
+
} else {
|
59
|
+
ANIMATION_PROP = 'animation';
|
60
|
+
ANIMATIONEND_EVENT = 'animationend';
|
61
|
+
}
|
62
|
+
|
63
|
+
var DURATION_KEY = 'Duration';
|
64
|
+
var PROPERTY_KEY = 'Property';
|
65
|
+
var DELAY_KEY = 'Delay';
|
66
|
+
var TIMING_KEY = 'TimingFunction';
|
67
|
+
var ANIMATION_ITERATION_COUNT_KEY = 'IterationCount';
|
68
|
+
var ANIMATION_PLAYSTATE_KEY = 'PlayState';
|
69
|
+
var SAFE_FAST_FORWARD_DURATION_VALUE = 9999;
|
70
|
+
|
71
|
+
var ANIMATION_DELAY_PROP = ANIMATION_PROP + DELAY_KEY;
|
72
|
+
var ANIMATION_DURATION_PROP = ANIMATION_PROP + DURATION_KEY;
|
73
|
+
var TRANSITION_DELAY_PROP = TRANSITION_PROP + DELAY_KEY;
|
74
|
+
var TRANSITION_DURATION_PROP = TRANSITION_PROP + DURATION_KEY;
|
75
|
+
|
27
76
|
var isPromiseLike = function(p) {
|
28
77
|
return p && p.then ? true : false;
|
29
|
-
}
|
78
|
+
};
|
30
79
|
|
80
|
+
var ngMinErr = angular.$$minErr('ng');
|
31
81
|
function assertArg(arg, name, reason) {
|
32
82
|
if (!arg) {
|
33
83
|
throw ngMinErr('areq', "Argument '{0}' is {1}", (name || '?'), (reason || "required"));
|
@@ -177,8 +227,21 @@ function mergeAnimationOptions(element, target, newOptions) {
|
|
177
227
|
var toRemove = (target.removeClass || '') + ' ' + (newOptions.removeClass || '');
|
178
228
|
var classes = resolveElementClasses(element.attr('class'), toAdd, toRemove);
|
179
229
|
|
230
|
+
if (newOptions.preparationClasses) {
|
231
|
+
target.preparationClasses = concatWithSpace(newOptions.preparationClasses, target.preparationClasses);
|
232
|
+
delete newOptions.preparationClasses;
|
233
|
+
}
|
234
|
+
|
235
|
+
// noop is basically when there is no callback; otherwise something has been set
|
236
|
+
var realDomOperation = target.domOperation !== noop ? target.domOperation : null;
|
237
|
+
|
180
238
|
extend(target, newOptions);
|
181
239
|
|
240
|
+
// TODO(matsko or sreeramu): proper fix is to maintain all animation callback in array and call at last,but now only leave has the callback so no issue with this.
|
241
|
+
if (realDomOperation) {
|
242
|
+
target.domOperation = realDomOperation;
|
243
|
+
}
|
244
|
+
|
182
245
|
if (classes.addClass) {
|
183
246
|
target.addClass = classes.addClass;
|
184
247
|
} else {
|
@@ -256,18 +319,75 @@ function getDomNode(element) {
|
|
256
319
|
return (element instanceof angular.element) ? element[0] : element;
|
257
320
|
}
|
258
321
|
|
322
|
+
function applyGeneratedPreparationClasses(element, event, options) {
|
323
|
+
var classes = '';
|
324
|
+
if (event) {
|
325
|
+
classes = pendClasses(event, EVENT_CLASS_PREFIX, true);
|
326
|
+
}
|
327
|
+
if (options.addClass) {
|
328
|
+
classes = concatWithSpace(classes, pendClasses(options.addClass, ADD_CLASS_SUFFIX));
|
329
|
+
}
|
330
|
+
if (options.removeClass) {
|
331
|
+
classes = concatWithSpace(classes, pendClasses(options.removeClass, REMOVE_CLASS_SUFFIX));
|
332
|
+
}
|
333
|
+
if (classes.length) {
|
334
|
+
options.preparationClasses = classes;
|
335
|
+
element.addClass(classes);
|
336
|
+
}
|
337
|
+
}
|
338
|
+
|
339
|
+
function clearGeneratedClasses(element, options) {
|
340
|
+
if (options.preparationClasses) {
|
341
|
+
element.removeClass(options.preparationClasses);
|
342
|
+
options.preparationClasses = null;
|
343
|
+
}
|
344
|
+
if (options.activeClasses) {
|
345
|
+
element.removeClass(options.activeClasses);
|
346
|
+
options.activeClasses = null;
|
347
|
+
}
|
348
|
+
}
|
349
|
+
|
350
|
+
function blockTransitions(node, duration) {
|
351
|
+
// we use a negative delay value since it performs blocking
|
352
|
+
// yet it doesn't kill any existing transitions running on the
|
353
|
+
// same element which makes this safe for class-based animations
|
354
|
+
var value = duration ? '-' + duration + 's' : '';
|
355
|
+
applyInlineStyle(node, [TRANSITION_DELAY_PROP, value]);
|
356
|
+
return [TRANSITION_DELAY_PROP, value];
|
357
|
+
}
|
358
|
+
|
359
|
+
function blockKeyframeAnimations(node, applyBlock) {
|
360
|
+
var value = applyBlock ? 'paused' : '';
|
361
|
+
var key = ANIMATION_PROP + ANIMATION_PLAYSTATE_KEY;
|
362
|
+
applyInlineStyle(node, [key, value]);
|
363
|
+
return [key, value];
|
364
|
+
}
|
365
|
+
|
366
|
+
function applyInlineStyle(node, styleTuple) {
|
367
|
+
var prop = styleTuple[0];
|
368
|
+
var value = styleTuple[1];
|
369
|
+
node.style[prop] = value;
|
370
|
+
}
|
371
|
+
|
372
|
+
function concatWithSpace(a,b) {
|
373
|
+
if (!a) return b;
|
374
|
+
if (!b) return a;
|
375
|
+
return a + ' ' + b;
|
376
|
+
}
|
377
|
+
|
259
378
|
var $$rAFSchedulerFactory = ['$$rAF', function($$rAF) {
|
260
|
-
var
|
261
|
-
var cancelFn;
|
379
|
+
var queue, cancelFn;
|
262
380
|
|
263
381
|
function scheduler(tasks) {
|
264
382
|
// we make a copy since RAFScheduler mutates the state
|
265
383
|
// of the passed in array variable and this would be difficult
|
266
384
|
// to track down on the outside code
|
267
|
-
|
385
|
+
queue = queue.concat(tasks);
|
268
386
|
nextTick();
|
269
387
|
}
|
270
388
|
|
389
|
+
queue = scheduler.queue = [];
|
390
|
+
|
271
391
|
/* waitUntilQuiet does two things:
|
272
392
|
* 1. It will run the FINAL `fn` value only when an uncancelled RAF has passed through
|
273
393
|
* 2. It will delay the next wave of tasks from running until the quiet `fn` has run.
|
@@ -289,17 +409,12 @@ var $$rAFSchedulerFactory = ['$$rAF', function($$rAF) {
|
|
289
409
|
return scheduler;
|
290
410
|
|
291
411
|
function nextTick() {
|
292
|
-
if (!
|
412
|
+
if (!queue.length) return;
|
293
413
|
|
294
|
-
var
|
295
|
-
for (var i = 0; i <
|
296
|
-
|
297
|
-
runNextTask(innerQueue);
|
298
|
-
if (innerQueue.length) {
|
299
|
-
updatedQueue.push(innerQueue);
|
300
|
-
}
|
414
|
+
var items = queue.shift();
|
415
|
+
for (var i = 0; i < items.length; i++) {
|
416
|
+
items[i]();
|
301
417
|
}
|
302
|
-
tickQueue = updatedQueue;
|
303
418
|
|
304
419
|
if (!cancelFn) {
|
305
420
|
$$rAF(function() {
|
@@ -307,11 +422,6 @@ var $$rAFSchedulerFactory = ['$$rAF', function($$rAF) {
|
|
307
422
|
});
|
308
423
|
}
|
309
424
|
}
|
310
|
-
|
311
|
-
function runNextTask(tasks) {
|
312
|
-
var nextTask = tasks.shift();
|
313
|
-
nextTask();
|
314
|
-
}
|
315
425
|
}];
|
316
426
|
|
317
427
|
var $$AnimateChildrenDirective = [function() {
|
@@ -328,6 +438,8 @@ var $$AnimateChildrenDirective = [function() {
|
|
328
438
|
};
|
329
439
|
}];
|
330
440
|
|
441
|
+
var ANIMATE_TIMER_KEY = '$$animateCss';
|
442
|
+
|
331
443
|
/**
|
332
444
|
* @ngdoc service
|
333
445
|
* @name $animateCss
|
@@ -512,8 +624,10 @@ var $$AnimateChildrenDirective = [function() {
|
|
512
624
|
*
|
513
625
|
* * `event` - The DOM event (e.g. enter, leave, move). When used, a generated CSS class of `ng-EVENT` and `ng-EVENT-active` will be applied
|
514
626
|
* to the element during the animation. Multiple events can be provided when spaces are used as a separator. (Note that this will not perform any DOM operation.)
|
627
|
+
* * `structural` - Indicates that the `ng-` prefix will be added to the event class. Setting to `false` or omitting will turn `ng-EVENT` and
|
628
|
+
* `ng-EVENT-active` in `EVENT` and `EVENT-active`. Unused if `event` is omitted.
|
515
629
|
* * `easing` - The CSS easing value that will be applied to the transition or keyframe animation (or both).
|
516
|
-
* * `
|
630
|
+
* * `transitionStyle` - The raw CSS transition style that will be used (e.g. `1s linear all`).
|
517
631
|
* * `keyframeStyle` - The raw CSS keyframe animation style that will be used (e.g. `1s my_animation linear`).
|
518
632
|
* * `from` - The starting CSS styles (a key/value object) that will be applied at the start of the animation.
|
519
633
|
* * `to` - The ending CSS styles (a key/value object) that will be applied across the animation via a CSS transition.
|
@@ -528,63 +642,23 @@ var $$AnimateChildrenDirective = [function() {
|
|
528
642
|
* * `stagger` - A numeric time value representing the delay between successively animated elements
|
529
643
|
* ({@link ngAnimate#css-staggering-animations Click here to learn how CSS-based staggering works in ngAnimate.})
|
530
644
|
* * `staggerIndex` - The numeric index representing the stagger item (e.g. a value of 5 is equal to the sixth item in the stagger; therefore when a
|
531
|
-
* `stagger` option value of `0.1` is used then there will be a stagger delay of `600ms`)
|
532
|
-
* `applyClassesEarly` - Whether or not the classes being added or removed will be used when detecting the animation. This is set by `$animate` when enter/leave/move animations are fired to ensure that the CSS classes are resolved in time. (Note that this will prevent any transitions from occuring on the classes being added and removed.)
|
645
|
+
* * `stagger` option value of `0.1` is used then there will be a stagger delay of `600ms`)
|
646
|
+
* * `applyClassesEarly` - Whether or not the classes being added or removed will be used when detecting the animation. This is set by `$animate` when enter/leave/move animations are fired to ensure that the CSS classes are resolved in time. (Note that this will prevent any transitions from occuring on the classes being added and removed.)
|
647
|
+
* * `cleanupStyles` - Whether or not the provided `from` and `to` styles will be removed once
|
648
|
+
* the animation is closed. This is useful for when the styles are used purely for the sake of
|
649
|
+
* the animation and do not have a lasting visual effect on the element (e.g. a colapse and open animation).
|
650
|
+
* By default this value is set to `false`.
|
533
651
|
*
|
534
652
|
* @return {object} an object with start and end methods and details about the animation.
|
535
653
|
*
|
536
654
|
* * `start` - The method to start the animation. This will return a `Promise` when called.
|
537
655
|
* * `end` - This method will cancel the animation and remove all applied CSS classes and styles.
|
538
656
|
*/
|
539
|
-
|
540
|
-
// Detect proper transitionend/animationend event names.
|
541
|
-
var CSS_PREFIX = '', TRANSITION_PROP, TRANSITIONEND_EVENT, ANIMATION_PROP, ANIMATIONEND_EVENT;
|
542
|
-
|
543
|
-
// If unprefixed events are not supported but webkit-prefixed are, use the latter.
|
544
|
-
// Otherwise, just use W3C names, browsers not supporting them at all will just ignore them.
|
545
|
-
// Note: Chrome implements `window.onwebkitanimationend` and doesn't implement `window.onanimationend`
|
546
|
-
// but at the same time dispatches the `animationend` event and not `webkitAnimationEnd`.
|
547
|
-
// Register both events in case `window.onanimationend` is not supported because of that,
|
548
|
-
// do the same for `transitionend` as Safari is likely to exhibit similar behavior.
|
549
|
-
// Also, the only modern browser that uses vendor prefixes for transitions/keyframes is webkit
|
550
|
-
// therefore there is no reason to test anymore for other vendor prefixes:
|
551
|
-
// http://caniuse.com/#search=transition
|
552
|
-
if (window.ontransitionend === undefined && window.onwebkittransitionend !== undefined) {
|
553
|
-
CSS_PREFIX = '-webkit-';
|
554
|
-
TRANSITION_PROP = 'WebkitTransition';
|
555
|
-
TRANSITIONEND_EVENT = 'webkitTransitionEnd transitionend';
|
556
|
-
} else {
|
557
|
-
TRANSITION_PROP = 'transition';
|
558
|
-
TRANSITIONEND_EVENT = 'transitionend';
|
559
|
-
}
|
560
|
-
|
561
|
-
if (window.onanimationend === undefined && window.onwebkitanimationend !== undefined) {
|
562
|
-
CSS_PREFIX = '-webkit-';
|
563
|
-
ANIMATION_PROP = 'WebkitAnimation';
|
564
|
-
ANIMATIONEND_EVENT = 'webkitAnimationEnd animationend';
|
565
|
-
} else {
|
566
|
-
ANIMATION_PROP = 'animation';
|
567
|
-
ANIMATIONEND_EVENT = 'animationend';
|
568
|
-
}
|
569
|
-
|
570
|
-
var DURATION_KEY = 'Duration';
|
571
|
-
var PROPERTY_KEY = 'Property';
|
572
|
-
var DELAY_KEY = 'Delay';
|
573
|
-
var TIMING_KEY = 'TimingFunction';
|
574
|
-
var ANIMATION_ITERATION_COUNT_KEY = 'IterationCount';
|
575
|
-
var ANIMATION_PLAYSTATE_KEY = 'PlayState';
|
576
|
-
var ELAPSED_TIME_MAX_DECIMAL_PLACES = 3;
|
577
|
-
var CLOSING_TIME_BUFFER = 1.5;
|
578
657
|
var ONE_SECOND = 1000;
|
579
658
|
var BASE_TEN = 10;
|
580
659
|
|
581
|
-
var
|
582
|
-
|
583
|
-
var ANIMATION_DELAY_PROP = ANIMATION_PROP + DELAY_KEY;
|
584
|
-
var ANIMATION_DURATION_PROP = ANIMATION_PROP + DURATION_KEY;
|
585
|
-
|
586
|
-
var TRANSITION_DELAY_PROP = TRANSITION_PROP + DELAY_KEY;
|
587
|
-
var TRANSITION_DURATION_PROP = TRANSITION_PROP + DURATION_KEY;
|
660
|
+
var ELAPSED_TIME_MAX_DECIMAL_PLACES = 3;
|
661
|
+
var CLOSING_TIME_BUFFER = 1.5;
|
588
662
|
|
589
663
|
var DETECT_CSS_PROPERTIES = {
|
590
664
|
transitionDuration: TRANSITION_DURATION_PROP,
|
@@ -602,6 +676,15 @@ var DETECT_STAGGER_CSS_PROPERTIES = {
|
|
602
676
|
animationDelay: ANIMATION_DELAY_PROP
|
603
677
|
};
|
604
678
|
|
679
|
+
function getCssKeyframeDurationStyle(duration) {
|
680
|
+
return [ANIMATION_DURATION_PROP, duration + 's'];
|
681
|
+
}
|
682
|
+
|
683
|
+
function getCssDelayStyle(delay, isKeyframeAnimation) {
|
684
|
+
var prop = isKeyframeAnimation ? ANIMATION_DELAY_PROP : TRANSITION_DELAY_PROP;
|
685
|
+
return [prop, delay + 's'];
|
686
|
+
}
|
687
|
+
|
605
688
|
function computeCssStyles($window, element, properties) {
|
606
689
|
var styles = Object.create(null);
|
607
690
|
var detectedStyles = $window.getComputedStyle(element) || {};
|
@@ -658,37 +741,6 @@ function getCssTransitionDurationStyle(duration, applyOnlyDuration) {
|
|
658
741
|
return [style, value];
|
659
742
|
}
|
660
743
|
|
661
|
-
function getCssKeyframeDurationStyle(duration) {
|
662
|
-
return [ANIMATION_DURATION_PROP, duration + 's'];
|
663
|
-
}
|
664
|
-
|
665
|
-
function getCssDelayStyle(delay, isKeyframeAnimation) {
|
666
|
-
var prop = isKeyframeAnimation ? ANIMATION_DELAY_PROP : TRANSITION_DELAY_PROP;
|
667
|
-
return [prop, delay + 's'];
|
668
|
-
}
|
669
|
-
|
670
|
-
function blockTransitions(node, duration) {
|
671
|
-
// we use a negative delay value since it performs blocking
|
672
|
-
// yet it doesn't kill any existing transitions running on the
|
673
|
-
// same element which makes this safe for class-based animations
|
674
|
-
var value = duration ? '-' + duration + 's' : '';
|
675
|
-
applyInlineStyle(node, [TRANSITION_DELAY_PROP, value]);
|
676
|
-
return [TRANSITION_DELAY_PROP, value];
|
677
|
-
}
|
678
|
-
|
679
|
-
function blockKeyframeAnimations(node, applyBlock) {
|
680
|
-
var value = applyBlock ? 'paused' : '';
|
681
|
-
var key = ANIMATION_PROP + ANIMATION_PLAYSTATE_KEY;
|
682
|
-
applyInlineStyle(node, [key, value]);
|
683
|
-
return [key, value];
|
684
|
-
}
|
685
|
-
|
686
|
-
function applyInlineStyle(node, styleTuple) {
|
687
|
-
var prop = styleTuple[0];
|
688
|
-
var value = styleTuple[1];
|
689
|
-
node.style[prop] = value;
|
690
|
-
}
|
691
|
-
|
692
744
|
function createLocalCacheLookup() {
|
693
745
|
var cache = Object.create(null);
|
694
746
|
return {
|
@@ -716,14 +768,31 @@ function createLocalCacheLookup() {
|
|
716
768
|
};
|
717
769
|
}
|
718
770
|
|
771
|
+
// we do not reassign an already present style value since
|
772
|
+
// if we detect the style property value again we may be
|
773
|
+
// detecting styles that were added via the `from` styles.
|
774
|
+
// We make use of `isDefined` here since an empty string
|
775
|
+
// or null value (which is what getPropertyValue will return
|
776
|
+
// for a non-existing style) will still be marked as a valid
|
777
|
+
// value for the style (a falsy value implies that the style
|
778
|
+
// is to be removed at the end of the animation). If we had a simple
|
779
|
+
// "OR" statement then it would not be enough to catch that.
|
780
|
+
function registerRestorableStyles(backup, node, properties) {
|
781
|
+
forEach(properties, function(prop) {
|
782
|
+
backup[prop] = isDefined(backup[prop])
|
783
|
+
? backup[prop]
|
784
|
+
: node.style.getPropertyValue(prop);
|
785
|
+
});
|
786
|
+
}
|
787
|
+
|
719
788
|
var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
720
789
|
var gcsLookup = createLocalCacheLookup();
|
721
790
|
var gcsStaggerLookup = createLocalCacheLookup();
|
722
791
|
|
723
792
|
this.$get = ['$window', '$$jqLite', '$$AnimateRunner', '$timeout',
|
724
|
-
'
|
793
|
+
'$$forceReflow', '$sniffer', '$$rAFScheduler', '$$animateQueue',
|
725
794
|
function($window, $$jqLite, $$AnimateRunner, $timeout,
|
726
|
-
|
795
|
+
$$forceReflow, $sniffer, $$rAFScheduler, $$animateQueue) {
|
727
796
|
|
728
797
|
var applyAnimationClasses = applyAnimationClassesFactory($$jqLite);
|
729
798
|
|
@@ -780,7 +849,7 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
|
780
849
|
return stagger || {};
|
781
850
|
}
|
782
851
|
|
783
|
-
var
|
852
|
+
var cancelLastRAFRequest;
|
784
853
|
var rafWaitQueue = [];
|
785
854
|
function waitUntilQuiet(callback) {
|
786
855
|
rafWaitQueue.push(callback);
|
@@ -788,27 +857,19 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
|
788
857
|
gcsLookup.flush();
|
789
858
|
gcsStaggerLookup.flush();
|
790
859
|
|
791
|
-
//
|
792
|
-
//
|
793
|
-
|
794
|
-
//ensure that the preparation animation is properly flushed so that
|
795
|
-
//the active state picks up from there. DO NOT REMOVE THIS LINE.
|
796
|
-
//DO NOT OPTIMIZE THIS LINE. THE MINIFIER WILL REMOVE IT OTHERWISE WHICH
|
797
|
-
//WILL RESULT IN AN UNPREDICTABLE BUG THAT IS VERY HARD TO TRACK DOWN AND
|
798
|
-
//WILL TAKE YEARS AWAY FROM YOUR LIFE.
|
799
|
-
var width = bod.offsetWidth + 1;
|
860
|
+
// DO NOT REMOVE THIS LINE OR REFACTOR OUT THE `pageWidth` variable.
|
861
|
+
// PLEASE EXAMINE THE `$$forceReflow` service to understand why.
|
862
|
+
var pageWidth = $$forceReflow();
|
800
863
|
|
801
864
|
// we use a for loop to ensure that if the queue is changed
|
802
865
|
// during this looping then it will consider new requests
|
803
866
|
for (var i = 0; i < rafWaitQueue.length; i++) {
|
804
|
-
rafWaitQueue[i](
|
867
|
+
rafWaitQueue[i](pageWidth);
|
805
868
|
}
|
806
869
|
rafWaitQueue.length = 0;
|
807
870
|
});
|
808
871
|
}
|
809
872
|
|
810
|
-
return init;
|
811
|
-
|
812
873
|
function computeTimings(node, className, cacheKey) {
|
813
874
|
var timings = computeCachedCssStyles(node, className, cacheKey, DETECT_CSS_PROPERTIES);
|
814
875
|
var aD = timings.animationDelay;
|
@@ -823,14 +884,24 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
|
823
884
|
return timings;
|
824
885
|
}
|
825
886
|
|
826
|
-
function init(element,
|
887
|
+
return function init(element, initialOptions) {
|
888
|
+
// all of the animation functions should create
|
889
|
+
// a copy of the options data, however, if a
|
890
|
+
// parent service has already created a copy then
|
891
|
+
// we should stick to using that
|
892
|
+
var options = initialOptions || {};
|
893
|
+
if (!options.$$prepared) {
|
894
|
+
options = prepareAnimationOptions(copy(options));
|
895
|
+
}
|
896
|
+
|
897
|
+
var restoreStyles = {};
|
827
898
|
var node = getDomNode(element);
|
828
|
-
if (!node
|
899
|
+
if (!node
|
900
|
+
|| !node.parentNode
|
901
|
+
|| !$$animateQueue.enabled()) {
|
829
902
|
return closeAndReturnNoopAnimator();
|
830
903
|
}
|
831
904
|
|
832
|
-
options = prepareAnimationOptions(options);
|
833
|
-
|
834
905
|
var temporaryStyles = [];
|
835
906
|
var classes = element.attr('class');
|
836
907
|
var styles = packageStyles(options);
|
@@ -843,6 +914,8 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
|
843
914
|
var maxDelayTime;
|
844
915
|
var maxDuration;
|
845
916
|
var maxDurationTime;
|
917
|
+
var startTime;
|
918
|
+
var events = [];
|
846
919
|
|
847
920
|
if (options.duration === 0 || (!$sniffer.animations && !$sniffer.transitions)) {
|
848
921
|
return closeAndReturnNoopAnimator();
|
@@ -857,20 +930,20 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
|
857
930
|
var addRemoveClassName = '';
|
858
931
|
|
859
932
|
if (isStructural) {
|
860
|
-
structuralClassName = pendClasses(method,
|
933
|
+
structuralClassName = pendClasses(method, EVENT_CLASS_PREFIX, true);
|
861
934
|
} else if (method) {
|
862
935
|
structuralClassName = method;
|
863
936
|
}
|
864
937
|
|
865
938
|
if (options.addClass) {
|
866
|
-
addRemoveClassName += pendClasses(options.addClass,
|
939
|
+
addRemoveClassName += pendClasses(options.addClass, ADD_CLASS_SUFFIX);
|
867
940
|
}
|
868
941
|
|
869
942
|
if (options.removeClass) {
|
870
943
|
if (addRemoveClassName.length) {
|
871
944
|
addRemoveClassName += ' ';
|
872
945
|
}
|
873
|
-
addRemoveClassName += pendClasses(options.removeClass,
|
946
|
+
addRemoveClassName += pendClasses(options.removeClass, REMOVE_CLASS_SUFFIX);
|
874
947
|
}
|
875
948
|
|
876
949
|
// there may be a situation where a structural animation is combined together
|
@@ -881,12 +954,11 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
|
881
954
|
// there actually is a detected transition or keyframe animation
|
882
955
|
if (options.applyClassesEarly && addRemoveClassName.length) {
|
883
956
|
applyAnimationClasses(element, options);
|
884
|
-
addRemoveClassName = '';
|
885
957
|
}
|
886
958
|
|
887
|
-
var
|
888
|
-
var fullClassName = classes + ' ' +
|
889
|
-
var activeClasses = pendClasses(
|
959
|
+
var preparationClasses = [structuralClassName, addRemoveClassName].join(' ').trim();
|
960
|
+
var fullClassName = classes + ' ' + preparationClasses;
|
961
|
+
var activeClasses = pendClasses(preparationClasses, ACTIVE_CLASS_SUFFIX);
|
890
962
|
var hasToStyles = styles.to && Object.keys(styles.to).length > 0;
|
891
963
|
var containsKeyframeAnimation = (options.keyframeStyle || '').length > 0;
|
892
964
|
|
@@ -895,7 +967,7 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
|
895
967
|
// unless there a is raw keyframe value that is applied to the element.
|
896
968
|
if (!containsKeyframeAnimation
|
897
969
|
&& !hasToStyles
|
898
|
-
&& !
|
970
|
+
&& !preparationClasses) {
|
899
971
|
return closeAndReturnNoopAnimator();
|
900
972
|
}
|
901
973
|
|
@@ -910,10 +982,12 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
|
910
982
|
};
|
911
983
|
} else {
|
912
984
|
cacheKey = gcsHashFn(node, fullClassName);
|
913
|
-
stagger = computeCachedCssStaggerStyles(node,
|
985
|
+
stagger = computeCachedCssStaggerStyles(node, preparationClasses, cacheKey, DETECT_STAGGER_CSS_PROPERTIES);
|
914
986
|
}
|
915
987
|
|
916
|
-
|
988
|
+
if (!options.$$skipPreparationClasses) {
|
989
|
+
$$jqLite.addClass(element, preparationClasses);
|
990
|
+
}
|
917
991
|
|
918
992
|
var applyOnlyDuration;
|
919
993
|
|
@@ -952,7 +1026,7 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
|
952
1026
|
// transition delay to allow for the transition to naturally do it's thing. The beauty here is
|
953
1027
|
// that if there is no transition defined then nothing will happen and this will also allow
|
954
1028
|
// other transitions to be stacked on top of each other without any chopping them out.
|
955
|
-
if (isFirst) {
|
1029
|
+
if (isFirst && !options.skipBlocking) {
|
956
1030
|
blockTransitions(node, SAFE_FAST_FORWARD_DURATION_VALUE);
|
957
1031
|
}
|
958
1032
|
|
@@ -994,6 +1068,23 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
|
994
1068
|
return closeAndReturnNoopAnimator();
|
995
1069
|
}
|
996
1070
|
|
1071
|
+
if (options.delay != null) {
|
1072
|
+
var delayStyle;
|
1073
|
+
if (typeof options.delay !== "boolean") {
|
1074
|
+
delayStyle = parseFloat(options.delay);
|
1075
|
+
// number in options.delay means we have to recalculate the delay for the closing timeout
|
1076
|
+
maxDelay = Math.max(delayStyle, 0);
|
1077
|
+
}
|
1078
|
+
|
1079
|
+
if (flags.applyTransitionDelay) {
|
1080
|
+
temporaryStyles.push(getCssDelayStyle(delayStyle));
|
1081
|
+
}
|
1082
|
+
|
1083
|
+
if (flags.applyAnimationDelay) {
|
1084
|
+
temporaryStyles.push(getCssDelayStyle(delayStyle, true));
|
1085
|
+
}
|
1086
|
+
}
|
1087
|
+
|
997
1088
|
// we need to recalculate the delay value since we used a pre-emptive negative
|
998
1089
|
// delay value and the delay value is required for the final event checking. This
|
999
1090
|
// property will ensure that this will happen after the RAF phase has passed.
|
@@ -1010,12 +1101,18 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
|
1010
1101
|
stagger.animationDuration === 0;
|
1011
1102
|
}
|
1012
1103
|
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
1104
|
+
if (options.from) {
|
1105
|
+
if (options.cleanupStyles) {
|
1106
|
+
registerRestorableStyles(restoreStyles, node, Object.keys(options.from));
|
1107
|
+
}
|
1108
|
+
applyAnimationFromStyles(element, options);
|
1016
1109
|
}
|
1017
1110
|
|
1018
|
-
|
1111
|
+
if (flags.blockTransition || flags.blockKeyframeAnimation) {
|
1112
|
+
applyBlocking(maxDuration);
|
1113
|
+
} else if (!options.skipBlocking) {
|
1114
|
+
blockTransitions(node, false);
|
1115
|
+
}
|
1019
1116
|
|
1020
1117
|
// TODO(matsko): for 1.5 change this code to have an animator object for better debugging
|
1021
1118
|
return {
|
@@ -1058,7 +1155,9 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
|
1058
1155
|
animationClosed = true;
|
1059
1156
|
animationPaused = false;
|
1060
1157
|
|
1061
|
-
|
1158
|
+
if (!options.$$skipPreparationClasses) {
|
1159
|
+
$$jqLite.removeClass(element, preparationClasses);
|
1160
|
+
}
|
1062
1161
|
$$jqLite.removeClass(element, activeClasses);
|
1063
1162
|
|
1064
1163
|
blockKeyframeAnimations(node, false);
|
@@ -1074,6 +1173,13 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
|
1074
1173
|
applyAnimationClasses(element, options);
|
1075
1174
|
applyAnimationStyles(element, options);
|
1076
1175
|
|
1176
|
+
if (Object.keys(restoreStyles).length) {
|
1177
|
+
forEach(restoreStyles, function(value, prop) {
|
1178
|
+
value ? node.style.setProperty(prop, value)
|
1179
|
+
: node.style.removeProperty(prop);
|
1180
|
+
});
|
1181
|
+
}
|
1182
|
+
|
1077
1183
|
// the reason why we have this option is to allow a synchronous closing callback
|
1078
1184
|
// that is fired as SOON as the animation ends (when the CSS is removed) or if
|
1079
1185
|
// the animation never takes off at all. A good example is a leave animation since
|
@@ -1083,6 +1189,11 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
|
1083
1189
|
options.onDone();
|
1084
1190
|
}
|
1085
1191
|
|
1192
|
+
if (events && events.length) {
|
1193
|
+
// Remove the transitionend / animationend listener(s)
|
1194
|
+
element.off(events.join(' '), onAnimationProgress);
|
1195
|
+
}
|
1196
|
+
|
1086
1197
|
// if the preparation function fails then the promise is not setup
|
1087
1198
|
if (runner) {
|
1088
1199
|
runner.complete(!rejected);
|
@@ -1105,6 +1216,8 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
|
1105
1216
|
cancel: cancelFn
|
1106
1217
|
});
|
1107
1218
|
|
1219
|
+
// should flush the cache animation
|
1220
|
+
waitUntilQuiet(noop);
|
1108
1221
|
close();
|
1109
1222
|
|
1110
1223
|
return {
|
@@ -1116,6 +1229,33 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
|
1116
1229
|
};
|
1117
1230
|
}
|
1118
1231
|
|
1232
|
+
function onAnimationProgress(event) {
|
1233
|
+
event.stopPropagation();
|
1234
|
+
var ev = event.originalEvent || event;
|
1235
|
+
|
1236
|
+
// we now always use `Date.now()` due to the recent changes with
|
1237
|
+
// event.timeStamp in Firefox, Webkit and Chrome (see #13494 for more info)
|
1238
|
+
var timeStamp = ev.$manualTimeStamp || Date.now();
|
1239
|
+
|
1240
|
+
/* Firefox (or possibly just Gecko) likes to not round values up
|
1241
|
+
* when a ms measurement is used for the animation */
|
1242
|
+
var elapsedTime = parseFloat(ev.elapsedTime.toFixed(ELAPSED_TIME_MAX_DECIMAL_PLACES));
|
1243
|
+
|
1244
|
+
/* $manualTimeStamp is a mocked timeStamp value which is set
|
1245
|
+
* within browserTrigger(). This is only here so that tests can
|
1246
|
+
* mock animations properly. Real events fallback to event.timeStamp,
|
1247
|
+
* or, if they don't, then a timeStamp is automatically created for them.
|
1248
|
+
* We're checking to see if the timeStamp surpasses the expected delay,
|
1249
|
+
* but we're using elapsedTime instead of the timeStamp on the 2nd
|
1250
|
+
* pre-condition since animationPauseds sometimes close off early */
|
1251
|
+
if (Math.max(timeStamp - startTime, 0) >= maxDelayTime && elapsedTime >= maxDuration) {
|
1252
|
+
// we set this flag to ensure that if the transition is paused then, when resumed,
|
1253
|
+
// the animation will automatically close itself since transitions cannot be paused.
|
1254
|
+
animationCompleted = true;
|
1255
|
+
close();
|
1256
|
+
}
|
1257
|
+
}
|
1258
|
+
|
1119
1259
|
function start() {
|
1120
1260
|
if (animationClosed) return;
|
1121
1261
|
if (!node.parentNode) {
|
@@ -1123,8 +1263,6 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
|
1123
1263
|
return;
|
1124
1264
|
}
|
1125
1265
|
|
1126
|
-
var startTime, events = [];
|
1127
|
-
|
1128
1266
|
// even though we only pause keyframe animations here the pause flag
|
1129
1267
|
// will still happen when transitions are used. Only the transition will
|
1130
1268
|
// not be paused since that is not possible. If the animation ends when
|
@@ -1185,7 +1323,7 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
|
1185
1323
|
$$jqLite.addClass(element, activeClasses);
|
1186
1324
|
|
1187
1325
|
if (flags.recalculateTimingStyles) {
|
1188
|
-
fullClassName = node.className + ' ' +
|
1326
|
+
fullClassName = node.className + ' ' + preparationClasses;
|
1189
1327
|
cacheKey = gcsHashFn(node, fullClassName);
|
1190
1328
|
|
1191
1329
|
timings = computeTimings(node, fullClassName, cacheKey);
|
@@ -1202,27 +1340,16 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
|
1202
1340
|
flags.hasAnimations = timings.animationDuration > 0;
|
1203
1341
|
}
|
1204
1342
|
|
1205
|
-
if (flags.
|
1343
|
+
if (flags.applyAnimationDelay) {
|
1206
1344
|
relativeDelay = typeof options.delay !== "boolean" && truthyTimingValue(options.delay)
|
1207
1345
|
? parseFloat(options.delay)
|
1208
1346
|
: relativeDelay;
|
1209
1347
|
|
1210
1348
|
maxDelay = Math.max(relativeDelay, 0);
|
1211
|
-
|
1212
|
-
|
1213
|
-
|
1214
|
-
|
1215
|
-
delayStyle = getCssDelayStyle(relativeDelay);
|
1216
|
-
temporaryStyles.push(delayStyle);
|
1217
|
-
node.style[delayStyle[0]] = delayStyle[1];
|
1218
|
-
}
|
1219
|
-
|
1220
|
-
if (flags.applyAnimationDelay) {
|
1221
|
-
timings.animationDelay = relativeDelay;
|
1222
|
-
delayStyle = getCssDelayStyle(relativeDelay, true);
|
1223
|
-
temporaryStyles.push(delayStyle);
|
1224
|
-
node.style[delayStyle[0]] = delayStyle[1];
|
1225
|
-
}
|
1349
|
+
timings.animationDelay = relativeDelay;
|
1350
|
+
delayStyle = getCssDelayStyle(relativeDelay, true);
|
1351
|
+
temporaryStyles.push(delayStyle);
|
1352
|
+
node.style[delayStyle[0]] = delayStyle[1];
|
1226
1353
|
}
|
1227
1354
|
|
1228
1355
|
maxDelayTime = maxDelay * ONE_SECOND;
|
@@ -1251,44 +1378,58 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
|
1251
1378
|
}
|
1252
1379
|
|
1253
1380
|
startTime = Date.now();
|
1254
|
-
|
1255
|
-
|
1381
|
+
var timerTime = maxDelayTime + CLOSING_TIME_BUFFER * maxDurationTime;
|
1382
|
+
var endTime = startTime + timerTime;
|
1383
|
+
|
1384
|
+
var animationsData = element.data(ANIMATE_TIMER_KEY) || [];
|
1385
|
+
var setupFallbackTimer = true;
|
1386
|
+
if (animationsData.length) {
|
1387
|
+
var currentTimerData = animationsData[0];
|
1388
|
+
setupFallbackTimer = endTime > currentTimerData.expectedEndTime;
|
1389
|
+
if (setupFallbackTimer) {
|
1390
|
+
$timeout.cancel(currentTimerData.timer);
|
1391
|
+
} else {
|
1392
|
+
animationsData.push(close);
|
1393
|
+
}
|
1394
|
+
}
|
1256
1395
|
|
1257
|
-
|
1258
|
-
|
1396
|
+
if (setupFallbackTimer) {
|
1397
|
+
var timer = $timeout(onAnimationExpired, timerTime, false);
|
1398
|
+
animationsData[0] = {
|
1399
|
+
timer: timer,
|
1400
|
+
expectedEndTime: endTime
|
1401
|
+
};
|
1402
|
+
animationsData.push(close);
|
1403
|
+
element.data(ANIMATE_TIMER_KEY, animationsData);
|
1404
|
+
}
|
1259
1405
|
|
1260
|
-
|
1261
|
-
|
1262
|
-
|
1263
|
-
|
1264
|
-
|
1406
|
+
if (events.length) {
|
1407
|
+
element.on(events.join(' '), onAnimationProgress);
|
1408
|
+
}
|
1409
|
+
|
1410
|
+
if (options.to) {
|
1411
|
+
if (options.cleanupStyles) {
|
1412
|
+
registerRestorableStyles(restoreStyles, node, Object.keys(options.to));
|
1413
|
+
}
|
1414
|
+
applyAnimationToStyles(element, options);
|
1415
|
+
}
|
1265
1416
|
}
|
1266
1417
|
|
1267
|
-
function
|
1268
|
-
|
1269
|
-
|
1270
|
-
|
1271
|
-
|
1272
|
-
|
1273
|
-
|
1274
|
-
|
1275
|
-
|
1276
|
-
|
1277
|
-
|
1278
|
-
* mock animations properly. Real events fallback to event.timeStamp,
|
1279
|
-
* or, if they don't, then a timeStamp is automatically created for them.
|
1280
|
-
* We're checking to see if the timeStamp surpasses the expected delay,
|
1281
|
-
* but we're using elapsedTime instead of the timeStamp on the 2nd
|
1282
|
-
* pre-condition since animations sometimes close off early */
|
1283
|
-
if (Math.max(timeStamp - startTime, 0) >= maxDelayTime && elapsedTime >= maxDuration) {
|
1284
|
-
// we set this flag to ensure that if the transition is paused then, when resumed,
|
1285
|
-
// the animation will automatically close itself since transitions cannot be paused.
|
1286
|
-
animationCompleted = true;
|
1287
|
-
close();
|
1418
|
+
function onAnimationExpired() {
|
1419
|
+
var animationsData = element.data(ANIMATE_TIMER_KEY);
|
1420
|
+
|
1421
|
+
// this will be false in the event that the element was
|
1422
|
+
// removed from the DOM (via a leave animation or something
|
1423
|
+
// similar)
|
1424
|
+
if (animationsData) {
|
1425
|
+
for (var i = 1; i < animationsData.length; i++) {
|
1426
|
+
animationsData[i]();
|
1427
|
+
}
|
1428
|
+
element.removeData(ANIMATE_TIMER_KEY);
|
1288
1429
|
}
|
1289
1430
|
}
|
1290
1431
|
}
|
1291
|
-
}
|
1432
|
+
};
|
1292
1433
|
}];
|
1293
1434
|
}];
|
1294
1435
|
|
@@ -1301,16 +1442,27 @@ var $$AnimateCssDriverProvider = ['$$animationProvider', function($$animationPro
|
|
1301
1442
|
var NG_OUT_ANCHOR_CLASS_NAME = 'ng-anchor-out';
|
1302
1443
|
var NG_IN_ANCHOR_CLASS_NAME = 'ng-anchor-in';
|
1303
1444
|
|
1304
|
-
|
1305
|
-
|
1445
|
+
function isDocumentFragment(node) {
|
1446
|
+
return node.parentNode && node.parentNode.nodeType === 11;
|
1447
|
+
}
|
1448
|
+
|
1449
|
+
this.$get = ['$animateCss', '$rootScope', '$$AnimateRunner', '$rootElement', '$sniffer', '$$jqLite', '$document',
|
1450
|
+
function($animateCss, $rootScope, $$AnimateRunner, $rootElement, $sniffer, $$jqLite, $document) {
|
1306
1451
|
|
1307
1452
|
// only browsers that support these properties can render animations
|
1308
1453
|
if (!$sniffer.animations && !$sniffer.transitions) return noop;
|
1309
1454
|
|
1310
|
-
var bodyNode =
|
1455
|
+
var bodyNode = $document[0].body;
|
1311
1456
|
var rootNode = getDomNode($rootElement);
|
1312
1457
|
|
1313
|
-
var rootBodyElement = jqLite(
|
1458
|
+
var rootBodyElement = jqLite(
|
1459
|
+
// this is to avoid using something that exists outside of the body
|
1460
|
+
// we also special case the doc fragement case because our unit test code
|
1461
|
+
// appends the $rootElement to the body after the app has been bootstrapped
|
1462
|
+
isDocumentFragment(rootNode) || bodyNode.contains(rootNode) ? rootNode : bodyNode
|
1463
|
+
);
|
1464
|
+
|
1465
|
+
var applyAnimationClasses = applyAnimationClassesFactory($$jqLite);
|
1314
1466
|
|
1315
1467
|
return function initDriverFn(animationDetails) {
|
1316
1468
|
return animationDetails.from && animationDetails.to
|
@@ -1462,8 +1614,8 @@ var $$AnimateCssDriverProvider = ['$$animationProvider', function($$animationPro
|
|
1462
1614
|
}
|
1463
1615
|
|
1464
1616
|
function prepareFromToAnchorAnimation(from, to, classes, anchors) {
|
1465
|
-
var fromAnimation = prepareRegularAnimation(from);
|
1466
|
-
var toAnimation = prepareRegularAnimation(to);
|
1617
|
+
var fromAnimation = prepareRegularAnimation(from, noop);
|
1618
|
+
var toAnimation = prepareRegularAnimation(to, noop);
|
1467
1619
|
|
1468
1620
|
var anchorAnimations = [];
|
1469
1621
|
forEach(anchors, function(anchor) {
|
@@ -1519,19 +1671,23 @@ var $$AnimateCssDriverProvider = ['$$animationProvider', function($$animationPro
|
|
1519
1671
|
var options = animationDetails.options || {};
|
1520
1672
|
|
1521
1673
|
if (animationDetails.structural) {
|
1522
|
-
|
1523
|
-
|
1524
|
-
options.
|
1674
|
+
options.event = animationDetails.event;
|
1675
|
+
options.structural = true;
|
1676
|
+
options.applyClassesEarly = true;
|
1525
1677
|
|
1526
1678
|
// we special case the leave animation since we want to ensure that
|
1527
1679
|
// the element is removed as soon as the animation is over. Otherwise
|
1528
1680
|
// a flicker might appear or the element may not be removed at all
|
1529
|
-
|
1530
|
-
if (options.event === 'leave') {
|
1681
|
+
if (animationDetails.event === 'leave') {
|
1531
1682
|
options.onDone = options.domOperation;
|
1532
1683
|
}
|
1533
|
-
}
|
1534
|
-
|
1684
|
+
}
|
1685
|
+
|
1686
|
+
// We assign the preparationClasses as the actual animation event since
|
1687
|
+
// the internals of $animateCss will just suffix the event token values
|
1688
|
+
// with `-active` to trigger the animation.
|
1689
|
+
if (options.preparationClasses) {
|
1690
|
+
options.event = concatWithSpace(options.event, options.preparationClasses);
|
1535
1691
|
}
|
1536
1692
|
|
1537
1693
|
var animator = $animateCss(element, options);
|
@@ -1550,12 +1706,14 @@ var $$AnimateCssDriverProvider = ['$$animationProvider', function($$animationPro
|
|
1550
1706
|
// by the time...
|
1551
1707
|
|
1552
1708
|
var $$AnimateJsProvider = ['$animateProvider', function($animateProvider) {
|
1553
|
-
this.$get = ['$injector', '$$AnimateRunner', '$$
|
1554
|
-
function($injector, $$AnimateRunner, $$
|
1709
|
+
this.$get = ['$injector', '$$AnimateRunner', '$$jqLite',
|
1710
|
+
function($injector, $$AnimateRunner, $$jqLite) {
|
1555
1711
|
|
1556
1712
|
var applyAnimationClasses = applyAnimationClassesFactory($$jqLite);
|
1557
1713
|
// $animateJs(element, 'enter');
|
1558
1714
|
return function(element, event, classes, options) {
|
1715
|
+
var animationClosed = false;
|
1716
|
+
|
1559
1717
|
// the `classes` argument is optional and if it is not used
|
1560
1718
|
// then the classes will be resolved from the element's className
|
1561
1719
|
// property as well as options.addClass/options.removeClass.
|
@@ -1608,8 +1766,32 @@ var $$AnimateJsProvider = ['$animateProvider', function($animateProvider) {
|
|
1608
1766
|
applyAnimationClasses(element, options);
|
1609
1767
|
}
|
1610
1768
|
|
1769
|
+
function close() {
|
1770
|
+
animationClosed = true;
|
1771
|
+
applyOptions();
|
1772
|
+
applyAnimationStyles(element, options);
|
1773
|
+
}
|
1774
|
+
|
1775
|
+
var runner;
|
1776
|
+
|
1611
1777
|
return {
|
1778
|
+
$$willAnimate: true,
|
1779
|
+
end: function() {
|
1780
|
+
if (runner) {
|
1781
|
+
runner.end();
|
1782
|
+
} else {
|
1783
|
+
close();
|
1784
|
+
runner = new $$AnimateRunner();
|
1785
|
+
runner.complete(true);
|
1786
|
+
}
|
1787
|
+
return runner;
|
1788
|
+
},
|
1612
1789
|
start: function() {
|
1790
|
+
if (runner) {
|
1791
|
+
return runner;
|
1792
|
+
}
|
1793
|
+
|
1794
|
+
runner = new $$AnimateRunner();
|
1613
1795
|
var closeActiveAnimations;
|
1614
1796
|
var chain = [];
|
1615
1797
|
|
@@ -1634,8 +1816,7 @@ var $$AnimateJsProvider = ['$animateProvider', function($animateProvider) {
|
|
1634
1816
|
});
|
1635
1817
|
}
|
1636
1818
|
|
1637
|
-
|
1638
|
-
var runner = new $$AnimateRunner({
|
1819
|
+
runner.setHost({
|
1639
1820
|
end: function() {
|
1640
1821
|
endAnimations();
|
1641
1822
|
},
|
@@ -1648,9 +1829,7 @@ var $$AnimateJsProvider = ['$animateProvider', function($animateProvider) {
|
|
1648
1829
|
return runner;
|
1649
1830
|
|
1650
1831
|
function onComplete(success) {
|
1651
|
-
|
1652
|
-
applyOptions();
|
1653
|
-
applyAnimationStyles(element, options);
|
1832
|
+
close(success);
|
1654
1833
|
runner.complete(success);
|
1655
1834
|
}
|
1656
1835
|
|
@@ -1870,6 +2049,7 @@ var NG_ANIMATE_PIN_DATA = '$ngAnimatePin';
|
|
1870
2049
|
var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
1871
2050
|
var PRE_DIGEST_STATE = 1;
|
1872
2051
|
var RUNNING_STATE = 2;
|
2052
|
+
var ONE_SPACE = ' ';
|
1873
2053
|
|
1874
2054
|
var rules = this.rules = {
|
1875
2055
|
skip: [],
|
@@ -1877,6 +2057,29 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
1877
2057
|
join: []
|
1878
2058
|
};
|
1879
2059
|
|
2060
|
+
function makeTruthyCssClassMap(classString) {
|
2061
|
+
if (!classString) {
|
2062
|
+
return null;
|
2063
|
+
}
|
2064
|
+
|
2065
|
+
var keys = classString.split(ONE_SPACE);
|
2066
|
+
var map = Object.create(null);
|
2067
|
+
|
2068
|
+
forEach(keys, function(key) {
|
2069
|
+
map[key] = true;
|
2070
|
+
});
|
2071
|
+
return map;
|
2072
|
+
}
|
2073
|
+
|
2074
|
+
function hasMatchingClasses(newClassString, currentClassString) {
|
2075
|
+
if (newClassString && currentClassString) {
|
2076
|
+
var currentClassMap = makeTruthyCssClassMap(currentClassString);
|
2077
|
+
return newClassString.split(ONE_SPACE).some(function(className) {
|
2078
|
+
return currentClassMap[className];
|
2079
|
+
});
|
2080
|
+
}
|
2081
|
+
}
|
2082
|
+
|
1880
2083
|
function isAllowed(ruleType, element, currentAnimation, previousAnimation) {
|
1881
2084
|
return rules[ruleType].some(function(fn) {
|
1882
2085
|
return fn(element, currentAnimation, previousAnimation);
|
@@ -1908,8 +2111,8 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
1908
2111
|
});
|
1909
2112
|
|
1910
2113
|
rules.skip.push(function(element, newAnimation, currentAnimation) {
|
1911
|
-
// if there is
|
1912
|
-
return currentAnimation.structural && !newAnimation.structural;
|
2114
|
+
// if there is an ongoing current animation then don't even bother running the class-based animation
|
2115
|
+
return currentAnimation.structural && currentAnimation.state === RUNNING_STATE && !newAnimation.structural;
|
1913
2116
|
});
|
1914
2117
|
|
1915
2118
|
rules.cancel.push(function(element, newAnimation, currentAnimation) {
|
@@ -1924,23 +2127,48 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
1924
2127
|
});
|
1925
2128
|
|
1926
2129
|
rules.cancel.push(function(element, newAnimation, currentAnimation) {
|
1927
|
-
var nO = newAnimation.options;
|
1928
|
-
var cO = currentAnimation.options;
|
1929
2130
|
|
1930
|
-
|
1931
|
-
|
2131
|
+
|
2132
|
+
var nA = newAnimation.options.addClass;
|
2133
|
+
var nR = newAnimation.options.removeClass;
|
2134
|
+
var cA = currentAnimation.options.addClass;
|
2135
|
+
var cR = currentAnimation.options.removeClass;
|
2136
|
+
|
2137
|
+
// early detection to save the global CPU shortage :)
|
2138
|
+
if ((isUndefined(nA) && isUndefined(nR)) || (isUndefined(cA) && isUndefined(cR))) {
|
2139
|
+
return false;
|
2140
|
+
}
|
2141
|
+
|
2142
|
+
return (hasMatchingClasses(nA, cR)) || (hasMatchingClasses(nR, cA));
|
1932
2143
|
});
|
1933
2144
|
|
1934
2145
|
this.$get = ['$$rAF', '$rootScope', '$rootElement', '$document', '$$HashMap',
|
1935
|
-
'$$animation', '$$AnimateRunner', '$templateRequest', '$$jqLite',
|
2146
|
+
'$$animation', '$$AnimateRunner', '$templateRequest', '$$jqLite', '$$forceReflow',
|
1936
2147
|
function($$rAF, $rootScope, $rootElement, $document, $$HashMap,
|
1937
|
-
$$animation, $$AnimateRunner, $templateRequest, $$jqLite) {
|
2148
|
+
$$animation, $$AnimateRunner, $templateRequest, $$jqLite, $$forceReflow) {
|
1938
2149
|
|
1939
2150
|
var activeAnimationsLookup = new $$HashMap();
|
1940
2151
|
var disabledElementsLookup = new $$HashMap();
|
1941
|
-
|
1942
2152
|
var animationsEnabled = null;
|
1943
2153
|
|
2154
|
+
function postDigestTaskFactory() {
|
2155
|
+
var postDigestCalled = false;
|
2156
|
+
return function(fn) {
|
2157
|
+
// we only issue a call to postDigest before
|
2158
|
+
// it has first passed. This prevents any callbacks
|
2159
|
+
// from not firing once the animation has completed
|
2160
|
+
// since it will be out of the digest cycle.
|
2161
|
+
if (postDigestCalled) {
|
2162
|
+
fn();
|
2163
|
+
} else {
|
2164
|
+
$rootScope.$$postDigest(function() {
|
2165
|
+
postDigestCalled = true;
|
2166
|
+
fn();
|
2167
|
+
});
|
2168
|
+
}
|
2169
|
+
};
|
2170
|
+
}
|
2171
|
+
|
1944
2172
|
// Wait until all directive and route-related templates are downloaded and
|
1945
2173
|
// compiled. The $templateRequest.totalPendingRequests variable keeps track of
|
1946
2174
|
// all of the remote templates being currently downloaded. If there are no
|
@@ -1970,8 +2198,6 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
1970
2198
|
}
|
1971
2199
|
);
|
1972
2200
|
|
1973
|
-
var bodyElement = jqLite($document[0].body);
|
1974
|
-
|
1975
2201
|
var callbackRegistry = {};
|
1976
2202
|
|
1977
2203
|
// remember that the classNameFilter is set during the provider/config
|
@@ -1989,14 +2215,24 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
1989
2215
|
return mergeAnimationOptions(element, options, {});
|
1990
2216
|
}
|
1991
2217
|
|
1992
|
-
|
2218
|
+
// IE9-11 has no method "contains" in SVG element and in Node.prototype. Bug #10259.
|
2219
|
+
var contains = Node.prototype.contains || function(arg) {
|
2220
|
+
// jshint bitwise: false
|
2221
|
+
return this === arg || !!(this.compareDocumentPosition(arg) & 16);
|
2222
|
+
// jshint bitwise: true
|
2223
|
+
};
|
2224
|
+
|
2225
|
+
function findCallbacks(parent, element, event) {
|
1993
2226
|
var targetNode = getDomNode(element);
|
2227
|
+
var targetParentNode = getDomNode(parent);
|
1994
2228
|
|
1995
2229
|
var matches = [];
|
1996
2230
|
var entries = callbackRegistry[event];
|
1997
2231
|
if (entries) {
|
1998
2232
|
forEach(entries, function(entry) {
|
1999
|
-
if (entry.node
|
2233
|
+
if (contains.call(entry.node, targetNode)) {
|
2234
|
+
matches.push(entry.callback);
|
2235
|
+
} else if (event === 'leave' && contains.call(entry.node, targetParentNode)) {
|
2000
2236
|
matches.push(entry.callback);
|
2001
2237
|
}
|
2002
2238
|
});
|
@@ -2005,14 +2241,6 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
2005
2241
|
return matches;
|
2006
2242
|
}
|
2007
2243
|
|
2008
|
-
function triggerCallback(event, element, phase, data) {
|
2009
|
-
$$rAF(function() {
|
2010
|
-
forEach(findCallbacks(element, event), function(callback) {
|
2011
|
-
callback(element, phase, data);
|
2012
|
-
});
|
2013
|
-
});
|
2014
|
-
}
|
2015
|
-
|
2016
2244
|
return {
|
2017
2245
|
on: function(event, container, callback) {
|
2018
2246
|
var node = extractElementNode(container);
|
@@ -2079,12 +2307,7 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
2079
2307
|
bool = !recordExists;
|
2080
2308
|
} else {
|
2081
2309
|
// (element, bool) - Element setter
|
2082
|
-
|
2083
|
-
if (!bool) {
|
2084
|
-
disabledElementsLookup.put(node, true);
|
2085
|
-
} else if (recordExists) {
|
2086
|
-
disabledElementsLookup.remove(node);
|
2087
|
-
}
|
2310
|
+
disabledElementsLookup.put(node, !bool);
|
2088
2311
|
}
|
2089
2312
|
}
|
2090
2313
|
}
|
@@ -2093,7 +2316,12 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
2093
2316
|
}
|
2094
2317
|
};
|
2095
2318
|
|
2096
|
-
function queueAnimation(element, event,
|
2319
|
+
function queueAnimation(element, event, initialOptions) {
|
2320
|
+
// we always make a copy of the options since
|
2321
|
+
// there should never be any side effects on
|
2322
|
+
// the input data when running `$animateCss`.
|
2323
|
+
var options = copy(initialOptions);
|
2324
|
+
|
2097
2325
|
var node, parent;
|
2098
2326
|
element = stripCommentsFromElement(element);
|
2099
2327
|
if (element) {
|
@@ -2107,22 +2335,25 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
2107
2335
|
// These methods will become available after the digest has passed
|
2108
2336
|
var runner = new $$AnimateRunner();
|
2109
2337
|
|
2110
|
-
//
|
2111
|
-
|
2112
|
-
// happens then there is no way we can perform an animation
|
2113
|
-
if (!node) {
|
2114
|
-
close();
|
2115
|
-
return runner;
|
2116
|
-
}
|
2338
|
+
// this is used to trigger callbacks in postDigest mode
|
2339
|
+
var runInNextPostDigestOrNow = postDigestTaskFactory();
|
2117
2340
|
|
2118
2341
|
if (isArray(options.addClass)) {
|
2119
2342
|
options.addClass = options.addClass.join(' ');
|
2120
2343
|
}
|
2121
2344
|
|
2345
|
+
if (options.addClass && !isString(options.addClass)) {
|
2346
|
+
options.addClass = null;
|
2347
|
+
}
|
2348
|
+
|
2122
2349
|
if (isArray(options.removeClass)) {
|
2123
2350
|
options.removeClass = options.removeClass.join(' ');
|
2124
2351
|
}
|
2125
2352
|
|
2353
|
+
if (options.removeClass && !isString(options.removeClass)) {
|
2354
|
+
options.removeClass = null;
|
2355
|
+
}
|
2356
|
+
|
2126
2357
|
if (options.from && !isObject(options.from)) {
|
2127
2358
|
options.from = null;
|
2128
2359
|
}
|
@@ -2131,6 +2362,14 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
2131
2362
|
options.to = null;
|
2132
2363
|
}
|
2133
2364
|
|
2365
|
+
// there are situations where a directive issues an animation for
|
2366
|
+
// a jqLite wrapper that contains only comment nodes... If this
|
2367
|
+
// happens then there is no way we can perform an animation
|
2368
|
+
if (!node) {
|
2369
|
+
close();
|
2370
|
+
return runner;
|
2371
|
+
}
|
2372
|
+
|
2134
2373
|
var className = [node.className, options.addClass, options.removeClass].join(' ');
|
2135
2374
|
if (!isAnimatableClassName(className)) {
|
2136
2375
|
close();
|
@@ -2142,7 +2381,9 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
2142
2381
|
// this is a hard disable of all animations for the application or on
|
2143
2382
|
// the element itself, therefore there is no need to continue further
|
2144
2383
|
// past this point if not enabled
|
2145
|
-
|
2384
|
+
// Animations are also disabled if the document is currently hidden (page is not visible
|
2385
|
+
// to the user), because browsers slow down or do not flush calls to requestAnimationFrame
|
2386
|
+
var skipAnimations = !animationsEnabled || $document[0].hidden || disabledElementsLookup.get(node);
|
2146
2387
|
var existingAnimation = (!skipAnimations && activeAnimationsLookup.get(node)) || {};
|
2147
2388
|
var hasExistingAnimation = !!existingAnimation.state;
|
2148
2389
|
|
@@ -2195,8 +2436,9 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
2195
2436
|
// method which will call the runner methods in async.
|
2196
2437
|
existingAnimation.close();
|
2197
2438
|
} else {
|
2198
|
-
// this will merge the
|
2199
|
-
mergeAnimationOptions(element,
|
2439
|
+
// this will merge the new animation options into existing animation options
|
2440
|
+
mergeAnimationOptions(element, existingAnimation.options, newAnimation.options);
|
2441
|
+
return existingAnimation.runner;
|
2200
2442
|
}
|
2201
2443
|
} else {
|
2202
2444
|
// a joined animation means that this animation will take over the existing one
|
@@ -2207,9 +2449,14 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
2207
2449
|
if (existingAnimation.state === RUNNING_STATE) {
|
2208
2450
|
normalizeAnimationOptions(element, options);
|
2209
2451
|
} else {
|
2452
|
+
applyGeneratedPreparationClasses(element, isStructural ? event : null, options);
|
2453
|
+
|
2210
2454
|
event = newAnimation.event = existingAnimation.event;
|
2211
2455
|
options = mergeAnimationOptions(element, existingAnimation.options, newAnimation.options);
|
2212
|
-
|
2456
|
+
|
2457
|
+
//we return the same runner since only the option values of this animation will
|
2458
|
+
//be fed into the `existingAnimation`.
|
2459
|
+
return existingAnimation.runner;
|
2213
2460
|
}
|
2214
2461
|
}
|
2215
2462
|
}
|
@@ -2235,10 +2482,6 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
2235
2482
|
return runner;
|
2236
2483
|
}
|
2237
2484
|
|
2238
|
-
if (isStructural) {
|
2239
|
-
closeParentClassBasedAnimations(parent);
|
2240
|
-
}
|
2241
|
-
|
2242
2485
|
// the counter keeps track of cancelled animations
|
2243
2486
|
var counter = (existingAnimation.counter || 0) + 1;
|
2244
2487
|
newAnimation.counter = counter;
|
@@ -2296,12 +2539,9 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
2296
2539
|
? 'setClass'
|
2297
2540
|
: animationDetails.event;
|
2298
2541
|
|
2299
|
-
if (animationDetails.structural) {
|
2300
|
-
closeParentClassBasedAnimations(parentElement);
|
2301
|
-
}
|
2302
|
-
|
2303
2542
|
markElementAnimationState(element, RUNNING_STATE);
|
2304
2543
|
var realRunner = $$animation(element, event, animationDetails.options);
|
2544
|
+
|
2305
2545
|
realRunner.done(function(status) {
|
2306
2546
|
close(!status);
|
2307
2547
|
var animationDetails = activeAnimationsLookup.get(node);
|
@@ -2320,11 +2560,25 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
2320
2560
|
return runner;
|
2321
2561
|
|
2322
2562
|
function notifyProgress(runner, event, phase, data) {
|
2323
|
-
|
2563
|
+
runInNextPostDigestOrNow(function() {
|
2564
|
+
var callbacks = findCallbacks(parent, element, event);
|
2565
|
+
if (callbacks.length) {
|
2566
|
+
// do not optimize this call here to RAF because
|
2567
|
+
// we don't know how heavy the callback code here will
|
2568
|
+
// be and if this code is buffered then this can
|
2569
|
+
// lead to a performance regression.
|
2570
|
+
$$rAF(function() {
|
2571
|
+
forEach(callbacks, function(callback) {
|
2572
|
+
callback(element, phase, data);
|
2573
|
+
});
|
2574
|
+
});
|
2575
|
+
}
|
2576
|
+
});
|
2324
2577
|
runner.progress(event, phase, data);
|
2325
2578
|
}
|
2326
2579
|
|
2327
2580
|
function close(reject) { // jshint ignore:line
|
2581
|
+
clearGeneratedClasses(element, options);
|
2328
2582
|
applyAnimationClasses(element, options);
|
2329
2583
|
applyAnimationStyles(element, options);
|
2330
2584
|
options.domOperation();
|
@@ -2338,15 +2592,15 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
2338
2592
|
forEach(children, function(child) {
|
2339
2593
|
var state = parseInt(child.getAttribute(NG_ANIMATE_ATTR_NAME));
|
2340
2594
|
var animationDetails = activeAnimationsLookup.get(child);
|
2341
|
-
|
2342
|
-
|
2343
|
-
|
2344
|
-
|
2345
|
-
|
2346
|
-
|
2595
|
+
if (animationDetails) {
|
2596
|
+
switch (state) {
|
2597
|
+
case RUNNING_STATE:
|
2598
|
+
animationDetails.runner.end();
|
2599
|
+
/* falls through */
|
2600
|
+
case PRE_DIGEST_STATE:
|
2347
2601
|
activeAnimationsLookup.remove(child);
|
2348
|
-
|
2349
|
-
|
2602
|
+
break;
|
2603
|
+
}
|
2350
2604
|
}
|
2351
2605
|
});
|
2352
2606
|
}
|
@@ -2361,38 +2615,20 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
2361
2615
|
return getDomNode(nodeOrElmA) === getDomNode(nodeOrElmB);
|
2362
2616
|
}
|
2363
2617
|
|
2364
|
-
|
2365
|
-
|
2366
|
-
|
2367
|
-
|
2368
|
-
|
2369
|
-
|
2370
|
-
|
2371
|
-
examineParentAnimation(parentNode, animationDetails);
|
2372
|
-
}
|
2373
|
-
|
2374
|
-
parentNode = parentNode.parentNode;
|
2375
|
-
} while (true);
|
2376
|
-
|
2377
|
-
// since animations are detected from CSS classes, we need to flush all parent
|
2378
|
-
// class-based animations so that the parent classes are all present for child
|
2379
|
-
// animations to properly function (otherwise any CSS selectors may not work)
|
2380
|
-
function examineParentAnimation(node, animationDetails) {
|
2381
|
-
// enter/leave/move always have priority
|
2382
|
-
if (animationDetails.structural || !hasAnimationClasses(animationDetails.options)) return;
|
2383
|
-
|
2384
|
-
if (animationDetails.state === RUNNING_STATE) {
|
2385
|
-
animationDetails.runner.end();
|
2386
|
-
}
|
2387
|
-
clearElementAnimationState(node);
|
2388
|
-
}
|
2389
|
-
}
|
2390
|
-
|
2618
|
+
/**
|
2619
|
+
* This fn returns false if any of the following is true:
|
2620
|
+
* a) animations on any parent element are disabled, and animations on the element aren't explicitly allowed
|
2621
|
+
* b) a parent element has an ongoing structural animation, and animateChildren is false
|
2622
|
+
* c) the element is not a child of the body
|
2623
|
+
* d) the element is not a child of the $rootElement
|
2624
|
+
*/
|
2391
2625
|
function areAnimationsAllowed(element, parentElement, event) {
|
2392
|
-
var
|
2393
|
-
var
|
2626
|
+
var bodyElement = jqLite($document[0].body);
|
2627
|
+
var bodyElementDetected = isMatchingElement(element, bodyElement) || element[0].nodeName === 'HTML';
|
2628
|
+
var rootElementDetected = isMatchingElement(element, $rootElement);
|
2394
2629
|
var parentAnimationDetected = false;
|
2395
2630
|
var animateChildren;
|
2631
|
+
var elementDisabled = disabledElementsLookup.get(getDomNode(element));
|
2396
2632
|
|
2397
2633
|
var parentHost = element.data(NG_ANIMATE_PIN_DATA);
|
2398
2634
|
if (parentHost) {
|
@@ -2417,7 +2653,18 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
2417
2653
|
// therefore we can't allow any animations to take place
|
2418
2654
|
// but if a parent animation is class-based then that's ok
|
2419
2655
|
if (!parentAnimationDetected) {
|
2420
|
-
|
2656
|
+
var parentElementDisabled = disabledElementsLookup.get(parentNode);
|
2657
|
+
|
2658
|
+
if (parentElementDisabled === true && elementDisabled !== false) {
|
2659
|
+
// disable animations if the user hasn't explicitly enabled animations on the
|
2660
|
+
// current element
|
2661
|
+
elementDisabled = true;
|
2662
|
+
// element is disabled via parent element, no need to check anything else
|
2663
|
+
break;
|
2664
|
+
} else if (parentElementDisabled === false) {
|
2665
|
+
elementDisabled = false;
|
2666
|
+
}
|
2667
|
+
parentAnimationDetected = details.structural;
|
2421
2668
|
}
|
2422
2669
|
|
2423
2670
|
if (isUndefined(animateChildren) || animateChildren === true) {
|
@@ -2430,28 +2677,32 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
2430
2677
|
// there is no need to continue traversing at this point
|
2431
2678
|
if (parentAnimationDetected && animateChildren === false) break;
|
2432
2679
|
|
2433
|
-
if (!rootElementDetected) {
|
2434
|
-
// angular doesn't want to attempt to animate elements outside of the application
|
2435
|
-
// therefore we need to ensure that the rootElement is an ancestor of the current element
|
2436
|
-
rootElementDetected = isMatchingElement(parentElement, $rootElement);
|
2437
|
-
if (!rootElementDetected) {
|
2438
|
-
parentHost = parentElement.data(NG_ANIMATE_PIN_DATA);
|
2439
|
-
if (parentHost) {
|
2440
|
-
parentElement = parentHost;
|
2441
|
-
}
|
2442
|
-
}
|
2443
|
-
}
|
2444
|
-
|
2445
2680
|
if (!bodyElementDetected) {
|
2446
|
-
// we also need to ensure that the element is or will be
|
2681
|
+
// we also need to ensure that the element is or will be a part of the body element
|
2447
2682
|
// otherwise it is pointless to even issue an animation to be rendered
|
2448
2683
|
bodyElementDetected = isMatchingElement(parentElement, bodyElement);
|
2449
2684
|
}
|
2450
2685
|
|
2686
|
+
if (bodyElementDetected && rootElementDetected) {
|
2687
|
+
// If both body and root have been found, any other checks are pointless,
|
2688
|
+
// as no animation data should live outside the application
|
2689
|
+
break;
|
2690
|
+
}
|
2691
|
+
|
2692
|
+
if (!rootElementDetected) {
|
2693
|
+
// If no rootElement is detected, check if the parentElement is pinned to another element
|
2694
|
+
parentHost = parentElement.data(NG_ANIMATE_PIN_DATA);
|
2695
|
+
if (parentHost) {
|
2696
|
+
// The pin target element becomes the next parent element
|
2697
|
+
parentElement = parentHost;
|
2698
|
+
continue;
|
2699
|
+
}
|
2700
|
+
}
|
2701
|
+
|
2451
2702
|
parentElement = parentElement.parent();
|
2452
2703
|
}
|
2453
2704
|
|
2454
|
-
var allowAnimation = !parentAnimationDetected || animateChildren;
|
2705
|
+
var allowAnimation = (!parentAnimationDetected || animateChildren) && elementDisabled !== true;
|
2455
2706
|
return allowAnimation && rootElementDetected && bodyElementDetected;
|
2456
2707
|
}
|
2457
2708
|
|
@@ -2471,184 +2722,112 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
|
2471
2722
|
}];
|
2472
2723
|
}];
|
2473
2724
|
|
2474
|
-
var $$
|
2475
|
-
|
2476
|
-
var passed = false;
|
2477
|
-
$$rAF(function() {
|
2478
|
-
passed = true;
|
2479
|
-
});
|
2480
|
-
return function(fn) {
|
2481
|
-
passed ? fn() : $$rAF(fn);
|
2482
|
-
};
|
2483
|
-
};
|
2484
|
-
}];
|
2485
|
-
|
2486
|
-
var $$AnimateRunnerFactory = ['$q', '$$rAFMutex', function($q, $$rAFMutex) {
|
2487
|
-
var INITIAL_STATE = 0;
|
2488
|
-
var DONE_PENDING_STATE = 1;
|
2489
|
-
var DONE_COMPLETE_STATE = 2;
|
2490
|
-
|
2491
|
-
AnimateRunner.chain = function(chain, callback) {
|
2492
|
-
var index = 0;
|
2493
|
-
|
2494
|
-
next();
|
2495
|
-
function next() {
|
2496
|
-
if (index === chain.length) {
|
2497
|
-
callback(true);
|
2498
|
-
return;
|
2499
|
-
}
|
2500
|
-
|
2501
|
-
chain[index](function(response) {
|
2502
|
-
if (response === false) {
|
2503
|
-
callback(false);
|
2504
|
-
return;
|
2505
|
-
}
|
2506
|
-
index++;
|
2507
|
-
next();
|
2508
|
-
});
|
2509
|
-
}
|
2510
|
-
};
|
2725
|
+
var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
|
2726
|
+
var NG_ANIMATE_REF_ATTR = 'ng-animate-ref';
|
2511
2727
|
|
2512
|
-
|
2513
|
-
var count = 0;
|
2514
|
-
var status = true;
|
2515
|
-
forEach(runners, function(runner) {
|
2516
|
-
runner.done(onProgress);
|
2517
|
-
});
|
2728
|
+
var drivers = this.drivers = [];
|
2518
2729
|
|
2519
|
-
|
2520
|
-
status = status && response;
|
2521
|
-
if (++count === runners.length) {
|
2522
|
-
callback(status);
|
2523
|
-
}
|
2524
|
-
}
|
2525
|
-
};
|
2730
|
+
var RUNNER_STORAGE_KEY = '$$animationRunner';
|
2526
2731
|
|
2527
|
-
function
|
2528
|
-
|
2732
|
+
function setRunner(element, runner) {
|
2733
|
+
element.data(RUNNER_STORAGE_KEY, runner);
|
2734
|
+
}
|
2529
2735
|
|
2530
|
-
|
2531
|
-
|
2532
|
-
this._state = 0;
|
2736
|
+
function removeRunner(element) {
|
2737
|
+
element.removeData(RUNNER_STORAGE_KEY);
|
2533
2738
|
}
|
2534
2739
|
|
2535
|
-
|
2536
|
-
|
2537
|
-
|
2538
|
-
},
|
2740
|
+
function getRunner(element) {
|
2741
|
+
return element.data(RUNNER_STORAGE_KEY);
|
2742
|
+
}
|
2539
2743
|
|
2540
|
-
|
2541
|
-
|
2542
|
-
fn();
|
2543
|
-
} else {
|
2544
|
-
this._doneCallbacks.push(fn);
|
2545
|
-
}
|
2546
|
-
},
|
2744
|
+
this.$get = ['$$jqLite', '$rootScope', '$injector', '$$AnimateRunner', '$$HashMap', '$$rAFScheduler',
|
2745
|
+
function($$jqLite, $rootScope, $injector, $$AnimateRunner, $$HashMap, $$rAFScheduler) {
|
2547
2746
|
|
2548
|
-
|
2747
|
+
var animationQueue = [];
|
2748
|
+
var applyAnimationClasses = applyAnimationClassesFactory($$jqLite);
|
2549
2749
|
|
2550
|
-
|
2551
|
-
|
2552
|
-
|
2553
|
-
|
2554
|
-
|
2555
|
-
|
2556
|
-
|
2750
|
+
function sortAnimations(animations) {
|
2751
|
+
var tree = { children: [] };
|
2752
|
+
var i, lookup = new $$HashMap();
|
2753
|
+
|
2754
|
+
// this is done first beforehand so that the hashmap
|
2755
|
+
// is filled with a list of the elements that will be animated
|
2756
|
+
for (i = 0; i < animations.length; i++) {
|
2757
|
+
var animation = animations[i];
|
2758
|
+
lookup.put(animation.domNode, animations[i] = {
|
2759
|
+
domNode: animation.domNode,
|
2760
|
+
fn: animation.fn,
|
2761
|
+
children: []
|
2557
2762
|
});
|
2558
2763
|
}
|
2559
|
-
return this.promise;
|
2560
|
-
},
|
2561
|
-
|
2562
|
-
then: function(resolveHandler, rejectHandler) {
|
2563
|
-
return this.getPromise().then(resolveHandler, rejectHandler);
|
2564
|
-
},
|
2565
|
-
|
2566
|
-
'catch': function(handler) {
|
2567
|
-
return this.getPromise()['catch'](handler);
|
2568
|
-
},
|
2569
|
-
|
2570
|
-
'finally': function(handler) {
|
2571
|
-
return this.getPromise()['finally'](handler);
|
2572
|
-
},
|
2573
2764
|
|
2574
|
-
|
2575
|
-
|
2576
|
-
this.host.pause();
|
2765
|
+
for (i = 0; i < animations.length; i++) {
|
2766
|
+
processNode(animations[i]);
|
2577
2767
|
}
|
2578
|
-
},
|
2579
2768
|
|
2580
|
-
|
2581
|
-
if (this.host.resume) {
|
2582
|
-
this.host.resume();
|
2583
|
-
}
|
2584
|
-
},
|
2769
|
+
return flatten(tree);
|
2585
2770
|
|
2586
|
-
|
2587
|
-
|
2588
|
-
|
2589
|
-
}
|
2590
|
-
this._resolve(true);
|
2591
|
-
},
|
2771
|
+
function processNode(entry) {
|
2772
|
+
if (entry.processed) return entry;
|
2773
|
+
entry.processed = true;
|
2592
2774
|
|
2593
|
-
|
2594
|
-
|
2595
|
-
|
2596
|
-
}
|
2597
|
-
this._resolve(false);
|
2598
|
-
},
|
2775
|
+
var elementNode = entry.domNode;
|
2776
|
+
var parentNode = elementNode.parentNode;
|
2777
|
+
lookup.put(elementNode, entry);
|
2599
2778
|
|
2600
|
-
|
2601
|
-
|
2602
|
-
|
2603
|
-
|
2604
|
-
|
2605
|
-
|
2606
|
-
|
2607
|
-
|
2608
|
-
|
2779
|
+
var parentEntry;
|
2780
|
+
while (parentNode) {
|
2781
|
+
parentEntry = lookup.get(parentNode);
|
2782
|
+
if (parentEntry) {
|
2783
|
+
if (!parentEntry.processed) {
|
2784
|
+
parentEntry = processNode(parentEntry);
|
2785
|
+
}
|
2786
|
+
break;
|
2787
|
+
}
|
2788
|
+
parentNode = parentNode.parentNode;
|
2789
|
+
}
|
2609
2790
|
|
2610
|
-
|
2611
|
-
|
2612
|
-
forEach(this._doneCallbacks, function(fn) {
|
2613
|
-
fn(response);
|
2614
|
-
});
|
2615
|
-
this._doneCallbacks.length = 0;
|
2616
|
-
this._state = DONE_COMPLETE_STATE;
|
2791
|
+
(parentEntry || tree).children.push(entry);
|
2792
|
+
return entry;
|
2617
2793
|
}
|
2618
|
-
}
|
2619
|
-
};
|
2620
|
-
|
2621
|
-
return AnimateRunner;
|
2622
|
-
}];
|
2623
|
-
|
2624
|
-
var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
|
2625
|
-
var NG_ANIMATE_REF_ATTR = 'ng-animate-ref';
|
2626
2794
|
|
2627
|
-
|
2628
|
-
|
2629
|
-
|
2630
|
-
|
2631
|
-
function setRunner(element, runner) {
|
2632
|
-
element.data(RUNNER_STORAGE_KEY, runner);
|
2633
|
-
}
|
2795
|
+
function flatten(tree) {
|
2796
|
+
var result = [];
|
2797
|
+
var queue = [];
|
2798
|
+
var i;
|
2634
2799
|
|
2635
|
-
|
2636
|
-
|
2637
|
-
|
2638
|
-
|
2639
|
-
function getRunner(element) {
|
2640
|
-
return element.data(RUNNER_STORAGE_KEY);
|
2641
|
-
}
|
2800
|
+
for (i = 0; i < tree.children.length; i++) {
|
2801
|
+
queue.push(tree.children[i]);
|
2802
|
+
}
|
2642
2803
|
|
2643
|
-
|
2644
|
-
|
2804
|
+
var remainingLevelEntries = queue.length;
|
2805
|
+
var nextLevelEntries = 0;
|
2806
|
+
var row = [];
|
2807
|
+
|
2808
|
+
for (i = 0; i < queue.length; i++) {
|
2809
|
+
var entry = queue[i];
|
2810
|
+
if (remainingLevelEntries <= 0) {
|
2811
|
+
remainingLevelEntries = nextLevelEntries;
|
2812
|
+
nextLevelEntries = 0;
|
2813
|
+
result.push(row);
|
2814
|
+
row = [];
|
2815
|
+
}
|
2816
|
+
row.push(entry.fn);
|
2817
|
+
entry.children.forEach(function(childEntry) {
|
2818
|
+
nextLevelEntries++;
|
2819
|
+
queue.push(childEntry);
|
2820
|
+
});
|
2821
|
+
remainingLevelEntries--;
|
2822
|
+
}
|
2645
2823
|
|
2646
|
-
|
2647
|
-
|
2824
|
+
if (row.length) {
|
2825
|
+
result.push(row);
|
2826
|
+
}
|
2648
2827
|
|
2649
|
-
|
2650
|
-
|
2651
|
-
|
2828
|
+
return result;
|
2829
|
+
}
|
2830
|
+
}
|
2652
2831
|
|
2653
2832
|
// TODO(matsko): document the signature in a better way
|
2654
2833
|
return function(element, event, options) {
|
@@ -2678,19 +2857,12 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
|
|
2678
2857
|
options.tempClasses = null;
|
2679
2858
|
}
|
2680
2859
|
|
2681
|
-
var classBasedIndex;
|
2682
|
-
if (!isStructural) {
|
2683
|
-
classBasedIndex = totalPendingClassBasedAnimations;
|
2684
|
-
totalPendingClassBasedAnimations += 1;
|
2685
|
-
}
|
2686
|
-
|
2687
2860
|
animationQueue.push({
|
2688
2861
|
// this data is used by the postDigest code and passed into
|
2689
2862
|
// the driver step function
|
2690
2863
|
element: element,
|
2691
2864
|
classes: classes,
|
2692
2865
|
event: event,
|
2693
|
-
classBasedIndex: classBasedIndex,
|
2694
2866
|
structural: isStructural,
|
2695
2867
|
options: options,
|
2696
2868
|
beforeStart: beforeStart,
|
@@ -2705,10 +2877,6 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
|
|
2705
2877
|
if (animationQueue.length > 1) return runner;
|
2706
2878
|
|
2707
2879
|
$rootScope.$$postDigest(function() {
|
2708
|
-
totalActiveClassBasedAnimations = totalPendingClassBasedAnimations;
|
2709
|
-
totalPendingClassBasedAnimations = 0;
|
2710
|
-
classBasedAnimationsQueue.length = 0;
|
2711
|
-
|
2712
2880
|
var animations = [];
|
2713
2881
|
forEach(animationQueue, function(entry) {
|
2714
2882
|
// the element was destroyed early on which removed the runner
|
@@ -2716,67 +2884,58 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
|
|
2716
2884
|
// at all and it already has been closed due to destruction.
|
2717
2885
|
if (getRunner(entry.element)) {
|
2718
2886
|
animations.push(entry);
|
2887
|
+
} else {
|
2888
|
+
entry.close();
|
2719
2889
|
}
|
2720
2890
|
});
|
2721
2891
|
|
2722
2892
|
// now any future animations will be in another postDigest
|
2723
2893
|
animationQueue.length = 0;
|
2724
2894
|
|
2725
|
-
|
2726
|
-
|
2727
|
-
|
2728
|
-
|
2729
|
-
|
2730
|
-
|
2731
|
-
|
2732
|
-
|
2733
|
-
|
2734
|
-
|
2735
|
-
|
2736
|
-
|
2737
|
-
|
2738
|
-
|
2739
|
-
|
2740
|
-
|
2741
|
-
|
2742
|
-
|
2743
|
-
|
2744
|
-
|
2745
|
-
|
2746
|
-
|
2747
|
-
|
2748
|
-
|
2749
|
-
|
2750
|
-
// temporary classes before we do any driver invoking since these
|
2751
|
-
// CSS classes may be required for proper CSS detection.
|
2752
|
-
animationEntry.beforeStart();
|
2753
|
-
|
2754
|
-
var startAnimationFn, closeFn = animationEntry.close;
|
2755
|
-
|
2756
|
-
// in the event that the element was removed before the digest runs or
|
2757
|
-
// during the RAF sequencing then we should not trigger the animation.
|
2758
|
-
var targetElement = animationEntry.anchors
|
2759
|
-
? (animationEntry.from.element || animationEntry.to.element)
|
2760
|
-
: animationEntry.element;
|
2761
|
-
|
2762
|
-
if (getRunner(targetElement) && getDomNode(targetElement).parentNode) {
|
2763
|
-
var operation = invokeFirstDriver(animationEntry);
|
2764
|
-
if (operation) {
|
2765
|
-
startAnimationFn = operation.start;
|
2895
|
+
var groupedAnimations = groupAnimations(animations);
|
2896
|
+
var toBeSortedAnimations = [];
|
2897
|
+
|
2898
|
+
forEach(groupedAnimations, function(animationEntry) {
|
2899
|
+
toBeSortedAnimations.push({
|
2900
|
+
domNode: getDomNode(animationEntry.from ? animationEntry.from.element : animationEntry.element),
|
2901
|
+
fn: function triggerAnimationStart() {
|
2902
|
+
// it's important that we apply the `ng-animate` CSS class and the
|
2903
|
+
// temporary classes before we do any driver invoking since these
|
2904
|
+
// CSS classes may be required for proper CSS detection.
|
2905
|
+
animationEntry.beforeStart();
|
2906
|
+
|
2907
|
+
var startAnimationFn, closeFn = animationEntry.close;
|
2908
|
+
|
2909
|
+
// in the event that the element was removed before the digest runs or
|
2910
|
+
// during the RAF sequencing then we should not trigger the animation.
|
2911
|
+
var targetElement = animationEntry.anchors
|
2912
|
+
? (animationEntry.from.element || animationEntry.to.element)
|
2913
|
+
: animationEntry.element;
|
2914
|
+
|
2915
|
+
if (getRunner(targetElement)) {
|
2916
|
+
var operation = invokeFirstDriver(animationEntry);
|
2917
|
+
if (operation) {
|
2918
|
+
startAnimationFn = operation.start;
|
2919
|
+
}
|
2766
2920
|
}
|
2767
|
-
}
|
2768
2921
|
|
2769
|
-
|
2770
|
-
|
2771
|
-
|
2772
|
-
|
2773
|
-
|
2774
|
-
|
2775
|
-
|
2776
|
-
|
2922
|
+
if (!startAnimationFn) {
|
2923
|
+
closeFn();
|
2924
|
+
} else {
|
2925
|
+
var animationRunner = startAnimationFn();
|
2926
|
+
animationRunner.done(function(status) {
|
2927
|
+
closeFn(!status);
|
2928
|
+
});
|
2929
|
+
updateAnimationRunners(animationEntry, animationRunner);
|
2930
|
+
}
|
2777
2931
|
}
|
2778
|
-
}
|
2932
|
+
});
|
2779
2933
|
});
|
2934
|
+
|
2935
|
+
// we need to sort each of the animations in order of parent to child
|
2936
|
+
// relationships. This ensures that the child classes are applied at the
|
2937
|
+
// right time.
|
2938
|
+
$$rAFScheduler(sortAnimations(toBeSortedAnimations));
|
2780
2939
|
});
|
2781
2940
|
|
2782
2941
|
return runner;
|
@@ -2963,10 +3122,9 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
|
|
2963
3122
|
|
2964
3123
|
/* global angularAnimateModule: true,
|
2965
3124
|
|
2966
|
-
$$
|
3125
|
+
$$AnimateAsyncRunFactory,
|
2967
3126
|
$$rAFSchedulerFactory,
|
2968
3127
|
$$AnimateChildrenDirective,
|
2969
|
-
$$AnimateRunnerFactory,
|
2970
3128
|
$$AnimateQueueProvider,
|
2971
3129
|
$$AnimationProvider,
|
2972
3130
|
$AnimateCssProvider,
|
@@ -2981,7 +3139,7 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
|
|
2981
3139
|
* @description
|
2982
3140
|
*
|
2983
3141
|
* The `ngAnimate` module provides support for CSS-based animations (keyframes and transitions) as well as JavaScript-based animations via
|
2984
|
-
* callback hooks. Animations are not enabled by default, however, by including `ngAnimate`
|
3142
|
+
* callback hooks. Animations are not enabled by default, however, by including `ngAnimate` the animation hooks are enabled for an Angular app.
|
2985
3143
|
*
|
2986
3144
|
* <div doc-module-components="ngAnimate"></div>
|
2987
3145
|
*
|
@@ -3014,7 +3172,7 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
|
|
3014
3172
|
* 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
|
3015
3173
|
* and CSS code we can create an animation that will be picked up by Angular when an the underlying directive performs an operation.
|
3016
3174
|
*
|
3017
|
-
* The example below shows how an `enter` animation can be made possible on
|
3175
|
+
* The example below shows how an `enter` animation can be made possible on an element using `ng-if`:
|
3018
3176
|
*
|
3019
3177
|
* ```html
|
3020
3178
|
* <div ng-if="bool" class="fade">
|
@@ -3149,8 +3307,8 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
|
|
3149
3307
|
* /* this will have a 100ms delay between each successive leave animation */
|
3150
3308
|
* transition-delay: 0.1s;
|
3151
3309
|
*
|
3152
|
-
* /*
|
3153
|
-
*
|
3310
|
+
* /* As of 1.4.4, this must always be set: it signals ngAnimate
|
3311
|
+
* to not accidentally inherit a delay property from another CSS class */
|
3154
3312
|
* transition-duration: 0s;
|
3155
3313
|
* }
|
3156
3314
|
* .my-animation.ng-enter.ng-enter-active {
|
@@ -3251,7 +3409,7 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
|
|
3251
3409
|
* jQuery(element).fadeOut(1000, doneFn);
|
3252
3410
|
* }
|
3253
3411
|
* }
|
3254
|
-
* }]
|
3412
|
+
* }]);
|
3255
3413
|
* ```
|
3256
3414
|
*
|
3257
3415
|
* The nice thing about JS-based animations is that we can inject other services and make use of advanced animation libraries such as
|
@@ -3282,7 +3440,7 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
|
|
3282
3440
|
* // do some cool animation and call the doneFn
|
3283
3441
|
* }
|
3284
3442
|
* }
|
3285
|
-
* }]
|
3443
|
+
* }]);
|
3286
3444
|
* ```
|
3287
3445
|
*
|
3288
3446
|
* ## CSS + JS Animations Together
|
@@ -3304,7 +3462,7 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
|
|
3304
3462
|
* jQuery(element).slideIn(1000, doneFn);
|
3305
3463
|
* }
|
3306
3464
|
* }
|
3307
|
-
* }]
|
3465
|
+
* }]);
|
3308
3466
|
* ```
|
3309
3467
|
*
|
3310
3468
|
* ```css
|
@@ -3324,16 +3482,15 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
|
|
3324
3482
|
* ```js
|
3325
3483
|
* myModule.animation('.slide', ['$animateCss', function($animateCss) {
|
3326
3484
|
* return {
|
3327
|
-
* enter: function(element
|
3485
|
+
* enter: function(element) {
|
3328
3486
|
* // this will trigger `.slide.ng-enter` and `.slide.ng-enter-active`.
|
3329
|
-
*
|
3487
|
+
* return $animateCss(element, {
|
3330
3488
|
* event: 'enter',
|
3331
3489
|
* structural: true
|
3332
|
-
* })
|
3333
|
-
* runner.done(doneFn);
|
3490
|
+
* });
|
3334
3491
|
* }
|
3335
3492
|
* }
|
3336
|
-
* }]
|
3493
|
+
* }]);
|
3337
3494
|
* ```
|
3338
3495
|
*
|
3339
3496
|
* The nice thing here is that we can save bandwidth by sticking to our CSS-based animation code and we don't need to rely on a 3rd-party animation framework.
|
@@ -3345,18 +3502,17 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
|
|
3345
3502
|
* ```js
|
3346
3503
|
* myModule.animation('.slide', ['$animateCss', function($animateCss) {
|
3347
3504
|
* return {
|
3348
|
-
* enter: function(element
|
3349
|
-
*
|
3505
|
+
* enter: function(element) {
|
3506
|
+
* return $animateCss(element, {
|
3350
3507
|
* event: 'enter',
|
3508
|
+
* structural: true,
|
3351
3509
|
* addClass: 'maroon-setting',
|
3352
3510
|
* from: { height:0 },
|
3353
3511
|
* to: { height: 200 }
|
3354
|
-
* })
|
3355
|
-
*
|
3356
|
-
* runner.done(doneFn);
|
3512
|
+
* });
|
3357
3513
|
* }
|
3358
3514
|
* }
|
3359
|
-
* }]
|
3515
|
+
* }]);
|
3360
3516
|
* ```
|
3361
3517
|
*
|
3362
3518
|
* Now we can fill in the rest via our transition CSS code:
|
@@ -3698,16 +3854,12 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
|
|
3698
3854
|
* @description
|
3699
3855
|
* The ngAnimate `$animate` service documentation is the same for the core `$animate` service.
|
3700
3856
|
*
|
3701
|
-
* Click here {@link ng.$animate
|
3857
|
+
* Click here {@link ng.$animate to learn more about animations with `$animate`}.
|
3702
3858
|
*/
|
3703
3859
|
angular.module('ngAnimate', [])
|
3704
3860
|
.directive('ngAnimateChildren', $$AnimateChildrenDirective)
|
3705
|
-
|
3706
|
-
.factory('$$rAFMutex', $$rAFMutexFactory)
|
3707
3861
|
.factory('$$rAFScheduler', $$rAFSchedulerFactory)
|
3708
3862
|
|
3709
|
-
.factory('$$AnimateRunner', $$AnimateRunnerFactory)
|
3710
|
-
|
3711
3863
|
.provider('$$animateQueue', $$AnimateQueueProvider)
|
3712
3864
|
.provider('$$animation', $$AnimationProvider)
|
3713
3865
|
|