From 64251967d7536118e1d8c2a0d2957b9d2e91cf17 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Thu, 11 Jun 2026 08:43:28 -0300 Subject: html: html.metatag('breakout') not actually tested with blockwrap hell yeah hell yeah --- src/html.js | 43 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) (limited to 'src/html.js') diff --git a/src/html.js b/src/html.js index b4f62ae0..7b8f327a 100644 --- a/src/html.js +++ b/src/html.js @@ -152,6 +152,14 @@ export const blockwrap = Symbol(); // considered wrappable units, not the entire element! export const chunkwrap = Symbol(); +// Don't pass this directly, use html.metatag('breakout') instead. +// Causes *contained* content to be excluded from any *containing* metatag +// to do with special line breaking, i.e. blockwrap or chunkwrap, regardless +// the hierarchical distance. Practically, that means momentarily concluding +// the containing metatag's behavior wherever it operates, then starting more +// or less anew, so the metatag still applies to any following content. +export const breakout = Symbol(); + // Don't pass this directly, use html.metatag('imaginary-sibling') instead. // A tag without any content, which is completely ignored when serializing, // but makes siblings with [onlyIfSiblings] feel less shy and show up on @@ -391,6 +399,9 @@ export function metatag(identifier, ...args) { case 'chunkwrap': return new Tag(null, {[chunkwrap]: true, ...opts}, content); + case 'breakout': + return new Tag(null, {[breakout]: true}, content); + case 'imaginary-sibling': return new Tag(null, {[imaginarySibling]: true}, content); @@ -691,6 +702,14 @@ export class Tag { return this.#getAttributeFlag(chunkwrap); } + get breakout() { + return this.#getAttributeFlag(breakout); + } + + set breakout(value) { + this.#setAttributeFlag(breakout, value); + } + set imaginarySibling(value) { this.#setAttributeFlag(imaginarySibling, value); @@ -819,10 +838,15 @@ export class Tag { chunkwrapSplitter && itemContent.includes('`; } - if (itemIncludesItsOwnChunkwrap) { + if (itemIncludesItsOwnChunkwrap || itemIncludesBreakout) { const trailingWhitespace = content.match(/\s*$/); if (trailingWhitespace) { content = content.slice(0, -trailingWhitespace.length); @@ -864,16 +888,21 @@ export class Tag { if (insideOpenChunkwrapChunk) { content += ''; + } else if (blockwrapClosers) { + content += blockwrapClosers; + blockwrapClosers = ''; } content += trailingWhitespace; content += itemContent; - // Instate a new EVIL chunkwrap: it's not a chunkwrap chunk at all, - // because it's treated as display: inline, but will be closed the - // same as , and can be detected in CSS. - content += ``; - insideOpenChunkwrapChunk = true; + if (chunkwrapSplitter) { + // Instate a new EVIL chunkwrap: it's not a chunkwrap chunk at all, + // because it's treated as display: inline, but will be closed the + // same as , and can be detected in CSS. + content += ``; + insideOpenChunkwrapChunk = true; + } /* Bonus commentary re: above - * An item that item includes its own chunkwrap purposely causes @@ -939,6 +968,8 @@ export class Tag { // been seen at all, just wrap everything in one now. content = `${content}`; } + } else if (this.breakout) { + content = `${content}`; } content += blockwrapClosers; -- cgit 1.3.0-6-gf8a5