From bf4c680ec16267e4757e773317cc56c5603bbb68 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Tue, 26 Mar 2024 09:34:22 -0300 Subject: html: html.smush(), Tag.smush() --- src/util/html.js | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) (limited to 'src/util') diff --git a/src/util/html.js b/src/util/html.js index 944eab7..c7157a8 100644 --- a/src/util/html.js +++ b/src/util/html.js @@ -619,6 +619,61 @@ export class Tag { return new Tag(null, null, content); } + smush() { + if (!this.contentOnly) { + return tags([this]); + } + + const joiner = this.#getContentJoiner(); + + const result = []; + + let workingText = ''; + + for (const item of this.content) { + const smushed = smush(item); + const smushedItems = smushed.content.slice(); + + if (empty(smushedItems)) { + continue; + } + + if (typeof smushedItems[0] === 'string') { + if (workingText) { + workingText += joiner; + } + + workingText += smushedItems.shift(); + } + + if (empty(smushedItems)) { + continue; + } + + if (workingText) { + result.push(workingText); + } + + if (typeof smushedItems.at(-1) === 'string') { + workingText = smushedItems.pop(); + } else { + workingText = ''; + } + + result.push(...smushedItems); + } + + if (workingText) { + result.push(workingText); + } + + const attributes = { + [joinChildren]: this.joinChildren, + }; + + return new Tag(null, attributes, result); + } + [inspect.custom](depth, opts) { const lines = []; @@ -1111,6 +1166,31 @@ export function resolve(tagOrTemplate, {normalize = null} = {}) { } } +export function smush(smushee) { + if ( + typeof smushee === 'string' || + typeof smushee === 'number' + ) { + return tags([smushee.toString()]); + } + + if (smushee instanceof Template) { + // Smushing is only really useful if the contents are resolved, because + // otherwise we can't actually inspect the boundaries. However, as usual + // for smushing, we don't care at all about the contents of tags (which + // aren't contentOnly) *within* the content we're smushing, so this won't + // for example smush a template nested within a *tag* within the contents + // of this template. + return smush(Template.resolve(smushee)); + } + + if (smushee instanceof Tag) { + return smushee.smush(); + } + + return smush(Tag.normalize(smushee)); +} + export function template(description) { return new Template(description); } -- cgit 1.3.0-6-gf8a5