parent
							
								
									5a624fa1be
								
							
						
					
					
						commit
						5df626bbe1
					
				| @ -9,8 +9,7 @@ | |||||||
| import {LContainerNode, LElementNode, LTextNode} from './node'; | import {LContainerNode, LElementNode, LTextNode} from './node'; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * An LProjection is a pointer to the first and the last projected nodes. |  * Linked list of projected nodes (using the pNextOrParent property). | ||||||
|  * It is a linked list (using the pNextOrParent property). |  | ||||||
|  */ |  */ | ||||||
| export interface LProjection { | export interface LProjection { | ||||||
|   head: LElementNode|LTextNode|LContainerNode|null; |   head: LElementNode|LTextNode|LContainerNode|null; | ||||||
|  | |||||||
| @ -18,7 +18,7 @@ import {Renderer3} from './renderer'; | |||||||
|  * they are invoked from the template. Each embedded view and component view has its |  * they are invoked from the template. Each embedded view and component view has its | ||||||
|  * own `LView`. When processing a particular view, we set the `currentView` to that |  * own `LView`. When processing a particular view, we set the `currentView` to that | ||||||
|  * `LView`. When that view is done processing, the `currentView` is set back to |  * `LView`. When that view is done processing, the `currentView` is set back to | ||||||
|  * whatever the original `currentView` was before(the parent `LView`). |  * whatever the original `currentView` was before (the parent `LView`). | ||||||
|  * |  * | ||||||
|  * Keeping separate state for each view facilities view insertion / deletion, so we |  * Keeping separate state for each view facilities view insertion / deletion, so we | ||||||
|  * don't have to edit the data array based on which views are present. |  * don't have to edit the data array based on which views are present. | ||||||
|  | |||||||
| @ -18,25 +18,25 @@ import {assertNodeType} from './node_assert'; | |||||||
| const unusedValueToPlacateAjd = unused1 + unused2 + unused3 + unused4 + unused5; | const unusedValueToPlacateAjd = unused1 + unused2 + unused3 + unused4 + unused5; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Returns the first DOM node following the given logical node in the same parent DOM element. |  * Returns the first RNode following the given LNode in the same parent DOM element. | ||||||
|  * |  * | ||||||
|  * This is needed in order to insert the given node with insertBefore. |  * This is needed in order to insert the given node with insertBefore. | ||||||
|  * |  * | ||||||
|  * @param node The node whose following DOM node must be found. |  * @param node The node whose following DOM node must be found. | ||||||
|  * @param stopNode A parent node at which the lookup in the tree should be stopped, or null if the |  * @param stopNode A parent node at which the lookup in the tree should be stopped, or null if the | ||||||
|  * lookup should not be stopped until the result is found. |  * lookup should not be stopped until the result is found. | ||||||
|  * @returns Node before which the provided node should be inserted or null if the lookup was stopped |  * @returns RNode before which the provided node should be inserted or null if the lookup was | ||||||
|  |  * stopped | ||||||
|  * or if there is no native node after the given logical node in the same native parent. |  * or if there is no native node after the given logical node in the same native parent. | ||||||
|  */ |  */ | ||||||
| function findBeforeNode(node: LNode | null, stopNode: LNode | null): RElement|RText|null { | function findNextRNodeSibling(node: LNode | null, stopNode: LNode | null): RElement|RText|null { | ||||||
|   let currentNode = node; |   let currentNode = node; | ||||||
|   while (currentNode && currentNode !== stopNode) { |   while (currentNode && currentNode !== stopNode) { | ||||||
|     const currentNodeType = currentNode.flags && LNodeFlags.TYPE_MASK; |  | ||||||
|     let pNextOrParent = currentNode.pNextOrParent; |     let pNextOrParent = currentNode.pNextOrParent; | ||||||
|     if (pNextOrParent) { |     if (pNextOrParent) { | ||||||
|       let pNextOrParentType = pNextOrParent.flags & LNodeFlags.TYPE_MASK; |       let pNextOrParentType = pNextOrParent.flags & LNodeFlags.TYPE_MASK; | ||||||
|       while (pNextOrParentType !== LNodeFlags.Projection) { |       while (pNextOrParentType !== LNodeFlags.Projection) { | ||||||
|         const nativeNode = findFirstNativeNode(pNextOrParent); |         const nativeNode = findFirstRNode(pNextOrParent); | ||||||
|         if (nativeNode) { |         if (nativeNode) { | ||||||
|           return nativeNode; |           return nativeNode; | ||||||
|         } |         } | ||||||
| @ -46,7 +46,7 @@ function findBeforeNode(node: LNode | null, stopNode: LNode | null): RElement|RT | |||||||
|     } else { |     } else { | ||||||
|       let currentSibling = currentNode.next; |       let currentSibling = currentNode.next; | ||||||
|       while (currentSibling) { |       while (currentSibling) { | ||||||
|         const nativeNode = findFirstNativeNode(currentSibling); |         const nativeNode = findFirstRNode(currentSibling); | ||||||
|         if (nativeNode) { |         if (nativeNode) { | ||||||
|           return nativeNode; |           return nativeNode; | ||||||
|         } |         } | ||||||
| @ -68,72 +68,78 @@ function findBeforeNode(node: LNode | null, stopNode: LNode | null): RElement|RT | |||||||
| /** | /** | ||||||
|  * 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). | ||||||
|  * If the node is not projected, the return value is simply node.next. |  * | ||||||
|  * If the node is projected, the return value is node.pNextOrParent if node.pNextOrParent is |  | ||||||
|  * not a projection node (which marks the end of the linked list). |  | ||||||
|  * Otherwise the return value is null. |  | ||||||
|  * @param node The node whose next node in the LNode tree must be found. |  * @param node The node whose next node in the LNode tree must be found. | ||||||
|  * @return The next sibling in the LNode tree. |  * @return LNode|null The next sibling in the LNode tree. | ||||||
|  */ |  */ | ||||||
| function getNextNode(node: LNode): LNode|null { | function getNextLNodeWithProjection(node: LNode): LNode|null { | ||||||
|   const pNextOrParent = node.pNextOrParent; |   const pNextOrParent = node.pNextOrParent; | ||||||
|  | 
 | ||||||
|   if (pNextOrParent) { |   if (pNextOrParent) { | ||||||
|     return (pNextOrParent.flags & LNodeFlags.TYPE_MASK) === LNodeFlags.Projection ? null : |     // The node is projected
 | ||||||
|                                                                                     pNextOrParent; |     const isLastProjectedNode = | ||||||
|   } else { |         (pNextOrParent.flags & LNodeFlags.TYPE_MASK) === LNodeFlags.Projection; | ||||||
|     return node.next; |     // returns pNextOrParent if we are not at the end of the list, null otherwise
 | ||||||
|  |     return isLastProjectedNode ? null : pNextOrParent; | ||||||
|   } |   } | ||||||
|  | 
 | ||||||
|  |   // returns node.next because the the node is not projected
 | ||||||
|  |   return node.next; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Find the next node in the LNode tree, taking into account the place where a node is |  * Find 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). | ||||||
|  |  * | ||||||
|  * If there is no sibling node, this function goes to the next sibling of the parent node... |  * If there is no sibling node, this function goes to the next sibling of the parent node... | ||||||
|  * until it reaches rootNode (at which point null is returned). |  * until it reaches rootNode (at which point null is returned). | ||||||
|  * |  * | ||||||
|  * @param initialNode The node whose following node in the LNode tree must be found. |  * @param initialNode The node whose following node in the LNode tree must be found. | ||||||
|  * @param rootNode The root node at which the lookup should stop. |  * @param rootNode The root node at which the lookup should stop. | ||||||
|  * @return The following node in the LNode tree. |  * @return LNode|null The following node in the LNode tree. | ||||||
|  */ |  */ | ||||||
| function getNextOrParentSiblingNode(initialNode: LNode, rootNode: LNode): LNode|null { | function getNextOrParentSiblingNode(initialNode: LNode, rootNode: LNode): LNode|null { | ||||||
|   let node: LNode|null = initialNode; |   let node: LNode|null = initialNode; | ||||||
|   let nextNode = getNextNode(node); |   let nextNode = getNextLNodeWithProjection(node); | ||||||
|   while (node && !nextNode) { |   while (node && !nextNode) { | ||||||
|     // if node.pNextOrParent is not null here, it is not the next node
 |     // if node.pNextOrParent is not null here, it is not the next node
 | ||||||
|     // (because, at this point, nextNode is null, so it is the parent)
 |     // (because, at this point, nextNode is null, so it is the parent)
 | ||||||
|     node = node.pNextOrParent || node.parent; |     node = node.pNextOrParent || node.parent; | ||||||
|     if (node === rootNode) node = null; |     if (node === rootNode) { | ||||||
|     nextNode = node && getNextNode(node); |       return null; | ||||||
|  |     } | ||||||
|  |     nextNode = node && getNextLNodeWithProjection(node); | ||||||
|   } |   } | ||||||
|   return nextNode; |   return nextNode; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Returns the first DOM node inside the given logical node. |  * Returns the first RNode inside the given LNode. | ||||||
|  * |  * | ||||||
|  * @param node The node whose first DOM node must be found |  * @param node The node whose first DOM node must be found | ||||||
|  * @returns The first native node of the given logical node or null if there is none. |  * @returns RNode The first RNode of the given LNode or null if there is none. | ||||||
|  */ |  */ | ||||||
| function findFirstNativeNode(rootNode: LNode): RElement|RText|null { | function findFirstRNode(rootNode: LNode): RElement|RText|null { | ||||||
|   let node: LNode|null = rootNode; |   let node: LNode|null = rootNode; | ||||||
|   while (node) { |   while (node) { | ||||||
|     const type = node.flags & LNodeFlags.TYPE_MASK; |     const type = node.flags & LNodeFlags.TYPE_MASK; | ||||||
|     let nextNode: LNode|null = null; |     let nextNode: LNode|null = null; | ||||||
|     if (type === LNodeFlags.Element) { |     if (type === LNodeFlags.Element) { | ||||||
|  |       // A LElementNode has a matching RNode in LElementNode.native
 | ||||||
|       return (node as LElementNode).native; |       return (node as LElementNode).native; | ||||||
|     } else if (type === LNodeFlags.Container) { |     } else if (type === LNodeFlags.Container) { | ||||||
|  |       // For container look at the first node of the view next
 | ||||||
|       const childContainerData: LContainer = (node as LContainerNode).data; |       const childContainerData: LContainer = (node as LContainerNode).data; | ||||||
|       nextNode = childContainerData.views.length ? childContainerData.views[0].child : null; |       nextNode = childContainerData.views.length ? childContainerData.views[0].child : null; | ||||||
|     } else if (type === LNodeFlags.Projection) { |     } else if (type === LNodeFlags.Projection) { | ||||||
|  |       // 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
 | ||||||
|       nextNode = (node as LViewNode).child; |       nextNode = (node as LViewNode).child; | ||||||
|     } |     } | ||||||
|     if (nextNode === null) { | 
 | ||||||
|       node = getNextOrParentSiblingNode(node, rootNode); |     node = nextNode === null ? getNextOrParentSiblingNode(node, rootNode) : nextNode; | ||||||
|     } else { |  | ||||||
|       node = nextNode; |  | ||||||
|     } |  | ||||||
|   } |   } | ||||||
|   return null; |   return null; | ||||||
| } | } | ||||||
| @ -279,11 +285,11 @@ export function insertView( | |||||||
|   // and we should wait until that parent processes its nodes (otherwise, we will insert this view's
 |   // and we should wait until that parent processes its nodes (otherwise, we will insert this view's
 | ||||||
|   // nodes twice - once now and once when its parent inserts its views).
 |   // nodes twice - once now and once when its parent inserts its views).
 | ||||||
|   if (container.data.renderParent !== null) { |   if (container.data.renderParent !== null) { | ||||||
|     let beforeNode = findBeforeNode(newView, container); |     let beforeNode = findNextRNodeSibling(newView, container); | ||||||
|     if (!beforeNode) { |     if (!beforeNode) { | ||||||
|       let containerNextNativeNode = container.native; |       let containerNextNativeNode = container.native; | ||||||
|       if (containerNextNativeNode === undefined) { |       if (containerNextNativeNode === undefined) { | ||||||
|         containerNextNativeNode = container.native = findBeforeNode(container, null); |         containerNextNativeNode = container.native = findNextRNodeSibling(container, null); | ||||||
|       } |       } | ||||||
|       beforeNode = containerNextNativeNode; |       beforeNode = containerNextNativeNode; | ||||||
|     } |     } | ||||||
| @ -470,7 +476,7 @@ export function insertChild(node: LNode, currentView: LView): void { | |||||||
|   if (canInsertNativeNode(parent, currentView)) { |   if (canInsertNativeNode(parent, currentView)) { | ||||||
|     // We only add element if not in View or not projected.
 |     // We only add element if not in View or not projected.
 | ||||||
| 
 | 
 | ||||||
|     let nativeSibling: RNode|null = findBeforeNode(node, null); |     let nativeSibling: RNode|null = findNextRNodeSibling(node, null); | ||||||
|     const renderer = currentView.renderer; |     const renderer = currentView.renderer; | ||||||
|     (renderer as ProceduralRenderer3).listen ? |     (renderer as ProceduralRenderer3).listen ? | ||||||
|         (renderer as ProceduralRenderer3) |         (renderer as ProceduralRenderer3) | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user