refactor(ivy): separate first creation pass in the elementContainerStart instruction (#33894)

PR Close #33894
This commit is contained in:
Pawel Kozlowski 2019-11-18 15:07:25 +01:00 committed by Alex Rickabaugh
parent 96499c898f
commit c44415494a
1 changed files with 37 additions and 29 deletions

View File

@ -9,9 +9,9 @@ import {assertDataInRange, assertEqual} from '../../util/assert';
import {assertHasParent} from '../assert'; import {assertHasParent} from '../assert';
import {attachPatchData} from '../context_discovery'; import {attachPatchData} from '../context_discovery';
import {registerPostOrderHooks} from '../hooks'; 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 {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 {assertNodeType} from '../node_assert';
import {appendChild} from '../node_manipulation'; import {appendChild} from '../node_manipulation';
import {getBindingIndex, getIsParent, getLView, getPreviousOrParentTNode, setIsNotParent, setPreviousOrParentTNode} from '../state'; 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 {createDirectivesInstances, executeContentQueries, getOrCreateTNode, resolveDirectives, saveResolvedLocalsInData} from './shared';
import {registerInitialStylingOnTNode} from './styling'; 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<TAttributes>(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<string[]>(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 (<ng-container>) backed by a comment node in the DOM. * Creates a logical container for other nodes (<ng-container>) backed by a comment node in the DOM.
@ -40,46 +64,30 @@ export function ɵɵelementContainerStart(
index: number, attrsIndex?: number | null, localRefsIndex?: number): void { index: number, attrsIndex?: number | null, localRefsIndex?: number): void {
const lView = getLView(); const lView = getLView();
const tView = lView[TVIEW]; const tView = lView[TVIEW];
const renderer = lView[RENDERER]; const adjustedIndex = index + HEADER_OFFSET;
const tagName = 'ng-container';
const tViewConsts = tView.consts; ngDevMode && assertDataInRange(lView, adjustedIndex);
const attrs = getConstant<TAttributes>(tViewConsts, attrsIndex);
const localRefs = getConstant<string[]>(tViewConsts, localRefsIndex);
ngDevMode && assertEqual( ngDevMode && assertEqual(
getBindingIndex(), tView.bindingStartIndex, getBindingIndex(), tView.bindingStartIndex,
'element containers should be created before any bindings'); '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 && ngDevMode.rendererCreateComment++;
ngDevMode && assertDataInRange(lView, index + HEADER_OFFSET); const native = lView[adjustedIndex] =
const native = lView[index + HEADER_OFFSET] = renderer.createComment(ngDevMode ? tagName : ''); lView[RENDERER].createComment(ngDevMode ? 'ng-container' : '');
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);
}
appendChild(native, tNode, lView); appendChild(native, tNode, lView);
attachPatchData(native, 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)) { if (isDirectiveHost(tNode)) {
createDirectivesInstances(tView, lView, tNode); createDirectivesInstances(tView, lView, tNode);
executeContentQueries(tView, tNode, lView); executeContentQueries(tView, tNode, lView);
} }
if (localRefs != null) { if (localRefsIndex != null) {
saveResolvedLocalsInData(lView, tNode); saveResolvedLocalsInData(lView, tNode);
} }
} }