angularjs-rails 1.2.22 → 1.2.25
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/lib/angularjs-rails/version.rb +2 -2
- data/vendor/assets/javascripts/angular-animate.js +1 -1
- data/vendor/assets/javascripts/angular-cookies.js +1 -1
- data/vendor/assets/javascripts/angular-loader.js +5 -4
- data/vendor/assets/javascripts/angular-mocks.js +5 -1
- data/vendor/assets/javascripts/angular-resource.js +7 -1
- data/vendor/assets/javascripts/angular-route.js +1 -2
- data/vendor/assets/javascripts/angular-sanitize.js +2 -2
- data/vendor/assets/javascripts/angular-scenario.js +200 -98
- data/vendor/assets/javascripts/angular-touch.js +1 -1
- data/vendor/assets/javascripts/angular.js +200 -98
- data/vendor/assets/javascripts/unstable/angular-animate.js +390 -239
- data/vendor/assets/javascripts/unstable/angular-aria.js +250 -0
- data/vendor/assets/javascripts/unstable/angular-cookies.js +1 -1
- data/vendor/assets/javascripts/unstable/angular-loader.js +10 -7
- data/vendor/assets/javascripts/unstable/angular-messages.js +7 -7
- data/vendor/assets/javascripts/unstable/angular-mocks.js +23 -35
- data/vendor/assets/javascripts/unstable/angular-resource.js +10 -5
- data/vendor/assets/javascripts/unstable/angular-route.js +43 -15
- data/vendor/assets/javascripts/unstable/angular-sanitize.js +2 -2
- data/vendor/assets/javascripts/unstable/angular-scenario.js +2928 -1730
- data/vendor/assets/javascripts/unstable/angular-touch.js +1 -1
- data/vendor/assets/javascripts/unstable/angular.js +2922 -1710
- metadata +3 -2
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.3.0-
|
2
|
+
* @license AngularJS v1.3.0-rc.3
|
3
3
|
* (c) 2010-2014 Google, Inc. http://angularjs.org
|
4
4
|
* License: MIT
|
5
5
|
*/
|
@@ -79,6 +79,16 @@
|
|
79
79
|
* When the `on` expression value changes and an animation is triggered then each of the elements within
|
80
80
|
* will all animate without the block being applied to child elements.
|
81
81
|
*
|
82
|
+
* ## Are animations run when the application starts?
|
83
|
+
* No they are not. When an application is bootstrapped Angular will disable animations from running to avoid
|
84
|
+
* a frenzy of animations from being triggered as soon as the browser has rendered the screen. For this to work,
|
85
|
+
* Angular will wait for two digest cycles until enabling animations. From there on, any animation-triggering
|
86
|
+
* layout changes in the application will trigger animations as normal.
|
87
|
+
*
|
88
|
+
* In addition, upon bootstrap, if the routing system or any directives or load remote data (via $http) then Angular
|
89
|
+
* will automatically extend the wait time to enable animations once **all** of the outbound HTTP requests
|
90
|
+
* are complete.
|
91
|
+
*
|
82
92
|
* <h2>CSS-defined Animations</h2>
|
83
93
|
* The animate service will automatically apply two CSS classes to the animated element and these two CSS classes
|
84
94
|
* are designed to contain the start and end CSS styling. Both CSS transitions and keyframe animations are supported
|
@@ -270,7 +280,7 @@
|
|
270
280
|
*
|
271
281
|
* Stagger animations are currently only supported within CSS-defined animations.
|
272
282
|
*
|
273
|
-
*
|
283
|
+
* ## JavaScript-defined Animations
|
274
284
|
* In the event that you do not want to use CSS3 transitions or CSS3 animations or if you wish to offer animations on browsers that do not
|
275
285
|
* yet support CSS transitions/animations, then you can make use of JavaScript animations defined inside of your AngularJS module.
|
276
286
|
*
|
@@ -338,7 +348,7 @@ angular.module('ngAnimate', ['ng'])
|
|
338
348
|
var NG_ANIMATE_CHILDREN = '$$ngAnimateChildren';
|
339
349
|
return function(scope, element, attrs) {
|
340
350
|
var val = attrs.ngAnimateChildren;
|
341
|
-
if(angular.isString(val) && val.length === 0) { //empty attribute
|
351
|
+
if (angular.isString(val) && val.length === 0) { //empty attribute
|
342
352
|
element.data(NG_ANIMATE_CHILDREN, true);
|
343
353
|
} else {
|
344
354
|
scope.$watch(val, function(value) {
|
@@ -372,6 +382,7 @@ angular.module('ngAnimate', ['ng'])
|
|
372
382
|
var noop = angular.noop;
|
373
383
|
var forEach = angular.forEach;
|
374
384
|
var selectors = $animateProvider.$$selectors;
|
385
|
+
var isArray = angular.isArray;
|
375
386
|
|
376
387
|
var ELEMENT_NODE = 1;
|
377
388
|
var NG_ANIMATE_STATE = '$$ngAnimateState';
|
@@ -382,7 +393,7 @@ angular.module('ngAnimate', ['ng'])
|
|
382
393
|
function extractElementNode(element) {
|
383
394
|
for(var i = 0; i < element.length; i++) {
|
384
395
|
var elm = element[i];
|
385
|
-
if(elm.nodeType == ELEMENT_NODE) {
|
396
|
+
if (elm.nodeType == ELEMENT_NODE) {
|
386
397
|
return elm;
|
387
398
|
}
|
388
399
|
}
|
@@ -400,24 +411,38 @@ angular.module('ngAnimate', ['ng'])
|
|
400
411
|
return extractElementNode(elm1) == extractElementNode(elm2);
|
401
412
|
}
|
402
413
|
|
403
|
-
$provide.decorator('$animate',
|
404
|
-
|
414
|
+
$provide.decorator('$animate',
|
415
|
+
['$delegate', '$$q', '$injector', '$sniffer', '$rootElement', '$$asyncCallback', '$rootScope', '$document', '$templateRequest',
|
416
|
+
function($delegate, $$q, $injector, $sniffer, $rootElement, $$asyncCallback, $rootScope, $document, $templateRequest) {
|
405
417
|
|
406
|
-
var globalAnimationCounter = 0;
|
407
418
|
$rootElement.data(NG_ANIMATE_STATE, rootAnimateState);
|
408
419
|
|
409
|
-
//
|
410
|
-
//
|
411
|
-
//
|
412
|
-
//
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
+
// Wait until all directive and route-related templates are downloaded and
|
421
|
+
// compiled. The $templateRequest.totalPendingRequests variable keeps track of
|
422
|
+
// all of the remote templates being currently downloaded. If there are no
|
423
|
+
// templates currently downloading then the watcher will still fire anyway.
|
424
|
+
var deregisterWatch = $rootScope.$watch(
|
425
|
+
function() { return $templateRequest.totalPendingRequests; },
|
426
|
+
function(val, oldVal) {
|
427
|
+
if (val !== 0) return;
|
428
|
+
deregisterWatch();
|
429
|
+
|
430
|
+
// Now that all templates have been downloaded, $animate will wait until
|
431
|
+
// the post digest queue is empty before enabling animations. By having two
|
432
|
+
// calls to $postDigest calls we can ensure that the flag is enabled at the
|
433
|
+
// very end of the post digest queue. Since all of the animations in $animate
|
434
|
+
// use $postDigest, it's important that the code below executes at the end.
|
435
|
+
// This basically means that the page is fully downloaded and compiled before
|
436
|
+
// any animations are triggered.
|
437
|
+
$rootScope.$$postDigest(function() {
|
438
|
+
$rootScope.$$postDigest(function() {
|
439
|
+
rootAnimateState.running = false;
|
440
|
+
});
|
441
|
+
});
|
442
|
+
}
|
443
|
+
);
|
420
444
|
|
445
|
+
var globalAnimationCounter = 0;
|
421
446
|
var classNameFilter = $animateProvider.classNameFilter();
|
422
447
|
var isAnimatableClassName = !classNameFilter
|
423
448
|
? function() { return true; }
|
@@ -425,20 +450,81 @@ angular.module('ngAnimate', ['ng'])
|
|
425
450
|
return classNameFilter.test(className);
|
426
451
|
};
|
427
452
|
|
428
|
-
function
|
453
|
+
function classBasedAnimationsBlocked(element, setter) {
|
429
454
|
var data = element.data(NG_ANIMATE_STATE) || {};
|
430
|
-
|
431
|
-
|
455
|
+
if (setter) {
|
456
|
+
data.running = true;
|
457
|
+
data.structural = true;
|
458
|
+
element.data(NG_ANIMATE_STATE, data);
|
459
|
+
}
|
460
|
+
return data.disabled || (data.running && data.structural);
|
432
461
|
}
|
433
462
|
|
434
463
|
function runAnimationPostDigest(fn) {
|
435
|
-
var cancelFn;
|
436
|
-
|
437
|
-
cancelFn = fn();
|
438
|
-
});
|
439
|
-
return function() {
|
464
|
+
var cancelFn, defer = $$q.defer();
|
465
|
+
defer.promise.$$cancelFn = function() {
|
440
466
|
cancelFn && cancelFn();
|
441
467
|
};
|
468
|
+
$rootScope.$$postDigest(function() {
|
469
|
+
cancelFn = fn(function() {
|
470
|
+
defer.resolve();
|
471
|
+
});
|
472
|
+
});
|
473
|
+
return defer.promise;
|
474
|
+
}
|
475
|
+
|
476
|
+
function resolveElementClasses(element, cache, runningAnimations) {
|
477
|
+
runningAnimations = runningAnimations || {};
|
478
|
+
var map = {};
|
479
|
+
|
480
|
+
forEach(cache.add, function(className) {
|
481
|
+
if (className && className.length) {
|
482
|
+
map[className] = map[className] || 0;
|
483
|
+
map[className]++;
|
484
|
+
}
|
485
|
+
});
|
486
|
+
|
487
|
+
forEach(cache.remove, function(className) {
|
488
|
+
if (className && className.length) {
|
489
|
+
map[className] = map[className] || 0;
|
490
|
+
map[className]--;
|
491
|
+
}
|
492
|
+
});
|
493
|
+
|
494
|
+
var lookup = [];
|
495
|
+
forEach(runningAnimations, function(data, selector) {
|
496
|
+
forEach(selector.split(' '), function(s) {
|
497
|
+
lookup[s]=data;
|
498
|
+
});
|
499
|
+
});
|
500
|
+
|
501
|
+
var toAdd = [], toRemove = [];
|
502
|
+
forEach(map, function(status, className) {
|
503
|
+
var hasClass = angular.$$hasClass(element[0], className);
|
504
|
+
var matchingAnimation = lookup[className] || {};
|
505
|
+
|
506
|
+
// When addClass and removeClass is called then $animate will check to
|
507
|
+
// see if addClass and removeClass cancel each other out. When there are
|
508
|
+
// more calls to removeClass than addClass then the count falls below 0
|
509
|
+
// and then the removeClass animation will be allowed. Otherwise if the
|
510
|
+
// count is above 0 then that means an addClass animation will commence.
|
511
|
+
// Once an animation is allowed then the code will also check to see if
|
512
|
+
// there exists any on-going animation that is already adding or remvoing
|
513
|
+
// the matching CSS class.
|
514
|
+
if (status < 0) {
|
515
|
+
//does it have the class or will it have the class
|
516
|
+
if (hasClass || matchingAnimation.event == 'addClass') {
|
517
|
+
toRemove.push(className);
|
518
|
+
}
|
519
|
+
} else if (status > 0) {
|
520
|
+
//is the class missing or will it be removed?
|
521
|
+
if (!hasClass || matchingAnimation.event == 'removeClass') {
|
522
|
+
toAdd.push(className);
|
523
|
+
}
|
524
|
+
}
|
525
|
+
});
|
526
|
+
|
527
|
+
return (toAdd.length + toRemove.length) > 0 && [toAdd.join(' '), toRemove.join(' ')];
|
442
528
|
}
|
443
529
|
|
444
530
|
function lookup(name) {
|
@@ -462,7 +548,7 @@ angular.module('ngAnimate', ['ng'])
|
|
462
548
|
for(var i=0; i < classes.length; i++) {
|
463
549
|
var klass = classes[i],
|
464
550
|
selectorFactoryName = selectors[klass];
|
465
|
-
if(selectorFactoryName && !flagMap[klass]) {
|
551
|
+
if (selectorFactoryName && !flagMap[klass]) {
|
466
552
|
matches.push($injector.get(selectorFactoryName));
|
467
553
|
flagMap[klass] = true;
|
468
554
|
}
|
@@ -475,25 +561,34 @@ angular.module('ngAnimate', ['ng'])
|
|
475
561
|
//transcluded directives may sometimes fire an animation using only comment nodes
|
476
562
|
//best to catch this early on to prevent any animation operations from occurring
|
477
563
|
var node = element[0];
|
478
|
-
if(!node) {
|
564
|
+
if (!node) {
|
479
565
|
return;
|
480
566
|
}
|
481
567
|
|
568
|
+
var classNameAdd;
|
569
|
+
var classNameRemove;
|
570
|
+
if (isArray(className)) {
|
571
|
+
classNameAdd = className[0];
|
572
|
+
classNameRemove = className[1];
|
573
|
+
if (!classNameAdd) {
|
574
|
+
className = classNameRemove;
|
575
|
+
animationEvent = 'removeClass';
|
576
|
+
} else if (!classNameRemove) {
|
577
|
+
className = classNameAdd;
|
578
|
+
animationEvent = 'addClass';
|
579
|
+
} else {
|
580
|
+
className = classNameAdd + ' ' + classNameRemove;
|
581
|
+
}
|
582
|
+
}
|
583
|
+
|
482
584
|
var isSetClassOperation = animationEvent == 'setClass';
|
483
585
|
var isClassBased = isSetClassOperation ||
|
484
586
|
animationEvent == 'addClass' ||
|
485
587
|
animationEvent == 'removeClass';
|
486
588
|
|
487
|
-
var classNameAdd, classNameRemove;
|
488
|
-
if(angular.isArray(className)) {
|
489
|
-
classNameAdd = className[0];
|
490
|
-
classNameRemove = className[1];
|
491
|
-
className = classNameAdd + ' ' + classNameRemove;
|
492
|
-
}
|
493
|
-
|
494
589
|
var currentClassName = element.attr('class');
|
495
590
|
var classes = currentClassName + ' ' + className;
|
496
|
-
if(!isAnimatableClassName(classes)) {
|
591
|
+
if (!isAnimatableClassName(classes)) {
|
497
592
|
return;
|
498
593
|
}
|
499
594
|
|
@@ -507,7 +602,7 @@ angular.module('ngAnimate', ['ng'])
|
|
507
602
|
var animationLookup = (' ' + classes).replace(/\s+/g,'.');
|
508
603
|
forEach(lookup(animationLookup), function(animationFactory) {
|
509
604
|
var created = registerAnimation(animationFactory, animationEvent);
|
510
|
-
if(!created && isSetClassOperation) {
|
605
|
+
if (!created && isSetClassOperation) {
|
511
606
|
registerAnimation(animationFactory, 'addClass');
|
512
607
|
registerAnimation(animationFactory, 'removeClass');
|
513
608
|
}
|
@@ -516,8 +611,8 @@ angular.module('ngAnimate', ['ng'])
|
|
516
611
|
function registerAnimation(animationFactory, event) {
|
517
612
|
var afterFn = animationFactory[event];
|
518
613
|
var beforeFn = animationFactory['before' + event.charAt(0).toUpperCase() + event.substr(1)];
|
519
|
-
if(afterFn || beforeFn) {
|
520
|
-
if(event == 'leave') {
|
614
|
+
if (afterFn || beforeFn) {
|
615
|
+
if (event == 'leave') {
|
521
616
|
beforeFn = afterFn;
|
522
617
|
//when set as null then animation knows to skip this phase
|
523
618
|
afterFn = null;
|
@@ -540,9 +635,9 @@ angular.module('ngAnimate', ['ng'])
|
|
540
635
|
|
541
636
|
var count = 0;
|
542
637
|
function afterAnimationComplete(index) {
|
543
|
-
if(cancellations) {
|
638
|
+
if (cancellations) {
|
544
639
|
(cancellations[index] || noop)();
|
545
|
-
if(++count < animations.length) return;
|
640
|
+
if (++count < animations.length) return;
|
546
641
|
cancellations = null;
|
547
642
|
}
|
548
643
|
allCompleteFn();
|
@@ -571,7 +666,7 @@ angular.module('ngAnimate', ['ng'])
|
|
571
666
|
}
|
572
667
|
});
|
573
668
|
|
574
|
-
if(cancellations && cancellations.length === 0) {
|
669
|
+
if (cancellations && cancellations.length === 0) {
|
575
670
|
allCompleteFn();
|
576
671
|
}
|
577
672
|
}
|
@@ -597,13 +692,13 @@ angular.module('ngAnimate', ['ng'])
|
|
597
692
|
});
|
598
693
|
},
|
599
694
|
cancel : function() {
|
600
|
-
if(beforeCancel) {
|
695
|
+
if (beforeCancel) {
|
601
696
|
forEach(beforeCancel, function(cancelFn) {
|
602
697
|
(cancelFn || noop)(true);
|
603
698
|
});
|
604
699
|
beforeComplete(true);
|
605
700
|
}
|
606
|
-
if(afterCancel) {
|
701
|
+
if (afterCancel) {
|
607
702
|
forEach(afterCancel, function(cancelFn) {
|
608
703
|
(cancelFn || noop)(true);
|
609
704
|
});
|
@@ -616,7 +711,7 @@ angular.module('ngAnimate', ['ng'])
|
|
616
711
|
/**
|
617
712
|
* @ngdoc service
|
618
713
|
* @name $animate
|
619
|
-
* @kind
|
714
|
+
* @kind object
|
620
715
|
*
|
621
716
|
* @description
|
622
717
|
* The `$animate` service provides animation detection support while performing DOM operations (enter, leave and move) as well as during addClass and removeClass operations.
|
@@ -630,6 +725,46 @@ angular.module('ngAnimate', ['ng'])
|
|
630
725
|
* Requires the {@link ngAnimate `ngAnimate`} module to be installed.
|
631
726
|
*
|
632
727
|
* Please visit the {@link ngAnimate `ngAnimate`} module overview page learn more about how to use animations in your application.
|
728
|
+
* ## Callback Promises
|
729
|
+
* With AngularJS 1.3, each of the animation methods, on the `$animate` service, return a promise when called. The
|
730
|
+
* promise itself is then resolved once the animation has completed itself, has been cancelled or has been
|
731
|
+
* skipped due to animations being disabled. (Note that even if the animation is cancelled it will still
|
732
|
+
* call the resolve function of the animation.)
|
733
|
+
*
|
734
|
+
* ```js
|
735
|
+
* $animate.enter(element, container).then(function() {
|
736
|
+
* //...this is called once the animation is complete...
|
737
|
+
* });
|
738
|
+
* ```
|
739
|
+
*
|
740
|
+
* Also note that, due to the nature of the callback promise, if any Angular-specific code (like changing the scope,
|
741
|
+
* location of the page, etc...) is executed within the callback promise then be sure to wrap the code using
|
742
|
+
* `$scope.$apply(...)`;
|
743
|
+
*
|
744
|
+
* ```js
|
745
|
+
* $animate.leave(element).then(function() {
|
746
|
+
* $scope.$apply(function() {
|
747
|
+
* $location.path('/new-page');
|
748
|
+
* });
|
749
|
+
* });
|
750
|
+
* ```
|
751
|
+
*
|
752
|
+
* An animation can also be cancelled by calling the `$animate.cancel(promise)` method with the provided
|
753
|
+
* promise that was returned when the animation was started.
|
754
|
+
*
|
755
|
+
* ```js
|
756
|
+
* var promise = $animate.addClass(element, 'super-long-animation').then(function() {
|
757
|
+
* //this will still be called even if cancelled
|
758
|
+
* });
|
759
|
+
*
|
760
|
+
* element.on('click', function() {
|
761
|
+
* //tooo lazy to wait for the animation to end
|
762
|
+
* $animate.cancel(promise);
|
763
|
+
* });
|
764
|
+
* ```
|
765
|
+
*
|
766
|
+
* (Keep in mind that the promise cancellation is unique to `$animate` since promises in
|
767
|
+
* general cannot be cancelled.)
|
633
768
|
*
|
634
769
|
*/
|
635
770
|
return {
|
@@ -658,23 +793,22 @@ angular.module('ngAnimate', ['ng'])
|
|
658
793
|
* | 10. the .ng-enter-active class is added (this triggers the CSS transition/animation) | class="my-animation ng-animate ng-enter ng-enter-active" |
|
659
794
|
* | 11. $animate waits for the animation to complete (via events and timeout) | class="my-animation ng-animate ng-enter ng-enter-active" |
|
660
795
|
* | 12. The animation ends and all generated CSS classes are removed from the element | class="my-animation" |
|
661
|
-
* | 13. The
|
796
|
+
* | 13. The returned promise is resolved. | class="my-animation" |
|
662
797
|
*
|
663
798
|
* @param {DOMElement} element the element that will be the focus of the enter animation
|
664
799
|
* @param {DOMElement} parentElement the parent element of the element that will be the focus of the enter animation
|
665
800
|
* @param {DOMElement} afterElement the sibling element (which is the previous element) of the element that will be the focus of the enter animation
|
666
|
-
* @
|
667
|
-
* @return {function} the animation cancellation function
|
801
|
+
* @return {Promise} the animation callback promise
|
668
802
|
*/
|
669
|
-
enter : function(element, parentElement, afterElement
|
803
|
+
enter : function(element, parentElement, afterElement) {
|
670
804
|
element = angular.element(element);
|
671
805
|
parentElement = prepareElement(parentElement);
|
672
806
|
afterElement = prepareElement(afterElement);
|
673
807
|
|
674
|
-
|
808
|
+
classBasedAnimationsBlocked(element, true);
|
675
809
|
$delegate.enter(element, parentElement, afterElement);
|
676
|
-
return runAnimationPostDigest(function() {
|
677
|
-
return performAnimation('enter', 'ng-enter', stripCommentsFromElement(element), parentElement, afterElement, noop,
|
810
|
+
return runAnimationPostDigest(function(done) {
|
811
|
+
return performAnimation('enter', 'ng-enter', stripCommentsFromElement(element), parentElement, afterElement, noop, done);
|
678
812
|
});
|
679
813
|
},
|
680
814
|
|
@@ -703,22 +837,21 @@ angular.module('ngAnimate', ['ng'])
|
|
703
837
|
* | 10. $animate waits for the animation to complete (via events and timeout) | class="my-animation ng-animate ng-leave ng-leave-active" |
|
704
838
|
* | 11. The animation ends and all generated CSS classes are removed from the element | class="my-animation" |
|
705
839
|
* | 12. The element is removed from the DOM | ... |
|
706
|
-
* | 13. The
|
840
|
+
* | 13. The returned promise is resolved. | ... |
|
707
841
|
*
|
708
842
|
* @param {DOMElement} element the element that will be the focus of the leave animation
|
709
|
-
* @
|
710
|
-
* @return {function} the animation cancellation function
|
843
|
+
* @return {Promise} the animation callback promise
|
711
844
|
*/
|
712
|
-
leave : function(element
|
845
|
+
leave : function(element) {
|
713
846
|
element = angular.element(element);
|
714
847
|
|
715
848
|
cancelChildAnimations(element);
|
716
|
-
|
849
|
+
classBasedAnimationsBlocked(element, true);
|
717
850
|
this.enabled(false, element);
|
718
|
-
return runAnimationPostDigest(function() {
|
851
|
+
return runAnimationPostDigest(function(done) {
|
719
852
|
return performAnimation('leave', 'ng-leave', stripCommentsFromElement(element), null, null, function() {
|
720
853
|
$delegate.leave(element);
|
721
|
-
},
|
854
|
+
}, done);
|
722
855
|
});
|
723
856
|
},
|
724
857
|
|
@@ -748,24 +881,23 @@ angular.module('ngAnimate', ['ng'])
|
|
748
881
|
* | 10. the .ng-move-active class is added (this triggers the CSS transition/animation) | class="my-animation ng-animate ng-move ng-move-active" |
|
749
882
|
* | 11. $animate waits for the animation to complete (via events and timeout) | class="my-animation ng-animate ng-move ng-move-active" |
|
750
883
|
* | 12. The animation ends and all generated CSS classes are removed from the element | class="my-animation" |
|
751
|
-
* | 13. The
|
884
|
+
* | 13. The returned promise is resolved. | class="my-animation" |
|
752
885
|
*
|
753
886
|
* @param {DOMElement} element the element that will be the focus of the move animation
|
754
887
|
* @param {DOMElement} parentElement the parentElement element of the element that will be the focus of the move animation
|
755
888
|
* @param {DOMElement} afterElement the sibling element (which is the previous element) of the element that will be the focus of the move animation
|
756
|
-
* @
|
757
|
-
* @return {function} the animation cancellation function
|
889
|
+
* @return {Promise} the animation callback promise
|
758
890
|
*/
|
759
|
-
move : function(element, parentElement, afterElement
|
891
|
+
move : function(element, parentElement, afterElement) {
|
760
892
|
element = angular.element(element);
|
761
893
|
parentElement = prepareElement(parentElement);
|
762
894
|
afterElement = prepareElement(afterElement);
|
763
895
|
|
764
896
|
cancelChildAnimations(element);
|
765
|
-
|
897
|
+
classBasedAnimationsBlocked(element, true);
|
766
898
|
$delegate.move(element, parentElement, afterElement);
|
767
|
-
return runAnimationPostDigest(function() {
|
768
|
-
return performAnimation('move', 'ng-move', stripCommentsFromElement(element), parentElement, afterElement, noop,
|
899
|
+
return runAnimationPostDigest(function(done) {
|
900
|
+
return performAnimation('move', 'ng-move', stripCommentsFromElement(element), parentElement, afterElement, noop, done);
|
769
901
|
});
|
770
902
|
},
|
771
903
|
|
@@ -792,19 +924,14 @@ angular.module('ngAnimate', ['ng'])
|
|
792
924
|
* | 7. $animate waits for the animation to complete (via events and timeout) | class="my-animation super super-add super-add-active" |
|
793
925
|
* | 8. The animation ends and all generated CSS classes are removed from the element | class="my-animation super" |
|
794
926
|
* | 9. The super class is kept on the element | class="my-animation super" |
|
795
|
-
* | 10. The
|
927
|
+
* | 10. The returned promise is resolved. | class="my-animation super" |
|
796
928
|
*
|
797
929
|
* @param {DOMElement} element the element that will be animated
|
798
930
|
* @param {string} className the CSS class that will be added to the element and then animated
|
799
|
-
* @
|
800
|
-
* @return {function} the animation cancellation function
|
931
|
+
* @return {Promise} the animation callback promise
|
801
932
|
*/
|
802
|
-
addClass : function(element, className
|
803
|
-
|
804
|
-
element = stripCommentsFromElement(element);
|
805
|
-
return performAnimation('addClass', className, element, null, null, function() {
|
806
|
-
$delegate.addClass(element, className);
|
807
|
-
}, doneCallback);
|
933
|
+
addClass : function(element, className) {
|
934
|
+
return this.setClass(element, className, []);
|
808
935
|
},
|
809
936
|
|
810
937
|
/**
|
@@ -829,20 +956,15 @@ angular.module('ngAnimate', ['ng'])
|
|
829
956
|
* | 6. $animate scans the element styles to get the CSS transition/animation duration and delay | class="my-animation super ng-animate super-remove" |
|
830
957
|
* | 7. $animate waits for the animation to complete (via events and timeout) | class="my-animation ng-animate super-remove super-remove-active" |
|
831
958
|
* | 8. The animation ends and all generated CSS classes are removed from the element | class="my-animation" |
|
832
|
-
* | 9. The
|
959
|
+
* | 9. The returned promise is resolved. | class="my-animation" |
|
833
960
|
*
|
834
961
|
*
|
835
962
|
* @param {DOMElement} element the element that will be animated
|
836
963
|
* @param {string} className the CSS class that will be animated and then removed from the element
|
837
|
-
* @
|
838
|
-
* @return {function} the animation cancellation function
|
964
|
+
* @return {Promise} the animation callback promise
|
839
965
|
*/
|
840
|
-
removeClass : function(element, className
|
841
|
-
|
842
|
-
element = stripCommentsFromElement(element);
|
843
|
-
return performAnimation('removeClass', className, element, null, null, function() {
|
844
|
-
$delegate.removeClass(element, className);
|
845
|
-
}, doneCallback);
|
966
|
+
removeClass : function(element, className) {
|
967
|
+
return this.setClass(element, [], className);
|
846
968
|
},
|
847
969
|
|
848
970
|
/**
|
@@ -862,23 +984,68 @@ angular.module('ngAnimate', ['ng'])
|
|
862
984
|
* | 5. the .on, .on-add-active and .off-remove-active classes are added and .off is removed (this triggers the CSS transition/animation) | class="my-animation ng-animate on on-add on-add-active off-remove off-remove-active” |
|
863
985
|
* | 6. $animate scans the element styles to get the CSS transition/animation duration and delay | class="my-animation ng-animate on on-add on-add-active off-remove off-remove-active" |
|
864
986
|
* | 7. $animate waits for the animation to complete (via events and timeout) | class="my-animation ng-animate on on-add on-add-active off-remove off-remove-active" |
|
865
|
-
* | 8. The animation ends and all generated CSS classes are removed from the element | class="my-animation"
|
866
|
-
* | 9. The
|
987
|
+
* | 8. The animation ends and all generated CSS classes are removed from the element | class="my-animation on" |
|
988
|
+
* | 9. The returned promise is resolved. | class="my-animation on" |
|
867
989
|
*
|
868
990
|
* @param {DOMElement} element the element which will have its CSS classes changed
|
869
991
|
* removed from it
|
870
992
|
* @param {string} add the CSS classes which will be added to the element
|
871
993
|
* @param {string} remove the CSS class which will be removed from the element
|
872
|
-
* @param {function=} done the callback function (if provided) that will be fired after the
|
873
994
|
* CSS classes have been set on the element
|
874
|
-
* @return {
|
995
|
+
* @return {Promise} the animation callback promise
|
875
996
|
*/
|
876
|
-
setClass : function(element, add, remove
|
997
|
+
setClass : function(element, add, remove) {
|
998
|
+
var STORAGE_KEY = '$$animateClasses';
|
877
999
|
element = angular.element(element);
|
878
1000
|
element = stripCommentsFromElement(element);
|
879
|
-
|
880
|
-
|
881
|
-
|
1001
|
+
|
1002
|
+
if (classBasedAnimationsBlocked(element)) {
|
1003
|
+
return $delegate.setClass(element, add, remove);
|
1004
|
+
}
|
1005
|
+
|
1006
|
+
add = isArray(add) ? add : add.split(' ');
|
1007
|
+
remove = isArray(remove) ? remove : remove.split(' ');
|
1008
|
+
|
1009
|
+
var cache = element.data(STORAGE_KEY);
|
1010
|
+
if (cache) {
|
1011
|
+
cache.add = cache.add.concat(add);
|
1012
|
+
cache.remove = cache.remove.concat(remove);
|
1013
|
+
|
1014
|
+
//the digest cycle will combine all the animations into one function
|
1015
|
+
return cache.promise;
|
1016
|
+
} else {
|
1017
|
+
element.data(STORAGE_KEY, cache = {
|
1018
|
+
add : add,
|
1019
|
+
remove : remove
|
1020
|
+
});
|
1021
|
+
}
|
1022
|
+
|
1023
|
+
return cache.promise = runAnimationPostDigest(function(done) {
|
1024
|
+
var cache = element.data(STORAGE_KEY);
|
1025
|
+
element.removeData(STORAGE_KEY);
|
1026
|
+
|
1027
|
+
var state = element.data(NG_ANIMATE_STATE) || {};
|
1028
|
+
var classes = resolveElementClasses(element, cache, state.active);
|
1029
|
+
return !classes
|
1030
|
+
? done()
|
1031
|
+
: performAnimation('setClass', classes, element, null, null, function() {
|
1032
|
+
$delegate.setClass(element, classes[0], classes[1]);
|
1033
|
+
}, done);
|
1034
|
+
});
|
1035
|
+
},
|
1036
|
+
|
1037
|
+
/**
|
1038
|
+
* @ngdoc method
|
1039
|
+
* @name $animate#cancel
|
1040
|
+
* @kind function
|
1041
|
+
*
|
1042
|
+
* @param {Promise} animationPromise The animation promise that is returned when an animation is started.
|
1043
|
+
*
|
1044
|
+
* @description
|
1045
|
+
* Cancels the provided animation.
|
1046
|
+
*/
|
1047
|
+
cancel : function(promise) {
|
1048
|
+
promise.$$cancelFn();
|
882
1049
|
},
|
883
1050
|
|
884
1051
|
/**
|
@@ -897,7 +1064,7 @@ angular.module('ngAnimate', ['ng'])
|
|
897
1064
|
enabled : function(value, element) {
|
898
1065
|
switch(arguments.length) {
|
899
1066
|
case 2:
|
900
|
-
if(value) {
|
1067
|
+
if (value) {
|
901
1068
|
cleanup(element);
|
902
1069
|
} else {
|
903
1070
|
var data = element.data(NG_ANIMATE_STATE) || {};
|
@@ -929,7 +1096,7 @@ angular.module('ngAnimate', ['ng'])
|
|
929
1096
|
|
930
1097
|
var noopCancel = noop;
|
931
1098
|
var runner = animationRunner(element, animationEvent, className);
|
932
|
-
if(!runner) {
|
1099
|
+
if (!runner) {
|
933
1100
|
fireDOMOperation();
|
934
1101
|
fireBeforeCallbackAsync();
|
935
1102
|
fireAfterCallbackAsync();
|
@@ -937,6 +1104,7 @@ angular.module('ngAnimate', ['ng'])
|
|
937
1104
|
return noopCancel;
|
938
1105
|
}
|
939
1106
|
|
1107
|
+
animationEvent = runner.event;
|
940
1108
|
className = runner.className;
|
941
1109
|
var elementEvents = angular.element._data(runner.node);
|
942
1110
|
elementEvents = elementEvents && elementEvents.events;
|
@@ -945,25 +1113,11 @@ angular.module('ngAnimate', ['ng'])
|
|
945
1113
|
parentElement = afterElement ? afterElement.parent() : element.parent();
|
946
1114
|
}
|
947
1115
|
|
948
|
-
var ngAnimateState = element.data(NG_ANIMATE_STATE) || {};
|
949
|
-
var runningAnimations = ngAnimateState.active || {};
|
950
|
-
var totalActiveAnimations = ngAnimateState.totalActive || 0;
|
951
|
-
var lastAnimation = ngAnimateState.last;
|
952
|
-
|
953
|
-
//only allow animations if the currently running animation is not structural
|
954
|
-
//or if there is no animation running at all
|
955
|
-
var skipAnimations;
|
956
|
-
if (runner.isClassBased) {
|
957
|
-
skipAnimations = ngAnimateState.running ||
|
958
|
-
ngAnimateState.disabled ||
|
959
|
-
(lastAnimation && !lastAnimation.isClassBased);
|
960
|
-
}
|
961
|
-
|
962
1116
|
//skip the animation if animations are disabled, a parent is already being animated,
|
963
1117
|
//the element is not currently attached to the document body or then completely close
|
964
1118
|
//the animation if any matching animations are not found at all.
|
965
1119
|
//NOTE: IE8 + IE9 should close properly (run closeAnimation()) in case an animation was found.
|
966
|
-
if (
|
1120
|
+
if (animationsDisabled(element, parentElement)) {
|
967
1121
|
fireDOMOperation();
|
968
1122
|
fireBeforeCallbackAsync();
|
969
1123
|
fireAfterCallbackAsync();
|
@@ -971,11 +1125,16 @@ angular.module('ngAnimate', ['ng'])
|
|
971
1125
|
return noopCancel;
|
972
1126
|
}
|
973
1127
|
|
1128
|
+
var ngAnimateState = element.data(NG_ANIMATE_STATE) || {};
|
1129
|
+
var runningAnimations = ngAnimateState.active || {};
|
1130
|
+
var totalActiveAnimations = ngAnimateState.totalActive || 0;
|
1131
|
+
var lastAnimation = ngAnimateState.last;
|
974
1132
|
var skipAnimation = false;
|
975
|
-
|
1133
|
+
|
1134
|
+
if (totalActiveAnimations > 0) {
|
976
1135
|
var animationsToCancel = [];
|
977
|
-
if(!runner.isClassBased) {
|
978
|
-
if(animationEvent == 'leave' && runningAnimations['ng-leave']) {
|
1136
|
+
if (!runner.isClassBased) {
|
1137
|
+
if (animationEvent == 'leave' && runningAnimations['ng-leave']) {
|
979
1138
|
skipAnimation = true;
|
980
1139
|
} else {
|
981
1140
|
//cancel all animations when a structural animation takes place
|
@@ -985,13 +1144,13 @@ angular.module('ngAnimate', ['ng'])
|
|
985
1144
|
ngAnimateState = {};
|
986
1145
|
cleanup(element, true);
|
987
1146
|
}
|
988
|
-
} else if(lastAnimation.event == 'setClass') {
|
1147
|
+
} else if (lastAnimation.event == 'setClass') {
|
989
1148
|
animationsToCancel.push(lastAnimation);
|
990
1149
|
cleanup(element, className);
|
991
1150
|
}
|
992
|
-
else if(runningAnimations[className]) {
|
1151
|
+
else if (runningAnimations[className]) {
|
993
1152
|
var current = runningAnimations[className];
|
994
|
-
if(current.event == animationEvent) {
|
1153
|
+
if (current.event == animationEvent) {
|
995
1154
|
skipAnimation = true;
|
996
1155
|
} else {
|
997
1156
|
animationsToCancel.push(current);
|
@@ -999,21 +1158,18 @@ angular.module('ngAnimate', ['ng'])
|
|
999
1158
|
}
|
1000
1159
|
}
|
1001
1160
|
|
1002
|
-
if(animationsToCancel.length > 0) {
|
1161
|
+
if (animationsToCancel.length > 0) {
|
1003
1162
|
forEach(animationsToCancel, function(operation) {
|
1004
1163
|
operation.cancel();
|
1005
1164
|
});
|
1006
1165
|
}
|
1007
1166
|
}
|
1008
1167
|
|
1009
|
-
|
1010
|
-
totalActiveAnimations = ngAnimateState.totalActive || 0;
|
1011
|
-
|
1012
|
-
if(runner.isClassBased && !runner.isSetClassOperation && !skipAnimation) {
|
1168
|
+
if (runner.isClassBased && !runner.isSetClassOperation && !skipAnimation) {
|
1013
1169
|
skipAnimation = (animationEvent == 'addClass') == element.hasClass(className); //opposite of XOR
|
1014
1170
|
}
|
1015
1171
|
|
1016
|
-
if(skipAnimation) {
|
1172
|
+
if (skipAnimation) {
|
1017
1173
|
fireDOMOperation();
|
1018
1174
|
fireBeforeCallbackAsync();
|
1019
1175
|
fireAfterCallbackAsync();
|
@@ -1021,16 +1177,19 @@ angular.module('ngAnimate', ['ng'])
|
|
1021
1177
|
return noopCancel;
|
1022
1178
|
}
|
1023
1179
|
|
1024
|
-
|
1180
|
+
runningAnimations = ngAnimateState.active || {};
|
1181
|
+
totalActiveAnimations = ngAnimateState.totalActive || 0;
|
1182
|
+
|
1183
|
+
if (animationEvent == 'leave') {
|
1025
1184
|
//there's no need to ever remove the listener since the element
|
1026
1185
|
//will be removed (destroyed) after the leave animation ends or
|
1027
1186
|
//is cancelled midway
|
1028
1187
|
element.one('$destroy', function(e) {
|
1029
1188
|
var element = angular.element(this);
|
1030
1189
|
var state = element.data(NG_ANIMATE_STATE);
|
1031
|
-
if(state) {
|
1190
|
+
if (state) {
|
1032
1191
|
var activeLeaveAnimation = state.active['ng-leave'];
|
1033
|
-
if(activeLeaveAnimation) {
|
1192
|
+
if (activeLeaveAnimation) {
|
1034
1193
|
activeLeaveAnimation.cancel();
|
1035
1194
|
cleanup(element, 'ng-leave');
|
1036
1195
|
}
|
@@ -1063,7 +1222,7 @@ angular.module('ngAnimate', ['ng'])
|
|
1063
1222
|
(runner.isClassBased && data.active[className].event != animationEvent);
|
1064
1223
|
|
1065
1224
|
fireDOMOperation();
|
1066
|
-
if(cancelled === true) {
|
1225
|
+
if (cancelled === true) {
|
1067
1226
|
closeAnimation();
|
1068
1227
|
} else {
|
1069
1228
|
fireAfterCallbackAsync();
|
@@ -1075,7 +1234,7 @@ angular.module('ngAnimate', ['ng'])
|
|
1075
1234
|
|
1076
1235
|
function fireDOMCallback(animationPhase) {
|
1077
1236
|
var eventName = '$animate:' + animationPhase;
|
1078
|
-
if(elementEvents && elementEvents[eventName] && elementEvents[eventName].length > 0) {
|
1237
|
+
if (elementEvents && elementEvents[eventName] && elementEvents[eventName].length > 0) {
|
1079
1238
|
$$asyncCallback(function() {
|
1080
1239
|
element.triggerHandler(eventName, {
|
1081
1240
|
event : animationEvent,
|
@@ -1095,37 +1254,33 @@ angular.module('ngAnimate', ['ng'])
|
|
1095
1254
|
|
1096
1255
|
function fireDoneCallbackAsync() {
|
1097
1256
|
fireDOMCallback('close');
|
1098
|
-
|
1099
|
-
$$asyncCallback(function() {
|
1100
|
-
doneCallback();
|
1101
|
-
});
|
1102
|
-
}
|
1257
|
+
doneCallback();
|
1103
1258
|
}
|
1104
1259
|
|
1105
1260
|
//it is less complicated to use a flag than managing and canceling
|
1106
1261
|
//timeouts containing multiple callbacks.
|
1107
1262
|
function fireDOMOperation() {
|
1108
|
-
if(!fireDOMOperation.hasBeenRun) {
|
1263
|
+
if (!fireDOMOperation.hasBeenRun) {
|
1109
1264
|
fireDOMOperation.hasBeenRun = true;
|
1110
1265
|
domOperation();
|
1111
1266
|
}
|
1112
1267
|
}
|
1113
1268
|
|
1114
1269
|
function closeAnimation() {
|
1115
|
-
if(!closeAnimation.hasBeenRun) {
|
1270
|
+
if (!closeAnimation.hasBeenRun) {
|
1116
1271
|
closeAnimation.hasBeenRun = true;
|
1117
1272
|
var data = element.data(NG_ANIMATE_STATE);
|
1118
|
-
if(data) {
|
1273
|
+
if (data) {
|
1119
1274
|
/* only structural animations wait for reflow before removing an
|
1120
1275
|
animation, but class-based animations don't. An example of this
|
1121
1276
|
failing would be when a parent HTML tag has a ng-class attribute
|
1122
1277
|
causing ALL directives below to skip animations during the digest */
|
1123
|
-
if(runner && runner.isClassBased) {
|
1278
|
+
if (runner && runner.isClassBased) {
|
1124
1279
|
cleanup(element, className);
|
1125
1280
|
} else {
|
1126
1281
|
$$asyncCallback(function() {
|
1127
1282
|
var data = element.data(NG_ANIMATE_STATE) || {};
|
1128
|
-
if(localAnimationCount == data.index) {
|
1283
|
+
if (localAnimationCount == data.index) {
|
1129
1284
|
cleanup(element, className, animationEvent);
|
1130
1285
|
}
|
1131
1286
|
});
|
@@ -1146,7 +1301,7 @@ angular.module('ngAnimate', ['ng'])
|
|
1146
1301
|
forEach(nodes, function(element) {
|
1147
1302
|
element = angular.element(element);
|
1148
1303
|
var data = element.data(NG_ANIMATE_STATE);
|
1149
|
-
if(data && data.active) {
|
1304
|
+
if (data && data.active) {
|
1150
1305
|
forEach(data.active, function(runner) {
|
1151
1306
|
runner.cancel();
|
1152
1307
|
});
|
@@ -1156,21 +1311,21 @@ angular.module('ngAnimate', ['ng'])
|
|
1156
1311
|
}
|
1157
1312
|
|
1158
1313
|
function cleanup(element, className) {
|
1159
|
-
if(isMatchingElement(element, $rootElement)) {
|
1160
|
-
if(!rootAnimateState.disabled) {
|
1314
|
+
if (isMatchingElement(element, $rootElement)) {
|
1315
|
+
if (!rootAnimateState.disabled) {
|
1161
1316
|
rootAnimateState.running = false;
|
1162
1317
|
rootAnimateState.structural = false;
|
1163
1318
|
}
|
1164
|
-
} else if(className) {
|
1319
|
+
} else if (className) {
|
1165
1320
|
var data = element.data(NG_ANIMATE_STATE) || {};
|
1166
1321
|
|
1167
1322
|
var removeAnimations = className === true;
|
1168
|
-
if(!removeAnimations && data.active && data.active[className]) {
|
1323
|
+
if (!removeAnimations && data.active && data.active[className]) {
|
1169
1324
|
data.totalActive--;
|
1170
1325
|
delete data.active[className];
|
1171
1326
|
}
|
1172
1327
|
|
1173
|
-
if(removeAnimations || !data.totalActive) {
|
1328
|
+
if (removeAnimations || !data.totalActive) {
|
1174
1329
|
element.removeClass(NG_ANIMATE_CLASS_NAME);
|
1175
1330
|
element.removeData(NG_ANIMATE_STATE);
|
1176
1331
|
}
|
@@ -1209,7 +1364,7 @@ angular.module('ngAnimate', ['ng'])
|
|
1209
1364
|
//it will be discarded and all child animations will be restricted
|
1210
1365
|
if (allowChildAnimations !== false) {
|
1211
1366
|
var animateChildrenFlag = parentElement.data(NG_ANIMATE_CHILDREN);
|
1212
|
-
if(angular.isDefined(animateChildrenFlag)) {
|
1367
|
+
if (angular.isDefined(animateChildrenFlag)) {
|
1213
1368
|
allowChildAnimations = animateChildrenFlag;
|
1214
1369
|
}
|
1215
1370
|
}
|
@@ -1259,6 +1414,7 @@ angular.module('ngAnimate', ['ng'])
|
|
1259
1414
|
var PROPERTY_KEY = 'Property';
|
1260
1415
|
var DELAY_KEY = 'Delay';
|
1261
1416
|
var ANIMATION_ITERATION_COUNT_KEY = 'IterationCount';
|
1417
|
+
var ANIMATION_PLAYSTATE_KEY = 'PlayState';
|
1262
1418
|
var NG_ANIMATE_PARENT_KEY = '$$ngAnimateKey';
|
1263
1419
|
var NG_ANIMATE_CSS_DATA_KEY = '$$ngAnimateCSS3Data';
|
1264
1420
|
var ELAPSED_TIME_MAX_DECIMAL_PLACES = 3;
|
@@ -1270,7 +1426,7 @@ angular.module('ngAnimate', ['ng'])
|
|
1270
1426
|
var animationReflowQueue = [];
|
1271
1427
|
var cancelAnimationReflow;
|
1272
1428
|
function afterReflow(element, callback) {
|
1273
|
-
if(cancelAnimationReflow) {
|
1429
|
+
if (cancelAnimationReflow) {
|
1274
1430
|
cancelAnimationReflow();
|
1275
1431
|
}
|
1276
1432
|
animationReflowQueue.push(callback);
|
@@ -1299,7 +1455,7 @@ angular.module('ngAnimate', ['ng'])
|
|
1299
1455
|
//but it may not need to cancel out the existing timeout
|
1300
1456
|
//if the timestamp is less than the previous one
|
1301
1457
|
var futureTimestamp = Date.now() + totalTime;
|
1302
|
-
if(futureTimestamp <= closingTimestamp) {
|
1458
|
+
if (futureTimestamp <= closingTimestamp) {
|
1303
1459
|
return;
|
1304
1460
|
}
|
1305
1461
|
|
@@ -1315,7 +1471,7 @@ angular.module('ngAnimate', ['ng'])
|
|
1315
1471
|
function closeAllAnimations(elements) {
|
1316
1472
|
forEach(elements, function(element) {
|
1317
1473
|
var elementData = element.data(NG_ANIMATE_CSS_DATA_KEY);
|
1318
|
-
if(elementData) {
|
1474
|
+
if (elementData) {
|
1319
1475
|
forEach(elementData.closeAnimationFns, function(fn) {
|
1320
1476
|
fn();
|
1321
1477
|
});
|
@@ -1325,56 +1481,42 @@ angular.module('ngAnimate', ['ng'])
|
|
1325
1481
|
|
1326
1482
|
function getElementAnimationDetails(element, cacheKey) {
|
1327
1483
|
var data = cacheKey ? lookupCache[cacheKey] : null;
|
1328
|
-
if(!data) {
|
1484
|
+
if (!data) {
|
1329
1485
|
var transitionDuration = 0;
|
1330
1486
|
var transitionDelay = 0;
|
1331
1487
|
var animationDuration = 0;
|
1332
1488
|
var animationDelay = 0;
|
1333
|
-
var transitionDelayStyle;
|
1334
|
-
var animationDelayStyle;
|
1335
|
-
var transitionDurationStyle;
|
1336
|
-
var transitionPropertyStyle;
|
1337
1489
|
|
1338
1490
|
//we want all the styles defined before and after
|
1339
1491
|
forEach(element, function(element) {
|
1340
1492
|
if (element.nodeType == ELEMENT_NODE) {
|
1341
1493
|
var elementStyles = $window.getComputedStyle(element) || {};
|
1342
1494
|
|
1343
|
-
transitionDurationStyle = elementStyles[TRANSITION_PROP + DURATION_KEY];
|
1344
|
-
|
1495
|
+
var transitionDurationStyle = elementStyles[TRANSITION_PROP + DURATION_KEY];
|
1345
1496
|
transitionDuration = Math.max(parseMaxTime(transitionDurationStyle), transitionDuration);
|
1346
1497
|
|
1347
|
-
|
1348
|
-
|
1349
|
-
transitionDelayStyle = elementStyles[TRANSITION_PROP + DELAY_KEY];
|
1350
|
-
|
1498
|
+
var transitionDelayStyle = elementStyles[TRANSITION_PROP + DELAY_KEY];
|
1351
1499
|
transitionDelay = Math.max(parseMaxTime(transitionDelayStyle), transitionDelay);
|
1352
1500
|
|
1353
|
-
animationDelayStyle = elementStyles[ANIMATION_PROP + DELAY_KEY];
|
1354
|
-
|
1355
|
-
animationDelay = Math.max(parseMaxTime(animationDelayStyle), animationDelay);
|
1501
|
+
var animationDelayStyle = elementStyles[ANIMATION_PROP + DELAY_KEY];
|
1502
|
+
animationDelay = Math.max(parseMaxTime(elementStyles[ANIMATION_PROP + DELAY_KEY]), animationDelay);
|
1356
1503
|
|
1357
1504
|
var aDuration = parseMaxTime(elementStyles[ANIMATION_PROP + DURATION_KEY]);
|
1358
1505
|
|
1359
|
-
if(aDuration > 0) {
|
1506
|
+
if (aDuration > 0) {
|
1360
1507
|
aDuration *= parseInt(elementStyles[ANIMATION_PROP + ANIMATION_ITERATION_COUNT_KEY], 10) || 1;
|
1361
1508
|
}
|
1362
|
-
|
1363
1509
|
animationDuration = Math.max(aDuration, animationDuration);
|
1364
1510
|
}
|
1365
1511
|
});
|
1366
1512
|
data = {
|
1367
1513
|
total : 0,
|
1368
|
-
transitionPropertyStyle: transitionPropertyStyle,
|
1369
|
-
transitionDurationStyle: transitionDurationStyle,
|
1370
|
-
transitionDelayStyle: transitionDelayStyle,
|
1371
1514
|
transitionDelay: transitionDelay,
|
1372
1515
|
transitionDuration: transitionDuration,
|
1373
|
-
animationDelayStyle: animationDelayStyle,
|
1374
1516
|
animationDelay: animationDelay,
|
1375
1517
|
animationDuration: animationDuration
|
1376
1518
|
};
|
1377
|
-
if(cacheKey) {
|
1519
|
+
if (cacheKey) {
|
1378
1520
|
lookupCache[cacheKey] = data;
|
1379
1521
|
}
|
1380
1522
|
}
|
@@ -1395,7 +1537,7 @@ angular.module('ngAnimate', ['ng'])
|
|
1395
1537
|
function getCacheKey(element) {
|
1396
1538
|
var parentElement = element.parent();
|
1397
1539
|
var parentID = parentElement.data(NG_ANIMATE_PARENT_KEY);
|
1398
|
-
if(!parentID) {
|
1540
|
+
if (!parentID) {
|
1399
1541
|
parentElement.data(NG_ANIMATE_PARENT_KEY, ++parentCounter);
|
1400
1542
|
parentID = parentCounter;
|
1401
1543
|
}
|
@@ -1410,7 +1552,7 @@ angular.module('ngAnimate', ['ng'])
|
|
1410
1552
|
var itemIndex = lookupCache[eventCacheKey] ? ++lookupCache[eventCacheKey].total : 0;
|
1411
1553
|
|
1412
1554
|
var stagger = {};
|
1413
|
-
if(itemIndex > 0) {
|
1555
|
+
if (itemIndex > 0) {
|
1414
1556
|
var staggerClassName = className + '-stagger';
|
1415
1557
|
var staggerCacheKey = cacheKey + ' ' + staggerClassName;
|
1416
1558
|
var applyClasses = !lookupCache[staggerCacheKey];
|
@@ -1429,7 +1571,7 @@ angular.module('ngAnimate', ['ng'])
|
|
1429
1571
|
var transitionDuration = timings.transitionDuration;
|
1430
1572
|
var animationDuration = timings.animationDuration;
|
1431
1573
|
|
1432
|
-
if(structural && transitionDuration === 0 && animationDuration === 0) {
|
1574
|
+
if (structural && transitionDuration === 0 && animationDuration === 0) {
|
1433
1575
|
element.removeClass(className);
|
1434
1576
|
return false;
|
1435
1577
|
}
|
@@ -1446,18 +1588,17 @@ angular.module('ngAnimate', ['ng'])
|
|
1446
1588
|
running : formerData.running || 0,
|
1447
1589
|
itemIndex : itemIndex,
|
1448
1590
|
blockTransition : blockTransition,
|
1449
|
-
blockAnimation : blockAnimation,
|
1450
1591
|
closeAnimationFns : closeAnimationFns
|
1451
1592
|
});
|
1452
1593
|
|
1453
1594
|
var node = extractElementNode(element);
|
1454
1595
|
|
1455
|
-
if(blockTransition) {
|
1456
|
-
node
|
1596
|
+
if (blockTransition) {
|
1597
|
+
blockTransitions(node, true);
|
1457
1598
|
}
|
1458
1599
|
|
1459
|
-
if(blockAnimation) {
|
1460
|
-
node
|
1600
|
+
if (blockAnimation) {
|
1601
|
+
blockAnimations(node, true);
|
1461
1602
|
}
|
1462
1603
|
|
1463
1604
|
return true;
|
@@ -1466,30 +1607,51 @@ angular.module('ngAnimate', ['ng'])
|
|
1466
1607
|
function animateRun(animationEvent, element, className, activeAnimationComplete) {
|
1467
1608
|
var node = extractElementNode(element);
|
1468
1609
|
var elementData = element.data(NG_ANIMATE_CSS_DATA_KEY);
|
1469
|
-
if(node.getAttribute('class').indexOf(className) == -1 || !elementData) {
|
1610
|
+
if (node.getAttribute('class').indexOf(className) == -1 || !elementData) {
|
1470
1611
|
activeAnimationComplete();
|
1471
1612
|
return;
|
1472
1613
|
}
|
1473
1614
|
|
1474
|
-
if(elementData.blockTransition) {
|
1475
|
-
node
|
1476
|
-
}
|
1477
|
-
|
1478
|
-
if(elementData.blockAnimation) {
|
1479
|
-
node.style[ANIMATION_PROP] = '';
|
1615
|
+
if (elementData.blockTransition) {
|
1616
|
+
blockTransitions(node, false);
|
1480
1617
|
}
|
1481
1618
|
|
1482
1619
|
var activeClassName = '';
|
1620
|
+
var pendingClassName = '';
|
1483
1621
|
forEach(className.split(' '), function(klass, i) {
|
1484
|
-
|
1622
|
+
var prefix = (i > 0 ? ' ' : '') + klass;
|
1623
|
+
activeClassName += prefix + '-active';
|
1624
|
+
pendingClassName += prefix + '-pending';
|
1485
1625
|
});
|
1486
1626
|
|
1487
|
-
|
1627
|
+
var style = '';
|
1628
|
+
var appliedStyles = [];
|
1629
|
+
var itemIndex = elementData.itemIndex;
|
1630
|
+
var stagger = elementData.stagger;
|
1631
|
+
var staggerTime = 0;
|
1632
|
+
if (itemIndex > 0) {
|
1633
|
+
var transitionStaggerDelay = 0;
|
1634
|
+
if (stagger.transitionDelay > 0 && stagger.transitionDuration === 0) {
|
1635
|
+
transitionStaggerDelay = stagger.transitionDelay * itemIndex;
|
1636
|
+
}
|
1637
|
+
|
1638
|
+
var animationStaggerDelay = 0;
|
1639
|
+
if (stagger.animationDelay > 0 && stagger.animationDuration === 0) {
|
1640
|
+
animationStaggerDelay = stagger.animationDelay * itemIndex;
|
1641
|
+
appliedStyles.push(CSS_PREFIX + 'animation-play-state');
|
1642
|
+
}
|
1643
|
+
|
1644
|
+
staggerTime = Math.round(Math.max(transitionStaggerDelay, animationStaggerDelay) * 100) / 100;
|
1645
|
+
}
|
1646
|
+
|
1647
|
+
if (!staggerTime) {
|
1648
|
+
element.addClass(activeClassName);
|
1649
|
+
}
|
1650
|
+
|
1488
1651
|
var eventCacheKey = elementData.cacheKey + ' ' + activeClassName;
|
1489
1652
|
var timings = getElementAnimationDetails(element, eventCacheKey);
|
1490
|
-
|
1491
1653
|
var maxDuration = Math.max(timings.transitionDuration, timings.animationDuration);
|
1492
|
-
if(maxDuration === 0) {
|
1654
|
+
if (maxDuration === 0) {
|
1493
1655
|
element.removeClass(activeClassName);
|
1494
1656
|
animateClose(element, className);
|
1495
1657
|
activeAnimationComplete();
|
@@ -1497,46 +1659,36 @@ angular.module('ngAnimate', ['ng'])
|
|
1497
1659
|
}
|
1498
1660
|
|
1499
1661
|
var maxDelay = Math.max(timings.transitionDelay, timings.animationDelay);
|
1500
|
-
var stagger = elementData.stagger;
|
1501
|
-
var itemIndex = elementData.itemIndex;
|
1502
1662
|
var maxDelayTime = maxDelay * ONE_SECOND;
|
1503
1663
|
|
1504
|
-
|
1505
|
-
if(timings.transitionDuration > 0) {
|
1506
|
-
var propertyStyle = timings.transitionPropertyStyle;
|
1507
|
-
if(propertyStyle.indexOf('all') == -1) {
|
1508
|
-
style += CSS_PREFIX + 'transition-property: ' + propertyStyle + ';';
|
1509
|
-
style += CSS_PREFIX + 'transition-duration: ' + timings.transitionDurationStyle + ';';
|
1510
|
-
appliedStyles.push(CSS_PREFIX + 'transition-property');
|
1511
|
-
appliedStyles.push(CSS_PREFIX + 'transition-duration');
|
1512
|
-
}
|
1513
|
-
}
|
1514
|
-
|
1515
|
-
if(itemIndex > 0) {
|
1516
|
-
if(stagger.transitionDelay > 0 && stagger.transitionDuration === 0) {
|
1517
|
-
var delayStyle = timings.transitionDelayStyle;
|
1518
|
-
style += CSS_PREFIX + 'transition-delay: ' +
|
1519
|
-
prepareStaggerDelay(delayStyle, stagger.transitionDelay, itemIndex) + '; ';
|
1520
|
-
appliedStyles.push(CSS_PREFIX + 'transition-delay');
|
1521
|
-
}
|
1522
|
-
|
1523
|
-
if(stagger.animationDelay > 0 && stagger.animationDuration === 0) {
|
1524
|
-
style += CSS_PREFIX + 'animation-delay: ' +
|
1525
|
-
prepareStaggerDelay(timings.animationDelayStyle, stagger.animationDelay, itemIndex) + '; ';
|
1526
|
-
appliedStyles.push(CSS_PREFIX + 'animation-delay');
|
1527
|
-
}
|
1528
|
-
}
|
1529
|
-
|
1530
|
-
if(appliedStyles.length > 0) {
|
1664
|
+
if (appliedStyles.length > 0) {
|
1531
1665
|
//the element being animated may sometimes contain comment nodes in
|
1532
1666
|
//the jqLite object, so we're safe to use a single variable to house
|
1533
1667
|
//the styles since there is always only one element being animated
|
1534
1668
|
var oldStyle = node.getAttribute('style') || '';
|
1535
|
-
|
1669
|
+
if (oldStyle.charAt(oldStyle.length-1) !== ';') {
|
1670
|
+
oldStyle += ';';
|
1671
|
+
}
|
1672
|
+
node.setAttribute('style', oldStyle + ' ' + style);
|
1536
1673
|
}
|
1537
1674
|
|
1538
1675
|
var startTime = Date.now();
|
1539
1676
|
var css3AnimationEvents = ANIMATIONEND_EVENT + ' ' + TRANSITIONEND_EVENT;
|
1677
|
+
var animationTime = (maxDelay + maxDuration) * CLOSING_TIME_BUFFER;
|
1678
|
+
var totalTime = (staggerTime + animationTime) * ONE_SECOND;
|
1679
|
+
|
1680
|
+
var staggerTimeout;
|
1681
|
+
if (staggerTime > 0) {
|
1682
|
+
element.addClass(pendingClassName);
|
1683
|
+
staggerTimeout = $timeout(function() {
|
1684
|
+
staggerTimeout = null;
|
1685
|
+
element.addClass(activeClassName);
|
1686
|
+
element.removeClass(pendingClassName);
|
1687
|
+
if (timings.animationDuration > 0) {
|
1688
|
+
blockAnimations(node, false);
|
1689
|
+
}
|
1690
|
+
}, staggerTime * ONE_SECOND, false);
|
1691
|
+
}
|
1540
1692
|
|
1541
1693
|
element.on(css3AnimationEvents, onAnimationProgress);
|
1542
1694
|
elementData.closeAnimationFns.push(function() {
|
@@ -1544,10 +1696,6 @@ angular.module('ngAnimate', ['ng'])
|
|
1544
1696
|
activeAnimationComplete();
|
1545
1697
|
});
|
1546
1698
|
|
1547
|
-
var staggerTime = itemIndex * (Math.max(stagger.animationDelay, stagger.transitionDelay) || 0);
|
1548
|
-
var animationTime = (maxDelay + maxDuration) * CLOSING_TIME_BUFFER;
|
1549
|
-
var totalTime = (staggerTime + animationTime) * ONE_SECOND;
|
1550
|
-
|
1551
1699
|
elementData.running++;
|
1552
1700
|
animationCloseHandler(element, totalTime);
|
1553
1701
|
return onEnd;
|
@@ -1558,6 +1706,10 @@ angular.module('ngAnimate', ['ng'])
|
|
1558
1706
|
function onEnd(cancelled) {
|
1559
1707
|
element.off(css3AnimationEvents, onAnimationProgress);
|
1560
1708
|
element.removeClass(activeClassName);
|
1709
|
+
element.removeClass(pendingClassName);
|
1710
|
+
if (staggerTimeout) {
|
1711
|
+
$timeout.cancel(staggerTimeout);
|
1712
|
+
}
|
1561
1713
|
animateClose(element, className);
|
1562
1714
|
var node = extractElementNode(element);
|
1563
1715
|
for (var i in appliedStyles) {
|
@@ -1581,23 +1733,22 @@ angular.module('ngAnimate', ['ng'])
|
|
1581
1733
|
* We're checking to see if the timeStamp surpasses the expected delay,
|
1582
1734
|
* but we're using elapsedTime instead of the timeStamp on the 2nd
|
1583
1735
|
* pre-condition since animations sometimes close off early */
|
1584
|
-
if(Math.max(timeStamp - startTime, 0) >= maxDelayTime && elapsedTime >= maxDuration) {
|
1736
|
+
if (Math.max(timeStamp - startTime, 0) >= maxDelayTime && elapsedTime >= maxDuration) {
|
1585
1737
|
activeAnimationComplete();
|
1586
1738
|
}
|
1587
1739
|
}
|
1588
1740
|
}
|
1589
1741
|
|
1590
|
-
function
|
1591
|
-
|
1592
|
-
|
1593
|
-
|
1594
|
-
|
1595
|
-
|
1596
|
-
return style;
|
1742
|
+
function blockTransitions(node, bool) {
|
1743
|
+
node.style[TRANSITION_PROP + PROPERTY_KEY] = bool ? 'none' : '';
|
1744
|
+
}
|
1745
|
+
|
1746
|
+
function blockAnimations(node, bool) {
|
1747
|
+
node.style[ANIMATION_PROP + ANIMATION_PLAYSTATE_KEY] = bool ? 'paused' : '';
|
1597
1748
|
}
|
1598
1749
|
|
1599
1750
|
function animateBefore(animationEvent, element, className, calculationDecorator) {
|
1600
|
-
if(animateSetup(animationEvent, element, className, calculationDecorator)) {
|
1751
|
+
if (animateSetup(animationEvent, element, className, calculationDecorator)) {
|
1601
1752
|
return function(cancelled) {
|
1602
1753
|
cancelled && animateClose(element, className);
|
1603
1754
|
};
|
@@ -1605,7 +1756,7 @@ angular.module('ngAnimate', ['ng'])
|
|
1605
1756
|
}
|
1606
1757
|
|
1607
1758
|
function animateAfter(animationEvent, element, className, afterAnimationComplete) {
|
1608
|
-
if(element.data(NG_ANIMATE_CSS_DATA_KEY)) {
|
1759
|
+
if (element.data(NG_ANIMATE_CSS_DATA_KEY)) {
|
1609
1760
|
return animateRun(animationEvent, element, className, afterAnimationComplete);
|
1610
1761
|
} else {
|
1611
1762
|
animateClose(element, className);
|
@@ -1618,7 +1769,7 @@ angular.module('ngAnimate', ['ng'])
|
|
1618
1769
|
//cancellation function then it means that there is no animation
|
1619
1770
|
//to perform at all
|
1620
1771
|
var preReflowCancellation = animateBefore(animationEvent, element, className);
|
1621
|
-
if(!preReflowCancellation) {
|
1772
|
+
if (!preReflowCancellation) {
|
1622
1773
|
animationComplete();
|
1623
1774
|
return;
|
1624
1775
|
}
|
@@ -1644,11 +1795,11 @@ angular.module('ngAnimate', ['ng'])
|
|
1644
1795
|
function animateClose(element, className) {
|
1645
1796
|
element.removeClass(className);
|
1646
1797
|
var data = element.data(NG_ANIMATE_CSS_DATA_KEY);
|
1647
|
-
if(data) {
|
1648
|
-
if(data.running) {
|
1798
|
+
if (data) {
|
1799
|
+
if (data.running) {
|
1649
1800
|
data.running--;
|
1650
1801
|
}
|
1651
|
-
if(!data.running || data.running === 0) {
|
1802
|
+
if (!data.running || data.running === 0) {
|
1652
1803
|
element.removeData(NG_ANIMATE_CSS_DATA_KEY);
|
1653
1804
|
}
|
1654
1805
|
}
|
@@ -1671,7 +1822,7 @@ angular.module('ngAnimate', ['ng'])
|
|
1671
1822
|
var className = suffixClasses(remove, '-remove') + ' ' +
|
1672
1823
|
suffixClasses(add, '-add');
|
1673
1824
|
var cancellationMethod = animateBefore('setClass', element, className);
|
1674
|
-
if(cancellationMethod) {
|
1825
|
+
if (cancellationMethod) {
|
1675
1826
|
afterReflow(element, animationCompleted);
|
1676
1827
|
return cancellationMethod;
|
1677
1828
|
}
|
@@ -1680,7 +1831,7 @@ angular.module('ngAnimate', ['ng'])
|
|
1680
1831
|
|
1681
1832
|
beforeAddClass : function(element, className, animationCompleted) {
|
1682
1833
|
var cancellationMethod = animateBefore('addClass', element, suffixClasses(className, '-add'));
|
1683
|
-
if(cancellationMethod) {
|
1834
|
+
if (cancellationMethod) {
|
1684
1835
|
afterReflow(element, animationCompleted);
|
1685
1836
|
return cancellationMethod;
|
1686
1837
|
}
|
@@ -1689,7 +1840,7 @@ angular.module('ngAnimate', ['ng'])
|
|
1689
1840
|
|
1690
1841
|
beforeRemoveClass : function(element, className, animationCompleted) {
|
1691
1842
|
var cancellationMethod = animateBefore('removeClass', element, suffixClasses(className, '-remove'));
|
1692
|
-
if(cancellationMethod) {
|
1843
|
+
if (cancellationMethod) {
|
1693
1844
|
afterReflow(element, animationCompleted);
|
1694
1845
|
return cancellationMethod;
|
1695
1846
|
}
|
@@ -1714,9 +1865,9 @@ angular.module('ngAnimate', ['ng'])
|
|
1714
1865
|
|
1715
1866
|
function suffixClasses(classes, suffix) {
|
1716
1867
|
var className = '';
|
1717
|
-
classes =
|
1868
|
+
classes = isArray(classes) ? classes : classes.split(/\s+/);
|
1718
1869
|
forEach(classes, function(klass, i) {
|
1719
|
-
if(klass && klass.length > 0) {
|
1870
|
+
if (klass && klass.length > 0) {
|
1720
1871
|
className += (i > 0 ? ' ' : '') + klass + suffix;
|
1721
1872
|
}
|
1722
1873
|
});
|