diff --git a/packages/animations/browser/src/render/transition_animation_engine.ts b/packages/animations/browser/src/render/transition_animation_engine.ts index 992ebf3cb056e..b0be786100b6e 100644 --- a/packages/animations/browser/src/render/transition_animation_engine.ts +++ b/packages/animations/browser/src/render/transition_animation_engine.ts @@ -1169,8 +1169,17 @@ export class TransitionAnimationEngine { if (details && details.removedBeforeQueried) return new NoopAnimationPlayer(); const isQueriedElement = element !== rootElement; - const previousPlayers = flattenGroupPlayers( - (allPreviousPlayersMap.get(element) || EMPTY_PLAYER_ARRAY).map(p => p.getRealPlayer())); + const previousPlayers = + flattenGroupPlayers((allPreviousPlayersMap.get(element) || EMPTY_PLAYER_ARRAY) + .map(p => p.getRealPlayer())) + .filter(p => { + // the `element` is not apart of the AnimationPlayer definition, but + // Mock/WebAnimations + // use the element within their implementation. This will be added in Angular5 to + // AnimationPlayer + const pp = p as any; + return pp.element ? pp.element === element : false; + }); const preStyles = preStylesMap.get(element); const postStyles = postStylesMap.get(element); diff --git a/packages/core/test/animation/animation_integration_spec.ts b/packages/core/test/animation/animation_integration_spec.ts index 1884f35567043..b6c9ddcee6709 100644 --- a/packages/core/test/animation/animation_integration_spec.ts +++ b/packages/core/test/animation/animation_integration_spec.ts @@ -868,6 +868,87 @@ export function main() { expect(pp[2].currentSnapshot).toEqual({opacity: AUTO_STYLE}); }); + it('should provide the styling of previous players that are grouped and queried and make sure match the players with the correct elements', + () => { + @Component({ + selector: 'ani-cmp', + template: ` +
+
+
+ `, + animations: [ + trigger( + 'myAnimation', + [ + transition( + '1 => 2', + [ + style({fontSize: '10px'}), + query( + '.inner', + [ + style({fontSize: '20px'}), + ]), + animate('1s', style({fontSize: '100px'})), + query( + '.inner', + [ + animate('1s', style({fontSize: '200px'})), + ]), + ]), + transition( + '2 => 3', + [ + animate('1s', style({fontSize: '0px'})), + query( + '.inner', + [ + animate('1s', style({fontSize: '0px'})), + ]), + ]), + ]), + ], + }) + class Cmp { + exp: any = false; + } + + TestBed.configureTestingModule({declarations: [Cmp]}); + + const engine = TestBed.get(ɵAnimationEngine); + const fixture = TestBed.createComponent(Cmp); + const cmp = fixture.componentInstance; + + fixture.detectChanges(); + + cmp.exp = '1'; + fixture.detectChanges(); + resetLog(); + + cmp.exp = '2'; + fixture.detectChanges(); + resetLog(); + + cmp.exp = '3'; + fixture.detectChanges(); + const players = getLog(); + expect(players.length).toEqual(2); + const [p1, p2] = players as MockAnimationPlayer[]; + + const pp1 = p1.previousPlayers as MockAnimationPlayer[]; + expect(p1.element.classList.contains('container')).toBeTruthy(); + for (let i = 0; i < pp1.length; i++) { + expect(pp1[i].element).toEqual(p1.element); + } + + const pp2 = p2.previousPlayers as MockAnimationPlayer[]; + expect(p2.element.classList.contains('inner')).toBeTruthy(); + for (let i = 0; i < pp2.length; i++) { + expect(pp2[i].element).toEqual(p2.element); + } + }); + it('should properly balance styles between states even if there are no destination state styles', () => { @Component({