fix(animations): stringify boolean values as `1` and `0` (#15311)
Closes #15247 Closes #15311 PR Close #15311
This commit is contained in:
parent
764e90f9bb
commit
94da80148e
|
@ -31,6 +31,7 @@ export interface TriggerListenerTuple {
|
|||
const MARKED_FOR_ANIMATION_CLASSNAME = 'ng-animating';
|
||||
const MARKED_FOR_ANIMATION_SELECTOR = '.ng-animating';
|
||||
const MARKED_FOR_REMOVAL = '$$ngRemove';
|
||||
const VOID_STATE = 'void';
|
||||
|
||||
export class DomAnimationEngine {
|
||||
private _flaggedInserts = new Set<any>();
|
||||
|
@ -84,7 +85,7 @@ export class DomAnimationEngine {
|
|||
const possibleTriggers = Object.keys(lookupRef);
|
||||
const hasRemoval = possibleTriggers.some(triggerName => {
|
||||
const oldValue = lookupRef[triggerName];
|
||||
const instruction = this._triggers[triggerName].matchTransition(oldValue, 'void');
|
||||
const instruction = this._triggers[triggerName].matchTransition(oldValue, VOID_STATE);
|
||||
return !!instruction;
|
||||
});
|
||||
if (hasRemoval) {
|
||||
|
@ -115,8 +116,9 @@ export class DomAnimationEngine {
|
|||
this._elementTriggerStates.set(element, lookupRef = {});
|
||||
}
|
||||
|
||||
let oldValue = lookupRef.hasOwnProperty(property) ? lookupRef[property] : 'void';
|
||||
let oldValue = lookupRef.hasOwnProperty(property) ? lookupRef[property] : VOID_STATE;
|
||||
if (oldValue !== value) {
|
||||
value = normalizeTriggerValue(value);
|
||||
let instruction = trigger.matchTransition(oldValue, value);
|
||||
if (!instruction) {
|
||||
// we do this to make sure we always have an animation player so
|
||||
|
@ -407,11 +409,11 @@ export class DomAnimationEngine {
|
|||
Object.keys(stateDetails).forEach(triggerName => {
|
||||
flushAgain = true;
|
||||
const oldValue = stateDetails[triggerName];
|
||||
const instruction = this._triggers[triggerName].matchTransition(oldValue, 'void');
|
||||
const instruction = this._triggers[triggerName].matchTransition(oldValue, VOID_STATE);
|
||||
if (instruction) {
|
||||
players.push(this.animateTransition(element, instruction));
|
||||
} else {
|
||||
const event = makeAnimationEvent(element, triggerName, oldValue, 'void', '', 0);
|
||||
const event = makeAnimationEvent(element, triggerName, oldValue, VOID_STATE, '', 0);
|
||||
const player = new NoopAnimationPlayer();
|
||||
this._queuePlayer(element, triggerName, player, event);
|
||||
}
|
||||
|
@ -515,3 +517,12 @@ function makeAnimationEvent(
|
|||
totalTime: number): AnimationEvent {
|
||||
return <AnimationEvent>{element, triggerName, fromState, toState, phaseName, totalTime};
|
||||
}
|
||||
|
||||
function normalizeTriggerValue(value: any): string {
|
||||
switch (typeof value) {
|
||||
case 'boolean':
|
||||
return value ? '1' : '0';
|
||||
default:
|
||||
return value ? value.toString() : null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -147,6 +147,46 @@ export function main() {
|
|||
]);
|
||||
});
|
||||
|
||||
it('should stringify boolean triggers to `1` and `0`', () => {
|
||||
@Component({
|
||||
selector: 'if-cmp',
|
||||
template: `
|
||||
<div [@myAnimation]="exp"></div>
|
||||
`,
|
||||
animations: [trigger(
|
||||
'myAnimation',
|
||||
[
|
||||
transition('void => 1', [style({opacity: 0}), animate(1000, style({opacity: 1}))]),
|
||||
transition('1 => 0', [style({opacity: 1}), animate(1000, style({opacity: 0}))])
|
||||
])]
|
||||
})
|
||||
class Cmp {
|
||||
exp: any = false;
|
||||
}
|
||||
|
||||
TestBed.configureTestingModule({declarations: [Cmp]});
|
||||
|
||||
const engine = TestBed.get(ɵAnimationEngine);
|
||||
const fixture = TestBed.createComponent(Cmp);
|
||||
const cmp = fixture.componentInstance;
|
||||
|
||||
cmp.exp = true;
|
||||
fixture.detectChanges();
|
||||
engine.flush();
|
||||
|
||||
expect(getLog().pop().keyframes).toEqual([
|
||||
{offset: 0, opacity: '0'}, {offset: 1, opacity: '1'}
|
||||
]);
|
||||
|
||||
cmp.exp = false;
|
||||
fixture.detectChanges();
|
||||
engine.flush();
|
||||
|
||||
expect(getLog().pop().keyframes).toEqual([
|
||||
{offset: 0, opacity: '1'}, {offset: 1, opacity: '0'}
|
||||
]);
|
||||
});
|
||||
|
||||
it('should not throw an error if a trigger with the same name exists in separate components',
|
||||
() => {
|
||||
@Component({selector: 'cmp1', template: '...', animations: [trigger('trig', [])]})
|
||||
|
|
Loading…
Reference in New Issue