diff options
Diffstat (limited to 'src/util/html.js')
-rw-r--r-- | src/util/html.js | 63 |
1 files changed, 44 insertions, 19 deletions
diff --git a/src/util/html.js b/src/util/html.js index a311bbba..282a52da 100644 --- a/src/util/html.js +++ b/src/util/html.js @@ -2,7 +2,7 @@ import {inspect} from 'node:util'; -import {empty} from '#sugar'; +import {empty, typeAppearance} from '#sugar'; import * as commonValidators from '#validators'; // COMPREHENSIVE! @@ -242,7 +242,7 @@ export class Tag { this.selfClosing && !(value === null || value === undefined || - !Boolean(value) || + !value || Array.isArray(value) && value.filter(Boolean).length === 0) ) { throw new Error(`Tag <${this.tagName}> is self-closing but got content`); @@ -633,7 +633,7 @@ export class Template { static validateDescription(description) { if (typeof description !== 'object') { - throw new TypeError(`Expected object, got ${typeof description}`); + throw new TypeError(`Expected object, got ${typeAppearance(description)}`); } if (description === null) { @@ -806,24 +806,43 @@ export class Template { } // Null is always an acceptable slot value. - if (value !== null) { - if ('validate' in description) { - description.validate({ - ...commonValidators, - ...validators, - })(value); - } + if (value === null) { + return true; + } + + if ('validate' in description) { + description.validate({ + ...commonValidators, + ...validators, + })(value); + } - if ('type' in description) { - const {type} = description; - if (type === 'html') { - if (!isHTML(value)) { + if ('type' in description) { + switch (description.type) { + case 'html': { + if (!isHTML(value)) throw new TypeError(`Slot expects html (tag, template or blank), got ${typeof value}`); - } - } else { - if (typeof value !== type) { - throw new TypeError(`Slot expects ${type}, got ${typeof value}`); - } + + return true; + } + + case 'string': { + // Tags and templates are valid in string arguments - they'll be + // stringified when exposed to the description's .content() function. + if (isTag(value) || isTemplate(value)) + return true; + + if (typeof value !== 'string') + throw new TypeError(`Slot expects string, got ${typeof value}`); + + return true; + } + + default: { + if (typeof value !== description.type) + throw new TypeError(`Slot expects ${description.type}, got ${typeof value}`); + + return true; } } } @@ -847,6 +866,12 @@ export class Template { return providedValue; } + if (description.type === 'string') { + if (isTag(providedValue) || isTemplate(providedValue)) { + return providedValue.toString(); + } + } + if (providedValue !== null) { return providedValue; } |