parent
68bf8c36c6
commit
609e6b9787
|
@ -17,7 +17,7 @@ import {CurrentMatchesList, LView, LViewFlags, LifecycleStage, RootContext, TDat
|
||||||
|
|
||||||
import {LContainerNode, LElementNode, LNode, TNodeType, TNodeFlags, LProjectionNode, LTextNode, LViewNode, TNode, TContainerNode, InitialInputData, InitialInputs, PropertyAliases, PropertyAliasValue,} from './interfaces/node';
|
import {LContainerNode, LElementNode, LNode, TNodeType, TNodeFlags, LProjectionNode, LTextNode, LViewNode, TNode, TContainerNode, InitialInputData, InitialInputs, PropertyAliases, PropertyAliasValue,} from './interfaces/node';
|
||||||
import {assertNodeType} from './node_assert';
|
import {assertNodeType} from './node_assert';
|
||||||
import {appendChild, insertView, appendProjectedNode, removeView, canInsertNativeNode, createTextNode, getNextLNode} from './node_manipulation';
|
import {appendChild, insertView, appendProjectedNode, removeView, canInsertNativeNode, createTextNode, getNextLNode, getChildLNode} from './node_manipulation';
|
||||||
import {isNodeMatchingSelectorList, matchingSelectorIndex} from './node_selector_matcher';
|
import {isNodeMatchingSelectorList, matchingSelectorIndex} from './node_selector_matcher';
|
||||||
import {ComponentDef, ComponentTemplate, DirectiveDef, DirectiveDefList, DirectiveDefListOrFactory, PipeDefList, PipeDefListOrFactory, RenderFlags} from './interfaces/definition';
|
import {ComponentDef, ComponentTemplate, DirectiveDef, DirectiveDefList, DirectiveDefListOrFactory, PipeDefList, PipeDefListOrFactory, RenderFlags} from './interfaces/definition';
|
||||||
import {RElement, RText, Renderer3, RendererFactory3, ProceduralRenderer3, RendererStyleFlags3, isProceduralRenderer} from './interfaces/renderer';
|
import {RElement, RText, Renderer3, RendererFactory3, ProceduralRenderer3, RendererStyleFlags3, isProceduralRenderer} from './interfaces/renderer';
|
||||||
|
@ -344,7 +344,6 @@ export function createLNodeObject(
|
||||||
native: native as any,
|
native: native as any,
|
||||||
view: currentView,
|
view: currentView,
|
||||||
parent: parent as any,
|
parent: parent as any,
|
||||||
child: null,
|
|
||||||
nodeInjector: parent ? parent.nodeInjector : null,
|
nodeInjector: parent ? parent.nodeInjector : null,
|
||||||
data: state,
|
data: state,
|
||||||
queries: queries,
|
queries: queries,
|
||||||
|
@ -414,15 +413,10 @@ export function createLNode(
|
||||||
// Now link ourselves into the tree.
|
// Now link ourselves into the tree.
|
||||||
if (isParent) {
|
if (isParent) {
|
||||||
currentQueries = null;
|
currentQueries = null;
|
||||||
if (previousOrParentNode.view === currentView ||
|
if (previousOrParentNode.tNode.child == null && previousOrParentNode.view === currentView ||
|
||||||
previousOrParentNode.tNode.type === TNodeType.View) {
|
previousOrParentNode.tNode.type === TNodeType.View) {
|
||||||
// We are in the same view, which means we are adding content node to the parent View.
|
// We are in the same view, which means we are adding content node to the parent View.
|
||||||
ngDevMode && assertNull(
|
previousOrParentNode.tNode.child = node.tNode;
|
||||||
previousOrParentNode.child,
|
|
||||||
`previousOrParentNode's child should not have been set.`);
|
|
||||||
previousOrParentNode.child = node;
|
|
||||||
} else {
|
|
||||||
// We are adding component view, so we don't link parent node child to this node.
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1063,6 +1057,7 @@ export function createTNode(
|
||||||
outputs: undefined,
|
outputs: undefined,
|
||||||
tViews: tViews,
|
tViews: tViews,
|
||||||
next: null,
|
next: null,
|
||||||
|
child: null,
|
||||||
dynamicContainerNode: null
|
dynamicContainerNode: null
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1699,7 +1694,7 @@ export function embeddedViewEnd(): void {
|
||||||
function setRenderParentInProjectedNodes(
|
function setRenderParentInProjectedNodes(
|
||||||
renderParent: LElementNode | null, viewNode: LViewNode): void {
|
renderParent: LElementNode | null, viewNode: LViewNode): void {
|
||||||
if (renderParent != null) {
|
if (renderParent != null) {
|
||||||
let node: LNode|null = viewNode.child;
|
let node: LNode|null = getChildLNode(viewNode);
|
||||||
while (node) {
|
while (node) {
|
||||||
if (node.tNode.type === TNodeType.Projection) {
|
if (node.tNode.type === TNodeType.Projection) {
|
||||||
let nodeToProject: LNode|null = (node as LProjectionNode).data.head;
|
let nodeToProject: LNode|null = (node as LProjectionNode).data.head;
|
||||||
|
@ -1776,7 +1771,7 @@ export function projectionDef(
|
||||||
}
|
}
|
||||||
|
|
||||||
const componentNode: LElementNode = findComponentHost(currentView);
|
const componentNode: LElementNode = findComponentHost(currentView);
|
||||||
let componentChild: LNode|null = componentNode.child;
|
let componentChild: LNode|null = getChildLNode(componentNode);
|
||||||
|
|
||||||
while (componentChild !== null) {
|
while (componentChild !== null) {
|
||||||
// execute selector matching logic if and only if:
|
// execute selector matching logic if and only if:
|
||||||
|
|
|
@ -71,11 +71,6 @@ export interface LNode {
|
||||||
*/
|
*/
|
||||||
readonly parent: LNode|null;
|
readonly parent: LNode|null;
|
||||||
|
|
||||||
/**
|
|
||||||
* First child of the current node.
|
|
||||||
*/
|
|
||||||
child: LNode|null;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If regular LElementNode, then `data` will be null.
|
* If regular LElementNode, then `data` will be null.
|
||||||
* If LElementNode with component, then `data` contains LView.
|
* If LElementNode with component, then `data` contains LView.
|
||||||
|
@ -130,8 +125,6 @@ export interface LElementNode extends LNode {
|
||||||
/** The DOM element associated with this node. */
|
/** The DOM element associated with this node. */
|
||||||
readonly native: RElement;
|
readonly native: RElement;
|
||||||
|
|
||||||
child: LContainerNode|LElementNode|LTextNode|LProjectionNode|null;
|
|
||||||
|
|
||||||
/** If Component then data has LView (light DOM) */
|
/** If Component then data has LView (light DOM) */
|
||||||
readonly data: LView|null;
|
readonly data: LView|null;
|
||||||
|
|
||||||
|
@ -143,7 +136,6 @@ export interface LElementNode extends LNode {
|
||||||
export interface LTextNode extends LNode {
|
export interface LTextNode extends LNode {
|
||||||
/** The text node associated with this node. */
|
/** The text node associated with this node. */
|
||||||
native: RText;
|
native: RText;
|
||||||
child: null;
|
|
||||||
|
|
||||||
/** LTextNodes can be inside LElementNodes or inside LViewNodes. */
|
/** LTextNodes can be inside LElementNodes or inside LViewNodes. */
|
||||||
readonly parent: LElementNode|LViewNode;
|
readonly parent: LElementNode|LViewNode;
|
||||||
|
@ -154,7 +146,6 @@ export interface LTextNode extends LNode {
|
||||||
/** Abstract node which contains root nodes of a view. */
|
/** Abstract node which contains root nodes of a view. */
|
||||||
export interface LViewNode extends LNode {
|
export interface LViewNode extends LNode {
|
||||||
readonly native: null;
|
readonly native: null;
|
||||||
child: LContainerNode|LElementNode|LTextNode|LProjectionNode|null;
|
|
||||||
|
|
||||||
/** LViewNodes can only be added to LContainerNodes. */
|
/** LViewNodes can only be added to LContainerNodes. */
|
||||||
readonly parent: LContainerNode|null;
|
readonly parent: LContainerNode|null;
|
||||||
|
@ -173,7 +164,6 @@ export interface LContainerNode extends LNode {
|
||||||
*/
|
*/
|
||||||
native: RElement|RText|null|undefined;
|
native: RElement|RText|null|undefined;
|
||||||
readonly data: LContainer;
|
readonly data: LContainer;
|
||||||
child: null;
|
|
||||||
|
|
||||||
/** Containers can be added to elements or views. */
|
/** Containers can be added to elements or views. */
|
||||||
readonly parent: LElementNode|LViewNode|null;
|
readonly parent: LElementNode|LViewNode|null;
|
||||||
|
@ -182,7 +172,6 @@ export interface LContainerNode extends LNode {
|
||||||
|
|
||||||
export interface LProjectionNode extends LNode {
|
export interface LProjectionNode extends LNode {
|
||||||
readonly native: null;
|
readonly native: null;
|
||||||
child: null;
|
|
||||||
|
|
||||||
readonly data: LProjection;
|
readonly data: LProjection;
|
||||||
|
|
||||||
|
@ -310,6 +299,14 @@ export interface TNode {
|
||||||
*/
|
*/
|
||||||
next: TNode|null;
|
next: TNode|null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* First child of the current node.
|
||||||
|
*
|
||||||
|
* For component nodes, the child will always be a ContentChild (in same view).
|
||||||
|
* For embedded view nodes, the child will be in their child view.
|
||||||
|
*/
|
||||||
|
child: TNode|null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A pointer to a TContainerNode created by directives requesting ViewContainerRef
|
* A pointer to a TContainerNode created by directives requesting ViewContainerRef
|
||||||
*/
|
*/
|
||||||
|
@ -317,10 +314,34 @@ export interface TNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Static data for an LElementNode */
|
/** Static data for an LElementNode */
|
||||||
export interface TElementNode extends TNode { tViews: null; }
|
export interface TElementNode extends TNode {
|
||||||
|
child: TContainerNode|TElementNode|TProjectionNode|null;
|
||||||
|
tViews: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Static data for an LTextNode */
|
||||||
|
export interface TTextNode extends TNode {
|
||||||
|
child: null;
|
||||||
|
tViews: null;
|
||||||
|
}
|
||||||
|
|
||||||
/** Static data for an LContainerNode */
|
/** Static data for an LContainerNode */
|
||||||
export interface TContainerNode extends TNode { tViews: TView|TView[]|null; }
|
export interface TContainerNode extends TNode {
|
||||||
|
child: null;
|
||||||
|
tViews: TView|TView[]|null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Static data for an LViewNode */
|
||||||
|
export interface TViewNode extends TNode {
|
||||||
|
child: TContainerNode|TElementNode|TProjectionNode|null;
|
||||||
|
tViews: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Static data for an LProjectionNode */
|
||||||
|
export interface TProjectionNode extends TNode {
|
||||||
|
child: null;
|
||||||
|
tViews: null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This mapping is necessary so we can set input properties and output listeners
|
* This mapping is necessary so we can set input properties and output listeners
|
||||||
|
|
|
@ -75,6 +75,15 @@ export function getNextLNode(node: LNode): LNode|null {
|
||||||
return node.tNode.next ? node.view.data[node.tNode.next !.index as number] : null;
|
return node.tNode.next ? node.view.data[node.tNode.next !.index as number] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Retrieves the first child of a given node */
|
||||||
|
export function getChildLNode(node: LNode): LNode|null {
|
||||||
|
if (node.tNode.child) {
|
||||||
|
const view = node.tNode.type === TNodeType.View ? node.data as LView : node.view;
|
||||||
|
return view.data[node.tNode.child.index as number];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the next node in the LNode tree, taking into account the place where a node is
|
* Get the next node in the LNode 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).
|
* projected (in the shadow DOM) rather than where it comes from (in the light DOM).
|
||||||
|
@ -140,13 +149,14 @@ function findFirstRNode(rootNode: LNode): RElement|RText|null {
|
||||||
const childContainerData: LContainer = lContainerNode.dynamicLContainerNode ?
|
const childContainerData: LContainer = lContainerNode.dynamicLContainerNode ?
|
||||||
lContainerNode.dynamicLContainerNode.data :
|
lContainerNode.dynamicLContainerNode.data :
|
||||||
lContainerNode.data;
|
lContainerNode.data;
|
||||||
nextNode = childContainerData.views.length ? childContainerData.views[0].child : null;
|
nextNode =
|
||||||
|
childContainerData.views.length ? getChildLNode(childContainerData.views[0]) : null;
|
||||||
} else if (node.tNode.type === TNodeType.Projection) {
|
} else if (node.tNode.type === TNodeType.Projection) {
|
||||||
// For Projection look at the first projected node
|
// For Projection look at the first projected node
|
||||||
nextNode = (node as LProjectionNode).data.head;
|
nextNode = (node as LProjectionNode).data.head;
|
||||||
} else {
|
} else {
|
||||||
// Otherwise look at the first child
|
// Otherwise look at the first child
|
||||||
nextNode = (node as LViewNode).child;
|
nextNode = getChildLNode(node as LViewNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
node = nextNode === null ? getNextOrParentSiblingNode(node, rootNode) : nextNode;
|
node = nextNode === null ? getNextOrParentSiblingNode(node, rootNode) : nextNode;
|
||||||
|
@ -183,7 +193,7 @@ export function addRemoveViewFromContainer(
|
||||||
ngDevMode && assertNodeType(rootNode, TNodeType.View);
|
ngDevMode && assertNodeType(rootNode, TNodeType.View);
|
||||||
const parentNode = container.data.renderParent;
|
const parentNode = container.data.renderParent;
|
||||||
const parent = parentNode ? parentNode.native : null;
|
const parent = parentNode ? parentNode.native : null;
|
||||||
let node: LNode|null = rootNode.child;
|
let node: LNode|null = getChildLNode(rootNode);
|
||||||
if (parent) {
|
if (parent) {
|
||||||
while (node) {
|
while (node) {
|
||||||
let nextNode: LNode|null = null;
|
let nextNode: LNode|null = null;
|
||||||
|
@ -203,11 +213,12 @@ export function addRemoveViewFromContainer(
|
||||||
// propagating down into child views / containers and not child elements
|
// propagating down into child views / containers and not child elements
|
||||||
const childContainerData: LContainer = (node as LContainerNode).data;
|
const childContainerData: LContainer = (node as LContainerNode).data;
|
||||||
childContainerData.renderParent = parentNode;
|
childContainerData.renderParent = parentNode;
|
||||||
nextNode = childContainerData.views.length ? childContainerData.views[0].child : null;
|
nextNode =
|
||||||
|
childContainerData.views.length ? getChildLNode(childContainerData.views[0]) : null;
|
||||||
} else if (node.tNode.type === TNodeType.Projection) {
|
} else if (node.tNode.type === TNodeType.Projection) {
|
||||||
nextNode = (node as LProjectionNode).data.head;
|
nextNode = (node as LProjectionNode).data.head;
|
||||||
} else {
|
} else {
|
||||||
nextNode = (node as LViewNode).child;
|
nextNode = getChildLNode(node as LViewNode);
|
||||||
}
|
}
|
||||||
if (nextNode === null) {
|
if (nextNode === null) {
|
||||||
node = getNextOrParentSiblingNode(node, rootNode);
|
node = getNextOrParentSiblingNode(node, rootNode);
|
||||||
|
|
|
@ -383,6 +383,9 @@
|
||||||
{
|
{
|
||||||
"name": "generatePropertyAliases"
|
"name": "generatePropertyAliases"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "getChildLNode"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "getCurrentSanitizer"
|
"name": "getCurrentSanitizer"
|
||||||
},
|
},
|
||||||
|
|
|
@ -22,6 +22,7 @@ function testLStaticData(tagName: string, attrs: string[] | null): TNode {
|
||||||
outputs: undefined,
|
outputs: undefined,
|
||||||
tViews: null,
|
tViews: null,
|
||||||
next: null,
|
next: null,
|
||||||
|
child: null,
|
||||||
dynamicContainerNode: null
|
dynamicContainerNode: null
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue