From 64759fd0b49a6d07e70ef116d8b6fdfd1a01a223 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Fri, 29 Dec 2023 18:18:03 -0400 Subject: html: refactor attributes toString logic --- src/util/html.js | 87 ++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 65 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/util/html.js b/src/util/html.js index 5b6743e0..f01e2d87 100644 --- a/src/util/html.js +++ b/src/util/html.js @@ -502,28 +502,71 @@ export class Attributes { } toString() { - return Object.entries(this.attributes) - .map(([key, val]) => { - if (typeof val === 'undefined' || val === null) - return [key, val, false]; - else if (typeof val === 'string') - return [key, val, true]; - else if (typeof val === 'boolean') - return [key, val, val]; - else if (typeof val === 'number') - return [key, val.toString(), true]; - else if (Array.isArray(val)) - return [key, val.filter(Boolean).join(' '), val.length > 0]; - else - throw new Error(`Attribute value for ${key} should be primitive or array, got ${typeof val}`); - }) - .filter(([_key, _val, keep]) => keep) - .map(([key, val]) => - typeof val === 'boolean' - ? `${key}` - : `${key}="${this.#escapeAttributeValue(val)}"` - ) - .join(' '); + const attributeKeyValues = + Object.entries(this.attributes) + .map(([key, value]) => + (this.#keepAttributeValue(value) + ? [key, this.#transformAttributeValue(value), true] + : [key, undefined, false])) + .filter(([_key, _value, keep]) => keep) + .map(([key, value]) => [key, value]); + + const attributeParts = + attributeKeyValues + .map(([key, value]) => + (typeof value === 'boolean' + ? `${key}` + : `${key}="${this.#escapeAttributeValue(value)}"`)); + + return attributeParts.join(' '); + } + + #keepAttributeValue(value) { + switch (typeof value) { + case 'undefined': + return false; + + case 'object': + if (Array.isArray(value)) { + return value.some(Boolean); + } else if (value === null) { + return false; + } else { + // Other objects are an error. + break; + } + + case 'boolean': + return value; + + case 'string': + case 'number': + return true; + + case 'array': + return value.some(Boolean); + } + + throw new Error( + `Attribute value for ${key} should be primitive or array, ` + + `got ${typeAppearance(val)}`); + } + + #transformAttributeValue(value) { + switch (typeof value) { + case 'boolean': + return value; + + case 'number': + return value.toString(); + + // If it's a kept object, it's an array. + case 'object': + return value.filter(Boolean).join(' '); + + default: + return value; + } } #escapeAttributeValue(value) { -- cgit 1.3.0-6-gf8a5