refactor(animations): ensure animation data-structures are created only when used
Closes #12250
This commit is contained in:
parent
606e51881a
commit
33c8948fd3
|
@ -32,6 +32,7 @@ export class AnimationCompiler {
|
||||||
var _ANIMATION_FACTORY_ELEMENT_VAR = o.variable('element');
|
var _ANIMATION_FACTORY_ELEMENT_VAR = o.variable('element');
|
||||||
var _ANIMATION_DEFAULT_STATE_VAR = o.variable('defaultStateStyles');
|
var _ANIMATION_DEFAULT_STATE_VAR = o.variable('defaultStateStyles');
|
||||||
var _ANIMATION_FACTORY_VIEW_VAR = o.variable('view');
|
var _ANIMATION_FACTORY_VIEW_VAR = o.variable('view');
|
||||||
|
var _ANIMATION_FACTORY_VIEW_CONTEXT = _ANIMATION_FACTORY_VIEW_VAR.prop('animationContext');
|
||||||
var _ANIMATION_FACTORY_RENDERER_VAR = _ANIMATION_FACTORY_VIEW_VAR.prop('renderer');
|
var _ANIMATION_FACTORY_RENDERER_VAR = _ANIMATION_FACTORY_VIEW_VAR.prop('renderer');
|
||||||
var _ANIMATION_CURRENT_STATE_VAR = o.variable('currentState');
|
var _ANIMATION_CURRENT_STATE_VAR = o.variable('currentState');
|
||||||
var _ANIMATION_NEXT_STATE_VAR = o.variable('nextState');
|
var _ANIMATION_NEXT_STATE_VAR = o.variable('nextState');
|
||||||
|
@ -186,7 +187,7 @@ class _AnimationBuilder implements AnimationAstVisitor {
|
||||||
context.stateMap.registerState(DEFAULT_STATE, {});
|
context.stateMap.registerState(DEFAULT_STATE, {});
|
||||||
|
|
||||||
var statements: o.Statement[] = [];
|
var statements: o.Statement[] = [];
|
||||||
statements.push(_ANIMATION_FACTORY_VIEW_VAR
|
statements.push(_ANIMATION_FACTORY_VIEW_CONTEXT
|
||||||
.callMethod(
|
.callMethod(
|
||||||
'cancelActiveAnimation',
|
'cancelActiveAnimation',
|
||||||
[
|
[
|
||||||
|
@ -263,13 +264,20 @@ class _AnimationBuilder implements AnimationAstVisitor {
|
||||||
.toStmt()])])
|
.toStmt()])])
|
||||||
.toStmt());
|
.toStmt());
|
||||||
|
|
||||||
statements.push(_ANIMATION_FACTORY_VIEW_VAR
|
var transitionParams = o.literalMap([
|
||||||
|
['toState', _ANIMATION_NEXT_STATE_VAR], ['fromState', _ANIMATION_CURRENT_STATE_VAR],
|
||||||
|
['totalTime', _ANIMATION_TIME_VAR]
|
||||||
|
]);
|
||||||
|
|
||||||
|
var transitionEvent = o.importExpr(resolveIdentifier(Identifiers.AnimationTransitionEvent))
|
||||||
|
.instantiate([transitionParams]);
|
||||||
|
|
||||||
|
statements.push(_ANIMATION_FACTORY_VIEW_CONTEXT
|
||||||
.callMethod(
|
.callMethod(
|
||||||
'queueAnimation',
|
'queueAnimation',
|
||||||
[
|
[
|
||||||
_ANIMATION_FACTORY_ELEMENT_VAR, o.literal(this.animationName),
|
_ANIMATION_FACTORY_ELEMENT_VAR, o.literal(this.animationName),
|
||||||
_ANIMATION_PLAYER_VAR, _ANIMATION_TIME_VAR,
|
_ANIMATION_PLAYER_VAR, transitionEvent
|
||||||
_ANIMATION_CURRENT_STATE_VAR, _ANIMATION_NEXT_STATE_VAR
|
|
||||||
])
|
])
|
||||||
.toStmt());
|
.toStmt());
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {ANALYZE_FOR_ENTRY_COMPONENTS, ChangeDetectionStrategy, ChangeDetectorRef, ComponentFactory, ComponentFactoryResolver, ElementRef, Injector, LOCALE_ID as LOCALE_ID_, NgModuleFactory, QueryList, RenderComponentType, Renderer, SecurityContext, SimpleChange, TRANSLATIONS_FORMAT as TRANSLATIONS_FORMAT_, TemplateRef, ViewContainerRef, ViewEncapsulation} from '@angular/core';
|
import {ANALYZE_FOR_ENTRY_COMPONENTS, AnimationTransitionEvent, ChangeDetectionStrategy, ChangeDetectorRef, ComponentFactory, ComponentFactoryResolver, ElementRef, Injector, LOCALE_ID as LOCALE_ID_, NgModuleFactory, QueryList, RenderComponentType, Renderer, SecurityContext, SimpleChange, TRANSLATIONS_FORMAT as TRANSLATIONS_FORMAT_, TemplateRef, ViewContainerRef, ViewEncapsulation} from '@angular/core';
|
||||||
|
|
||||||
import {CompileIdentifierMetadata, CompileTokenMetadata} from './compile_metadata';
|
import {CompileIdentifierMetadata, CompileTokenMetadata} from './compile_metadata';
|
||||||
import {AnimationGroupPlayer, AnimationKeyframe, AnimationSequencePlayer, AnimationStyles, AppElement, AppView, ChangeDetectorStatus, CodegenComponentFactoryResolver, DebugAppView, DebugContext, EMPTY_ARRAY, EMPTY_MAP, NgModuleInjector, NoOpAnimationPlayer, StaticNodeDebugInfo, TemplateRef_, UNINITIALIZED, ValueUnwrapper, ViewType, ViewUtils, balanceAnimationKeyframes, castByValue, checkBinding, clearStyles, collectAndResolveStyles, devModeEqual, flattenNestedViewRenderNodes, interpolate, prepareFinalAnimationStyles, pureProxy1, pureProxy10, pureProxy2, pureProxy3, pureProxy4, pureProxy5, pureProxy6, pureProxy7, pureProxy8, pureProxy9, reflector, registerModuleFactory, renderStyles} from './private_import_core';
|
import {AnimationGroupPlayer, AnimationKeyframe, AnimationSequencePlayer, AnimationStyles, AppElement, AppView, ChangeDetectorStatus, CodegenComponentFactoryResolver, DebugAppView, DebugContext, EMPTY_ARRAY, EMPTY_MAP, NgModuleInjector, NoOpAnimationPlayer, StaticNodeDebugInfo, TemplateRef_, UNINITIALIZED, ValueUnwrapper, ViewType, ViewUtils, balanceAnimationKeyframes, castByValue, checkBinding, clearStyles, collectAndResolveStyles, devModeEqual, flattenNestedViewRenderNodes, interpolate, prepareFinalAnimationStyles, pureProxy1, pureProxy10, pureProxy2, pureProxy3, pureProxy4, pureProxy5, pureProxy6, pureProxy7, pureProxy8, pureProxy9, reflector, registerModuleFactory, renderStyles} from './private_import_core';
|
||||||
|
@ -266,6 +266,11 @@ export class Identifiers {
|
||||||
moduleUrl: assetUrl('core', 'i18n/tokens'),
|
moduleUrl: assetUrl('core', 'i18n/tokens'),
|
||||||
runtime: TRANSLATIONS_FORMAT_
|
runtime: TRANSLATIONS_FORMAT_
|
||||||
};
|
};
|
||||||
|
static AnimationTransitionEvent: IdentifierSpec = {
|
||||||
|
name: 'AnimationTransitionEvent',
|
||||||
|
moduleUrl: assetUrl('core', 'animation/animation_transition_event'),
|
||||||
|
runtime: AnimationTransitionEvent
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function resolveIdentifier(identifier: IdentifierSpec) {
|
export function resolveIdentifier(identifier: IdentifierSpec) {
|
||||||
|
|
|
@ -119,9 +119,9 @@ export class CompileEventListener {
|
||||||
[o.THIS_EXPR.prop(this._methodName).callMethod(o.BuiltinMethod.Bind, [o.THIS_EXPR])]);
|
[o.THIS_EXPR.prop(this._methodName).callMethod(o.BuiltinMethod.Bind, [o.THIS_EXPR])]);
|
||||||
|
|
||||||
// tie the property callback method to the view animations map
|
// tie the property callback method to the view animations map
|
||||||
var stmt = o.THIS_EXPR
|
var stmt = o.THIS_EXPR.prop('animationContext')
|
||||||
.callMethod(
|
.callMethod(
|
||||||
'registerAnimationOutput',
|
'registerOutputHandler',
|
||||||
[
|
[
|
||||||
this.compileElement.renderNode, o.literal(this.eventName),
|
this.compileElement.renderNode, o.literal(this.eventName),
|
||||||
o.literal(this.eventPhase), outputListener
|
o.literal(this.eventPhase), outputListener
|
||||||
|
|
|
@ -15,8 +15,6 @@ export class ViewAnimationMap {
|
||||||
private _map = new Map<any, {[key: string]: AnimationPlayer}>();
|
private _map = new Map<any, {[key: string]: AnimationPlayer}>();
|
||||||
private _allPlayers: AnimationPlayer[] = [];
|
private _allPlayers: AnimationPlayer[] = [];
|
||||||
|
|
||||||
get length(): number { return this.getAllPlayers().length; }
|
|
||||||
|
|
||||||
find(element: any, animationName: string): AnimationPlayer {
|
find(element: any, animationName: string): AnimationPlayer {
|
||||||
var playersByAnimation = this._map.get(element);
|
var playersByAnimation = this._map.get(element);
|
||||||
if (isPresent(playersByAnimation)) {
|
if (isPresent(playersByAnimation)) {
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright Google Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by an MIT-style license that can be
|
||||||
|
* found in the LICENSE file at https://angular.io/license
|
||||||
|
*/
|
||||||
|
import {AnimationGroupPlayer} from '../animation/animation_group_player';
|
||||||
|
import {AnimationPlayer} from '../animation/animation_player';
|
||||||
|
import {queueAnimation as queueAnimationGlobally} from '../animation/animation_queue';
|
||||||
|
import {AnimationTransitionEvent} from '../animation/animation_transition_event';
|
||||||
|
import {ViewAnimationMap} from '../animation/view_animation_map';
|
||||||
|
|
||||||
|
export class AnimationViewContext {
|
||||||
|
private _players = new ViewAnimationMap();
|
||||||
|
private _listeners = new Map<any, _AnimationOutputHandler[]>();
|
||||||
|
|
||||||
|
onAllActiveAnimationsDone(callback: () => any): void {
|
||||||
|
var activeAnimationPlayers = this._players.getAllPlayers();
|
||||||
|
// we check for the length to avoid having GroupAnimationPlayer
|
||||||
|
// issue an unnecessary microtask when zero players are passed in
|
||||||
|
if (activeAnimationPlayers.length) {
|
||||||
|
new AnimationGroupPlayer(activeAnimationPlayers).onDone(() => callback());
|
||||||
|
} else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
queueAnimation(
|
||||||
|
element: any, animationName: string, player: AnimationPlayer,
|
||||||
|
event: AnimationTransitionEvent): void {
|
||||||
|
queueAnimationGlobally(player);
|
||||||
|
|
||||||
|
this._players.set(element, animationName, player);
|
||||||
|
player.onDone(() => {
|
||||||
|
// TODO: add codegen to remove the need to store these values
|
||||||
|
this._triggerOutputHandler(element, animationName, 'done', event);
|
||||||
|
this._players.remove(element, animationName);
|
||||||
|
});
|
||||||
|
|
||||||
|
player.onStart(() => this._triggerOutputHandler(element, animationName, 'start', event));
|
||||||
|
}
|
||||||
|
|
||||||
|
cancelActiveAnimation(element: any, animationName: string, removeAllAnimations: boolean = false):
|
||||||
|
void {
|
||||||
|
if (removeAllAnimations) {
|
||||||
|
this._players.findAllPlayersByElement(element).forEach(player => player.destroy());
|
||||||
|
} else {
|
||||||
|
var player = this._players.find(element, animationName);
|
||||||
|
if (player) {
|
||||||
|
player.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
registerOutputHandler(
|
||||||
|
element: any, eventName: string, eventPhase: string, eventHandler: Function): void {
|
||||||
|
var animations = this._listeners.get(element);
|
||||||
|
if (!animations) {
|
||||||
|
this._listeners.set(element, animations = []);
|
||||||
|
}
|
||||||
|
animations.push(new _AnimationOutputHandler(eventName, eventPhase, eventHandler));
|
||||||
|
}
|
||||||
|
|
||||||
|
private _triggerOutputHandler(
|
||||||
|
element: any, animationName: string, phase: string, event: AnimationTransitionEvent): void {
|
||||||
|
const listeners = this._listeners.get(element);
|
||||||
|
if (listeners && listeners.length) {
|
||||||
|
for (let i = 0; i < listeners.length; i++) {
|
||||||
|
let listener = listeners[i];
|
||||||
|
// we check for both the name in addition to the phase in the event
|
||||||
|
// that there may be more than one @trigger on the same element
|
||||||
|
if (listener.eventName === animationName && listener.eventPhase === phase) {
|
||||||
|
listener.handler(event);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AnimationOutputHandler {
|
||||||
|
constructor(public eventName: string, public eventPhase: string, public handler: Function) {}
|
||||||
|
}
|
|
@ -6,11 +6,6 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {AnimationGroupPlayer} from '../animation/animation_group_player';
|
|
||||||
import {AnimationPlayer} from '../animation/animation_player';
|
|
||||||
import {queueAnimation} from '../animation/animation_queue';
|
|
||||||
import {AnimationTransitionEvent} from '../animation/animation_transition_event';
|
|
||||||
import {ViewAnimationMap} from '../animation/view_animation_map';
|
|
||||||
import {ChangeDetectorRef, ChangeDetectorStatus} from '../change_detection/change_detection';
|
import {ChangeDetectorRef, ChangeDetectorStatus} from '../change_detection/change_detection';
|
||||||
import {Injector} from '../di/injector';
|
import {Injector} from '../di/injector';
|
||||||
import {ListWrapper} from '../facade/collection';
|
import {ListWrapper} from '../facade/collection';
|
||||||
|
@ -18,6 +13,7 @@ import {isPresent} from '../facade/lang';
|
||||||
import {WtfScopeFn, wtfCreateScope, wtfLeave} from '../profile/profile';
|
import {WtfScopeFn, wtfCreateScope, wtfLeave} from '../profile/profile';
|
||||||
import {RenderComponentType, RenderDebugInfo, Renderer} from '../render/api';
|
import {RenderComponentType, RenderDebugInfo, Renderer} from '../render/api';
|
||||||
|
|
||||||
|
import {AnimationViewContext} from './animation_view_context';
|
||||||
import {DebugContext, StaticNodeDebugInfo} from './debug_context';
|
import {DebugContext, StaticNodeDebugInfo} from './debug_context';
|
||||||
import {AppElement} from './element';
|
import {AppElement} from './element';
|
||||||
import {ElementInjector} from './element_injector';
|
import {ElementInjector} from './element_injector';
|
||||||
|
@ -49,10 +45,7 @@ export abstract class AppView<T> {
|
||||||
renderer: Renderer;
|
renderer: Renderer;
|
||||||
|
|
||||||
private _hasExternalHostElement: boolean;
|
private _hasExternalHostElement: boolean;
|
||||||
|
private _animationContext: AnimationViewContext;
|
||||||
public animationPlayers = new ViewAnimationMap();
|
|
||||||
|
|
||||||
private _animationListeners = new Map<any, _AnimationOutputHandler[]>();
|
|
||||||
|
|
||||||
public context: T;
|
public context: T;
|
||||||
|
|
||||||
|
@ -68,61 +61,15 @@ export abstract class AppView<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get animationContext(): AnimationViewContext {
|
||||||
|
if (!this._animationContext) {
|
||||||
|
this._animationContext = new AnimationViewContext();
|
||||||
|
}
|
||||||
|
return this._animationContext;
|
||||||
|
}
|
||||||
|
|
||||||
get destroyed(): boolean { return this.cdMode === ChangeDetectorStatus.Destroyed; }
|
get destroyed(): boolean { return this.cdMode === ChangeDetectorStatus.Destroyed; }
|
||||||
|
|
||||||
cancelActiveAnimation(element: any, animationName: string, removeAllAnimations: boolean = false) {
|
|
||||||
if (removeAllAnimations) {
|
|
||||||
this.animationPlayers.findAllPlayersByElement(element).forEach(player => player.destroy());
|
|
||||||
} else {
|
|
||||||
var player = this.animationPlayers.find(element, animationName);
|
|
||||||
if (isPresent(player)) {
|
|
||||||
player.destroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
queueAnimation(
|
|
||||||
element: any, animationName: string, player: AnimationPlayer, totalTime: number,
|
|
||||||
fromState: string, toState: string): void {
|
|
||||||
queueAnimation(player);
|
|
||||||
var event = new AnimationTransitionEvent(
|
|
||||||
{'fromState': fromState, 'toState': toState, 'totalTime': totalTime});
|
|
||||||
this.animationPlayers.set(element, animationName, player);
|
|
||||||
|
|
||||||
player.onDone(() => {
|
|
||||||
// TODO: make this into a datastructure for done|start
|
|
||||||
this.triggerAnimationOutput(element, animationName, 'done', event);
|
|
||||||
this.animationPlayers.remove(element, animationName);
|
|
||||||
});
|
|
||||||
|
|
||||||
player.onStart(() => { this.triggerAnimationOutput(element, animationName, 'start', event); });
|
|
||||||
}
|
|
||||||
|
|
||||||
triggerAnimationOutput(
|
|
||||||
element: any, animationName: string, phase: string, event: AnimationTransitionEvent) {
|
|
||||||
var listeners = this._animationListeners.get(element);
|
|
||||||
if (isPresent(listeners) && listeners.length) {
|
|
||||||
for (let i = 0; i < listeners.length; i++) {
|
|
||||||
let listener = listeners[i];
|
|
||||||
// we check for both the name in addition to the phase in the event
|
|
||||||
// that there may be more than one @trigger on the same element
|
|
||||||
if (listener.eventName === animationName && listener.eventPhase === phase) {
|
|
||||||
listener.handler(event);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
registerAnimationOutput(
|
|
||||||
element: any, eventName: string, eventPhase: string, eventHandler: Function): void {
|
|
||||||
var animations = this._animationListeners.get(element);
|
|
||||||
if (!isPresent(animations)) {
|
|
||||||
this._animationListeners.set(element, animations = []);
|
|
||||||
}
|
|
||||||
animations.push(new _AnimationOutputHandler(eventName, eventPhase, eventHandler));
|
|
||||||
}
|
|
||||||
|
|
||||||
create(context: T, givenProjectableNodes: Array<any|any[]>, rootSelectorOrNode: string|any):
|
create(context: T, givenProjectableNodes: Array<any|any[]>, rootSelectorOrNode: string|any):
|
||||||
AppElement {
|
AppElement {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
|
@ -234,11 +181,11 @@ export abstract class AppView<T> {
|
||||||
this.destroyInternal();
|
this.destroyInternal();
|
||||||
this.dirtyParentQueriesInternal();
|
this.dirtyParentQueriesInternal();
|
||||||
|
|
||||||
if (this.animationPlayers.length == 0) {
|
if (this._animationContext) {
|
||||||
this.renderer.destroyView(hostElement, this.allNodes);
|
this._animationContext.onAllActiveAnimationsDone(
|
||||||
|
() => this.renderer.destroyView(hostElement, this.allNodes));
|
||||||
} else {
|
} else {
|
||||||
var player = new AnimationGroupPlayer(this.animationPlayers.getAllPlayers());
|
this.renderer.destroyView(hostElement, this.allNodes);
|
||||||
player.onDone(() => { this.renderer.destroyView(hostElement, this.allNodes); });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,11 +201,11 @@ export abstract class AppView<T> {
|
||||||
|
|
||||||
detach(): void {
|
detach(): void {
|
||||||
this.detachInternal();
|
this.detachInternal();
|
||||||
if (this.animationPlayers.length == 0) {
|
if (this._animationContext) {
|
||||||
this.renderer.detachView(this.flatRootNodes);
|
this._animationContext.onAllActiveAnimationsDone(
|
||||||
|
() => this.renderer.detachView(this.flatRootNodes));
|
||||||
} else {
|
} else {
|
||||||
var player = new AnimationGroupPlayer(this.animationPlayers.getAllPlayers());
|
this.renderer.detachView(this.flatRootNodes);
|
||||||
player.onDone(() => { this.renderer.detachView(this.flatRootNodes); });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -466,7 +413,3 @@ function _findLastRenderNode(node: any): any {
|
||||||
}
|
}
|
||||||
return lastNode;
|
return lastNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
class _AnimationOutputHandler {
|
|
||||||
constructor(public eventName: string, public eventPhase: string, public handler: Function) {}
|
|
||||||
}
|
|
||||||
|
|
|
@ -36,17 +36,17 @@ export function main() {
|
||||||
expect(playersMap.find(elementNode, animationName)).toBe(player);
|
expect(playersMap.find(elementNode, animationName)).toBe(player);
|
||||||
expect(playersMap.findAllPlayersByElement(elementNode)).toEqual([player]);
|
expect(playersMap.findAllPlayersByElement(elementNode)).toEqual([player]);
|
||||||
expect(playersMap.getAllPlayers()).toEqual([player]);
|
expect(playersMap.getAllPlayers()).toEqual([player]);
|
||||||
expect(playersMap.length).toEqual(1);
|
expect(countPlayers(playersMap)).toEqual(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should remove a registered player when remove() is called', () => {
|
it('should remove a registered player when remove() is called', () => {
|
||||||
var player = new MockAnimationPlayer();
|
var player = new MockAnimationPlayer();
|
||||||
playersMap.set(elementNode, animationName, player);
|
playersMap.set(elementNode, animationName, player);
|
||||||
expect(playersMap.find(elementNode, animationName)).toBe(player);
|
expect(playersMap.find(elementNode, animationName)).toBe(player);
|
||||||
expect(playersMap.length).toEqual(1);
|
expect(countPlayers(playersMap)).toEqual(1);
|
||||||
playersMap.remove(elementNode, animationName);
|
playersMap.remove(elementNode, animationName);
|
||||||
expect(playersMap.find(elementNode, animationName)).not.toBe(player);
|
expect(playersMap.find(elementNode, animationName)).not.toBe(player);
|
||||||
expect(playersMap.length).toEqual(0);
|
expect(countPlayers(playersMap)).toEqual(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow multiple players to be registered on the same element', () => {
|
it('should allow multiple players to be registered on the same element', () => {
|
||||||
|
@ -54,7 +54,7 @@ export function main() {
|
||||||
var player2 = new MockAnimationPlayer();
|
var player2 = new MockAnimationPlayer();
|
||||||
playersMap.set(elementNode, 'myAnimation1', player1);
|
playersMap.set(elementNode, 'myAnimation1', player1);
|
||||||
playersMap.set(elementNode, 'myAnimation2', player2);
|
playersMap.set(elementNode, 'myAnimation2', player2);
|
||||||
expect(playersMap.length).toEqual(2);
|
expect(countPlayers(playersMap)).toEqual(2);
|
||||||
expect(playersMap.findAllPlayersByElement(elementNode)).toEqual([player1, player2]);
|
expect(playersMap.findAllPlayersByElement(elementNode)).toEqual([player1, player2]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -63,10 +63,14 @@ export function main() {
|
||||||
var player2 = new MockAnimationPlayer();
|
var player2 = new MockAnimationPlayer();
|
||||||
playersMap.set(elementNode, animationName, player1);
|
playersMap.set(elementNode, animationName, player1);
|
||||||
expect(playersMap.find(elementNode, animationName)).toBe(player1);
|
expect(playersMap.find(elementNode, animationName)).toBe(player1);
|
||||||
expect(playersMap.length).toEqual(1);
|
expect(countPlayers(playersMap)).toEqual(1);
|
||||||
playersMap.set(elementNode, animationName, player2);
|
playersMap.set(elementNode, animationName, player2);
|
||||||
expect(playersMap.find(elementNode, animationName)).toBe(player2);
|
expect(playersMap.find(elementNode, animationName)).toBe(player2);
|
||||||
expect(playersMap.length).toEqual(1);
|
expect(countPlayers(playersMap)).toEqual(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function countPlayers(map: ViewAnimationMap): number {
|
||||||
|
return map.getAllPlayers().length;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue