fix(animations): report correct totalTime value even during noOp animations (#22225)

This patch ensures that if the NoopAnimationsModule is used then it will
correctly report the associated `totalTime` property within the emitted
AnimationEvent instance when an animation event trigger is fired.

BREAKING CHANGE: When animation is trigged within a disabled zone, the
associated event (which an instance of AnimationEvent) will no longer
report the totalTime as 0 (it will emit the actual time of the
animation). To detect if an animation event is reporting a disabled
animation then the `event.disabled` property can be used instead.

PR Close #22225
This commit is contained in:
Matias Niemelä
2018-02-14 10:12:10 -08:00
committed by Victor Berchet
parent 884de18cba
commit e1bf067090
12 changed files with 108 additions and 37 deletions

View File

@ -34,7 +34,7 @@ export class NoopAnimationDriver implements AnimationDriver {
animate(
element: any, keyframes: {[key: string]: string | number}[], duration: number, delay: number,
easing: string, previousPlayers: any[] = []): AnimationPlayer {
return new NoopAnimationPlayer();
return new NoopAnimationPlayer(duration, delay);
}
}

View File

@ -75,23 +75,24 @@ export function listenOnPlayer(
callback: (event: any) => any) {
switch (eventName) {
case 'start':
player.onStart(() => callback(event && copyAnimationEvent(event, 'start', player.totalTime)));
player.onStart(() => callback(event && copyAnimationEvent(event, 'start', player)));
break;
case 'done':
player.onDone(() => callback(event && copyAnimationEvent(event, 'done', player.totalTime)));
player.onDone(() => callback(event && copyAnimationEvent(event, 'done', player)));
break;
case 'destroy':
player.onDestroy(
() => callback(event && copyAnimationEvent(event, 'destroy', player.totalTime)));
player.onDestroy(() => callback(event && copyAnimationEvent(event, 'destroy', player)));
break;
}
}
export function copyAnimationEvent(
e: AnimationEvent, phaseName?: string, totalTime?: number): AnimationEvent {
e: AnimationEvent, phaseName: string, player: AnimationPlayer): AnimationEvent {
const totalTime = player.totalTime;
const disabled = (player as any).disabled ? true : false;
const event = makeAnimationEvent(
e.element, e.triggerName, e.fromState, e.toState, phaseName || e.phaseName,
totalTime == undefined ? e.totalTime : totalTime);
totalTime == undefined ? e.totalTime : totalTime, disabled);
const data = (e as any)['_data'];
if (data != null) {
(event as any)['_data'] = data;
@ -101,8 +102,8 @@ export function copyAnimationEvent(
export function makeAnimationEvent(
element: any, triggerName: string, fromState: string, toState: string, phaseName: string = '',
totalTime: number = 0): AnimationEvent {
return {element, triggerName, fromState, toState, phaseName, totalTime};
totalTime: number = 0, disabled?: boolean): AnimationEvent {
return {element, triggerName, fromState, toState, phaseName, totalTime, disabled: !!disabled};
}
export function getOrSetAsInMap(

View File

@ -1081,6 +1081,8 @@ export class TransitionAnimationEngine {
if (subTimelines.has(element)) {
if (disabledElementsSet.has(element)) {
player.onDestroy(() => setStyles(element, instruction.toStyles));
player.disabled = true;
player.overrideTotalTime(instruction.totalTime);
skippedPlayers.push(player);
return;
}
@ -1311,7 +1313,8 @@ export class TransitionAnimationEngine {
// FIXME (matsko): make sure to-be-removed animations are removed properly
const details = element[REMOVAL_FLAG];
if (details && details.removedBeforeQueried) return new NoopAnimationPlayer();
if (details && details.removedBeforeQueried)
return new NoopAnimationPlayer(timelineInstruction.duration, timelineInstruction.delay);
const isQueriedElement = element !== rootElement;
const previousPlayers =
@ -1379,7 +1382,7 @@ export class TransitionAnimationEngine {
// special case for when an empty transition|definition is provided
// ... there is no point in rendering an empty animation
return new NoopAnimationPlayer();
return new NoopAnimationPlayer(instruction.duration, instruction.delay);
}
}
@ -1392,8 +1395,10 @@ export class TransitionAnimationPlayer implements AnimationPlayer {
public parentPlayer: AnimationPlayer;
public markedForDestroy: boolean = false;
public disabled = false;
readonly queued: boolean = true;
public readonly totalTime: number = 0;
constructor(public namespaceId: string, public triggerName: string, public element: any) {}
@ -1407,15 +1412,18 @@ export class TransitionAnimationPlayer implements AnimationPlayer {
});
this._queuedCallbacks = {};
this._containsRealPlayer = true;
this.overrideTotalTime(player.totalTime);
(this as{queued: boolean}).queued = false;
}
getRealPlayer() { return this._player; }
overrideTotalTime(totalTime: number) { (this as any).totalTime = totalTime; }
syncPlayerEvents(player: AnimationPlayer) {
const p = this._player as any;
if (p.triggerCallback) {
player.onStart(() => p.triggerCallback('start'));
player.onStart(() => p.triggerCallback !('start'));
}
player.onDone(() => this.finish());
player.onDestroy(() => this.destroy());
@ -1473,8 +1481,6 @@ export class TransitionAnimationPlayer implements AnimationPlayer {
getPosition(): number { return this.queued ? 0 : this._player.getPosition(); }
get totalTime(): number { return this._player.totalTime; }
/* @internal */
triggerCallback(phaseName: string): void {
const p = this._player as any;