diff --git a/packages/animations/browser/src/render/animation_engine_next.ts b/packages/animations/browser/src/render/animation_engine_next.ts index 3bd0b4b6bd..410d3a77df 100644 --- a/packages/animations/browser/src/render/animation_engine_next.ts +++ b/packages/animations/browser/src/render/animation_engine_next.ts @@ -48,11 +48,8 @@ export class AnimationEngine { trigger = buildTrigger(name, ast); this._triggerCache[cacheKey] = trigger; } - this._transitionEngine.registerTrigger(namespaceId, name, trigger); - } - register(namespaceId: string, hostElement: any) { - this._transitionEngine.register(namespaceId, hostElement); + this._transitionEngine.register(namespaceId, hostElement, name, trigger); } destroy(namespaceId: string, context: any) { @@ -89,7 +86,7 @@ export class AnimationEngine { return this._transitionEngine.listen(namespaceId, element, eventName, eventPhase, callback); } - flush(microtaskId: number = -1): void { this._transitionEngine.flush(microtaskId); } + flush(countId: number = -1): void { this._transitionEngine.flush(countId); } get players(): AnimationPlayer[] { return (this._transitionEngine.players as AnimationPlayer[]) diff --git a/packages/animations/browser/src/render/transition_animation_engine.ts b/packages/animations/browser/src/render/transition_animation_engine.ts index fa3e1419b0..f925d4b337 100644 --- a/packages/animations/browser/src/render/transition_animation_engine.ts +++ b/packages/animations/browser/src/render/transition_animation_engine.ts @@ -13,13 +13,12 @@ import {AnimationTransitionInstruction} from '../dsl/animation_transition_instru import {AnimationTrigger} from '../dsl/animation_trigger'; import {ElementInstructionMap} from '../dsl/element_instruction_map'; import {AnimationStyleNormalizer} from '../dsl/style_normalization/animation_style_normalizer'; -import {ENTER_CLASSNAME, LEAVE_CLASSNAME, LEAVE_SELECTOR, NG_ANIMATING_CLASSNAME, NG_TRIGGER_CLASSNAME, NG_TRIGGER_SELECTOR, copyObj, eraseStyles, setStyles} from '../util'; +import {ENTER_CLASSNAME, LEAVE_CLASSNAME, LEAVE_SELECTOR, NG_ANIMATING_CLASSNAME, NG_TRIGGER_CLASSNAME, NG_TRIGGER_SELECTOR, copyObj, eraseStyles, iteratorToArray, setStyles} from '../util'; import {AnimationDriver} from './animation_driver'; import {getOrSetAsInMap, listenOnPlayer, makeAnimationEvent, normalizeKeyframes, optimizeGroupPlayer} from './shared'; const EMPTY_PLAYER_ARRAY: AnimationPlayer[] = []; -const ANIMATE_EPOCH_ATTR = 'ng-animate-id'; interface TriggerListener { name: string; @@ -256,7 +255,7 @@ export class AnimationTransitionNamespace { } private _destroyInnerNodes(rootElement: any, context: any, animate: boolean = false) { - this._engine.driver.query(rootElement, NG_TRIGGER_SELECTOR, true).forEach(elm => { + listToArray(this._engine.driver.query(rootElement, NG_TRIGGER_SELECTOR, true)).forEach(elm => { if (animate && containsClass(elm, this._hostClassName)) { const innerNs = this._engine.namespacesByHostElement.get(elm); @@ -274,7 +273,9 @@ export class AnimationTransitionNamespace { removeNode(element: any, context: any, doNotRecurse?: boolean): void { const engine = this._engine; - engine.markElementAsRemoved(element); + + addClass(element, LEAVE_CLASSNAME); + engine.afterFlush(() => removeClass(element, LEAVE_CLASSNAME)); if (!doNotRecurse && element.childElementCount) { this._destroyInnerNodes(element, context, true); @@ -381,7 +382,7 @@ export class AnimationTransitionNamespace { insertNode(element: any, parent: any): void { addClass(element, this._hostClassName); } - drainQueuedTransitions(microtaskId: number): QueueInstruction[] { + drainQueuedTransitions(countId: number): QueueInstruction[] { const instructions: QueueInstruction[] = []; this._queue.forEach(entry => { const player = entry.player; @@ -394,7 +395,7 @@ export class AnimationTransitionNamespace { if (listener.name == entry.triggerName) { const baseEvent = makeAnimationEvent( element, entry.triggerName, entry.fromState.value, entry.toState.value); - (baseEvent as any)['_data'] = microtaskId; + (baseEvent as any)['_data'] = countId; listenOnPlayer(entry.player, listener.phase, baseEvent, listener.callback); } }); @@ -448,13 +449,13 @@ export interface QueuedTransition { export class TransitionAnimationEngine { public players: TransitionAnimationPlayer[] = []; public queuedRemovals = new Map any>(); + public newlyInserted = new Set(); public newHostElements = new Map(); public playersByElement = new Map(); public playersByQueriedElement = new Map(); public statesByElement = new Map(); public totalAnimations = 0; public totalQueuedPlayers = 0; - public currentEpochId = 0; private _namespaceLookup: {[id: string]: AnimationTransitionNamespace} = {}; private _namespaceList: AnimationTransitionNamespace[] = []; @@ -497,7 +498,7 @@ export class TransitionAnimationEngine { // animation renderer type. If this happens then we can still have // access to this item when we query for :enter nodes. If the parent // is a renderer then the set data-structure will normalize the entry - this.updateElementEpoch(hostElement); + this.newlyInserted.add(hostElement); } return this._namespaceLookup[namespaceId] = ns; } @@ -525,24 +526,17 @@ export class TransitionAnimationEngine { return ns; } - register(namespaceId: string, hostElement: any) { + register(namespaceId: string, hostElement: any, name: string, trigger: AnimationTrigger) { let ns = this._namespaceLookup[namespaceId]; if (!ns) { ns = this.createNamespace(namespaceId, hostElement); } - return ns; - } - - registerTrigger(namespaceId: string, name: string, trigger: AnimationTrigger) { - let ns = this._namespaceLookup[namespaceId]; - if (ns && ns.register(name, trigger)) { + if (ns.register(name, trigger)) { this.totalAnimations++; } } destroy(namespaceId: string, context: any) { - if (!namespaceId) return; - const ns = this._fetchNamespace(namespaceId); this.afterFlush(() => { @@ -570,51 +564,20 @@ export class TransitionAnimationEngine { insertNode(namespaceId: string, element: any, parent: any, insertBefore: boolean): void { if (!isElementNode(element)) return; - // special case for when an element is removed and reinserted (move operation) - // when this occurs we do not want to use the element for deletion later - if (this.queuedRemovals.has(element)) { - this.markElementAsRemoved(element, true); - this.queuedRemovals.delete(element); - } - - // in the event that the namespaceId is blank then the caller - // code does not contain any animation code in it, but it is - // just being called so that the node is marked as being inserted - if (namespaceId) { - this._fetchNamespace(namespaceId).insertNode(element, parent); - } + this._fetchNamespace(namespaceId).insertNode(element, parent); // only *directives and host elements are inserted before if (insertBefore) { - this.updateElementEpoch(element); - } - } - - updateElementEpoch(element: any, isRemoval?: boolean) { - const epoch = (isRemoval ? -1 : 1) * this.currentEpochId; - setAttribute(element, ANIMATE_EPOCH_ATTR, epoch); - } - - markElementAsRemoved(element: any, unmark?: boolean) { - if (unmark) { - removeClass(element, LEAVE_CLASSNAME); - } else { - addClass(element, LEAVE_CLASSNAME); - this.afterFlush(() => removeClass(element, LEAVE_CLASSNAME)); + this.newlyInserted.add(element); } } removeNode(namespaceId: string, element: any, context: any, doNotRecurse?: boolean): void { - if (namespaceId) { - const ns = this._fetchNamespace(namespaceId); - if (!isElementNode(element) || !ns) { - this._onRemovalComplete(element, context); - } else { - ns.removeNode(element, context, doNotRecurse); - } + const ns = this._fetchNamespace(namespaceId); + if (!isElementNode(element) || !ns) { + this._onRemovalComplete(element, context); } else { - this.markElementAsRemoved(element); - this.queuedRemovals.set(element, () => this._onRemovalComplete(element, context)); + ns.removeNode(element, context, doNotRecurse); } } @@ -634,7 +597,7 @@ export class TransitionAnimationEngine { } destroyInnerAnimations(containerElement: any) { - this.driver.query(containerElement, NG_TRIGGER_SELECTOR, true).forEach(element => { + listToArray(this.driver.query(containerElement, NG_TRIGGER_SELECTOR, true)).forEach(element => { const players = this.playersByElement.get(element); if (players) { players.forEach(player => { @@ -665,21 +628,20 @@ export class TransitionAnimationEngine { }); } - flush(microtaskId: number = -1) { + flush(countId: number = -1) { let players: AnimationPlayer[] = []; if (this.newHostElements.size) { - this.newHostElements.forEach((ns, element) => this._balanceNamespaceList(ns, element)); + this.newHostElements.forEach((ns, element) => { this._balanceNamespaceList(ns, element); }); this.newHostElements.clear(); } if (this._namespaceList.length && (this.totalQueuedPlayers || this.queuedRemovals.size)) { - players = this._flushAnimations(microtaskId); - } else { - this.queuedRemovals.forEach(fn => fn()); + players = this._flushAnimations(countId); } this.totalQueuedPlayers = 0; this.queuedRemovals.clear(); + this.newlyInserted.clear(); this._flushFns.forEach(fn => fn()); this._flushFns = []; @@ -696,11 +658,9 @@ export class TransitionAnimationEngine { quietFns.forEach(fn => fn()); } } - - this.currentEpochId++; } - private _flushAnimations(microtaskId: number): TransitionAnimationPlayer[] { + private _flushAnimations(countId: number): TransitionAnimationPlayer[] { const subTimelines = new ElementInstructionMap(); const skippedPlayers: TransitionAnimationPlayer[] = []; const skippedPlayersMap = new Map(); @@ -712,15 +672,13 @@ export class TransitionAnimationEngine { // this must occur before the instructions are built below such that // the :enter queries match the elements (since the timeline queries // are fired during instruction building). + const allEnterNodes = iteratorToArray(this.newlyInserted.values()); + const enterNodes: any[] = collectEnterElements(this.driver, allEnterNodes); const bodyNode = getBodyNode(); - const allEnterNodes: any[] = - bodyNode ? this.driver.query(bodyNode, makeEpochSelector(this.currentEpochId), true) : []; - const enterNodes: any[] = - allEnterNodes.length ? collectEnterElements(this.driver, allEnterNodes) : []; for (let i = this._namespaceList.length - 1; i >= 0; i--) { const ns = this._namespaceList[i]; - ns.drainQueuedTransitions(microtaskId).forEach(entry => { + ns.drainQueuedTransitions(countId).forEach(entry => { const player = entry.player; const element = entry.element; @@ -793,7 +751,7 @@ export class TransitionAnimationEngine { allPreviousPlayersMap.forEach(players => players.forEach(player => player.destroy())); const leaveNodes: any[] = bodyNode && allPostStyleElements.size ? - this.driver.query(bodyNode, LEAVE_SELECTOR, true) : + listToArray(this.driver.query(bodyNode, LEAVE_SELECTOR, true)) : []; // PRE STAGE: fill the ! styles @@ -908,6 +866,7 @@ export class TransitionAnimationEngine { elementContainsData(namespaceId: string, element: any) { let containsData = false; if (this.queuedRemovals.has(element)) containsData = true; + if (this.newlyInserted.has(element)) containsData = true; if (this.playersByElement.has(element)) containsData = true; if (this.playersByQueriedElement.has(element)) containsData = true; if (this.statesByElement.has(element)) containsData = true; @@ -1258,6 +1217,12 @@ function cloakAndComputeStyles( return valuesMap; } +function listToArray(list: any): any[] { + const arr: any[] = []; + arr.push(...(list as any[])); + return arr; +} + function collectEnterElements(driver: AnimationDriver, allEnterNodes: any[]) { allEnterNodes.forEach(element => addClass(element, POTENTIAL_ENTER_CLASSNAME)); const enterNodes = filterNodeClasses(driver, getBodyNode(), POTENTIAL_ENTER_SELECTOR); @@ -1299,22 +1264,9 @@ function removeClass(element: any, className: string) { } } -function setAttribute(element: any, attr: string, value: any) { - if (element.setAttribute) { - element.setAttribute(attr, value); - } else { - element[attr] = value; - } -} - function getBodyNode(): any|null { if (typeof document != 'undefined') { return document.body; } return null; } - -function makeEpochSelector(epochId: number, isRemoval?: boolean) { - const value = (isRemoval ? -1 : 1) * epochId; - return `[${ANIMATE_EPOCH_ATTR}="${value}"]`; -} diff --git a/packages/animations/browser/test/render/transition_animation_engine_spec.ts b/packages/animations/browser/test/render/transition_animation_engine_spec.ts index 2ed18f0047..75cd0a1c5a 100644 --- a/packages/animations/browser/test/render/transition_animation_engine_spec.ts +++ b/packages/animations/browser/test/render/transition_animation_engine_spec.ts @@ -660,8 +660,7 @@ function registerTrigger( if (errors.length) { } const trigger = buildTrigger(name, ast); - engine.register(id, element); - engine.registerTrigger(id, name, trigger); + engine.register(id, element, name, trigger) } function setProperty( diff --git a/packages/core/test/animation/animation_integration_spec.ts b/packages/core/test/animation/animation_integration_spec.ts index b12240b1c6..9f69208e25 100644 --- a/packages/core/test/animation/animation_integration_spec.ts +++ b/packages/core/test/animation/animation_integration_spec.ts @@ -1101,10 +1101,9 @@ export function main() { const cmp = fixture.componentInstance; const someTrigger = trigger('someTrigger', []); - const hostElement = fixture.nativeElement; - engine.register(DEFAULT_NAMESPACE_ID, hostElement); engine.registerTrigger( - DEFAULT_COMPONENT_ID, DEFAULT_NAMESPACE_ID, hostElement, someTrigger.name, someTrigger); + DEFAULT_COMPONENT_ID, DEFAULT_NAMESPACE_ID, fixture.nativeElement, someTrigger.name, + someTrigger); cmp.exp = 'a'; fixture.detectChanges(); diff --git a/packages/core/test/animation/animation_query_integration_spec.ts b/packages/core/test/animation/animation_query_integration_spec.ts index 6582fb55be..869f57a940 100644 --- a/packages/core/test/animation/animation_query_integration_spec.ts +++ b/packages/core/test/animation/animation_query_integration_spec.ts @@ -1084,107 +1084,6 @@ export function main() { ]); }); }); - - it('should query elements in sub components that do not contain animations using the :enter selector', - () => { - @Component({ - selector: 'parent-cmp', - template: ` -
- -
- `, - animations: [trigger( - 'myAnimation', - [transition( - '* => on', - [query( - ':enter', [style({opacity: 0}), animate(1000, style({opacity: 1}))])])])] - }) - class ParentCmp { - public exp: any; - - @ViewChild('child') public child: any; - } - - @Component({ - selector: 'child-cmp', - template: ` -
- {{ item }} -
- ` - }) - class ChildCmp { - public items: any[] = []; - } - - TestBed.configureTestingModule({declarations: [ParentCmp, ChildCmp]}); - const fixture = TestBed.createComponent(ParentCmp); - const cmp = fixture.componentInstance; - fixture.detectChanges(); - - cmp.exp = 'on'; - cmp.child.items = [1, 2, 3]; - fixture.detectChanges(); - - const players = getLog() as any[]; - expect(players.length).toEqual(3); - - expect(players[0].element.innerText.trim()).toEqual('1'); - expect(players[1].element.innerText.trim()).toEqual('2'); - expect(players[2].element.innerText.trim()).toEqual('3'); - }); - - it('should query elements in sub components that do not contain animations using the :leave selector', - () => { - @Component({ - selector: 'parent-cmp', - template: ` -
- -
- `, - animations: [trigger( - 'myAnimation', - [transition( - '* => on', [query(':leave', [animate(1000, style({opacity: 0}))])])])] - }) - class ParentCmp { - public exp: any; - - @ViewChild('child') public child: any; - } - - @Component({ - selector: 'child-cmp', - template: ` -
- {{ item }} -
- ` - }) - class ChildCmp { - public items: any[] = []; - } - - TestBed.configureTestingModule({declarations: [ParentCmp, ChildCmp]}); - const fixture = TestBed.createComponent(ParentCmp); - const cmp = fixture.componentInstance; - cmp.child.items = [4, 5, 6]; - fixture.detectChanges(); - - cmp.exp = 'on'; - cmp.child.items = []; - fixture.detectChanges(); - - const players = getLog() as any[]; - expect(players.length).toEqual(3); - - expect(players[0].element.innerText.trim()).toEqual('4'); - expect(players[1].element.innerText.trim()).toEqual('5'); - expect(players[2].element.innerText.trim()).toEqual('6'); - }); }); describe('sub triggers', () => { diff --git a/packages/core/test/linker/projection_integration_spec.ts b/packages/core/test/linker/projection_integration_spec.ts index 9ba823ed4b..36e6e213d9 100644 --- a/packages/core/test/linker/projection_integration_spec.ts +++ b/packages/core/test/linker/projection_integration_spec.ts @@ -130,13 +130,11 @@ export function main() { .map(de => de.injector.get(ManualViewportDirective)); expect(main.nativeElement).toHaveText('(, B)'); - viewportDirectives.forEach(d => d.show()); - main.detectChanges(); expect(main.nativeElement).toHaveText('(A1, B)'); viewportDirectives.forEach(d => d.hide()); - main.detectChanges(); + expect(main.nativeElement).toHaveText('(, B)'); }); @@ -202,11 +200,10 @@ export function main() { expect(main.nativeElement).toHaveText('(, BC)'); viewportDirective.show(); - main.detectChanges(); expect(main.nativeElement).toHaveText('(A, BC)'); viewportDirective.hide(); - main.detectChanges(); + expect(main.nativeElement).toHaveText('(, BC)'); }); @@ -495,7 +492,7 @@ export function main() { expect(main.nativeElement).toHaveText('(, D)'); viewViewportDir.show(); - main.detectChanges(); + expect(main.nativeElement).toHaveText('(AC, D)'); const contentViewportDir = @@ -503,13 +500,12 @@ export function main() { ManualViewportDirective); contentViewportDir.show(); - main.detectChanges(); + expect(main.nativeElement).toHaveText('(ABC, D)'); // hide view viewport, and test that it also hides // the content viewport's views viewViewportDir.hide(); - main.detectChanges(); expect(main.nativeElement).toHaveText('(, D)'); }); }); diff --git a/packages/core/test/view/embedded_view_spec.ts b/packages/core/test/view/embedded_view_spec.ts index 017a7de9c6..fee7481e5c 100644 --- a/packages/core/test/view/embedded_view_spec.ts +++ b/packages/core/test/view/embedded_view_spec.ts @@ -62,7 +62,6 @@ export function main() { [elementDef(NodeFlags.None, null !, null !, 0, 'span', [['name', 'child1']])])) ])); const viewContainerData = asElementData(parentView, 1); - const rf = parentView.root.rendererFactory; const childView0 = createEmbeddedView(parentView, parentView.def.nodes[1]); const childView1 = createEmbeddedView(parentView, parentView.def.nodes[2]); @@ -76,10 +75,8 @@ export function main() { expect(getDOM().getAttribute(rootChildren[1], 'name')).toBe('child0'); expect(getDOM().getAttribute(rootChildren[2], 'name')).toBe('child1'); - rf.begin !(); detachEmbeddedView(viewContainerData, 1); detachEmbeddedView(viewContainerData, 0); - rf.end !(); expect(getDOM().childNodes(rootNodes[0]).length).toBe(2); }); @@ -190,4 +187,4 @@ export function main() { expect(log).toEqual(['ngOnDestroy']); }); }); -} +} \ No newline at end of file diff --git a/packages/core/test/view/ng_content_spec.ts b/packages/core/test/view/ng_content_spec.ts index b65b24668f..1c176b0dad 100644 --- a/packages/core/test/view/ng_content_spec.ts +++ b/packages/core/test/view/ng_content_spec.ts @@ -121,7 +121,6 @@ export function main() { ]))); const componentView = asElementData(view, 0).componentView; - const rf = componentView.root.rendererFactory; const view0 = createEmbeddedView(componentView, componentView.def.nodes[1]); attachEmbeddedView(view, asElementData(componentView, 1), 0, view0); @@ -129,9 +128,7 @@ export function main() { expect(getDOM().childNodes(getDOM().firstChild(rootNodes[0]))[1]) .toBe(asTextData(view, 2).renderText); - rf.begin !(); detachEmbeddedView(asElementData(componentView, 1), 0); - rf.end !(); expect(getDOM().childNodes(getDOM().firstChild(rootNodes[0])).length).toBe(1); }); diff --git a/packages/platform-browser/animations/src/animation_renderer.ts b/packages/platform-browser/animations/src/animation_renderer.ts index 69caf1b144..de510acc08 100644 --- a/packages/platform-browser/animations/src/animation_renderer.ts +++ b/packages/platform-browser/animations/src/animation_renderer.ts @@ -12,13 +12,12 @@ import {Injectable, NgZone, Renderer2, RendererFactory2, RendererStyleFlags2, Re @Injectable() export class AnimationRendererFactory implements RendererFactory2 { private _currentId: number = 0; - private _microtaskId: number = 1; + private _currentFlushId: number = 1; private _animationCallbacksBuffer: [(e: any) => any, any][] = []; - private _rendererCache = new Map(); constructor( - private delegate: RendererFactory2, private engine: AnimationEngine, private _zone: NgZone) { - engine.onRemovalComplete = (element: any, delegate: Renderer2) => { + private delegate: RendererFactory2, private _engine: AnimationEngine, private _zone: NgZone) { + _engine.onRemovalComplete = (element: any, delegate: any) => { // Note: if an component element has a leave animation, and the component // a host leave animation, the view engine will call `removeChild` for the parent // component renderer as well as for the child component renderer. @@ -30,31 +29,18 @@ export class AnimationRendererFactory implements RendererFactory2 { } createRenderer(hostElement: any, type: RendererType2): Renderer2 { - const EMPTY_NAMESPACE_ID = ''; - - // cache the delegates to find out which cached delegate can - // be used by which cached renderer - const delegate = this.delegate.createRenderer(hostElement, type); - if (!hostElement || !type || !type.data || !type.data['animation']) { - let renderer: BaseAnimationRenderer|undefined = this._rendererCache.get(delegate); - if (!renderer) { - renderer = new BaseAnimationRenderer(EMPTY_NAMESPACE_ID, delegate, this.engine); - // only cache this result when the base renderer is used - this._rendererCache.set(delegate, renderer); - } - return renderer; - } + let delegate = this.delegate.createRenderer(hostElement, type); + if (!hostElement || !type || !type.data || !type.data['animation']) return delegate; const componentId = type.id; const namespaceId = type.id + '-' + this._currentId; this._currentId++; - this.engine.register(namespaceId, hostElement); const animationTriggers = type.data['animation'] as AnimationTriggerMetadata[]; animationTriggers.forEach( - trigger => this.engine.registerTrigger( + trigger => this._engine.registerTrigger( componentId, namespaceId, hostElement, trigger.name, trigger)); - return new AnimationRenderer(this, namespaceId, delegate, this.engine); + return new AnimationRenderer(this, delegate, this._engine, this._zone, namespaceId); } begin() { @@ -64,12 +50,13 @@ export class AnimationRendererFactory implements RendererFactory2 { } private _scheduleCountTask() { - Zone.current.scheduleMicroTask('incremenet the animation microtask', () => this._microtaskId++); + Zone.current.scheduleMicroTask( + 'incremenet the animation microtask', () => { this._currentFlushId++; }); } /* @internal */ scheduleListenerCallback(count: number, fn: (e: any) => any, data: any) { - if (count >= 0 && count < this._microtaskId) { + if (count >= 0 && count < this._currentFlushId) { this._zone.run(() => fn(data)); return; } @@ -92,64 +79,54 @@ export class AnimationRendererFactory implements RendererFactory2 { end() { this._zone.runOutsideAngular(() => { this._scheduleCountTask(); - this.engine.flush(this._microtaskId); + this._engine.flush(this._currentFlushId); }); if (this.delegate.end) { this.delegate.end(); } } - whenRenderingDone(): Promise { return this.engine.whenRenderingDone(); } + whenRenderingDone(): Promise { return this._engine.whenRenderingDone(); } } -export class BaseAnimationRenderer implements Renderer2 { +export class AnimationRenderer implements Renderer2 { + public destroyNode: ((node: any) => any)|null = null; + public microtaskCount: number = 0; + constructor( - protected namespaceId: string, public delegate: Renderer2, public engine: AnimationEngine) { + private _factory: AnimationRendererFactory, public delegate: Renderer2, + private _engine: AnimationEngine, private _zone: NgZone, private _namespaceId: string) { this.destroyNode = this.delegate.destroyNode ? (n) => delegate.destroyNode !(n) : null; } get data() { return this.delegate.data; } - destroyNode: ((n: any) => void)|null; - destroy(): void { - this.engine.destroy(this.namespaceId, this.delegate); + this._engine.destroy(this._namespaceId, this.delegate); this.delegate.destroy(); } - createElement(name: string, namespace?: string|null|undefined) { + createElement(name: string, namespace?: string): any { return this.delegate.createElement(name, namespace); } - createComment(value: string) { return this.delegate.createComment(value); } + createComment(value: string): any { return this.delegate.createComment(value); } - createText(value: string) { return this.delegate.createText(value); } + createText(value: string): any { return this.delegate.createText(value); } - appendChild(parent: any, newChild: any): void { - this.delegate.appendChild(parent, newChild); - this.engine.onInsert(this.namespaceId, newChild, parent, false); + selectRootElement(selectorOrNode: string|any): any { + return this.delegate.selectRootElement(selectorOrNode); } - insertBefore(parent: any, newChild: any, refChild: any): void { - this.delegate.insertBefore(parent, newChild, refChild); - this.engine.onInsert(this.namespaceId, newChild, parent, true); - } + parentNode(node: any): any { return this.delegate.parentNode(node); } - removeChild(parent: any, oldChild: any): void { - this.engine.onRemove(this.namespaceId, oldChild, this.delegate); - } + nextSibling(node: any): any { return this.delegate.nextSibling(node); } - selectRootElement(selectorOrNode: any) { return this.delegate.selectRootElement(selectorOrNode); } - - parentNode(node: any) { return this.delegate.parentNode(node); } - - nextSibling(node: any) { return this.delegate.nextSibling(node); } - - setAttribute(el: any, name: string, value: string, namespace?: string|null|undefined): void { + setAttribute(el: any, name: string, value: string, namespace?: string): void { this.delegate.setAttribute(el, name, value, namespace); } - removeAttribute(el: any, name: string, namespace?: string|null|undefined): void { + removeAttribute(el: any, name: string, namespace?: string): void { this.delegate.removeAttribute(el, name, namespace); } @@ -157,37 +134,34 @@ export class BaseAnimationRenderer implements Renderer2 { removeClass(el: any, name: string): void { this.delegate.removeClass(el, name); } - setStyle(el: any, style: string, value: any, flags?: RendererStyleFlags2|undefined): void { + setStyle(el: any, style: string, value: any, flags: RendererStyleFlags2): void { this.delegate.setStyle(el, style, value, flags); } - removeStyle(el: any, style: string, flags?: RendererStyleFlags2|undefined): void { + removeStyle(el: any, style: string, flags: RendererStyleFlags2): void { this.delegate.removeStyle(el, style, flags); } - setProperty(el: any, name: string, value: any): void { - this.delegate.setProperty(el, name, value); - } - setValue(node: any, value: string): void { this.delegate.setValue(node, value); } - listen(target: any, eventName: string, callback: (event: any) => boolean | void): () => void { - return this.delegate.listen(target, eventName, callback); + appendChild(parent: any, newChild: any): void { + this.delegate.appendChild(parent, newChild); + this._engine.onInsert(this._namespaceId, newChild, parent, false); } -} -export class AnimationRenderer extends BaseAnimationRenderer implements Renderer2 { - constructor( - public factory: AnimationRendererFactory, namespaceId: string, delegate: Renderer2, - engine: AnimationEngine) { - super(namespaceId, delegate, engine); - this.namespaceId = namespaceId; + insertBefore(parent: any, newChild: any, refChild: any): void { + this.delegate.insertBefore(parent, newChild, refChild); + this._engine.onInsert(this._namespaceId, newChild, parent, true); + } + + removeChild(parent: any, oldChild: any): void { + this._engine.onRemove(this._namespaceId, oldChild, this.delegate); } setProperty(el: any, name: string, value: any): void { if (name.charAt(0) == '@') { name = name.substr(1); - this.engine.setProperty(this.namespaceId, el, name, value); + this._engine.setProperty(this._namespaceId, el, name, value); } else { this.delegate.setProperty(el, name, value); } @@ -202,9 +176,9 @@ export class AnimationRenderer extends BaseAnimationRenderer implements Renderer if (name.charAt(0) != '@') { // transition-specific [name, phase] = parseTriggerCallbackName(name); } - return this.engine.listen(this.namespaceId, element, name, phase, event => { + return this._engine.listen(this._namespaceId, element, name, phase, event => { const countId = (event as any)['_data'] || -1; - this.factory.scheduleListenerCallback(countId, callback, event); + this._factory.scheduleListenerCallback(countId, callback, event); }); } return this.delegate.listen(target, eventName, callback);