refactor(ivy): Explicitly pass in `TView` (#35069)
- Adds `TView` into `LFrame`, read the `TView` from `LView` on `enterView`. - Before this change the `TView` was ofter looked up from `LView` as `lView[TVIEW]`. This is suboptimal since reading from an Array, requires that the read checks array size before the read. This means that such a read has a much higher cost than reading from the property directly. By passing in the `TView` explicitly it makes the code more explicit and faster. - Some rearrangements of arguments so that `TView` would come before `LView` for consistency. PR Close #35069
This commit is contained in:
parent
770980de69
commit
d528dedd50
|
@ -144,9 +144,9 @@ export function renderComponent<T>(
|
|||
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();
|
||||
|
|
|
@ -174,7 +174,7 @@ export class ComponentFactory<T> extends viewEngine_ComponentFactory<T> {
|
|||
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<T> extends viewEngine_ComponentFactory<T> {
|
|||
component = createRootComponent(
|
||||
componentView, this.componentDef, rootLView, rootContext, [LifecycleHooksFeature]);
|
||||
|
||||
renderView(rootLView, rootTView, null);
|
||||
renderView(rootTView, rootLView, null);
|
||||
} finally {
|
||||
leaveView();
|
||||
}
|
||||
|
|
|
@ -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<T>(
|
||||
def: DirectiveDef<T>, 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);
|
||||
|
||||
|
|
|
@ -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<T>(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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<string[]>(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`;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<T>(
|
|||
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<T>(
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<T>(
|
|||
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<T>(
|
|||
* 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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<T>(lView: LView, tView: TView, context: T): void {
|
||||
export function renderView<T>(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<T>(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<T>(lView: LView, tView: TView, context: T): void {
|
|||
* - refreshing child (embedded and component) views.
|
||||
*/
|
||||
export function refreshView<T>(
|
||||
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<T>(
|
|||
|
||||
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<T>(
|
|||
}
|
||||
|
||||
export function renderComponentOrTemplate<T>(
|
||||
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<T>(
|
|||
}
|
||||
|
||||
function executeTemplate<T>(
|
||||
lView: LView, templateFn: ComponentTemplate<T>, rf: RenderFlags, context: T) {
|
||||
tView: TView, lView: LView, templateFn: ComponentTemplate<T>, 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<T>(
|
||||
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<T>(
|
|||
|
||||
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<T>(
|
|||
} 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<T>(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<T extends LView|LContainer>(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<T>(view: LView, context: T) {
|
||||
const rendererFactory = view[RENDERER_FACTORY];
|
||||
export function detectChangesInternal<T>(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<T>(view: LView, context: T) {
|
||||
export function checkNoChangesInternal<T>(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;
|
||||
|
|
|
@ -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<T>(index: number, value: T): void {
|
||||
const lView = getLView();
|
||||
const tView = lView[TVIEW];
|
||||
export function store<T>(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;
|
||||
|
|
|
@ -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<any>, key: string, value: any) => void,
|
||||
stringParser: (styleKeyValueArray: KeyValueArray<any>, 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 `<div [style] my-dir>` 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],
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<any>).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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<any>;
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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<T>(lView: LView, tQuery: TQuery, queryIndex: number): (T | null)[] {
|
||||
function materializeViewResults<T>(
|
||||
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<T>(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<T>(lView: LView, queryIndex: number, result: T[]): T[] {
|
||||
const tQuery = lView[TVIEW].queries !.getByIndex(queryIndex);
|
||||
function collectQueryResults<T>(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<T>(lView, tQuery, queryIndex);
|
||||
const lViewResults = materializeViewResults<T>(tView, lView, tQuery, queryIndex);
|
||||
|
||||
for (let i = 0; i < tQueryMatches.length; i += 2) {
|
||||
const tNodeIdx = tQueryMatches[i];
|
||||
|
@ -359,7 +360,7 @@ function collectQueryResults<T>(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<T>(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<T>(lView: LView, queryIndex: number, result: T[]):
|
|||
*/
|
||||
export function ɵɵqueryRefresh(queryList: QueryList<any>): 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<any>): boolean {
|
|||
*/
|
||||
export function ɵɵstaticViewQuery<T>(
|
||||
predicate: Type<any>| 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<T>(
|
|||
* @codeGenApi
|
||||
*/
|
||||
export function ɵɵviewQuery<T>(predicate: Type<any>| string[], descend: boolean, read?: any): void {
|
||||
viewQueryInternal(getLView(), predicate, descend, read, false);
|
||||
viewQueryInternal(getTView(), getLView(), predicate, descend, read, false);
|
||||
}
|
||||
|
||||
function viewQueryInternal<T>(
|
||||
lView: LView, predicate: Type<any>| string[], descend: boolean, read: any,
|
||||
tView: TView, lView: LView, predicate: Type<any>| 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<T>(lView);
|
||||
createLQuery<T>(tView, lView);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -463,7 +466,8 @@ function viewQueryInternal<T>(
|
|||
export function ɵɵcontentQuery<T>(
|
||||
directiveIndex: number, predicate: Type<any>| 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<T>(
|
|||
export function ɵɵstaticContentQuery<T>(
|
||||
directiveIndex: number, predicate: Type<any>| string[], descend: boolean, read?: any): void {
|
||||
contentQueryInternal(
|
||||
getLView(), predicate, descend, read, true, getPreviousOrParentTNode(), directiveIndex);
|
||||
getTView(), getLView(), predicate, descend, read, true, getPreviousOrParentTNode(),
|
||||
directiveIndex);
|
||||
}
|
||||
|
||||
function contentQueryInternal<T>(
|
||||
lView: LView, predicate: Type<any>| string[], descend: boolean, read: any, isStatic: boolean,
|
||||
tNode: TNode, directiveIndex: number): void {
|
||||
const tView = lView[TVIEW];
|
||||
tView: TView, lView: LView, predicate: Type<any>| 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<T>(
|
|||
}
|
||||
}
|
||||
|
||||
createLQuery<T>(lView);
|
||||
createLQuery<T>(tView, lView);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -515,9 +519,9 @@ function loadQueryInternal<T>(lView: LView, queryIndex: number): QueryList<T> {
|
|||
return lView[QUERIES] !.queries[queryIndex].queryList;
|
||||
}
|
||||
|
||||
function createLQuery<T>(lView: LView) {
|
||||
function createLQuery<T>(tView: TView, lView: LView) {
|
||||
const queryList = new QueryList<T>();
|
||||
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));
|
||||
|
|
|
@ -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, //
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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`. */
|
||||
|
|
|
@ -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<T>(
|
|||
|
||||
createEmbeddedView(context: T): viewEngine_EmbeddedViewRef<T> {
|
||||
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<T>(lView);
|
||||
viewRef._tViewNode = lView[T_HOST] as TViewNode;
|
||||
const viewRef = new ViewRef<T>(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<any>)._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<any>).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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<T> implements viewEngine_EmbeddedViewRef<T>, 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<T> implements viewEngine_EmbeddedViewRef<T>, 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<T> implements viewEngine_EmbeddedViewRef<T>, 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<T> implements viewEngine_EmbeddedViewRef<T>, 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<T> implements viewEngine_EmbeddedViewRef<T>, 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<T> extends ViewRef<T> {
|
|||
}
|
||||
|
||||
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;
|
||||
|
|
|
@ -386,6 +386,9 @@
|
|||
{
|
||||
"name": "getSelectedIndex"
|
||||
},
|
||||
{
|
||||
"name": "getTView"
|
||||
},
|
||||
{
|
||||
"name": "growHostVarsSpace"
|
||||
},
|
||||
|
|
|
@ -323,6 +323,9 @@
|
|||
{
|
||||
"name": "getSelectedIndex"
|
||||
},
|
||||
{
|
||||
"name": "getTView"
|
||||
},
|
||||
{
|
||||
"name": "growHostVarsSpace"
|
||||
},
|
||||
|
|
|
@ -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"
|
||||
},
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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<T> 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<T>(
|
|||
hostLView, componentTView, context, LViewFlags.CheckAlways, hostNode, hostTNode,
|
||||
providedRendererFactory, renderer, sanitizer);
|
||||
}
|
||||
renderComponentOrTemplate(componentView, templateFn, context);
|
||||
renderComponentOrTemplate(componentView[TVIEW], componentView, templateFn, context);
|
||||
return componentView;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue