(ctx, oldParent, newParent, insertionPoint = null, endPoint = null)
| 58 | } |
| 59 | |
| 60 | function _morphChildren(ctx, oldParent, newParent, insertionPoint = null, endPoint = null) { |
| 61 | if (oldParent instanceof HTMLTemplateElement && newParent instanceof HTMLTemplateElement) { |
| 62 | oldParent = oldParent.content; |
| 63 | newParent = newParent.content; |
| 64 | } |
| 65 | insertionPoint ||= oldParent.firstChild; |
| 66 | |
| 67 | let newChild = newParent.firstChild; |
| 68 | while (newChild) { |
| 69 | let matchedNode; |
| 70 | if (insertionPoint && insertionPoint !== endPoint) { |
| 71 | matchedNode = _findBestMatch(ctx, newChild, insertionPoint, endPoint); |
| 72 | if (matchedNode && matchedNode !== insertionPoint) { |
| 73 | let cursor = insertionPoint; |
| 74 | while (cursor && cursor !== matchedNode) { |
| 75 | let tempNode = cursor; |
| 76 | cursor = cursor.nextSibling; |
| 77 | if (tempNode instanceof Element && (ctx.idMap.has(tempNode) || _matchesUpcomingSibling(ctx, tempNode, newChild))) { |
| 78 | _moveBefore(oldParent, tempNode, endPoint); |
| 79 | } else { |
| 80 | _removeNode(ctx, tempNode); |
| 81 | } |
| 82 | } |
| 83 | } |
| 84 | } |
| 85 | |
| 86 | if (!matchedNode && newChild instanceof Element && ctx.persistentIds.has(newChild.id)) { |
| 87 | let escapedId = CSS.escape(newChild.id); |
| 88 | matchedNode = (ctx.target.id === newChild.id && ctx.target) || |
| 89 | ctx.target.querySelector('[id="' + escapedId + '"]') || |
| 90 | ctx.pantry.querySelector('[id="' + escapedId + '"]'); |
| 91 | let element = matchedNode; |
| 92 | while ((element = element.parentNode)) { |
| 93 | let idSet = ctx.idMap.get(element); |
| 94 | if (idSet) { |
| 95 | idSet.delete(matchedNode.id); |
| 96 | if (!idSet.size) ctx.idMap.delete(element); |
| 97 | } |
| 98 | } |
| 99 | _moveBefore(oldParent, matchedNode, insertionPoint); |
| 100 | } |
| 101 | |
| 102 | if (matchedNode) { |
| 103 | _morphNode(matchedNode, newChild, ctx); |
| 104 | insertionPoint = matchedNode.nextSibling; |
| 105 | newChild = newChild.nextSibling; |
| 106 | continue; |
| 107 | } |
| 108 | |
| 109 | let nextNewChild = newChild.nextSibling; |
| 110 | if (ctx.idMap.has(newChild)) { |
| 111 | let placeholder = document.createElement(newChild.tagName); |
| 112 | oldParent.insertBefore(placeholder, insertionPoint); |
| 113 | _morphNode(placeholder, newChild, ctx); |
| 114 | insertionPoint = placeholder.nextSibling; |
| 115 | } else { |
| 116 | oldParent.insertBefore(newChild, insertionPoint); |
| 117 | ctx.callbacks.afterNodeAdded?.(newChild); |
no test coverage detected