Precise DOM morphing
morphing typescript dom
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Trigger nodeRemoved callbacks

+27 -14
+13 -7
dist/morphlex.js
··· 23 23 } 24 24 } 25 25 } 26 - // This is where we actually morph the nodes. The `morph` function exists to set up the `idMap`. 26 + // This is where we actually morph the nodes. The `morph` function (above) exists only to set up the `idMap`. 27 27 function morphNode(node, ref, context) { 28 28 const writableRef = ref; 29 29 if (!(context.beforeNodeMorphed?.(node, writableRef) ?? true)) return; ··· 35 35 for (const child of node.children) { 36 36 const key = child.outerHTML; 37 37 const refChild = refChildNodes.get(key); 38 - refChild ? refChildNodes.delete(key) : child.remove(); // TODO add callback 38 + refChild ? refChildNodes.delete(key) : removeNode(child, context); 39 39 } 40 40 for (const refChild of refChildNodes.values()) appendChild(node, refChild.cloneNode(true), context); 41 41 } else if (node.hasChildNodes() || ref.hasChildNodes()) morphChildNodes(node, ref, context); ··· 89 89 if (child && refChild) morphChildNode(child, refChild, element, context); 90 90 else if (refChild) { 91 91 appendChild(element, refChild.cloneNode(true), context); 92 - } else if (child && (context.beforeNodeRemoved?.(child) ?? true)) { 93 - child.remove(); 94 - context.afterNodeRemoved?.(child); 95 - } 92 + } else if (child) removeNode(child, context); 96 93 } 97 94 // Remove any excess child nodes from the main element. This is separate because 98 95 // the loop above might modify the length of the main element’s child nodes. 99 - while (element.childNodes.length > ref.childNodes.length) element.lastChild?.remove(); 96 + while (element.childNodes.length > ref.childNodes.length) { 97 + const child = element.lastChild; 98 + if (child) removeNode(child, context); 99 + } 100 100 } 101 101 function updateProperty(element, propertyName, newValue, context) { 102 102 const previousValue = element[propertyName]; ··· 151 151 if (context.beforeNodeAdded?.(newNode, node) ?? true) { 152 152 node.appendChild(newNode); 153 153 context.afterNodeAdded?.(newNode); 154 + } 155 + } 156 + function removeNode(node, context) { 157 + if (context.beforeNodeRemoved?.(node) ?? true) { 158 + node.remove(); 159 + context.afterNodeRemoved?.(node); 154 160 } 155 161 } 156 162 function isText(node) {
+14 -7
src/morphlex.ts
··· 83 83 } 84 84 } 85 85 86 - // This is where we actually morph the nodes. The `morph` function exists to set up the `idMap`. 86 + // This is where we actually morph the nodes. The `morph` function (above) exists only to set up the `idMap`. 87 87 function morphNode(node: ChildNode, ref: ReadonlyNode<ChildNode>, context: Context): void { 88 88 const writableRef = ref as ChildNode; 89 89 if (!(context.beforeNodeMorphed?.(node, writableRef) ?? true)) return; ··· 96 96 for (const child of node.children) { 97 97 const key = child.outerHTML; 98 98 const refChild = refChildNodes.get(key); 99 - refChild ? refChildNodes.delete(key) : child.remove(); // TODO add callback 99 + refChild ? refChildNodes.delete(key) : removeNode(child, context); 100 100 } 101 101 for (const refChild of refChildNodes.values()) appendChild(node, refChild.cloneNode(true), context); 102 102 } else if (node.hasChildNodes() || ref.hasChildNodes()) morphChildNodes(node, ref, context); ··· 158 158 if (child && refChild) morphChildNode(child, refChild, element, context); 159 159 else if (refChild) { 160 160 appendChild(element, refChild.cloneNode(true), context); 161 - } else if (child && (context.beforeNodeRemoved?.(child) ?? true)) { 162 - child.remove(); 163 - context.afterNodeRemoved?.(child); 164 - } 161 + } else if (child) removeNode(child, context); 165 162 } 166 163 167 164 // Remove any excess child nodes from the main element. This is separate because 168 165 // the loop above might modify the length of the main element’s child nodes. 169 - while (element.childNodes.length > ref.childNodes.length) element.lastChild?.remove(); 166 + while (element.childNodes.length > ref.childNodes.length) { 167 + const child = element.lastChild; 168 + if (child) removeNode(child, context); 169 + } 170 170 } 171 171 172 172 function updateProperty<N extends Node, P extends keyof N>(element: N, propertyName: P, newValue: N[P], context: Context): void { ··· 232 232 if (context.beforeNodeAdded?.(newNode, node) ?? true) { 233 233 node.appendChild(newNode); 234 234 context.afterNodeAdded?.(newNode); 235 + } 236 + } 237 + 238 + function removeNode(node: ChildNode, context: Context): void { 239 + if (context.beforeNodeRemoved?.(node) ?? true) { 240 + node.remove(); 241 + context.afterNodeRemoved?.(node); 235 242 } 236 243 } 237 244