From 4521989ae0346da90835a488ebcc2e7254161fcd Mon Sep 17 00:00:00 2001 From: Altan Birler Date: Sun, 27 Jun 2021 07:51:03 +0200 Subject: [PATCH] Improve claim_text Split an existing text node if we match the prefix --- src/runtime/internal/dom.ts | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/src/runtime/internal/dom.ts b/src/runtime/internal/dom.ts index 58f72190fdcc..d1d12642f56d 100644 --- a/src/runtime/internal/dom.ts +++ b/src/runtime/internal/dom.ts @@ -41,12 +41,12 @@ function init_hydrate(target: NodeEx) { let children: ArrayLike = target.childNodes as NodeListOf; // If target is head, there may be children without claim_order - if (target.nodeName.toLowerCase() == "head") { + if (target.nodeName.toLowerCase() === 'head') { const myChildren = []; for (let i = 0; i < children.length; i++) { const node = children[i]; if (node.claim_order !== undefined) { - myChildren.push(node) + myChildren.push(node); } } children = myChildren; @@ -325,7 +325,7 @@ function init_claim_info(nodes: ChildNodeArray) { } } -function claim_node(nodes: ChildNodeArray, predicate: (node: ChildNodeEx) => node is R, processNode: (node: ChildNodeEx) => void, createNode: () => R, dontUpdateLastIndex: boolean = false) { +function claim_node(nodes: ChildNodeArray, predicate: (node: ChildNodeEx) => node is R, processNode: (node: ChildNodeEx) => ChildNodeEx | undefined, createNode: () => R, dontUpdateLastIndex: boolean = false) { // Try to find nodes in an order such that we lengthen the longest increasing subsequence init_claim_info(nodes); @@ -335,9 +335,13 @@ function claim_node(nodes: ChildNodeArray, predicate: (no const node = nodes[i]; if (predicate(node)) { - processNode(node); + const replacement = processNode(node); - nodes.splice(i, 1); + if (replacement === undefined) { + nodes.splice(i, 1); + } else { + nodes[i] = replacement; + } if (!dontUpdateLastIndex) { nodes.claim_info.last_index = i; } @@ -352,12 +356,16 @@ function claim_node(nodes: ChildNodeArray, predicate: (no const node = nodes[i]; if (predicate(node)) { - processNode(node); + const replacement = processNode(node); - nodes.splice(i, 1); + if (replacement === undefined) { + nodes.splice(i, 1); + } else { + nodes[i] = replacement; + } if (!dontUpdateLastIndex) { nodes.claim_info.last_index = i; - } else { + } else if (replacement === undefined) { // Since we spliced before the last_index, we decrease it nodes.claim_info.last_index--; } @@ -387,6 +395,7 @@ export function claim_element(nodes: ChildNodeArray, name: string, attributes: { } } remove.forEach(v => node.removeAttribute(v)); + return undefined; }, () => svg ? svg_element(name as keyof SVGElementTagNameMap) : element(name as keyof HTMLElementTagNameMap) ); @@ -397,7 +406,14 @@ export function claim_text(nodes: ChildNodeArray, data) { nodes, (node: ChildNode): node is Text => node.nodeType === 3, (node: Text) => { - node.data = '' + data; + const dataStr = '' + data; + if (node.data.startsWith(dataStr)) { + if (node.data.length !== dataStr.length) { + return node.splitText(dataStr.length); + } + } else { + node.data = dataStr; + } }, () => text(data), true // Text nodes should not update last index since it is likely not worth it to eliminate an increasing subsequence of actual elements