| Index: third_party/pkg/angular/lib/animate/css_animation.dart
|
| diff --git a/third_party/pkg/angular/lib/animate/css_animation.dart b/third_party/pkg/angular/lib/animate/css_animation.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..e236e541b1450fe9cacf863710aa4ba10b1f668b
|
| --- /dev/null
|
| +++ b/third_party/pkg/angular/lib/animate/css_animation.dart
|
| @@ -0,0 +1,132 @@
|
| +part of angular.animate;
|
| +
|
| +/**
|
| + * [Animation] implementation for handling the standard angular 'event' and
|
| + * 'event-active' class pattern with css. This will compute transition and
|
| + * animation duration from the css classes and use it to complete futures when
|
| + * the css animations complete.
|
| + */
|
| +class CssAnimation extends LoopedAnimation {
|
| + final CssAnimationMap _animationMap;
|
| + final AnimationOptimizer _optimizer;
|
| +
|
| + final dom.Element element;
|
| + final String addAtStart;
|
| + final String addAtEnd;
|
| + final String removeAtStart;
|
| + final String removeAtEnd;
|
| +
|
| + final String eventClass;
|
| + final String activeClass;
|
| +
|
| + final _completer = new Completer<AnimationResult>.sync();
|
| +
|
| + static const EXTRA_DURATION = 16.0; // Just a little extra time
|
| +
|
| + bool _active = true;
|
| + bool _started = false;
|
| + bool _isDisplayNone = false;
|
| +
|
| + Future<AnimationResult> get onCompleted => _completer.future;
|
| +
|
| + num _startTime;
|
| + num _duration;
|
| +
|
| + CssAnimation(
|
| + this.element,
|
| + this.eventClass,
|
| + this.activeClass,
|
| + { this.addAtStart,
|
| + this.removeAtStart,
|
| + this.addAtEnd,
|
| + this.removeAtEnd,
|
| + CssAnimationMap animationMap,
|
| + AnimationOptimizer optimizer })
|
| + : _animationMap = animationMap,
|
| + _optimizer = optimizer
|
| + {
|
| + if (_optimizer != null) _optimizer.track(this, element);
|
| + if (_animationMap != null) _animationMap.track(this);
|
| + element.classes.add(eventClass);
|
| + if (addAtStart != null) element.classes.add(addAtStart);
|
| + if (removeAtStart != null) element.classes.remove(removeAtStart);
|
| + }
|
| +
|
| + void read(num timeInMs) {
|
| + if (_active && _startTime == null) {
|
| + _startTime = timeInMs;
|
| + var style = element.getComputedStyle();
|
| + _isDisplayNone = style.display == "none";
|
| + _duration = util.computeLongestTransition(style);
|
| + if (_duration > 0.0) {
|
| + // Add a little extra time just to make sure transitions
|
| + // fully complete and that we don't remove the animation classes
|
| + // before it's completed.
|
| + _duration = _duration + EXTRA_DURATION;
|
| + }
|
| + }
|
| + }
|
| +
|
| + bool update(num timeInMs) {
|
| + if (!_active) return false;
|
| +
|
| + if (timeInMs >= _startTime + _duration) {
|
| + _complete(AnimationResult.COMPLETED);
|
| +
|
| + // TODO(codelogic): If the initial frame takes a significant amount of
|
| + // time, the computed duration + startTime might not actually represent
|
| + // the end of the animation
|
| + // Done with the animation
|
| + return false;
|
| + } else if (!_started) {
|
| + // This will always run after the first animationFrame is queued so that
|
| + // inserted elements have the base event class applied before adding the
|
| + // active class to the element. If this is not done, inserted dom nodes
|
| + // will not run their enter animation.
|
| +
|
| + if (_isDisplayNone && removeAtEnd != null) {
|
| + element.classes.remove(removeAtEnd);
|
| + }
|
| +
|
| + element.classes.add(activeClass);
|
| + _started = true;
|
| + }
|
| +
|
| + // Continue updating
|
| + return true;
|
| + }
|
| +
|
| + void cancel() {
|
| + if (_active) {
|
| + _detach();
|
| + if (addAtStart != null) element.classes.remove(addAtStart);
|
| + if (removeAtStart != null) element.classes.add(removeAtStart);
|
| + if (_completer != null) _completer.complete(AnimationResult.CANCELED);
|
| + }
|
| + }
|
| +
|
| + void complete() {
|
| + _complete(AnimationResult.COMPLETED_IGNORED);
|
| + }
|
| +
|
| + // Since there are two different ways to 'complete' an animation, this lets us
|
| + // configure the final result.
|
| + void _complete(AnimationResult result) {
|
| + if (_active) {
|
| + _detach();
|
| + if (addAtEnd != null) element.classes.add(addAtEnd);
|
| + if (removeAtEnd != null) element.classes.remove(removeAtEnd);
|
| + _completer.complete(result);
|
| + }
|
| + }
|
| +
|
| + // Cleanup css event classes.
|
| + void _detach() {
|
| + _active = false;
|
| +
|
| + if (_animationMap != null) _animationMap.forget(this);
|
| + if (_optimizer != null) _optimizer.forget(this);
|
| +
|
| + element.classes..remove(eventClass)..remove(activeClass);
|
| + }
|
| +}
|
|
|