From 8c67f426b678d8823945e967dd94aea82e0659e8 Mon Sep 17 00:00:00 2001 From: iambumblehead Date: Wed, 8 Nov 2023 10:52:33 -0800 Subject: [PATCH] fix: patching namespaced attributes (#1049) (#1061) Co-authored-by: chris --- src/modules/attributes.ts | 8 ++++++-- test/unit/attributes.ts | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/modules/attributes.ts b/src/modules/attributes.ts index 7fdfcb2..00baa11 100755 --- a/src/modules/attributes.ts +++ b/src/modules/attributes.ts @@ -4,9 +4,11 @@ import { Module } from "./module"; export type Attrs = Record; const xlinkNS = "http://www.w3.org/1999/xlink"; +const xmlnsNS = "http://www.w3.org/2000/xmlns/"; const xmlNS = "http://www.w3.org/XML/1998/namespace"; const colonChar = 58; const xChar = 120; +const mChar = 109; function updateAttrs(oldVnode: VNode, vnode: VNode): void { let key: string; @@ -35,8 +37,10 @@ function updateAttrs(oldVnode: VNode, vnode: VNode): void { // Assume xml namespace elm.setAttributeNS(xmlNS, key, cur as any); } else if (key.charCodeAt(5) === colonChar) { - // Assume xlink namespace - elm.setAttributeNS(xlinkNS, key, cur as any); + // Assume 'xmlns' or 'xlink' namespace + key.charCodeAt(1) === mChar + ? elm.setAttributeNS(xmlnsNS, key, cur as any) + : elm.setAttributeNS(xlinkNS, key, cur as any); } else { elm.setAttribute(key, cur as any); } diff --git a/test/unit/attributes.ts b/test/unit/attributes.ts index e3ada44..efdb248 100644 --- a/test/unit/attributes.ts +++ b/test/unit/attributes.ts @@ -64,6 +64,26 @@ describe("attributes", function () { assert.strictEqual(elm.className, "myClass"); assert.strictEqual(elm.textContent, "Hello"); }); + it("should apply legacy namespace attributes, xmlns", function () { + const elmNamespaceQualifiedName = "xmlns:xlink"; + const elmNamespaceValue = "http://www.w3.org/1999/xlink"; + const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); + const vnodeSVG = h("svg", { + attrs: { [elmNamespaceQualifiedName]: elmNamespaceValue }, + }); + + elm = patch(svg, vnodeSVG).elm; + // https://developer.mozilla.org/en-US/docs/Web/API/Element/getAttributeNS + // > Namespaces are only supported in XML documents. HTML documents have to + // > use getAttribute() instead. + // + // MDN advise getAttribute over getAttributeNS, as the latter returns `null` + // and namespaces are a legacy feature, no longer supported + assert.strictEqual( + elm.getAttribute(elmNamespaceQualifiedName), + elmNamespaceValue, + ); + }); describe("boolean attribute", function () { it("is present and empty string if the value is truthy", function () { const vnode1 = h("div", {