refactor(ivy): remove LNode (#26426)

PR Close #26426
This commit is contained in:
Kara Erickson 2018-10-12 18:49:00 -07:00 committed by Miško Hevery
parent 9afc9a7464
commit e76a570908
27 changed files with 302 additions and 449 deletions

View File

@ -18,10 +18,10 @@ import {getComponentDef} from './definition';
import {queueInitHooks, queueLifecycleHooks} from './hooks';
import {CLEAN_PROMISE, baseDirectiveCreate, createLViewData, createNodeAtIndex, createTView, detectChangesInternal, enterView, executeInitAndContentHooks, getOrCreateTView, leaveView, locateHostElement, prefillHostVars, resetComponentState, setHostBindings} from './instructions';
import {ComponentDef, ComponentType} from './interfaces/definition';
import {TNodeFlags, TNodeType} from './interfaces/node';
import {TElementNode, TNodeFlags, TNodeType} from './interfaces/node';
import {PlayerHandler} from './interfaces/player';
import {RElement, RNode, Renderer3, RendererFactory3, domRendererFactory3} from './interfaces/renderer';
import {CONTEXT, HEADER_OFFSET, HOST, INJECTOR, LViewData, LViewFlags, RootContext, RootContextFlags, TVIEW} from './interfaces/view';
import {CONTEXT, HEADER_OFFSET, HOST, HOST_NODE, INJECTOR, LViewData, LViewFlags, RootContext, RootContextFlags, TVIEW} from './interfaces/view';
import {getRootView, readElementValue, readPatchedLViewData, stringify} from './util';
@ -166,7 +166,7 @@ export function createRootComponentView(
getOrCreateTView(
def.template, def.consts, def.vars, def.directiveDefs, def.pipeDefs, def.viewQuery),
null, def.onPush ? LViewFlags.Dirty : LViewFlags.CheckAlways, sanitizer);
const tNode = createNodeAtIndex(0, TNodeType.Element, rNode, null, null, componentView);
const tNode = createNodeAtIndex(0, TNodeType.Element, rNode, null, null);
if (tView.firstTemplatePass) {
tView.expandoInstructions = ROOT_EXPANDO_INSTRUCTIONS.slice();
@ -177,10 +177,10 @@ export function createRootComponentView(
// Store component view at node index, with node as the HOST
componentView[HOST] = rootView[HEADER_OFFSET];
componentView[HOST_NODE] = tNode as TElementNode;
return rootView[HEADER_OFFSET] = componentView;
}
/**
* Creates a root component and sets it up with features and host bindings. Shared by
* renderComponent() and ViewContainerRef.createComponent().
@ -255,7 +255,7 @@ function getRootContext(component: any): RootContext {
* @param component Component for which the host element should be retrieved.
*/
export function getHostElement<T>(component: T): HTMLElement {
return readElementValue(getComponentViewByInstance(component)).native as HTMLElement;
return readElementValue(getComponentViewByInstance(component)) as HTMLElement;
}
/**

View File

@ -19,7 +19,7 @@ import {Type} from '../type';
import {assertComponentType, assertDefined} from './assert';
import {LifecycleHooksFeature, createRootComponent, createRootComponentView, createRootContext} from './component';
import {getComponentDef} from './definition';
import {adjustBlueprintForNewNode, createLViewData, createNodeAtIndex, createTView, elementCreate, enterView, locateHostElement, renderEmbeddedTemplate} from './instructions';
import {adjustBlueprintForNewNode, createLViewData, createNodeAtIndex, createTView, createViewNode, elementCreate, enterView, locateHostElement, renderEmbeddedTemplate} from './instructions';
import {ComponentDef, RenderFlags} from './interfaces/definition';
import {TElementNode, TNode, TNodeType, TViewNode} from './interfaces/node';
import {RElement, RendererFactory3, domRendererFactory3} from './interfaces/renderer';
@ -141,7 +141,7 @@ export class ComponentFactory<T> extends viewEngine_ComponentFactory<T> {
createRootComponentView(hostRNode, this.componentDef, rootView, renderer);
tElementNode = getTNode(0, rootView) as TElementNode;
// Transform the arrays of native nodes into a LNode structure that can be consumed by the
// Transform the arrays of native nodes into a structure that can be consumed by the
// projection instruction. This is needed to support the reprojection of these nodes.
if (projectableNodes) {
let index = 0;
@ -223,7 +223,7 @@ export class ComponentRef<T> extends viewEngine_ComponentRef<T> {
super();
this.instance = instance;
this.hostView = this.changeDetectorRef = new RootViewRef<T>(rootView);
this.hostView._tViewNode = createNodeAtIndex(-1, TNodeType.View, null, null, null, rootView);
this.hostView._tViewNode = createViewNode(-1, rootView);
this.injector = injector;
this.componentType = componentType;
}

View File

@ -9,10 +9,10 @@ import './ng_dev_mode';
import {assertEqual} from './assert';
import {LContext, MONKEY_PATCH_KEY_NAME} from './interfaces/context';
import {LElementNode, TNode, TNodeFlags} from './interfaces/node';
import {TNode, TNodeFlags} from './interfaces/node';
import {RElement} from './interfaces/renderer';
import {CONTEXT, HEADER_OFFSET, HOST, LViewData, TVIEW} from './interfaces/view';
import {getComponentViewByIndex, readElementValue, readPatchedData} from './util';
import {getComponentViewByIndex, getNativeByTNode, readElementValue, readPatchedData} from './util';
/** Returns the matching `LContext` data for a given DOM node, directive or component instance.
@ -66,11 +66,11 @@ export function getContext(target: any): LContext|null {
// are expensive. Instead, only the target data (the element, compontent or
// directive details) are filled into the context. If called multiple times
// with different target values then the missing target data will be filled in.
const lNode = getLNodeFromViewData(lViewData, nodeIndex) !;
const existingCtx = readPatchedData(lNode.native);
const native = readElementValue(lViewData[nodeIndex]);
const existingCtx = readPatchedData(native);
const context: LContext = (existingCtx && !Array.isArray(existingCtx)) ?
existingCtx :
createLContext(lViewData, nodeIndex, lNode.native);
createLContext(lViewData, nodeIndex, native);
// only when the component has been discovered then update the monkey-patch
if (component && context.component === undefined) {
@ -114,9 +114,9 @@ export function getContext(target: any): LContext|null {
const index = findViaNativeElement(lViewData, rElement);
if (index >= 0) {
const lNode = getLNodeFromViewData(lViewData, index) !;
const context = createLContext(lViewData, index, lNode.native);
attachPatchData(lNode.native, context);
const native = readElementValue(lViewData[index]);
const context = createLContext(lViewData, index, native);
attachPatchData(native, context);
mpValue = context;
break;
}
@ -129,10 +129,10 @@ export function getContext(target: any): LContext|null {
/**
* Creates an empty instance of a `LContext` context
*/
function createLContext(lViewData: LViewData, lNodeIndex: number, native: RElement): LContext {
function createLContext(lViewData: LViewData, nodeIndex: number, native: RElement): LContext {
return {
lViewData,
nodeIndex: lNodeIndex, native,
nodeIndex: nodeIndex, native,
component: undefined,
directives: undefined,
localRefs: undefined,
@ -150,9 +150,9 @@ export function getComponentViewByInstance(componentInstance: {}): LViewData {
let view: LViewData;
if (Array.isArray(lViewData)) {
const lNodeIndex = findViaComponent(lViewData, componentInstance);
view = getComponentViewByIndex(lNodeIndex, lViewData);
const context = createLContext(lViewData, lNodeIndex, (view[HOST] as LElementNode).native);
const nodeIndex = findViaComponent(lViewData, componentInstance);
view = getComponentViewByIndex(nodeIndex, lViewData);
const context = createLContext(lViewData, nodeIndex, view[HOST] as RElement);
context.component = componentInstance;
attachPatchData(componentInstance, context);
attachPatchData(context.native, context);
@ -182,11 +182,11 @@ export function isDirectiveInstance(instance: any): boolean {
/**
* Locates the element within the given LViewData and returns the matching index
*/
function findViaNativeElement(lViewData: LViewData, native: RElement): number {
function findViaNativeElement(lViewData: LViewData, target: RElement): number {
let tNode = lViewData[TVIEW].firstChild;
while (tNode) {
const lNode = getLNodeFromViewData(lViewData, tNode.index) !;
if (lNode.native === native) {
const native = getNativeByTNode(tNode, lViewData) !;
if (native === target) {
return tNode.index;
}
tNode = traverseNextElement(tNode);
@ -261,18 +261,6 @@ function assertDomElement(element: any) {
assertEqual(element.nodeType, 1, 'The provided value must be an instance of an HTMLElement');
}
/**
* Retruns the instance of the LElementNode at the given index in the LViewData.
*
* This function will also unwrap the inner value incase it's stuffed into an
* array (which is what happens when [style] and [class] bindings are present
* in the view instructions for the element being returned).
*/
function getLNodeFromViewData(lViewData: LViewData, lElementIndex: number): LElementNode|null {
const value = lViewData[lElementIndex];
return value ? readElementValue(value) : null;
}
/**
* Returns a list of directives extracted from the given view based on the
* provided list of directive index values.
@ -294,17 +282,16 @@ export function discoverDirectives(
* Returns a map of local references (local reference name => element or directive instance) that
* exist on a given element.
*/
export function discoverLocalRefs(lViewData: LViewData, lNodeIndex: number): {[key: string]: any}|
export function discoverLocalRefs(lViewData: LViewData, nodeIndex: number): {[key: string]: any}|
null {
const tNode = lViewData[TVIEW].data[lNodeIndex] as TNode;
const tNode = lViewData[TVIEW].data[nodeIndex] as TNode;
if (tNode && tNode.localNames) {
const result: {[key: string]: any} = {};
for (let i = 0; i < tNode.localNames.length; i += 2) {
const localRefName = tNode.localNames[i];
const directiveIndex = tNode.localNames[i + 1] as number;
result[localRefName] = directiveIndex === -1 ?
getLNodeFromViewData(lViewData, lNodeIndex) !.native :
lViewData[directiveIndex];
result[localRefName] =
directiveIndex === -1 ? getNativeByTNode(tNode, lViewData) ! : lViewData[directiveIndex];
}
return result;
}

View File

@ -11,18 +11,17 @@
import {getInjectableDef, getInjectorDef} from '../di/defs';
import {InjectionToken} from '../di/injection_token';
import {InjectFlags, Injector, NullInjector, inject, setCurrentInjector} from '../di/injector';
import {Renderer2} from '../render';
import {InjectFlags, Injector, inject, setCurrentInjector} from '../di/injector';
import {Type} from '../type';
import {assertDefined} from './assert';
import {getComponentDef, getDirectiveDef, getPipeDef} from './definition';
import {NG_ELEMENT_ID} from './fields';
import {_getViewData, assertPreviousIsParent, getPreviousOrParentTNode, resolveDirective, setEnvironment} from './instructions';
import {_getViewData, getPreviousOrParentTNode, resolveDirective, setEnvironment} from './instructions';
import {DirectiveDef} from './interfaces/definition';
import {InjectorLocationFlags, PARENT_INJECTOR, TNODE,} from './interfaces/injector';
import {AttributeMarker, TContainerNode, TElementContainerNode, TElementNode, TNode, TNodeFlags, TNodeType} from './interfaces/node';
import {DECLARATION_VIEW, HOST_NODE, INJECTOR, LViewData, PARENT, RENDERER, TData, TVIEW, TView} from './interfaces/view';
import {DECLARATION_VIEW, HOST_NODE, INJECTOR, LViewData, TData, TVIEW, TView} from './interfaces/view';
import {assertNodeOfPossibleTypes} from './node_assert';
/**

View File

@ -7,13 +7,14 @@
*/
import {assertEqual, assertLessThan} from './assert';
import {NO_CHANGE, _getViewData, adjustBlueprintForNewNode, bindingUpdated, bindingUpdated2, bindingUpdated3, bindingUpdated4, createNodeAtIndex, getRenderer, load, loadElement, resetComponentState} from './instructions';
import {NO_CHANGE, _getViewData, adjustBlueprintForNewNode, bindingUpdated, bindingUpdated2, bindingUpdated3, bindingUpdated4, createNodeAtIndex, getRenderer, load, resetComponentState} from './instructions';
import {LContainer, NATIVE, RENDER_PARENT} from './interfaces/container';
import {LContainerNode, LNode, TElementNode, TNode, TNodeType} from './interfaces/node';
import {TElementNode, TNode, TNodeType} from './interfaces/node';
import {RComment, RElement} from './interfaces/renderer';
import {StylingContext} from './interfaces/styling';
import {BINDING_INDEX, HEADER_OFFSET, HOST_NODE, TVIEW} from './interfaces/view';
import {appendChild, createTextNode, removeChild} from './node_manipulation';
import {getNative, getTNode, isLContainer, stringify} from './util';
import {getNativeByIndex, getNativeByTNode, getTNode, isLContainer, stringify} from './util';
@ -273,7 +274,7 @@ function appendI18nNode(tNode: TNode, parentTNode: TNode, previousTNode: TNode):
}
}
appendChild(getNative(tNode, viewData), tNode, viewData);
appendChild(getNativeByTNode(tNode, viewData), tNode, viewData);
const slotValue = viewData[tNode.index];
if (tNode.type !== TNodeType.Container && isLContainer(slotValue)) {
@ -364,11 +365,11 @@ export function i18nApply(startIndex: number, instructions: I18nInstruction[]):
ngDevMode.rendererRemoveNode++;
}
const removeIndex = instruction & I18nInstructions.IndexMask;
const removedNode: LNode|LContainerNode = loadElement(removeIndex);
const removedElement: RElement|RComment = getNativeByIndex(removeIndex, viewData);
const removedTNode = getTNode(removeIndex, viewData);
removeChild(removedTNode, removedNode.native || null, viewData);
removeChild(removedTNode, removedElement || null, viewData);
const slotValue = load(removeIndex) as LNode | LContainer | StylingContext;
const slotValue = load(removeIndex) as RElement | RComment | LContainer | StylingContext;
if (isLContainer(slotValue)) {
const lContainer = slotValue as LContainer;
if (removedTNode.type !== TNodeType.Container) {

View File

@ -19,7 +19,7 @@ import {executeHooks, executeInitHooks, queueInitHooks, queueLifecycleHooks} fro
import {ACTIVE_INDEX, LContainer, VIEWS} from './interfaces/container';
import {ComponentDef, ComponentQuery, ComponentTemplate, DirectiveDef, DirectiveDefListOrFactory, InitialStylingFlags, PipeDefListOrFactory, RenderFlags} from './interfaces/definition';
import {INJECTOR_SIZE} from './interfaces/injector';
import {AttributeMarker, InitialInputData, InitialInputs, LContainerNode, LElementContainerNode, LElementNode, LTextNode, LocalRefExtractor, PropertyAliasValue, PropertyAliases, TAttributes, TContainerNode, TElementContainerNode, TElementNode, TNode, TNodeFlags, TNodeType, TProjectionNode, TViewNode} from './interfaces/node';
import {AttributeMarker, InitialInputData, InitialInputs, LocalRefExtractor, PropertyAliasValue, PropertyAliases, TAttributes, TContainerNode, TElementContainerNode, TElementNode, TNode, TNodeFlags, TNodeType, TProjectionNode, TViewNode} from './interfaces/node';
import {CssSelectorList, NG_PROJECT_AS_ATTR_NAME} from './interfaces/projection';
import {LQueries} from './interfaces/query';
import {ProceduralRenderer3, RComment, RElement, RNode, RText, Renderer3, RendererFactory3, isProceduralRenderer} from './interfaces/renderer';
@ -29,7 +29,7 @@ import {appendChild, appendProjectedNode, createTextNode, findComponentView, get
import {isNodeMatchingSelectorList, matchingSelectorIndex} from './node_selector_matcher';
import {createStylingContextTemplate, renderStyling as renderElementStyles, updateClassProp as updateElementClassProp, updateStyleProp as updateElementStyleProp, updateStylingMap} from './styling/class_and_style_bindings';
import {getStylingContext} from './styling/util';
import {assertDataInRangeInternal, getComponentViewByIndex, getNative, getRootView, getTNode, isComponent, isContentQueryHost, isDifferent, loadElementInternal, loadInternal, readPatchedLViewData, stringify} from './util';
import {assertDataInRangeInternal, getComponentViewByIndex, getNativeByIndex, getNativeByTNode, getRootView, getTNode, isComponent, isContentQueryHost, isDifferent, loadInternal, readPatchedLViewData, stringify} from './util';
@ -415,96 +415,53 @@ export function createLViewData<T>(
}
/**
* A common way of creating the LNode to make sure that all of them have same shape to
* keep the execution code monomorphic and fast.
* Create and stores the TNode, and hooks it up to the tree.
*
* @param index The index at which the LNode should be saved (null if view, since they are not
* @param index The index at which the TNode should be saved (null if view, since they are not
* saved).
* @param type The type of LNode to create
* @param native The native element for this LNode, if applicable
* @param type The type of TNode to create
* @param native The native element for this node, if applicable
* @param name The tag name of the associated native element, if applicable
* @param attrs Any attrs for the native element, if applicable
* @param data Any data that should be saved on the LNode
*/
export function createNodeAtIndex(
index: number, type: TNodeType.Element, native: RElement | RText | null, name: string | null,
attrs: TAttributes | null, lViewData?: LViewData | null): TElementNode;
export function createNodeAtIndex(
index: number, type: TNodeType.View, native: null, name: null, attrs: null,
lViewData: LViewData): TViewNode;
attrs: TAttributes | null): TElementNode;
export function createNodeAtIndex(
index: number, type: TNodeType.Container, native: RComment, name: string | null,
attrs: TAttributes | null, data: null): TContainerNode;
attrs: TAttributes | null): TContainerNode;
export function createNodeAtIndex(
index: number, type: TNodeType.Projection, native: null, name: null, attrs: TAttributes | null,
data: null): TProjectionNode;
index: number, type: TNodeType.Projection, native: null, name: null,
attrs: TAttributes | null): TProjectionNode;
export function createNodeAtIndex(
index: number, type: TNodeType.ElementContainer, native: RComment, name: null,
attrs: TAttributes | null, data: null): TElementContainerNode;
attrs: TAttributes | null): TElementContainerNode;
export function createNodeAtIndex(
index: number, type: TNodeType, native: RText | RElement | RComment | null, name: string | null,
attrs: TAttributes | null, state?: null | LViewData): TElementNode&TViewNode&TContainerNode&
TElementContainerNode&TProjectionNode {
const parent =
isParent ? previousOrParentTNode : previousOrParentTNode && previousOrParentTNode.parent;
attrs: TAttributes | null): TElementNode&TContainerNode&TElementContainerNode&TProjectionNode {
const adjustedIndex = index + HEADER_OFFSET;
ngDevMode &&
assertLessThan(adjustedIndex, viewData.length, `Slot should have been initialized with null`);
viewData[adjustedIndex] = native;
// Parents cannot cross component boundaries because components will be used in multiple places,
// so it's only set if the view is the same.
const parentInSameView = parent && viewData && parent !== viewData[HOST_NODE];
const tParent = parentInSameView ? parent as TElementNode | TContainerNode : null;
const isState = state != null;
const node = {native: native as any};
let tNode: TNode;
if (index === -1 || type === TNodeType.View) {
// View nodes are not stored in data because they can be added / removed at runtime (which
// would cause indices to change). Their TNodes are instead stored in tView.node.
tNode = (state ? (state as LViewData)[TVIEW].node : null) ||
createTNode(type, index, null, null, tParent, null);
} else {
const adjustedIndex = index + HEADER_OFFSET;
// This is an element or container or projection node
const tData = tView.data;
ngDevMode && assertLessThan(
adjustedIndex, viewData.length, `Slot should have been initialized with null`);
viewData[adjustedIndex] = node;
if (tData[adjustedIndex] == null) {
const tNode = tData[adjustedIndex] =
createTNode(type, adjustedIndex, name, attrs, tParent, null);
if (!isParent && previousOrParentTNode) {
previousOrParentTNode.next = tNode;
}
}
tNode = tData[adjustedIndex] as TNode;
if (!tView.firstChild && type === TNodeType.Element) {
tView.firstChild = tNode;
}
let tNode = tView.data[adjustedIndex] as TNode;
if (tNode == null) {
tNode = tView.data[adjustedIndex] = createTNode(type, adjustedIndex, name, attrs, null);
// Now link ourselves into the tree.
if (isParent && previousOrParentTNode) {
if (previousOrParentTNode.child == null && parentInSameView ||
previousOrParentTNode.type === TNodeType.View) {
// We are in the same view, which means we are adding content node to the parent View.
if (previousOrParentTNode) {
if (isParent && previousOrParentTNode.child == null &&
(tNode.parent !== null || previousOrParentTNode.type === TNodeType.View)) {
// We are in the same view, which means we are adding content node to the parent view.
previousOrParentTNode.child = tNode;
} else if (!isParent) {
previousOrParentTNode.next = tNode;
}
}
}
// View nodes and host elements need to set their host node (components do not save host TNodes)
if ((type & TNodeType.ViewOrElement) === TNodeType.ViewOrElement && isState) {
const lViewData = state as LViewData;
ngDevMode &&
assertEqual(
lViewData[HOST_NODE], null, 'lViewData[HOST_NODE] should not have been initialized');
lViewData[HOST_NODE] = tNode as TElementNode | TViewNode;
if (lViewData[TVIEW].firstTemplatePass) {
lViewData[TVIEW].node = tNode as TViewNode | TElementNode;
}
if (tView.firstChild == null && type === TNodeType.Element) {
tView.firstChild = tNode;
}
previousOrParentTNode = tNode;
@ -513,8 +470,20 @@ export function createNodeAtIndex(
TProjectionNode;
}
export function createViewNode(index: number, view: LViewData) {
// View nodes are not stored in data because they can be added / removed at runtime (which
// would cause indices to change). Their TNodes are instead stored in tView.node.
if (view[TVIEW].node == null) {
view[TVIEW].node = createTNode(TNodeType.View, index, null, null, null) as TViewNode;
}
isParent = true;
return previousOrParentTNode = view[HOST_NODE] = view[TVIEW].node as TViewNode;
}
/**
* When LNodes are created dynamically after a view blueprint is created (e.g. through
* When elements are created dynamically after a view blueprint is created (e.g. through
* i18nApply() or ComponentFactory.create), we need to adjust the blueprint for future
* template passes.
*/
@ -571,7 +540,7 @@ export function renderTemplate<T>(
getOrCreateTView(templateFn, consts, vars, directives || null, pipes || null, null);
hostView =
createLViewData(renderer, componentTView, context, LViewFlags.CheckAlways, sanitizer);
createNodeAtIndex(0, TNodeType.Element, hostNode, null, null, hostView);
hostView[HOST_NODE] = createNodeAtIndex(0, TNodeType.Element, hostNode, null, null);
}
renderComponentOrTemplate(hostView, context, templateFn);
@ -598,7 +567,7 @@ export function createEmbeddedViewAndNode<T>(
if (queries) {
lView[QUERIES] = queries.createView();
}
createNodeAtIndex(-1, TNodeType.View, null, null, null, lView);
createViewNode(-1, lView);
if (tView.firstTemplatePass) {
tView.node !.injectorIndex = injectorIndex;
@ -769,8 +738,7 @@ export function elementContainerStart(
const native = renderer.createComment(ngDevMode ? 'ng-container' : '');
ngDevMode && assertDataInRange(index - 1);
const tNode =
createNodeAtIndex(index, TNodeType.ElementContainer, native, null, attrs || null, null);
const tNode = createNodeAtIndex(index, TNodeType.ElementContainer, native, null, attrs || null);
appendChild(native, tNode, viewData);
createDirectivesAndLocals(localRefs);
@ -816,11 +784,12 @@ export function elementStart(
ngDevMode && assertDataInRange(index - 1);
const tNode = createNodeAtIndex(index, TNodeType.Element, native !, name, attrs || null, null);
const tNode = createNodeAtIndex(index, TNodeType.Element, native !, name, attrs || null);
if (attrs) {
setUpAttributes(native, attrs);
}
appendChild(native, tNode, viewData);
createDirectivesAndLocals(localRefs);
@ -858,12 +827,12 @@ export function elementCreate(name: string, overriddenRenderer?: Renderer3): REl
/**
* Creates directive instances and populates local refs.
*
* @param lNode LNode for which directive and locals should be created
* @param localRefs Local refs of the node in question
* @param localRefExtractor mapping function that extracts local ref value from LNode
* @param localRefExtractor mapping function that extracts local ref value from TNode
*/
function createDirectivesAndLocals(
localRefs: string[] | null | undefined, localRefExtractor: LocalRefExtractor = getNative) {
localRefs: string[] | null | undefined,
localRefExtractor: LocalRefExtractor = getNativeByTNode) {
if (!bindingsEnabled) return;
if (firstTemplatePass) {
ngDevMode && ngDevMode.firstTemplatePass++;
@ -1226,7 +1195,7 @@ export function listener(
// add native event listener - applicable to elements only
if (tNode.type === TNodeType.Element) {
const native = getNative(previousOrParentTNode, viewData) as RElement;
const native = getNativeByTNode(previousOrParentTNode, viewData) as RElement;
ngDevMode && ngDevMode.rendererAddEventListener++;
// In order to match current behavior, native DOM event listeners must be added for all
@ -1333,16 +1302,16 @@ export function elementEnd(): void {
export function elementAttribute(
index: number, name: string, value: any, sanitizer?: SanitizerFn): void {
if (value !== NO_CHANGE) {
const element = loadElement(index);
const element = getNativeByIndex(index, viewData);
if (value == null) {
ngDevMode && ngDevMode.rendererRemoveAttribute++;
isProceduralRenderer(renderer) ? renderer.removeAttribute(element.native, name) :
element.native.removeAttribute(name);
isProceduralRenderer(renderer) ? renderer.removeAttribute(element, name) :
element.removeAttribute(name);
} else {
ngDevMode && ngDevMode.rendererSetAttribute++;
const strValue = sanitizer == null ? stringify(value) : sanitizer(value);
isProceduralRenderer(renderer) ? renderer.setAttribute(element.native, name, strValue) :
element.native.setAttribute(name, strValue);
isProceduralRenderer(renderer) ? renderer.setAttribute(element, name, strValue) :
element.setAttribute(name, strValue);
}
}
}
@ -1364,7 +1333,7 @@ export function elementAttribute(
export function elementProperty<T>(
index: number, propName: string, value: T | NO_CHANGE, sanitizer?: SanitizerFn): void {
if (value === NO_CHANGE) return;
const node = loadElement(index) as LElementNode | LContainerNode | LElementContainerNode;
const element = getNativeByIndex(index, viewData) as RElement | RComment;
const tNode = getTNode(index, viewData);
// if tNode.inputs is undefined, a listener has created outputs, but inputs haven't
// yet been checked
@ -1382,11 +1351,11 @@ export function elementProperty<T>(
// It is assumed that the sanitizer is only added when the compiler determines that the property
// is risky, so sanitization can be done without further checks.
value = sanitizer != null ? (sanitizer(value) as any) : value;
const native = node.native as RElement;
ngDevMode && ngDevMode.rendererSetProperty++;
isProceduralRenderer(renderer) ? renderer.setProperty(native, propName, value) :
(native.setProperty ? native.setProperty(propName, value) :
(native as any)[propName] = value);
isProceduralRenderer(renderer) ?
renderer.setProperty(element as RElement, propName, value) :
((element as RElement).setProperty ? (element as any).setProperty(propName, value) :
(element as any)[propName] = value);
}
}
@ -1439,18 +1408,25 @@ export function disableBindings(): void {
* @param adjustedIndex The index of the TNode in TView.data, adjusted for HEADER_OFFSET
* @param tagName The tag name of the node
* @param attrs The attributes defined on this node
* @param parent The parent of this node
* @param tViews Any TViews attached to this node
* @returns the TNode object
*/
export function createTNode(
type: TNodeType, adjustedIndex: number, tagName: string | null, attrs: TAttributes | null,
parent: TElementNode | TContainerNode | null, tViews: TView[] | null): TNode {
tViews: TView[] | null): TNode {
ngDevMode && ngDevMode.tNode++;
const parent =
isParent ? previousOrParentTNode : previousOrParentTNode && previousOrParentTNode.parent;
// Parents cannot cross component boundaries because components will be used in multiple places,
// so it's only set if the view is the same.
const parentInSameView = parent && viewData && parent !== viewData[HOST_NODE];
const tParent = parentInSameView ? parent as TElementNode | TContainerNode : null;
return {
type: type,
index: adjustedIndex,
injectorIndex: parent ? parent.injectorIndex : -1,
injectorIndex: tParent ? tParent.injectorIndex : -1,
flags: 0,
tagName: tagName,
attrs: attrs,
@ -1461,7 +1437,7 @@ export function createTNode(
tViews: tViews,
next: null,
child: null,
parent: parent,
parent: tParent,
detached: null,
stylingTemplate: null,
projection: null
@ -1482,7 +1458,7 @@ function setInputsForProperty(inputs: PropertyAliasValue, value: any): void {
/**
* Consolidates all inputs or outputs of all directives on this logical node.
*
* @param number lNodeFlags logical node flags
* @param number tNodeFlags node flags
* @param Direction direction whether to consider inputs or outputs
* @returns PropertyAliases|null aggregate of all properties if any, `null` otherwise
*/
@ -1692,12 +1668,11 @@ export function text(index: number, value?: any): void {
export function textBinding<T>(index: number, value: T | NO_CHANGE): void {
if (value !== NO_CHANGE) {
ngDevMode && assertDataInRange(index + HEADER_OFFSET);
const existingNode = loadElement(index) as any as LTextNode;
ngDevMode && assertDefined(existingNode, 'LNode should exist');
ngDevMode && assertDefined(existingNode.native, 'native element should exist');
const element = getNativeByIndex(index, viewData) as any as RText;
ngDevMode && assertDefined(element, 'native element should exist');
ngDevMode && ngDevMode.rendererSetText++;
isProceduralRenderer(renderer) ? renderer.setValue(existingNode.native, stringify(value)) :
existingNode.native.textContent = stringify(value);
isProceduralRenderer(renderer) ? renderer.setValue(element, stringify(value)) :
element.textContent = stringify(value);
}
}
@ -1716,7 +1691,7 @@ export function textBinding<T>(index: number, value: T | NO_CHANGE): void {
*/
export function directiveCreate<T>(
directiveDefIdx: number, directive: T, directiveDef: DirectiveDef<T>| ComponentDef<T>): T {
const native = getNative(previousOrParentTNode, viewData);
const native = getNativeByTNode(previousOrParentTNode, viewData);
const instance = baseDirectiveCreate(directiveDefIdx, directive, directiveDef, native);
if ((directiveDef as ComponentDef<T>).template) {
@ -1743,7 +1718,7 @@ export function directiveCreate<T>(
}
function addComponentLogic<T>(def: ComponentDef<T>): void {
const native = getNative(previousOrParentTNode, viewData);
const native = getNativeByTNode(previousOrParentTNode, viewData);
const tView = getOrCreateTView(
def.template, def.consts, def.vars, def.directiveDefs, def.pipeDefs, def.viewQuery);
@ -1759,7 +1734,7 @@ function addComponentLogic<T>(def: ComponentDef<T>): void {
componentView[HOST_NODE] = previousOrParentTNode as TElementNode;
// Component view will always be created before any injected LContainers,
// so this is a regular LNode, wrap it with the component view
// so this is a regular element, wrap it with the component view
componentView[HOST] = viewData[previousOrParentTNode.index];
viewData[previousOrParentTNode.index] = componentView;
@ -1896,7 +1871,7 @@ function generateInitialInputs(
/**
* Creates a LContainer, either from a container instruction, or for a ViewContainerRef.
*
* @param hostLNode The host node for the LContainer
* @param hostNative The host element for the LContainer
* @param hostTNode The host TNode for the LContainer
* @param currentView The parent view of the LContainer
* @param native The native comment element
@ -1904,7 +1879,7 @@ function generateInitialInputs(
* @returns LContainer
*/
export function createLContainer(
hostLNode: LElementNode | LContainerNode | LElementContainerNode,
hostNative: RElement | RComment,
hostTNode: TElementNode | TContainerNode | TElementContainerNode, currentView: LViewData,
native: RComment, isForViewContainerRef?: boolean): LContainer {
return [
@ -1913,14 +1888,14 @@ export function createLContainer(
currentView, // parent
null, // next
null, // queries
hostLNode, // host native
hostNative, // host native
native, // native
getRenderParent(hostTNode, currentView) // renderParent
];
}
/**
* Creates an LContainerNode for an ng-template (dynamically-inserted view), e.g.
* Creates an LContainer for an ng-template (dynamically-inserted view), e.g.
*
* <ng-template #foo>
* <div></div>
@ -1956,7 +1931,7 @@ export function template(
}
/**
* Creates an LContainerNode for inline views, e.g.
* Creates an LContainer for inline views, e.g.
*
* % if (showing) {
* <div></div>
@ -1979,7 +1954,7 @@ function containerInternal(
const adjustedIndex = index + HEADER_OFFSET;
const comment = renderer.createComment(ngDevMode ? 'container' : '');
ngDevMode && ngDevMode.rendererCreateComment++;
const tNode = createNodeAtIndex(index, TNodeType.Container, comment, tagName, attrs, null);
const tNode = createNodeAtIndex(index, TNodeType.Container, comment, tagName, attrs);
const lContainer = viewData[adjustedIndex] =
createLContainer(viewData[adjustedIndex], tNode, viewData, comment);
@ -2019,9 +1994,9 @@ export function containerRefreshStart(index: number): void {
}
/**
* Marks the end of the LContainerNode.
* Marks the end of the LContainer.
*
* Marking the end of LContainerNode is the time when to child Views get inserted or removed.
* Marking the end of LContainer is the time when to child views get inserted or removed.
*/
export function containerRefreshEnd(): void {
if (isParent) {
@ -2130,7 +2105,7 @@ export function embeddedViewStart(viewBlockId: number, consts: number, vars: num
viewToRender[QUERIES] = lContainer[QUERIES] !.createView();
}
createNodeAtIndex(viewBlockId, TNodeType.View, null, null, null, viewToRender);
createViewNode(viewBlockId, viewToRender);
enterView(viewToRender, viewToRender[TVIEW].node);
}
if (lContainer) {
@ -2306,7 +2281,7 @@ const projectionNodeStack: (LViewData | TNode)[] = [];
*/
export function projection(nodeIndex: number, selectorIndex: number = 0, attrs?: string[]): void {
const tProjectionNode =
createNodeAtIndex(nodeIndex, TNodeType.Projection, null, null, attrs || null, null);
createNodeAtIndex(nodeIndex, TNodeType.Projection, null, 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;
@ -2796,10 +2771,6 @@ export function load<T>(index: number): T {
return loadInternal<T>(index, viewData);
}
export function loadElement(index: number): LElementNode {
return loadElementInternal(index, viewData);
}
/** Gets the current binding value. */
export function getBinding(bindingIndex: number): any {
ngDevMode && assertDataInRange(viewData[bindingIndex]);

View File

@ -6,9 +6,8 @@
* found in the LICENSE file at https://angular.io/license
*/
import {LContainerNode, LElementContainerNode, LElementNode} from './node';
import {LQueries} from './query';
import {RComment} from './renderer';
import {RComment, RElement} from './renderer';
import {StylingContext} from './styling';
import {HOST, LViewData, NEXT, PARENT, QUERIES} from './view';
@ -26,7 +25,7 @@ export const NATIVE = 6;
export const RENDER_PARENT = 7;
/**
* The state associated with an LContainerNode.
* The state associated with a container.
*
* This is an array so that its structure is closer to LViewData. This helps
* when traversing the view tree (which is a mix of containers and component
@ -70,34 +69,41 @@ export interface LContainer extends Array<any> {
*/
[QUERIES]: LQueries|null;
/** The host node of this LContainer. */
// TODO: Should contain just the native element once LNode is removed.
[HOST]: LElementNode|LContainerNode|LElementContainerNode|StylingContext|LViewData;
/**
* The host element of this LContainer.
*
* The host could be an LViewData if this container is on a component node.
* In that case, the component LViewData is its HOST.
*
* It could also be a styling context if this is a node with a style/class
* binding.
*/
[HOST]: RElement|RComment|StylingContext|LViewData;
/** The comment element that serves as an anchor for this LContainer. */
[NATIVE]: RComment;
/**
* Parent Element which will contain the location where all of the Views will be
* Parent Element which will contain the location where all of the views will be
* inserted into to.
*
* If `renderParent` is `null` it is headless. This means that it is contained
* in another `LViewNode` which in turn is contained in another `LContainerNode` and
* in another view which in turn is contained in another container and
* therefore it does not yet have its own parent.
*
* If `renderParent` is not `null` then it may be:
* - same as `LContainerNode.parent` in which case it is just a normal container.
* - different from `LContainerNode.parent` in which case it has been re-projected.
* In other words `LContainerNode.parent` is logical parent where as
* `LContainer.projectedParent` is render parent.
* - same as `tContainerNode.parent` in which case it is just a normal container.
* - different from `tContainerNode.parent` in which case it has been re-projected.
* In other words `tContainerNode.parent` is logical parent where as
* `tContainerNode.projectedParent` is render parent.
*
* When views are inserted into `LContainerNode` then `renderParent` is:
* - `null`, we are in `LViewNode` keep going up a hierarchy until actual
* When views are inserted into `LContainer` then `renderParent` is:
* - `null`, we are in a view, keep going up a hierarchy until actual
* `renderParent` is found.
* - not `null`, then use the `projectedParent.native` as the `RElement` to insert
* `LViewNode`s into.
* views into.
*/
[RENDER_PARENT]: LElementNode|null;
[RENDER_PARENT]: RElement|null;
}
// Note: This hack is necessary so we don't erroneously get a circular dependency

View File

@ -6,16 +6,13 @@
* found in the LICENSE file at https://angular.io/license
*/
import {LContainer} from './container';
import {RComment, RElement, RText} from './renderer';
import {StylingContext} from './styling';
import {LViewData, TView} from './view';
/**
* TNodeType corresponds to the TNode.type property. It contains information
* on how to map a particular set of bits in LNode.flags to the node type.
* on how to map a particular set of bits in TNode.flags to the node type.
*/
export const enum TNodeType {
Container = 0b000,
@ -46,68 +43,6 @@ export const enum TNodeFlags {
DirectiveStartingIndexShift = 15,
}
/**
* LNode is an internal data structure which is used for the incremental DOM algorithm.
* The "L" stands for "Logical" to differentiate between `RNodes` (actual rendered DOM
* node) and our logical representation of DOM nodes, `LNodes`.
*
* The data structure is optimized for speed and size.
*
* In order to be fast, all subtypes of `LNode` should have the same shape.
* Because size of the `LNode` matters, many fields have multiple roles depending
* on the `LNode` subtype.
*
* See: https://en.wikipedia.org/wiki/Inline_caching#Monomorphic_inline_caching
*
* NOTE: This is a private data structure and should not be exported by any of the
* instructions.
*/
export interface LNode {
/**
* The associated DOM node. Storing this allows us to:
* - append children to their element parents in the DOM (e.g. `parent.native.appendChild(...)`)
* - retrieve the sibling elements of text nodes whose creation / insertion has been delayed
*/
readonly native: RComment|RElement|RText|null;
}
/** LNode representing an element. */
export interface LElementNode extends LNode {
/** The DOM element associated with this node. */
readonly native: RElement;
}
/** LNode representing <ng-container>. */
export interface LElementContainerNode extends LNode {
/** The DOM comment associated with this node. */
readonly native: RComment;
}
/** LNode representing a #text node. */
export interface LTextNode extends LNode {
/** The text node associated with this node. */
native: RText;
}
/** Abstract node which contains root nodes of a view. */
export interface LViewNode extends LNode { readonly native: null; }
/** Abstract node container which contains other views. */
export interface LContainerNode extends LNode {
/*
* This comment node is appended to the container's parent element to mark where
* in the DOM the container's child views should be added.
*
* If the container is a root node of a view, this comment will not be appended
* until the parent view is processed.
*/
native: RComment;
}
export interface LProjectionNode extends LNode { readonly native: null; }
/**
* A set of marker values to be used in the attributes arrays. Those markers indicate that some
* items are not regular attributes and the processing should be adapted accordingly.
@ -137,7 +72,7 @@ export const enum AttributeMarker {
export type TAttributes = (string | AttributeMarker)[];
/**
* LNode binding data (flyweight) for a particular node that is shared between all templates
* Binding data (flyweight) for a particular node that is shared between all templates
* of a specific type.
*
* If a property is:
@ -152,9 +87,9 @@ export interface TNode {
type: TNodeType;
/**
* Index of the TNode in TView.data and corresponding LNode in LView.data.
* Index of the TNode in TView.data and corresponding native element in LViewData.
*
* This is necessary to get from any TNode to its corresponding LNode when
* This is necessary to get from any TNode to its corresponding native element when
* traversing the node tree.
*
* If index is -1, this is a dynamically created container node or embedded view node.
@ -247,7 +182,7 @@ export interface TNode {
/**
* The TView or TViews attached to this node.
*
* If this TNode corresponds to an LContainerNode with inline views, the container will
* If this TNode corresponds to an LContainer with inline views, the container will
* need to store separate static data for each of its view blocks (TView[]). Otherwise,
* nodes in inline views with the same index as nodes in their parent views will overwrite
* each other, as they are in the same template.
@ -259,10 +194,10 @@ export interface TNode {
* [{tagName: 'div', attrs: ...}, null], // V(0) TView
* [{tagName: 'button', attrs ...}, null] // V(1) TView
*
* If this TNode corresponds to an LContainerNode with a template (e.g. structural
* If this TNode corresponds to an LContainer with a template (e.g. structural
* directive), the template's TView will be stored here.
*
* If this TNode corresponds to an LElementNode, tViews will be null .
* If this TNode corresponds to an element, tViews will be null .
*/
tViews: TView|TView[]|null;
@ -342,7 +277,7 @@ export interface TNode {
projection: (TNode|null)[]|number|null;
}
/** Static data for an LElementNode */
/** Static data for an element */
export interface TElementNode extends TNode {
/** Index in the data[] array */
index: number;
@ -363,7 +298,7 @@ export interface TElementNode extends TNode {
projection: (TNode|null)[]|null;
}
/** Static data for an LTextNode */
/** Static data for a text node */
export interface TTextNode extends TNode {
/** Index in the data[] array */
index: number;
@ -378,7 +313,7 @@ export interface TTextNode extends TNode {
projection: null;
}
/** Static data for an LContainerNode */
/** Static data for an LContainer */
export interface TContainerNode extends TNode {
/**
* Index in the data[] array.
@ -401,7 +336,7 @@ export interface TContainerNode extends TNode {
}
/** Static data for an LElementContainerNode */
/** Static data for an <ng-container> */
export interface TElementContainerNode extends TNode {
/** Index in the LViewData[] array. */
index: number;
@ -411,7 +346,7 @@ export interface TElementContainerNode extends TNode {
projection: null;
}
/** Static data for an LViewNode */
/** Static data for a view */
export interface TViewNode extends TNode {
/** If -1, it's a dynamically created view. Otherwise, it is the view block ID. */
index: number;

View File

@ -7,8 +7,8 @@
*/
import {StyleSanitizeFn} from '../../sanitization/style_sanitizer';
import {RElement} from '../interfaces/renderer';
import {LElementNode} from './node';
import {PlayerContext} from './player';
@ -118,9 +118,8 @@ import {PlayerContext} from './player';
* `updateStyleProp` or `updateClassProp` cannot be called with a new property (only
* `updateStylingMap` can include new CSS properties that will be added to the context).
*/
export interface StylingContext extends
Array<InitialStyles|{[key: string]: any}|number|string|boolean|LElementNode|StyleSanitizeFn|
PlayerContext|null> {
export interface StylingContext extends Array<InitialStyles|{[key: string]: any}|number|string|
boolean|RElement|StyleSanitizeFn|PlayerContext|null> {
/**
* Location of animation context (which contains the active players) for this element styling
* context.
@ -154,7 +153,7 @@ export interface StylingContext extends
/**
* Location of element that is used as a target for this context.
*/
[StylingIndex.ElementPosition]: LElementNode|null;
[StylingIndex.ElementPosition]: RElement|null;
/**
* The last class value that was interpreted by elementStylingMap. This is cached

View File

@ -13,9 +13,9 @@ import {PlayerHandler} from '../interfaces/player';
import {LContainer} from './container';
import {ComponentDef, ComponentQuery, ComponentTemplate, DirectiveDef, DirectiveDefList, HostBindingsFunction, PipeDef, PipeDefList} from './definition';
import {LContainerNode, LElementContainerNode, LElementNode, TElementNode, TNode, TViewNode} from './node';
import {TElementNode, TNode, TViewNode} from './node';
import {LQueries} from './query';
import {Renderer3} from './renderer';
import {RElement, Renderer3} from './renderer';
import {StylingContext} from './styling';
/** Size of LViewData's header. Necessary to adjust for it when setting slots. */
@ -100,8 +100,7 @@ export interface LViewData extends Array<any> {
*
* If this is an embedded view, HOST will be null.
*/
// TODO: should store native elements directly when we remove LNode
[HOST]: LElementNode|LContainerNode|LElementContainerNode|StylingContext|null;
[HOST]: RElement|StylingContext|null;
/**
* Pointer to the `TViewNode` or `TElementNode` which represents the root of the view.

View File

@ -7,7 +7,7 @@
*/
import {assertDefined, assertEqual} from './assert';
import {LNode, TNode, TNodeType} from './interfaces/node';
import {TNode, TNodeType} from './interfaces/node';
export function assertNodeType(tNode: TNode, type: TNodeType) {
assertDefined(tNode, 'should be called with a TNode');

View File

@ -10,30 +10,29 @@ import {assertDefined} from './assert';
import {attachPatchData} from './context_discovery';
import {callHooks} from './hooks';
import {LContainer, NATIVE, RENDER_PARENT, VIEWS, unusedValueExportToPlacateAjd as unused1} from './interfaces/container';
import {LContainerNode, LElementContainerNode, LElementNode, TContainerNode, TElementContainerNode, TElementNode, TNode, TNodeFlags, TNodeType, TViewNode, unusedValueExportToPlacateAjd as unused2} from './interfaces/node';
import {TContainerNode, TElementContainerNode, TElementNode, TNode, TNodeFlags, TNodeType, TViewNode, unusedValueExportToPlacateAjd as unused2} from './interfaces/node';
import {unusedValueExportToPlacateAjd as unused3} from './interfaces/projection';
import {ProceduralRenderer3, RComment, RElement, RNode, RText, Renderer3, isProceduralRenderer, unusedValueExportToPlacateAjd as unused4} from './interfaces/renderer';
import {CLEANUP, CONTAINER_INDEX, FLAGS, HEADER_OFFSET, HOST_NODE, HookData, LViewData, LViewFlags, NEXT, PARENT, QUERIES, RENDERER, TVIEW, unusedValueExportToPlacateAjd as unused5} from './interfaces/view';
import {assertNodeType} from './node_assert';
import {getLNode, getNative, isLContainer, readElementValue, stringify} from './util';
import {getNativeByTNode, isLContainer, readElementValue, stringify} from './util';
const unusedValueToPlacateAjd = unused1 + unused2 + unused3 + unused4 + unused5;
/** Retrieves the parent LNode of a given node. */
export function getParentLNode(tNode: TNode, currentView: LViewData): LElementNode|
LElementContainerNode|LContainerNode|null {
return tNode.parent == null ? getHostElementNode(currentView) :
getLNode(tNode.parent, currentView);
/** Retrieves the parent element of a given node. */
export function getParentNative(tNode: TNode, currentView: LViewData): RElement|RComment|null {
return tNode.parent == null ? getHostNative(currentView) :
getNativeByTNode(tNode.parent, currentView);
}
/**
* Gets the host LElementNode given a view. Will return null if the host element is an
* LViewNode, since they are being phased out.
* Gets the host element given a view. Will return null if the current view is an embedded view,
* which does not have a host element.
*/
export function getHostElementNode(currentView: LViewData): LElementNode|null {
export function getHostNative(currentView: LViewData): RElement|null {
const hostTNode = currentView[HOST_NODE] as TElementNode;
return hostTNode && hostTNode.type !== TNodeType.View ?
(getLNode(hostTNode, currentView[PARENT] !) as LElementNode) :
(getNativeByTNode(hostTNode, currentView[PARENT] !) as RElement) :
null;
}
@ -51,10 +50,10 @@ export function getLContainer(tNode: TViewNode, embeddedView: LViewData): LConta
/**
* Retrieves render parent LElementNode for a given view.
* Retrieves render parent for a given view.
* Might be null if a view is not yet attached to any container.
*/
export function getContainerRenderParent(tViewNode: TViewNode, view: LViewData): LElementNode|null {
export function getContainerRenderParent(tViewNode: TViewNode, view: LViewData): RElement|null {
const container = getLContainer(tViewNode, view);
return container ? container[RENDER_PARENT] : null;
}
@ -85,35 +84,35 @@ const projectionNodeStack: (LViewData | TNode)[] = [];
* one found, or on all of them.
*
* @param viewToWalk the view to walk
* @param action identifies the action to be performed on the LElement nodes.
* @param action identifies the action to be performed on the elements
* @param renderer the current renderer.
* @param renderParentNode Optional the render parent node to be set in all LContainerNodes found,
* @param renderParent Optional the render parent node to be set in all LContainers found,
* required for action modes Insert and Destroy.
* @param beforeNode Optional the node before which elements should be added, required for action
* Insert.
*/
function walkTNodeTree(
viewToWalk: LViewData, action: WalkTNodeTreeAction, renderer: Renderer3,
renderParentNode?: LElementNode | null, beforeNode?: RNode | null) {
renderParent: RElement | null, beforeNode?: RNode | null) {
const rootTNode = viewToWalk[TVIEW].node as TViewNode;
let projectionNodeIndex = -1;
let currentView = viewToWalk;
let tNode: TNode|null = rootTNode.child as TNode;
while (tNode) {
let nextTNode: TNode|null = null;
const parent = renderParentNode ? renderParentNode.native : null;
if (tNode.type === TNodeType.Element) {
executeNodeAction(action, renderer, parent, getNative(tNode, currentView), beforeNode);
executeNodeAction(
action, renderer, renderParent, getNativeByTNode(tNode, currentView), beforeNode);
const nodeOrContainer = currentView[tNode.index];
if (isLContainer(nodeOrContainer)) {
// This element has an LContainer, and its comment needs to be handled
executeNodeAction(action, renderer, parent, nodeOrContainer[NATIVE], beforeNode);
executeNodeAction(action, renderer, renderParent, nodeOrContainer[NATIVE], beforeNode);
}
} else if (tNode.type === TNodeType.Container) {
const lContainer = currentView ![tNode.index] as LContainer;
executeNodeAction(action, renderer, parent, lContainer[NATIVE], beforeNode);
executeNodeAction(action, renderer, renderParent, lContainer[NATIVE], beforeNode);
if (renderParentNode) lContainer[RENDER_PARENT] = renderParentNode;
if (renderParent) lContainer[RENDER_PARENT] = renderParent;
if (lContainer[VIEWS].length) {
currentView = lContainer[VIEWS][0];
@ -151,7 +150,7 @@ function walkTNodeTree(
nextTNode = tNode.next;
/**
* Find the next node in the LNode tree, taking into account the place where a node is
* Find the next node in the TNode tree, taking into account the place where a node is
* projected (in the shadow DOM) rather than where it comes from (in the light DOM).
*
* If there is no sibling node, then it goes to the next sibling of the parent node...
@ -241,14 +240,13 @@ export function addRemoveViewFromContainer(
export function addRemoveViewFromContainer(viewToWalk: LViewData, insertMode: false): void;
export function addRemoveViewFromContainer(
viewToWalk: LViewData, insertMode: boolean, beforeNode?: RNode | null): void {
const parentNode = getContainerRenderParent(viewToWalk[TVIEW].node as TViewNode, viewToWalk);
const parent = parentNode ? parentNode.native : null;
const renderParent = getContainerRenderParent(viewToWalk[TVIEW].node as TViewNode, viewToWalk);
ngDevMode && assertNodeType(viewToWalk[TVIEW].node as TNode, TNodeType.View);
if (parent) {
if (renderParent) {
const renderer = viewToWalk[RENDERER];
walkTNodeTree(
viewToWalk, insertMode ? WalkTNodeTreeAction.Insert : WalkTNodeTreeAction.Detach, renderer,
parentNode, beforeNode);
renderParent, beforeNode);
}
}
@ -407,7 +405,7 @@ export function getLViewChild(viewData: LViewData): LViewData|LContainer|null {
export function destroyLView(view: LViewData) {
const renderer = view[RENDERER];
if (isProceduralRenderer(renderer) && renderer.destroyNode) {
walkTNodeTree(view, WalkTNodeTreeAction.Destroy, renderer);
walkTNodeTree(view, WalkTNodeTreeAction.Destroy, renderer, null);
}
destroyViewTree(view);
// Sets the destroyed flag
@ -466,7 +464,7 @@ function removeListeners(viewData: LViewData): void {
for (let i = 0; i < cleanup.length - 1; i += 2) {
if (typeof cleanup[i] === 'string') {
// This is a listener with the native renderer
const native = readElementValue(viewData[cleanup[i + 1]]).native;
const native = readElementValue(viewData[cleanup[i + 1]]);
const listener = viewData[CLEANUP] ![cleanup[i + 2]];
native.removeEventListener(cleanup[i], listener, cleanup[i + 3]);
i += 2;
@ -501,12 +499,12 @@ function executePipeOnDestroys(viewData: LViewData): void {
}
}
export function getRenderParent(tNode: TNode, currentView: LViewData): LElementNode|null {
export function getRenderParent(tNode: TNode, currentView: LViewData): RElement|null {
if (canInsertNativeNode(tNode, currentView)) {
const hostTNode = currentView[HOST_NODE];
return tNode.parent == null && hostTNode !.type === TNodeType.View ?
getContainerRenderParent(hostTNode as TViewNode, currentView) :
getParentLNode(tNode, currentView) as LElementNode;
getParentNative(tNode, currentView) as RElement;
}
return null;
}
@ -615,25 +613,22 @@ function nativeInsertBefore(
*/
export function appendChild(
childEl: RNode | null, childTNode: TNode, currentView: LViewData): boolean {
const parentLNode = getParentLNode(childTNode, currentView);
const parentEl = parentLNode ? parentLNode.native : null;
if (childEl !== null && canInsertNativeNode(childTNode, currentView)) {
const renderer = currentView[RENDERER];
const parentEl = getParentNative(childTNode, currentView);
const parentTNode: TNode = childTNode.parent || currentView[HOST_NODE] !;
if (parentTNode.type === TNodeType.View) {
const lContainer = getLContainer(parentTNode as TViewNode, currentView) as LContainer;
const renderParent = lContainer[RENDER_PARENT];
const views = lContainer[VIEWS];
const index = views.indexOf(currentView);
nativeInsertBefore(
renderer, renderParent !.native, childEl,
renderer, lContainer[RENDER_PARENT] !, childEl,
getBeforeNodeForView(index, views, lContainer[NATIVE]));
} else if (parentTNode.type === TNodeType.ElementContainer) {
let elementContainer = getHighestElementContainer(childTNode);
let node: LElementNode = getRenderParent(elementContainer, currentView) !;
nativeInsertBefore(renderer, node.native, childEl, parentEl);
let renderParent: RElement = getRenderParent(elementContainer, currentView) !;
nativeInsertBefore(renderer, renderParent, childEl, parentEl);
} else {
isProceduralRenderer(renderer) ? renderer.appendChild(parentEl !as RElement, childEl) :
parentEl !.appendChild(childEl);
@ -660,27 +655,28 @@ export function getBeforeNodeForView(index: number, views: LViewData[], containe
if (index + 1 < views.length) {
const view = views[index + 1] as LViewData;
const viewTNode = view[HOST_NODE] as TViewNode;
return viewTNode.child ? getNative(viewTNode.child, view) : containerNative;
return viewTNode.child ? getNativeByTNode(viewTNode.child, view) : containerNative;
} else {
return containerNative;
}
}
/**
* Removes the `child` element of the `parent` from the DOM.
* Removes the `child` element from the DOM if not in view and not projected.
*
* @param parentEl The parent element from which to remove the child
* @param child The child that should be removed
* @param childTNode The TNode of the child to remove
* @param childEl The child that should be removed
* @param currentView The current LView
* @returns Whether or not the child was removed
*/
export function removeChild(tNode: TNode, child: RNode | null, currentView: LViewData): boolean {
const parentNative = getParentLNode(tNode, currentView) !.native as RElement;
if (child !== null && canInsertNativeNode(tNode, currentView)) {
// We only remove the element if not in View or not projected.
export function removeChild(
childTNode: TNode, childEl: RNode | null, currentView: LViewData): boolean {
// We only remove the element if not in View or not projected.
if (childEl !== null && canInsertNativeNode(childTNode, currentView)) {
const parentNative = getParentNative(childTNode, currentView) !as RElement;
const renderer = currentView[RENDERER];
isProceduralRenderer(renderer) ? renderer.removeChild(parentNative as RElement, child) :
parentNative !.removeChild(child);
isProceduralRenderer(renderer) ? renderer.removeChild(parentNative as RElement, childEl) :
parentNative !.removeChild(childEl);
return true;
}
return false;
@ -698,7 +694,7 @@ export function removeChild(tNode: TNode, child: RNode | null, currentView: LVie
export function appendProjectedNode(
projectedTNode: TNode, tProjectionNode: TNode, currentView: LViewData,
projectionView: LViewData): void {
const native = getNative(projectedTNode, projectionView);
const native = getNativeByTNode(projectedTNode, projectionView);
appendChild(native, tProjectionNode, currentView);
// the projected contents are processed while in the shadow view (which is the currentView)

View File

@ -8,7 +8,6 @@
import {StyleSanitizeFn} from '../../sanitization/style_sanitizer';
import {InitialStylingFlags} from '../interfaces/definition';
import {LElementNode} from '../interfaces/node';
import {Renderer3, RendererStyleFlags3, isProceduralRenderer} from '../interfaces/renderer';
import {InitialStyles, StylingContext, StylingFlags, StylingIndex} from '../interfaces/styling';
@ -388,7 +387,7 @@ export function renderStyling(
context: StylingContext, renderer: Renderer3, styleStore?: {[key: string]: any},
classStore?: {[key: string]: boolean}) {
if (isContextDirty(context)) {
const native = context[StylingIndex.ElementPosition] !.native;
const native = context[StylingIndex.ElementPosition] !;
const multiStartIndex = getMultiStartIndex(context);
const styleSanitizer = getStyleSanitizer(context);
for (let i = StylingIndex.SingleStylesStartPosition; i < context.length;

View File

@ -10,8 +10,8 @@ import {StyleSanitizeFn} from '../../sanitization/style_sanitizer';
import {getContext} from '../context_discovery';
import {ACTIVE_INDEX, LContainer} from '../interfaces/container';
import {LContext} from '../interfaces/context';
import {LElementNode} from '../interfaces/node';
import {PlayerContext} from '../interfaces/player';
import {RElement} from '../interfaces/renderer';
import {InitialStyles, StylingContext, StylingIndex} from '../interfaces/styling';
import {FLAGS, HEADER_OFFSET, HOST, LViewData} from '../interfaces/view';
import {getTNode} from '../util';
@ -20,7 +20,7 @@ export const EMPTY_ARR: any[] = [];
export const EMPTY_OBJ: {[key: string]: any} = {};
export function createEmptyStylingContext(
element?: LElementNode | null, sanitizer?: StyleSanitizeFn | null,
element?: RElement | null, sanitizer?: StyleSanitizeFn | null,
initialStylingValues?: InitialStyles): StylingContext {
return [
null, // PlayerContext
@ -41,10 +41,10 @@ export function createEmptyStylingContext(
* (instructions.ts has logic for caching this).
*/
export function allocStylingContext(
lElement: LElementNode | null, templateStyleContext: StylingContext): StylingContext {
element: RElement | null, templateStyleContext: StylingContext): StylingContext {
// each instance gets a copy
const context = templateStyleContext.slice() as any as StylingContext;
context[StylingIndex.ElementPosition] = lElement;
context[StylingIndex.ElementPosition] = element;
return context;
}
@ -61,12 +61,12 @@ export function allocStylingContext(
*/
export function getStylingContext(index: number, viewData: LViewData): StylingContext {
let storageIndex = index + HEADER_OFFSET;
let slotValue: LContainer|LViewData|StylingContext|LElementNode = viewData[storageIndex];
let slotValue: LContainer|LViewData|StylingContext|RElement = viewData[storageIndex];
let wrapper: LContainer|LViewData|StylingContext = viewData;
while (Array.isArray(slotValue)) {
wrapper = slotValue;
slotValue = slotValue[HOST] as LViewData | StylingContext | LElementNode;
slotValue = slotValue[HOST] as LViewData | StylingContext | RElement;
}
if (isStylingContext(wrapper)) {

View File

@ -11,10 +11,10 @@ import {devModeEqual} from '../change_detection/change_detection_util';
import {assertDefined, assertLessThan} from './assert';
import {ACTIVE_INDEX, LContainer} from './interfaces/container';
import {LContext, MONKEY_PATCH_KEY_NAME} from './interfaces/context';
import {LContainerNode, LElementContainerNode, LElementNode, LNode, TNode, TNodeFlags} from './interfaces/node';
import {TNode, TNodeFlags} from './interfaces/node';
import {RComment, RElement, RText} from './interfaces/renderer';
import {StylingContext} from './interfaces/styling';
import {CONTEXT, FLAGS, HEADER_OFFSET, HOST, LViewData, LViewFlags, PARENT, RootContext, TData, TVIEW, TView} from './interfaces/view';
import {CONTEXT, FLAGS, HEADER_OFFSET, HOST, LViewData, LViewFlags, PARENT, RootContext, TData, TVIEW} from './interfaces/view';
/**
@ -38,16 +38,6 @@ export function stringify(value: any): string {
return '' + value;
}
/**
* Function that throws a "not implemented" error so it's clear certain
* behaviors/methods aren't yet ready.
*
* @returns Not implemented error
*/
export function notImplemented(): Error {
return new Error('NotImplemented');
}
/**
* Flattens an array in non-recursive way. Input arrays are not modified.
*/
@ -83,16 +73,6 @@ export function assertDataInRangeInternal(index: number, arr: any[]) {
assertLessThan(index, arr ? arr.length : 0, 'index expected to be a valid data index');
}
/** Retrieves an element value from the provided `viewData`.
*
* Elements that are read may be wrapped in a style context,
* therefore reading the value may involve unwrapping that.
*/
export function loadElementInternal(index: number, arr: LViewData): LElementNode {
const value = loadInternal<LElementNode>(index, arr);
return readElementValue(value);
}
/**
* Takes the value of a slot in `LViewData` and returns the element node.
*
@ -104,21 +84,23 @@ export function loadElementInternal(index: number, arr: LViewData): LElementNode
*
* @param value The initial value in `LViewData`
*/
export function readElementValue(value: LElementNode | StylingContext | LContainer | LViewData):
LElementNode {
export function readElementValue(value: RElement | StylingContext | LContainer | LViewData):
RElement {
while (Array.isArray(value)) {
value = value[HOST] as any;
}
return value;
}
export function getNative(tNode: TNode, hostView: LViewData): RElement|RText|RComment {
return getLNode(tNode, hostView).native;
/**
* Retrieves an element value from the provided `viewData`, by unwrapping
* from any containers, component views, or style contexts.
*/
export function getNativeByIndex(index: number, arr: LViewData): RElement {
return readElementValue(arr[index + HEADER_OFFSET]);
}
// TODO(kara): remove when removing LNode.native
export function getLNode(tNode: TNode, hostView: LViewData): LElementNode|LContainerNode|
LElementContainerNode {
export function getNativeByTNode(tNode: TNode, hostView: LViewData): RElement|RText|RComment {
return readElementValue(hostView[tNode.index]);
}
@ -140,7 +122,7 @@ export function isComponent(tNode: TNode): boolean {
return (tNode.flags & TNodeFlags.isComponent) === TNodeFlags.isComponent;
}
export function isLContainer(value: LNode | LContainer | StylingContext): boolean {
export function isLContainer(value: RElement | RComment | LContainer | StylingContext): boolean {
// Styling contexts are also arrays, but their first index contains an element node
return Array.isArray(value) && typeof value[ACTIVE_INDEX] === 'number';
}

View File

@ -28,7 +28,7 @@ import {RComment, RElement, Renderer3, isProceduralRenderer} from './interfaces/
import {CONTEXT, HOST_NODE, LViewData, QUERIES, RENDERER, TVIEW, TView} from './interfaces/view';
import {assertNodeOfPossibleTypes, assertNodeType} from './node_assert';
import {addRemoveViewFromContainer, appendChild, detachView, findComponentView, getBeforeNodeForView, getRenderParent, insertView, removeView} from './node_manipulation';
import {getComponentViewByIndex, getNative, isComponent, isLContainer} from './util';
import {getComponentViewByIndex, getNativeByTNode, isComponent, isLContainer} from './util';
import {ViewRef} from './view_ref';
@ -60,7 +60,7 @@ export function createElementRef(
// TODO: Fix class name, should be ElementRef, but there appears to be a rollup bug
R3ElementRef = class ElementRef_ extends ElementRefToken {};
}
return new R3ElementRef(getNative(tNode, view));
return new R3ElementRef(getNativeByTNode(tNode, view));
}
let R3TemplateRef: {

View File

@ -410,6 +410,9 @@
{
"name": "createViewBlueprint"
},
{
"name": "createViewNode"
},
{
"name": "createViewQuery"
},
@ -579,7 +582,7 @@
"name": "getHighestElementContainer"
},
{
"name": "getHostElementNode"
"name": "getHostNative"
},
{
"name": "getInitialIndex"
@ -596,12 +599,6 @@
{
"name": "getLContainer"
},
{
"name": "getLNode"
},
{
"name": "getLNodeFromViewData"
},
{
"name": "getLViewChild"
},
@ -612,7 +609,10 @@
"name": "getMultiStartIndex"
},
{
"name": "getNative"
"name": "getNativeByIndex"
},
{
"name": "getNativeByTNode"
},
{
"name": "getOrCreateInjectable"
@ -636,7 +636,7 @@
"name": "getParentInjectorView"
},
{
"name": "getParentLNode"
"name": "getParentNative"
},
{
"name": "getParentState"
@ -797,15 +797,6 @@
{
"name": "listener"
},
{
"name": "loadElement"
},
{
"name": "loadElementInternal"
},
{
"name": "loadInternal"
},
{
"name": "locateHostElement"
},

View File

@ -243,7 +243,7 @@
"name": "getHighestElementContainer"
},
{
"name": "getHostElementNode"
"name": "getHostNative"
},
{
"name": "getInjectorIndex"
@ -251,14 +251,11 @@
{
"name": "getLContainer"
},
{
"name": "getLNode"
},
{
"name": "getLViewChild"
},
{
"name": "getNative"
"name": "getNativeByTNode"
},
{
"name": "getOrCreateNodeInjector"
@ -276,7 +273,7 @@
"name": "getParentInjectorView"
},
{
"name": "getParentLNode"
"name": "getParentNative"
},
{
"name": "getPipeDef"

View File

@ -473,6 +473,9 @@
{
"name": "createViewBlueprint"
},
{
"name": "createViewNode"
},
{
"name": "createViewQuery"
},
@ -624,7 +627,7 @@
"name": "getHighestElementContainer"
},
{
"name": "getHostElementNode"
"name": "getHostNative"
},
{
"name": "getInitialIndex"
@ -641,9 +644,6 @@
{
"name": "getLContainer"
},
{
"name": "getLNode"
},
{
"name": "getLViewChild"
},
@ -654,7 +654,10 @@
"name": "getMultiStartIndex"
},
{
"name": "getNative"
"name": "getNativeByIndex"
},
{
"name": "getNativeByTNode"
},
{
"name": "getOrCreateInjectable"
@ -675,7 +678,7 @@
"name": "getParentInjectorView"
},
{
"name": "getParentLNode"
"name": "getParentNative"
},
{
"name": "getParentState"
@ -815,12 +818,6 @@
{
"name": "listener"
},
{
"name": "loadElement"
},
{
"name": "loadElementInternal"
},
{
"name": "loadInternal"
},

View File

@ -1364,6 +1364,9 @@
{
"name": "createViewBlueprint"
},
{
"name": "createViewNode"
},
{
"name": "createViewQuery"
},
@ -1659,7 +1662,7 @@
"name": "getHighestElementContainer"
},
{
"name": "getHostElementNode"
"name": "getHostNative"
},
{
"name": "getInitialIndex"
@ -1679,9 +1682,6 @@
{
"name": "getLContainer"
},
{
"name": "getLNode"
},
{
"name": "getLViewChild"
},
@ -1740,7 +1740,10 @@
"name": "getNamedFormat"
},
{
"name": "getNative"
"name": "getNativeByIndex"
},
{
"name": "getNativeByTNode"
},
{
"name": "getNgModuleDef"
@ -1779,7 +1782,7 @@
"name": "getParentInjectorView"
},
{
"name": "getParentLNode"
"name": "getParentNative"
},
{
"name": "getParentState"
@ -2051,12 +2054,6 @@
{
"name": "listener"
},
{
"name": "loadElement"
},
{
"name": "loadElementInternal"
},
{
"name": "loadInternal"
},

View File

@ -13,10 +13,10 @@ import {defineComponent} from '../../src/render3/definition';
import {bloomAdd, bloomHashBitOrFactory as bloomHash, getOrCreateNodeInjector, injectAttribute, injectorHasToken} from '../../src/render3/di';
import {PublicFeature, defineDirective, directiveInject, elementProperty, load, templateRefExtractor} from '../../src/render3/index';
import {bind, container, containerRefreshEnd, containerRefreshStart, createNodeAtIndex, createLViewData, createTView, element, elementEnd, elementStart, embeddedViewEnd, embeddedViewStart, enterView, interpolation2, leaveView, projection, projectionDef, reference, template, text, textBinding, elementContainerStart, elementContainerEnd, loadElement} from '../../src/render3/instructions';
import {isProceduralRenderer} from '../../src/render3/interfaces/renderer';
import {AttributeMarker, LContainerNode, LElementNode, TNodeType} from '../../src/render3/interfaces/node';
import {bind, container, containerRefreshEnd, containerRefreshStart, createNodeAtIndex, createLViewData, createTView, element, elementEnd, elementStart, embeddedViewEnd, embeddedViewStart, enterView, interpolation2, leaveView, projection, projectionDef, reference, template, text, textBinding, elementContainerStart, elementContainerEnd, _getViewData} from '../../src/render3/instructions';
import {isProceduralRenderer, RElement} from '../../src/render3/interfaces/renderer';
import {AttributeMarker, TNodeType} from '../../src/render3/interfaces/node';
import {getNativeByIndex} from '../../src/render3/util';
import {LViewFlags} from '../../src/render3/interfaces/view';
import {ViewRef} from '../../src/render3/view_ref';
@ -1086,7 +1086,7 @@ describe('di', () => {
it('should create directive with ElementRef dependencies', () => {
let dir !: Directive;
let dirSameInstance !: DirectiveSameInstance;
let divNode !: LElementNode;
let div !: RElement;
class Directive {
value: string;
@ -1121,14 +1121,14 @@ describe('di', () => {
if (rf & RenderFlags.Create) {
elementStart(0, 'div', ['dir', '', 'dirSame', '']);
elementEnd();
divNode = load(0);
div = getNativeByIndex(0, _getViewData());
}
}, 1, 0, [Directive, DirectiveSameInstance]);
const fixture = new ComponentFixture(App);
expect(dir.value).toContain('ElementRef');
expect(dir.elementRef.nativeElement).toEqual(divNode.native);
expect(dirSameInstance.elementRef.nativeElement).toEqual(divNode.native);
expect(dir.elementRef.nativeElement).toEqual(div);
expect(dirSameInstance.elementRef.nativeElement).toEqual(div);
// Each ElementRef instance should be unique
expect(dirSameInstance.isSameInstance).toBe(false);
@ -1841,7 +1841,7 @@ describe('di', () => {
null !, createTView(-1, null, 1, 0, null, null, null), null, LViewFlags.CheckAlways);
const oldView = enterView(contentView, null);
try {
const parentTNode = createNodeAtIndex(0, TNodeType.Element, null, null, null, null);
const parentTNode = createNodeAtIndex(0, TNodeType.Element, null, null, null);
// Simulate the situation where the previous parent is not initialized.
// This happens on first bootstrap because we don't init existing values
// so that we have smaller HelloWorld.

View File

@ -8,12 +8,11 @@
import {NgForOfContext} from '@angular/common';
import {RenderFlags, directiveInject} from '../../src/render3';
import {RenderFlags} from '../../src/render3';
import {defineComponent} from '../../src/render3/definition';
import {bind, element, elementAttribute, elementEnd, elementProperty, elementStart, elementStyleProp, elementStyling, elementStylingApply, elementStylingMap, interpolation1, renderTemplate, template, text, textBinding} from '../../src/render3/instructions';
import {InitialStylingFlags} from '../../src/render3/interfaces/definition';
import {AttributeMarker, LElementNode, LNode} from '../../src/render3/interfaces/node';
import {RElement, domRendererFactory3} from '../../src/render3/interfaces/renderer';
import {AttributeMarker} from '../../src/render3/interfaces/node';
import {bypassSanitizationTrustHtml, bypassSanitizationTrustResourceUrl, bypassSanitizationTrustScript, bypassSanitizationTrustStyle, bypassSanitizationTrustUrl} from '../../src/sanitization/bypass';
import {defaultStyleSanitizer, sanitizeHtml, sanitizeResourceUrl, sanitizeScript, sanitizeStyle, sanitizeUrl} from '../../src/sanitization/sanitization';
import {Sanitizer, SecurityContext} from '../../src/sanitization/security';

View File

@ -1970,7 +1970,7 @@ describe('render3 integration test', () => {
const elementResult = result1[HEADER_OFFSET]; // first element
expect(Array.isArray(elementResult)).toBeTruthy();
expect(elementResult[StylingIndex.ElementPosition].native).toBe(section);
expect(elementResult[StylingIndex.ElementPosition]).toBe(section);
const context = getContext(section) !;
const result2 = section[MONKEY_PATCH_KEY_NAME];

View File

@ -13,13 +13,13 @@ import {getProjectAsAttrValue, isNodeMatchingSelectorList, isNodeMatchingSelecto
import {createTNode} from '@angular/core/src/render3/instructions';
function testLStaticData(tagName: string, attrs: TAttributes | null): TNode {
return createTNode(TNodeType.Element, 0, tagName, attrs, null, null);
return createTNode(TNodeType.Element, 0, tagName, attrs, null);
}
describe('css selector matching', () => {
function isMatching(tagName: string, attrs: TAttributes | null, selector: CssSelector): boolean {
return isNodeMatchingSelector(
createTNode(TNodeType.Element, 0, tagName, attrs, null, null), selector);
createTNode(TNodeType.Element, 0, tagName, attrs, null), selector);
}
describe('isNodeMatchingSimpleSelector', () => {
@ -36,7 +36,7 @@ describe('css selector matching', () => {
});
/**
* We assume that compiler will lower-case tag names both in LNode
* We assume that compiler will lower-case tag names both in node
* and in a selector.
*/
it('should match element name case-sensitively', () => {

View File

@ -13,8 +13,8 @@ import {EventEmitter} from '../..';
import {directiveInject} from '../../src/render3/di';
import {AttributeMarker, QueryList, defineComponent, defineDirective, detectChanges} from '../../src/render3/index';
import {bind, container, containerRefreshEnd, containerRefreshStart, element, elementContainerEnd, elementContainerStart, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, load, loadElement, loadQueryList, reference, registerContentQuery, template} from '../../src/render3/instructions';
import {getNativeByIndex} from '../../src/render3/util';
import {bind, container, containerRefreshEnd, containerRefreshStart, element, elementContainerEnd, elementContainerStart, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, load, loadQueryList, reference, registerContentQuery, template, _getViewData} from '../../src/render3/instructions';
import {RenderFlags} from '../../src/render3/interfaces/definition';
import {query, queryRefresh} from '../../src/render3/query';
import {templateRefExtractor} from '../../src/render3/view_engine_compatibility_prebound';
@ -115,7 +115,7 @@ describe('query', () => {
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
element(1, 'div', ['child', '']);
elToQuery = loadElement(1).native;
elToQuery = getNativeByIndex(1, _getViewData());
}
},
2, 0, [Child], [],
@ -222,7 +222,7 @@ describe('query', () => {
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
element(1, 'div', null, ['foo', '']);
elToQuery = loadElement(1).native;
elToQuery = getNativeByIndex(1, _getViewData());
element(3, 'div');
}
},
@ -259,7 +259,7 @@ describe('query', () => {
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
element(2, 'div', null, ['foo', '', 'bar', '']);
elToQuery = loadElement(2).native;
elToQuery = getNativeByIndex(2, _getViewData());
element(5, 'div');
}
},
@ -306,10 +306,10 @@ describe('query', () => {
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
element(1, 'div', null, ['foo', '']);
el1ToQuery = loadElement(1).native;
el1ToQuery = getNativeByIndex(1, _getViewData());
element(3, 'div');
element(4, 'div', null, ['bar', '']);
el2ToQuery = loadElement(4).native;
el2ToQuery = getNativeByIndex(4, _getViewData());
}
},
6, 0, [], [],
@ -345,7 +345,7 @@ describe('query', () => {
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
element(1, 'div', null, ['foo', '']);
elToQuery = loadElement(1).native;
elToQuery = getNativeByIndex(1, _getViewData());
element(3, 'div');
}
},
@ -381,7 +381,7 @@ describe('query', () => {
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
elementContainerStart(1, null, ['foo', '']);
elToQuery = loadElement(1).native;
elToQuery = getNativeByIndex(1, _getViewData());
elementContainerEnd();
}
},
@ -417,7 +417,7 @@ describe('query', () => {
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
elementContainerStart(1, null, ['foo', '']);
elToQuery = loadElement(1).native;
elToQuery = getNativeByIndex(1, _getViewData());
elementContainerEnd();
}
},
@ -480,7 +480,7 @@ describe('query', () => {
elementContainerStart(2);
{
element(3, 'div', null, ['foo', '']);
elToQuery = loadElement(3).native;
elToQuery = getNativeByIndex(3, _getViewData());
}
elementContainerEnd();
}
@ -890,7 +890,7 @@ describe('query', () => {
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
element(1, 'div', ['child', ''], ['foo', 'child']);
div = loadElement(1).native;
div = getNativeByIndex(1, _getViewData());
}
},
3, 0, [Child], [],
@ -925,7 +925,7 @@ describe('query', () => {
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
element(1, 'div', ['child', ''], ['foo', '', 'bar', 'child']);
div = loadElement(1).native;
div = getNativeByIndex(1, _getViewData());
}
if (rf & RenderFlags.Update) {
childInstance = getDirectiveOnNode(1);
@ -1409,7 +1409,7 @@ describe('query', () => {
{
if (rf1 & RenderFlags.Create) {
element(0, 'div', null, ['foo', '']);
firstEl = loadElement(0).native;
firstEl = getNativeByIndex(0, _getViewData());
}
}
embeddedViewEnd();
@ -1461,10 +1461,10 @@ describe('query', () => {
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
element(1, 'span', null, ['foo', '']);
firstEl = loadElement(1).native;
firstEl = getNativeByIndex(1, _getViewData());
container(3);
element(4, 'span', null, ['foo', '']);
lastEl = loadElement(4).native;
lastEl = getNativeByIndex(4, _getViewData());
}
if (rf & RenderFlags.Update) {
containerRefreshStart(3);
@ -1474,7 +1474,7 @@ describe('query', () => {
{
if (rf1 & RenderFlags.Create) {
element(0, 'div', null, ['foo', '']);
viewEl = loadElement(0).native;
viewEl = getNativeByIndex(0, _getViewData());
}
}
embeddedViewEnd();
@ -1541,7 +1541,7 @@ describe('query', () => {
{
if (rf0 & RenderFlags.Create) {
element(0, 'div', null, ['foo', '']);
firstEl = loadElement(0).native;
firstEl = getNativeByIndex(0, _getViewData());
}
}
embeddedViewEnd();
@ -1551,7 +1551,7 @@ describe('query', () => {
{
if (rf1 & RenderFlags.Create) {
element(0, 'span', null, ['foo', '']);
lastEl = loadElement(0).native;
lastEl = getNativeByIndex(0, _getViewData());
}
}
embeddedViewEnd();
@ -1614,7 +1614,7 @@ describe('query', () => {
{
if (rf0 & RenderFlags.Create) {
element(0, 'div', null, ['foo', '']);
firstEl = loadElement(0).native;
firstEl = getNativeByIndex(0, _getViewData());
container(2);
}
if (rf0 & RenderFlags.Update) {
@ -1625,7 +1625,7 @@ describe('query', () => {
{
if (rf2) {
element(0, 'span', null, ['foo', '']);
lastEl = loadElement(0).native;
lastEl = getNativeByIndex(0, _getViewData());
}
}
embeddedViewEnd();

View File

@ -22,7 +22,6 @@ import {NG_ELEMENT_ID} from '../../src/render3/fields';
import {ComponentTemplate, ComponentType, DirectiveDef, DirectiveType, PublicFeature, RenderFlags, defineComponent, defineDirective, renderComponent as _renderComponent, tick} from '../../src/render3/index';
import {_getViewData, renderTemplate} from '../../src/render3/instructions';
import {DirectiveDefList, DirectiveTypesOrFactory, PipeDef, PipeDefList, PipeTypesOrFactory} from '../../src/render3/interfaces/definition';
import {LElementNode} from '../../src/render3/interfaces/node';
import {PlayerHandler} from '../../src/render3/interfaces/player';
import {RElement, RText, Renderer3, RendererFactory3, domRendererFactory3} from '../../src/render3/interfaces/renderer';
import {HEADER_OFFSET, LViewData} from '../../src/render3/interfaces/view';

View File

@ -7,8 +7,7 @@
*/
import {elementEnd, elementStart, elementStyleProp, elementStyling, elementStylingApply, elementStylingMap} from '../../../src/render3/instructions';
import {InitialStylingFlags, RenderFlags} from '../../../src/render3/interfaces/definition';
import {LElementNode} from '../../../src/render3/interfaces/node';
import {Renderer3} from '../../../src/render3/interfaces/renderer';
import {RElement, Renderer3} from '../../../src/render3/interfaces/renderer';
import {StylingContext, StylingFlags, StylingIndex} from '../../../src/render3/interfaces/styling';
import {createStylingContextTemplate, isContextDirty, renderStyling as _renderStyling, setContextDirty, updateClassProp, updateStyleProp, updateStylingMap} from '../../../src/render3/styling/class_and_style_bindings';
import {allocStylingContext} from '../../../src/render3/styling/util';
@ -17,7 +16,7 @@ import {StyleSanitizeFn} from '../../../src/sanitization/style_sanitizer';
import {renderToHtml} from '../render_util';
describe('styling', () => {
let element: LElementNode|null = null;
let element: RElement|null = null;
beforeEach(() => { element = {} as any; });
function initContext(