diff --git a/changelog_unreleased/mjml/17400.md b/changelog_unreleased/mjml/17400.md new file mode 100644 index 000000000..59f025afb --- /dev/null +++ b/changelog_unreleased/mjml/17400.md @@ -0,0 +1,17 @@ +#### Correctly parse `` and `` (#17400 by @fisker) + + +```html + + + a::before { + content: "

"; + } +
+ + +SyntaxError: Unexpected closing tag "p". + + +Correctly parsed as CSS. +``` diff --git a/src/language-html/parser-html.js b/src/language-html/parser-html.js index 9aab2030a..28be3609b 100644 --- a/src/language-html/parser-html.js +++ b/src/language-html/parser-html.js @@ -445,8 +445,14 @@ const HTML_PARSE_OPTIONS = { // HTML export const html = createParser(HTML_PARSE_OPTIONS); + +const MJML_RAW_TAGS = new Set(["mj-style", "mj-raw"]); // MJML https://mjml.io/ -export const mjml = createParser({ ...HTML_PARSE_OPTIONS, name: "mjml" }); +export const mjml = createParser({ + ...HTML_PARSE_OPTIONS, + name: "mjml", + shouldParseAsRawText: (tagName) => MJML_RAW_TAGS.has(tagName), +}); // Angular export const angular = createParser({ name: "angular" }); // Vue diff --git a/tests/config/utils/check-parsers.js b/tests/config/utils/check-parsers.js index 02f3717fd..ede5d8c98 100644 --- a/tests/config/utils/check-parsers.js +++ b/tests/config/utils/check-parsers.js @@ -50,7 +50,10 @@ const categoryParsers = new Map([ "html", { parsers: ["html"], verifyParsers: [], extensions: [".html", ".svg"] }, ], - ["mjml", { parsers: ["mjml"], verifyParsers: [], extensions: [".mjml"] }], + [ + "mjml", + { parsers: ["mjml"], verifyParsers: ["html"], extensions: [".mjml"] }, + ], [ "js", { diff --git a/tests/format/mjml/mjml/__snapshots__/format.test.js.snap b/tests/format/mjml/mjml/__snapshots__/format.test.js.snap index eb7bd3760..03b6b1e5f 100644 --- a/tests/format/mjml/mjml/__snapshots__/format.test.js.snap +++ b/tests/format/mjml/mjml/__snapshots__/format.test.js.snap @@ -13,6 +13,56 @@ printWidth: 80 ================================================================================ `; +exports[`example.mjml format 1`] = ` +====================================options===================================== +parsers: ["mjml"] +printWidth: 80 + | printWidth +=====================================input====================================== + + + + + + + + + + + + + + Hello World + + + + + + +=====================================output===================================== + + + + + + + + + + + + + Hello World + + + + + +================================================================================ +`; + exports[`head.mjml format 1`] = ` ====================================options===================================== parsers: ["mjml"] diff --git a/tests/format/mjml/mjml/example.mjml b/tests/format/mjml/mjml/example.mjml new file mode 100644 index 000000000..2c0dc58bd --- /dev/null +++ b/tests/format/mjml/mjml/example.mjml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + Hello World + + + + + diff --git a/tests/format/mjml/parse/mj-raw/__snapshots__/format.test.js.snap b/tests/format/mjml/parse/mj-raw/__snapshots__/format.test.js.snap new file mode 100644 index 000000000..1856c08a6 --- /dev/null +++ b/tests/format/mjml/parse/mj-raw/__snapshots__/format.test.js.snap @@ -0,0 +1,38 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`invalid-in-html.mjml [html] format 1`] = ` +"Unexpected closing tag "p". It may happen when the tag has already been closed by another tag. For more info see https://www.w3.org/TR/html5/syntax.html#closing-elements-that-have-implied-end-tags (3:9) + 1 |

+ 2 | Wrapped +> 3 |

+ | ^^^^ + 4 | + 5 |

+ 6 | WRAPPED" +`; + +exports[`invalid-in-html.mjml format 1`] = ` +====================================options===================================== +parsers: ["mjml", "html"] +printWidth: 80 + | printWidth +=====================================input====================================== +

+Wrapped +

+ +

+WRAPPED +

+ +=====================================output===================================== +

+Wrapped +

+ +

+WRAPPED +

+ +================================================================================ +`; diff --git a/tests/format/mjml/parse/mj-raw/format.test.js b/tests/format/mjml/parse/mj-raw/format.test.js new file mode 100644 index 000000000..e10c3bafd --- /dev/null +++ b/tests/format/mjml/parse/mj-raw/format.test.js @@ -0,0 +1,3 @@ +runFormatTest(import.meta, ["mjml", "html"], { + errors: { html: ["invalid-in-html.mjml"] }, +}); diff --git a/tests/format/mjml/parse/mj-raw/invalid-in-html.mjml b/tests/format/mjml/parse/mj-raw/invalid-in-html.mjml new file mode 100644 index 000000000..e5a22ece3 --- /dev/null +++ b/tests/format/mjml/parse/mj-raw/invalid-in-html.mjml @@ -0,0 +1,7 @@ +

+Wrapped +

+ +

+WRAPPED +

diff --git a/tests/format/mjml/parse/mj-style/__snapshots__/format.test.js.snap b/tests/format/mjml/parse/mj-style/__snapshots__/format.test.js.snap new file mode 100644 index 000000000..b13d71ac8 --- /dev/null +++ b/tests/format/mjml/parse/mj-style/__snapshots__/format.test.js.snap @@ -0,0 +1,39 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`invalid-in-html.mjml [html] format 1`] = ` +"Unexpected closing tag "p". It may happen when the tag has already been closed by another tag. For more info see https://www.w3.org/TR/html5/syntax.html#closing-elements-that-have-implied-end-tags (2:25) + 1 | +> 2 | a::before { content: "

"; + | ^^^^ + 3 | } + 4 |
+ 5 |" +`; + +exports[`invalid-in-html.mjml format 1`] = ` +====================================options===================================== +parsers: ["mjml", "html"] +printWidth: 80 + | printWidth +=====================================input====================================== + + a::before { content: "

"; + } +
+ + + a::before { content: "

"; + } +
+ +=====================================output===================================== + + a::before { + content: "

"; + } +
+ + a::before { content: "

"; }
+ +================================================================================ +`; diff --git a/tests/format/mjml/parse/mj-style/format.test.js b/tests/format/mjml/parse/mj-style/format.test.js new file mode 100644 index 000000000..e10c3bafd --- /dev/null +++ b/tests/format/mjml/parse/mj-style/format.test.js @@ -0,0 +1,3 @@ +runFormatTest(import.meta, ["mjml", "html"], { + errors: { html: ["invalid-in-html.mjml"] }, +}); diff --git a/tests/format/mjml/parse/mj-style/invalid-in-html.mjml b/tests/format/mjml/parse/mj-style/invalid-in-html.mjml new file mode 100644 index 000000000..d83271a3c --- /dev/null +++ b/tests/format/mjml/parse/mj-style/invalid-in-html.mjml @@ -0,0 +1,9 @@ + + a::before { content: "

"; + } +
+ + + a::before { content: "

"; + } +
diff --git a/tests/integration/cli/experimental-cli/test-0/should-format.js b/tests/integration/cli/experimental-cli/test-0/should-format.js new file mode 100644 index 000000000..994d8a206 --- /dev/null +++ b/tests/integration/cli/experimental-cli/test-0/should-format.js @@ -0,0 +1,6 @@ + + console.log( +"Hello, world!" + + + ) diff --git a/tests/integration/cli/experimental-cli/test-0/should-not-format.js b/tests/integration/cli/experimental-cli/test-0/should-not-format.js new file mode 100644 index 000000000..a8141d3b1 --- /dev/null +++ b/tests/integration/cli/experimental-cli/test-0/should-not-format.js @@ -0,0 +1 @@ +console.log("Hello, world!"); diff --git a/tests/integration/cli/experimental-cli/test-1/should-format.js b/tests/integration/cli/experimental-cli/test-1/should-format.js new file mode 100644 index 000000000..994d8a206 --- /dev/null +++ b/tests/integration/cli/experimental-cli/test-1/should-format.js @@ -0,0 +1,6 @@ + + console.log( +"Hello, world!" + + + ) diff --git a/tests/integration/cli/experimental-cli/test-1/should-not-format.js b/tests/integration/cli/experimental-cli/test-1/should-not-format.js new file mode 100644 index 000000000..a8141d3b1 --- /dev/null +++ b/tests/integration/cli/experimental-cli/test-1/should-not-format.js @@ -0,0 +1 @@ +console.log("Hello, world!"); diff --git a/tests/integration/cli/experimental-cli/test-2/should-format.js b/tests/integration/cli/experimental-cli/test-2/should-format.js new file mode 100644 index 000000000..a8141d3b1 --- /dev/null +++ b/tests/integration/cli/experimental-cli/test-2/should-format.js @@ -0,0 +1 @@ +console.log("Hello, world!"); diff --git a/tests/integration/cli/experimental-cli/test-2/should-not-format.js b/tests/integration/cli/experimental-cli/test-2/should-not-format.js new file mode 100644 index 000000000..a8141d3b1 --- /dev/null +++ b/tests/integration/cli/experimental-cli/test-2/should-not-format.js @@ -0,0 +1 @@ +console.log("Hello, world!"); diff --git a/tests/integration/cli/experimental-cli/test-3/should-format.js b/tests/integration/cli/experimental-cli/test-3/should-format.js new file mode 100644 index 000000000..a8141d3b1 --- /dev/null +++ b/tests/integration/cli/experimental-cli/test-3/should-format.js @@ -0,0 +1 @@ +console.log("Hello, world!"); diff --git a/tests/integration/cli/experimental-cli/test-3/should-not-format.js b/tests/integration/cli/experimental-cli/test-3/should-not-format.js new file mode 100644 index 000000000..a8141d3b1 --- /dev/null +++ b/tests/integration/cli/experimental-cli/test-3/should-not-format.js @@ -0,0 +1 @@ +console.log("Hello, world!");