| Index: third_party/pkg/angular/lib/animate/css_animate.dart
|
| diff --git a/third_party/pkg/angular/lib/animate/css_animate.dart b/third_party/pkg/angular/lib/animate/css_animate.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..db5bebaee7e0a72281dc5f106d2e3c99d834c914
|
| --- /dev/null
|
| +++ b/third_party/pkg/angular/lib/animate/css_animate.dart
|
| @@ -0,0 +1,156 @@
|
| +part of angular.animate;
|
| +
|
| +/**
|
| + * This defines the standard set of CSS animation classes, transitions, and
|
| + * nomenclature that will eventually be the foundation of the AngularDart
|
| + * animation framework. This implementation uses the [AnimationLoop] class to
|
| + * queue and run CSS based transition and keyframe animations.
|
| + */
|
| +@Injectable()
|
| +class CssAnimate implements Animate {
|
| + static const NG_ANIMATE = "ng-animate";
|
| + static const NG_MOVE = "ng-move";
|
| + static const NG_INSERT = "ng-enter";
|
| + static const NG_REMOVE = "ng-leave";
|
| +
|
| + static const NG_ADD_POSTFIX = "-add";
|
| + static const NG_REMOVE_POSTFIX = "-remove";
|
| + static const NG_ACTIVE_POSTFIX = "-active";
|
| +
|
| + final NoOpAnimation _noOp = new NoOpAnimation();
|
| +
|
| + final AnimationLoop _runner;
|
| + final AnimationOptimizer _optimizer;
|
| + final CssAnimationMap _animationMap;
|
| +
|
| + CssAnimate(this._runner, this._animationMap, this._optimizer);
|
| +
|
| + Animation addClass(dom.Element element, String cssClass) {
|
| + if (!_optimizer.shouldAnimate(element)) {
|
| + element.classes.add(cssClass);
|
| + return _noOp;
|
| + }
|
| +
|
| + cancelAnimation(element, "$cssClass$NG_REMOVE_POSTFIX");
|
| + var event = "$cssClass$NG_ADD_POSTFIX";
|
| + return animate(element, event, addAtEnd: cssClass);
|
| + }
|
| +
|
| + Animation removeClass(dom.Element element, String cssClass) {
|
| + if (!_optimizer.shouldAnimate(element)) {
|
| + element.classes.remove(cssClass);
|
| + return _noOp;
|
| + }
|
| +
|
| + cancelAnimation(element, "$cssClass$NG_ADD_POSTFIX");
|
| +
|
| + var event = "$cssClass$NG_REMOVE_POSTFIX";
|
| + return animate(element, event, removeAtEnd: cssClass);
|
| + }
|
| +
|
| + Animation insert(Iterable<dom.Node> nodes, dom.Node parent,
|
| + { dom.Node insertBefore }) {
|
| + util.domInsert(nodes, parent, insertBefore: insertBefore);
|
| +
|
| + var animations = util.getElements(nodes)
|
| + .where((el) =>_optimizer.shouldAnimate(el))
|
| + .map((el) => animate(el, NG_INSERT));
|
| +
|
| + return _animationFromList(animations);
|
| + }
|
| +
|
| + Animation remove(Iterable<dom.Node> nodes) {
|
| + var animations = nodes.map((node) {
|
| + if (node.nodeType == dom.Node.ELEMENT_NODE &&
|
| + _optimizer.shouldAnimate(node)) {
|
| + return animate(node, NG_REMOVE);
|
| + }
|
| + return _noOp;
|
| + });
|
| +
|
| + var result = _animationFromList(animations)..onCompleted.then((result) {
|
| + if (result.isCompleted) nodes.toList().forEach((n) => n.remove());
|
| + });
|
| +
|
| + return result;
|
| + }
|
| +
|
| + Animation move(Iterable<dom.Node> nodes, dom.Node parent,
|
| + { dom.Node insertBefore }) {
|
| + util.domMove(nodes, parent, insertBefore: insertBefore);
|
| +
|
| + var animations = util.getElements(nodes)
|
| + .where((el) => _optimizer.shouldAnimate(el))
|
| + .map((el) => animate(el, NG_MOVE));
|
| +
|
| + return _animationFromList(animations);
|
| + }
|
| +
|
| + /**
|
| + * Run a css animation on a element for a given css class. If the css
|
| + * animation already exists, the method will attempt to return the existing
|
| + * instance.
|
| + */
|
| + CssAnimation animate(
|
| + dom.Element element,
|
| + String event,
|
| + { String addAtStart,
|
| + String addAtEnd,
|
| + String removeAtStart,
|
| + String removeAtEnd }) {
|
| +
|
| + var _existing = _animationMap.findExisting(element, event);
|
| + if (_existing != null) return _existing;
|
| +
|
| + var animation = new CssAnimation(
|
| + element,
|
| + event,
|
| + "$event$NG_ACTIVE_POSTFIX",
|
| + addAtStart: addAtStart,
|
| + addAtEnd: addAtEnd,
|
| + removeAtStart: removeAtStart,
|
| + removeAtEnd: removeAtEnd,
|
| + animationMap: _animationMap,
|
| + optimizer: _optimizer);
|
| +
|
| + _runner.play(animation);
|
| + return animation;
|
| + }
|
| +
|
| + /**
|
| + * For a given element and css event, attempt to find an existing instance
|
| + * of the given animation and cancel it.
|
| + */
|
| + void cancelAnimation(dom.Element element, String event) {
|
| + var existing = _animationMap.findExisting(element, event);
|
| +
|
| + if (existing != null) existing.cancel();
|
| + }
|
| +}
|
| +
|
| +/**
|
| + * Tracked set of currently running css animations grouped by element.
|
| + */
|
| +@Injectable()
|
| +class CssAnimationMap {
|
| + final Map<dom.Element, Map<String, CssAnimation>> cssAnimations
|
| + = new Map<dom.Element, Map<String, CssAnimation>>();
|
| +
|
| + void track(CssAnimation animation) {
|
| + var animations = cssAnimations.putIfAbsent(animation.element,
|
| + () => <String, CssAnimation>{});
|
| + animations[animation.eventClass] = animation;
|
| + }
|
| +
|
| + void forget(CssAnimation animation) {
|
| + var animations = cssAnimations[animation.element];
|
| + animations.remove(animation.eventClass);
|
| + if (animations.length == 0) cssAnimations.remove(animation.element);
|
| + }
|
| +
|
| + CssAnimation findExisting(dom.Element element, String event) {
|
| + var animations = cssAnimations[element];
|
| + if (animations == null) return null;
|
| + return animations[event];
|
| + }
|
| +}
|
|
|