diff --git a/packages/core/src/render3/component.ts b/packages/core/src/render3/component.ts index 9e92995877..2895e71664 100644 --- a/packages/core/src/render3/component.ts +++ b/packages/core/src/render3/component.ts @@ -144,9 +144,9 @@ export function renderComponent( componentView, componentDef, rootView, rootContext, opts.hostFeatures || null); // create mode pass - renderView(rootView, rootTView, null); + renderView(rootTView, rootView, null); // update mode pass - refreshView(rootView, rootTView, null, null); + refreshView(rootTView, rootView, null, null); } finally { leaveView(); diff --git a/packages/core/src/render3/component_ref.ts b/packages/core/src/render3/component_ref.ts index 2b9b21c286..4045132cf0 100644 --- a/packages/core/src/render3/component_ref.ts +++ b/packages/core/src/render3/component_ref.ts @@ -174,7 +174,7 @@ export class ComponentFactory extends viewEngine_ComponentFactory { const componentView = createRootComponentView( hostRNode, this.componentDef, rootLView, rendererFactory, hostRenderer, addVersion, null); - tElementNode = getTNode(0, rootLView) as TElementNode; + tElementNode = getTNode(rootLView[TVIEW], 0) as TElementNode; if (projectableNodes) { // projectable nodes can be passed as array of arrays or an array of iterables (ngUpgrade @@ -190,7 +190,7 @@ export class ComponentFactory extends viewEngine_ComponentFactory { component = createRootComponent( componentView, this.componentDef, rootLView, rootContext, [LifecycleHooksFeature]); - renderView(rootLView, rootTView, null); + renderView(rootTView, rootLView, null); } finally { leaveView(); } diff --git a/packages/core/src/render3/di_setup.ts b/packages/core/src/render3/di_setup.ts index e0815cc58b..1666dbcae5 100644 --- a/packages/core/src/render3/di_setup.ts +++ b/packages/core/src/render3/di_setup.ts @@ -18,7 +18,7 @@ import {NodeInjectorFactory} from './interfaces/injector'; import {TContainerNode, TDirectiveHostNode, TElementContainerNode, TElementNode, TNodeProviderIndexes} from './interfaces/node'; import {isComponentDef} from './interfaces/type_checks'; import {LView, TData, TVIEW, TView} from './interfaces/view'; -import {getLView, getPreviousOrParentTNode} from './state'; +import {getLView, getPreviousOrParentTNode, getTView} from './state'; @@ -42,8 +42,7 @@ import {getLView, getPreviousOrParentTNode} from './state'; */ export function providersResolver( def: DirectiveDef, providers: Provider[], viewProviders: Provider[]): void { - const lView = getLView(); - const tView: TView = lView[TVIEW]; + const tView = getTView(); if (tView.firstCreatePass) { const isComponent = isComponentDef(def); @@ -71,8 +70,8 @@ function resolveProvider( provider[i], tInjectables, lInjectablesBlueprint, isComponent, isViewProvider); } } else { + const tView = getTView(); const lView = getLView(); - const tView = lView[TVIEW]; let token: any = isTypeProvider(provider) ? provider : resolveForwardRef(provider.provide); let providerFactory: () => any = providerToFactory(provider); diff --git a/packages/core/src/render3/i18n.ts b/packages/core/src/render3/i18n.ts index e4f4366dba..a679190614 100644 --- a/packages/core/src/render3/i18n.ts +++ b/packages/core/src/render3/i18n.ts @@ -13,7 +13,6 @@ import {InertBodyHelper} from '../sanitization/inert_body'; import {_sanitizeUrl, sanitizeSrcset} from '../sanitization/url_sanitizer'; import {addAllToArray} from '../util/array_utils'; import {assertDataInRange, assertDefined, assertEqual} from '../util/assert'; - import {bindingUpdated} from './bindings'; import {attachPatchData} from './context_discovery'; import {setDelayProjection} from './instructions/all'; @@ -28,7 +27,7 @@ import {SanitizerFn} from './interfaces/sanitization'; import {isLContainer} from './interfaces/type_checks'; import {HEADER_OFFSET, LView, RENDERER, TVIEW, TView, T_HOST} from './interfaces/view'; import {appendChild, applyProjection, createTextNode, nativeRemoveNode} from './node_manipulation'; -import {getBindingIndex, getIsParent, getLView, getPreviousOrParentTNode, nextBindingIndex, setIsNotParent, setPreviousOrParentTNode} from './state'; +import {getBindingIndex, getIsParent, getLView, getPreviousOrParentTNode, getTView, nextBindingIndex, setIsNotParent, setPreviousOrParentTNode} from './state'; import {renderStringify} from './util/misc_utils'; import {getNativeByIndex, getNativeByTNode, getTNode, load} from './util/view_utils'; @@ -360,14 +359,13 @@ const parentIndexStack: number[] = []; * @codeGenApi */ export function ɵɵi18nStart(index: number, message: string, subTemplateIndex?: number): void { - const lView = getLView(); - const tView = lView[TVIEW]; + const tView = getTView(); ngDevMode && assertDefined(tView, `tView should be defined`); i18nIndexStack[++i18nIndexStackPointer] = index; // We need to delay projections until `i18nEnd` setDelayProjection(true); if (tView.firstCreatePass && tView.data[index + HEADER_OFFSET] === null) { - i18nStartFirstPass(lView, tView, index, message, subTemplateIndex); + i18nStartFirstPass(getLView(), tView, index, message, subTemplateIndex); } } @@ -471,7 +469,7 @@ function i18nStartFirstPass( } if (i18nVarsCount > 0) { - allocExpando(lView, i18nVarsCount); + allocExpando(tView, lView, i18nVarsCount); } ngDevMode && @@ -490,7 +488,8 @@ function i18nStartFirstPass( } function appendI18nNode( - tNode: TNode, parentTNode: TNode, previousTNode: TNode | null, lView: LView): TNode { + tView: TView, tNode: TNode, parentTNode: TNode, previousTNode: TNode | null, + lView: LView): TNode { ngDevMode && ngDevMode.rendererMoveNode++; const nextNode = tNode.next; if (!previousTNode) { @@ -523,16 +522,16 @@ function appendI18nNode( // If the placeholder to append is a projection, we need to move the projected nodes instead if (tNode.type === TNodeType.Projection) { - applyProjection(lView, tNode as TProjectionNode); + applyProjection(tView, lView, tNode as TProjectionNode); return tNode; } - appendChild(getNativeByTNode(tNode, lView), tNode, lView); + appendChild(tView, lView, getNativeByTNode(tNode, lView), tNode); const slotValue = lView[tNode.index]; if (tNode.type !== TNodeType.Container && isLContainer(slotValue)) { // Nodes that inject ViewContainerRef also have a comment node that should be moved - appendChild(slotValue[NATIVE], tNode, lView); + appendChild(tView, lView, slotValue[NATIVE], tNode); } return tNode; } @@ -657,9 +656,9 @@ export function ɵɵi18nPostprocess( */ export function ɵɵi18nEnd(): void { const lView = getLView(); - const tView = lView[TVIEW]; + const tView = getTView(); ngDevMode && assertDefined(tView, `tView should be defined`); - i18nEndFirstPass(lView, tView); + i18nEndFirstPass(tView, lView); // Stop delaying projections setDelayProjection(false); } @@ -667,7 +666,7 @@ export function ɵɵi18nEnd(): void { /** * See `i18nEnd` above. */ -function i18nEndFirstPass(lView: LView, tView: TView) { +function i18nEndFirstPass(tView: TView, lView: LView) { ngDevMode && assertEqual( getBindingIndex(), tView.bindingStartIndex, 'i18nEnd should be called before any binding'); @@ -680,16 +679,16 @@ function i18nEndFirstPass(lView: LView, tView: TView) { const lastCreatedNode = getPreviousOrParentTNode(); // Read the instructions to insert/move/remove DOM elements - const visitedNodes = readCreateOpCodes(rootIndex, tI18n.create, lView); + const visitedNodes = readCreateOpCodes(rootIndex, tI18n.create, tView, lView); // Remove deleted nodes let index = rootIndex + 1; while (index <= lastCreatedNode.index - HEADER_OFFSET) { if (visitedNodes.indexOf(index) === -1) { - removeNode(index, lView, /* markAsDetached */ true); + removeNode(tView, lView, index, /* markAsDetached */ true); } // Check if an element has any local refs and skip them - const tNode = getTNode(index, lView); + const tNode = getTNode(tView, index); if (tNode && (tNode.type === TNodeType.Element || tNode.type === TNodeType.ElementContainer) && tNode.localNames !== null) { // Divide by 2 to get the number of local refs, @@ -705,12 +704,12 @@ function i18nEndFirstPass(lView: LView, tView: TView) { * Creates and stores the dynamic TNode, and unhooks it from the tree for now. */ function createDynamicNodeAtIndex( - lView: LView, index: number, type: TNodeType, native: RElement | RText | null, + tView: TView, lView: LView, index: number, type: TNodeType, native: RElement | RText | null, name: string | null): TElementNode|TIcuContainerNode { const previousOrParentTNode = getPreviousOrParentTNode(); ngDevMode && assertDataInRange(lView, index + HEADER_OFFSET); lView[index + HEADER_OFFSET] = native; - const tNode = getOrCreateTNode(lView[TVIEW], lView[T_HOST], index, type as any, name, null); + const tNode = getOrCreateTNode(tView, lView[T_HOST], index, type as any, name, null); // We are creating a dynamic node, the previous tNode might not be pointing at this node. // We will link ourselves into the tree later with `appendI18nNode`. @@ -722,7 +721,7 @@ function createDynamicNodeAtIndex( } function readCreateOpCodes( - index: number, createOpCodes: I18nMutateOpCodes, lView: LView): number[] { + index: number, createOpCodes: I18nMutateOpCodes, tView: TView, lView: LView): number[] { const renderer = lView[RENDERER]; let currentTNode: TNode|null = null; let previousTNode: TNode|null = null; @@ -735,7 +734,7 @@ function readCreateOpCodes( ngDevMode && ngDevMode.rendererCreateTextNode++; previousTNode = currentTNode; currentTNode = - createDynamicNodeAtIndex(lView, textNodeIndex, TNodeType.Element, textRNode, null); + createDynamicNodeAtIndex(tView, lView, textNodeIndex, TNodeType.Element, textRNode, null); visitedNodes.push(textNodeIndex); setIsNotParent(); } else if (typeof opCode == 'number') { @@ -748,26 +747,27 @@ function readCreateOpCodes( // top-level node and we should use the host node instead destinationTNode = lView[T_HOST] !; } else { - destinationTNode = getTNode(destinationNodeIndex, lView); + destinationTNode = getTNode(tView, destinationNodeIndex); } ngDevMode && assertDefined( currentTNode !, `You need to create or select a node before you can insert it into the DOM`); - previousTNode = appendI18nNode(currentTNode !, destinationTNode, previousTNode, lView); + previousTNode = + appendI18nNode(tView, currentTNode !, destinationTNode, previousTNode, lView); break; case I18nMutateOpCode.Select: const nodeIndex = opCode >>> I18nMutateOpCode.SHIFT_REF; visitedNodes.push(nodeIndex); previousTNode = currentTNode; - currentTNode = getTNode(nodeIndex, lView); + currentTNode = getTNode(tView, nodeIndex); if (currentTNode) { setPreviousOrParentTNode(currentTNode, currentTNode.type === TNodeType.Element); } break; case I18nMutateOpCode.ElementEnd: const elementIndex = opCode >>> I18nMutateOpCode.SHIFT_REF; - previousTNode = currentTNode = getTNode(elementIndex, lView); + previousTNode = currentTNode = getTNode(tView, elementIndex); setPreviousOrParentTNode(currentTNode, false); break; case I18nMutateOpCode.Attr: @@ -776,7 +776,7 @@ function readCreateOpCodes( const attrValue = createOpCodes[++i] as string; // This code is used for ICU expressions only, since we don't support // directives/components in ICUs, we don't need to worry about inputs here - elementAttributeInternal(elementNodeIndex, attrName, attrValue, lView); + elementAttributeInternal(elementNodeIndex, attrName, attrValue, tView, lView); break; default: throw new Error(`Unable to determine the type of mutate operation for "${opCode}"`); @@ -793,7 +793,7 @@ function readCreateOpCodes( ngDevMode && ngDevMode.rendererCreateComment++; previousTNode = currentTNode; currentTNode = createDynamicNodeAtIndex( - lView, commentNodeIndex, TNodeType.IcuContainer, commentRNode, null); + tView, lView, commentNodeIndex, TNodeType.IcuContainer, commentRNode, null); visitedNodes.push(commentNodeIndex); attachPatchData(commentRNode, lView); (currentTNode as TIcuContainerNode).activeCaseIndex = null; @@ -810,7 +810,7 @@ function readCreateOpCodes( ngDevMode && ngDevMode.rendererCreateElement++; previousTNode = currentTNode; currentTNode = createDynamicNodeAtIndex( - lView, elementNodeIndex, TNodeType.Element, elementRNode, tagNameValue); + tView, lView, elementNodeIndex, TNodeType.Element, elementRNode, tagNameValue); visitedNodes.push(elementNodeIndex); break; default: @@ -826,7 +826,7 @@ function readCreateOpCodes( function readUpdateOpCodes( updateOpCodes: I18nUpdateOpCodes, icus: TIcu[] | null, bindingsStartIndex: number, - changeMask: number, viewData: LView, bypassCheckBit = false) { + changeMask: number, tView: TView, lView: LView, bypassCheckBit = false) { let caseCreated = false; for (let i = 0; i < updateOpCodes.length; i++) { // bit code to check if we should apply the next update @@ -843,7 +843,7 @@ function readUpdateOpCodes( } else if (typeof opCode == 'number') { if (opCode < 0) { // It's a binding index whose value is negative - value += renderStringify(viewData[bindingsStartIndex - opCode]); + value += renderStringify(lView[bindingsStartIndex - opCode]); } else { const nodeIndex = opCode >>> I18nUpdateOpCode.SHIFT_REF; let tIcuIndex: number; @@ -853,15 +853,15 @@ function readUpdateOpCodes( case I18nUpdateOpCode.Attr: const propName = updateOpCodes[++j] as string; const sanitizeFn = updateOpCodes[++j] as SanitizerFn | null; - elementPropertyInternal(viewData, nodeIndex, propName, value, sanitizeFn); + elementPropertyInternal(tView, lView, nodeIndex, propName, value, sanitizeFn); break; case I18nUpdateOpCode.Text: - textBindingInternal(viewData, nodeIndex, value); + textBindingInternal(lView, nodeIndex, value); break; case I18nUpdateOpCode.IcuSwitch: tIcuIndex = updateOpCodes[++j] as number; tIcu = icus ![tIcuIndex]; - icuTNode = getTNode(nodeIndex, viewData) as TIcuContainerNode; + icuTNode = getTNode(tView, nodeIndex) as TIcuContainerNode; // If there is an active case, delete the old nodes if (icuTNode.activeCaseIndex !== null) { const removeCodes = tIcu.remove[icuTNode.activeCaseIndex]; @@ -873,13 +873,13 @@ function readUpdateOpCodes( // Remove DOM element, but do *not* mark TNode as detached, since we are // just switching ICU cases (while keeping the same TNode), so a DOM element // representing a new ICU case will be re-created. - removeNode(nodeIndex, viewData, /* markAsDetached */ false); + removeNode(tView, lView, nodeIndex, /* markAsDetached */ false); break; case I18nMutateOpCode.RemoveNestedIcu: const nestedIcuNodeIndex = removeCodes[k + 1] as number >>> I18nMutateOpCode.SHIFT_REF; const nestedIcuTNode = - getTNode(nestedIcuNodeIndex, viewData) as TIcuContainerNode; + getTNode(tView, nestedIcuNodeIndex) as TIcuContainerNode; const activeIndex = nestedIcuTNode.activeCaseIndex; if (activeIndex !== null) { const nestedIcuTIndex = removeOpCode >>> I18nMutateOpCode.SHIFT_REF; @@ -896,18 +896,18 @@ function readUpdateOpCodes( icuTNode.activeCaseIndex = caseIndex !== -1 ? caseIndex : null; if (caseIndex > -1) { // Add the nodes for the new case - readCreateOpCodes(-1, tIcu.create[caseIndex], viewData); + readCreateOpCodes(-1, tIcu.create[caseIndex], tView, lView); caseCreated = true; } break; case I18nUpdateOpCode.IcuUpdate: tIcuIndex = updateOpCodes[++j] as number; tIcu = icus ![tIcuIndex]; - icuTNode = getTNode(nodeIndex, viewData) as TIcuContainerNode; + icuTNode = getTNode(tView, nodeIndex) as TIcuContainerNode; if (icuTNode.activeCaseIndex !== null) { readUpdateOpCodes( tIcu.update[icuTNode.activeCaseIndex], icus, bindingsStartIndex, changeMask, - viewData, caseCreated); + tView, lView, caseCreated); } break; } @@ -919,18 +919,18 @@ function readUpdateOpCodes( } } -function removeNode(index: number, viewData: LView, markAsDetached: boolean) { - const removedPhTNode = getTNode(index, viewData); - const removedPhRNode = getNativeByIndex(index, viewData); +function removeNode(tView: TView, lView: LView, index: number, markAsDetached: boolean) { + const removedPhTNode = getTNode(tView, index); + const removedPhRNode = getNativeByIndex(index, lView); if (removedPhRNode) { - nativeRemoveNode(viewData[RENDERER], removedPhRNode); + nativeRemoveNode(lView[RENDERER], removedPhRNode); } - const slotValue = load(viewData, index) as RElement | RComment | LContainer; + const slotValue = load(lView, index) as RElement | RComment | LContainer; if (isLContainer(slotValue)) { const lContainer = slotValue as LContainer; if (removedPhTNode.type !== TNodeType.Container) { - nativeRemoveNode(viewData[RENDERER], lContainer[NATIVE]); + nativeRemoveNode(lView[RENDERER], lContainer[NATIVE]); } } @@ -982,7 +982,7 @@ export function ɵɵi18n(index: number, message: string, subTemplateIndex?: numb */ export function ɵɵi18nAttributes(index: number, values: string[]): void { const lView = getLView(); - const tView = lView[TVIEW]; + const tView = getTView(); ngDevMode && assertDefined(tView, `tView should be defined`); i18nAttributesFirstPass(lView, tView, index, values); } @@ -1014,16 +1014,16 @@ function i18nAttributesFirstPass(lView: LView, tView: TView, index: number, valu generateBindingUpdateOpCodes(value, previousElementIndex, attrName), updateOpCodes); } } else { - const tNode = getTNode(previousElementIndex, lView); + const tNode = getTNode(tView, previousElementIndex); // Set attributes for Elements only, for other types (like ElementContainer), // only set inputs below if (tNode.type === TNodeType.Element) { - elementAttributeInternal(previousElementIndex, attrName, value, lView); + elementAttributeInternal(previousElementIndex, attrName, value, tView, lView); } // Check if that attribute is a directive input const dataValue = tNode.inputs !== null && tNode.inputs[attrName]; if (dataValue) { - setInputsForProperty(lView, dataValue, attrName, value); + setInputsForProperty(tView, lView, dataValue, attrName, value); if (ngDevMode) { const element = getNativeByIndex(previousElementIndex, lView) as RElement | RComment; setNgReflectProperties(lView, element, tNode.type, dataValue, value); @@ -1071,8 +1071,7 @@ export function ɵɵi18nExp(value: T): typeof ɵɵi18nExp { */ export function ɵɵi18nApply(index: number) { if (shiftsCounter) { - const lView = getLView(); - const tView = lView[TVIEW]; + const tView = getTView(); ngDevMode && assertDefined(tView, `tView should be defined`); const tI18n = tView.data[index + HEADER_OFFSET]; let updateOpCodes: I18nUpdateOpCodes; @@ -1084,7 +1083,8 @@ export function ɵɵi18nApply(index: number) { icus = (tI18n as TI18n).icus; } const bindingsStartIndex = getBindingIndex() - shiftsCounter - 1; - readUpdateOpCodes(updateOpCodes, icus, bindingsStartIndex, changeMask, lView); + const lView = getLView(); + readUpdateOpCodes(updateOpCodes, icus, bindingsStartIndex, changeMask, tView, lView); // Reset changeMask & maskBit to default for the next update cycle changeMask = 0b0; diff --git a/packages/core/src/render3/instructions/advance.ts b/packages/core/src/render3/instructions/advance.ts index fb09a8ab41..551de37caf 100644 --- a/packages/core/src/render3/instructions/advance.ts +++ b/packages/core/src/render3/instructions/advance.ts @@ -7,9 +7,8 @@ */ import {assertDataInRange, assertGreaterThan} from '../../util/assert'; import {executeCheckHooks, executeInitAndCheckHooks} from '../hooks'; -import {FLAGS, HEADER_OFFSET, InitPhaseState, LView, LViewFlags, TVIEW} from '../interfaces/view'; -import {getCheckNoChangesMode, getLView, getSelectedIndex, setSelectedIndex} from '../state'; - +import {FLAGS, HEADER_OFFSET, InitPhaseState, LView, LViewFlags, TView} from '../interfaces/view'; +import {getCheckNoChangesMode, getLView, getSelectedIndex, getTView, setSelectedIndex} from '../state'; /** @@ -37,7 +36,7 @@ import {getCheckNoChangesMode, getLView, getSelectedIndex, setSelectedIndex} fro */ export function ɵɵadvance(delta: number): void { ngDevMode && assertGreaterThan(delta, 0, 'Can only advance forward'); - selectIndexInternal(getLView(), getSelectedIndex() + delta, getCheckNoChangesMode()); + selectIndexInternal(getTView(), getLView(), getSelectedIndex() + delta, getCheckNoChangesMode()); } /** @@ -47,10 +46,11 @@ export function ɵɵadvance(delta: number): void { */ export function ɵɵselect(index: number): void { // TODO(misko): Remove this function as it is no longer being used. - selectIndexInternal(getLView(), index, getCheckNoChangesMode()); + selectIndexInternal(getTView(), getLView(), index, getCheckNoChangesMode()); } -export function selectIndexInternal(lView: LView, index: number, checkNoChangesMode: boolean) { +export function selectIndexInternal( + tView: TView, lView: LView, index: number, checkNoChangesMode: boolean) { ngDevMode && assertGreaterThan(index, -1, 'Invalid index'); ngDevMode && assertDataInRange(lView, index + HEADER_OFFSET); @@ -60,12 +60,12 @@ export function selectIndexInternal(lView: LView, index: number, checkNoChangesM const hooksInitPhaseCompleted = (lView[FLAGS] & LViewFlags.InitPhaseStateMask) === InitPhaseState.InitPhaseCompleted; if (hooksInitPhaseCompleted) { - const preOrderCheckHooks = lView[TVIEW].preOrderCheckHooks; + const preOrderCheckHooks = tView.preOrderCheckHooks; if (preOrderCheckHooks !== null) { executeCheckHooks(lView, preOrderCheckHooks, index); } } else { - const preOrderHooks = lView[TVIEW].preOrderHooks; + const preOrderHooks = tView.preOrderHooks; if (preOrderHooks !== null) { executeInitAndCheckHooks(lView, preOrderHooks, InitPhaseState.OnInitHooksToBeRun, index); } diff --git a/packages/core/src/render3/instructions/attribute.ts b/packages/core/src/render3/instructions/attribute.ts index b3d0442f27..13641efd82 100644 --- a/packages/core/src/render3/instructions/attribute.ts +++ b/packages/core/src/render3/instructions/attribute.ts @@ -7,9 +7,7 @@ */ import {bindingUpdated} from '../bindings'; import {SanitizerFn} from '../interfaces/sanitization'; -import {TVIEW} from '../interfaces/view'; -import {getLView, getSelectedIndex, nextBindingIndex} from '../state'; - +import {getLView, getSelectedIndex, getTView, nextBindingIndex} from '../state'; import {elementAttributeInternal, storePropertyBindingMetadata} from './shared'; @@ -34,9 +32,9 @@ export function ɵɵattribute( const bindingIndex = nextBindingIndex(); if (bindingUpdated(lView, bindingIndex, value)) { const nodeIndex = getSelectedIndex(); - elementAttributeInternal(nodeIndex, name, value, lView, sanitizer, namespace); - ngDevMode && - storePropertyBindingMetadata(lView[TVIEW].data, nodeIndex, 'attr.' + name, bindingIndex); + const tView = getTView(); + elementAttributeInternal(nodeIndex, name, value, tView, lView, sanitizer, namespace); + ngDevMode && storePropertyBindingMetadata(tView.data, nodeIndex, 'attr.' + name, bindingIndex); } return ɵɵattribute; } diff --git a/packages/core/src/render3/instructions/attribute_interpolation.ts b/packages/core/src/render3/instructions/attribute_interpolation.ts index 34ea69f205..1f83b7e817 100644 --- a/packages/core/src/render3/instructions/attribute_interpolation.ts +++ b/packages/core/src/render3/instructions/attribute_interpolation.ts @@ -6,10 +6,8 @@ * found in the LICENSE file at https://angular.io/license */ import {SanitizerFn} from '../interfaces/sanitization'; -import {TVIEW} from '../interfaces/view'; -import {getBindingIndex, getLView, getSelectedIndex} from '../state'; +import {getBindingIndex, getLView, getSelectedIndex, getTView} from '../state'; import {NO_CHANGE} from '../tokens'; - import {interpolation1, interpolation2, interpolation3, interpolation4, interpolation5, interpolation6, interpolation7, interpolation8, interpolationV} from './interpolation'; import {elementAttributeInternal, storePropertyBindingMetadata} from './shared'; @@ -46,10 +44,12 @@ export function ɵɵattributeInterpolate1( const interpolatedValue = interpolation1(lView, prefix, v0, suffix); if (interpolatedValue !== NO_CHANGE) { const nodeIndex = getSelectedIndex(); - elementAttributeInternal(nodeIndex, attrName, interpolatedValue, lView, sanitizer, namespace); - ngDevMode && storePropertyBindingMetadata( - lView[TVIEW].data, nodeIndex, 'attr.' + attrName, getBindingIndex() - 1, - prefix, suffix); + const tView = getTView(); + elementAttributeInternal( + nodeIndex, attrName, interpolatedValue, tView, lView, sanitizer, namespace); + ngDevMode && + storePropertyBindingMetadata( + tView.data, nodeIndex, 'attr.' + attrName, getBindingIndex() - 1, prefix, suffix); } return ɵɵattributeInterpolate1; } @@ -87,10 +87,12 @@ export function ɵɵattributeInterpolate2( const interpolatedValue = interpolation2(lView, prefix, v0, i0, v1, suffix); if (interpolatedValue !== NO_CHANGE) { const nodeIndex = getSelectedIndex(); - elementAttributeInternal(nodeIndex, attrName, interpolatedValue, lView, sanitizer, namespace); - ngDevMode && storePropertyBindingMetadata( - lView[TVIEW].data, nodeIndex, 'attr.' + attrName, getBindingIndex() - 2, - prefix, i0, suffix); + const tView = getTView(); + elementAttributeInternal( + nodeIndex, attrName, interpolatedValue, tView, lView, sanitizer, namespace); + ngDevMode && + storePropertyBindingMetadata( + tView.data, nodeIndex, 'attr.' + attrName, getBindingIndex() - 2, prefix, i0, suffix); } return ɵɵattributeInterpolate2; } @@ -131,10 +133,12 @@ export function ɵɵattributeInterpolate3( const interpolatedValue = interpolation3(lView, prefix, v0, i0, v1, i1, v2, suffix); if (interpolatedValue !== NO_CHANGE) { const nodeIndex = getSelectedIndex(); - elementAttributeInternal(nodeIndex, attrName, interpolatedValue, lView, sanitizer, namespace); + const tView = getTView(); + elementAttributeInternal( + nodeIndex, attrName, interpolatedValue, tView, lView, sanitizer, namespace); ngDevMode && storePropertyBindingMetadata( - lView[TVIEW].data, nodeIndex, 'attr.' + attrName, getBindingIndex() - 3, - prefix, i0, i1, suffix); + tView.data, nodeIndex, 'attr.' + attrName, getBindingIndex() - 3, prefix, i0, + i1, suffix); } return ɵɵattributeInterpolate3; } @@ -178,10 +182,12 @@ export function ɵɵattributeInterpolate4( const interpolatedValue = interpolation4(lView, prefix, v0, i0, v1, i1, v2, i2, v3, suffix); if (interpolatedValue !== NO_CHANGE) { const nodeIndex = getSelectedIndex(); - elementAttributeInternal(nodeIndex, attrName, interpolatedValue, lView, sanitizer, namespace); + const tView = getTView(); + elementAttributeInternal( + nodeIndex, attrName, interpolatedValue, tView, lView, sanitizer, namespace); ngDevMode && storePropertyBindingMetadata( - lView[TVIEW].data, nodeIndex, 'attr.' + attrName, getBindingIndex() - 4, - prefix, i0, i1, i2, suffix); + tView.data, nodeIndex, 'attr.' + attrName, getBindingIndex() - 4, prefix, i0, + i1, i2, suffix); } return ɵɵattributeInterpolate4; } @@ -228,10 +234,12 @@ export function ɵɵattributeInterpolate5( interpolation5(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix); if (interpolatedValue !== NO_CHANGE) { const nodeIndex = getSelectedIndex(); - elementAttributeInternal(nodeIndex, attrName, interpolatedValue, lView, sanitizer, namespace); + const tView = getTView(); + elementAttributeInternal( + nodeIndex, attrName, interpolatedValue, tView, lView, sanitizer, namespace); ngDevMode && storePropertyBindingMetadata( - lView[TVIEW].data, nodeIndex, 'attr.' + attrName, getBindingIndex() - 5, - prefix, i0, i1, i2, i3, suffix); + tView.data, nodeIndex, 'attr.' + attrName, getBindingIndex() - 5, prefix, i0, + i1, i2, i3, suffix); } return ɵɵattributeInterpolate5; } @@ -280,10 +288,12 @@ export function ɵɵattributeInterpolate6( interpolation6(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix); if (interpolatedValue !== NO_CHANGE) { const nodeIndex = getSelectedIndex(); - elementAttributeInternal(nodeIndex, attrName, interpolatedValue, lView, sanitizer, namespace); + const tView = getTView(); + elementAttributeInternal( + nodeIndex, attrName, interpolatedValue, tView, lView, sanitizer, namespace); ngDevMode && storePropertyBindingMetadata( - lView[TVIEW].data, nodeIndex, 'attr.' + attrName, getBindingIndex() - 6, - prefix, i0, i1, i2, i3, i4, suffix); + tView.data, nodeIndex, 'attr.' + attrName, getBindingIndex() - 6, prefix, i0, + i1, i2, i3, i4, suffix); } return ɵɵattributeInterpolate6; } @@ -334,10 +344,12 @@ export function ɵɵattributeInterpolate7( interpolation7(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix); if (interpolatedValue !== NO_CHANGE) { const nodeIndex = getSelectedIndex(); - elementAttributeInternal(nodeIndex, attrName, interpolatedValue, lView, sanitizer, namespace); + const tView = getTView(); + elementAttributeInternal( + nodeIndex, attrName, interpolatedValue, tView, lView, sanitizer, namespace); ngDevMode && storePropertyBindingMetadata( - lView[TVIEW].data, nodeIndex, 'attr.' + attrName, getBindingIndex() - 7, - prefix, i0, i1, i2, i3, i4, i5, suffix); + tView.data, nodeIndex, 'attr.' + attrName, getBindingIndex() - 7, prefix, i0, + i1, i2, i3, i4, i5, suffix); } return ɵɵattributeInterpolate7; } @@ -390,10 +402,12 @@ export function ɵɵattributeInterpolate8( lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix); if (interpolatedValue !== NO_CHANGE) { const nodeIndex = getSelectedIndex(); - elementAttributeInternal(nodeIndex, attrName, interpolatedValue, lView, sanitizer, namespace); + const tView = getTView(); + elementAttributeInternal( + nodeIndex, attrName, interpolatedValue, tView, lView, sanitizer, namespace); ngDevMode && storePropertyBindingMetadata( - lView[TVIEW].data, nodeIndex, 'attr.' + attrName, getBindingIndex() - 8, - prefix, i0, i1, i2, i3, i4, i5, i6, suffix); + tView.data, nodeIndex, 'attr.' + attrName, getBindingIndex() - 8, prefix, i0, + i1, i2, i3, i4, i5, i6, suffix); } return ɵɵattributeInterpolate8; } @@ -430,15 +444,16 @@ export function ɵɵattributeInterpolateV( const lView = getLView(); const interpolated = interpolationV(lView, values); if (interpolated !== NO_CHANGE) { + const tView = getTView(); const nodeIndex = getSelectedIndex(); - elementAttributeInternal(nodeIndex, attrName, interpolated, lView, sanitizer, namespace); + elementAttributeInternal(nodeIndex, attrName, interpolated, tView, lView, sanitizer, namespace); if (ngDevMode) { const interpolationInBetween = [values[0]]; // prefix for (let i = 2; i < values.length; i += 2) { interpolationInBetween.push(values[i]); } storePropertyBindingMetadata( - lView[TVIEW].data, nodeIndex, 'attr.' + attrName, + tView.data, nodeIndex, 'attr.' + attrName, getBindingIndex() - interpolationInBetween.length + 1, ...interpolationInBetween); } } diff --git a/packages/core/src/render3/instructions/change_detection.ts b/packages/core/src/render3/instructions/change_detection.ts index 420e074b01..3a78623e3c 100644 --- a/packages/core/src/render3/instructions/change_detection.ts +++ b/packages/core/src/render3/instructions/change_detection.ts @@ -8,7 +8,7 @@ import {assertDefined} from '../../util/assert'; import {getComponentViewByInstance} from '../context_discovery'; -import {CONTEXT, RootContext, RootContextFlags} from '../interfaces/view'; +import {CONTEXT, RootContext, RootContextFlags, TVIEW} from '../interfaces/view'; import {getRootView} from '../util/view_traversal_utils'; import {detectChangesInternal, markViewDirty, scheduleTick, tickRootContext} from './shared'; @@ -21,7 +21,7 @@ import {detectChangesInternal, markViewDirty, scheduleTick, tickRootContext} fro */ export function detectChanges(component: {}): void { const view = getComponentViewByInstance(component); - detectChangesInternal(view, component); + detectChangesInternal(view[TVIEW], view, component); } /** diff --git a/packages/core/src/render3/instructions/container.ts b/packages/core/src/render3/instructions/container.ts index ef5fa7e63f..70c0ce0cd8 100644 --- a/packages/core/src/render3/instructions/container.ts +++ b/packages/core/src/render3/instructions/container.ts @@ -13,12 +13,11 @@ import {ACTIVE_INDEX, CONTAINER_HEADER_OFFSET, LContainer} from '../interfaces/c import {ComponentTemplate} from '../interfaces/definition'; import {LocalRefExtractor, TAttributes, TContainerNode, TNode, TNodeType, TViewNode} from '../interfaces/node'; import {isDirectiveHost} from '../interfaces/type_checks'; -import {FLAGS, HEADER_OFFSET, InitPhaseState, LView, LViewFlags, RENDERER, TVIEW, TView, TViewType, T_HOST} from '../interfaces/view'; +import {FLAGS, HEADER_OFFSET, InitPhaseState, LView, LViewFlags, RENDERER, TView, TViewType, T_HOST} from '../interfaces/view'; import {assertNodeType} from '../node_assert'; import {appendChild, removeView} from '../node_manipulation'; -import {getBindingIndex, getCheckNoChangesMode, getIsParent, getLView, getPreviousOrParentTNode, setIsNotParent, setPreviousOrParentTNode} from '../state'; +import {getBindingIndex, getCheckNoChangesMode, getIsParent, getLView, getPreviousOrParentTNode, getTView, setIsNotParent, setPreviousOrParentTNode} from '../state'; import {getConstant, getLContainerActiveIndex, load} from '../util/view_utils'; - import {addToViewTree, createDirectivesInstances, createLContainer, createTNode, createTView, getOrCreateTNode, resolveDirectives, saveResolvedLocalsInData} from './shared'; @@ -36,9 +35,10 @@ import {addToViewTree, createDirectivesInstances, createLContainer, createTNode, */ export function ɵɵcontainer(index: number): void { const lView = getLView(); - const tNode = containerInternal(lView, index, null, null); + const tView = getTView(); + const tNode = containerInternal(tView, lView, index, null, null); - if (lView[TVIEW].firstCreatePass) { + if (tView.firstCreatePass) { tNode.tViews = []; } setIsNotParent(); @@ -98,7 +98,7 @@ export function ɵɵtemplate( tagName?: string | null, attrsIndex?: number | null, localRefsIndex?: number | null, localRefExtractor?: LocalRefExtractor) { const lView = getLView(); - const tView = lView[TVIEW]; + const tView = getTView(); const adjustedIndex = index + HEADER_OFFSET; const tNode = tView.firstCreatePass ? @@ -108,7 +108,7 @@ export function ɵɵtemplate( setPreviousOrParentTNode(tNode, false); const comment = lView[RENDERER].createComment(ngDevMode ? 'container' : ''); - appendChild(comment, tNode, lView); + appendChild(tView, lView, comment, tNode); attachPatchData(comment, lView); addToViewTree(lView, lView[adjustedIndex] = createLContainer(comment, lView, comment, tNode)); @@ -131,7 +131,7 @@ export function ɵɵtemplate( */ export function ɵɵcontainerRefreshStart(index: number): void { const lView = getLView(); - const tView = lView[TVIEW]; + const tView = getTView(); let previousOrParentTNode = load(tView.data, index) as TNode; ngDevMode && assertNodeType(previousOrParentTNode, TNodeType.Container); setPreviousOrParentTNode(previousOrParentTNode, true); @@ -188,10 +188,10 @@ export function ɵɵcontainerRefreshEnd(): void { } function containerInternal( - lView: LView, nodeIndex: number, tagName: string | null, + tView: TView, lView: LView, nodeIndex: number, tagName: string | null, attrs: TAttributes | null): TContainerNode { ngDevMode && assertEqual( - getBindingIndex(), lView[TVIEW].bindingStartIndex, + getBindingIndex(), tView.bindingStartIndex, 'container nodes should be created before any bindings'); const adjustedIndex = nodeIndex + HEADER_OFFSET; @@ -200,10 +200,10 @@ function containerInternal( const comment = lView[adjustedIndex] = lView[RENDERER].createComment(ngDevMode ? 'container' : ''); const tNode = - getOrCreateTNode(lView[TVIEW], lView[T_HOST], nodeIndex, TNodeType.Container, tagName, attrs); + getOrCreateTNode(tView, lView[T_HOST], nodeIndex, TNodeType.Container, tagName, attrs); const lContainer = lView[adjustedIndex] = createLContainer(comment, lView, comment, tNode); - appendChild(comment, tNode, lView); + appendChild(tView, lView, comment, tNode); attachPatchData(comment, lView); // Containers are added to the current view tree instead of their embedded views diff --git a/packages/core/src/render3/instructions/element.ts b/packages/core/src/render3/instructions/element.ts index b8ac798d69..52eda6249b 100644 --- a/packages/core/src/render3/instructions/element.ts +++ b/packages/core/src/render3/instructions/element.ts @@ -16,7 +16,7 @@ import {isContentQueryHost, isDirectiveHost} from '../interfaces/type_checks'; import {HEADER_OFFSET, LView, RENDERER, TVIEW, TView, T_HOST} from '../interfaces/view'; import {assertNodeType} from '../node_assert'; import {appendChild, writeDirectClass, writeDirectStyle} from '../node_manipulation'; -import {decreaseElementDepthCount, getBindingIndex, getElementDepthCount, getIsParent, getLView, getNamespace, getPreviousOrParentTNode, increaseElementDepthCount, setIsNotParent, setPreviousOrParentTNode} from '../state'; +import {decreaseElementDepthCount, getBindingIndex, getElementDepthCount, getIsParent, getLView, getNamespace, getPreviousOrParentTNode, getTView, increaseElementDepthCount, setIsNotParent, setPreviousOrParentTNode} from '../state'; import {computeStaticStyling} from '../styling/static_styling'; import {setUpAttributes} from '../util/attrs_utils'; import {getConstant} from '../util/view_utils'; @@ -36,7 +36,7 @@ function elementStartFirstCreatePass( const hasDirectives = resolveDirectives(tView, lView, tNode, getConstant(tViewConsts, localRefsIndex)); - ngDevMode && warnAboutUnknownElement(lView, native, tNode, hasDirectives); + ngDevMode && warnAboutUnknownElement(tView, lView, native, tNode, hasDirectives); if (tNode.mergedAttrs !== null) { computeStaticStyling(tNode, tNode.mergedAttrs); @@ -66,7 +66,7 @@ function elementStartFirstCreatePass( export function ɵɵelementStart( index: number, name: string, attrsIndex?: number | null, localRefsIndex?: number): void { const lView = getLView(); - const tView = lView[TVIEW]; + const tView = getTView(); const adjustedIndex = HEADER_OFFSET + index; ngDevMode && assertEqual( @@ -96,7 +96,7 @@ export function ɵɵelementStart( writeDirectStyle(renderer, native, styles); } - appendChild(native, tNode, lView); + appendChild(tView, lView, native, tNode); // any immediate children of a component or template container must be pre-emptively // monkey-patched with the component view data so that the element can be inspected @@ -135,11 +135,10 @@ export function ɵɵelementEnd(): void { const tNode = previousOrParentTNode; ngDevMode && assertNodeType(tNode, TNodeType.Element); - const lView = getLView(); - const tView = lView[TVIEW]; decreaseElementDepthCount(); + const tView = getTView(); if (tView.firstCreatePass) { registerPostOrderHooks(tView, previousOrParentTNode); if (isContentQueryHost(previousOrParentTNode)) { @@ -148,11 +147,11 @@ export function ɵɵelementEnd(): void { } if (tNode.classes !== null && hasClassInput(tNode)) { - setDirectiveInputsWhichShadowsStyling(tNode, lView, tNode.classes, true); + setDirectiveInputsWhichShadowsStyling(tView, tNode, getLView(), tNode.classes, true); } if (tNode.styles !== null && hasStyleInput(tNode)) { - setDirectiveInputsWhichShadowsStyling(tNode, lView, tNode.styles, false); + setDirectiveInputsWhichShadowsStyling(tView, tNode, getLView(), tNode.styles, false); } } @@ -173,8 +172,8 @@ export function ɵɵelement( } function warnAboutUnknownElement( - hostView: LView, element: RElement, tNode: TNode, hasDirectives: boolean): void { - const schemas = hostView[TVIEW].schemas; + tView: TView, lView: LView, element: RElement, tNode: TNode, hasDirectives: boolean): void { + const schemas = tView.schemas; // If `schemas` is set to `null`, that's an indication that this Component was compiled in AOT // mode where this check happens at compile time. In JIT mode, `schemas` is always present and @@ -197,7 +196,7 @@ function warnAboutUnknownElement( (typeof customElements !== 'undefined' && tagName.indexOf('-') > -1 && !customElements.get(tagName)); - if (isUnknown && !matchingSchemas(hostView, tagName)) { + if (isUnknown && !matchingSchemas(tView, lView, tagName)) { let warning = `'${tagName}' is not a known element:\n`; warning += `1. If '${tagName}' is an Angular component, then verify that it is part of this module.\n`; diff --git a/packages/core/src/render3/instructions/element_container.ts b/packages/core/src/render3/instructions/element_container.ts index 509a5888f9..54f1cd9dd3 100644 --- a/packages/core/src/render3/instructions/element_container.ts +++ b/packages/core/src/render3/instructions/element_container.ts @@ -11,10 +11,10 @@ import {attachPatchData} from '../context_discovery'; import {registerPostOrderHooks} from '../hooks'; import {TAttributes, TElementContainerNode, TNodeType} from '../interfaces/node'; import {isContentQueryHost, isDirectiveHost} from '../interfaces/type_checks'; -import {HEADER_OFFSET, LView, RENDERER, TVIEW, TView, T_HOST} from '../interfaces/view'; +import {HEADER_OFFSET, LView, RENDERER, 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'; +import {getBindingIndex, getIsParent, getLView, getPreviousOrParentTNode, getTView, setIsNotParent, setPreviousOrParentTNode} from '../state'; import {computeStaticStyling} from '../styling/static_styling'; import {getConstant} from '../util/view_utils'; @@ -63,7 +63,7 @@ function elementContainerStartFirstCreatePass( export function ɵɵelementContainerStart( index: number, attrsIndex?: number | null, localRefsIndex?: number): void { const lView = getLView(); - const tView = lView[TVIEW]; + const tView = getTView(); const adjustedIndex = index + HEADER_OFFSET; ngDevMode && assertDataInRange(lView, adjustedIndex); @@ -79,7 +79,7 @@ export function ɵɵelementContainerStart( ngDevMode && ngDevMode.rendererCreateComment++; const native = lView[adjustedIndex] = lView[RENDERER].createComment(ngDevMode ? 'ng-container' : ''); - appendChild(native, tNode, lView); + appendChild(tView, lView, native, tNode); attachPatchData(native, lView); if (isDirectiveHost(tNode)) { @@ -99,8 +99,7 @@ export function ɵɵelementContainerStart( */ export function ɵɵelementContainerEnd(): void { let previousOrParentTNode = getPreviousOrParentTNode(); - const lView = getLView(); - const tView = lView[TVIEW]; + const tView = getTView(); if (getIsParent()) { setIsNotParent(); } else { diff --git a/packages/core/src/render3/instructions/embedded_view.ts b/packages/core/src/render3/instructions/embedded_view.ts index 46ef37b186..777d22911b 100644 --- a/packages/core/src/render3/instructions/embedded_view.ts +++ b/packages/core/src/render3/instructions/embedded_view.ts @@ -14,7 +14,7 @@ import {TContainerNode, TNodeType} from '../interfaces/node'; import {CONTEXT, LView, LViewFlags, PARENT, TVIEW, TView, TViewType, T_HOST} from '../interfaces/view'; import {assertNodeType} from '../node_assert'; import {insertView, removeView} from '../node_manipulation'; -import {enterView, getIsParent, getLView, getPreviousOrParentTNode, leaveView, setIsParent, setPreviousOrParentTNode} from '../state'; +import {enterView, getIsParent, getLView, getPreviousOrParentTNode, getTView, leaveView, setIsParent, setPreviousOrParentTNode} from '../state'; import {getLContainerActiveIndex, isCreationMode} from '../util/view_utils'; import {assignTViewNodeToLView, createLView, createTView, refreshView, renderView} from './shared'; @@ -58,7 +58,8 @@ export function ɵɵembeddedViewStart(viewBlockId: number, decls: number, vars: if (lContainer) { if (isCreationMode(viewToRender)) { // it is a new view, insert it into collection of views for a given container - insertView(viewToRender, lContainer, getLContainerActiveIndex(lContainer)); + insertView( + viewToRender[TVIEW], viewToRender, lContainer, getLContainerActiveIndex(lContainer)); } lContainer[ACTIVE_INDEX] += ActiveIndexFlag.INCREMENT; } @@ -128,14 +129,14 @@ function scanForView(lContainer: LContainer, startIdx: number, viewBlockId: numb */ export function ɵɵembeddedViewEnd(): void { const lView = getLView(); - const tView = lView[TVIEW]; + const tView = getTView(); const viewHost = lView[T_HOST]; const context = lView[CONTEXT]; if (isCreationMode(lView)) { - renderView(lView, tView, context); // creation mode pass + renderView(tView, lView, context); // creation mode pass } - refreshView(lView, tView, tView.template, context); // update mode pass + refreshView(tView, lView, tView.template, context); // update mode pass const lContainer = lView[PARENT] as LContainer; ngDevMode && assertLContainerOrUndefined(lContainer); diff --git a/packages/core/src/render3/instructions/host_property.ts b/packages/core/src/render3/instructions/host_property.ts index 460f45caec..3201c3ab0c 100644 --- a/packages/core/src/render3/instructions/host_property.ts +++ b/packages/core/src/render3/instructions/host_property.ts @@ -7,10 +7,8 @@ */ import {bindingUpdated} from '../bindings'; import {SanitizerFn} from '../interfaces/sanitization'; -import {TVIEW} from '../interfaces/view'; -import {getLView, getSelectedIndex, nextBindingIndex} from '../state'; +import {getLView, getSelectedIndex, getTView, nextBindingIndex} from '../state'; import {NO_CHANGE} from '../tokens'; - import {elementPropertyInternal, loadComponentRenderer, storePropertyBindingMetadata} from './shared'; /** @@ -33,8 +31,9 @@ export function ɵɵhostProperty( const bindingIndex = nextBindingIndex(); if (bindingUpdated(lView, bindingIndex, value)) { const nodeIndex = getSelectedIndex(); - elementPropertyInternal(lView, nodeIndex, propName, value, sanitizer, true); - ngDevMode && storePropertyBindingMetadata(lView[TVIEW].data, nodeIndex, propName, bindingIndex); + const tView = getTView(); + elementPropertyInternal(tView, lView, nodeIndex, propName, value, sanitizer, true); + ngDevMode && storePropertyBindingMetadata(tView.data, nodeIndex, propName, bindingIndex); } return ɵɵhostProperty; } @@ -68,9 +67,10 @@ export function ɵɵupdateSyntheticHostBinding( const bindingIndex = nextBindingIndex(); if (bindingUpdated(lView, bindingIndex, value)) { const nodeIndex = getSelectedIndex(); + const tView = getTView(); elementPropertyInternal( - lView, nodeIndex, propName, value, sanitizer, true, loadComponentRenderer); - ngDevMode && storePropertyBindingMetadata(lView[TVIEW].data, nodeIndex, propName, bindingIndex); + tView, lView, nodeIndex, propName, value, sanitizer, true, loadComponentRenderer); + ngDevMode && storePropertyBindingMetadata(tView.data, nodeIndex, propName, bindingIndex); } return ɵɵupdateSyntheticHostBinding; } diff --git a/packages/core/src/render3/instructions/listener.ts b/packages/core/src/render3/instructions/listener.ts index 07faa7eefd..981924a988 100644 --- a/packages/core/src/render3/instructions/listener.ts +++ b/packages/core/src/render3/instructions/listener.ts @@ -13,12 +13,11 @@ import {EMPTY_OBJ} from '../empty'; import {PropertyAliasValue, TNode, TNodeFlags, TNodeType} from '../interfaces/node'; import {GlobalTargetResolver, RElement, Renderer3, isProceduralRenderer} from '../interfaces/renderer'; import {isDirectiveHost} from '../interfaces/type_checks'; -import {CLEANUP, FLAGS, LView, LViewFlags, RENDERER, TVIEW} from '../interfaces/view'; +import {CLEANUP, FLAGS, LView, LViewFlags, RENDERER, TView} from '../interfaces/view'; import {assertNodeOfPossibleTypes} from '../node_assert'; -import {getLView, getPreviousOrParentTNode} from '../state'; +import {getLView, getPreviousOrParentTNode, getTView} from '../state'; import {getComponentLViewByIndex, getNativeByTNode, unwrapRNode} from '../util/view_utils'; - -import {getCleanup, handleError, loadComponentRenderer, markViewDirty} from './shared'; +import {getLCleanup, handleError, loadComponentRenderer, markViewDirty} from './shared'; @@ -40,9 +39,10 @@ export function ɵɵlistener( eventName: string, listenerFn: (e?: any) => any, useCapture = false, eventTargetResolver?: GlobalTargetResolver): typeof ɵɵlistener { const lView = getLView(); + const tView = getTView(); const tNode = getPreviousOrParentTNode(); listenerInternal( - lView, lView[RENDERER], tNode, eventName, listenerFn, useCapture, eventTargetResolver); + tView, lView, lView[RENDERER], tNode, eventName, listenerFn, useCapture, eventTargetResolver); return ɵɵlistener; } @@ -70,10 +70,12 @@ export function ɵɵlistener( export function ɵɵcomponentHostSyntheticListener( eventName: string, listenerFn: (e?: any) => any, useCapture = false, eventTargetResolver?: GlobalTargetResolver): typeof ɵɵcomponentHostSyntheticListener { - const lView = getLView(); const tNode = getPreviousOrParentTNode(); + const lView = getLView(); const renderer = loadComponentRenderer(tNode, lView); - listenerInternal(lView, renderer, tNode, eventName, listenerFn, useCapture, eventTargetResolver); + const tView = getTView(); + listenerInternal( + tView, lView, renderer, tNode, eventName, listenerFn, useCapture, eventTargetResolver); return ɵɵcomponentHostSyntheticListener; } @@ -83,8 +85,7 @@ export function ɵɵcomponentHostSyntheticListener( * are registered for a given element. */ function findExistingListener( - lView: LView, eventName: string, tNodeIdx: number): ((e?: any) => any)|null { - const tView = lView[TVIEW]; + tView: TView, lView: LView, eventName: string, tNodeIdx: number): ((e?: any) => any)|null { const tCleanup = tView.cleanup; if (tCleanup != null) { for (let i = 0; i < tCleanup.length - 1; i += 2) { @@ -111,10 +112,9 @@ function findExistingListener( } function listenerInternal( - lView: LView, renderer: Renderer3, tNode: TNode, eventName: string, + tView: TView, lView: LView, renderer: Renderer3, tNode: TNode, eventName: string, listenerFn: (e?: any) => any, useCapture = false, eventTargetResolver?: GlobalTargetResolver): void { - const tView = lView[TVIEW]; const isTNodeDirectiveHost = isDirectiveHost(tNode); const firstCreatePass = tView.firstCreatePass; const tCleanup: false|any[] = firstCreatePass && (tView.cleanup || (tView.cleanup = [])); @@ -122,7 +122,7 @@ function listenerInternal( // When the ɵɵlistener instruction was generated and is executed we know that there is either a // native listener or a directive output on this element. As such we we know that we will have to // register a listener and store its cleanup function on LView. - const lCleanup = getCleanup(lView); + const lCleanup = getLCleanup(lView); ngDevMode && assertNodeOfPossibleTypes( tNode, TNodeType.Element, TNodeType.Container, TNodeType.ElementContainer); @@ -160,7 +160,7 @@ function listenerInternal( // matching on a given node as we can't register multiple event handlers for the same event in // a template (this would mean having duplicate attributes). if (!eventTargetResolver && isTNodeDirectiveHost) { - existingListener = findExistingListener(lView, eventName, tNode.index); + existingListener = findExistingListener(tView, lView, eventName, tNode.index); } if (existingListener !== null) { // Attach a new listener to coalesced listeners list, maintaining the order in which diff --git a/packages/core/src/render3/instructions/lview_debug.ts b/packages/core/src/render3/instructions/lview_debug.ts index a0e4bb7262..a801bbe5e2 100644 --- a/packages/core/src/render3/instructions/lview_debug.ts +++ b/packages/core/src/render3/instructions/lview_debug.ts @@ -507,7 +507,7 @@ export function readLViewValue(value: any): LView|null { export class I18NDebugItem { [key: string]: any; - get tNode() { return getTNode(this.nodeIndex, this._lView); } + get tNode() { return getTNode(this._lView[TVIEW], this.nodeIndex); } constructor( public __raw_opCode: any, private _lView: LView, public nodeIndex: number, diff --git a/packages/core/src/render3/instructions/projection.ts b/packages/core/src/render3/instructions/projection.ts index 730a071a8e..b432a37d64 100644 --- a/packages/core/src/render3/instructions/projection.ts +++ b/packages/core/src/render3/instructions/projection.ts @@ -8,10 +8,10 @@ import {newArray} from '../../util/array_utils'; import {TAttributes, TElementNode, TNode, TNodeType} from '../interfaces/node'; import {ProjectionSlots} from '../interfaces/projection'; -import {DECLARATION_COMPONENT_VIEW, TVIEW, T_HOST} from '../interfaces/view'; +import {DECLARATION_COMPONENT_VIEW, T_HOST} from '../interfaces/view'; import {applyProjection} from '../node_manipulation'; import {getProjectAsAttrValue, isNodeMatchingSelectorList, isSelectorInSelectorList} from '../node_selector_matcher'; -import {getLView, setIsNotParent} from '../state'; +import {getLView, getTView, setIsNotParent} from '../state'; import {getOrCreateTNode} from './shared'; @@ -123,8 +123,9 @@ export function setDelayProjection(value: boolean) { export function ɵɵprojection( nodeIndex: number, selectorIndex: number = 0, attrs?: TAttributes): void { const lView = getLView(); - const tProjectionNode = getOrCreateTNode( - lView[TVIEW], lView[T_HOST], nodeIndex, TNodeType.Projection, null, attrs || null); + const tView = getTView(); + const tProjectionNode = + getOrCreateTNode(tView, lView[T_HOST], nodeIndex, TNodeType.Projection, null, attrs || null); // We can't use viewData[HOST_NODE] because projection nodes can be nested in embedded views. if (tProjectionNode.projection === null) tProjectionNode.projection = selectorIndex; @@ -135,6 +136,6 @@ export function ɵɵprojection( // We might need to delay the projection of nodes if they are in the middle of an i18n block if (!delayProjection) { // re-distribution of projectable nodes is stored on a component's view level - applyProjection(lView, tProjectionNode); + applyProjection(tView, lView, tProjectionNode); } } diff --git a/packages/core/src/render3/instructions/property.ts b/packages/core/src/render3/instructions/property.ts index 7abe5bf75c..dda96ec053 100644 --- a/packages/core/src/render3/instructions/property.ts +++ b/packages/core/src/render3/instructions/property.ts @@ -8,8 +8,8 @@ import {bindingUpdated} from '../bindings'; import {TNode} from '../interfaces/node'; import {SanitizerFn} from '../interfaces/sanitization'; -import {LView, TVIEW} from '../interfaces/view'; -import {getLView, getSelectedIndex, nextBindingIndex} from '../state'; +import {LView, TView} from '../interfaces/view'; +import {getLView, getSelectedIndex, getTView, nextBindingIndex} from '../state'; import {elementPropertyInternal, setInputsForProperty, storePropertyBindingMetadata} from './shared'; @@ -37,8 +37,9 @@ export function ɵɵproperty( const bindingIndex = nextBindingIndex(); if (bindingUpdated(lView, bindingIndex, value)) { const nodeIndex = getSelectedIndex(); - elementPropertyInternal(lView, nodeIndex, propName, value, sanitizer); - ngDevMode && storePropertyBindingMetadata(lView[TVIEW].data, nodeIndex, propName, bindingIndex); + const tView = getTView(); + elementPropertyInternal(tView, lView, nodeIndex, propName, value, sanitizer); + ngDevMode && storePropertyBindingMetadata(tView.data, nodeIndex, propName, bindingIndex); } return ɵɵproperty; } @@ -48,10 +49,10 @@ export function ɵɵproperty( * directive input. */ export function setDirectiveInputsWhichShadowsStyling( - tNode: TNode, lView: LView, value: any, isClassBased: boolean) { + tView: TView, tNode: TNode, lView: LView, value: any, isClassBased: boolean) { const inputs = tNode.inputs !; const property = isClassBased ? 'class' : 'style'; // We support both 'class' and `className` hence the fallback. const stylingInputs = inputs[property] || (isClassBased && inputs['className']); - setInputsForProperty(lView, stylingInputs, property, value); + setInputsForProperty(tView, lView, stylingInputs, property, value); } diff --git a/packages/core/src/render3/instructions/property_interpolation.ts b/packages/core/src/render3/instructions/property_interpolation.ts index 213d320e44..1ac64eefd7 100644 --- a/packages/core/src/render3/instructions/property_interpolation.ts +++ b/packages/core/src/render3/instructions/property_interpolation.ts @@ -6,15 +6,12 @@ * found in the LICENSE file at https://angular.io/license */ import {SanitizerFn} from '../interfaces/sanitization'; -import {TVIEW} from '../interfaces/view'; -import {getBindingIndex, getLView, getSelectedIndex} from '../state'; +import {getBindingIndex, getLView, getSelectedIndex, getTView} from '../state'; import {NO_CHANGE} from '../tokens'; - import {interpolation1, interpolation2, interpolation3, interpolation4, interpolation5, interpolation6, interpolation7, interpolation8, interpolationV} from './interpolation'; import {elementPropertyInternal, storePropertyBindingMetadata} from './shared'; - /** * * Update an interpolated property on an element with a lone bound value @@ -86,9 +83,10 @@ export function ɵɵpropertyInterpolate1( const interpolatedValue = interpolation1(lView, prefix, v0, suffix); if (interpolatedValue !== NO_CHANGE) { const nodeIndex = getSelectedIndex(); - elementPropertyInternal(lView, nodeIndex, propName, interpolatedValue, sanitizer); + const tView = getTView(); + elementPropertyInternal(tView, lView, nodeIndex, propName, interpolatedValue, sanitizer); ngDevMode && storePropertyBindingMetadata( - lView[TVIEW].data, nodeIndex, propName, getBindingIndex() - 1, prefix, suffix); + tView.data, nodeIndex, propName, getBindingIndex() - 1, prefix, suffix); } return ɵɵpropertyInterpolate1; } @@ -130,10 +128,10 @@ export function ɵɵpropertyInterpolate2( const interpolatedValue = interpolation2(lView, prefix, v0, i0, v1, suffix); if (interpolatedValue !== NO_CHANGE) { const nodeIndex = getSelectedIndex(); - elementPropertyInternal(lView, nodeIndex, propName, interpolatedValue, sanitizer); - ngDevMode && - storePropertyBindingMetadata( - lView[TVIEW].data, nodeIndex, propName, getBindingIndex() - 2, prefix, i0, suffix); + const tView = getTView(); + elementPropertyInternal(tView, lView, nodeIndex, propName, interpolatedValue, sanitizer); + ngDevMode && storePropertyBindingMetadata( + tView.data, nodeIndex, propName, getBindingIndex() - 2, prefix, i0, suffix); } return ɵɵpropertyInterpolate2; } @@ -178,10 +176,11 @@ export function ɵɵpropertyInterpolate3( const interpolatedValue = interpolation3(lView, prefix, v0, i0, v1, i1, v2, suffix); if (interpolatedValue !== NO_CHANGE) { const nodeIndex = getSelectedIndex(); - elementPropertyInternal(lView, nodeIndex, propName, interpolatedValue, sanitizer); + const tView = getTView(); + elementPropertyInternal(tView, lView, nodeIndex, propName, interpolatedValue, sanitizer); ngDevMode && storePropertyBindingMetadata( - lView[TVIEW].data, nodeIndex, propName, getBindingIndex() - 3, prefix, i0, i1, suffix); + tView.data, nodeIndex, propName, getBindingIndex() - 3, prefix, i0, i1, suffix); } return ɵɵpropertyInterpolate3; } @@ -228,10 +227,11 @@ export function ɵɵpropertyInterpolate4( const interpolatedValue = interpolation4(lView, prefix, v0, i0, v1, i1, v2, i2, v3, suffix); if (interpolatedValue !== NO_CHANGE) { const nodeIndex = getSelectedIndex(); - elementPropertyInternal(lView, nodeIndex, propName, interpolatedValue, sanitizer); - ngDevMode && storePropertyBindingMetadata( - lView[TVIEW].data, nodeIndex, propName, getBindingIndex() - 4, prefix, i0, i1, - i2, suffix); + const tView = getTView(); + elementPropertyInternal(tView, lView, nodeIndex, propName, interpolatedValue, sanitizer); + ngDevMode && + storePropertyBindingMetadata( + tView.data, nodeIndex, propName, getBindingIndex() - 4, prefix, i0, i1, i2, suffix); } return ɵɵpropertyInterpolate4; } @@ -282,10 +282,11 @@ export function ɵɵpropertyInterpolate5( interpolation5(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix); if (interpolatedValue !== NO_CHANGE) { const nodeIndex = getSelectedIndex(); - elementPropertyInternal(lView, nodeIndex, propName, interpolatedValue, sanitizer); - ngDevMode && storePropertyBindingMetadata( - lView[TVIEW].data, nodeIndex, propName, getBindingIndex() - 5, prefix, i0, i1, - i2, i3, suffix); + const tView = getTView(); + elementPropertyInternal(tView, lView, nodeIndex, propName, interpolatedValue, sanitizer); + ngDevMode && + storePropertyBindingMetadata( + tView.data, nodeIndex, propName, getBindingIndex() - 5, prefix, i0, i1, i2, i3, suffix); } return ɵɵpropertyInterpolate5; } @@ -338,10 +339,11 @@ export function ɵɵpropertyInterpolate6( interpolation6(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix); if (interpolatedValue !== NO_CHANGE) { const nodeIndex = getSelectedIndex(); - elementPropertyInternal(lView, nodeIndex, propName, interpolatedValue, sanitizer); + const tView = getTView(); + elementPropertyInternal(tView, lView, nodeIndex, propName, interpolatedValue, sanitizer); ngDevMode && storePropertyBindingMetadata( - lView[TVIEW].data, nodeIndex, propName, getBindingIndex() - 6, prefix, i0, i1, - i2, i3, i4, suffix); + tView.data, nodeIndex, propName, getBindingIndex() - 6, prefix, i0, i1, i2, i3, + i4, suffix); } return ɵɵpropertyInterpolate6; } @@ -396,10 +398,11 @@ export function ɵɵpropertyInterpolate7( interpolation7(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix); if (interpolatedValue !== NO_CHANGE) { const nodeIndex = getSelectedIndex(); - elementPropertyInternal(lView, nodeIndex, propName, interpolatedValue, sanitizer); + const tView = getTView(); + elementPropertyInternal(tView, lView, nodeIndex, propName, interpolatedValue, sanitizer); ngDevMode && storePropertyBindingMetadata( - lView[TVIEW].data, nodeIndex, propName, getBindingIndex() - 7, prefix, i0, i1, - i2, i3, i4, i5, suffix); + tView.data, nodeIndex, propName, getBindingIndex() - 7, prefix, i0, i1, i2, i3, + i4, i5, suffix); } return ɵɵpropertyInterpolate7; } @@ -456,10 +459,11 @@ export function ɵɵpropertyInterpolate8( lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix); if (interpolatedValue !== NO_CHANGE) { const nodeIndex = getSelectedIndex(); - elementPropertyInternal(lView, nodeIndex, propName, interpolatedValue, sanitizer); + const tView = getTView(); + elementPropertyInternal(tView, lView, nodeIndex, propName, interpolatedValue, sanitizer); ngDevMode && storePropertyBindingMetadata( - lView[TVIEW].data, nodeIndex, propName, getBindingIndex() - 8, prefix, i0, i1, - i2, i3, i4, i5, i6, suffix); + tView.data, nodeIndex, propName, getBindingIndex() - 8, prefix, i0, i1, i2, i3, + i4, i5, i6, suffix); } return ɵɵpropertyInterpolate8; } @@ -500,15 +504,16 @@ export function ɵɵpropertyInterpolateV( const interpolatedValue = interpolationV(lView, values); if (interpolatedValue !== NO_CHANGE) { const nodeIndex = getSelectedIndex(); - elementPropertyInternal(lView, nodeIndex, propName, interpolatedValue, sanitizer); + const tView = getTView(); + elementPropertyInternal(tView, lView, nodeIndex, propName, interpolatedValue, sanitizer); if (ngDevMode) { const interpolationInBetween = [values[0]]; // prefix for (let i = 2; i < values.length; i += 2) { interpolationInBetween.push(values[i]); } storePropertyBindingMetadata( - lView[TVIEW].data, nodeIndex, propName, - getBindingIndex() - interpolationInBetween.length + 1, ...interpolationInBetween); + tView.data, nodeIndex, propName, getBindingIndex() - interpolationInBetween.length + 1, + ...interpolationInBetween); } } return ɵɵpropertyInterpolateV; diff --git a/packages/core/src/render3/instructions/shared.ts b/packages/core/src/render3/instructions/shared.ts index 0bc63fa699..58509c4517 100644 --- a/packages/core/src/render3/instructions/shared.ts +++ b/packages/core/src/render3/instructions/shared.ts @@ -31,7 +31,7 @@ import {isComponentDef, isComponentHost, isContentQueryHost, isLContainer, isRoo import {CHILD_HEAD, CHILD_TAIL, CLEANUP, CONTEXT, DECLARATION_COMPONENT_VIEW, DECLARATION_VIEW, FLAGS, HEADER_OFFSET, HOST, INJECTOR, InitPhaseState, LView, LViewFlags, NEXT, PARENT, RENDERER, RENDERER_FACTORY, RootContext, RootContextFlags, SANITIZER, TData, TVIEW, TView, TViewType, T_HOST} from '../interfaces/view'; import {assertNodeOfPossibleTypes} from '../node_assert'; import {isNodeMatchingSelectorList} from '../node_selector_matcher'; -import {enterView, getBindingsEnabled, getCheckNoChangesMode, getIsParent, getPreviousOrParentTNode, getSelectedIndex, leaveView, setBindingIndex, setBindingRootForHostBindings, setCheckNoChangesMode, setCurrentQueryIndex, setPreviousOrParentTNode, setSelectedIndex} from '../state'; +import {enterView, getBindingsEnabled, getCheckNoChangesMode, getIsParent, getPreviousOrParentTNode, getSelectedIndex, getTView, leaveView, setBindingIndex, setBindingRootForHostBindings, setCheckNoChangesMode, setCurrentQueryIndex, setPreviousOrParentTNode, setSelectedIndex} from '../state'; import {NO_CHANGE} from '../tokens'; import {isAnimationProp, mergeHostAttrs} from '../util/attrs_utils'; import {INTERPOLATION_DELIMITER, renderStringify, stringifyForError} from '../util/misc_utils'; @@ -289,19 +289,19 @@ export function assignTViewNodeToLView( * i18nApply() or ComponentFactory.create), we need to adjust the blueprint for future * template passes. * - * @param view The LView containing the blueprint to adjust + * @param tView `TView` associated with `LView` + * @param view The `LView` containing the blueprint to adjust * @param numSlotsToAlloc The number of slots to alloc in the LView, should be >0 */ -export function allocExpando(view: LView, numSlotsToAlloc: number) { +export function allocExpando(tView: TView, lView: LView, numSlotsToAlloc: number) { ngDevMode && assertGreaterThan( numSlotsToAlloc, 0, 'The number of slots to alloc should be greater than 0'); if (numSlotsToAlloc > 0) { - const tView = view[TVIEW]; if (tView.firstCreatePass) { for (let i = 0; i < numSlotsToAlloc; i++) { tView.blueprint.push(null); tView.data.push(null); - view.push(null); + lView.push(null); } // We should only increment the expando start index if there aren't already directives @@ -329,7 +329,7 @@ export function allocExpando(view: LView, numSlotsToAlloc: number) { * - updating static queries (if any); * - creating child components defined in a given view. */ -export function renderView(lView: LView, tView: TView, context: T): void { +export function renderView(tView: TView, lView: LView, context: T): void { ngDevMode && assertEqual(isCreationMode(lView), true, 'Should be run in creation mode'); enterView(lView, lView[T_HOST]); try { @@ -342,7 +342,7 @@ export function renderView(lView: LView, tView: TView, context: T): void { // defined for the root component views. const templateFn = tView.template; if (templateFn !== null) { - executeTemplate(lView, templateFn, RenderFlags.Create, context); + executeTemplate(tView, lView, templateFn, RenderFlags.Create, context); } // This needs to be set before children are processed to support recursive components. @@ -389,7 +389,7 @@ export function renderView(lView: LView, tView: TView, context: T): void { * - refreshing child (embedded and component) views. */ export function refreshView( - lView: LView, tView: TView, templateFn: ComponentTemplate<{}>| null, context: T) { + tView: TView, lView: LView, templateFn: ComponentTemplate<{}>| null, context: T) { ngDevMode && assertEqual(isCreationMode(lView), false, 'Should be run in update mode'); const flags = lView[FLAGS]; if ((flags & LViewFlags.Destroyed) === LViewFlags.Destroyed) return; @@ -400,7 +400,7 @@ export function refreshView( setBindingIndex(tView.bindingStartIndex); if (templateFn !== null) { - executeTemplate(lView, templateFn, RenderFlags.Update, context); + executeTemplate(tView, lView, templateFn, RenderFlags.Update, context); } const hooksInitPhaseCompleted = @@ -505,19 +505,18 @@ export function refreshView( } export function renderComponentOrTemplate( - hostView: LView, templateFn: ComponentTemplate<{}>| null, context: T) { - const rendererFactory = hostView[RENDERER_FACTORY]; + tView: TView, lView: LView, templateFn: ComponentTemplate<{}>| null, context: T) { + const rendererFactory = lView[RENDERER_FACTORY]; const normalExecutionPath = !getCheckNoChangesMode(); - const creationModeIsActive = isCreationMode(hostView); + const creationModeIsActive = isCreationMode(lView); try { if (normalExecutionPath && !creationModeIsActive && rendererFactory.begin) { rendererFactory.begin(); } - const tView = hostView[TVIEW]; if (creationModeIsActive) { - renderView(hostView, tView, context); + renderView(tView, lView, context); } - refreshView(hostView, tView, templateFn, context); + refreshView(tView, lView, templateFn, context); } finally { if (normalExecutionPath && !creationModeIsActive && rendererFactory.end) { rendererFactory.end(); @@ -526,14 +525,14 @@ export function renderComponentOrTemplate( } function executeTemplate( - lView: LView, templateFn: ComponentTemplate, rf: RenderFlags, context: T) { + tView: TView, lView: LView, templateFn: ComponentTemplate, rf: RenderFlags, context: T) { const prevSelectedIndex = getSelectedIndex(); try { setSelectedIndex(-1); if (rf & RenderFlags.Update && lView.length > HEADER_OFFSET) { // When we're updating, inherently select 0 so we don't // have to generate that instruction for most update blocks. - selectIndexInternal(lView, 0, getCheckNoChangesMode()); + selectIndexInternal(tView, lView, 0, getCheckNoChangesMode()); } templateFn(rf, context); } finally { @@ -759,12 +758,13 @@ export function locateHostElement( * - Cleanup function * - Index of context we just saved in LView.cleanupInstances */ -export function storeCleanupWithContext(lView: LView, context: any, cleanupFn: Function): void { - const lCleanup = getCleanup(lView); +export function storeCleanupWithContext( + tView: TView, lView: LView, context: any, cleanupFn: Function): void { + const lCleanup = getLCleanup(lView); lCleanup.push(context); - if (lView[TVIEW].firstCreatePass) { - getTViewCleanup(lView).push(cleanupFn, lCleanup.length - 1); + if (tView.firstCreatePass) { + getTViewCleanup(tView).push(cleanupFn, lCleanup.length - 1); } } @@ -776,11 +776,11 @@ export function storeCleanupWithContext(lView: LView, context: any, cleanupFn: F * * On the first template pass, the index of the cleanup function is saved in TView. */ -export function storeCleanupFn(view: LView, cleanupFn: Function): void { - getCleanup(view).push(cleanupFn); +export function storeCleanupFn(tView: TView, lView: LView, cleanupFn: Function): void { + getLCleanup(lView).push(cleanupFn); - if (view[TVIEW].firstCreatePass) { - getTViewCleanup(view).push(view[CLEANUP] !.length - 1, null); + if (tView.firstCreatePass) { + getTViewCleanup(tView).push(lView[CLEANUP] !.length - 1, null); } } @@ -941,16 +941,16 @@ function mapPropName(name: string): string { } export function elementPropertyInternal( - lView: LView, index: number, propName: string, value: T, sanitizer?: SanitizerFn | null, - nativeOnly?: boolean, + tView: TView, lView: LView, index: number, propName: string, value: T, + sanitizer?: SanitizerFn | null, nativeOnly?: boolean, loadRendererFn?: ((tNode: TNode, lView: LView) => Renderer3) | null): void { ngDevMode && assertNotSame(value, NO_CHANGE as any, 'Incoming value should never be NO_CHANGE.'); const element = getNativeByIndex(index, lView) as RElement | RComment; - const tNode = getTNode(index, lView); + const tNode = getTNode(tView, index); let inputData = tNode.inputs; let dataValue: PropertyAliasValue|undefined; if (!nativeOnly && inputData != null && (dataValue = inputData[propName])) { - setInputsForProperty(lView, dataValue, propName, value); + setInputsForProperty(tView, lView, dataValue, propName, value); if (isComponentHost(tNode)) markDirtyIfOnPush(lView, index + HEADER_OFFSET); if (ngDevMode) { setNgReflectProperties(lView, element, tNode.type, dataValue, value); @@ -960,7 +960,7 @@ export function elementPropertyInternal( if (ngDevMode) { validateAgainstEventProperties(propName); - if (!validateProperty(lView, element, propName, tNode)) { + if (!validateProperty(tView, lView, element, propName, tNode)) { // Return here since we only log warnings for unknown properties. warnAboutUnknownProperty(propName, tNode); return; @@ -981,7 +981,7 @@ export function elementPropertyInternal( } else if (tNode.type === TNodeType.Container) { // If the node is a container and the property didn't // match any of the inputs or schemas we should throw. - if (ngDevMode && !matchingSchemas(lView, tNode.tagName)) { + if (ngDevMode && !matchingSchemas(tView, lView, tNode.tagName)) { warnAboutUnknownProperty(propName, tNode); } } @@ -1039,10 +1039,11 @@ export function setNgReflectProperties( } function validateProperty( - hostView: LView, element: RElement | RComment, propName: string, tNode: TNode): boolean { + tView: TView, lView: LView, element: RElement | RComment, propName: string, + tNode: TNode): boolean { // The property is considered valid if the element matches the schema, it exists on the element // or it is synthetic, and we are in a browser context (web worker nodes should be skipped). - if (matchingSchemas(hostView, tNode.tagName) || propName in element || + if (matchingSchemas(tView, lView, tNode.tagName) || propName in element || isAnimationProp(propName)) { return true; } @@ -1052,8 +1053,8 @@ function validateProperty( return typeof Node === 'undefined' || Node === null || !(element instanceof Node); } -export function matchingSchemas(hostView: LView, tagName: string | null): boolean { - const schemas = hostView[TVIEW].schemas; +export function matchingSchemas(tView: TView, lView: LView, tagName: string | null): boolean { + const schemas = tView.schemas; if (schemas !== null) { for (let i = 0; i < schemas.length; i++) { @@ -1437,8 +1438,8 @@ function addComponentLogic(lView: LView, hostTNode: TElementNode, def: Compon } export function elementAttributeInternal( - index: number, name: string, value: any, lView: LView, sanitizer?: SanitizerFn | null, - namespace?: string) { + index: number, name: string, value: any, tView: TView, lView: LView, + sanitizer?: SanitizerFn | null, namespace?: string) { ngDevMode && assertNotSame(value, NO_CHANGE as any, 'Incoming value should never be NO_CHANGE.'); ngDevMode && validateAgainstEventAttributes(name); const element = getNativeByIndex(index, lView) as RElement; @@ -1449,7 +1450,7 @@ export function elementAttributeInternal( element.removeAttribute(name); } else { ngDevMode && ngDevMode.rendererSetAttribute++; - const tNode = getTNode(index, lView); + const tNode = getTNode(tView, index); const strValue = sanitizer == null ? renderStringify(value) : sanitizer(value, tNode.tagName || '', name); @@ -1592,12 +1593,12 @@ function refreshDynamicEmbeddedViews(lView: LView) { (activeIndexFlag = viewOrContainer[ACTIVE_INDEX]) >> ActiveIndexFlag.SHIFT === ActiveIndexFlag.DYNAMIC_EMBEDDED_VIEWS_ONLY) { for (let i = CONTAINER_HEADER_OFFSET; i < viewOrContainer.length; i++) { - const embeddedLView = viewOrContainer[i]; + const embeddedLView = viewOrContainer[i] as LView; const embeddedTView = embeddedLView[TVIEW]; ngDevMode && assertDefined(embeddedTView, 'TView must be allocated'); if (viewAttachedToChangeDetector(embeddedLView)) { refreshView( - embeddedLView, embeddedTView, embeddedTView.template, embeddedLView[CONTEXT] !); + embeddedTView, embeddedLView, embeddedTView.template, embeddedLView[CONTEXT] !); } } if ((activeIndexFlag & ActiveIndexFlag.HAS_TRANSPLANTED_VIEWS) !== 0) { @@ -1646,7 +1647,7 @@ function refreshTransplantedViews(lContainer: LContainer, declaredComponentLView // point. const movedTView = movedLView[TVIEW]; ngDevMode && assertDefined(movedTView, 'TView must be allocated'); - refreshView(movedLView, movedTView, movedTView.template, movedLView[CONTEXT] !); + refreshView(movedTView, movedLView, movedTView.template, movedLView[CONTEXT] !); } } } @@ -1665,16 +1666,17 @@ function refreshComponent(hostLView: LView, componentHostIdx: number): void { // Only attached components that are CheckAlways or OnPush and dirty should be refreshed if (viewAttachedToChangeDetector(componentView) && componentView[FLAGS] & (LViewFlags.CheckAlways | LViewFlags.Dirty)) { - const tView = componentView[TVIEW]; - refreshView(componentView, tView, tView.template, componentView[CONTEXT]); + const componentTView = componentView[TVIEW]; + refreshView(componentTView, componentView, componentTView.template, componentView[CONTEXT]); } } function renderComponent(hostLView: LView, componentHostIdx: number) { ngDevMode && assertEqual(isCreationMode(hostLView), true, 'Should be run in creation mode'); const componentView = getComponentLViewByIndex(componentHostIdx, hostLView); - syncViewWithBlueprint(componentView); - renderView(componentView, componentView[TVIEW], componentView[CONTEXT]); + const componentTView = componentView[TVIEW]; + syncViewWithBlueprint(componentTView, componentView); + renderView(componentTView, componentView, componentView[CONTEXT]); } /** @@ -1701,12 +1703,12 @@ function renderComponent(hostLView: LView, componentHostIdx: number) { * Note that embedded views inside ngFor loops will never be out of sync because these views * are processed as soon as they are created. * - * @param componentView The view to sync + * @param tView The `TView` that contains the blueprint for syncing + * @param lView The view to sync */ -function syncViewWithBlueprint(componentView: LView) { - const componentTView = componentView[TVIEW]; - for (let i = componentView.length; i < componentTView.blueprint.length; i++) { - componentView.push(componentTView.blueprint[i]); +function syncViewWithBlueprint(tView: TView, lView: LView) { + for (let i = lView.length; i < tView.blueprint.length; i++) { + lView.push(tView.blueprint[i]); } } @@ -1723,12 +1725,9 @@ function syncViewWithBlueprint(componentView: LView) { */ export function addToViewTree(lView: LView, lViewOrLContainer: T): T { // TODO(benlesh/misko): This implementation is incorrect, because it always adds the LContainer - // to - // the end of the queue, which means if the developer retrieves the LContainers from RNodes out - // of - // order, the change detection will run out of order, as the act of retrieving the the - // LContainer - // from the RNode is what adds it to the queue. + // to the end of the queue, which means if the developer retrieves the LContainers from RNodes out + // of order, the change detection will run out of order, as the act of retrieving the the + // LContainer from the RNode is what adds it to the queue. if (lView[CHILD_HEAD]) { lView[CHILD_TAIL] ![NEXT] = lViewOrLContainer; } else { @@ -1812,18 +1811,17 @@ export function tickRootContext(rootContext: RootContext) { const rootComponent = rootContext.components[i]; const lView = readPatchedLView(rootComponent) !; const tView = lView[TVIEW]; - renderComponentOrTemplate(lView, tView.template, rootComponent); + renderComponentOrTemplate(tView, lView, tView.template, rootComponent); } } -export function detectChangesInternal(view: LView, context: T) { - const rendererFactory = view[RENDERER_FACTORY]; +export function detectChangesInternal(tView: TView, lView: LView, context: T) { + const rendererFactory = lView[RENDERER_FACTORY]; if (rendererFactory.begin) rendererFactory.begin(); try { - const tView = view[TVIEW]; - refreshView(view, tView, tView.template, context); + refreshView(tView, lView, tView.template, context); } catch (error) { - handleError(view, error); + handleError(lView, error); throw error; } finally { if (rendererFactory.end) rendererFactory.end(); @@ -1839,10 +1837,10 @@ export function detectChangesInRootView(lView: LView): void { tickRootContext(lView[CONTEXT] as RootContext); } -export function checkNoChangesInternal(view: LView, context: T) { +export function checkNoChangesInternal(tView: TView, view: LView, context: T) { setCheckNoChangesMode(true); try { - detectChangesInternal(view, context); + detectChangesInternal(tView, view, context); } finally { setCheckNoChangesMode(false); } @@ -1922,13 +1920,13 @@ export function storePropertyBindingMetadata( export const CLEAN_PROMISE = _CLEAN_PROMISE; -export function getCleanup(view: LView): any[] { +export function getLCleanup(view: LView): any[] { // top level variables should not be exported for performance reasons (PERF_NOTES.md) return view[CLEANUP] || (view[CLEANUP] = ngDevMode ? new LCleanup() : []); } -function getTViewCleanup(view: LView): any[] { - return view[TVIEW].cleanup || (view[TVIEW].cleanup = ngDevMode ? new TCleanup() : []); +function getTViewCleanup(tView: TView): any[] { + return tView.cleanup || (tView.cleanup = ngDevMode ? new TCleanup() : []); } /** @@ -1950,14 +1948,14 @@ export function handleError(lView: LView, error: any): void { /** * Set the inputs of directives at the current node to corresponding value. * + * @param tView The current TView * @param lView the `LView` which contains the directives. * @param inputs mapping between the public "input" name and privately-known, - * possibly minified, property names to write to. + * possibly minified, property names to write to. * @param value Value to set. */ export function setInputsForProperty( - lView: LView, inputs: PropertyAliasValue, publicName: string, value: any): void { - const tView = lView[TVIEW]; + tView: TView, lView: LView, inputs: PropertyAliasValue, publicName: string, value: any): void { for (let i = 0; i < inputs.length;) { const index = inputs[i++] as number; const privateName = inputs[i++] as string; diff --git a/packages/core/src/render3/instructions/storage.ts b/packages/core/src/render3/instructions/storage.ts index 3af4c123f8..c373e912cc 100644 --- a/packages/core/src/render3/instructions/storage.ts +++ b/packages/core/src/render3/instructions/storage.ts @@ -5,14 +5,13 @@ * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ -import {HEADER_OFFSET, TVIEW} from '../interfaces/view'; -import {getContextLView, getLView} from '../state'; +import {HEADER_OFFSET, LView, TView} from '../interfaces/view'; +import {getContextLView} from '../state'; import {load} from '../util/view_utils'; + /** Store a value in the `data` at a given `index`. */ -export function store(index: number, value: T): void { - const lView = getLView(); - const tView = lView[TVIEW]; +export function store(tView: TView, lView: LView, index: number, value: T): void { // We don't store any static data for local variables, so the first time // we see the template, we should store as null to avoid a sparse array const adjustedIndex = index + HEADER_OFFSET; diff --git a/packages/core/src/render3/instructions/styling.ts b/packages/core/src/render3/instructions/styling.ts index b07fb5499b..0fe940e6ca 100644 --- a/packages/core/src/render3/instructions/styling.ts +++ b/packages/core/src/render3/instructions/styling.ts @@ -20,18 +20,16 @@ import {AttributeMarker, TAttributes, TNode, TNodeFlags, TNodeType} from '../int import {RElement, Renderer3} from '../interfaces/renderer'; import {SanitizerFn} from '../interfaces/sanitization'; import {TStylingKey, TStylingRange, getTStylingRangeNext, getTStylingRangeNextDuplicate, getTStylingRangePrev, getTStylingRangePrevDuplicate} from '../interfaces/styling'; -import {HEADER_OFFSET, LView, RENDERER, TData, TVIEW, TView} from '../interfaces/view'; +import {HEADER_OFFSET, LView, RENDERER, TData, TView} from '../interfaces/view'; import {applyStyling} from '../node_manipulation'; -import {getCurrentDirectiveIndex, getCurrentStyleSanitizer, getLView, getSelectedIndex, incrementBindingIndex, setCurrentStyleSanitizer} from '../state'; +import {getCurrentDirectiveIndex, getCurrentStyleSanitizer, getLView, getSelectedIndex, getTView, incrementBindingIndex, setCurrentStyleSanitizer} from '../state'; import {insertTStylingBinding} from '../styling/style_binding_list'; import {getLastParsedKey, getLastParsedValue, parseClassName, parseClassNameNext, parseStyle, parseStyleNext} from '../styling/styling_parser'; import {NO_CHANGE} from '../tokens'; import {getNativeByIndex} from '../util/view_utils'; - import {setDirectiveInputsWhichShadowsStyling} from './property'; - /** * Sets the current style sanitizer function which will then be used * within all follow-up prop and map-based style binding instructions @@ -195,7 +193,7 @@ export function checkStylingProperty( prop: string, value: any | NO_CHANGE, suffixOrSanitizer: SanitizerFn | string | undefined | null, isClassBased: boolean): void { const lView = getLView(); - const tView = lView[TVIEW]; + const tView = getTView(); // Styling instructions use 2 slots per binding. // 1. one for the value / TStylingKey // 2. one for the intermittent-value / TStylingRange @@ -236,12 +234,12 @@ export function checkStylingMap( keyValueArraySet: (keyValueArray: KeyValueArray, key: string, value: any) => void, stringParser: (styleKeyValueArray: KeyValueArray, text: string) => void, value: any|NO_CHANGE, isClassBased: boolean): void { - const lView = getLView(); - const tView = lView[TVIEW]; + const tView = getTView(); const bindingIndex = incrementBindingIndex(2); if (tView.firstUpdatePass) { stylingFirstUpdatePass(tView, null, bindingIndex, isClassBased); } + const lView = getLView(); if (value !== NO_CHANGE && bindingUpdated(lView, bindingIndex, value)) { // `getSelectedIndex()` should be here (rather than in instruction) so that it is guarded by the // if so as not to read unnecessarily. @@ -271,7 +269,7 @@ export function checkStylingMap( } // Given `
` such that `my-dir` has `@Input('style')`. // This takes over the `[style]` binding. (Same for `[class]`) - setDirectiveInputsWhichShadowsStyling(tNode, lView, value, isClassBased); + setDirectiveInputsWhichShadowsStyling(tView, tNode, lView, value, isClassBased); } else { updateStylingMap( tView, tNode, lView, lView[RENDERER], lView[bindingIndex + 1], diff --git a/packages/core/src/render3/instructions/text.ts b/packages/core/src/render3/instructions/text.ts index 7f97e05c16..b7b1c90906 100644 --- a/packages/core/src/render3/instructions/text.ts +++ b/packages/core/src/render3/instructions/text.ts @@ -7,10 +7,9 @@ */ import {assertDataInRange, assertEqual} from '../../util/assert'; import {TElementNode, TNodeType} from '../interfaces/node'; -import {HEADER_OFFSET, RENDERER, TVIEW, T_HOST} from '../interfaces/view'; +import {HEADER_OFFSET, RENDERER, T_HOST} from '../interfaces/view'; import {appendChild, createTextNode} from '../node_manipulation'; -import {getBindingIndex, getLView, setPreviousOrParentTNode} from '../state'; - +import {getBindingIndex, getLView, getTView, setPreviousOrParentTNode} from '../state'; import {getOrCreateTNode} from './shared'; @@ -25,7 +24,7 @@ import {getOrCreateTNode} from './shared'; */ export function ɵɵtext(index: number, value: string = ''): void { const lView = getLView(); - const tView = lView[TVIEW]; + const tView = getTView(); const adjustedIndex = index + HEADER_OFFSET; ngDevMode && assertEqual( @@ -38,7 +37,7 @@ export function ɵɵtext(index: number, value: string = ''): void { tView.data[adjustedIndex] as TElementNode; const textNative = lView[adjustedIndex] = createTextNode(value, lView[RENDERER]); - appendChild(textNative, tNode, lView); + appendChild(tView, lView, textNative, tNode); // Text nodes are self closing. setPreviousOrParentTNode(tNode, false); diff --git a/packages/core/src/render3/node_manipulation.ts b/packages/core/src/render3/node_manipulation.ts index 90aa81f4e3..50c33997e4 100644 --- a/packages/core/src/render3/node_manipulation.ts +++ b/packages/core/src/render3/node_manipulation.ts @@ -19,7 +19,7 @@ import {TElementNode, TNode, TNodeFlags, TNodeType, TProjectionNode, TViewNode, import {unusedValueExportToPlacateAjd as unused3} from './interfaces/projection'; import {ProceduralRenderer3, RElement, RNode, RText, Renderer3, isProceduralRenderer, unusedValueExportToPlacateAjd as unused4} from './interfaces/renderer'; import {isLContainer, isLView} from './interfaces/type_checks'; -import {CHILD_HEAD, CLEANUP, DECLARATION_COMPONENT_VIEW, DECLARATION_LCONTAINER, FLAGS, HOST, HookData, LView, LViewFlags, NEXT, PARENT, QUERIES, RENDERER, TVIEW, T_HOST, unusedValueExportToPlacateAjd as unused5} from './interfaces/view'; +import {CHILD_HEAD, CLEANUP, DECLARATION_COMPONENT_VIEW, DECLARATION_LCONTAINER, FLAGS, HOST, HookData, LView, LViewFlags, NEXT, PARENT, QUERIES, RENDERER, TVIEW, TView, T_HOST, unusedValueExportToPlacateAjd as unused5} from './interfaces/view'; import {assertNodeOfPossibleTypes, assertNodeType} from './node_assert'; import {getLViewParent} from './util/view_traversal_utils'; import {getNativeByTNode, unwrapRNode} from './util/view_utils'; @@ -130,31 +130,34 @@ export function createTextNode(value: string, renderer: Renderer3): RText { * to propagate deeply into the nested containers to remove all elements in the * views beneath it. * + * @param tView The `TView' of the `LView` from which elements should be added or removed * @param lView The view from which elements should be added or removed * @param insertMode Whether or not elements should be added (if false, removing) * @param beforeNode The node before which elements should be added, if insert mode */ export function addRemoveViewFromContainer( - lView: LView, insertMode: true, beforeNode: RNode | null): void; -export function addRemoveViewFromContainer(lView: LView, insertMode: false, beforeNode: null): void; + tView: TView, lView: LView, insertMode: true, beforeNode: RNode | null): void; export function addRemoveViewFromContainer( - lView: LView, insertMode: boolean, beforeNode: RNode | null): void { - const renderParent = getContainerRenderParent(lView[TVIEW].node as TViewNode, lView); - ngDevMode && assertNodeType(lView[TVIEW].node as TNode, TNodeType.View); + tView: TView, lView: LView, insertMode: false, beforeNode: null): void; +export function addRemoveViewFromContainer( + tView: TView, lView: LView, insertMode: boolean, beforeNode: RNode | null): void { + const renderParent = getContainerRenderParent(tView.node as TViewNode, lView); + ngDevMode && assertNodeType(tView.node as TNode, TNodeType.View); if (renderParent) { const renderer = lView[RENDERER]; const action = insertMode ? WalkTNodeTreeAction.Insert : WalkTNodeTreeAction.Detach; - applyView(renderer, action, lView, renderParent, beforeNode); + applyView(tView, lView, renderer, action, renderParent, beforeNode); } } /** * Detach a `LView` from the DOM by detaching its nodes. * + * @param tView The `TView' of the `LView` to be detached * @param lView the `LView` to be detached. */ -export function renderDetachView(lView: LView) { - applyView(lView[RENDERER], WalkTNodeTreeAction.Detach, lView, null, null); +export function renderDetachView(tView: TView, lView: LView) { + applyView(tView, lView, lView[RENDERER], WalkTNodeTreeAction.Detach, null, null); } /** @@ -174,7 +177,7 @@ export function destroyViewTree(rootView: LView): void { // If the view has no children, we can clean it up and return early. let lViewOrLContainer = rootView[CHILD_HEAD]; if (!lViewOrLContainer) { - return cleanUpView(rootView); + return cleanUpView(rootView[TVIEW], rootView); } while (lViewOrLContainer) { @@ -194,10 +197,11 @@ export function destroyViewTree(rootView: LView): void { // Only clean up view when moving to the side or up, as destroy hooks // should be called in order from the bottom up. while (lViewOrLContainer && !lViewOrLContainer ![NEXT] && lViewOrLContainer !== rootView) { - cleanUpView(lViewOrLContainer); + isLView(lViewOrLContainer) && cleanUpView(lViewOrLContainer[TVIEW], lViewOrLContainer); lViewOrLContainer = getParentState(lViewOrLContainer, rootView); } - cleanUpView(lViewOrLContainer || rootView); + if (lViewOrLContainer === null) lViewOrLContainer = rootView; + isLView(lViewOrLContainer) && cleanUpView(lViewOrLContainer[TVIEW], lViewOrLContainer); next = lViewOrLContainer && lViewOrLContainer ![NEXT]; } lViewOrLContainer = next; @@ -212,11 +216,12 @@ export function destroyViewTree(rootView: LView): void { * root node of another view (in that case, the view's elements will be added when * the container's parent view is added later). * + * @param tView The `TView' of the `LView` to insert * @param lView The view to insert * @param lContainer The container into which the view should be inserted * @param index Which index in the container to insert the child view into */ -export function insertView(lView: LView, lContainer: LContainer, index: number) { +export function insertView(tView: TView, lView: LView, lContainer: LContainer, index: number) { ngDevMode && assertLView(lView); ngDevMode && assertLContainer(lContainer); const indexInContainer = CONTAINER_HEADER_OFFSET + index; @@ -245,7 +250,7 @@ export function insertView(lView: LView, lContainer: LContainer, index: number) // notify query that a new view has been added const lQueries = lView[QUERIES]; if (lQueries !== null) { - lQueries.insertView(lView[TVIEW]); + lQueries.insertView(tView); } // Sets the attached flag @@ -321,7 +326,7 @@ export function detachView(lContainer: LContainer, removeIndex: number): LView|u lContainer[indexInContainer - 1][NEXT] = viewToDetach[NEXT] as LView; } const removedLView = removeFromArray(lContainer, CONTAINER_HEADER_OFFSET + removeIndex); - addRemoveViewFromContainer(viewToDetach, false, null); + addRemoveViewFromContainer(viewToDetach[TVIEW], viewToDetach, false, null); // notify query that a view has been removed const lQueries = removedLView[QUERIES]; @@ -345,20 +350,21 @@ export function detachView(lContainer: LContainer, removeIndex: number): LView|u */ export function removeView(lContainer: LContainer, removeIndex: number) { const detachedView = detachView(lContainer, removeIndex); - detachedView && destroyLView(detachedView); + detachedView && destroyLView(detachedView[TVIEW], detachedView); } /** * A standalone function which destroys an LView, - * conducting cleanup (e.g. removing listeners, calling onDestroys). + * conducting clean up (e.g. removing listeners, calling onDestroys). * + * @param tView The `TView' of the `LView` to be destroyed * @param lView The view to be destroyed. */ -export function destroyLView(lView: LView) { +export function destroyLView(tView: TView, lView: LView) { if (!(lView[FLAGS] & LViewFlags.Destroyed)) { const renderer = lView[RENDERER]; if (isProceduralRenderer(renderer) && renderer.destroyNode) { - applyView(renderer, WalkTNodeTreeAction.Destroy, lView, null, null); + applyView(tView, lView, renderer, WalkTNodeTreeAction.Destroy, null, null); } destroyViewTree(lView); @@ -396,50 +402,52 @@ export function getParentState(lViewOrLContainer: LView | LContainer, rootView: * listeners. Listeners are removed as the last step so events delivered in the onDestroys hooks * can be propagated to @Output listeners. * - * @param view The LView to clean up + * @param tView `TView` for the `LView` to clean up. + * @param lView The LView to clean up */ -function cleanUpView(view: LView | LContainer): void { - if (isLView(view) && !(view[FLAGS] & LViewFlags.Destroyed)) { +function cleanUpView(tView: TView, lView: LView): void { + if (!(lView[FLAGS] & LViewFlags.Destroyed)) { // Usually the Attached flag is removed when the view is detached from its parent, however // if it's a root view, the flag won't be unset hence why we're also removing on destroy. - view[FLAGS] &= ~LViewFlags.Attached; + lView[FLAGS] &= ~LViewFlags.Attached; // Mark the LView as destroyed *before* executing the onDestroy hooks. An onDestroy hook // runs arbitrary user code, which could include its own `viewRef.destroy()` (or similar). If // We don't flag the view as destroyed before the hooks, this could lead to an infinite loop. // This also aligns with the ViewEngine behavior. It also means that the onDestroy hook is // really more of an "afterDestroy" hook if you think about it. - view[FLAGS] |= LViewFlags.Destroyed; + lView[FLAGS] |= LViewFlags.Destroyed; - executeOnDestroys(view); - removeListeners(view); - const hostTNode = view[T_HOST]; + executeOnDestroys(tView, lView); + removeListeners(tView, lView); + const hostTNode = lView[T_HOST]; // For component views only, the local renderer is destroyed as clean up time. - if (hostTNode && hostTNode.type === TNodeType.Element && isProceduralRenderer(view[RENDERER])) { + if (hostTNode && hostTNode.type === TNodeType.Element && + isProceduralRenderer(lView[RENDERER])) { ngDevMode && ngDevMode.rendererDestroy++; - (view[RENDERER] as ProceduralRenderer3).destroy(); + (lView[RENDERER] as ProceduralRenderer3).destroy(); } - const declarationContainer = view[DECLARATION_LCONTAINER]; + const declarationContainer = lView[DECLARATION_LCONTAINER]; // we are dealing with an embedded view that is still inserted into a container - if (declarationContainer !== null && isLContainer(view[PARENT])) { + if (declarationContainer !== null && isLContainer(lView[PARENT])) { // and this is a projected view - if (declarationContainer !== view[PARENT]) { - detachMovedView(declarationContainer, view); + if (declarationContainer !== lView[PARENT]) { + detachMovedView(declarationContainer, lView); } // For embedded views still attached to a container: remove query result from this view. - const lQueries = view[QUERIES]; + const lQueries = lView[QUERIES]; if (lQueries !== null) { - lQueries.detachView(view[TVIEW]); + lQueries.detachView(tView); } } } } /** Removes listeners and unsubscribes from output subscriptions */ -function removeListeners(lView: LView): void { - const tCleanup = lView[TVIEW].cleanup; +function removeListeners(tView: TView, lView: LView): void { + const tCleanup = tView.cleanup; if (tCleanup !== null) { const lCleanup = lView[CLEANUP] !; for (let i = 0; i < tCleanup.length - 1; i += 2) { @@ -475,13 +483,12 @@ function removeListeners(lView: LView): void { } /** Calls onDestroy hooks for this view */ -function executeOnDestroys(view: LView): void { - const tView = view[TVIEW]; +function executeOnDestroys(tView: TView, lView: LView): void { let destroyHooks: HookData|null; if (tView != null && (destroyHooks = tView.destroyHooks) != null) { for (let i = 0; i < destroyHooks.length; i += 2) { - const context = view[destroyHooks[i] as number]; + const context = lView[destroyHooks[i] as number]; // Only call the destroy hook if the context has been requested. if (!(context instanceof NodeInjectorFactory)) { @@ -503,7 +510,7 @@ function executeOnDestroys(view: LView): void { * of a View which has not be inserted or is made for projection but has not been inserted * into destination. */ -function getRenderParent(tNode: TNode, currentView: LView): RElement|null { +function getRenderParent(tView: TView, tNode: TNode, currentView: LView): RElement|null { // Skip over element and ICU containers as those are represented by a comment node and // can't be used as a render parent. let parentTNode = tNode.parent; @@ -542,7 +549,7 @@ function getRenderParent(tNode: TNode, currentView: LView): RElement|null { ngDevMode && assertNodeType(parentTNode, TNodeType.Element); if (parentTNode.flags & TNodeFlags.isComponentHost) { - const tData = currentView[TVIEW].data; + const tData = tView.data; const tNode = tData[parentTNode.index] as TNode; const encapsulation = (tData[tNode.directiveStart] as ComponentDef).encapsulation; @@ -645,17 +652,19 @@ function getNativeAnchorNode(parentTNode: TNode, lView: LView): RNode|null { * * The element insertion might be delayed {@link canInsertNativeNode}. * + * @param tView The `TView' to be appended + * @param lView The current LView * @param childEl The native child (or children) that should be appended * @param childTNode The TNode of the child element - * @param currentView The current LView * @returns Whether or not the child was appended */ -export function appendChild(childEl: RNode | RNode[], childTNode: TNode, currentView: LView): void { - const renderParent = getRenderParent(childTNode, currentView); +export function appendChild( + tView: TView, lView: LView, childEl: RNode | RNode[], childTNode: TNode): void { + const renderParent = getRenderParent(tView, childTNode, lView); if (renderParent != null) { - const renderer = currentView[RENDERER]; - const parentTNode: TNode = childTNode.parent || currentView[T_HOST] !; - const anchorNode = getNativeAnchorNode(parentTNode, currentView); + const renderer = lView[RENDERER]; + const parentTNode: TNode = childTNode.parent || lView[T_HOST] !; + const anchorNode = getNativeAnchorNode(parentTNode, lView); if (Array.isArray(childEl)) { for (let i = 0; i < childEl.length; i++) { nativeAppendOrInsertBefore(renderer, renderParent, childEl[i], anchorNode); @@ -796,16 +805,16 @@ function applyNodes( * As you can see this is a very recursive problem. Yes recursion is not most efficient but the * code is complicated enough that trying to implemented with recursion becomes unmaintainable. * + * @param tView The `TView' which needs to be inserted, detached, destroyed + * @param lView The LView which needs to be inserted, detached, destroyed. * @param renderer Renderer to use * @param action action to perform (insert, detach, destroy) - * @param lView The LView which needs to be inserted, detached, destroyed. * @param renderParent parent DOM element for insertion/removal. * @param beforeNode Before which node the insertions should happen. */ function applyView( - renderer: Renderer3, action: WalkTNodeTreeAction, lView: LView, renderParent: RElement | null, - beforeNode: RNode | null) { - const tView = lView[TVIEW]; + tView: TView, lView: LView, renderer: Renderer3, action: WalkTNodeTreeAction, + renderParent: RElement | null, beforeNode: RNode | null) { ngDevMode && assertNodeType(tView.node !, TNodeType.View); const viewRootTNode: TNode|null = tView.node !.child; applyNodes(renderer, action, viewRootTNode, lView, renderParent, beforeNode, false); @@ -817,12 +826,13 @@ function applyView( * Inserting a projection requires us to locate the projected nodes from the parent component. The * complication is that those nodes themselves could be re-projected from their parent component. * - * @param lView The LView which needs to be inserted, detached, destroyed. + * @param tView The `TView` of `LView` which needs to be inserted, detached, destroyed + * @param lView The `LView` which needs to be inserted, detached, destroyed. * @param tProjectionNode node to project */ -export function applyProjection(lView: LView, tProjectionNode: TProjectionNode) { +export function applyProjection(tView: TView, lView: LView, tProjectionNode: TProjectionNode) { const renderer = lView[RENDERER]; - const renderParent = getRenderParent(tProjectionNode, lView); + const renderParent = getRenderParent(tView, tProjectionNode, lView); const parentTNode = tProjectionNode.parent || lView[T_HOST] !; let beforeNode = getNativeAnchorNode(parentTNode, lView); applyProjectionRecursive( @@ -904,7 +914,7 @@ function applyContainer( } for (let i = CONTAINER_HEADER_OFFSET; i < lContainer.length; i++) { const lView = lContainer[i] as LView; - applyView(renderer, action, lView, renderParent, anchor); + applyView(lView[TVIEW], lView, renderer, action, renderParent, anchor); } } diff --git a/packages/core/src/render3/pipe.ts b/packages/core/src/render3/pipe.ts index d4b5b9c02d..a7b1452b91 100644 --- a/packages/core/src/render3/pipe.ts +++ b/packages/core/src/render3/pipe.ts @@ -14,7 +14,7 @@ import {store} from './instructions/all'; import {PipeDef, PipeDefList} from './interfaces/definition'; import {HEADER_OFFSET, LView, TVIEW} from './interfaces/view'; import {pureFunction1Internal, pureFunction2Internal, pureFunction3Internal, pureFunction4Internal, pureFunctionVInternal} from './pure_function'; -import {getBindingIndex, getBindingRoot, getLView} from './state'; +import {getBindingIndex, getBindingRoot, getLView, getTView} from './state'; import {NO_CHANGE} from './tokens'; import {load} from './util/view_utils'; @@ -30,7 +30,7 @@ import {load} from './util/view_utils'; * @codeGenApi */ export function ɵɵpipe(index: number, pipeName: string): any { - const tView = getLView()[TVIEW]; + const tView = getTView(); let pipeDef: PipeDef; const adjustedIndex = index + HEADER_OFFSET; @@ -46,7 +46,7 @@ export function ɵɵpipe(index: number, pipeName: string): any { const pipeFactory = pipeDef.factory || (pipeDef.factory = getFactoryDef(pipeDef.type, true)); const pipeInstance = pipeFactory(); - store(index, pipeInstance); + store(tView, getLView(), index, pipeInstance); return pipeInstance; } diff --git a/packages/core/src/render3/query.ts b/packages/core/src/render3/query.ts index 0717eeae84..ebbef19a4a 100644 --- a/packages/core/src/render3/query.ts +++ b/packages/core/src/render3/query.ts @@ -27,7 +27,7 @@ import {TContainerNode, TElementContainerNode, TElementNode, TNode, TNodeType, u import {LQueries, LQuery, TQueries, TQuery, TQueryMetadata, unusedValueExportToPlacateAjd as unused4} from './interfaces/query'; import {DECLARATION_LCONTAINER, LView, PARENT, QUERIES, TVIEW, TView} from './interfaces/view'; import {assertNodeOfPossibleTypes} from './node_assert'; -import {getCurrentQueryIndex, getLView, getPreviousOrParentTNode, setCurrentQueryIndex} from './state'; +import {getCurrentQueryIndex, getLView, getPreviousOrParentTNode, getTView, setCurrentQueryIndex} from './state'; import {isCreationMode} from './util/view_utils'; import {createContainerRef, createElementRef, createTemplateRef} from './view_engine_compatibility'; @@ -308,10 +308,11 @@ function createSpecialToken(lView: LView, tNode: TNode, read: any): any { * processing once and only once for a given view instance (a set of results for a given view * doesn't change). */ -function materializeViewResults(lView: LView, tQuery: TQuery, queryIndex: number): (T | null)[] { +function materializeViewResults( + tView: TView, lView: LView, tQuery: TQuery, queryIndex: number): (T | null)[] { const lQuery = lView[QUERIES] !.queries ![queryIndex]; if (lQuery.matches === null) { - const tViewData = lView[TVIEW].data; + const tViewData = tView.data; const tQueryMatches = tQuery.matches !; const result: T|null[] = []; for (let i = 0; i < tQueryMatches.length; i += 2) { @@ -337,11 +338,11 @@ function materializeViewResults(lView: LView, tQuery: TQuery, queryIndex: num * A helper function that collects (already materialized) query results from a tree of views, * starting with a provided LView. */ -function collectQueryResults(lView: LView, queryIndex: number, result: T[]): T[] { - const tQuery = lView[TVIEW].queries !.getByIndex(queryIndex); +function collectQueryResults(tView: TView, lView: LView, queryIndex: number, result: T[]): T[] { + const tQuery = tView.queries !.getByIndex(queryIndex); const tQueryMatches = tQuery.matches; if (tQueryMatches !== null) { - const lViewResults = materializeViewResults(lView, tQuery, queryIndex); + const lViewResults = materializeViewResults(tView, lView, tQuery, queryIndex); for (let i = 0; i < tQueryMatches.length; i += 2) { const tNodeIdx = tQueryMatches[i]; @@ -359,7 +360,7 @@ function collectQueryResults(lView: LView, queryIndex: number, result: T[]): for (let i = CONTAINER_HEADER_OFFSET; i < declarationLContainer.length; i++) { const embeddedLView = declarationLContainer[i]; if (embeddedLView[DECLARATION_LCONTAINER] === embeddedLView[PARENT]) { - collectQueryResults(embeddedLView, childQueryIndex, result); + collectQueryResults(embeddedLView[TVIEW], embeddedLView, childQueryIndex, result); } } @@ -368,7 +369,8 @@ function collectQueryResults(lView: LView, queryIndex: number, result: T[]): if (declarationLContainer[MOVED_VIEWS] !== null) { const embeddedLViews = declarationLContainer[MOVED_VIEWS] !; for (let i = 0; i < embeddedLViews.length; i++) { - collectQueryResults(embeddedLViews[i], childQueryIndex, result); + const embeddedLView = embeddedLViews[i]; + collectQueryResults(embeddedLView[TVIEW], embeddedLView, childQueryIndex, result); } } } @@ -388,17 +390,19 @@ function collectQueryResults(lView: LView, queryIndex: number, result: T[]): */ export function ɵɵqueryRefresh(queryList: QueryList): boolean { const lView = getLView(); + const tView = getTView(); const queryIndex = getCurrentQueryIndex(); setCurrentQueryIndex(queryIndex + 1); - const tQuery = getTQuery(lView[TVIEW], queryIndex); + const tQuery = getTQuery(tView, queryIndex); if (queryList.dirty && (isCreationMode(lView) === tQuery.metadata.isStatic)) { if (tQuery.matches === null) { queryList.reset([]); } else { - const result = tQuery.crossesNgTemplate ? collectQueryResults(lView, queryIndex, []) : - materializeViewResults(lView, tQuery, queryIndex); + const result = tQuery.crossesNgTemplate ? + collectQueryResults(tView, lView, queryIndex, []) : + materializeViewResults(tView, lView, tQuery, queryIndex); queryList.reset(result); queryList.notifyOnChanges(); } @@ -419,7 +423,7 @@ export function ɵɵqueryRefresh(queryList: QueryList): boolean { */ export function ɵɵstaticViewQuery( predicate: Type| string[], descend: boolean, read?: any): void { - viewQueryInternal(getLView(), predicate, descend, read, true); + viewQueryInternal(getTView(), getLView(), predicate, descend, read, true); } /** @@ -432,20 +436,19 @@ export function ɵɵstaticViewQuery( * @codeGenApi */ export function ɵɵviewQuery(predicate: Type| string[], descend: boolean, read?: any): void { - viewQueryInternal(getLView(), predicate, descend, read, false); + viewQueryInternal(getTView(), getLView(), predicate, descend, read, false); } function viewQueryInternal( - lView: LView, predicate: Type| string[], descend: boolean, read: any, + tView: TView, lView: LView, predicate: Type| string[], descend: boolean, read: any, isStatic: boolean): void { - const tView = lView[TVIEW]; if (tView.firstCreatePass) { createTQuery(tView, new TQueryMetadata_(predicate, descend, isStatic, read), -1); if (isStatic) { tView.staticViewQueries = true; } } - createLQuery(lView); + createLQuery(tView, lView); } /** @@ -463,7 +466,8 @@ function viewQueryInternal( export function ɵɵcontentQuery( directiveIndex: number, predicate: Type| string[], descend: boolean, read?: any): void { contentQueryInternal( - getLView(), predicate, descend, read, false, getPreviousOrParentTNode(), directiveIndex); + getTView(), getLView(), predicate, descend, read, false, getPreviousOrParentTNode(), + directiveIndex); } /** @@ -481,13 +485,13 @@ export function ɵɵcontentQuery( export function ɵɵstaticContentQuery( directiveIndex: number, predicate: Type| string[], descend: boolean, read?: any): void { contentQueryInternal( - getLView(), predicate, descend, read, true, getPreviousOrParentTNode(), directiveIndex); + getTView(), getLView(), predicate, descend, read, true, getPreviousOrParentTNode(), + directiveIndex); } function contentQueryInternal( - lView: LView, predicate: Type| string[], descend: boolean, read: any, isStatic: boolean, - tNode: TNode, directiveIndex: number): void { - const tView = lView[TVIEW]; + tView: TView, lView: LView, predicate: Type| string[], descend: boolean, read: any, + isStatic: boolean, tNode: TNode, directiveIndex: number): void { if (tView.firstCreatePass) { createTQuery(tView, new TQueryMetadata_(predicate, descend, isStatic, read), tNode.index); saveContentQueryAndDirectiveIndex(tView, directiveIndex); @@ -496,7 +500,7 @@ function contentQueryInternal( } } - createLQuery(lView); + createLQuery(tView, lView); } /** @@ -515,9 +519,9 @@ function loadQueryInternal(lView: LView, queryIndex: number): QueryList { return lView[QUERIES] !.queries[queryIndex].queryList; } -function createLQuery(lView: LView) { +function createLQuery(tView: TView, lView: LView) { const queryList = new QueryList(); - storeCleanupWithContext(lView, queryList, queryList.destroy); + storeCleanupWithContext(tView, lView, queryList, queryList.destroy); if (lView[QUERIES] === null) lView[QUERIES] = new LQueries_(); lView[QUERIES] !.queries.push(new LQuery_(queryList)); diff --git a/packages/core/src/render3/state.ts b/packages/core/src/render3/state.ts index c68dc42841..63816da418 100644 --- a/packages/core/src/render3/state.ts +++ b/packages/core/src/render3/state.ts @@ -10,7 +10,7 @@ import {StyleSanitizeFn} from '../sanitization/style_sanitizer'; import {assertDefined} from '../util/assert'; import {assertLViewOrUndefined} from './assert'; import {TNode} from './interfaces/node'; -import {CONTEXT, DECLARATION_VIEW, LView, OpaqueViewState, TVIEW} from './interfaces/view'; +import {CONTEXT, DECLARATION_VIEW, LView, OpaqueViewState, TVIEW, TView} from './interfaces/view'; /** @@ -39,6 +39,14 @@ interface LFrame { */ lView: LView; + /** + * Current `TView` associated with the `LFrame.lView`. + * + * One can get `TView` from `lFrame[TVIEW]` however because it is so common it makes sense to + * store it in `LFrame` for perf reasons. + */ + tView: TView; + /** * Used to set the parent property when nodes are created and track query results. * @@ -229,15 +237,17 @@ export function ɵɵdisableBindings(): void { } /** - * Return the current LView. - * - * The return value can be `null` if the method is called outside of template. This can happen if - * directive is instantiated by module injector (rather than by node injector.) + * Return the current `LView`. */ export function getLView(): LView { - // TODO(misko): the return value should be `LView|null` but doing so breaks a lot of code. - const lFrame = instructionState.lFrame; - return lFrame === null ? null ! : lFrame.lView; + return instructionState.lFrame.lView; +} + +/** + * Return the current `TView`. + */ +export function getTView(): TView { + return instructionState.lFrame.tView; } /** @@ -293,8 +303,7 @@ export function getBindingRoot() { const lFrame = instructionState.lFrame; let index = lFrame.bindingRootIndex; if (index === -1) { - const lView = lFrame.lView; - index = lFrame.bindingRootIndex = lView[TVIEW].bindingStartIndex; + index = lFrame.bindingRootIndex = lFrame.tView.bindingStartIndex; } return index; } @@ -402,10 +411,12 @@ export const leaveDI = leaveView; export function enterView(newView: LView, tNode: TNode | null): void { ngDevMode && assertLViewOrUndefined(newView); const newLFrame = allocLFrame(); + const tView = newView[TVIEW]; instructionState.lFrame = newLFrame; newLFrame.previousOrParentTNode = tNode !; newLFrame.isParent = true; newLFrame.lView = newView; + newLFrame.tView = tView; newLFrame.selectedIndex = 0; newLFrame.contextLView = newView !; newLFrame.elementDepthCount = 0; @@ -413,7 +424,7 @@ export function enterView(newView: LView, tNode: TNode | null): void { newLFrame.currentNamespace = null; newLFrame.currentSanitizer = null; newLFrame.bindingRootIndex = -1; - newLFrame.bindingIndex = newView === null ? -1 : newView[TVIEW].bindingStartIndex; + newLFrame.bindingIndex = tView.bindingStartIndex; newLFrame.currentQueryIndex = 0; } @@ -432,6 +443,7 @@ function createLFrame(parent: LFrame | null): LFrame { previousOrParentTNode: null !, // isParent: true, // lView: null !, // + tView: null !, // selectedIndex: 0, // contextLView: null !, // elementDepthCount: 0, // diff --git a/packages/core/src/render3/styling/static_styling.ts b/packages/core/src/render3/styling/static_styling.ts index 8944d8aae7..9a54073ac9 100644 --- a/packages/core/src/render3/styling/static_styling.ts +++ b/packages/core/src/render3/styling/static_styling.ts @@ -9,8 +9,7 @@ import {concatStringsWithSpace} from '../../util/stringify'; import {assertFirstCreatePass} from '../assert'; import {AttributeMarker, TAttributes, TNode} from '../interfaces/node'; -import {TVIEW} from '../interfaces/view'; -import {getLView} from '../state'; +import {getTView} from '../state'; /** * Compute the static styling (class/style) from `TAttributes`. @@ -21,8 +20,8 @@ import {getLView} from '../state'; * @param attrs `TAttributes` containing the styling information. */ export function computeStaticStyling(tNode: TNode, attrs: TAttributes): void { - ngDevMode && assertFirstCreatePass( - getLView()[TVIEW], 'Expecting to be called in first template pass only'); + ngDevMode && + assertFirstCreatePass(getTView(), 'Expecting to be called in first template pass only'); let styles: string|null = tNode.styles; let classes: string|null = tNode.classes; let mode: AttributeMarker|0 = 0; diff --git a/packages/core/src/render3/styling/style_binding_list.ts b/packages/core/src/render3/styling/style_binding_list.ts index 33dd41d435..808e4e11eb 100644 --- a/packages/core/src/render3/styling/style_binding_list.ts +++ b/packages/core/src/render3/styling/style_binding_list.ts @@ -11,9 +11,8 @@ import {assertDataInRange, assertEqual, assertNotEqual} from '../../util/assert' import {assertFirstUpdatePass} from '../assert'; import {TNode} from '../interfaces/node'; import {TStylingKey, TStylingKeyPrimitive, TStylingRange, getTStylingRangeNext, getTStylingRangePrev, setTStylingRangeNext, setTStylingRangeNextDuplicate, setTStylingRangePrev, setTStylingRangePrevDuplicate, toTStylingRange} from '../interfaces/styling'; -import {TData, TVIEW} from '../interfaces/view'; -import {getLView} from '../state'; - +import {TData} from '../interfaces/view'; +import {getTView} from '../state'; /** @@ -194,7 +193,7 @@ let __unused_const_as_closure_does_not_like_standalone_comment_blocks__: undefin export function insertTStylingBinding( tData: TData, tNode: TNode, tStylingKeyWithStatic: TStylingKey, index: number, isHostBinding: boolean, isClassBinding: boolean): void { - ngDevMode && assertFirstUpdatePass(getLView()[TVIEW]); + ngDevMode && assertFirstUpdatePass(getTView()); let tBindings = isClassBinding ? tNode.classBindings : tNode.styleBindings; let tmplHead = getTStylingRangePrev(tBindings); let tmplTail = getTStylingRangeNext(tBindings); diff --git a/packages/core/src/render3/util/discovery_utils.ts b/packages/core/src/render3/util/discovery_utils.ts index 2a03289758..695d2899ff 100644 --- a/packages/core/src/render3/util/discovery_utils.ts +++ b/packages/core/src/render3/util/discovery_utils.ts @@ -16,7 +16,6 @@ import {DirectiveDef} from '../interfaces/definition'; import {TElementNode, TNode, TNodeProviderIndexes} from '../interfaces/node'; import {isLView} from '../interfaces/type_checks'; import {CLEANUP, CONTEXT, FLAGS, HEADER_OFFSET, HOST, LView, LViewFlags, TVIEW, T_HOST} from '../interfaces/view'; - import {stringifyForError} from './misc_utils'; import {getLViewParent, getRootContext} from './view_traversal_utils'; import {getTNode, unwrapRNode} from './view_utils'; @@ -388,7 +387,7 @@ export function getDebugNode(element: Element): DebugNode|null { // this means that value in the lView is a component with its own // data. In this situation the TNode is not accessed at the same spot. const tNode = isLView(valueInLView) ? (valueInLView[T_HOST] as TNode) : - getTNode(nodeIndex - HEADER_OFFSET, lView); + getTNode(lView[TVIEW], nodeIndex - HEADER_OFFSET); debugNode = buildDebugNode(tNode, lView, nodeIndex); } diff --git a/packages/core/src/render3/util/view_utils.ts b/packages/core/src/render3/util/view_utils.ts index f9af88e232..d98c91f825 100644 --- a/packages/core/src/render3/util/view_utils.ts +++ b/packages/core/src/render3/util/view_utils.ts @@ -13,7 +13,7 @@ import {LContext, MONKEY_PATCH_KEY_NAME} from '../interfaces/context'; import {TConstants, TNode} from '../interfaces/node'; import {RNode, isProceduralRenderer} from '../interfaces/renderer'; import {isLContainer, isLView} from '../interfaces/type_checks'; -import {FLAGS, HEADER_OFFSET, HOST, LView, LViewFlags, PARENT, PREORDER_HOOK_FLAGS, RENDERER, TData, TVIEW} from '../interfaces/view'; +import {FLAGS, HEADER_OFFSET, HOST, LView, LViewFlags, PARENT, PREORDER_HOOK_FLAGS, RENDERER, TData, TView} from '../interfaces/view'; @@ -117,10 +117,10 @@ export function getNativeByTNodeOrNull(tNode: TNode, lView: LView): RNode|null { } -export function getTNode(index: number, view: LView): TNode { +export function getTNode(tView: TView, index: number): TNode { ngDevMode && assertGreaterThan(index, -1, 'wrong index for TNode'); - ngDevMode && assertLessThan(index, view[TVIEW].data.length, 'wrong index for TNode'); - return view[TVIEW].data[index + HEADER_OFFSET] as TNode; + ngDevMode && assertLessThan(index, tView.data.length, 'wrong index for TNode'); + return tView.data[index + HEADER_OFFSET] as TNode; } /** Retrieves a value from any `LView` or `TData`. */ diff --git a/packages/core/src/render3/view_engine_compatibility.ts b/packages/core/src/render3/view_engine_compatibility.ts index a82ad0c66d..36c9aa2b75 100644 --- a/packages/core/src/render3/view_engine_compatibility.ts +++ b/packages/core/src/render3/view_engine_compatibility.ts @@ -25,7 +25,7 @@ import {ActiveIndexFlag, CONTAINER_HEADER_OFFSET, LContainer, VIEW_REFS} from '. import {TContainerNode, TDirectiveHostNode, TElementContainerNode, TElementNode, TNode, TNodeType, TViewNode} from './interfaces/node'; import {RComment, RElement, isProceduralRenderer} from './interfaces/renderer'; import {isComponentHost, isLContainer, isLView, isRootView} from './interfaces/type_checks'; -import {DECLARATION_COMPONENT_VIEW, DECLARATION_LCONTAINER, LView, LViewFlags, PARENT, QUERIES, RENDERER, TView, T_HOST} from './interfaces/view'; +import {DECLARATION_COMPONENT_VIEW, DECLARATION_LCONTAINER, LView, LViewFlags, PARENT, QUERIES, RENDERER, TVIEW, TView, T_HOST} from './interfaces/view'; import {assertNodeOfPossibleTypes} from './node_assert'; import {addRemoveViewFromContainer, appendChild, detachView, getBeforeNodeForView, insertView, nativeInsertBefore, nativeNextSibling, nativeParentNode, removeView} from './node_manipulation'; import {getParentInjectorTNode} from './node_util'; @@ -104,23 +104,23 @@ export function createTemplateRef( createEmbeddedView(context: T): viewEngine_EmbeddedViewRef { const embeddedTView = this._declarationTContainer.tViews as TView; - const lView = createLView( + const embeddedLView = createLView( this._declarationView, embeddedTView, context, LViewFlags.CheckAlways, null, embeddedTView.node); const declarationLContainer = this._declarationView[this._declarationTContainer.index]; ngDevMode && assertLContainer(declarationLContainer); - lView[DECLARATION_LCONTAINER] = declarationLContainer; + embeddedLView[DECLARATION_LCONTAINER] = declarationLContainer; const declarationViewLQueries = this._declarationView[QUERIES]; if (declarationViewLQueries !== null) { - lView[QUERIES] = declarationViewLQueries.createEmbeddedView(embeddedTView); + embeddedLView[QUERIES] = declarationViewLQueries.createEmbeddedView(embeddedTView); } - renderView(lView, embeddedTView, context); + renderView(embeddedTView, embeddedLView, context); - const viewRef = new ViewRef(lView); - viewRef._tViewNode = lView[T_HOST] as TViewNode; + const viewRef = new ViewRef(embeddedLView); + viewRef._tViewNode = embeddedLView[T_HOST] as TViewNode; return viewRef; } }; @@ -238,6 +238,7 @@ export function createContainerRef( insert(viewRef: viewEngine_ViewRef, index?: number): viewEngine_ViewRef { const lView = (viewRef as ViewRef)._lView !; + const tView = lView[TVIEW]; if (viewRef.destroyed) { throw new Error('Cannot insert a destroyed View in a ViewContainer!'); @@ -274,10 +275,10 @@ export function createContainerRef( } const adjustedIdx = this._adjustIndex(index); - insertView(lView, this._lContainer, adjustedIdx); + insertView(tView, lView, this._lContainer, adjustedIdx); const beforeNode = getBeforeNodeForView(adjustedIdx, this._lContainer); - addRemoveViewFromContainer(lView, true, beforeNode); + addRemoveViewFromContainer(tView, lView, true, beforeNode); (viewRef as ViewRef).attachToViewContainerRef(this); addToArray(this._lContainer[VIEW_REFS] !, adjustedIdx, viewRef); @@ -367,7 +368,7 @@ export function createContainerRef( nativeInsertBefore( renderer, parentOfHostNative !, commentNode, nativeNextSibling(renderer, hostNative)); } else { - appendChild(commentNode, hostTNode, hostView); + appendChild(hostView[TVIEW], hostView, commentNode, hostTNode); } } diff --git a/packages/core/src/render3/view_ref.ts b/packages/core/src/render3/view_ref.ts index 091d3c9204..722733dbb4 100644 --- a/packages/core/src/render3/view_ref.ts +++ b/packages/core/src/render3/view_ref.ts @@ -10,12 +10,11 @@ import {ApplicationRef} from '../application_ref'; import {ChangeDetectorRef as viewEngine_ChangeDetectorRef} from '../change_detection/change_detector_ref'; import {ViewContainerRef as viewEngine_ViewContainerRef} from '../linker/view_container_ref'; import {EmbeddedViewRef as viewEngine_EmbeddedViewRef, InternalViewRef as viewEngine_InternalViewRef} from '../linker/view_ref'; - import {checkNoChangesInRootView, checkNoChangesInternal, detectChangesInRootView, detectChangesInternal, markViewDirty, storeCleanupFn} from './instructions/shared'; import {CONTAINER_HEADER_OFFSET} from './interfaces/container'; import {TElementNode, TNode, TNodeType, TViewNode} from './interfaces/node'; import {isLContainer} from './interfaces/type_checks'; -import {CONTEXT, DECLARATION_COMPONENT_VIEW, FLAGS, HOST, LView, LViewFlags, TVIEW, T_HOST} from './interfaces/view'; +import {CONTEXT, DECLARATION_COMPONENT_VIEW, FLAGS, HOST, LView, LViewFlags, TVIEW, TView, T_HOST} from './interfaces/view'; import {assertNodeOfPossibleTypes} from './node_assert'; import {destroyLView, renderDetachView} from './node_manipulation'; import {getLViewParent} from './util/view_traversal_utils'; @@ -39,9 +38,10 @@ export class ViewRef implements viewEngine_EmbeddedViewRef, viewEngine_Int public _tViewNode: TViewNode|null = null; get rootNodes(): any[] { - if (this._lView[HOST] == null) { - const tView = this._lView[T_HOST] as TViewNode; - return collectNativeNodes(this._lView, tView.child, []); + const lView = this._lView; + if (lView[HOST] == null) { + const hostTView = lView[T_HOST] as TViewNode; + return collectNativeNodes(lView[TVIEW], lView, hostTView.child, []); } return []; } @@ -86,10 +86,10 @@ export class ViewRef implements viewEngine_EmbeddedViewRef, viewEngine_Int this._viewContainerRef = null; } - destroyLView(this._lView); + destroyLView(this._lView[TVIEW], this._lView); } - onDestroy(callback: Function) { storeCleanupFn(this._lView, callback); } + onDestroy(callback: Function) { storeCleanupFn(this._lView[TVIEW], this._lView, callback); } /** * Marks a view and all of its ancestors dirty. @@ -261,7 +261,7 @@ export class ViewRef implements viewEngine_EmbeddedViewRef, viewEngine_Int * * See {@link ChangeDetectorRef#detach detach} for more information. */ - detectChanges(): void { detectChangesInternal(this._lView, this.context); } + detectChanges(): void { detectChangesInternal(this._lView[TVIEW], this._lView, this.context); } /** * Checks the change detector and its children, and throws if any changes are detected. @@ -269,7 +269,7 @@ export class ViewRef implements viewEngine_EmbeddedViewRef, viewEngine_Int * This is used in development mode to verify that running change detection doesn't * introduce other changes. */ - checkNoChanges(): void { checkNoChangesInternal(this._lView, this.context); } + checkNoChanges(): void { checkNoChangesInternal(this._lView[TVIEW], this._lView, this.context); } attachToViewContainerRef(vcRef: viewEngine_ViewContainerRef) { if (this._appRef) { @@ -280,7 +280,7 @@ export class ViewRef implements viewEngine_EmbeddedViewRef, viewEngine_Int detachFromAppRef() { this._appRef = null; - renderDetachView(this._lView); + renderDetachView(this._lView[TVIEW], this._lView); } attachToAppRef(appRef: ApplicationRef) { @@ -303,7 +303,8 @@ export class RootViewRef extends ViewRef { } function collectNativeNodes( - lView: LView, tNode: TNode | null, result: any[], isProjection: boolean = false): any[] { + tView: TView, lView: LView, tNode: TNode | null, result: any[], + isProjection: boolean = false): any[] { while (tNode !== null) { ngDevMode && assertNodeOfPossibleTypes( tNode, TNodeType.Element, TNodeType.Container, TNodeType.Projection, @@ -322,14 +323,15 @@ function collectNativeNodes( const lViewInAContainer = lNode[i]; const lViewFirstChildTNode = lViewInAContainer[TVIEW].firstChild; if (lViewFirstChildTNode !== null) { - collectNativeNodes(lViewInAContainer, lViewFirstChildTNode, result); + collectNativeNodes( + lViewInAContainer[TVIEW], lViewInAContainer, lViewFirstChildTNode, result); } } } const tNodeType = tNode.type; if (tNodeType === TNodeType.ElementContainer || tNodeType === TNodeType.IcuContainer) { - collectNativeNodes(lView, tNode.child, result); + collectNativeNodes(tView, lView, tNode.child, result); } else if (tNodeType === TNodeType.Projection) { const componentView = lView[DECLARATION_COMPONENT_VIEW]; const componentHost = componentView[T_HOST] as TElementNode; @@ -337,7 +339,7 @@ function collectNativeNodes( let firstProjectedNode: TNode|null = (componentHost.projection as(TNode | null)[])[tNode.projection as number]; if (firstProjectedNode !== null && parentView !== null) { - collectNativeNodes(parentView, firstProjectedNode, result, true); + collectNativeNodes(parentView[TVIEW], parentView, firstProjectedNode, result, true); } } tNode = isProjection ? tNode.projectionNext : tNode.next; diff --git a/packages/core/test/bundling/cyclic_import/bundle.golden_symbols.json b/packages/core/test/bundling/cyclic_import/bundle.golden_symbols.json index 7999a421e4..b2c2a743f7 100644 --- a/packages/core/test/bundling/cyclic_import/bundle.golden_symbols.json +++ b/packages/core/test/bundling/cyclic_import/bundle.golden_symbols.json @@ -386,6 +386,9 @@ { "name": "getSelectedIndex" }, + { + "name": "getTView" + }, { "name": "growHostVarsSpace" }, diff --git a/packages/core/test/bundling/hello_world/bundle.golden_symbols.json b/packages/core/test/bundling/hello_world/bundle.golden_symbols.json index 1f19f46d8b..3198731638 100644 --- a/packages/core/test/bundling/hello_world/bundle.golden_symbols.json +++ b/packages/core/test/bundling/hello_world/bundle.golden_symbols.json @@ -323,6 +323,9 @@ { "name": "getSelectedIndex" }, + { + "name": "getTView" + }, { "name": "growHostVarsSpace" }, diff --git a/packages/core/test/bundling/todo/bundle.golden_symbols.json b/packages/core/test/bundling/todo/bundle.golden_symbols.json index 5898645355..9b6679651a 100644 --- a/packages/core/test/bundling/todo/bundle.golden_symbols.json +++ b/packages/core/test/bundling/todo/bundle.golden_symbols.json @@ -566,9 +566,6 @@ { "name": "getCheckNoChangesMode" }, - { - "name": "getCleanup" - }, { "name": "getClosureSafeProperty" }, @@ -629,6 +626,9 @@ { "name": "getIsParent" }, + { + "name": "getLCleanup" + }, { "name": "getLContainer" }, @@ -725,6 +725,9 @@ { "name": "getTStylingRangePrevDuplicate" }, + { + "name": "getTView" + }, { "name": "getTViewCleanup" }, diff --git a/packages/core/test/render3/perf/directive_inputs/index.ts b/packages/core/test/render3/perf/directive_inputs/index.ts index 1898e6fef5..3129875312 100644 --- a/packages/core/test/render3/perf/directive_inputs/index.ts +++ b/packages/core/test/render3/perf/directive_inputs/index.ts @@ -61,7 +61,7 @@ const updateTime = directiveInputs('update'); console.profile('directive_inputs'); while (updateTime()) { ctx.counter++; - refreshView(rootLView, rootTView, null, null); + refreshView(rootTView, rootLView, null, null); } console.profileEnd(); diff --git a/packages/core/test/render3/perf/duplicate_map_based_style_and_class_bindings/index.ts b/packages/core/test/render3/perf/duplicate_map_based_style_and_class_bindings/index.ts index 2d91e4de8e..b8d3a02b31 100644 --- a/packages/core/test/render3/perf/duplicate_map_based_style_and_class_bindings/index.ts +++ b/packages/core/test/render3/perf/duplicate_map_based_style_and_class_bindings/index.ts @@ -167,7 +167,7 @@ const refreshTime = duplicateMapBasedStyleAndClassBindingsBenchmark('refresh'); // run change detection in the update mode console.profile('duplicate_map_based_style_and_class_bindings_refresh'); while (refreshTime()) { - refreshView(rootLView, rootTView, null, null); + refreshView(rootTView, rootLView, null, null); } console.profileEnd(); diff --git a/packages/core/test/render3/perf/duplicate_style_and_class_bindings/index.ts b/packages/core/test/render3/perf/duplicate_style_and_class_bindings/index.ts index 4ac9aea0f2..89ef94b473 100644 --- a/packages/core/test/render3/perf/duplicate_style_and_class_bindings/index.ts +++ b/packages/core/test/render3/perf/duplicate_style_and_class_bindings/index.ts @@ -167,7 +167,7 @@ const refreshTime = duplicateStyleAndClassBindingsBenchmark('refresh'); // run change detection in the update mode console.profile('duplicate_style_and_class_bindings_refresh'); while (refreshTime()) { - refreshView(rootLView, rootTView, null, null); + refreshView(rootTView, rootLView, null, null); } console.profileEnd(); diff --git a/packages/core/test/render3/perf/interpolation/index.ts b/packages/core/test/render3/perf/interpolation/index.ts index dea2c4f17d..e25efa1fb1 100644 --- a/packages/core/test/render3/perf/interpolation/index.ts +++ b/packages/core/test/render3/perf/interpolation/index.ts @@ -99,7 +99,7 @@ const refreshTime = interpolationRefresh('refresh'); // run change detection in the update mode console.profile('interpolation_refresh'); while (refreshTime()) { - refreshView(rootLView, rootTView, null, null); + refreshView(rootTView, rootLView, null, null); } console.profileEnd(); diff --git a/packages/core/test/render3/perf/map_based_style_and_class_bindings/index.ts b/packages/core/test/render3/perf/map_based_style_and_class_bindings/index.ts index 5ef13e8f14..61248bf009 100644 --- a/packages/core/test/render3/perf/map_based_style_and_class_bindings/index.ts +++ b/packages/core/test/render3/perf/map_based_style_and_class_bindings/index.ts @@ -88,7 +88,7 @@ const refreshTime = styleAndClassBindingMapBenchmark('refresh'); // run change detection in the update mode console.profile('style_and_class_map_binding_refresh'); while (refreshTime()) { - refreshView(rootLView, rootTView, null, null); + refreshView(rootTView, rootLView, null, null); } console.profileEnd(); diff --git a/packages/core/test/render3/perf/noop_change_detection/index.ts b/packages/core/test/render3/perf/noop_change_detection/index.ts index b77b373e57..29ccaec750 100644 --- a/packages/core/test/render3/perf/noop_change_detection/index.ts +++ b/packages/core/test/render3/perf/noop_change_detection/index.ts @@ -20,7 +20,7 @@ const refreshTime = noopChangeDetection('refresh'); // run change detection in the update mode console.profile('noop_change_detection'); while (refreshTime()) { - refreshView(rootLView, rootTView, null, null); + refreshView(rootTView, rootLView, null, null); } console.profileEnd(); diff --git a/packages/core/test/render3/perf/property_binding/index.ts b/packages/core/test/render3/perf/property_binding/index.ts index fe403ecedb..810959f88c 100644 --- a/packages/core/test/render3/perf/property_binding/index.ts +++ b/packages/core/test/render3/perf/property_binding/index.ts @@ -78,7 +78,7 @@ const refreshTime = propertyBindingRefresh('refresh'); // run change detection in the update mode console.profile('property_binding_refresh'); while (refreshTime()) { - refreshView(rootLView, rootTView, null, null); + refreshView(rootTView, rootLView, null, null); } console.profileEnd(); diff --git a/packages/core/test/render3/perf/property_binding_update/index.ts b/packages/core/test/render3/perf/property_binding_update/index.ts index 860388c02b..2baacbf5f8 100644 --- a/packages/core/test/render3/perf/property_binding_update/index.ts +++ b/packages/core/test/render3/perf/property_binding_update/index.ts @@ -84,7 +84,7 @@ console.profile('element property update'); let i = 0; while (updateTime()) { ctx.value = `value${i++}`; - refreshView(rootLView, rootTView, null, ctx); + refreshView(rootTView, rootLView, null, ctx); } console.profileEnd(); diff --git a/packages/core/test/render3/perf/setup.ts b/packages/core/test/render3/perf/setup.ts index 9c917cfd3e..2eddc4e5ec 100644 --- a/packages/core/test/render3/perf/setup.ts +++ b/packages/core/test/render3/perf/setup.ts @@ -9,7 +9,7 @@ import {addToViewTree, createLContainer, createLView, createTNode, createTView, import {ComponentTemplate, DirectiveDefList} from '../../../src/render3/interfaces/definition'; import {TAttributes, TNodeType, TViewNode} from '../../../src/render3/interfaces/node'; import {RendererFactory3, domRendererFactory3} from '../../../src/render3/interfaces/renderer'; -import {LView, LViewFlags, TView, TViewType} from '../../../src/render3/interfaces/view'; +import {LView, LViewFlags, TVIEW, TView, TViewType} from '../../../src/render3/interfaces/view'; import {insertView} from '../../../src/render3/node_manipulation'; import {MicroBenchmarkRendererFactory} from './noop_renderer'; @@ -22,7 +22,7 @@ const renderer = rendererFactory.createRenderer(null, null); export function createAndRenderLView(parentLView: LView, tView: TView, hostTNode: TViewNode) { const embeddedLView = createLView( parentLView, tView, {}, LViewFlags.CheckAlways, null, hostTNode, rendererFactory, renderer); - renderView(embeddedLView, tView, null); + renderView(tView, embeddedLView, null); } export function setupRootViewWithEmbeddedViews( @@ -68,17 +68,18 @@ export function setupTestHarness( const embeddedLView = createLView( hostLView, embeddedTView, embeddedViewContext, LViewFlags.CheckAlways, null, viewTNode, rendererFactory, renderer); - renderView(embeddedLView, embeddedTView, embeddedViewContext); + renderView(embeddedTView, embeddedLView, embeddedViewContext); return embeddedLView; } function detectChanges(): void { - refreshView(hostLView, hostTView, hostTView.template, embeddedViewContext); + refreshView(hostTView, hostLView, hostTView.template, embeddedViewContext); } // create embedded views and add them to the container for (let i = 0; i < noOfViews; i++) { - insertView(createEmbeddedLView(), lContainer, i); + const lView = createEmbeddedLView(); + insertView(lView[TVIEW], lView, lContainer, i); } return { diff --git a/packages/core/test/render3/perf/style_and_class_bindings/index.ts b/packages/core/test/render3/perf/style_and_class_bindings/index.ts index 1d1af47729..84a6cf4de9 100644 --- a/packages/core/test/render3/perf/style_and_class_bindings/index.ts +++ b/packages/core/test/render3/perf/style_and_class_bindings/index.ts @@ -92,7 +92,7 @@ const refreshTime = styleAndClassBindingBenchmark('refresh'); // run change detection in the update mode console.profile('style_and_class_binding_refresh'); while (refreshTime()) { - refreshView(rootLView, rootTView, null, null); + refreshView(rootTView, rootLView, null, null); } console.profileEnd(); diff --git a/packages/core/test/render3/perf/style_binding/index.ts b/packages/core/test/render3/perf/style_binding/index.ts index 4457439545..5e63677bb1 100644 --- a/packages/core/test/render3/perf/style_binding/index.ts +++ b/packages/core/test/render3/perf/style_binding/index.ts @@ -78,7 +78,7 @@ const refreshTime = styleBindingBenchmark('refresh'); // run change detection in the update mode console.profile('style_binding_refresh'); while (refreshTime()) { - refreshView(rootLView, rootTView, null, null); + refreshView(rootTView, rootLView, null, null); } console.profileEnd(); diff --git a/packages/core/test/render3/render_util.ts b/packages/core/test/render3/render_util.ts index 5f3fb49a52..d4c84c4a0a 100644 --- a/packages/core/test/render3/render_util.ts +++ b/packages/core/test/render3/render_util.ts @@ -32,7 +32,7 @@ import {ComponentDef, ComponentTemplate, ComponentType, DirectiveDef, DirectiveT import {DirectiveDefList, DirectiveDefListOrFactory, DirectiveTypesOrFactory, HostBindingsFunction, PipeDef, PipeDefList, PipeDefListOrFactory, PipeTypesOrFactory} from '../../src/render3/interfaces/definition'; import {PlayerHandler} from '../../src/render3/interfaces/player'; import {ProceduralRenderer3, RComment, RElement, RNode, RText, Renderer3, RendererFactory3, RendererStyleFlags3, domRendererFactory3} from '../../src/render3/interfaces/renderer'; -import {HEADER_OFFSET, LView, LViewFlags, TViewType, T_HOST} from '../../src/render3/interfaces/view'; +import {HEADER_OFFSET, LView, LViewFlags, TVIEW, TViewType, T_HOST} from '../../src/render3/interfaces/view'; import {destroyLView} from '../../src/render3/node_manipulation'; import {getRootView} from '../../src/render3/util/view_traversal_utils'; import {Sanitizer} from '../../src/sanitization/sanitizer'; @@ -139,7 +139,7 @@ export class TemplateFixture extends BaseFixture { destroy(): void { this.containerElement.removeChild(this.hostElement); - destroyLView(this.hostView); + destroyLView(this.hostView[TVIEW], this.hostView); } } @@ -190,7 +190,8 @@ export class ComponentFixture extends BaseFixture { this.containerElement.removeChild(this.hostElement); } - destroyLView(getRootView(this.component)); + const rootLView = getRootView(this.component); + destroyLView(rootLView[TVIEW], rootLView); } } @@ -279,7 +280,7 @@ export function renderTemplate( hostLView, componentTView, context, LViewFlags.CheckAlways, hostNode, hostTNode, providedRendererFactory, renderer, sanitizer); } - renderComponentOrTemplate(componentView, templateFn, context); + renderComponentOrTemplate(componentView[TVIEW], componentView, templateFn, context); return componentView; }