@@ -18,7 +18,7 @@ import {CLEAN_PROMISE, _getComponentHostLElementNode, baseDirectiveCreate, creat
|
||||
import {ComponentDef, ComponentDefInternal, ComponentType} from './interfaces/definition';
|
||||
import {LElementNode} from './interfaces/node';
|
||||
import {RElement, RendererFactory3, domRendererFactory3} from './interfaces/renderer';
|
||||
import {LViewData, LViewFlags, RootContext, BINDING_INDEX, INJECTOR, CONTEXT, TVIEW} from './interfaces/view';
|
||||
import {LViewData, LViewFlags, RootContext, INJECTOR, CONTEXT, TVIEW} from './interfaces/view';
|
||||
import {stringify} from './util';
|
||||
import {getComponentDef} from './definition';
|
||||
|
||||
@@ -53,7 +53,7 @@ export interface CreateComponentOptions {
|
||||
* features list because there's no way of knowing when the component will be used as
|
||||
* a root component.
|
||||
*/
|
||||
hostFeatures?: (<T>(component: T, componentDef: ComponentDef<T, string>) => void)[];
|
||||
hostFeatures?: HostFeature[];
|
||||
|
||||
/**
|
||||
* A function which is used to schedule change detection work in the future.
|
||||
@@ -69,6 +69,9 @@ export interface CreateComponentOptions {
|
||||
scheduler?: (work: () => void) => void;
|
||||
}
|
||||
|
||||
/** See CreateComponentOptions.hostFeatures */
|
||||
type HostFeature = (<T>(component: T, componentDef: ComponentDef<T, string>) => void);
|
||||
|
||||
// TODO: A hack to not pull in the NullInjector from @angular/core.
|
||||
export const NULL_INJECTOR: Injector = {
|
||||
get: (token: any, notFoundValue?: any) => {
|
||||
@@ -103,12 +106,13 @@ export function renderComponent<T>(
|
||||
// The first index of the first selector is the tag name.
|
||||
const componentTag = componentDef.selectors ![0] ![0] as string;
|
||||
const hostNode = locateHostElement(rendererFactory, opts.host || componentTag);
|
||||
const rootFlags = componentDef.onPush ? LViewFlags.Dirty | LViewFlags.IsRoot :
|
||||
LViewFlags.CheckAlways | LViewFlags.IsRoot;
|
||||
const rootContext = createRootContext(opts.scheduler || requestAnimationFrame.bind(window));
|
||||
|
||||
const rootView: LViewData = createLViewData(
|
||||
rendererFactory.createRenderer(hostNode, componentDef),
|
||||
createTView(-1, null, 1, 0, null, null, null), rootContext,
|
||||
componentDef.onPush ? LViewFlags.Dirty : LViewFlags.CheckAlways);
|
||||
createTView(-1, null, 1, 0, null, null, null), rootContext, rootFlags);
|
||||
rootView[INJECTOR] = opts.injector || null;
|
||||
|
||||
const oldView = enterView(rootView, null);
|
||||
@@ -119,20 +123,10 @@ export function renderComponent<T>(
|
||||
|
||||
// Create element node at index 0 in data array
|
||||
elementNode = hostElement(componentTag, hostNode, componentDef, sanitizer);
|
||||
|
||||
// Create directive instance with factory() and store at index 0 in directives array
|
||||
component = baseDirectiveCreate(0, componentDef.factory() as T, componentDef, elementNode);
|
||||
if (componentDef.hostBindings) {
|
||||
queueHostBindingForCheck(0, componentDef.hostVars);
|
||||
}
|
||||
rootContext.components.push(component);
|
||||
(elementNode.data as LViewData)[CONTEXT] = component;
|
||||
initChangeDetectorIfExisting(elementNode.nodeInjector, component, elementNode.data !);
|
||||
|
||||
opts.hostFeatures && opts.hostFeatures.forEach((feature) => feature(component, componentDef));
|
||||
component = createRootComponent(
|
||||
elementNode, componentDef, rootView, rootContext, opts.hostFeatures || null);
|
||||
|
||||
executeInitAndContentHooks();
|
||||
setHostBindings(rootView[TVIEW].hostBindings);
|
||||
detectChangesInternal(elementNode.data as LViewData, component);
|
||||
} finally {
|
||||
leaveView(oldView);
|
||||
@@ -142,6 +136,27 @@ export function renderComponent<T>(
|
||||
return component;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a root component and sets it up with features and host bindings. Shared by
|
||||
* renderComponent() and ViewContainerRef.createComponent().
|
||||
*/
|
||||
export function createRootComponent<T>(
|
||||
elementNode: LElementNode, componentDef: ComponentDef<T, string>, rootView: LViewData,
|
||||
rootContext: RootContext, hostFeatures: HostFeature[] | null): any {
|
||||
// Create directive instance with factory() and store at index 0 in directives array
|
||||
const component = baseDirectiveCreate(0, componentDef.factory() as T, componentDef, elementNode);
|
||||
|
||||
if (componentDef.hostBindings) queueHostBindingForCheck(0, componentDef.hostVars);
|
||||
rootContext.components.push(component);
|
||||
(elementNode.data as LViewData)[CONTEXT] = component;
|
||||
initChangeDetectorIfExisting(elementNode.nodeInjector, component, elementNode.data as LViewData);
|
||||
|
||||
hostFeatures && hostFeatures.forEach((feature) => feature(component, componentDef));
|
||||
setHostBindings(rootView[TVIEW].hostBindings);
|
||||
return component;
|
||||
}
|
||||
|
||||
|
||||
export function createRootContext(scheduler: (workFn: () => void) => void): RootContext {
|
||||
return {
|
||||
components: [],
|
||||
@@ -169,7 +184,8 @@ export function LifecycleHooksFeature(component: any, def: ComponentDefInternal<
|
||||
// Root component is always created at dir index 0
|
||||
const tView = elementNode.view[TVIEW];
|
||||
queueInitHooks(0, def.onInit, def.doCheck, tView);
|
||||
queueLifecycleHooks(elementNode.tNode.flags, tView);
|
||||
// Directive starting index 0, directive count 1 -> directive flags: 1
|
||||
queueLifecycleHooks(1, tView);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,13 +17,13 @@ import {RendererFactory2} from '../render/api';
|
||||
import {Type} from '../type';
|
||||
|
||||
import {assertComponentType, assertDefined} from './assert';
|
||||
import {LifecycleHooksFeature, createRootContext} from './component';
|
||||
import {LifecycleHooksFeature, createRootComponent, createRootContext} from './component';
|
||||
import {getComponentDef} from './definition';
|
||||
import {adjustBlueprintForNewNode, baseDirectiveCreate, createLNode, createLViewData, createTView, elementCreate, enterView, hostElement, initChangeDetectorIfExisting, locateHostElement, queueHostBindingForCheck, renderEmbeddedTemplate, setHostBindings} from './instructions';
|
||||
import {ComponentDefInternal, ComponentType, RenderFlags} from './interfaces/definition';
|
||||
import {LElementNode, TNode, TNodeType} from './interfaces/node';
|
||||
import {adjustBlueprintForNewNode, createLViewData, createNodeAtIndex, createTView, elementCreate, enterView, getTNode, hostElement, locateHostElement, renderEmbeddedTemplate} from './instructions';
|
||||
import {ComponentDefInternal, RenderFlags} from './interfaces/definition';
|
||||
import {LElementNode, TElementNode, TNode, TNodeType, TViewNode} from './interfaces/node';
|
||||
import {RElement, RendererFactory3, domRendererFactory3} from './interfaces/renderer';
|
||||
import {CONTEXT, FLAGS, INJECTOR, LViewData, LViewFlags, RootContext, TVIEW} from './interfaces/view';
|
||||
import {FLAGS, INJECTOR, LViewData, LViewFlags, RootContext, TVIEW} from './interfaces/view';
|
||||
import {RootViewRef, ViewRef} from './view_ref';
|
||||
|
||||
export class ComponentFactoryResolver extends viewEngine_ComponentFactoryResolver {
|
||||
@@ -115,6 +115,8 @@ export class ComponentFactory<T> extends viewEngine_ComponentFactory<T> {
|
||||
// The first index of the first selector is the tag name.
|
||||
const componentTag = this.componentDef.selectors ![0] ![0] as string;
|
||||
|
||||
const rootFlags = this.componentDef.onPush ? LViewFlags.Dirty | LViewFlags.IsRoot :
|
||||
LViewFlags.CheckAlways | LViewFlags.IsRoot;
|
||||
const rootContext: RootContext = ngModule && !isInternalRootView ?
|
||||
ngModule.injector.get(ROOT_CONTEXT) :
|
||||
createRootContext(requestAnimationFrame.bind(window));
|
||||
@@ -122,8 +124,7 @@ export class ComponentFactory<T> extends viewEngine_ComponentFactory<T> {
|
||||
// Create the root view. Uses empty TView and ContentTemplate.
|
||||
const rootView: LViewData = createLViewData(
|
||||
rendererFactory.createRenderer(hostNode, this.componentDef),
|
||||
createTView(-1, null, 1, 0, null, null, null), rootContext,
|
||||
this.componentDef.onPush ? LViewFlags.Dirty : LViewFlags.CheckAlways);
|
||||
createTView(-1, null, 1, 0, null, null, null), rootContext, rootFlags);
|
||||
rootView[INJECTOR] = ngModule && ngModule.injector || null;
|
||||
|
||||
// rootView is the parent when bootstrapping
|
||||
@@ -131,54 +132,43 @@ export class ComponentFactory<T> extends viewEngine_ComponentFactory<T> {
|
||||
|
||||
let component: T;
|
||||
let elementNode: LElementNode;
|
||||
let tElementNode: TElementNode;
|
||||
try {
|
||||
if (rendererFactory.begin) rendererFactory.begin();
|
||||
|
||||
// Create element node at index 0 in data array
|
||||
elementNode = hostElement(componentTag, hostNode, this.componentDef);
|
||||
const componentView = elementNode.data as LViewData;
|
||||
|
||||
// Create directive instance with factory() and store at index 0 in directives array
|
||||
component =
|
||||
baseDirectiveCreate(0, this.componentDef.factory(), this.componentDef, elementNode);
|
||||
if (this.componentDef.hostBindings) {
|
||||
queueHostBindingForCheck(0, this.componentDef.hostVars);
|
||||
}
|
||||
rootContext.components.push(component);
|
||||
initChangeDetectorIfExisting(elementNode.nodeInjector, component, componentView);
|
||||
componentView[CONTEXT] = component;
|
||||
// TODO: should LifecycleHooksFeature and other host features be generated by the compiler and
|
||||
// executed here?
|
||||
// Angular 5 reference: https://stackblitz.com/edit/lifecycle-hooks-vcref
|
||||
LifecycleHooksFeature(component, this.componentDef);
|
||||
component = createRootComponent(
|
||||
elementNode, this.componentDef, rootView, rootContext, [LifecycleHooksFeature]);
|
||||
|
||||
setHostBindings(rootView[TVIEW].hostBindings);
|
||||
tElementNode = getTNode(0) as TElementNode;
|
||||
|
||||
// Transform the arrays of native nodes into a LNode structure that can be consumed by the
|
||||
// projection instruction. This is needed to support the reprojection of these nodes.
|
||||
if (projectableNodes) {
|
||||
let index = 0;
|
||||
const projection: TNode[] = elementNode.tNode.projection = [];
|
||||
const projection: TNode[] = tElementNode.projection = [];
|
||||
for (let i = 0; i < projectableNodes.length; i++) {
|
||||
const nodeList = projectableNodes[i];
|
||||
let firstTNode: TNode|null = null;
|
||||
let previousTNode: TNode|null = null;
|
||||
for (let j = 0; j < nodeList.length; j++) {
|
||||
adjustBlueprintForNewNode(rootView);
|
||||
const lNode =
|
||||
createLNode(++index, TNodeType.Element, nodeList[j] as RElement, null, null);
|
||||
if (previousTNode) {
|
||||
previousTNode.next = lNode.tNode;
|
||||
} else {
|
||||
firstTNode = lNode.tNode;
|
||||
}
|
||||
previousTNode = lNode.tNode;
|
||||
const tNode =
|
||||
createNodeAtIndex(++index, TNodeType.Element, nodeList[j] as RElement, null, null);
|
||||
previousTNode ? (previousTNode.next = tNode) : (firstTNode = tNode);
|
||||
previousTNode = tNode;
|
||||
}
|
||||
projection.push(firstTNode !);
|
||||
}
|
||||
}
|
||||
|
||||
// Execute the template in creation mode only, and then turn off the CreationMode flag
|
||||
const componentView = elementNode.data as LViewData;
|
||||
renderEmbeddedTemplate(componentView, componentView[TVIEW], component, RenderFlags.Create);
|
||||
componentView[FLAGS] &= ~LViewFlags.CreationMode;
|
||||
} finally {
|
||||
@@ -190,7 +180,7 @@ export class ComponentFactory<T> extends viewEngine_ComponentFactory<T> {
|
||||
new ComponentRef(this.componentType, component, rootView, injector, hostNode !);
|
||||
if (isInternalRootView) {
|
||||
// The host element of the internal root view is attached to the component's host view node
|
||||
componentRef.hostView._lViewNode !.tNode.child = elementNode.tNode;
|
||||
componentRef.hostView._tViewNode !.child = tElementNode;
|
||||
}
|
||||
return componentRef;
|
||||
}
|
||||
@@ -219,7 +209,7 @@ export class ComponentRef<T> extends viewEngine_ComponentRef<T> {
|
||||
super();
|
||||
this.instance = instance;
|
||||
this.hostView = this.changeDetectorRef = new RootViewRef<T>(rootView);
|
||||
this.hostView._lViewNode = createLNode(-1, TNodeType.View, null, null, null, rootView);
|
||||
this.hostView._tViewNode = createNodeAtIndex(-1, TNodeType.View, null, null, null, rootView);
|
||||
this.injector = injector;
|
||||
this.location = new viewEngine_ElementRef(hostNode);
|
||||
this.componentType = componentType;
|
||||
|
||||
@@ -321,9 +321,8 @@ function findViaDirective(lViewData: LViewData, directiveInstance: {}): number {
|
||||
if (directiveIndex >= 0) {
|
||||
let tNode = lViewData[TVIEW].firstChild;
|
||||
while (tNode) {
|
||||
const lNode = getLNodeFromViewData(lViewData, tNode.index) !;
|
||||
const directiveIndexStart = getDirectiveStartIndex(lNode);
|
||||
const directiveIndexEnd = getDirectiveEndIndex(lNode, directiveIndexStart);
|
||||
const directiveIndexStart = getDirectiveStartIndex(tNode);
|
||||
const directiveIndexEnd = getDirectiveEndIndex(tNode, directiveIndexStart);
|
||||
if (directiveIndex >= directiveIndexStart && directiveIndex < directiveIndexEnd) {
|
||||
return tNode.index;
|
||||
}
|
||||
@@ -357,10 +356,11 @@ function getLNodeFromViewData(lViewData: LViewData, lElementIndex: number): LEle
|
||||
function discoverDirectiveIndices(lViewData: LViewData, lNodeIndex: number): number[]|null {
|
||||
const directivesAcrossView = lViewData[DIRECTIVES];
|
||||
const lNode = getLNodeFromViewData(lViewData, lNodeIndex);
|
||||
const tNode = lViewData[TVIEW].data[lNodeIndex] as TNode;
|
||||
if (lNode && directivesAcrossView && directivesAcrossView.length) {
|
||||
// this check for tNode is to determine if the calue is a LEmementNode instance
|
||||
const directiveIndexStart = getDirectiveStartIndex(lNode);
|
||||
const directiveIndexEnd = getDirectiveEndIndex(lNode, directiveIndexStart);
|
||||
const directiveIndexStart = getDirectiveStartIndex(tNode);
|
||||
const directiveIndexEnd = getDirectiveEndIndex(tNode, directiveIndexStart);
|
||||
const directiveIndices: number[] = [];
|
||||
for (let i = directiveIndexStart; i < directiveIndexEnd; i++) {
|
||||
// special case since the instance of the component (if it exists)
|
||||
@@ -388,17 +388,17 @@ function discoverDirectives(lViewData: LViewData, directiveIndices: number[]): n
|
||||
return directives;
|
||||
}
|
||||
|
||||
function getDirectiveStartIndex(lNode: LElementNode): number {
|
||||
function getDirectiveStartIndex(tNode: TNode): number {
|
||||
// the tNode instances store a flag value which then has a
|
||||
// pointer which tells the starting index of where all the
|
||||
// active directives are in the master directive array
|
||||
return lNode.tNode.flags >> TNodeFlags.DirectiveStartingIndexShift;
|
||||
return tNode.flags >> TNodeFlags.DirectiveStartingIndexShift;
|
||||
}
|
||||
|
||||
function getDirectiveEndIndex(lNode: LElementNode, startIndex: number): number {
|
||||
// The end value is also apart of the same flag
|
||||
function getDirectiveEndIndex(tNode: TNode, startIndex: number): number {
|
||||
// The end value is also a part of the same flag
|
||||
// (see `TNodeFlags` to see how the flag bit shifting
|
||||
// values are used).
|
||||
const count = lNode.tNode.flags & TNodeFlags.DirectiveCountMask;
|
||||
const count = tNode.flags & TNodeFlags.DirectiveCountMask;
|
||||
return count ? (startIndex + count) : -1;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,11 +7,12 @@
|
||||
*/
|
||||
|
||||
import {assertEqual, assertLessThan} from './assert';
|
||||
import {NO_CHANGE, _getViewData, adjustBlueprintForNewNode, bindingUpdated, bindingUpdated2, bindingUpdated3, bindingUpdated4, createLNode, getPreviousOrParentNode, getRenderer, load, resetComponentState} from './instructions';
|
||||
import {NO_CHANGE, _getViewData, adjustBlueprintForNewNode, bindingUpdated, bindingUpdated2, bindingUpdated3, bindingUpdated4, createNodeAtIndex, getRenderer, getTNode, load, loadElement, resetComponentState} from './instructions';
|
||||
import {RENDER_PARENT} from './interfaces/container';
|
||||
import {LContainerNode, LNode, TContainerNode, TElementNode, TNodeType} from './interfaces/node';
|
||||
import {BINDING_INDEX, HEADER_OFFSET, TVIEW} from './interfaces/view';
|
||||
import {appendChild, createTextNode, getParentLNode, removeChild} from './node_manipulation';
|
||||
import {LContainerNode, LElementNode, LNode, TElementNode, TNode, TNodeType, TViewNode} from './interfaces/node';
|
||||
import {RElement} from './interfaces/renderer';
|
||||
import {BINDING_INDEX, HEADER_OFFSET, HOST_NODE, TVIEW} from './interfaces/view';
|
||||
import {appendChild, createTextNode, getContainerRenderParent, getParentLNode, getParentOrContainerNode, removeChild} from './node_manipulation';
|
||||
import {stringify} from './util';
|
||||
|
||||
/**
|
||||
@@ -245,42 +246,42 @@ function generateMappingInstructions(
|
||||
return partIndex;
|
||||
}
|
||||
|
||||
function appendI18nNode(node: LNode, parentNode: LNode, previousNode: LNode) {
|
||||
// TODO: Remove LNode arg when we remove dynamicContainerNode
|
||||
function appendI18nNode(
|
||||
node: LNode, tNode: TNode, parentTNode: TNode, previousTNode: TNode): TNode {
|
||||
if (ngDevMode) {
|
||||
ngDevMode.rendererMoveNode++;
|
||||
}
|
||||
|
||||
const viewData = _getViewData();
|
||||
|
||||
appendChild(parentNode, node.native || null, viewData);
|
||||
|
||||
// On first pass, re-organize node tree to put this node in the correct position.
|
||||
const firstTemplatePass = node.view[TVIEW].firstTemplatePass;
|
||||
if (firstTemplatePass) {
|
||||
if (previousNode === parentNode && node.tNode !== parentNode.tNode.child) {
|
||||
node.tNode.next = parentNode.tNode.child;
|
||||
parentNode.tNode.child = node.tNode;
|
||||
} else if (previousNode !== parentNode && node.tNode !== previousNode.tNode.next) {
|
||||
node.tNode.next = previousNode.tNode.next;
|
||||
previousNode.tNode.next = node.tNode;
|
||||
if (previousTNode === parentTNode && tNode !== parentTNode.child) {
|
||||
tNode.next = parentTNode.child;
|
||||
parentTNode.child = tNode;
|
||||
} else if (previousTNode !== parentTNode && tNode !== previousTNode.next) {
|
||||
tNode.next = previousTNode.next;
|
||||
previousTNode.next = tNode;
|
||||
} else {
|
||||
node.tNode.next = null;
|
||||
tNode.next = null;
|
||||
}
|
||||
|
||||
if (parentNode.view === node.view) node.tNode.parent = parentNode.tNode as TElementNode;
|
||||
if (parentTNode !== viewData[HOST_NODE]) {
|
||||
tNode.parent = parentTNode as TElementNode;
|
||||
}
|
||||
}
|
||||
|
||||
appendChild(node.native, tNode, viewData);
|
||||
|
||||
// Template containers also have a comment node for the `ViewContainerRef` that should be moved
|
||||
if (node.tNode.type === TNodeType.Container && node.dynamicLContainerNode) {
|
||||
appendChild(parentNode, node.dynamicLContainerNode.native || null, viewData);
|
||||
if (firstTemplatePass) {
|
||||
node.tNode.dynamicContainerNode = node.dynamicLContainerNode.tNode;
|
||||
node.dynamicLContainerNode.tNode.parent = node.tNode as TContainerNode;
|
||||
}
|
||||
return node.dynamicLContainerNode;
|
||||
if (tNode.type === TNodeType.Container && node.dynamicLContainerNode) {
|
||||
appendChild(node.dynamicLContainerNode.native, tNode, viewData);
|
||||
return tNode.dynamicContainerNode !;
|
||||
}
|
||||
|
||||
return node;
|
||||
return tNode;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -303,23 +304,29 @@ export function i18nApply(startIndex: number, instructions: I18nInstruction[]):
|
||||
}
|
||||
|
||||
const renderer = getRenderer();
|
||||
let localParentNode: LNode = getParentLNode(load(startIndex)) || getPreviousOrParentNode();
|
||||
let localPreviousNode: LNode = localParentNode;
|
||||
const startTNode = getTNode(startIndex);
|
||||
let localParentTNode: TNode = startTNode.parent || viewData[HOST_NODE] !;
|
||||
let localPreviousTNode: TNode = localParentTNode;
|
||||
resetComponentState(); // We don't want to add to the tree with the wrong previous node
|
||||
|
||||
for (let i = 0; i < instructions.length; i++) {
|
||||
const instruction = instructions[i] as number;
|
||||
switch (instruction & I18nInstructions.InstructionMask) {
|
||||
case I18nInstructions.Element:
|
||||
const element: LNode = load(instruction & I18nInstructions.IndexMask);
|
||||
localPreviousNode = appendI18nNode(element, localParentNode, localPreviousNode);
|
||||
localParentNode = element;
|
||||
const elementIndex = instruction & I18nInstructions.IndexMask;
|
||||
const element: LNode = load(elementIndex);
|
||||
const elementTNode = getTNode(elementIndex);
|
||||
localPreviousTNode =
|
||||
appendI18nNode(element, elementTNode, localParentTNode, localPreviousTNode);
|
||||
localParentTNode = elementTNode;
|
||||
break;
|
||||
case I18nInstructions.Expression:
|
||||
case I18nInstructions.TemplateRoot:
|
||||
case I18nInstructions.Any:
|
||||
const node: LNode = load(instruction & I18nInstructions.IndexMask);
|
||||
localPreviousNode = appendI18nNode(node, localParentNode, localPreviousNode);
|
||||
const nodeIndex = instruction & I18nInstructions.IndexMask;
|
||||
const node: LNode = load(nodeIndex);
|
||||
localPreviousTNode =
|
||||
appendI18nNode(node, getTNode(nodeIndex), localParentTNode, localPreviousTNode);
|
||||
break;
|
||||
case I18nInstructions.Text:
|
||||
if (ngDevMode) {
|
||||
@@ -329,31 +336,32 @@ export function i18nApply(startIndex: number, instructions: I18nInstruction[]):
|
||||
const textRNode = createTextNode(value, renderer);
|
||||
// If we were to only create a `RNode` then projections won't move the text.
|
||||
// Create text node at the current end of viewData. Must subtract header offset because
|
||||
// createLNode takes a raw index (not adjusted by header offset).
|
||||
// createNodeAtIndex takes a raw index (not adjusted by header offset).
|
||||
adjustBlueprintForNewNode(viewData);
|
||||
const lastNodeIndex = viewData.length - 1;
|
||||
const textLNode =
|
||||
createLNode(lastNodeIndex - HEADER_OFFSET, TNodeType.Element, textRNode, null, null);
|
||||
localPreviousNode = appendI18nNode(textLNode, localParentNode, localPreviousNode);
|
||||
const lastNodeIndex = viewData.length - 1 - HEADER_OFFSET;
|
||||
const textTNode =
|
||||
createNodeAtIndex(lastNodeIndex, TNodeType.Element, textRNode, null, null);
|
||||
localPreviousTNode = appendI18nNode(
|
||||
loadElement(lastNodeIndex), textTNode, localParentTNode, localPreviousTNode);
|
||||
resetComponentState();
|
||||
break;
|
||||
case I18nInstructions.CloseNode:
|
||||
localPreviousNode = localParentNode;
|
||||
localParentNode = getParentLNode(localParentNode) !;
|
||||
localPreviousTNode = localParentTNode;
|
||||
localParentTNode = localParentTNode.parent || viewData[HOST_NODE] !;
|
||||
break;
|
||||
case I18nInstructions.RemoveNode:
|
||||
if (ngDevMode) {
|
||||
ngDevMode.rendererRemoveNode++;
|
||||
}
|
||||
const index = instruction & I18nInstructions.IndexMask;
|
||||
const removedNode: LNode|LContainerNode = load(index);
|
||||
const parentNode = getParentLNode(removedNode) !;
|
||||
removeChild(parentNode, removedNode.native || null, viewData);
|
||||
const removeIndex = instruction & I18nInstructions.IndexMask;
|
||||
const removedNode: LNode|LContainerNode = load(removeIndex);
|
||||
const removedTNode = getTNode(removeIndex);
|
||||
removeChild(removedTNode, removedNode.native || null, viewData);
|
||||
|
||||
// For template containers we also need to remove their `ViewContainerRef` from the DOM
|
||||
if (removedNode.tNode.type === TNodeType.Container && removedNode.dynamicLContainerNode) {
|
||||
removeChild(parentNode, removedNode.dynamicLContainerNode.native || null, viewData);
|
||||
removedNode.dynamicLContainerNode.tNode.detached = true;
|
||||
if (removedTNode.type === TNodeType.Container && removedNode.dynamicLContainerNode) {
|
||||
removeChild(removedTNode, removedNode.dynamicLContainerNode.native || null, viewData);
|
||||
removedTNode.dynamicContainerNode !.detached = true;
|
||||
removedNode.dynamicLContainerNode.data[RENDER_PARENT] = null;
|
||||
}
|
||||
break;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {LElementNode, LViewNode} from './node';
|
||||
import {LElementNode} from './node';
|
||||
import {LQueries} from './query';
|
||||
import {LViewData, NEXT, PARENT, QUERIES} from './view';
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import {ElementRef} from '../../linker/element_ref';
|
||||
import {TemplateRef} from '../../linker/template_ref';
|
||||
import {ViewContainerRef} from '../../linker/view_container_ref';
|
||||
|
||||
import {LContainerNode, LElementContainerNode, LElementNode} from './node';
|
||||
import {LContainerNode, LElementContainerNode, LElementNode, TContainerNode, TElementNode, TNode} from './node';
|
||||
|
||||
export interface LInjector {
|
||||
/**
|
||||
@@ -28,6 +28,8 @@ export interface LInjector {
|
||||
*/
|
||||
readonly node: LElementNode|LElementContainerNode|LContainerNode;
|
||||
|
||||
readonly tNode: TNode;
|
||||
|
||||
/**
|
||||
* The following bloom filter determines whether a directive is available
|
||||
* on the associated node or not. This prevents us from searching the directives
|
||||
|
||||
@@ -81,7 +81,6 @@ export interface LNode {
|
||||
*/
|
||||
readonly data: LViewData|LContainer|null;
|
||||
|
||||
|
||||
/**
|
||||
* Each node belongs to a view.
|
||||
*
|
||||
@@ -92,12 +91,6 @@ export interface LNode {
|
||||
/** The injector associated with this node. Necessary for DI. */
|
||||
nodeInjector: LInjector|null;
|
||||
|
||||
/**
|
||||
* Pointer to the corresponding TNode object, which stores static
|
||||
* data about this node.
|
||||
*/
|
||||
tNode: TNode;
|
||||
|
||||
/**
|
||||
* A pointer to an LContainerNode created by directives requesting ViewContainerRef
|
||||
*/
|
||||
@@ -385,13 +378,13 @@ export interface TNode {
|
||||
export interface TElementNode extends TNode {
|
||||
/** Index in the data[] array */
|
||||
index: number;
|
||||
child: TElementNode|TTextNode|TContainerNode|TProjectionNode|null;
|
||||
child: TElementNode|TTextNode|TElementContainerNode|TContainerNode|TProjectionNode|null;
|
||||
/**
|
||||
* Element nodes will have parents unless they are the first node of a component or
|
||||
* embedded view (which means their parent is in a different view and must be
|
||||
* retrieved using LView.node).
|
||||
* retrieved using viewData[HOST_NODE]).
|
||||
*/
|
||||
parent: TElementNode|null;
|
||||
parent: TElementNode|TElementContainerNode|null;
|
||||
tViews: null;
|
||||
|
||||
/**
|
||||
@@ -412,7 +405,7 @@ export interface TTextNode extends TNode {
|
||||
* embedded view (which means their parent is in a different view and must be
|
||||
* retrieved using LView.node).
|
||||
*/
|
||||
parent: TElementNode|null;
|
||||
parent: TElementNode|TElementContainerNode|null;
|
||||
tViews: null;
|
||||
projection: null;
|
||||
}
|
||||
@@ -434,16 +427,27 @@ export interface TContainerNode extends TNode {
|
||||
* - They are the first node of a component or embedded view
|
||||
* - They are dynamically created
|
||||
*/
|
||||
parent: TElementNode|null;
|
||||
parent: TElementNode|TElementContainerNode|null;
|
||||
tViews: TView|TView[]|null;
|
||||
projection: null;
|
||||
}
|
||||
|
||||
|
||||
/** Static data for an LElementContainerNode */
|
||||
export interface TElementContainerNode extends TNode {
|
||||
/** Index in the LViewData[] array. */
|
||||
index: number;
|
||||
child: TElementNode|TTextNode|TContainerNode|TElementContainerNode|TProjectionNode|null;
|
||||
parent: TElementNode|TElementContainerNode|null;
|
||||
tViews: null;
|
||||
projection: null;
|
||||
}
|
||||
|
||||
/** Static data for an LViewNode */
|
||||
export interface TViewNode extends TNode {
|
||||
/** If -1, it's a dynamically created view. Otherwise, it is the view block ID. */
|
||||
index: number;
|
||||
child: TElementNode|TTextNode|TContainerNode|TProjectionNode|null;
|
||||
child: TElementNode|TTextNode|TElementContainerNode|TContainerNode|TProjectionNode|null;
|
||||
parent: TContainerNode|null;
|
||||
tViews: null;
|
||||
projection: null;
|
||||
@@ -458,7 +462,7 @@ export interface TProjectionNode extends TNode {
|
||||
* or embedded view (which means their parent is in a different view and must be
|
||||
* retrieved using LView.node).
|
||||
*/
|
||||
parent: TElementNode|null;
|
||||
parent: TElementNode|TElementContainerNode|null;
|
||||
tViews: null;
|
||||
|
||||
/** Index of the projection node. (See TNode.projection for more info.) */
|
||||
@@ -536,4 +540,4 @@ export type LNodeWithLocalRefs = LContainerNode | LElementNode | LElementContain
|
||||
* - `<div #nativeDivEl>` - `nativeDivEl` should point to the native `<div>` element;
|
||||
* - `<ng-template #tplRef>` - `tplRef` should point to the `TemplateRef` instance;
|
||||
*/
|
||||
export type LocalRefExtractor = (lNode: LNodeWithLocalRefs) => any;
|
||||
export type LocalRefExtractor = (lNode: LNodeWithLocalRefs, tNode: TNode) => any;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
import {QueryList} from '../../linker';
|
||||
import {Type} from '../../type';
|
||||
import {LNode} from './node';
|
||||
import {TNode} from './node';
|
||||
|
||||
/** Used for tracking queries (e.g. ViewChild, ContentChild). */
|
||||
export interface LQueries {
|
||||
@@ -30,10 +30,10 @@ export interface LQueries {
|
||||
clone(): LQueries;
|
||||
|
||||
/**
|
||||
* Notify `LQueries` that a new `LNode` has been created and needs to be added to query results
|
||||
* Notify `LQueries` that a new `TNode` has been created and needs to be added to query results
|
||||
* if matching query predicate.
|
||||
*/
|
||||
addNode(node: LNode): LQueries|null;
|
||||
addNode(tNode: TNode): LQueries|null;
|
||||
|
||||
/**
|
||||
* Notify `LQueries` that a new LContainer was added to ivy data structures. As a result we need
|
||||
|
||||
@@ -94,15 +94,16 @@ export interface LViewData extends Array<any> {
|
||||
[FLAGS]: LViewFlags;
|
||||
|
||||
/**
|
||||
* Pointer to the `LViewNode` or `LElementNode` which represents the root of the view.
|
||||
* Pointer to the `TViewNode` or `TElementNode` which represents the root of the view.
|
||||
*
|
||||
* If `LViewNode`, this is an embedded view of a container. We need this to be able to
|
||||
* If `TViewNode`, this is an embedded view of a container. We need this to be able to
|
||||
* efficiently find the `LViewNode` when inserting the view into an anchor.
|
||||
*
|
||||
* If `LElementNode`, this is the LView of a component.
|
||||
* If `TElementNode`, this is the LView of a component.
|
||||
*
|
||||
* If null, this is the root view of an application (root component is in this view).
|
||||
*/
|
||||
// TODO(kara): Replace with index
|
||||
[HOST_NODE]: LViewNode|LElementNode;
|
||||
[HOST_NODE]: TViewNode|TElementNode|null;
|
||||
|
||||
/**
|
||||
* The binding index we should access next.
|
||||
@@ -213,16 +214,16 @@ export const enum LViewFlags {
|
||||
* back into the parent view, `data` will be defined and `creationMode` will be
|
||||
* improperly reported as false.
|
||||
*/
|
||||
CreationMode = 0b000001,
|
||||
CreationMode = 0b0000001,
|
||||
|
||||
/** Whether this view has default change detection strategy (checks always) or onPush */
|
||||
CheckAlways = 0b000010,
|
||||
CheckAlways = 0b0000010,
|
||||
|
||||
/** Whether or not this view is currently dirty (needing check) */
|
||||
Dirty = 0b000100,
|
||||
Dirty = 0b0000100,
|
||||
|
||||
/** Whether or not this view is currently attached to change detection tree. */
|
||||
Attached = 0b001000,
|
||||
Attached = 0b0001000,
|
||||
|
||||
/**
|
||||
* Whether or not the init hooks have run.
|
||||
@@ -231,10 +232,13 @@ export const enum LViewFlags {
|
||||
* runs OR the first cR() instruction that runs (so inits are run for the top level view before
|
||||
* any embedded views).
|
||||
*/
|
||||
RunInit = 0b010000,
|
||||
RunInit = 0b0010000,
|
||||
|
||||
/** Whether or not this view is destroyed. */
|
||||
Destroyed = 0b100000,
|
||||
Destroyed = 0b0100000,
|
||||
|
||||
/** Whether or not this view is the root view */
|
||||
IsRoot = 0b1000000,
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -17,13 +17,13 @@ import {getSymbolIterator} from '../util';
|
||||
|
||||
import {assertDefined, assertEqual} from './assert';
|
||||
import {ReadFromInjectorFn, getOrCreateNodeInjectorForNode} from './di';
|
||||
import {assertPreviousIsParent, getOrCreateCurrentQueries, isContentQueryHost, store, storeCleanupWithContext} from './instructions';
|
||||
import {_getViewData, assertPreviousIsParent, getOrCreateCurrentQueries, store, storeCleanupWithContext} from './instructions';
|
||||
import {DirectiveDefInternal, unusedValueExportToPlacateAjd as unused1} from './interfaces/definition';
|
||||
import {LInjector, unusedValueExportToPlacateAjd as unused2} from './interfaces/injector';
|
||||
import {LContainerNode, LElementNode, LNode, TNode, TNodeFlags, unusedValueExportToPlacateAjd as unused3} from './interfaces/node';
|
||||
import {LContainerNode, LElementNode, TNode, TNodeFlags, unusedValueExportToPlacateAjd as unused3} from './interfaces/node';
|
||||
import {LQueries, QueryReadType, unusedValueExportToPlacateAjd as unused4} from './interfaces/query';
|
||||
import {DIRECTIVES, TVIEW} from './interfaces/view';
|
||||
import {flatten} from './util';
|
||||
import {DIRECTIVES, LViewData, TVIEW} from './interfaces/view';
|
||||
import {flatten, isContentQueryHost, readElementValue} from './util';
|
||||
|
||||
const unusedValueToPlacateAjd = unused1 + unused2 + unused3 + unused4;
|
||||
|
||||
@@ -121,21 +121,21 @@ export class LQueries_ implements LQueries {
|
||||
insertView(index, this.deep);
|
||||
}
|
||||
|
||||
addNode(node: LNode): LQueries|null {
|
||||
add(this.deep, node);
|
||||
addNode(tNode: TNode): LQueries|null {
|
||||
add(this.deep, tNode);
|
||||
|
||||
if (isContentQueryHost(node.tNode)) {
|
||||
add(this.shallow, node);
|
||||
if (isContentQueryHost(tNode)) {
|
||||
add(this.shallow, tNode);
|
||||
|
||||
if (node.tNode.parent && isContentQueryHost(node.tNode.parent)) {
|
||||
if (tNode.parent && isContentQueryHost(tNode.parent)) {
|
||||
// if node has a content query and parent also has a content query
|
||||
// both queries need to check this node for shallow matches
|
||||
add(this.parent !.shallow, node);
|
||||
add(this.parent !.shallow, tNode);
|
||||
}
|
||||
return this.parent;
|
||||
}
|
||||
|
||||
isRootNodeOfQuery(node.tNode) && add(this.shallow, node);
|
||||
isRootNodeOfQuery(tNode) && add(this.shallow, tNode);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -241,51 +241,61 @@ function getIdxOfMatchingSelector(tNode: TNode, selector: string): number|null {
|
||||
/**
|
||||
* Iterates over all the directives for a node and returns index of a directive for a given type.
|
||||
*
|
||||
* @param node Node on which directives are present.
|
||||
* @param tNode TNode on which directives are present.
|
||||
* @param currentView The view we are currently processing
|
||||
* @param type Type of a directive to look for.
|
||||
* @returns Index of a found directive or null when none found.
|
||||
*/
|
||||
function getIdxOfMatchingDirective(node: LNode, type: Type<any>): number|null {
|
||||
const defs = node.view[TVIEW].directives !;
|
||||
const flags = node.tNode.flags;
|
||||
const count = flags & TNodeFlags.DirectiveCountMask;
|
||||
const start = flags >> TNodeFlags.DirectiveStartingIndexShift;
|
||||
const end = start + count;
|
||||
for (let i = start; i < end; i++) {
|
||||
const def = defs[i] as DirectiveDefInternal<any>;
|
||||
if (def.type === type && def.diPublic) {
|
||||
return i;
|
||||
function getIdxOfMatchingDirective(tNode: TNode, currentView: LViewData, type: Type<any>): number|
|
||||
null {
|
||||
const defs = currentView[TVIEW].directives;
|
||||
if (defs) {
|
||||
const flags = tNode.flags;
|
||||
const count = flags & TNodeFlags.DirectiveCountMask;
|
||||
const start = flags >> TNodeFlags.DirectiveStartingIndexShift;
|
||||
const end = start + count;
|
||||
for (let i = start; i < end; i++) {
|
||||
const def = defs[i] as DirectiveDefInternal<any>;
|
||||
if (def.type === type && def.diPublic) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function readFromNodeInjector(
|
||||
nodeInjector: LInjector, node: LNode, read: QueryReadType<any>| Type<any>,
|
||||
directiveIdx: number): any {
|
||||
nodeInjector: LInjector, tNode: TNode, currentView: LViewData,
|
||||
read: QueryReadType<any>| Type<any>, directiveIdx: number): any {
|
||||
if (read instanceof ReadFromInjectorFn) {
|
||||
return read.read(nodeInjector, node, directiveIdx);
|
||||
return read.read(nodeInjector, tNode, directiveIdx);
|
||||
} else {
|
||||
const matchingIdx = getIdxOfMatchingDirective(node, read as Type<any>);
|
||||
const matchingIdx = getIdxOfMatchingDirective(tNode, currentView, read as Type<any>);
|
||||
if (matchingIdx !== null) {
|
||||
return node.view[DIRECTIVES] ![matchingIdx];
|
||||
return currentView[DIRECTIVES] ![matchingIdx];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function add(query: LQuery<any>| null, node: LNode) {
|
||||
const nodeInjector = getOrCreateNodeInjectorForNode(node as LElementNode | LContainerNode);
|
||||
function add(query: LQuery<any>| null, tNode: TNode) {
|
||||
const currentView = _getViewData();
|
||||
|
||||
// TODO: remove this lookup when nodeInjector is removed from LNode
|
||||
const currentNode = readElementValue(currentView[tNode.index]);
|
||||
const nodeInjector =
|
||||
getOrCreateNodeInjectorForNode(currentNode as LElementNode | LContainerNode, tNode);
|
||||
|
||||
while (query) {
|
||||
const predicate = query.predicate;
|
||||
const type = predicate.type;
|
||||
if (type) {
|
||||
const directiveIdx = getIdxOfMatchingDirective(node, type);
|
||||
const directiveIdx = getIdxOfMatchingDirective(tNode, currentView, type);
|
||||
if (directiveIdx !== null) {
|
||||
// a node is matching a predicate - determine what to read
|
||||
// if read token and / or strategy is not specified, use type as read token
|
||||
const result =
|
||||
readFromNodeInjector(nodeInjector, node, predicate.read || type, directiveIdx);
|
||||
const result = readFromNodeInjector(
|
||||
nodeInjector, tNode, currentView, predicate.read || type, directiveIdx);
|
||||
if (result !== null) {
|
||||
addMatch(query, result);
|
||||
}
|
||||
@@ -293,12 +303,13 @@ function add(query: LQuery<any>| null, node: LNode) {
|
||||
} else {
|
||||
const selector = predicate.selector !;
|
||||
for (let i = 0; i < selector.length; i++) {
|
||||
const directiveIdx = getIdxOfMatchingSelector(node.tNode, selector[i]);
|
||||
const directiveIdx = getIdxOfMatchingSelector(tNode, selector[i]);
|
||||
if (directiveIdx !== null) {
|
||||
// a node is matching a predicate - determine what to read
|
||||
// note that queries using name selector must specify read strategy
|
||||
ngDevMode && assertDefined(predicate.read, 'the node should have a predicate');
|
||||
const result = readFromNodeInjector(nodeInjector, node, predicate.read !, directiveIdx);
|
||||
const result = readFromNodeInjector(
|
||||
nodeInjector, tNode, currentView, predicate.read !, directiveIdx);
|
||||
if (result !== null) {
|
||||
addMatch(query, result);
|
||||
}
|
||||
|
||||
@@ -5,13 +5,14 @@
|
||||
* 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 {devModeEqual} from '../change_detection/change_detection_util';
|
||||
import {assertLessThan} from './assert';
|
||||
import {LElementNode} from './interfaces/node';
|
||||
import {LElementNode, TNode, TNodeFlags} from './interfaces/node';
|
||||
import {HEADER_OFFSET, LViewData, TData} from './interfaces/view';
|
||||
|
||||
/**
|
||||
* Returns wether the values are different from a change detection stand point.
|
||||
* Returns whether the values are different from a change detection stand point.
|
||||
*
|
||||
* Constraints are relaxed in checkNoChanges mode. See `devModeEqual` for details.
|
||||
*/
|
||||
@@ -89,3 +90,11 @@ export function loadElementInternal(index: number, arr: LViewData): LElementNode
|
||||
export function readElementValue(value: LElementNode | any[]): LElementNode {
|
||||
return (Array.isArray(value) ? (value as any as any[])[0] : value) as LElementNode;
|
||||
}
|
||||
|
||||
export function isContentQueryHost(tNode: TNode): boolean {
|
||||
return (tNode.flags & TNodeFlags.hasContentQuery) !== 0;
|
||||
}
|
||||
|
||||
export function isComponent(tNode: TNode): boolean {
|
||||
return (tNode.flags & TNodeFlags.isComponent) === TNodeFlags.isComponent;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import {ViewContainerRef as viewEngine_ViewContainerRef} from '../linker/view_co
|
||||
import {EmbeddedViewRef as viewEngine_EmbeddedViewRef, InternalViewRef as viewEngine_InternalViewRef} from '../linker/view_ref';
|
||||
|
||||
import {checkNoChanges, checkNoChangesInRootView, detectChanges, detectChangesInRootView, getRendererFactory, markViewDirty, storeCleanupFn, viewAttached} from './instructions';
|
||||
import {LViewNode} from './interfaces/node';
|
||||
import {TViewNode} from './interfaces/node';
|
||||
import {FLAGS, LViewData, LViewFlags} from './interfaces/view';
|
||||
import {destroyLView} from './node_manipulation';
|
||||
|
||||
@@ -30,13 +30,21 @@ export class ViewRef<T> implements viewEngine_EmbeddedViewRef<T>, viewEngine_Int
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_lViewNode: LViewNode|null = null;
|
||||
_view: LViewData;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_tViewNode: TViewNode|null = null;
|
||||
|
||||
context: T;
|
||||
// TODO(issue/24571): remove '!'.
|
||||
rootNodes !: any[];
|
||||
|
||||
constructor(protected _view: LViewData, context: T|null) { this.context = context !; }
|
||||
constructor(_view: LViewData, context: T|null) {
|
||||
this.context = context !;
|
||||
this._view = _view;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
_setComponentContext(view: LViewData, context: T) {
|
||||
@@ -256,7 +264,7 @@ export class ViewRef<T> implements viewEngine_EmbeddedViewRef<T>, viewEngine_Int
|
||||
|
||||
/** @internal */
|
||||
export class RootViewRef<T> extends ViewRef<T> {
|
||||
constructor(protected _view: LViewData) { super(_view, null); }
|
||||
constructor(public _view: LViewData) { super(_view, null); }
|
||||
|
||||
detectChanges(): void { detectChangesInRootView(this._view); }
|
||||
|
||||
|
||||
@@ -134,15 +134,18 @@
|
||||
{
|
||||
"name": "componentRefresh"
|
||||
},
|
||||
{
|
||||
"name": "createLNode"
|
||||
},
|
||||
{
|
||||
"name": "createLNodeObject"
|
||||
},
|
||||
{
|
||||
"name": "createLViewData"
|
||||
},
|
||||
{
|
||||
"name": "createNodeAtIndex"
|
||||
},
|
||||
{
|
||||
"name": "createRootComponent"
|
||||
},
|
||||
{
|
||||
"name": "createRootContext"
|
||||
},
|
||||
@@ -198,7 +201,7 @@
|
||||
"name": "firstTemplatePass"
|
||||
},
|
||||
{
|
||||
"name": "getChildLNode"
|
||||
"name": "getBeforeNodeForView"
|
||||
},
|
||||
{
|
||||
"name": "getClosureSafeProperty"
|
||||
@@ -206,9 +209,21 @@
|
||||
{
|
||||
"name": "getComponentDef"
|
||||
},
|
||||
{
|
||||
"name": "getContainerNode"
|
||||
},
|
||||
{
|
||||
"name": "getContainerRenderParent"
|
||||
},
|
||||
{
|
||||
"name": "getDirectiveDef"
|
||||
},
|
||||
{
|
||||
"name": "getHighestElementContainer"
|
||||
},
|
||||
{
|
||||
"name": "getHostElementNode"
|
||||
},
|
||||
{
|
||||
"name": "getLViewChild"
|
||||
},
|
||||
@@ -224,12 +239,18 @@
|
||||
{
|
||||
"name": "getParentLNode"
|
||||
},
|
||||
{
|
||||
"name": "getParentOrContainerNode"
|
||||
},
|
||||
{
|
||||
"name": "getPipeDef"
|
||||
},
|
||||
{
|
||||
"name": "getPreviousOrParentNode"
|
||||
},
|
||||
{
|
||||
"name": "getPreviousOrParentTNode"
|
||||
},
|
||||
{
|
||||
"name": "getRenderFlags"
|
||||
},
|
||||
|
||||
@@ -314,6 +314,9 @@
|
||||
{
|
||||
"name": "_devMode"
|
||||
},
|
||||
{
|
||||
"name": "_getViewData"
|
||||
},
|
||||
{
|
||||
"name": "_global"
|
||||
},
|
||||
@@ -405,7 +408,7 @@
|
||||
"name": "createDirectivesAndLocals"
|
||||
},
|
||||
{
|
||||
"name": "createEmbeddedViewNode"
|
||||
"name": "createEmbeddedViewAndNode"
|
||||
},
|
||||
{
|
||||
"name": "createLContainer"
|
||||
@@ -413,18 +416,21 @@
|
||||
{
|
||||
"name": "createLContext"
|
||||
},
|
||||
{
|
||||
"name": "createLNode"
|
||||
},
|
||||
{
|
||||
"name": "createLNodeObject"
|
||||
},
|
||||
{
|
||||
"name": "createLViewData"
|
||||
},
|
||||
{
|
||||
"name": "createNodeAtIndex"
|
||||
},
|
||||
{
|
||||
"name": "createOutput$1"
|
||||
},
|
||||
{
|
||||
"name": "createRootComponent"
|
||||
},
|
||||
{
|
||||
"name": "createRootContext"
|
||||
},
|
||||
@@ -540,7 +546,7 @@
|
||||
"name": "findAttrIndexInNode"
|
||||
},
|
||||
{
|
||||
"name": "findComponentHost"
|
||||
"name": "findComponentView"
|
||||
},
|
||||
{
|
||||
"name": "findDirectiveMatches"
|
||||
@@ -558,20 +564,23 @@
|
||||
"name": "generatePropertyAliases"
|
||||
},
|
||||
{
|
||||
"name": "getChildLNode"
|
||||
"name": "getBeforeNodeForView"
|
||||
},
|
||||
{
|
||||
"name": "getCleanup"
|
||||
},
|
||||
{
|
||||
"name": "getClosestComponentAncestor"
|
||||
},
|
||||
{
|
||||
"name": "getClosureSafeProperty"
|
||||
},
|
||||
{
|
||||
"name": "getComponentDef"
|
||||
},
|
||||
{
|
||||
"name": "getContainerNode"
|
||||
},
|
||||
{
|
||||
"name": "getContainerRenderParent"
|
||||
},
|
||||
{
|
||||
"name": "getCurrentSanitizer"
|
||||
},
|
||||
@@ -581,6 +590,12 @@
|
||||
{
|
||||
"name": "getDirectiveDef"
|
||||
},
|
||||
{
|
||||
"name": "getHighestElementContainer"
|
||||
},
|
||||
{
|
||||
"name": "getHostElementNode"
|
||||
},
|
||||
{
|
||||
"name": "getInitialIndex"
|
||||
},
|
||||
@@ -635,6 +650,9 @@
|
||||
{
|
||||
"name": "getParentLNode"
|
||||
},
|
||||
{
|
||||
"name": "getParentOrContainerNode"
|
||||
},
|
||||
{
|
||||
"name": "getParentState"
|
||||
},
|
||||
@@ -650,6 +668,9 @@
|
||||
{
|
||||
"name": "getPreviousOrParentNode"
|
||||
},
|
||||
{
|
||||
"name": "getPreviousOrParentTNode"
|
||||
},
|
||||
{
|
||||
"name": "getProp"
|
||||
},
|
||||
@@ -674,6 +695,9 @@
|
||||
{
|
||||
"name": "getSymbolIterator"
|
||||
},
|
||||
{
|
||||
"name": "getTNode"
|
||||
},
|
||||
{
|
||||
"name": "getTViewCleanup"
|
||||
},
|
||||
|
||||
@@ -1091,6 +1091,9 @@
|
||||
{
|
||||
"name": "_getComponentHostLElementNode"
|
||||
},
|
||||
{
|
||||
"name": "_getViewData"
|
||||
},
|
||||
{
|
||||
"name": "_global"
|
||||
},
|
||||
@@ -1278,7 +1281,7 @@
|
||||
"name": "createDirectivesAndLocals"
|
||||
},
|
||||
{
|
||||
"name": "createEmbeddedViewNode"
|
||||
"name": "createEmbeddedViewAndNode"
|
||||
},
|
||||
{
|
||||
"name": "createInjector"
|
||||
@@ -1289,15 +1292,15 @@
|
||||
{
|
||||
"name": "createLContext"
|
||||
},
|
||||
{
|
||||
"name": "createLNode"
|
||||
},
|
||||
{
|
||||
"name": "createLNodeObject"
|
||||
},
|
||||
{
|
||||
"name": "createLViewData"
|
||||
},
|
||||
{
|
||||
"name": "createNodeAtIndex"
|
||||
},
|
||||
{
|
||||
"name": "createOutput$1"
|
||||
},
|
||||
@@ -1307,6 +1310,9 @@
|
||||
{
|
||||
"name": "createPlatformFactory"
|
||||
},
|
||||
{
|
||||
"name": "createRootComponent"
|
||||
},
|
||||
{
|
||||
"name": "createRootContext"
|
||||
},
|
||||
@@ -1482,7 +1488,7 @@
|
||||
"name": "findAttrIndexInNode"
|
||||
},
|
||||
{
|
||||
"name": "findComponentHost"
|
||||
"name": "findComponentView"
|
||||
},
|
||||
{
|
||||
"name": "findDirectiveMatches"
|
||||
@@ -1557,20 +1563,23 @@
|
||||
"name": "getBaseElementHref"
|
||||
},
|
||||
{
|
||||
"name": "getChildLNode"
|
||||
"name": "getBeforeNodeForView"
|
||||
},
|
||||
{
|
||||
"name": "getCleanup"
|
||||
},
|
||||
{
|
||||
"name": "getClosestComponentAncestor"
|
||||
},
|
||||
{
|
||||
"name": "getClosureSafeProperty"
|
||||
},
|
||||
{
|
||||
"name": "getComponentDef"
|
||||
},
|
||||
{
|
||||
"name": "getContainerNode"
|
||||
},
|
||||
{
|
||||
"name": "getContainerRenderParent"
|
||||
},
|
||||
{
|
||||
"name": "getCurrencySymbol"
|
||||
},
|
||||
@@ -1607,6 +1616,12 @@
|
||||
{
|
||||
"name": "getFirstThursdayOfYear"
|
||||
},
|
||||
{
|
||||
"name": "getHighestElementContainer"
|
||||
},
|
||||
{
|
||||
"name": "getHostElementNode"
|
||||
},
|
||||
{
|
||||
"name": "getInitialIndex"
|
||||
},
|
||||
@@ -1727,6 +1742,9 @@
|
||||
{
|
||||
"name": "getParentLNode"
|
||||
},
|
||||
{
|
||||
"name": "getParentOrContainerNode"
|
||||
},
|
||||
{
|
||||
"name": "getParentState"
|
||||
},
|
||||
@@ -1781,6 +1799,9 @@
|
||||
{
|
||||
"name": "getSymbolIterator$1"
|
||||
},
|
||||
{
|
||||
"name": "getTNode"
|
||||
},
|
||||
{
|
||||
"name": "getTViewCleanup"
|
||||
},
|
||||
|
||||
@@ -12,7 +12,7 @@ import {RenderFlags} from '@angular/core/src/render3/interfaces/definition';
|
||||
import {defineComponent} from '../../src/render3/definition';
|
||||
import {bloomAdd, bloomFindPossibleInjector, getOrCreateNodeInjector, injectAttribute} from '../../src/render3/di';
|
||||
import {NgOnChangesFeature, PublicFeature, defineDirective, directiveInject, injectChangeDetectorRef, injectElementRef, injectRenderer2, injectTemplateRef, injectViewContainerRef} from '../../src/render3/index';
|
||||
import {bind, container, containerRefreshEnd, containerRefreshStart, createLNode, createLViewData, createTView, element, elementEnd, elementStart, embeddedViewEnd, embeddedViewStart, enterView, interpolation2, leaveView, projection, projectionDef, reference, template, text, textBinding, loadDirective, elementContainerStart, elementContainerEnd} from '../../src/render3/instructions';
|
||||
import {bind, container, containerRefreshEnd, containerRefreshStart, createNodeAtIndex, createLViewData, createTView, element, elementEnd, elementStart, embeddedViewEnd, embeddedViewStart, enterView, interpolation2, leaveView, projection, projectionDef, reference, template, text, textBinding, loadDirective, elementContainerStart, elementContainerEnd} from '../../src/render3/instructions';
|
||||
import {LInjector} from '../../src/render3/interfaces/injector';
|
||||
import {isProceduralRenderer} from '../../src/render3/interfaces/renderer';
|
||||
import {AttributeMarker, TNodeType} from '../../src/render3/interfaces/node';
|
||||
@@ -1503,12 +1503,11 @@ describe('di', () => {
|
||||
null !, createTView(-1, null, 1, 0, null, null, null), null, LViewFlags.CheckAlways);
|
||||
const oldView = enterView(contentView, null);
|
||||
try {
|
||||
const parent = createLNode(0, TNodeType.Element, null, null, null, null);
|
||||
|
||||
const parentTNode = createNodeAtIndex(0, TNodeType.Element, null, 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.
|
||||
(parent.tNode as{parent: any}).parent = undefined;
|
||||
(parentTNode as{parent: any}).parent = undefined;
|
||||
|
||||
const injector: any = getOrCreateNodeInjector(); // TODO: Review use of `any` here (#19904)
|
||||
expect(injector).not.toBe(null);
|
||||
|
||||
@@ -50,7 +50,7 @@ describe('instructions', () => {
|
||||
expect(ngDevMode).toHaveProperties({
|
||||
firstTemplatePass: 1,
|
||||
tNode: 2, // 1 for hostElement + 1 for the template under test
|
||||
tView: 1,
|
||||
tView: 2, // 1 for rootView + 1 for the template view
|
||||
rendererCreateElement: 1,
|
||||
rendererSetProperty: 2
|
||||
});
|
||||
@@ -68,7 +68,7 @@ describe('instructions', () => {
|
||||
expect(ngDevMode).toHaveProperties({
|
||||
firstTemplatePass: 1,
|
||||
tNode: 2, // 1 for hostElement + 1 for the template under test
|
||||
tView: 1,
|
||||
tView: 2, // 1 for rootView + 1 for the template view
|
||||
rendererCreateElement: 1,
|
||||
rendererSetProperty: 1
|
||||
});
|
||||
@@ -87,7 +87,7 @@ describe('instructions', () => {
|
||||
expect(ngDevMode).toHaveProperties({
|
||||
firstTemplatePass: 1,
|
||||
tNode: 2, // 1 for div, 1 for host element
|
||||
tView: 1,
|
||||
tView: 2, // 1 for rootView + 1 for the template view
|
||||
rendererCreateElement: 1,
|
||||
});
|
||||
});
|
||||
@@ -127,7 +127,7 @@ describe('instructions', () => {
|
||||
expect(ngDevMode).toHaveProperties({
|
||||
firstTemplatePass: 1,
|
||||
tNode: 2, // 1 for div, 1 for host element
|
||||
tView: 1,
|
||||
tView: 2, // 1 for rootView + 1 for the template view
|
||||
rendererCreateElement: 1,
|
||||
rendererSetAttribute: 3
|
||||
});
|
||||
@@ -148,7 +148,7 @@ describe('instructions', () => {
|
||||
expect(ngDevMode).toHaveProperties({
|
||||
firstTemplatePass: 1,
|
||||
tNode: 2, // 1 for div, 1 for host element
|
||||
tView: 1,
|
||||
tView: 2, // 1 for rootView + 1 for the template view
|
||||
rendererCreateElement: 1,
|
||||
rendererSetAttribute: 2
|
||||
});
|
||||
@@ -169,7 +169,7 @@ describe('instructions', () => {
|
||||
expect(ngDevMode).toHaveProperties({
|
||||
firstTemplatePass: 1,
|
||||
tNode: 2, // 1 for div, 1 for host element
|
||||
tView: 1,
|
||||
tView: 2, // 1 for rootView + 1 for the template view
|
||||
rendererCreateElement: 1,
|
||||
});
|
||||
});
|
||||
@@ -183,7 +183,7 @@ describe('instructions', () => {
|
||||
expect(ngDevMode).toHaveProperties({
|
||||
firstTemplatePass: 1,
|
||||
tNode: 2, // 1 for div, 1 for host element
|
||||
tView: 1,
|
||||
tView: 2, // 1 for rootView + 1 for the template view
|
||||
rendererCreateElement: 1,
|
||||
rendererSetProperty: 1
|
||||
});
|
||||
|
||||
@@ -42,7 +42,7 @@ describe('render3 integration test', () => {
|
||||
expect(ngDevMode).toHaveProperties({
|
||||
firstTemplatePass: 1,
|
||||
tNode: 3, // 1 for div, 1 for text, 1 for host element
|
||||
tView: 1,
|
||||
tView: 2, // 1 for root view, 1 for template
|
||||
rendererCreateElement: 1,
|
||||
});
|
||||
});
|
||||
@@ -86,7 +86,7 @@ describe('render3 integration test', () => {
|
||||
expect(ngDevMode).toHaveProperties({
|
||||
firstTemplatePass: 0,
|
||||
tNode: 2,
|
||||
tView: 1,
|
||||
tView: 2, // 1 for root view, 1 for template
|
||||
rendererSetText: 2,
|
||||
});
|
||||
});
|
||||
@@ -106,7 +106,7 @@ describe('render3 integration test', () => {
|
||||
expect(ngDevMode).toHaveProperties({
|
||||
firstTemplatePass: 0,
|
||||
tNode: 2,
|
||||
tView: 1,
|
||||
tView: 2, // 1 for root view, 1 for template
|
||||
rendererSetText: 2,
|
||||
});
|
||||
});
|
||||
@@ -125,7 +125,7 @@ describe('render3 integration test', () => {
|
||||
expect(ngDevMode).toHaveProperties({
|
||||
firstTemplatePass: 0,
|
||||
tNode: 2,
|
||||
tView: 1,
|
||||
tView: 2, // 1 for root view, 1 for template
|
||||
rendererSetText: 1,
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user