diff --git a/demo/animate_demo/animate_demo.dart b/demo/animate_demo/animate_demo.dart index 7d68b78da..5b5e091b7 100644 --- a/demo/animate_demo/animate_demo.dart +++ b/demo/animate_demo/animate_demo.dart @@ -13,8 +13,7 @@ import 'dart:mirrors'; @NgController( selector: '[animation-demo]', - publishAs: 'adc' -) + publishAs: 'adc') class AnimationDemoController { final dom.Element rootElement; final NgAnimate animate; @@ -26,14 +25,14 @@ class AnimationDemoController { dom.Element _boxElement; dom.Element _hostElement; - List _animatedBoxes = []; - List listOfThings = []; - + final _animatedBoxes = []; + final listOfThings = []; + AnimationDemoController(this.animate, this.rootElement) { _boxElement = rootElement.querySelector(".animated-box"); _hostElement = rootElement.querySelector(".animated-host"); } - + animateABox() { if(_boxElement != null) { if(boxToggle) { @@ -50,8 +49,7 @@ class AnimationDemoController { if(!areThingsVisible && _animatedBoxes.length == 0) { for(int i = 0; i < 1000; i++) { - var element = new dom.Element.div(); - element.classes.add("magic-box"); + var element = new dom.Element.div()..classes.add("magic-box"); _animatedBoxes.add(element); } animate.insert(_animatedBoxes, _hostElement); @@ -65,21 +63,19 @@ class AnimationDemoController { areThingsVisible = !areThingsVisible; } } - + addThing() { listOfThings.add("Thing-$thingNumber"); thingNumber++; } - + removeThing() { - if(listOfThings.length > 0) { - listOfThings.removeLast(); - } + if (listOfThings.isNotEmpty) listOfThings.removeLast(); } } main() { ngBootstrap(module: new Module() - ..install(new NgAnimateModule()) - ..type(AnimationDemoController)); + ..install(new NgAnimateModule()) + ..type(AnimationDemoController)); } diff --git a/demo/animate_demo/index.html b/demo/animate_demo/index.html index 0c7d6c3e2..1f635607e 100644 --- a/demo/animate_demo/index.html +++ b/demo/animate_demo/index.html @@ -1,53 +1,51 @@ - Hello, World! - + Hello, World! + - -

ng-repeat Demo

- - -
    -
  • -
      -
    • - {{thing2}} -
    • -
    -
  • -
- - -

ng-switch Demo

- - - - -
-
I'm THING A
-
I'm THING B
-
I'm THING C
-
Uhhh I'm NoThing
-
- - -

ng-if Demo

- -
- I am a div with content. Just your standared ng-if. -
-
- -

Animate Demos

- -
- - -
- - - +

ng-repeat Demo

+ + +
    +
  • +
      +
    • + {{thing2}} +
    • +
    +
  • +
+ +

ng-switch Demo

+ + + + +
+
I'm THING A
+
I'm THING B
+
I'm THING C
+
Uhhh I'm NoThing
+
+ + +

ng-if Demo

+ +
+ I am a div with content. Just your standared ng-if. +
+
+ +

Animate Demos

+ +
+ + +
+ + + diff --git a/demo/animate_demo/style.css b/demo/animate_demo/style.css index 488f00c8b..05dfe538c 100644 --- a/demo/animate_demo/style.css +++ b/demo/animate_demo/style.css @@ -55,6 +55,12 @@ body { opacity: 0; } +button { + padding: 10px; + font-weight: bold; + font-size: 1.1em; +} + .some-div { height: 100px; opacity: 1; @@ -79,7 +85,7 @@ body { .some-div.ng-remove.ng-remove-active { opacity: 0; - height: 0px; + height: 0; } .animated-box { @@ -134,7 +140,7 @@ body { transform: scale(0.0, 0.0); -webkit-transform: scale(0.0,0.0); opacity: 0.0000001; /* Zero doesn't work???!!!! */ - /* Chrome bug filed: + /* Chrome bug filed: https://code.google.com/p/chromium/issues/detail?id=345894 */ transition: all 800ms linear; diff --git a/lib/animate/animation.dart b/lib/animate/animation.dart index 3647f0158..63b594106 100644 --- a/lib/animate/animation.dart +++ b/lib/animate/animation.dart @@ -12,8 +12,8 @@ class AnimationResult { /// A [CANCELED] animation should not procced with it's final effects. static const CANCELED = const AnimationResult._('CANCELED'); - - /// Convienence method if you don't care exactly how an animation completed + + /// Convenience method if you don't care exactly how an animation completed /// only that it did. bool get isCompleted => this == COMPLETED || this == COMPLETED_IGNORED; @@ -42,13 +42,13 @@ class AnimationResult { * * 4. read() - Every animation frame you may read computed state here. * - * 5. detatch() - After update returns false, detach will be executed and you + * 5. detach() - After update returns false, detach will be executed and you * should physically detach from the dom and execute onCompleted futures * so that external code that depends on your animation can do dom * mutates as well. - * + * * Additionally, interruptAndCancel() and interruptAndComplete are used to - * forcibly interupt an animation, and the implementation should immediatly + * forcibly interrupt an animation, and the implementation should immediately * detach from [element]. */ abstract class Animation { @@ -64,14 +64,14 @@ abstract class Animation { * Perform dom mutations to attach an initialize the animation on [element]. * The animation should not modify the [element] until this method is called. */ - attach() { } + void attach() { } /** * This performs DOM reads to compute information about the animation, and * will occur after attach. [time] is a date time representation of the * current time, and [offsetMs] is the time since the last animation frame. */ - start(num time) { } + void start(num time) { } /** * Occurs every animation frame. Return false to stop receiving animation @@ -89,22 +89,22 @@ abstract class Animation { * [time] is a [DateTime] representation of the current time * [offsetMs] is the time since the last animation frame. */ - read(num time) { } + void read(num time) { } /** * When [update] returns false, this will be called on the same animation * frame. Any temporary classes or element modifications should be removed * from the element and the onCompleted future should be executed. */ - detach(num time) { } + void detach(num time) { } /** - * This occurs when another animation interupts this animation or the cancel() - * method is called on the AnimationHandel. The animation should remove any - * temporary classes or element modifications and the onCompleted future - * should be executed with a result of [CANCELED]. + * This occurs when another animation interrupts this animation or the + * cancel() method is called on the AnimationHandel. The animation should + * remove any temporary classes or element modifications and the onCompleted + * future should be executed with a result of [CANCELED]. */ - interruptAndCancel() { } + void interruptAndCancel() { } /** * This occurs when the complete() method is called on the AnimationHandel. @@ -112,5 +112,5 @@ abstract class Animation { * finish any final permanent modifications and the onCompleted future * should be executed with a result of [COMPLETED]. */ - interruptAndComplete() { } + void interruptAndComplete() { } } \ No newline at end of file diff --git a/lib/animate/animation_handle.dart b/lib/animate/animation_handle.dart index 8d3c4c11a..92ff0d016 100644 --- a/lib/animate/animation_handle.dart +++ b/lib/animate/animation_handle.dart @@ -65,10 +65,10 @@ class _MultiAnimationHandle extends AnimationHandle { // animations were completed, COMPLETED_IGNORED will be returned. // if any animation was canceled, the result will be CANCELED var rtrn = AnimationResult.COMPLETED; - for(var result in results) { - if(result == AnimationResult.CANCELED) + for (var result in results) { + if (result == AnimationResult.CANCELED) return AnimationResult.CANCELED; - if(result == AnimationResult.COMPLETED_IGNORED) + if (result == AnimationResult.COMPLETED_IGNORED) rtrn = result; } return rtrn; @@ -77,14 +77,14 @@ class _MultiAnimationHandle extends AnimationHandle { /// For each of the tracked [AnimationHandle]s, call complete(). complete() { - for(var handle in _animationHandles) { + for (var handle in _animationHandles) { handle.complete(); } } /// For each of the tracked [AnimationHandle]s, call cancel(). cancel() { - for(var handle in _animationHandles) { + for (var handle in _animationHandles) { handle.cancel(); } } @@ -97,7 +97,7 @@ class _MultiAnimationHandle extends AnimationHandle { class _CompletedAnimationHandle extends AnimationHandle { Future _future; get onCompleted { - if(_future == null) { + if (_future == null) { var completer = new Completer(); completer.complete(AnimationResult.COMPLETED_IGNORED); _future = completer.future; diff --git a/lib/animate/animation_runner.dart b/lib/animate/animation_runner.dart index a1ce0a036..539c2c394 100644 --- a/lib/animate/animation_runner.dart +++ b/lib/animate/animation_runner.dart @@ -5,7 +5,7 @@ part of angular.animate; * * TODO(codelogic): Find a way to detect and rate-limit the number of concurrent * animations that are run at the same time. - * + * * TODO(codelogic): Shadow dom may prevents parent walks from * detecting parent animations. */ @@ -16,11 +16,11 @@ class AnimationRunner { // Active animations are stored so that the classes can later be removed // if an additional animation executes on the same element. - final BiMap _activeAnimations = new BiMap(); + final _activeAnimations = new BiMap(); - final List _attached = []; - final List _updating = []; - final List _completed = []; + final _attached = []; + final _updating = []; + final _completed = []; final Profiler _profiler; final NgZone _zone; @@ -34,17 +34,17 @@ class AnimationRunner { AnimationRunner(this._wnd, this._zone, [Profiler profiler]) : _profiler = _getProfiler(profiler); - // For some reason the turnary operator doesn't want to work with profiler. - static Profiler _getProfiler(Profiler value) { - if (value == null) return new Profiler(); - return value; + // For some reason the ternary operator doesn't want to work with profiler. + static Profiler _getProfiler(Profiler profiler) { + if (profiler == null) return new Profiler(); + return profiler; } /** * Start and play an animation through the state transitions defined in * [Animation]. */ - AnimationHandle play(Animation animation) { + AnimationHandle play(Animation animation) { _clearElement(animation.element); _activeAnimations[animation.element] = animation; @@ -53,12 +53,11 @@ class AnimationRunner { _queueAnimationFrame(); - var animationHandle = new _AnimationRunnerHandle(this, animation); - return animationHandle; + return new _AnimationRunnerHandle(this, animation); } - _queueAnimationFrame() { - if(!_animationFrameQueued) { + void _queueAnimationFrame() { + if (!_animationFrameQueued) { _animationFrameQueued = true; // TODO(codleogic): This should run outside of an angular scope digest. @@ -71,7 +70,7 @@ class AnimationRunner { /* On the browsers animation frame event, update animations and progress * through the animation state model: - * + * * 1. attach() - pre-animation frame. * 2. start(...) - frame 1 * 3. update(...) - frame 1+n @@ -79,13 +78,13 @@ class AnimationRunner { * 5. _repeat until update(...) returns false on frame m_ * 6. update(...) - frame m * 7. detach(...) - frame m - * + * * At any point any animation may be updated by calling interrupt and cancel * with a reference to the [Animation] to cancel. The [AnimationRunner] will * then forget about the [Animation] and will not call any further methods on * the [Animation]. */ - _animationFrame(num time) { + void _animationFrame(num time) { _profiler.startTimer("AnimationRunner.AnimationFrame"); _animationFrameQueued = false; @@ -95,7 +94,6 @@ class AnimationRunner { _detachCompleted(time); _profiler.stopTimer("AnimationRunner.AnimationFrame.DomMutates"); - _profiler.startTimer("AnimationRunner.AnimationFrame.DomReads"); // Dom reads _reads(time); @@ -105,17 +103,15 @@ class AnimationRunner { // We don't need to continue queuing animation frames // if there are no more animations to process. - if(_updating.length > 0) { - _queueAnimationFrame(); - } + if (_updating.isNotEmpty) _queueAnimationFrame(); _profiler.stopTimer("AnimationRunner.AnimationFrame"); } - _update(num timeMilliseconds) { - for(int i=0; i<_updating.length; i++) { + void _update(num timeMilliseconds) { + for (int i=0; i<_updating.length; i++) { var animation = _updating[i]; - if(!animation.update(timeMilliseconds)) { + if (!animation.update(timeMilliseconds)) { _completed.add(animation); _updating.removeAt(i); i--; @@ -123,37 +119,37 @@ class AnimationRunner { } } - _reads(num timeMilliseconds) { - for(var animation in _updating) { + void _reads(num timeMilliseconds) { + for (var animation in _updating) { animation.read(timeMilliseconds); } } - _detachCompleted(num timeMilliseconds) { - for(var animation in _completed) { + void _detachCompleted(num timeMilliseconds) { + for (var animation in _completed) { _activeAnimations.remove(animation.element); animation.detach(timeMilliseconds); } _completed.clear(); } - _startAttached(num timeMilliseconds) { - for(var animation in _attached) { + void _startAttached(num timeMilliseconds) { + for (var animation in _attached) { animation.start(timeMilliseconds); _updating.add(animation); } _attached.clear(); } - _clearElement(element) { - if(_activeAnimations.containsKey(element)) { + void _clearElement(element) { + if (_activeAnimations.containsKey(element)) { var animation = _activeAnimations[element]; _forget(animation); animation.interruptAndCancel(); } } - - _forget(Animation animation) { + + void _forget(Animation animation) { assert(animation != null); _attached.remove(animation); @@ -161,18 +157,18 @@ class AnimationRunner { _updating.remove(animation); _activeAnimations.remove(animation.element); } - + /** * This will return true if this [element] or any of the parent elements have * active animations applied to them and false if there is not. */ bool hasRunningParentAnimation(dom.Element element) { while(element != null) { - if(_activeAnimations.containsKey(element)) + if (_activeAnimations.containsKey(element)) return true; element = element.parent; } - + return false; } @@ -181,8 +177,8 @@ class AnimationRunner { * the animation from the list of active animations and any currently updating * animations, and call interruptAndCancel() on the [Animation] instance. */ - interruptAndCancel(Animation animation) { - if(_activeAnimations.containsValue(animation)) { + void interruptAndCancel(Animation animation) { + if (_activeAnimations.containsValue(animation)) { _forget(animation); animation.interruptAndCancel(); } @@ -193,8 +189,8 @@ class AnimationRunner { * the animation from the list of active animations and any currently updating * animations, and call interruptAndComplete() on the [Animation] instance. */ - interruptAndComplete(Animation animation) { - if(_activeAnimations.containsValue(animation)) { + void interruptAndComplete(Animation animation) { + if (_activeAnimations.containsValue(animation)) { _forget(animation); animation.interruptAndComplete(); } diff --git a/lib/animate/css_animate.dart b/lib/animate/css_animate.dart index 1d817d9bd..fea765e56 100644 --- a/lib/animate/css_animate.dart +++ b/lib/animate/css_animate.dart @@ -12,14 +12,14 @@ part of angular.animate; * in these cases. */ class CssAnimate extends NgAnimate { - static const String ngAnimateCssClass = "ng-animate"; - static const String ngMoveCssClass = "ng-move"; - static const String ngInsertCssClass = "ng-insert"; - static const String ngRemoveCssClass = "ng-remove"; + static const NG_ANIMATE_CSS_CLASS = "ng-animate"; + static const NG_MOVE_CSS_CLASS = "ng-move"; + static const NG_INSERT_CSS_CLASS = "ng-insert"; + static const NG_REMOVE_CSS_CLASS = "ng-remove"; - static const String ngAddPostfix = "add"; - static const String ngRemovePostfix = "remove"; - static const String ngActivePostfix = "active"; + static const NG_ADD_POSTFIX = "add"; + static const NG_REMOVE_POSTFIX = "remove"; + static const NG_ACTIVE_POSTFIX = "active"; AnimationRunner _animationRunner; NoAnimate _noAnimate; @@ -30,29 +30,32 @@ class CssAnimate extends NgAnimate { AnimationHandle addClass(Iterable nodes, String cssClass) { var elements = _partition(_elements(nodes)); - + var animateHandles = elements.animate.map((el) { - return _cssAnimation(el, "$cssClass-$ngAddPostfix", - cssClassToAdd: cssClass); + return _cssAnimation(el, "$cssClass-$NG_ADD_POSTFIX", + cssClassToAdd: cssClass); }); - - if(elements.noAnimate.length > 0) + + if (elements.noAnimate.isNotEmpty) { return _pickAnimationHandle(animateHandles, _noAnimate.addClass(elements.noAnimate, cssClass)); + } return _pickAnimationHandle(animateHandles); } AnimationHandle removeClass(Iterable nodes, String cssClass) { var elements = _partition(_elements(nodes)); - + var animateHandles = elements.animate.map((el) { - return _cssAnimation(el, "$cssClass-$ngRemovePostfix", + return _cssAnimation(el, "$cssClass-$NG_REMOVE_POSTFIX", cssClassToRemove: cssClass); }); - - if(elements.noAnimate.length > 0) + + if (elements.noAnimate.isNotEmpty) { return _pickAnimationHandle(animateHandles, _noAnimate.removeClass(elements.noAnimate, cssClass)); + } + return _pickAnimationHandle(animateHandles); } @@ -62,21 +65,17 @@ class CssAnimate extends NgAnimate { var animateHandles = _elements(nodes).where((el) { return !_animationRunner.hasRunningParentAnimation(el.parent); - }).map((el) { - return _cssAnimation(el, ngInsertCssClass); - }); + }).map((el) => _cssAnimation(el, NG_INSERT_CSS_CLASS)); return _pickAnimationHandle(animateHandles); } AnimationHandle remove(Iterable nodes) { var elements = _partition(_allNodesBetween(nodes)); - + var animateHandles = elements.animate.map((el) { - return _cssAnimation(el, ngRemoveCssClass)..onCompleted.then((result) { - if(result.isCompleted) { - el.remove(); - } + return _cssAnimation(el, NG_REMOVE_CSS_CLASS)..onCompleted.then((result) { + if (result.isCompleted) el.remove(); }); }); elements.noAnimate.forEach((el) => el.remove()); @@ -86,65 +85,60 @@ class CssAnimate extends NgAnimate { AnimationHandle move(Iterable nodes, dom.Node parent, { dom.Node insertBefore }) { _domMove(nodes, parent, insertBefore: insertBefore); - + var animateHandles = _elements(nodes).where((el) { return !_animationRunner.hasRunningParentAnimation(el.parent); }).map((el) { - return _cssAnimation(el, ngMoveCssClass); + return _cssAnimation(el, NG_MOVE_CSS_CLASS); }); return _pickAnimationHandle(animateHandles); } - AnimationHandle play(Iterable animations) { - // TODO(codelogic): Should we skip the running parent animation check for - // custom animations? - return _pickAnimationHandle(animations.map((a) - => _animationRunner.play(a))); - } + // TODO(codelogic): Should we skip the running parent animation check for + // custom animations? + AnimationHandle play(Iterable animations) => + _pickAnimationHandle(animations.map((a) => _animationRunner.play(a))); - AnimationHandle _cssAnimation(dom.Element element, - String cssEventClass, - { String cssClassToAdd, - String cssClassToRemove}) { + AnimationHandle _cssAnimation(dom.Element element, String cssEventClass, + { String cssClassToAdd, String cssClassToRemove}) { var animation = new CssAnimation( element, cssEventClass, - "$cssEventClass-$ngActivePostfix", + "$cssEventClass-$NG_ACTIVE_POSTFIX", addAtEnd: cssClassToAdd, removeAtEnd: cssClassToRemove, profiler: profiler); return _animationRunner.play(animation); } - + static AnimationHandle _pickAnimationHandle( Iterable animated, [AnimationHandle noAnimate]) { List handles; - - if(animated != null) + + if (animated != null) { handles = animated.toList(); - else if (noAnimate == null) + } else if (noAnimate == null) { return new _CompletedAnimationHandle(); - else + } else { return noAnimate; - - if(noAnimate != null) - handles.add(noAnimate); + } + + if (noAnimate != null) handles.add(noAnimate); - if(handles.length == 1) - return handles.first; + if (handles.length == 1) return handles.first; return new _MultiAnimationHandle(handles); } - + _RunnableAnimations _partition(Iterable nodes) { var runnable = new _RunnableAnimations(); nodes.forEach((el) { - if(el.nodeType != dom.Node.ELEMENT_NODE - || _animationRunner.hasRunningParentAnimation(el.parentNode)) { + if (el.nodeType != dom.Node.ELEMENT_NODE || + _animationRunner.hasRunningParentAnimation(el.parentNode)) { runnable.noAnimate.add(el); } else { runnable.animate.add(el); diff --git a/lib/animate/css_animation.dart b/lib/animate/css_animation.dart index 1c9ffbd7e..5b30dc1a1 100644 --- a/lib/animate/css_animation.dart +++ b/lib/animate/css_animation.dart @@ -16,7 +16,7 @@ class CssAnimation extends Animation { final String cssEventActiveClass; final Completer _completer= new Completer(); - + static const num extraDuration = 16.0; // Two extra 60fps frames of duration. AnimationResult _result; @@ -38,21 +38,22 @@ class CssAnimation extends Animation { this.removeAtEnd }) : super(targetElement); - attach() { + void attach() { // this happens right after creation time but before the first window // animation frame is called. element.classes.add(cssEventClass); } - start(num timeMs) { + void start(num timeMs) { // This occurs on the first animation frame. - // TODO(codelogic): It might be good to find some way of defering this to + // TODO(codelogic): It might be good to find some way of deferring this to // the next digest loop instead of the first animation frame. startTime = timeMs; try { // Duration needs to be in milliseconds duration = _computeTotalDuration() * 1000 + extraDuration; - } catch (e) { } + } catch (e) { + } } bool update(num timeMs) { @@ -60,14 +61,10 @@ class CssAnimation extends Animation { // 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(!_isActive && duration > 0.0 && timeMs >= startTime) { + if (!_isActive && duration > 0.0 && timeMs >= startTime) { element.classes.add(cssEventActiveClass); - if(addAtStart != null) { - element.classes.add(addAtStart); - } - if(removeAtStart != null) { - element.classes.remove(removeAtStart); - } + if (addAtStart != null) element.classes.add(addAtStart); + if (removeAtStart != null) element.classes.remove(removeAtStart); _isActive = true; } else if (timeMs >= startTime + duration) { // TODO(codelogic): If the initial frame takes a significant amount of @@ -81,19 +78,17 @@ class CssAnimation extends Animation { return true; } - detach(num timeMs) { - if (!_completer.isCompleted) { - _onComplete(AnimationResult.COMPLETED); - } + void detach(num timeMs) { + if (!_completer.isCompleted) _onComplete(AnimationResult.COMPLETED); } - interruptAndCancel() { + void interruptAndCancel() { if (!_completer.isCompleted) { _removeEventAnimationClasses(); - if(addAtStart != null) { + if (addAtStart != null) { element.classes.remove(addAtStart); - } - if(removeAtStart != null) { + } + if (removeAtStart != null) { element.classes.add(removeAtStart); } _result = AnimationResult.CANCELED; @@ -101,20 +96,18 @@ class CssAnimation extends Animation { } } - interruptAndComplete() { - if (!_completer.isCompleted) { - _onComplete(AnimationResult.COMPLETED_IGNORED); - } + void interruptAndComplete() { + if (!_completer.isCompleted) _onComplete(AnimationResult.COMPLETED_IGNORED); } // Since there are two different ways to 'complete' an animation: void _onComplete(AnimationResult result) { _removeEventAnimationClasses(); _result = result; - if(addAtEnd != null) { + if (addAtEnd != null) { element.classes.add(addAtEnd); - } - if(removeAtEnd != null) { + } + if (removeAtEnd != null) { element.classes.remove(removeAtEnd); } _completer.complete(_result); @@ -122,8 +115,9 @@ class CssAnimation extends Animation { // Cleanup css event classes. _removeEventAnimationClasses() { - element.classes.remove(cssEventClass); - element.classes.remove(cssEventActiveClass); + element.classes + ..remove(cssEventClass) + ..remove(cssEventActiveClass); } num _computeTotalDuration() { diff --git a/lib/animate/dom_tools.dart b/lib/animate/dom_tools.dart index 0f0406c92..7e15217ca 100644 --- a/lib/animate/dom_tools.dart +++ b/lib/animate/dom_tools.dart @@ -4,7 +4,7 @@ void _domRemove(List nodes) { // Not every element is sequential if the list of nodes only // includes the elements. Removing a block also includes // removing non-element nodes inbetween. - for(var j = 0, jj = nodes.length; j < jj; j++) { + for (var j = 0, jj = nodes.length; j < jj; j++) { dom.Node current = nodes[j]; dom.Node next = j+1 < jj ? nodes[j+1] : null; @@ -20,7 +20,7 @@ List _allNodesBetween(List nodes) { // Not every element is sequential if the list of nodes only // includes the elements. Removing a block also includes // removing non-element nodes inbetween. - for(var j = 0, jj = nodes.length; j < jj; j++) { + for (var j = 0, jj = nodes.length; j < jj; j++) { dom.Node current = nodes[j]; dom.Node next = j+1 < jj ? nodes[j+1] : null; @@ -41,55 +41,55 @@ void _domInsert(Iterable nodes, dom.Node parent, void _domMove(Iterable nodes, dom.Node parent, { dom.Node insertBefore }) { nodes.forEach((n) { - if(n.parentNode == null) n.remove(); + if (n.parentNode == null) n.remove(); parent.insertBefore(n, insertBefore); }); } num computeLongestTransition(dynamic style) { double longestTransition = 0.0; - - if(style.transitionDuration.length > 0) { + + if (style.transitionDuration.length > 0) { // Parse transitions List durations = _parseDurationList(style.transitionDuration) .toList(); List delays = _parseDurationList(style.transitionDelay) .toList(); - + assert(durations.length == delays.length); - - for(int i = 0; i < durations.length; i++) { + + for (int i = 0; i < durations.length; i++) { var total = _computeTotalDurationSeconds(delays[i], durations[i]); - if(total > longestTransition) + if (total > longestTransition) longestTransition = total; } } - - if(style.animationDuration.length > 0) { + + if (style.animationDuration.length > 0) { // Parse and add animation duration properties. - List animationDurations = + List animationDurations = _parseDurationList(style.animationDuration).toList(growable: false); // Note that animation iteration count only affects duration NOT delay. - List animationDelays = + List animationDelays = _parseDurationList(style.animationDelay).toList(growable: false); - + List iterationCounts = _parseIterationCounts( style.animationIterationCount).toList(growable: false); - + assert(animationDurations.length == animationDelays.length); - - for(int i = 0; i < animationDurations.length; i++) { + + for (int i = 0; i < animationDurations.length; i++) { var total = _computeTotalDurationSeconds( animationDelays[i], animationDurations[i], iterations: iterationCounts[i]); - if(total > longestTransition) + if (total > longestTransition) longestTransition = total; } } - + return longestTransition; } - + Iterable _parseIterationCounts(String iterationCounts) { return iterationCounts.split(", ") .map((x) => x == "infinite" ? -1 : num.parse(x)); @@ -115,6 +115,6 @@ num _computeTotalDurationSeconds(num delay, num duration, return 0.0; if (iterations < 0) // infinite iterations = 1; - + return (duration * iterations) + delay; } \ No newline at end of file diff --git a/lib/animate/no_animate.dart b/lib/animate/no_animate.dart index 0887f1b13..175e0b6d1 100644 --- a/lib/animate/no_animate.dart +++ b/lib/animate/no_animate.dart @@ -9,12 +9,12 @@ class NoAnimate extends NgAnimate { _elements(nodes).forEach((el) => el.classes.add(cssClass)); return new _CompletedAnimationHandle(); } - + AnimationHandle removeClass(Iterable nodes, String cssClass) { _elements(nodes).forEach((el) => el.classes.remove(cssClass)); return new _CompletedAnimationHandle(); } - + AnimationHandle insert(Iterable nodes, dom.Node parent, { dom.Node insertBefore } ) { _domInsert(nodes, parent, insertBefore: insertBefore); @@ -36,13 +36,12 @@ class NoAnimate extends NgAnimate { var handle = new _MultiAnimationHandle( animations.map((a) => new _CompletedAnimationHandle(future: a.onCompleted))); - + animations.forEach((a) => a.interruptAndComplete()); - + return handle; } } -Iterable _elements(Iterable nodes) { - return nodes.where((el) => el.nodeType == dom.Node.ELEMENT_NODE); -} \ No newline at end of file +Iterable _elements(Iterable nodes) => + nodes.where((el) => el.nodeType == dom.Node.ELEMENT_NODE); diff --git a/lib/core/zone.dart b/lib/core/zone.dart index 600b775aa..6d5eb3e39 100644 --- a/lib/core/zone.dart +++ b/lib/core/zone.dart @@ -144,7 +144,7 @@ class NgZone { * * Returns the return value of body. */ - run(body()) => _zone.run(body); + dynamic run(body()) => _zone.run(body); /** * Allows one to escape the auto-digest mechanism of Angular. @@ -160,13 +160,13 @@ class NgZone { * }); * } */ - runOutsideAngular(body()) => _outerZone.run(body); + dynamic runOutsideAngular(body()) => _outerZone.run(body); - assertInTurn() { + void assertInTurn() { assert(_runningInTurn > 0 || _inFinishTurn); } - assertInZone() { + void assertInZone() { assertInTurn(); } } diff --git a/test/animate/animation_runner_spec.dart b/test/animate/animation_runner_spec.dart index 13ff9912c..c819502a2 100644 --- a/test/animate/animation_runner_spec.dart +++ b/test/animate/animation_runner_spec.dart @@ -13,7 +13,7 @@ main() { wnd = new MockWindow(); runner = new AnimationRunner(wnd, zone); })); - + it('should play animations with window animation frames', async(() { _.compile('
'); var animation = new MockAnimation(_.rootElement); @@ -24,7 +24,7 @@ main() { .thenReturn(true, 2) .thenReturn(false); animation.when(callsTo('detach', anything)).alwaysReturn(null); - + runner.play(animation); animation.getLogs(callsTo('attach')).verify(happenedExactly(1)); @@ -43,19 +43,19 @@ main() { animation.getLogs(callsTo('update', anything)).verify(happenedExactly(0)); animation.getLogs(callsTo('detach', anything)).verify(happenedExactly(0)); animation.clearLogs(); - + wnd.executeAnimationFrame(); microLeap(); - + animation.getLogs(callsTo('attach')).verify(happenedExactly(0)); animation.getLogs(callsTo('start', anything)).verify(happenedExactly(0)); animation.getLogs(callsTo('read', anything)).verify(happenedExactly(1)); animation.getLogs(callsTo('update', anything)).verify(happenedExactly(1)); animation.getLogs(callsTo('detach', anything)).verify(happenedExactly(0)); animation.clearLogs(); - + wnd.executeAnimationFrame(); - microLeap(); + microLeap(); animation.getLogs(callsTo('attach')).verify(happenedExactly(0)); animation.getLogs(callsTo('start', anything)).verify(happenedExactly(0)); @@ -73,7 +73,7 @@ main() { animation.getLogs(callsTo('update', anything)).verify(happenedExactly(1)); animation.getLogs(callsTo('detach', anything)).verify(happenedExactly(1)); animation.clearLogs(); - + wnd.executeAnimationFrame(); microLeap(); @@ -83,40 +83,40 @@ main() { animation.getLogs(callsTo('update', anything)).verify(happenedExactly(0)); animation.getLogs(callsTo('detach', anything)).verify(happenedExactly(0)); animation.clearLogs(); - + expect(true).toBe(true); })); - + it('should interrupt existing animations', async(() { _.compile('
'); var animation = new MockAnimation(_.rootElement); animation.when(callsTo('attach')).alwaysReturn(null); - + runner.play(animation); var a2 = new MockAnimation(_.rootElement); animation.when(callsTo('attach')).alwaysReturn(null); - + runner.play(a2); - + animation.getLogs(callsTo('interruptAndCancel')).verify(happenedExactly(1)); a2.getLogs(callsTo('attach')).verify(happenedExactly(1)); })); - + it('should interrupt existing animations after attach', async(() { _.compile('
'); var animation = new MockAnimation(_.rootElement); animation.when(callsTo('attach')).alwaysReturn(null); animation.when(callsTo('start', anything)).alwaysReturn(null); animation.when(callsTo('update', anything)).alwaysReturn(true); - + runner.play(animation); var a2 = new MockAnimation(_.rootElement); a2.when(callsTo('attach')).alwaysReturn(null); a2.when(callsTo('start', anything)).alwaysReturn(null); a2.when(callsTo('update', anything)).alwaysReturn(true); - + runner.play(a2); wnd.executeAnimationFrame(); @@ -124,7 +124,7 @@ main() { wnd.executeAnimationFrame(); microLeap(); - + animation.getLogs(callsTo('attach')).verify(happenedExactly(1)); animation.getLogs(callsTo('start', anything)).verify(happenedExactly(0)); animation.getLogs(callsTo('read', anything)).verify(happenedExactly(0)); @@ -134,14 +134,14 @@ main() { animation.getLogs(callsTo('interruptAndComplete')).verify(happenedExactly(0)); animation.clearLogs(); })); - + it('should interrupt existing animations after start', async(() { _.compile('
'); var animation = new MockAnimation(_.rootElement); animation.when(callsTo('attach')).alwaysReturn(null); animation.when(callsTo('start', anything)).alwaysReturn(null); animation.when(callsTo('update', anything)).alwaysReturn(true); - + runner.play(animation); wnd.executeAnimationFrame(); @@ -151,7 +151,7 @@ main() { a2.when(callsTo('attach')).alwaysReturn(null); a2.when(callsTo('start', anything)).alwaysReturn(null); a2.when(callsTo('update', anything)).alwaysReturn(true); - + runner.play(a2); wnd.executeAnimationFrame(); @@ -159,7 +159,7 @@ main() { wnd.executeAnimationFrame(); microLeap(); - + animation.getLogs(callsTo('attach')).verify(happenedExactly(1)); animation.getLogs(callsTo('start', anything)).verify(happenedExactly(1)); animation.getLogs(callsTo('read', anything)).verify(happenedExactly(0)); @@ -169,20 +169,20 @@ main() { animation.getLogs(callsTo('interruptAndComplete')).verify(happenedExactly(0)); animation.clearLogs(); })); - - + + it('should interrupt existing animations after updating', async(() { _.compile('
'); var animation = new MockAnimation(_.rootElement); animation.when(callsTo('attach')).alwaysReturn(null); animation.when(callsTo('start', anything)).alwaysReturn(null); animation.when(callsTo('update', anything)).alwaysReturn(true); - + runner.play(animation); wnd.executeAnimationFrame(); microLeap(); - + wnd.executeAnimationFrame(); microLeap(); @@ -190,7 +190,7 @@ main() { a2.when(callsTo('attach')).alwaysReturn(null); a2.when(callsTo('start', anything)).alwaysReturn(null); a2.when(callsTo('update', anything)).alwaysReturn(true); - + runner.play(a2); wnd.executeAnimationFrame(); @@ -215,8 +215,8 @@ class MockAnimation extends Mock implements Animation { final Element element; final Completer onCompletedCompleter = new Completer(); Future get onCompleted => onCompletedCompleter.future; - + MockAnimation(this.element); - + noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); } \ No newline at end of file diff --git a/test/animate/css_animate_spec.dart b/test/animate/css_animate_spec.dart index fffbfae4a..d44acc9b3 100644 --- a/test/animate/css_animate_spec.dart +++ b/test/animate/css_animate_spec.dart @@ -1,4 +1,4 @@ -library css_animation_spec; +library css_animate_spec; import 'dart:async'; @@ -19,12 +19,12 @@ main() { it('should add a css class to an element node', async(() { _.compile('
'); expect(_.rootElement).not.toHaveClass('foo'); - + animate.addClass(_.rootElements, 'foo'); runner.doEverything(); expect(_.rootElement).toHaveClass('foo'); })); - + it('should remove a css class from an element node', async(() { _.compile('
'); expect(_.rootElement).toHaveClass('foo'); @@ -33,7 +33,7 @@ main() { runner.doEverything(); expect(_.rootElement).not.toHaveClass('foo'); })); - + it('should insert nodes', async(() { _.compile('
'); expect(_.rootElement.children.length).toBe(0); @@ -41,7 +41,7 @@ main() { animate.insert([new Element.div()], _.rootElement); expect(_.rootElement.children.length).toBe(1); })); - + it('should remove nodes', async(() { _.compile('

Hello World

'); expect(_.rootElement.childNodes.length).toBe(2); @@ -53,7 +53,7 @@ main() { microLeap(); expect(_.rootElement.childNodes.length).toBe(0); })); - + it('should move nodes', async(() { _.compile('
'); List a = $('Aa').toList(); @@ -65,17 +65,17 @@ main() { animate.move(b, _.rootElement, insertBefore: a.first); runner.doEverything(); expect(_.rootElement.text).toEqual("BbAa"); - + animate.move(a, _.rootElement, insertBefore: b.first); runner.doEverything(); expect(_.rootElement.text).toEqual("AaBb"); - + animate.move(a, _.rootElement); runner.doEverything(); expect(_.rootElement.text).toEqual("BbAa"); })); - + it('should animate multiple elements', async(() { _.compile('
'); List nodes = $('AaBb').toList(); @@ -84,7 +84,7 @@ main() { runner.doEverything(); expect(_.rootElement.text).toEqual("AaBb"); })); - + it('should prevent child animations', async(() { _.compile('
'); animate.addClass(_.rootElements, 'test'); @@ -95,16 +95,16 @@ main() { runner.start(); expect(spans.first).not.toHaveClass('ng-add'); })); - + it('should play any Animation', async(() { - var mockAnimation = new MockAnimation(); + var mockAnimation = new MockCssAnimation(); animate.play([mockAnimation, mockAnimation]); expect(runner.animation).toBe(mockAnimation); })); }); } -class MockAnimation extends Mock implements Animation { +class MockCssAnimation extends Mock implements Animation { noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); } @@ -112,35 +112,35 @@ class MockAnimationRunner extends Mock implements AnimationRunner { bool hasRunningParentAnimationValue = false; DateTime now = new DateTime.now(); Animation animation; - + AnimationHandle play(Animation animation) { this.animation = animation; animation.attach(); return new MockAnimationHandle(); } - + doEverything() { start(); update(); detach(); } - + start([num offset = 0]) { animation.start(offset); } - + update([num offset = 0]) { animation.update(offset); } - + read([num offset = 0]) { animation.read(offset); } - + detach([num offset = 0]) { animation.detach(offset); } - + bool hasRunningParentAnimation(Element element) { return hasRunningParentAnimationValue; } @@ -154,6 +154,6 @@ class MockAnimationHandle extends Mock implements AnimationHandle { cmp.complete(AnimationResult.COMPLETED); return cmp.future; } - + noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); } \ No newline at end of file diff --git a/test/animate/css_animation_spec.dart b/test/animate/css_animation_spec.dart index 839704406..61526ebcf 100644 --- a/test/animate/css_animation_spec.dart +++ b/test/animate/css_animation_spec.dart @@ -6,31 +6,31 @@ main() { describe('CssAnimation', () { TestBed _; beforeEach(inject((TestBed tb) => _ = tb)); - + it('should correctly respond to an animation lifecycle', async(() { _.compile("
"); var animation = new CssAnimation(_.rootElement, "event", "event-active"); expect(_.rootElement).not.toHaveClass('event'); expect(_.rootElement).not.toHaveClass('event-active'); - + animation.attach(); expect(_.rootElement).toHaveClass('event'); expect(_.rootElement).not.toHaveClass('event-active'); - + animation.start(0.0); expect(_.rootElement).toHaveClass('event'); expect(_.rootElement).not.toHaveClass('event-active'); - + animation.update(1000.0); expect(_.rootElement).toHaveClass('event'); expect(_.rootElement).toHaveClass('event-active'); - + animation.detach(1000.0); expect(_.rootElement).not.toHaveClass('event'); expect(_.rootElement).not.toHaveClass('event-active'); })); - + it('should add the cssClassToAdd', async(() { _.compile("
"); @@ -51,8 +51,8 @@ main() { expect(_.rootElement).not.toHaveClass('event'); expect(_.rootElement).not.toHaveClass('event-active'); })); - - + + it('should remove the cssClassToRemove', async(() { _.compile("
"); @@ -76,7 +76,7 @@ main() { expect(_.rootElement).not.toHaveClass('event'); expect(_.rootElement).not.toHaveClass('event-active'); })); - + it('should clean up event classes when canceled after attach', async(() { _.compile("
"); @@ -84,14 +84,14 @@ main() { addAtEnd: 'magic'); expect(_.rootElement).not.toHaveClass('event'); expect(_.rootElement).not.toHaveClass('event-active'); - + animation.attach(); animation.interruptAndCancel(); expect(_.rootElement).not.toHaveClass('magic'); expect(_.rootElement).not.toHaveClass('event'); expect(_.rootElement).not.toHaveClass('event-active'); })); - + it('should clean up event classes when canceled after start', async(() { _.compile("
"); @@ -99,7 +99,7 @@ main() { addAtEnd: 'magic'); expect(_.rootElement).not.toHaveClass('event'); expect(_.rootElement).not.toHaveClass('event-active'); - + animation.attach(); animation.start(0.0); @@ -108,7 +108,7 @@ main() { expect(_.rootElement).not.toHaveClass('event'); expect(_.rootElement).not.toHaveClass('event-active'); })); - + it('should clean up event classes when canceled after update', async(() { _.compile("
"); @@ -116,7 +116,7 @@ main() { addAtEnd: 'magic'); expect(_.rootElement).not.toHaveClass('event'); expect(_.rootElement).not.toHaveClass('event-active'); - + animation.attach(); animation.start(0.0); animation.update(0.0); @@ -126,8 +126,8 @@ main() { expect(_.rootElement).not.toHaveClass('event'); expect(_.rootElement).not.toHaveClass('event-active'); })); - - + + it('should clean up event classes when forcibly completed after attach', async(() { _.compile("
"); @@ -135,14 +135,14 @@ main() { addAtEnd: 'magic'); expect(_.rootElement).not.toHaveClass('event'); expect(_.rootElement).not.toHaveClass('event-active'); - + animation.attach(); animation.interruptAndComplete(); expect(_.rootElement).toHaveClass('magic'); expect(_.rootElement).not.toHaveClass('event'); expect(_.rootElement).not.toHaveClass('event-active'); })); - + it('should clean up event classes when forcibly completed after start', async(() { _.compile("
"); @@ -150,7 +150,7 @@ main() { addAtEnd: 'magic'); expect(_.rootElement).not.toHaveClass('event'); expect(_.rootElement).not.toHaveClass('event-active'); - + animation.attach(); animation.start(0.0); @@ -159,7 +159,7 @@ main() { expect(_.rootElement).not.toHaveClass('event'); expect(_.rootElement).not.toHaveClass('event-active'); })); - + it('should clean up event classes when forcibly completed after update', async(() { _.compile("
"); @@ -167,7 +167,7 @@ main() { addAtEnd: 'magic'); expect(_.rootElement).not.toHaveClass('event'); expect(_.rootElement).not.toHaveClass('event-active'); - + animation.attach(); animation.start(0.0); animation.update(0.0); diff --git a/test/animate/no_animate_spec.dart b/test/animate/no_animate_spec.dart index 995722e0b..1c1558f13 100644 --- a/test/animate/no_animate_spec.dart +++ b/test/animate/no_animate_spec.dart @@ -6,7 +6,7 @@ main() { describe('NoAniamte', () { TestBed _; beforeEach(inject((TestBed tb) => _ = tb)); - + it('should exist', inject((NgAnimate aniamte) { expect(aniamte).toBeDefined(); @@ -19,7 +19,7 @@ main() { animate.addClass(_.rootElements, 'foo'); expect(_.rootElement).toHaveClass('foo'); }); - + it('should remove css classes from nodes.', () { var animate = new NoAnimate(); _.compile('
'); @@ -27,7 +27,7 @@ main() { animate.removeClass(_.rootElements, 'foo'); expect(_.rootElement).not.toHaveClass('foo'); }); - + it('should insert elements', () { var animate = new NoAnimate(); _.compile('
'); @@ -35,7 +35,7 @@ main() { animate.insert([new Element.div()], _.rootElement); expect(_.rootElement.children.length).toBe(1); }); - + it('should remove nodes and elements', () { var animate = new NoAnimate(); _.compile('

Hello World

'); @@ -43,7 +43,7 @@ main() { animate.remove(_.rootElement.childNodes); expect(_.rootElement.childNodes.length).toBe(0); }); - + it('should move nodes and elements', () { var animate = new NoAnimate(); _.compile('
'); @@ -51,15 +51,15 @@ main() { List b = $('Bb').toList(); a.forEach((n) => _.rootElement.append(n)); b.forEach((n) => _.rootElement.append(n)); - + expect(_.rootElement.text).toEqual("AaBb"); animate.move(b, _.rootElement, insertBefore: a.first); expect(_.rootElement.text).toEqual("BbAa"); - + animate.move(a, _.rootElement, insertBefore: b.first); expect(_.rootElement.text).toEqual("AaBb"); - + animate.move(a, _.rootElement); expect(_.rootElement.text).toEqual("BbAa"); });