fix: patching namespaced attributes (#1049) (#1061)

Co-authored-by: chris <chris@bumblehead.com>
pull/1065/head
iambumblehead 1 year ago committed by GitHub
parent e91d4d150b
commit 8c67f426b6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -4,9 +4,11 @@ import { Module } from "./module";
export type Attrs = Record<string, string | number | boolean>;
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);
}

@ -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", {

Loading…
Cancel
Save