refactor(animations): ensure animation input/outputs are managed within the template parser (#11782)
Closes #11782 Closes #11601 Related #11707
This commit is contained in:

committed by
Chuck Jazdzewski

parent
cf750e17ed
commit
85489a166e
@ -1,10 +0,0 @@
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
export class AnimationOutput {
|
||||
constructor(public name: string, public phase: string, public fullPropertyName: string) {}
|
||||
}
|
@ -9,7 +9,6 @@
|
||||
import {ANY_STATE as ANY_STATE_, DEFAULT_STATE as DEFAULT_STATE_, EMPTY_STATE as EMPTY_STATE_, FILL_STYLE_FLAG as FILL_STYLE_FLAG_} from './animation/animation_constants';
|
||||
import {AnimationGroupPlayer as AnimationGroupPlayer_} from './animation/animation_group_player';
|
||||
import {AnimationKeyframe as AnimationKeyframe_} from './animation/animation_keyframe';
|
||||
import {AnimationOutput as AnimationOutput_} from './animation/animation_output';
|
||||
import {AnimationPlayer as AnimationPlayer_, NoOpAnimationPlayer as NoOpAnimationPlayer_} from './animation/animation_player';
|
||||
import {AnimationSequencePlayer as AnimationSequencePlayer_} from './animation/animation_sequence_player';
|
||||
import * as animationUtils from './animation/animation_style_util';
|
||||
@ -115,7 +114,6 @@ export var __core_private__: {
|
||||
renderStyles: typeof animationUtils.renderStyles,
|
||||
collectAndResolveStyles: typeof animationUtils.collectAndResolveStyles,
|
||||
AnimationStyles: typeof AnimationStyles_, _AnimationStyles?: AnimationStyles_,
|
||||
AnimationOutput: typeof AnimationOutput_, _AnimationOutput?: AnimationOutput_,
|
||||
ANY_STATE: typeof ANY_STATE_,
|
||||
DEFAULT_STATE: typeof DEFAULT_STATE_,
|
||||
EMPTY_STATE: typeof EMPTY_STATE_,
|
||||
@ -183,7 +181,6 @@ export var __core_private__: {
|
||||
renderStyles: animationUtils.renderStyles,
|
||||
collectAndResolveStyles: animationUtils.collectAndResolveStyles,
|
||||
AnimationStyles: AnimationStyles_,
|
||||
AnimationOutput: AnimationOutput_,
|
||||
ANY_STATE: ANY_STATE_,
|
||||
DEFAULT_STATE: DEFAULT_STATE_,
|
||||
EMPTY_STATE: EMPTY_STATE_,
|
||||
|
@ -7,7 +7,6 @@
|
||||
*/
|
||||
|
||||
import {AnimationGroupPlayer} from '../animation/animation_group_player';
|
||||
import {AnimationOutput} from '../animation/animation_output';
|
||||
import {AnimationPlayer, NoOpAnimationPlayer} from '../animation/animation_player';
|
||||
import {queueAnimation} from '../animation/animation_queue';
|
||||
import {AnimationTransitionEvent} from '../animation/animation_transition_event';
|
||||
@ -53,7 +52,7 @@ export abstract class AppView<T> {
|
||||
|
||||
public animationPlayers = new ViewAnimationMap();
|
||||
|
||||
private _animationListeners = new Map<any, _AnimationOutputWithHandler[]>();
|
||||
private _animationListeners = new Map<any, _AnimationOutputHandler[]>();
|
||||
|
||||
public context: T;
|
||||
|
||||
@ -107,7 +106,7 @@ export abstract class AppView<T> {
|
||||
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.output.name == animationName && listener.output.phase == phase) {
|
||||
if (listener.eventName === animationName && listener.eventPhase === phase) {
|
||||
listener.handler(event);
|
||||
break;
|
||||
}
|
||||
@ -115,14 +114,13 @@ export abstract class AppView<T> {
|
||||
}
|
||||
}
|
||||
|
||||
registerAnimationOutput(element: any, outputEvent: AnimationOutput, eventHandler: Function):
|
||||
void {
|
||||
var entry = new _AnimationOutputWithHandler(outputEvent, eventHandler);
|
||||
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(entry);
|
||||
animations.push(new _AnimationOutputHandler(eventName, eventPhase, eventHandler));
|
||||
}
|
||||
|
||||
create(context: T, givenProjectableNodes: Array<any|any[]>, rootSelectorOrNode: string|any):
|
||||
@ -469,6 +467,6 @@ function _findLastRenderNode(node: any): any {
|
||||
return lastNode;
|
||||
}
|
||||
|
||||
class _AnimationOutputWithHandler {
|
||||
constructor(public output: AnimationOutput, public handler: Function) {}
|
||||
class _AnimationOutputHandler {
|
||||
constructor(public eventName: string, public eventPhase: string, public handler: Function) {}
|
||||
}
|
||||
|
@ -997,7 +997,7 @@ function declareTests({useJit}: {useJit: boolean}) {
|
||||
<div *ngIf="exp" [@outer]="exp">
|
||||
outer
|
||||
<div *ngIf="exp2" [@inner]="exp">
|
||||
inner
|
||||
inner
|
||||
< </div>
|
||||
< </div>
|
||||
`,
|
||||
@ -1234,8 +1234,7 @@ function declareTests({useJit}: {useJit: boolean}) {
|
||||
message = e.message;
|
||||
}
|
||||
|
||||
expect(message).toMatch(
|
||||
/- Couldn't find the corresponding animation trigger definition for \(@something\)/);
|
||||
expect(message).toMatch(/Couldn't find an animation entry for "something"/);
|
||||
});
|
||||
|
||||
it('should throw an error if an animation output is referenced that is not bound to as a property on the same element',
|
||||
@ -1258,7 +1257,7 @@ function declareTests({useJit}: {useJit: boolean}) {
|
||||
}
|
||||
|
||||
expect(message).toMatch(
|
||||
/- Unable to listen on \(@trigger.done\) because the animation trigger \[@trigger\] isn't being used on the same element/);
|
||||
/Unable to listen on \(@trigger.done\) because the animation trigger \[@trigger\] isn't being used on the same element/);
|
||||
});
|
||||
|
||||
it('should throw an error if an unsupported animation output phase name is used', () => {
|
||||
@ -1287,7 +1286,7 @@ function declareTests({useJit}: {useJit: boolean}) {
|
||||
TestBed.overrideComponent(DummyIfCmp, {
|
||||
set: {
|
||||
template: `
|
||||
<div (@trigger)="callback($event)"></div>
|
||||
<div [@trigger]="exp" (@trigger)="callback($event)"></div>
|
||||
`,
|
||||
animations: [trigger('trigger', [transition('one => two', [animate(1000)])])]
|
||||
}
|
||||
@ -1319,7 +1318,7 @@ function declareTests({useJit}: {useJit: boolean}) {
|
||||
}
|
||||
|
||||
expect(message).toMatch(
|
||||
/Couldn't find the corresponding host-level animation trigger definition for \(@trigger\)/);
|
||||
/Unable to listen on \(@trigger.done\) because the animation trigger \[@trigger\] isn't being used on the same element/);
|
||||
});
|
||||
|
||||
it('should allow host and element-level animation bindings to be defined on the same tag/component',
|
||||
@ -1480,11 +1479,27 @@ function declareTests({useJit}: {useJit: boolean}) {
|
||||
failureMessage = e.message;
|
||||
}
|
||||
|
||||
expect(failureMessage)
|
||||
.toMatch(/Animation parsing for DummyIfCmp has failed due to the following errors:/);
|
||||
expect(failureMessage).toMatch(/- Couldn't find an animation entry for status/);
|
||||
expect(failureMessage).toMatch(/Template parse errors:/);
|
||||
expect(failureMessage).toMatch(/Couldn't find an animation entry for "status"/);
|
||||
});
|
||||
|
||||
it('should throw an error if an animation trigger is registered but is already in use', () => {
|
||||
TestBed.overrideComponent(
|
||||
DummyIfCmp, {set: {animations: [trigger('matias', []), trigger('matias', [])]}});
|
||||
|
||||
var failureMessage = '';
|
||||
try {
|
||||
const fixture = TestBed.createComponent(DummyLoadingCmp);
|
||||
} catch (e) {
|
||||
failureMessage = e.message;
|
||||
}
|
||||
|
||||
expect(failureMessage).toMatch(/Animation parse errors:/);
|
||||
expect(failureMessage)
|
||||
.toMatch(
|
||||
/The animation trigger "matias" has already been registered for the DummyIfCmp component/);
|
||||
});
|
||||
|
||||
it('should be permitted to be registered on the host element', fakeAsync(() => {
|
||||
TestBed.overrideComponent(DummyLoadingCmp, {
|
||||
set: {
|
||||
@ -1521,7 +1536,7 @@ function declareTests({useJit}: {useJit: boolean}) {
|
||||
failureMessage = e.message;
|
||||
}
|
||||
|
||||
expect(failureMessage).toMatch(/- Couldn't find an animation entry for loading/);
|
||||
expect(failureMessage).toMatch(/Couldn't find an animation entry for "loading"/);
|
||||
});
|
||||
|
||||
it('should retain the destination animation state styles once the animation is complete',
|
||||
|
Reference in New Issue
Block a user