From 3c2e656187f3f47f5c365fb376255083b53fce13 Mon Sep 17 00:00:00 2001 From: Simon H <5968653+dummdidumm@users.noreply.github.com> Date: Wed, 6 Dec 2023 14:57:01 +0100 Subject: [PATCH] fix: tweak css nth regex (#9806) fixes #9795 --- .changeset/swift-donkeys-perform.md | 5 + .../src/compiler/phases/1-parse/read/style.js | 4 +- .../samples/css-nth-syntax/input.svelte | 10 +- .../samples/css-nth-syntax/output.json | 156 ++++++++++++++++-- 4 files changed, 159 insertions(+), 16 deletions(-) create mode 100644 .changeset/swift-donkeys-perform.md diff --git a/.changeset/swift-donkeys-perform.md b/.changeset/swift-donkeys-perform.md new file mode 100644 index 0000000000..b911fa10a0 --- /dev/null +++ b/.changeset/swift-donkeys-perform.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: tweak css nth regex diff --git a/packages/svelte/src/compiler/phases/1-parse/read/style.js b/packages/svelte/src/compiler/phases/1-parse/read/style.js index 9f59e8205e..8b1d785446 100644 --- a/packages/svelte/src/compiler/phases/1-parse/read/style.js +++ b/packages/svelte/src/compiler/phases/1-parse/read/style.js @@ -6,7 +6,7 @@ const REGEX_ATTRIBUTE_FLAGS = /^[a-zA-Z]+/; // only `i` and `s` are valid today, const REGEX_COMBINATOR_WHITESPACE = /^\s*(\+|~|>|\|\|)\s*/; const REGEX_COMBINATOR = /^(\+|~|>|\|\|)/; const REGEX_PERCENTAGE = /^\d+(\.\d+)?%/; -const REGEX_NTH_OF = /^(even|odd|(-?[0-9]?n?(\s*\+\s*[0-9]+)?))(\s+of\s+)?/; +const REGEX_NTH_OF = /^\s*(even|odd|(-?[0-9]?n?(\s*\+\s*[0-9]+)?))(\s*(?=[,)])|\s+of\s+)/; const REGEX_WHITESPACE_OR_COLON = /[\s:]/; const REGEX_BRACE_OR_SEMICOLON = /[{;]/; const REGEX_LEADING_HYPHEN_OR_DIGIT = /-?\d/; @@ -294,7 +294,7 @@ function read_selector(parser, inside_pseudo_class = false) { start, end: parser.index }); - } else if (parser.match_regex(REGEX_NTH_OF)) { + } else if (inside_pseudo_class && parser.match_regex(REGEX_NTH_OF)) { children.push({ type: 'Nth', value: /** @type {string} */ (parser.read(REGEX_NTH_OF)), diff --git a/packages/svelte/tests/parser-modern/samples/css-nth-syntax/input.svelte b/packages/svelte/tests/parser-modern/samples/css-nth-syntax/input.svelte index b8e2d40864..5668a7799a 100644 --- a/packages/svelte/tests/parser-modern/samples/css-nth-syntax/input.svelte +++ b/packages/svelte/tests/parser-modern/samples/css-nth-syntax/input.svelte @@ -21,6 +21,14 @@ h1:nth-child(odd) { background: red; } + h1:nth-child( + n + ) { + background: red; + } + h1:global(nav) { + background: red; + } -

Broken

+

Foo

diff --git a/packages/svelte/tests/parser-modern/samples/css-nth-syntax/output.json b/packages/svelte/tests/parser-modern/samples/css-nth-syntax/output.json index 1cea48b17c..3716981b37 100644 --- a/packages/svelte/tests/parser-modern/samples/css-nth-syntax/output.json +++ b/packages/svelte/tests/parser-modern/samples/css-nth-syntax/output.json @@ -2,7 +2,7 @@ "css": { "type": "Style", "start": 0, - "end": 467, + "end": 586, "attributes": [], "children": [ { @@ -471,32 +471,162 @@ }, "start": 408, "end": 458 + }, + { + "type": "Rule", + "prelude": { + "type": "SelectorList", + "start": 463, + "end": 492, + "children": [ + { + "type": "Selector", + "start": 463, + "end": 492, + "children": [ + { + "type": "TypeSelector", + "name": "h1", + "start": 463, + "end": 465 + }, + { + "type": "PseudoClassSelector", + "name": "nth-child", + "args": { + "type": "SelectorList", + "start": 476, + "end": 491, + "children": [ + { + "type": "Selector", + "start": 476, + "end": 491, + "children": [ + { + "type": "Nth", + "value": "\n n\n ", + "start": 476, + "end": 491 + } + ] + } + ] + }, + "start": 465, + "end": 492 + } + ] + } + ] + }, + "block": { + "type": "Block", + "start": 493, + "end": 525, + "children": [ + { + "type": "Declaration", + "start": 503, + "end": 518, + "property": "background", + "value": "red" + } + ] + }, + "start": 463, + "end": 525 + }, + { + "type": "Rule", + "prelude": { + "type": "SelectorList", + "start": 530, + "end": 544, + "children": [ + { + "type": "Selector", + "start": 530, + "end": 544, + "children": [ + { + "type": "TypeSelector", + "name": "h1", + "start": 530, + "end": 532 + }, + { + "type": "PseudoClassSelector", + "name": "global", + "args": { + "type": "SelectorList", + "start": 540, + "end": 543, + "children": [ + { + "type": "Selector", + "start": 540, + "end": 543, + "children": [ + { + "type": "TypeSelector", + "name": "nav", + "start": 540, + "end": 543 + } + ] + } + ] + }, + "start": 532, + "end": 544 + } + ] + } + ] + }, + "block": { + "type": "Block", + "start": 545, + "end": 577, + "children": [ + { + "type": "Declaration", + "start": 555, + "end": 570, + "property": "background", + "value": "red" + } + ] + }, + "start": 530, + "end": 577 } ], "content": { "start": 7, - "end": 459, - "styles": "\n /* test that all these are parsed correctly */\n\th1:nth-of-type(2n+1){\n background: red;\n }\n h1:nth-child(-n + 3 of li.important) {\n background: red;\n }\n h1:nth-child(1) {\n background: red;\n }\n h1:nth-child(p) {\n background: red;\n }\n h1:nth-child(n+7) {\n background: red;\n }\n h1:nth-child(even) {\n background: red;\n }\n h1:nth-child(odd) {\n background: red;\n }\n" + "end": 578, + "styles": "\n /* test that all these are parsed correctly */\n\th1:nth-of-type(2n+1){\n background: red;\n }\n h1:nth-child(-n + 3 of li.important) {\n background: red;\n }\n h1:nth-child(1) {\n background: red;\n }\n h1:nth-child(p) {\n background: red;\n }\n h1:nth-child(n+7) {\n background: red;\n }\n h1:nth-child(even) {\n background: red;\n }\n h1:nth-child(odd) {\n background: red;\n }\n h1:nth-child(\n n\n ) {\n background: red;\n }\n h1:global(nav) {\n background: red;\n }\n" } }, "js": [], - "start": 469, - "end": 484, + "start": 588, + "end": 600, "type": "Root", "fragment": { "type": "Fragment", "nodes": [ { "type": "Text", - "start": 467, - "end": 469, + "start": 586, + "end": 588, "raw": "\n\n", "data": "\n\n" }, { "type": "RegularElement", - "start": 469, - "end": 484, + "start": 588, + "end": 600, "name": "h1", "attributes": [], "fragment": { @@ -504,10 +634,10 @@ "nodes": [ { "type": "Text", - "start": 473, - "end": 479, - "raw": "Broken", - "data": "Broken" + "start": 592, + "end": 595, + "raw": "Foo", + "data": "Foo" } ], "transparent": true