diff --git a/packages/core/src/render3/component.ts b/packages/core/src/render3/component.ts index 5fac476310..6f436b01f8 100644 --- a/packages/core/src/render3/component.ts +++ b/packages/core/src/render3/component.ts @@ -17,7 +17,7 @@ import {assertComponentType} from './assert'; import {getComponentDef} from './definition'; import {diPublicInInjector, getOrCreateNodeInjectorForNode} from './di'; import {registerPostOrderHooks, registerPreOrderHooks} from './hooks'; -import {CLEAN_PROMISE, addToViewTree, createLView, createNodeAtIndex, createTView, getOrCreateTView, initNodeFlags, instantiateRootComponent, invokeHostBindingsInCreationMode, locateHostElement, queueComponentIndexForCheck, refreshDescendantViews} from './instructions/shared'; +import {CLEAN_PROMISE, addToViewTree, createLView, createTView, getOrCreateTNode, getOrCreateTView, initNodeFlags, instantiateRootComponent, invokeHostBindingsInCreationMode, locateHostElement, queueComponentIndexForCheck, refreshDescendantViews} from './instructions/shared'; import {ComponentDef, ComponentType, RenderFlags} from './interfaces/definition'; import {TElementNode, TNode, TNodeFlags, TNodeType} from './interfaces/node'; import {PlayerHandler} from './interfaces/player'; @@ -175,7 +175,7 @@ export function createRootComponentView( const tView = rootView[TVIEW]; ngDevMode && assertDataInRange(rootView, 0 + HEADER_OFFSET); rootView[0 + HEADER_OFFSET] = rNode; - const tNode: TElementNode = createNodeAtIndex(0, TNodeType.Element, null, null); + const tNode: TElementNode = getOrCreateTNode(tView, null, 0, TNodeType.Element, null, null); const componentView = createLView( rootView, getOrCreateTView(def), null, def.onPush ? LViewFlags.Dirty : LViewFlags.CheckAlways, rootView[HEADER_OFFSET], tNode, rendererFactory, renderer, sanitizer); diff --git a/packages/core/src/render3/i18n.ts b/packages/core/src/render3/i18n.ts index 940160ce15..5cfb37f14e 100644 --- a/packages/core/src/render3/i18n.ts +++ b/packages/core/src/render3/i18n.ts @@ -17,7 +17,7 @@ import {assertDataInRange, assertDefined, assertEqual, assertGreaterThan} from ' import {attachPatchData} from './context_discovery'; import {attachI18nOpCodesDebug} from './debug'; import {ɵɵelementAttribute, ɵɵload, ɵɵtextBinding} from './instructions/all'; -import {allocExpando, createNodeAtIndex} from './instructions/shared'; +import {allocExpando, getOrCreateTNode} from './instructions/shared'; import {LContainer, NATIVE} from './interfaces/container'; import {COMMENT_MARKER, ELEMENT_MARKER, I18nMutateOpCode, I18nMutateOpCodes, I18nUpdateOpCode, I18nUpdateOpCodes, IcuType, TI18n, TIcu} from './interfaces/i18n'; import {TElementNode, TIcuContainerNode, TNode, TNodeType} from './interfaces/node'; @@ -676,7 +676,7 @@ function createDynamicNodeAtIndex( const previousOrParentTNode = getPreviousOrParentTNode(); ngDevMode && assertDataInRange(lView, index + HEADER_OFFSET); lView[index + HEADER_OFFSET] = native; - const tNode = createNodeAtIndex(index, type as any, name, null); + const tNode = getOrCreateTNode(lView[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`. diff --git a/packages/core/src/render3/instructions/container.ts b/packages/core/src/render3/instructions/container.ts index f66e488bb7..c3869b2698 100644 --- a/packages/core/src/render3/instructions/container.ts +++ b/packages/core/src/render3/instructions/container.ts @@ -12,12 +12,14 @@ import {executePreOrderHooks, registerPostOrderHooks} from '../hooks'; import {ACTIVE_INDEX, CONTAINER_HEADER_OFFSET, LContainer} from '../interfaces/container'; import {ComponentTemplate} from '../interfaces/definition'; import {LocalRefExtractor, TAttributes, TContainerNode, TNode, TNodeType} from '../interfaces/node'; -import {BINDING_INDEX, HEADER_OFFSET, LView, QUERIES, RENDERER, TVIEW} from '../interfaces/view'; +import {BINDING_INDEX, HEADER_OFFSET, LView, QUERIES, RENDERER, TVIEW, T_HOST} from '../interfaces/view'; import {assertNodeType} from '../node_assert'; import {appendChild, removeView} from '../node_manipulation'; import {getCheckNoChangesMode, getIsParent, getLView, getPreviousOrParentTNode, setIsNotParent, setPreviousOrParentTNode} from '../state'; import {getNativeByTNode, loadInternal} from '../util/view_utils'; -import {addToViewTree, createDirectivesAndLocals, createLContainer, createNodeAtIndex, createTView} from './shared'; + +import {addToViewTree, createDirectivesAndLocals, createLContainer, createTView, getOrCreateTNode} from './shared'; + /** * Creates an LContainer for inline views, e.g. @@ -168,7 +170,8 @@ function containerInternal( ngDevMode && ngDevMode.rendererCreateComment++; const comment = lView[index + HEADER_OFFSET] = lView[RENDERER].createComment(ngDevMode ? 'container' : ''); - const tNode = createNodeAtIndex(index, TNodeType.Container, tagName, attrs); + const tNode = + getOrCreateTNode(lView[TVIEW], lView[T_HOST], index, TNodeType.Container, tagName, attrs); const lContainer = lView[adjustedIndex] = createLContainer(lView[adjustedIndex], lView, comment, tNode); diff --git a/packages/core/src/render3/instructions/element.ts b/packages/core/src/render3/instructions/element.ts index a603edca0f..b75bc91eb8 100644 --- a/packages/core/src/render3/instructions/element.ts +++ b/packages/core/src/render3/instructions/element.ts @@ -14,7 +14,7 @@ import {TAttributes, TNodeFlags, TNodeType} from '../interfaces/node'; import {RElement, isProceduralRenderer} from '../interfaces/renderer'; import {SanitizerFn} from '../interfaces/sanitization'; import {StylingContext} from '../interfaces/styling'; -import {BINDING_INDEX, HEADER_OFFSET, QUERIES, RENDERER, TVIEW} from '../interfaces/view'; +import {BINDING_INDEX, HEADER_OFFSET, QUERIES, RENDERER, TVIEW, T_HOST} from '../interfaces/view'; import {assertNodeType} from '../node_assert'; import {appendChild} from '../node_manipulation'; import {applyOnCreateInstructions} from '../node_util'; @@ -27,10 +27,12 @@ import {NO_CHANGE} from '../tokens'; import {attrsStylingIndexOf, setUpAttributes} from '../util/attrs_utils'; import {renderStringify} from '../util/misc_utils'; import {getNativeByIndex, getNativeByTNode, getTNode} from '../util/view_utils'; -import {createDirectivesAndLocals, createNodeAtIndex, elementCreate, executeContentQueries, initializeTNodeInputs, setInputsForProperty, setNodeStylingTemplate} from './shared'; + +import {createDirectivesAndLocals, elementCreate, executeContentQueries, getOrCreateTNode, initializeTNodeInputs, setInputsForProperty, setNodeStylingTemplate} from './shared'; import {getActiveDirectiveStylingIndex} from './styling'; + /** * Create DOM element. The instruction must later be followed by `elementEnd()` call. * @@ -58,7 +60,8 @@ export function ɵɵelementStart( ngDevMode && assertDataInRange(lView, index + HEADER_OFFSET); const native = lView[index + HEADER_OFFSET] = elementCreate(name); const renderer = lView[RENDERER]; - const tNode = createNodeAtIndex(index, TNodeType.Element, name, attrs || null); + const tNode = + getOrCreateTNode(tView, lView[T_HOST], index, TNodeType.Element, name, attrs || null); let initialStylesIndex = 0; let initialClassesIndex = 0; diff --git a/packages/core/src/render3/instructions/element_container.ts b/packages/core/src/render3/instructions/element_container.ts index dac999f7a1..1c38196a91 100644 --- a/packages/core/src/render3/instructions/element_container.ts +++ b/packages/core/src/render3/instructions/element_container.ts @@ -10,13 +10,14 @@ import {assertHasParent} from '../assert'; import {attachPatchData} from '../context_discovery'; import {registerPostOrderHooks} from '../hooks'; import {TAttributes, TNodeType} from '../interfaces/node'; -import {BINDING_INDEX, HEADER_OFFSET, QUERIES, RENDERER, TVIEW} from '../interfaces/view'; +import {BINDING_INDEX, HEADER_OFFSET, QUERIES, RENDERER, TVIEW, T_HOST} from '../interfaces/view'; import {assertNodeType} from '../node_assert'; import {appendChild} from '../node_manipulation'; import {applyOnCreateInstructions} from '../node_util'; import {getIsParent, getLView, getPreviousOrParentTNode, setIsNotParent, setPreviousOrParentTNode} from '../state'; -import {createDirectivesAndLocals, createNodeAtIndex, executeContentQueries, setNodeStylingTemplate} from './shared'; +import {createDirectivesAndLocals, executeContentQueries, getOrCreateTNode, setNodeStylingTemplate} from './shared'; + /** * Creates a logical container for other nodes () backed by a comment node in the DOM. @@ -47,7 +48,8 @@ export function ɵɵelementContainerStart( const native = lView[index + HEADER_OFFSET] = renderer.createComment(ngDevMode ? tagName : ''); ngDevMode && assertDataInRange(lView, index - 1); - const tNode = createNodeAtIndex(index, TNodeType.ElementContainer, tagName, attrs || null); + const tNode = getOrCreateTNode( + tView, lView[T_HOST], index, TNodeType.ElementContainer, tagName, attrs || null); if (attrs) { diff --git a/packages/core/src/render3/instructions/projection.ts b/packages/core/src/render3/instructions/projection.ts index efe348ee10..9d8f699734 100644 --- a/packages/core/src/render3/instructions/projection.ts +++ b/packages/core/src/render3/instructions/projection.ts @@ -8,13 +8,14 @@ import {assertDataInRange} from '../../util/assert'; import {TAttributes, TElementNode, TNode, TNodeType} from '../interfaces/node'; import {CssSelectorList} from '../interfaces/projection'; -import {HEADER_OFFSET, T_HOST} from '../interfaces/view'; +import {HEADER_OFFSET, TVIEW, T_HOST} from '../interfaces/view'; import {appendProjectedNodes} from '../node_manipulation'; import {matchingProjectionSelectorIndex} from '../node_selector_matcher'; import {getLView, setIsNotParent} from '../state'; import {findComponentView} from '../util/view_traversal_utils'; -import {createNodeAtIndex} from './shared'; +import {getOrCreateTNode} from './shared'; + /** @@ -82,7 +83,8 @@ export function ɵɵprojectionDef(selectors?: CssSelectorList[]): void { export function ɵɵprojection( nodeIndex: number, selectorIndex: number = 0, attrs?: TAttributes): void { const lView = getLView(); - const tProjectionNode = createNodeAtIndex(nodeIndex, TNodeType.Projection, null, attrs || null); + const tProjectionNode = getOrCreateTNode( + lView[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; diff --git a/packages/core/src/render3/instructions/shared.ts b/packages/core/src/render3/instructions/shared.ts index d94795fc78..948c3617d5 100644 --- a/packages/core/src/render3/instructions/shared.ts +++ b/packages/core/src/render3/instructions/shared.ts @@ -225,6 +225,10 @@ export function createLView( /** * Create and stores the TNode, and hooks it up to the tree. * + * @param tView The current `TView`. + * @param tHostNode This is a hack and we should not have to pass this value in. It is only used to + * determine if the parent belongs to a different tView. Instead we should not have parentTView + * point to TView other the current one. * @param index The index at which the TNode should be saved (null if view, since they are not * saved). * @param type The type of TNode to create @@ -232,61 +236,63 @@ export function createLView( * @param name The tag name of the associated native element, if applicable * @param attrs Any attrs for the native element, if applicable */ -export function createNodeAtIndex( - index: number, type: TNodeType.Element, name: string | null, - attrs: TAttributes | null): TElementNode; -export function createNodeAtIndex( - index: number, type: TNodeType.Container, name: string | null, - attrs: TAttributes | null): TContainerNode; -export function createNodeAtIndex( - index: number, type: TNodeType.Projection, name: null, +export function getOrCreateTNode( + tView: TView, tHostNode: TNode | null, index: number, type: TNodeType.Element, + name: string | null, attrs: TAttributes | null): TElementNode; +export function getOrCreateTNode( + tView: TView, tHostNode: TNode | null, index: number, type: TNodeType.Container, + name: string | null, attrs: TAttributes | null): TContainerNode; +export function getOrCreateTNode( + tView: TView, tHostNode: TNode | null, index: number, type: TNodeType.Projection, name: null, attrs: TAttributes | null): TProjectionNode; -export function createNodeAtIndex( - index: number, type: TNodeType.ElementContainer, name: string | null, +export function getOrCreateTNode( + tView: TView, tHostNode: TNode | null, index: number, type: TNodeType.ElementContainer, + name: string | null, attrs: TAttributes | null): TElementContainerNode; +export function getOrCreateTNode( + tView: TView, tHostNode: TNode | null, index: number, type: TNodeType.IcuContainer, name: null, attrs: TAttributes | null): TElementContainerNode; -export function createNodeAtIndex( - index: number, type: TNodeType.IcuContainer, name: null, - attrs: TAttributes | null): TElementContainerNode; -export function createNodeAtIndex( - index: number, type: TNodeType, name: string | null, attrs: TAttributes | null): TElementNode& - TContainerNode&TElementContainerNode&TProjectionNode&TIcuContainerNode { - const lView = getLView(); - const tView = lView[TVIEW]; +export function getOrCreateTNode( + tView: TView, tHostNode: TNode | null, index: number, type: TNodeType, name: string | null, + attrs: TAttributes | null): TElementNode&TContainerNode&TElementContainerNode&TProjectionNode& + TIcuContainerNode { + // Keep this function short, so that the VM will inline it. const adjustedIndex = index + HEADER_OFFSET; - let tNode = tView.data[adjustedIndex] as TNode; - if (tNode == null) { - const previousOrParentTNode = getPreviousOrParentTNode(); - const isParent = getIsParent(); - const parent = - isParent ? previousOrParentTNode : previousOrParentTNode && previousOrParentTNode.parent; - - // Parents cannot cross component boundaries because components will be used in multiple places, - // so it's only set if the view is the same. - const parentInSameView = parent && parent !== lView[T_HOST]; - const tParentNode = parentInSameView ? parent as TElementNode | TContainerNode : null; - - tNode = tView.data[adjustedIndex] = createTNode(tParentNode, type, adjustedIndex, name, attrs); - - // Now link ourselves into the tree. - if (previousOrParentTNode) { - if (isParent && previousOrParentTNode.child == null && - (tNode.parent !== null || previousOrParentTNode.type === TNodeType.View)) { - // We are in the same view, which means we are adding content node to the parent view. - previousOrParentTNode.child = tNode; - } else if (!isParent) { - previousOrParentTNode.next = tNode; - } - } - if (index === 0) { - tView.firstChild = tNode; - } - } - + const tNode = tView.data[adjustedIndex] as TNode || + createTNodeAtIndex(tView, tHostNode, adjustedIndex, type, name, attrs, index); setPreviousOrParentTNode(tNode, true); return tNode as TElementNode & TViewNode & TContainerNode & TElementContainerNode & TProjectionNode & TIcuContainerNode; } +function createTNodeAtIndex( + tView: TView, tHostNode: TNode | null, adjustedIndex: number, type: TNodeType, + name: string | null, attrs: TAttributes | null, index: number) { + const previousOrParentTNode = getPreviousOrParentTNode(); + const isParent = getIsParent(); + const parent = + isParent ? previousOrParentTNode : previousOrParentTNode && previousOrParentTNode.parent; + // Parents cannot cross component boundaries because components will be used in multiple places, + // so it's only set if the view is the same. + const parentInSameView = parent && parent !== tHostNode; + const tParentNode = parentInSameView ? parent as TElementNode | TContainerNode : null; + const tNode = tView.data[adjustedIndex] = + createTNode(tParentNode, type, adjustedIndex, name, attrs); + if (index === 0) { + tView.firstChild = tNode; + } + // Now link ourselves into the tree. + if (previousOrParentTNode) { + if (isParent && previousOrParentTNode.child == null && + (tNode.parent !== null || previousOrParentTNode.type === TNodeType.View)) { + // We are in the same view, which means we are adding content node to the parent view. + previousOrParentTNode.child = tNode; + } else if (!isParent) { + previousOrParentTNode.next = tNode; + } + } + return tNode; +} + export function assignTViewNodeToLView( tView: TView, tParentNode: TNode | null, index: number, lView: LView): TViewNode { // View nodes are not stored in data because they can be added / removed at runtime (which diff --git a/packages/core/src/render3/instructions/text.ts b/packages/core/src/render3/instructions/text.ts index 0833ddf958..7d11848ec4 100644 --- a/packages/core/src/render3/instructions/text.ts +++ b/packages/core/src/render3/instructions/text.ts @@ -8,13 +8,13 @@ import {assertDataInRange, assertDefined, assertEqual} from '../../util/assert'; import {TNodeType} from '../interfaces/node'; import {RText, isProceduralRenderer} from '../interfaces/renderer'; -import {BINDING_INDEX, HEADER_OFFSET, RENDERER, TVIEW} from '../interfaces/view'; +import {BINDING_INDEX, HEADER_OFFSET, RENDERER, TVIEW, T_HOST} from '../interfaces/view'; import {appendChild, createTextNode} from '../node_manipulation'; import {getLView, setIsNotParent} from '../state'; import {NO_CHANGE} from '../tokens'; import {renderStringify} from '../util/misc_utils'; import {getNativeByIndex} from '../util/view_utils'; -import {createNodeAtIndex} from './shared'; +import {getOrCreateTNode} from './shared'; /** * Create static text node @@ -32,7 +32,7 @@ export function ɵɵtext(index: number, value?: any): void { ngDevMode && ngDevMode.rendererCreateTextNode++; ngDevMode && assertDataInRange(lView, index + HEADER_OFFSET); const textNative = lView[index + HEADER_OFFSET] = createTextNode(value, lView[RENDERER]); - const tNode = createNodeAtIndex(index, TNodeType.Element, null, null); + const tNode = getOrCreateTNode(lView[TVIEW], lView[T_HOST], index, TNodeType.Element, null, null); // Text nodes are self closing. setIsNotParent(); 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 4a213bed80..191b915e60 100644 --- a/packages/core/test/bundling/cyclic_import/bundle.golden_symbols.json +++ b/packages/core/test/bundling/cyclic_import/bundle.golden_symbols.json @@ -245,9 +245,6 @@ { "name": "createLView" }, - { - "name": "createNodeAtIndex" - }, { "name": "createRootComponent" }, @@ -260,6 +257,9 @@ { "name": "createTNode" }, + { + "name": "createTNodeAtIndex" + }, { "name": "createTView" }, @@ -404,6 +404,9 @@ { "name": "getOrCreateNodeInjectorForNode" }, + { + "name": "getOrCreateTNode" + }, { "name": "getOrCreateTView" }, 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 53c7d21ec3..08560f42bc 100644 --- a/packages/core/test/bundling/hello_world/bundle.golden_symbols.json +++ b/packages/core/test/bundling/hello_world/bundle.golden_symbols.json @@ -173,9 +173,6 @@ { "name": "createLView" }, - { - "name": "createNodeAtIndex" - }, { "name": "createRootComponent" }, @@ -188,6 +185,9 @@ { "name": "createTNode" }, + { + "name": "createTNodeAtIndex" + }, { "name": "createTView" }, @@ -287,6 +287,9 @@ { "name": "getOrCreateNodeInjectorForNode" }, + { + "name": "getOrCreateTNode" + }, { "name": "getOrCreateTView" }, diff --git a/packages/core/test/bundling/todo/bundle.golden_symbols.json b/packages/core/test/bundling/todo/bundle.golden_symbols.json index d5aaa32bce..6fd35afd5c 100644 --- a/packages/core/test/bundling/todo/bundle.golden_symbols.json +++ b/packages/core/test/bundling/todo/bundle.golden_symbols.json @@ -560,9 +560,6 @@ { "name": "createLView" }, - { - "name": "createNodeAtIndex" - }, { "name": "createRootComponent" }, @@ -575,6 +572,9 @@ { "name": "createTNode" }, + { + "name": "createTNodeAtIndex" + }, { "name": "createTView" }, @@ -866,6 +866,9 @@ { "name": "getOrCreateNodeInjectorForNode" }, + { + "name": "getOrCreateTNode" + }, { "name": "getOrCreateTView" }, diff --git a/packages/core/test/render3/di_spec.ts b/packages/core/test/render3/di_spec.ts index d4ac5315ab..f56827c9ec 100644 --- a/packages/core/test/render3/di_spec.ts +++ b/packages/core/test/render3/di_spec.ts @@ -7,7 +7,7 @@ */ import {ChangeDetectorRef, Host, InjectFlags, Injector, Optional, Renderer2, Self, ViewContainerRef} from '@angular/core'; -import {createLView, createNodeAtIndex, createTView} from '@angular/core/src/render3/instructions/shared'; +import {createLView, createTView, getOrCreateTNode} from '@angular/core/src/render3/instructions/shared'; import {RenderFlags} from '@angular/core/src/render3/interfaces/definition'; import {ɵɵdefineComponent} from '../../src/render3/definition'; @@ -16,7 +16,7 @@ import {ɵɵbind, ɵɵcontainer, ɵɵcontainerRefreshEnd, ɵɵcontainerRefreshSt import {TNODE} from '../../src/render3/interfaces/injector'; import {TNodeType} from '../../src/render3/interfaces/node'; import {isProceduralRenderer} from '../../src/render3/interfaces/renderer'; -import {LViewFlags} from '../../src/render3/interfaces/view'; +import {LViewFlags, TVIEW} from '../../src/render3/interfaces/view'; import {enterView, leaveView} from '../../src/render3/state'; import {ViewRef} from '../../src/render3/view_ref'; @@ -605,7 +605,8 @@ describe('di', () => { null, null, {} as any, {} as any); const oldView = enterView(contentView, null); try { - const parentTNode = createNodeAtIndex(0, TNodeType.Element, null, null); + const parentTNode = + getOrCreateTNode(contentView[TVIEW], null, 0, TNodeType.Element, null, null); // Simulate the situation where the previous parent is not initialized. // This happens on first bootstrap because we don't init existing values // so that we have smaller HelloWorld. diff --git a/packages/core/test/render3/render_util.ts b/packages/core/test/render3/render_util.ts index 51e8d418d5..da2ff926bc 100644 --- a/packages/core/test/render3/render_util.ts +++ b/packages/core/test/render3/render_util.ts @@ -12,7 +12,7 @@ import {ElementRef} from '@angular/core/src/linker/element_ref'; import {TemplateRef} from '@angular/core/src/linker/template_ref'; import {ViewContainerRef} from '@angular/core/src/linker/view_container_ref'; import {Renderer2} from '@angular/core/src/render/api'; -import {createLView, createNodeAtIndex, createTView, getOrCreateTView, renderComponentOrTemplate} from '@angular/core/src/render3/instructions/shared'; +import {createLView, createTView, getOrCreateTNode, getOrCreateTView, renderComponentOrTemplate} from '@angular/core/src/render3/instructions/shared'; import {TNodeType} from '@angular/core/src/render3/interfaces/node'; import {enterView, getLView, resetComponentState} from '@angular/core/src/render3/state'; import {stringifyElement} from '@angular/platform-browser/testing/src/browser_util'; @@ -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} from '../../src/render3/interfaces/view'; +import {HEADER_OFFSET, LView, LViewFlags, TVIEW, 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/security'; @@ -253,9 +253,10 @@ export function renderTemplate( const renderer = providedRendererFactory.createRenderer(null, null); // We need to create a root view so it's possible to look up the host element through its index + const tView = createTView(-1, null, 1, 0, null, null, null, null); const hostLView = createLView( - null, createTView(-1, null, 1, 0, null, null, null, null), {}, - LViewFlags.CheckAlways | LViewFlags.IsRoot, null, null, providedRendererFactory, renderer); + null, tView, {}, LViewFlags.CheckAlways | LViewFlags.IsRoot, null, null, + providedRendererFactory, renderer); enterView(hostLView, null); // SUSPECT! why do we need to enter the View? const def: ComponentDef = ɵɵdefineComponent({ @@ -270,7 +271,8 @@ export function renderTemplate( def.pipeDefs = pipes || null; const componentTView = getOrCreateTView(def); - const hostTNode = createNodeAtIndex(0, TNodeType.Element, hostNode, null, null); + const hostTNode = getOrCreateTNode(tView, hostLView[T_HOST], 0, TNodeType.Element, null, null); + hostLView[hostTNode.index] = hostNode; componentView = createLView( hostLView, componentTView, context, LViewFlags.CheckAlways, hostNode, hostTNode, providedRendererFactory, renderer, sanitizer);