From c44415494ab34dcb5c71b8466ecda517d256b7b0 Mon Sep 17 00:00:00 2001 From: Pawel Kozlowski Date: Mon, 18 Nov 2019 15:07:25 +0100 Subject: [PATCH] refactor(ivy): separate first creation pass in the elementContainerStart instruction (#33894) PR Close #33894 --- .../render3/instructions/element_container.ts | 66 +++++++++++-------- 1 file changed, 37 insertions(+), 29 deletions(-) diff --git a/packages/core/src/render3/instructions/element_container.ts b/packages/core/src/render3/instructions/element_container.ts index 4752b22097..8456ad1ff9 100644 --- a/packages/core/src/render3/instructions/element_container.ts +++ b/packages/core/src/render3/instructions/element_container.ts @@ -9,9 +9,9 @@ import {assertDataInRange, assertEqual} from '../../util/assert'; import {assertHasParent} from '../assert'; import {attachPatchData} from '../context_discovery'; import {registerPostOrderHooks} from '../hooks'; -import {TAttributes, TNodeType} from '../interfaces/node'; +import {TAttributes, TElementContainerNode, TNodeType} from '../interfaces/node'; import {isContentQueryHost, isDirectiveHost} from '../interfaces/type_checks'; -import {HEADER_OFFSET, RENDERER, TVIEW, T_HOST} from '../interfaces/view'; +import {HEADER_OFFSET, LView, RENDERER, TVIEW, TView, T_HOST} from '../interfaces/view'; import {assertNodeType} from '../node_assert'; import {appendChild} from '../node_manipulation'; import {getBindingIndex, getIsParent, getLView, getPreviousOrParentTNode, setIsNotParent, setPreviousOrParentTNode} from '../state'; @@ -20,7 +20,31 @@ import {getConstant} from '../util/view_utils'; import {createDirectivesInstances, executeContentQueries, getOrCreateTNode, resolveDirectives, saveResolvedLocalsInData} from './shared'; import {registerInitialStylingOnTNode} from './styling'; +function elementContainerStartFirstCreatePass( + index: number, tView: TView, lView: LView, attrsIndex?: number | null, + localRefsIndex?: number): TElementContainerNode { + ngDevMode && ngDevMode.firstCreatePass++; + const tViewConsts = tView.consts; + const attrs = getConstant(tViewConsts, attrsIndex); + const tNode = getOrCreateTNode( + tView, lView[T_HOST], index, TNodeType.ElementContainer, 'ng-container', attrs); + + // While ng-container doesn't necessarily support styling, we use the style context to identify + // and execute directives on the ng-container. + if (attrs !== null) { + registerInitialStylingOnTNode(tNode, attrs, 0); + } + + const localRefs = getConstant(tViewConsts, localRefsIndex); + resolveDirectives(tView, lView, tNode, localRefs); + + if (tView.queries !== null) { + tView.queries.elementStart(tView, tNode); + } + + return tNode; +} /** * Creates a logical container for other nodes () backed by a comment node in the DOM. @@ -40,46 +64,30 @@ export function ɵɵelementContainerStart( index: number, attrsIndex?: number | null, localRefsIndex?: number): void { const lView = getLView(); const tView = lView[TVIEW]; - const renderer = lView[RENDERER]; - const tagName = 'ng-container'; - const tViewConsts = tView.consts; - const attrs = getConstant(tViewConsts, attrsIndex); - const localRefs = getConstant(tViewConsts, localRefsIndex); + const adjustedIndex = index + HEADER_OFFSET; + + ngDevMode && assertDataInRange(lView, adjustedIndex); ngDevMode && assertEqual( getBindingIndex(), tView.bindingStartIndex, 'element containers should be created before any bindings'); + const tNode = tView.firstCreatePass ? + elementContainerStartFirstCreatePass(index, tView, lView, attrsIndex, localRefsIndex) : + tView.data[adjustedIndex] as TElementContainerNode; + setPreviousOrParentTNode(tNode, true); + ngDevMode && ngDevMode.rendererCreateComment++; - ngDevMode && assertDataInRange(lView, index + HEADER_OFFSET); - const native = lView[index + HEADER_OFFSET] = renderer.createComment(ngDevMode ? tagName : ''); - - ngDevMode && assertDataInRange(lView, index - 1); - const tNode = - getOrCreateTNode(tView, lView[T_HOST], index, TNodeType.ElementContainer, tagName, attrs); - - if (attrs && tView.firstCreatePass) { - // While ng-container doesn't necessarily support styling, we use the style context to identify - // and execute directives on the ng-container. - registerInitialStylingOnTNode(tNode, attrs, 0); - } - + const native = lView[adjustedIndex] = + lView[RENDERER].createComment(ngDevMode ? 'ng-container' : ''); appendChild(native, tNode, lView); attachPatchData(native, lView); - if (tView.firstCreatePass) { - ngDevMode && ngDevMode.firstCreatePass++; - resolveDirectives(tView, lView, tNode, localRefs); - if (tView.queries) { - tView.queries.elementStart(tView, tNode); - } - } - if (isDirectiveHost(tNode)) { createDirectivesInstances(tView, lView, tNode); executeContentQueries(tView, tNode, lView); } - if (localRefs != null) { + if (localRefsIndex != null) { saveResolvedLocalsInData(lView, tNode); } }