Handlebars: Fix invalid output for <style> containing mustaches (#20030)
Co-authored-by: fisker <lionkay@gmail.com>
This commit is contained in:
1 parent
3014654149
commit
c150b07c07
8 files changed
+105
-16
No files matched your search
@@ -0,0 +1,24 @@
|
|||||||
|
#### Fix invalid output for `<style>` containing mustaches (#20030 by @kovsu)
|
||||||
|
|
||||||
|
<!-- prettier-ignore -->
|
||||||
|
```hbs
|
||||||
|
{{! Input }}
|
||||||
|
<style>
|
||||||
|
a {
|
||||||
|
color: {{foo}}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
{{! Prettier stable }}
|
||||||
|
<style>
|
||||||
|
a {
|
||||||
|
color:{{foo}}}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
{{! Prettier main }}
|
||||||
|
<style>
|
||||||
|
a { color:
|
||||||
|
{{foo}}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
```
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { isPlainTextStyleElement } from "./utilities.js";
|
||||||
|
|
||||||
function embed(path /* , options*/) {
|
function embed(path /* , options*/) {
|
||||||
const { node } = path;
|
const { node } = path;
|
||||||
|
|
||||||
@@ -7,12 +9,7 @@ function embed(path /* , options*/) {
|
|||||||
|
|
||||||
const { parent } = path;
|
const { parent } = path;
|
||||||
|
|
||||||
if (!(
|
if (!(isPlainTextStyleElement(parent) && parent.children[0] === node)) {
|
||||||
parent.type === "ElementNode" &&
|
|
||||||
parent.tag === "style" &&
|
|
||||||
parent.children.length === 1 &&
|
|
||||||
parent.children[0] === node
|
|
||||||
)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import htmlWhitespace from "../../utilities/html-whitespace.js";
|
import htmlWhitespace from "../../utilities/html-whitespace.js";
|
||||||
|
import { isPlainTextStyleElement } from "../utilities.js";
|
||||||
|
|
||||||
function massageAstNode(original, cloned, parent) {
|
function massageAstNode(original, cloned, parent) {
|
||||||
// (Glimmer/HTML) ignore TextNode
|
// (Glimmer/HTML) ignore TextNode
|
||||||
@@ -9,11 +10,7 @@ function massageAstNode(original, cloned, parent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CSS will be formatted
|
// CSS will be formatted
|
||||||
if (
|
if (isPlainTextStyleElement(parent) && parent.children[0] === original) {
|
||||||
parent.tag === "style" &&
|
|
||||||
parent.children.length === 1 &&
|
|
||||||
parent.children[0] === original
|
|
||||||
) {
|
|
||||||
cloned.chars = "";
|
cloned.chars = "";
|
||||||
} else {
|
} else {
|
||||||
cloned.chars = htmlWhitespace.split(trimmed).join(" ");
|
cloned.chars = htmlWhitespace.split(trimmed).join(" ");
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import { locEnd, locStart } from "./loc.js";
|
|||||||
import { massageAstNode } from "./massage-ast/index.js";
|
import { massageAstNode } from "./massage-ast/index.js";
|
||||||
import {
|
import {
|
||||||
hasPrettierIgnore,
|
hasPrettierIgnore,
|
||||||
|
isPlainTextStyleElement,
|
||||||
isVoidElement,
|
isVoidElement,
|
||||||
isWhitespaceNode,
|
isWhitespaceNode,
|
||||||
} from "./utilities.js";
|
} from "./utilities.js";
|
||||||
@@ -59,11 +60,11 @@ function print(path, options, print) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const endingTag = ["</", node.tag, ">"];
|
const endingTag = ["</", node.tag, ">"];
|
||||||
const isStyle = node.tag === "style";
|
const isPlainStyle = isPlainTextStyleElement(node);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
node.children.length === 0 ||
|
node.children.length === 0 ||
|
||||||
((!isWhitespaceSensitive || isStyle) &&
|
((!isWhitespaceSensitive || isPlainStyle) &&
|
||||||
node.children.every((node) => isWhitespaceNode(node)))
|
node.children.every((node) => isWhitespaceNode(node)))
|
||||||
) {
|
) {
|
||||||
return [startingTag, endingTag];
|
return [startingTag, endingTag];
|
||||||
@@ -71,7 +72,7 @@ function print(path, options, print) {
|
|||||||
|
|
||||||
const parts = path.map(print, "children");
|
const parts = path.map(print, "children");
|
||||||
|
|
||||||
if (isStyle || !isWhitespaceSensitive) {
|
if (isPlainStyle || !isWhitespaceSensitive) {
|
||||||
return [startingTag, indent([softline, ...parts]), softline, endingTag];
|
return [startingTag, indent([softline, ...parts]), softline, endingTag];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,7 +173,7 @@ function print(path, options, print) {
|
|||||||
return replaceEndOfLine(text);
|
return replaceEndOfLine(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parent.tag === "style") {
|
if (isPlainTextStyleElement(parent)) {
|
||||||
text = text.replaceAll(/^\n+/g, "");
|
text = text.replaceAll(/^\n+/g, "");
|
||||||
text = htmlWhitespace.trimEnd(text);
|
text = htmlWhitespace.trimEnd(text);
|
||||||
text = htmlWhitespace.dedentString(text);
|
text = htmlWhitespace.dedentString(text);
|
||||||
|
|||||||
@@ -34,6 +34,18 @@ function isWhitespaceNode(node) {
|
|||||||
return node.type === "TextNode" && !/\S/.test(node.chars);
|
return node.type === "TextNode" && !/\S/.test(node.chars);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isPlainTextElement(node) {
|
||||||
|
return (
|
||||||
|
node.type === "ElementNode" &&
|
||||||
|
node.children.length === 1 &&
|
||||||
|
node.children[0].type === "TextNode"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isPlainTextStyleElement(node) {
|
||||||
|
return isPlainTextElement(node) && node.tag === "style";
|
||||||
|
}
|
||||||
|
|
||||||
function isPrettierIgnoreNode(node) {
|
function isPrettierIgnoreNode(node) {
|
||||||
return (
|
return (
|
||||||
node?.type === "MustacheCommentStatement" &&
|
node?.type === "MustacheCommentStatement" &&
|
||||||
@@ -53,4 +65,9 @@ function hasPrettierIgnore(path) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export { hasPrettierIgnore, isVoidElement, isWhitespaceNode };
|
export {
|
||||||
|
hasPrettierIgnore,
|
||||||
|
isPlainTextStyleElement,
|
||||||
|
isVoidElement,
|
||||||
|
isWhitespaceNode,
|
||||||
|
};
|
||||||
@@ -13,10 +13,14 @@ parsers: ["glimmer"]
|
|||||||
</style>
|
</style>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<style></style>
|
||||||
|
|
||||||
=====================================output=====================================
|
=====================================output=====================================
|
||||||
<div>
|
<div>
|
||||||
<style></style>
|
<style></style>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<style></style>
|
||||||
================================================================================
|
================================================================================
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@@ -195,3 +199,38 @@ parsers: ["glimmer"]
|
|||||||
</style>
|
</style>
|
||||||
================================================================================
|
================================================================================
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`with-mustache.hbs format 1`] = `
|
||||||
|
====================================options=====================================
|
||||||
|
parsers: ["glimmer"]
|
||||||
|
printWidth: 80 (default) |
|
||||||
|
=====================================input======================================
|
||||||
|
<style>
|
||||||
|
a {
|
||||||
|
color: {{foo}}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.a { color: {{color}}; }
|
||||||
|
{{#if debug}}.b { color: red; }{{/if}}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style>{{foo}}</style>
|
||||||
|
|
||||||
|
=====================================output=====================================
|
||||||
|
<style>
|
||||||
|
a { color:
|
||||||
|
{{foo}}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.a { color:
|
||||||
|
{{color}}; }
|
||||||
|
{{#if debug}}.b { color: red; }{{/if}}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style>{{foo}}</style>
|
||||||
|
================================================================================
|
||||||
|
`;
|
||||||
@@ -5,3 +5,5 @@
|
|||||||
|
|
||||||
</style>
|
</style>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<style></style>
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<style>
|
||||||
|
a {
|
||||||
|
color: {{foo}}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.a { color: {{color}}; }
|
||||||
|
{{#if debug}}.b { color: red; }{{/if}}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style>{{foo}}</style>
|
||||||
Reference in new issue
Block a user