fix(ivy): correct position for re-projected containers (#24721)
PR Close #24721
This commit is contained in:

committed by
Miško Hevery

parent
3553977bd7
commit
a294e0dd79
@ -9,7 +9,7 @@
|
||||
import {assertEqual, assertLessThan} from './assert';
|
||||
import {NO_CHANGE, bindingUpdated, createLNode, getPreviousOrParentNode, getRenderer, getViewData, load, resetApplicationState} from './instructions';
|
||||
import {RENDER_PARENT} from './interfaces/container';
|
||||
import {LContainerNode, LElementNode, LNode, TNodeType} from './interfaces/node';
|
||||
import {LContainerNode, LElementNode, LNode, TContainerNode, TNodeType} from './interfaces/node';
|
||||
import {BINDING_INDEX, HEADER_OFFSET, TVIEW} from './interfaces/view';
|
||||
import {appendChild, createTextNode, getParentLNode, removeChild} from './node_manipulation';
|
||||
import {stringify} from './util';
|
||||
@ -241,7 +241,8 @@ function appendI18nNode(node: LNode, parentNode: LNode, previousNode: LNode) {
|
||||
appendChild(parentNode, node.native || null, viewData);
|
||||
|
||||
// On first pass, re-organize node tree to put this node in the correct position.
|
||||
if (node.view[TVIEW].firstTemplatePass) {
|
||||
const firstTemplatePass = node.view[TVIEW].firstTemplatePass;
|
||||
if (firstTemplatePass) {
|
||||
node.tNode.next = null;
|
||||
if (previousNode === parentNode && node.tNode !== parentNode.tNode.child) {
|
||||
node.tNode.next = parentNode.tNode.child;
|
||||
@ -257,7 +258,10 @@ function appendI18nNode(node: LNode, parentNode: LNode, previousNode: LNode) {
|
||||
// (node.native as RComment).textContent = 'test';
|
||||
// console.log(node.native);
|
||||
appendChild(parentNode, node.dynamicLContainerNode.native || null, viewData);
|
||||
node.pNextOrParent = node.dynamicLContainerNode;
|
||||
if (firstTemplatePass) {
|
||||
node.tNode.dynamicContainerNode = node.dynamicLContainerNode.tNode;
|
||||
node.dynamicLContainerNode.tNode.parent = node.tNode as TContainerNode;
|
||||
}
|
||||
return node.dynamicLContainerNode;
|
||||
}
|
||||
|
||||
|
@ -1920,7 +1920,7 @@ export function projectionDef(
|
||||
* @param appendedFirst First node of the linked list to append.
|
||||
* @param appendedLast Last node of the linked list to append.
|
||||
*/
|
||||
function appendToProjectionNode(
|
||||
function addToProjectionList(
|
||||
projectionNode: LProjectionNode,
|
||||
appendedFirst: LElementNode | LTextNode | LContainerNode | null,
|
||||
appendedLast: LElementNode | LTextNode | LContainerNode | null) {
|
||||
@ -1965,36 +1965,33 @@ export function projection(
|
||||
const distributedNodes = loadInternal(localIndex, componentLView) as Array<LNode[]>;
|
||||
const nodesForSelector = distributedNodes[selectorIndex];
|
||||
|
||||
// build the linked list of projected nodes:
|
||||
const currentParent = getParentLNode(node);
|
||||
const canInsert = canInsertNativeNode(currentParent, viewData);
|
||||
const renderParent = currentParent.tNode.type === TNodeType.View ?
|
||||
(getParentLNode(currentParent) as LContainerNode).data[RENDER_PARENT] ! :
|
||||
currentParent as LElementNode;
|
||||
|
||||
for (let i = 0; i < nodesForSelector.length; i++) {
|
||||
const nodeToProject = nodesForSelector[i];
|
||||
let head = nodeToProject as LTextNode | LElementNode | LContainerNode | null;
|
||||
let tail = nodeToProject as LTextNode | LElementNode | LContainerNode | null;
|
||||
|
||||
if (nodeToProject.tNode.type === TNodeType.Projection) {
|
||||
// Reprojecting a projection -> append the list of previously projected nodes
|
||||
const previouslyProjected = (nodeToProject as LProjectionNode).data;
|
||||
appendToProjectionNode(node, previouslyProjected.head, previouslyProjected.tail);
|
||||
} else {
|
||||
// Projecting a single node
|
||||
appendToProjectionNode(
|
||||
node, nodeToProject as LTextNode | LElementNode | LContainerNode,
|
||||
nodeToProject as LTextNode | LElementNode | LContainerNode);
|
||||
head = previouslyProjected.head;
|
||||
tail = previouslyProjected.tail;
|
||||
}
|
||||
}
|
||||
|
||||
const currentParent = getParentLNode(node);
|
||||
if (canInsertNativeNode(currentParent, viewData)) {
|
||||
ngDevMode && assertNodeOfPossibleTypes(currentParent, TNodeType.Element, TNodeType.View);
|
||||
// process each node in the list of projected nodes:
|
||||
let nodeToProject: LNode|null = node.data.head;
|
||||
const lastNodeToProject = node.data.tail;
|
||||
const renderParent = currentParent.tNode.type === TNodeType.View ?
|
||||
(getParentLNode(currentParent) as LContainerNode).data[RENDER_PARENT] ! :
|
||||
currentParent as LElementNode;
|
||||
addToProjectionList(node, head, tail);
|
||||
|
||||
while (nodeToProject) {
|
||||
appendProjectedNode(
|
||||
nodeToProject as LTextNode | LElementNode | LContainerNode, currentParent, viewData,
|
||||
renderParent);
|
||||
nodeToProject = nodeToProject === lastNodeToProject ? null : nodeToProject.pNextOrParent;
|
||||
if (canInsert) {
|
||||
let currentNode: LNode|null = head;
|
||||
while (currentNode) {
|
||||
appendProjectedNode(
|
||||
currentNode as LTextNode | LElementNode | LContainerNode, currentParent, viewData,
|
||||
renderParent);
|
||||
currentNode = currentNode === tail ? null : currentNode.pNextOrParent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -618,7 +618,7 @@ export function appendProjectedNode(
|
||||
lContainer[RENDER_PARENT] = renderParent;
|
||||
const views = lContainer[VIEWS];
|
||||
for (let i = 0; i < views.length; i++) {
|
||||
addRemoveViewFromContainer(node as LContainerNode, views[i], true, null);
|
||||
addRemoveViewFromContainer(node as LContainerNode, views[i], true, node.native);
|
||||
}
|
||||
}
|
||||
if (node.dynamicLContainerNode) {
|
||||
|
Reference in New Issue
Block a user