From b74f4e5978a5ecaef42670cb255e05fc80c75d05 Mon Sep 17 00:00:00 2001 From: Samuele Arcidiacono Date: Fri, 24 Mar 2023 11:24:31 -0400 Subject: [PATCH 1/2] Update node_data.ts Don't use localName to identify tags, if it's not populated. I verified this issue on Cobalt 9, but this may also affect IE <=8. https://caniuse.com/?search=localName In browsers that don't populate localName, idom couldn't identify the tag name during patch, and would always think that a different tag was being re-rendered, always recreating DOM nodes rather than reusing them (you can't change the tag name of an existing node). Quick links: Element.localName https://developer.mozilla.org/en-US/docs/Web/API/Element/localName Node.nodeName https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeName Element.tagName https://developer.mozilla.org/en-US/docs/Web/API/Element/tagName --- src/node_data.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/node_data.ts b/src/node_data.ts index 40b3946..57390d3 100644 --- a/src/node_data.ts +++ b/src/node_data.ts @@ -135,7 +135,9 @@ function importSingleNode(node: Node, fallbackKey?: Key): NodeData { return node["__incrementalDOMData"]; } - const nodeName = isElement(node) ? node.localName : node.nodeName; + // Cobalt 9 doesn't populate localName. + const nodeName = + isElement(node) && node.localName ? node.localName : node.nodeName; const keyAttrName = getKeyAttributeName(); const keyAttr = isElement(node) && keyAttrName != null From 13501b6e4e646ff0533817205bb8ee5f4a0c1a8a Mon Sep 17 00:00:00 2001 From: Samuele Arcidiacono Date: Mon, 27 Mar 2023 07:24:22 -0700 Subject: [PATCH 2/2] Update node_data.ts Remove runtime Element check and force TypeScript to access `localName`. Changed check to use `??` after I verified that localName is not the empty string --- src/node_data.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/node_data.ts b/src/node_data.ts index 57390d3..f4b5538 100644 --- a/src/node_data.ts +++ b/src/node_data.ts @@ -135,9 +135,9 @@ function importSingleNode(node: Node, fallbackKey?: Key): NodeData { return node["__incrementalDOMData"]; } - // Cobalt 9 doesn't populate localName. - const nodeName = - isElement(node) && node.localName ? node.localName : node.nodeName; + // localName is preferred, but it's only available on Element, and some + // browsers (e.g. Cobalt 9) don't populate it anyway. + const nodeName = (node as Element).localName ?? node.nodeName; const keyAttrName = getKeyAttributeName(); const keyAttr = isElement(node) && keyAttrName != null