diff --git a/.changeset/slimy-suits-sparkle.md b/.changeset/slimy-suits-sparkle.md new file mode 100644 index 000000000..edb1146fe --- /dev/null +++ b/.changeset/slimy-suits-sparkle.md @@ -0,0 +1,5 @@ +--- +'@astrojs/compiler': patch +--- + +Updates `compressHTML` logic to account for elements which are known to be whitespace sensitive diff --git a/internal/transform/transform.go b/internal/transform/transform.go index d4240adbb..2d9ab83c5 100644 --- a/internal/transform/transform.go +++ b/internal/transform/transform.go @@ -280,6 +280,62 @@ func isWhitespaceInsensitiveElement(n *astro.Node) bool { return n.Data == "head" } +var knownTextElements = map[string]bool{ + "a": true, + "abbr": true, + "b": true, + "bdi": true, + "bdo": true, + "blockquote": true, + "br": true, + "caption": true, + "cite": true, + "code": true, + "col": true, + "colgroup": true, + "data": true, + "del": true, + "dfn": true, + "em": true, + "h1": true, + "h2": true, + "h3": true, + "h4": true, + "h5": true, + "h6": true, + "i": true, + "ins": true, + "kbd": true, + "mark": true, + "p": true, + "q": true, + "rp": true, + "rt": true, + "ruby": true, + "s": true, + "samp": true, + "small": true, + "span": true, + "strong": true, + "sub": true, + "sup": true, + "table": true, + "tbody": true, + "td": true, + "tfoot": true, + "th": true, + "thead": true, + "time": true, + "tr": true, + "u": true, + "var": true, + "wbr": true, +} + +func isTextElement(n *astro.Node) bool { + return knownTextElements[n.Data] +} + func collapseWhitespace(doc *astro.Node) { walk(doc, func(n *astro.Node) { if n.Type == astro.TextNode { @@ -304,10 +360,13 @@ func collapseWhitespace(doc *astro.Node) { // If the node is only whitespace, clear it if len(strings.TrimFunc(n.Data, unicode.IsSpace)) == 0 { - // If it's a lone text node, or if it's within a whitespace-insensitive element, clear completely - if (n.PrevSibling == nil && n.NextSibling == nil) || n.Closest(isWhitespaceInsensitiveElement) != nil { + if isTextElement(n) { + // Known textual elements can be handled early + n.Data = " " + } else if (n.PrevSibling == nil && n.NextSibling == nil) || n.Closest(isWhitespaceInsensitiveElement) != nil { + // If it's a lone text node, or if it's within a whitespace-insensitive element, clear completely n.Data = "" - } else { + } else if n.Parent != nil { n.Data = " " } return diff --git a/internal/transform/transform_test.go b/internal/transform/transform_test.go index a52dc11b6..580e08125 100644 --- a/internal/transform/transform_test.go +++ b/internal/transform/transform_test.go @@ -418,6 +418,16 @@ func TestCompactTransform(t *testing.T) { source: "
{'text'} text
", + want: "{'text'} text
", + }, + { + name: "preserve in-between inline elements II", + source: "text text
", + want: "text text
", + }, { name: "expression trim first", source: "{"text"} text
\ntext text
\n${"text"} text
text text