From 209f02236749020c1c11fd6328472d906654da11 Mon Sep 17 00:00:00 2001 From: Rogerio Amorim Date: Thu, 18 Jan 2024 12:04:06 -0300 Subject: [PATCH 01/13] fix error when using semicolon inside quotes in style --- packages/svelte/src/compiler/phases/1-parse/read/style.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 545542d80f4b..a8539ccfab71 100644 --- a/packages/svelte/src/compiler/phases/1-parse/read/style.js +++ b/packages/svelte/src/compiler/phases/1-parse/read/style.js @@ -9,7 +9,7 @@ const REGEX_PERCENTAGE = /^\d+(\.\d+)?%/; const REGEX_NTH_OF = /^(even|odd|\+?(\d+|\d*n(\s*[+-]\s*\d+)?)|-\d*n(\s*\+\s*\d+))((?=\s*[,)])|\s+of\s+)/; const REGEX_WHITESPACE_OR_COLON = /[\s:]/; -const REGEX_BRACE_OR_SEMICOLON = /[{;]/; +const REGEX_BRACE_OR_SEMICOLON = /;(?=(?:[^']*'[^']*')*[^']*$)/; const REGEX_LEADING_HYPHEN_OR_DIGIT = /-?\d/; const REGEX_VALID_IDENTIFIER_CHAR = /[a-zA-Z0-9_-]/; const REGEX_COMMENT_CLOSE = /\*\//; From 2be35cd5ab921308271a699044f3ec8c8d6e8e00 Mon Sep 17 00:00:00 2001 From: Rogerio Amorim Date: Thu, 18 Jan 2024 12:12:44 -0300 Subject: [PATCH 02/13] refactor to include { like in the original code --- packages/svelte/src/compiler/phases/1-parse/read/style.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 a8539ccfab71..6ed218ce80fb 100644 --- a/packages/svelte/src/compiler/phases/1-parse/read/style.js +++ b/packages/svelte/src/compiler/phases/1-parse/read/style.js @@ -9,7 +9,7 @@ const REGEX_PERCENTAGE = /^\d+(\.\d+)?%/; const REGEX_NTH_OF = /^(even|odd|\+?(\d+|\d*n(\s*[+-]\s*\d+)?)|-\d*n(\s*\+\s*\d+))((?=\s*[,)])|\s+of\s+)/; const REGEX_WHITESPACE_OR_COLON = /[\s:]/; -const REGEX_BRACE_OR_SEMICOLON = /;(?=(?:[^']*'[^']*')*[^']*$)/; +const REGEX_BRACE_OR_SEMICOLON = /[{;](?=(?:[^']*'[^']*')*[^']*$)/; const REGEX_LEADING_HYPHEN_OR_DIGIT = /-?\d/; const REGEX_VALID_IDENTIFIER_CHAR = /[a-zA-Z0-9_-]/; const REGEX_COMMENT_CLOSE = /\*\//; From 6fc7fe60c300bc2526653b1d22d7c630fbb03f8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rog=C3=A9rio=20Luiz=20Aques=20de=20Amorim?= Date: Thu, 18 Jan 2024 14:43:46 -0300 Subject: [PATCH 03/13] simplified version of regex Co-authored-by: navorite --- packages/svelte/src/compiler/phases/1-parse/read/style.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 6ed218ce80fb..955c10ef8419 100644 --- a/packages/svelte/src/compiler/phases/1-parse/read/style.js +++ b/packages/svelte/src/compiler/phases/1-parse/read/style.js @@ -9,7 +9,7 @@ const REGEX_PERCENTAGE = /^\d+(\.\d+)?%/; const REGEX_NTH_OF = /^(even|odd|\+?(\d+|\d*n(\s*[+-]\s*\d+)?)|-\d*n(\s*\+\s*\d+))((?=\s*[,)])|\s+of\s+)/; const REGEX_WHITESPACE_OR_COLON = /[\s:]/; -const REGEX_BRACE_OR_SEMICOLON = /[{;](?=(?:[^']*'[^']*')*[^']*$)/; +const REGEX_BRACE_OR_SEMICOLON = /[{;](?=[^"']*$)/; const REGEX_LEADING_HYPHEN_OR_DIGIT = /-?\d/; const REGEX_VALID_IDENTIFIER_CHAR = /[a-zA-Z0-9_-]/; const REGEX_COMMENT_CLOSE = /\*\//; From ab8c66d10c0c9f97818a8815637d5fdae85c8364 Mon Sep 17 00:00:00 2001 From: Rogerio Amorim Date: Thu, 18 Jan 2024 14:50:34 -0300 Subject: [PATCH 04/13] add changeset --- .changeset/seven-hornets-smile.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/seven-hornets-smile.md diff --git a/.changeset/seven-hornets-smile.md b/.changeset/seven-hornets-smile.md new file mode 100644 index 000000000000..98dc9c466923 --- /dev/null +++ b/.changeset/seven-hornets-smile.md @@ -0,0 +1,5 @@ +--- +"svelte": patch +--- + +fix parsing error when using semicolon inside quotes on component's style tag From db95220ca0a4170bdde531dc7aae24040f6ee286 Mon Sep 17 00:00:00 2001 From: Rogerio Amorim Date: Thu, 18 Jan 2024 14:52:24 -0300 Subject: [PATCH 05/13] add changeset --- playgrounds/demo/demo.css | 249 +------------------------------------- 1 file changed, 3 insertions(+), 246 deletions(-) diff --git a/playgrounds/demo/demo.css b/playgrounds/demo/demo.css index 5cfdeb0dd666..75bfe420145f 100644 --- a/playgrounds/demo/demo.css +++ b/playgrounds/demo/demo.css @@ -1,246 +1,3 @@ -body { - --bg-1: hsl(0, 0%, 100%); - --bg-2: hsl(206, 20%, 90%); - --bg-3: hsl(206, 20%, 80%); - --fg-1: hsl(0, 0%, 13%); - --fg-2: hsl(0, 0%, 20%); - --fg-2: hsl(0, 0%, 30%); - --link: hsl(208, 77%, 47%); - --link-hover: hsl(208, 77%, 55%); - --link-active: hsl(208, 77%, 40%); - --border-radius: 4px; - --font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, - 'Open Sans', 'Helvetica Neue', sans-serif; - --font-mono: ui-monospace, 'Cascadia Code', 'Source Code Pro', Menlo, Consolas, 'DejaVu Sans Mono', - monospace; - background: var(--bg-1); - color: var(--fg-1); - font-family: var(--font); - line-height: 1.5; - margin: 1rem; - height: calc(100vh - 2rem); -} - -h1, -h2, -h3, -h4, -h5, -h6 { - font-weight: normal; - font-variant-numeric: tabular-nums; - line-height: 1.1; -} - -:is(h1, h2, h3, h4, h5, h6, p) { - margin: 1rem 0.1rem; -} - -label { - margin: 0.5rem 0.1rem; -} - -:is(h1, h2, h3, h4, h5, h6, p, label):first-child { - margin-top: 0; -} - -:is(h1, h2, h3, h4, h5, h6, p, label):last-child { - margin-bottom: 0; -} - -a { - color: var(--link); -} - -a:hover { - color: var(--link-hover); -} - -a:active { - color: var(--link-active); -} - -label { - display: flex; - gap: 0.5rem; - align-items: center; -} - -label input { - margin: 0; -} - -button, -input, -select { - font-family: inherit; - font-size: inherit; -} - -button { - background: var(--link); - color: var(--bg-1); - padding: 0.5rem 1rem; - border: none; - border-radius: var(--border-radius); -} - -button:hover { - background: var(--link-hover); -} - -button:active { - background: var(--link-active); -} - -:is(button, button:hover, button:active):disabled { - background: var(--link); - filter: grayscale(1); - opacity: 0.4; -} - -input, -textarea, -select { - padding: 0.5rem; - border: 1px solid var(--bg-2); - border-radius: var(--border-radius); - box-sizing: border-box; -} - -input, -textarea { - background: var(--bg-1); -} - -select:not([multiple]) { - background: var(--bg-2); -} - -textarea { - font-family: var(--font-mono); - font-size: 0.9rem; -} - -form { - display: flex; - flex-direction: column; - gap: 1rem; - align-items: baseline; -} - -ul:has(li):has(form) { - list-style: none; - padding: 0; -} - -li form { - flex-direction: row; - gap: 0.5rem; - margin: 0.5rem 0; -} - -nav { - position: relative; - display: flex; - gap: 1em; - padding: 1em; - background: var(--bg-2); - z-index: 2; - margin: 0 0 1em 0; - border-radius: var(--border-radius); -} - -nav a { - text-decoration: none; -} - -nav a[aria-current='true'] { - border-bottom: 2px solid; -} - -ul:has(form) { - list-style: none; - padding: 0; -} - -progress { - margin: 0.5rem 0; -} - -progress:first-child { - margin-top: 0; -} - -progress:lsat-child { - margin-bottom: 0; -} - -.error { - color: red; -} - -code { - background: var(--bg-2); - font-family: var(--font-mono); - font-size: 0.9em; - padding: 0.15rem 0.3rem; - border-radius: var(--border-radius); -} - -ul.todos { - padding: 0; -} - -ul.todos li:not(:has(> form)), -ul.todos li form { - position: relative; - display: flex; - align-items: center; - padding: 0.5em 0.5em 0.5em 1em; - margin: 0 0 0.5em 0; - gap: 0.5em; - border-radius: 5px; - user-select: none; - background: var(--bg-1); - filter: drop-shadow(2px 3px 6px rgba(0, 0, 0, 0.1)); - transition: - filter 0.2s, - opacity 0.2s; -} - -ul.todos .done { - filter: none; - opacity: 0.4; -} - -ul.todos button { - border: none; - background-color: transparent; - background-repeat: no-repeat; - background-position: 50% 50%; - background-size: 1rem 1rem; - cursor: pointer; - width: 3em; - height: 3em; - margin: -0.5em -0.5em -0.5em 0; - aspect-ratio: 1; - opacity: 0.5; - transition: opacity 0.2s; -} - -ul.todos button:hover { - opacity: 1; -} - -body.dark { - --bg-1: hsl(0, 0%, 18%); - --bg-2: hsl(0, 0%, 30%); - --bg-3: hsl(0, 0%, 40%); - --fg-1: hsl(0, 0%, 90%); - --fg-2: hsl(0, 0%, 70%); - --fg-3: hsl(0, 0%, 60%); - --link: hsl(206, 96%, 72%); - --link-hover: hsl(206, 96%, 78%); - --link-active: hsl(206, 96%, 64%); -} +h1 { + font-family: 'Cairo'; +} \ No newline at end of file From 1726a1c757f4239f65de088168afd575485318a9 Mon Sep 17 00:00:00 2001 From: Rogerio Amorim Date: Thu, 18 Jan 2024 15:23:27 -0300 Subject: [PATCH 06/13] add test --- .../semicolon-inside-quotes/input.svelte | 7 ++ .../semicolon-inside-quotes/output.json | 72 +++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 packages/svelte/tests/parser-modern/samples/semicolon-inside-quotes/input.svelte create mode 100644 packages/svelte/tests/parser-modern/samples/semicolon-inside-quotes/output.json diff --git a/packages/svelte/tests/parser-modern/samples/semicolon-inside-quotes/input.svelte b/packages/svelte/tests/parser-modern/samples/semicolon-inside-quotes/input.svelte new file mode 100644 index 000000000000..87932ca32632 --- /dev/null +++ b/packages/svelte/tests/parser-modern/samples/semicolon-inside-quotes/input.svelte @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/packages/svelte/tests/parser-modern/samples/semicolon-inside-quotes/output.json b/packages/svelte/tests/parser-modern/samples/semicolon-inside-quotes/output.json new file mode 100644 index 000000000000..2cf3b6a8bf0d --- /dev/null +++ b/packages/svelte/tests/parser-modern/samples/semicolon-inside-quotes/output.json @@ -0,0 +1,72 @@ +{ + "css": { + "type": "Style", + "start": 0, + "end": 137, + "attributes": [], + "children": [ + { + "type": "Atrule", + "start": 9, + "end": 97, + "name": "import", + "prelude": "url('https://fonts.googleapis.com/css2?family=Cairo:wght@400;700&display=swap')", + "block": null + }, + { + "type": "Rule", + "prelude": { + "type": "SelectorList", + "start": 100, + "end": 102, + "children": [ + { + "type": "Selector", + "start": 100, + "end": 102, + "children": [ + { + "type": "TypeSelector", + "name": "h1", + "start": 100, + "end": 102 + } + ] + } + ] + }, + "block": { + "type": "Block", + "start": 103, + "end": 128, + "children": [ + { + "type": "Declaration", + "start": 107, + "end": 124, + "property": "font-weight", + "value": "bold" + } + ] + }, + "start": 100, + "end": 128 + } + ], + "content": { + "start": 7, + "end": 129, + "styles": "\n\t@import url('https://fonts.googleapis.com/css2?family=Cairo:wght@400;700&display=swap');\n\n\th1 {\n\t\tfont-weight: bold;\n\t}\n" + } + }, + "js": [], + "start": null, + "end": null, + "type": "Root", + "fragment": { + "type": "Fragment", + "nodes": [], + "transparent": false + }, + "options": null +} From 6faac2fb56e001230b2c28131b78ec7c848f8a87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rog=C3=A9rio=20Luiz=20Aques=20de=20Amorim?= Date: Thu, 18 Jan 2024 15:25:05 -0300 Subject: [PATCH 07/13] Update .changeset/seven-hornets-smile.md Co-authored-by: navorite --- .changeset/seven-hornets-smile.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/seven-hornets-smile.md b/.changeset/seven-hornets-smile.md index 98dc9c466923..262f4757b102 100644 --- a/.changeset/seven-hornets-smile.md +++ b/.changeset/seven-hornets-smile.md @@ -2,4 +2,4 @@ "svelte": patch --- -fix parsing error when using semicolon inside quotes on component's style tag +fix: improve at-rule parsing From 05350430c8eec8531fd89fa8c62c1fe5b449e6ea Mon Sep 17 00:00:00 2001 From: Rogerio Amorim Date: Thu, 18 Jan 2024 15:26:08 -0300 Subject: [PATCH 08/13] undo demo.css change --- playgrounds/demo/demo.css | 249 +++++++++++++++++++++++++++++++++++++- 1 file changed, 246 insertions(+), 3 deletions(-) diff --git a/playgrounds/demo/demo.css b/playgrounds/demo/demo.css index 75bfe420145f..5cfdeb0dd666 100644 --- a/playgrounds/demo/demo.css +++ b/playgrounds/demo/demo.css @@ -1,3 +1,246 @@ -h1 { - font-family: 'Cairo'; -} \ No newline at end of file +body { + --bg-1: hsl(0, 0%, 100%); + --bg-2: hsl(206, 20%, 90%); + --bg-3: hsl(206, 20%, 80%); + --fg-1: hsl(0, 0%, 13%); + --fg-2: hsl(0, 0%, 20%); + --fg-2: hsl(0, 0%, 30%); + --link: hsl(208, 77%, 47%); + --link-hover: hsl(208, 77%, 55%); + --link-active: hsl(208, 77%, 40%); + --border-radius: 4px; + --font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, + 'Open Sans', 'Helvetica Neue', sans-serif; + --font-mono: ui-monospace, 'Cascadia Code', 'Source Code Pro', Menlo, Consolas, 'DejaVu Sans Mono', + monospace; + background: var(--bg-1); + color: var(--fg-1); + font-family: var(--font); + line-height: 1.5; + margin: 1rem; + height: calc(100vh - 2rem); +} + +h1, +h2, +h3, +h4, +h5, +h6 { + font-weight: normal; + font-variant-numeric: tabular-nums; + line-height: 1.1; +} + +:is(h1, h2, h3, h4, h5, h6, p) { + margin: 1rem 0.1rem; +} + +label { + margin: 0.5rem 0.1rem; +} + +:is(h1, h2, h3, h4, h5, h6, p, label):first-child { + margin-top: 0; +} + +:is(h1, h2, h3, h4, h5, h6, p, label):last-child { + margin-bottom: 0; +} + +a { + color: var(--link); +} + +a:hover { + color: var(--link-hover); +} + +a:active { + color: var(--link-active); +} + +label { + display: flex; + gap: 0.5rem; + align-items: center; +} + +label input { + margin: 0; +} + +button, +input, +select { + font-family: inherit; + font-size: inherit; +} + +button { + background: var(--link); + color: var(--bg-1); + padding: 0.5rem 1rem; + border: none; + border-radius: var(--border-radius); +} + +button:hover { + background: var(--link-hover); +} + +button:active { + background: var(--link-active); +} + +:is(button, button:hover, button:active):disabled { + background: var(--link); + filter: grayscale(1); + opacity: 0.4; +} + +input, +textarea, +select { + padding: 0.5rem; + border: 1px solid var(--bg-2); + border-radius: var(--border-radius); + box-sizing: border-box; +} + +input, +textarea { + background: var(--bg-1); +} + +select:not([multiple]) { + background: var(--bg-2); +} + +textarea { + font-family: var(--font-mono); + font-size: 0.9rem; +} + +form { + display: flex; + flex-direction: column; + gap: 1rem; + align-items: baseline; +} + +ul:has(li):has(form) { + list-style: none; + padding: 0; +} + +li form { + flex-direction: row; + gap: 0.5rem; + margin: 0.5rem 0; +} + +nav { + position: relative; + display: flex; + gap: 1em; + padding: 1em; + background: var(--bg-2); + z-index: 2; + margin: 0 0 1em 0; + border-radius: var(--border-radius); +} + +nav a { + text-decoration: none; +} + +nav a[aria-current='true'] { + border-bottom: 2px solid; +} + +ul:has(form) { + list-style: none; + padding: 0; +} + +progress { + margin: 0.5rem 0; +} + +progress:first-child { + margin-top: 0; +} + +progress:lsat-child { + margin-bottom: 0; +} + +.error { + color: red; +} + +code { + background: var(--bg-2); + font-family: var(--font-mono); + font-size: 0.9em; + padding: 0.15rem 0.3rem; + border-radius: var(--border-radius); +} + +ul.todos { + padding: 0; +} + +ul.todos li:not(:has(> form)), +ul.todos li form { + position: relative; + display: flex; + align-items: center; + padding: 0.5em 0.5em 0.5em 1em; + margin: 0 0 0.5em 0; + gap: 0.5em; + border-radius: 5px; + user-select: none; + background: var(--bg-1); + filter: drop-shadow(2px 3px 6px rgba(0, 0, 0, 0.1)); + transition: + filter 0.2s, + opacity 0.2s; +} + +ul.todos .done { + filter: none; + opacity: 0.4; +} + +ul.todos button { + border: none; + background-color: transparent; + background-repeat: no-repeat; + background-position: 50% 50%; + background-size: 1rem 1rem; + cursor: pointer; + width: 3em; + height: 3em; + margin: -0.5em -0.5em -0.5em 0; + aspect-ratio: 1; + opacity: 0.5; + transition: opacity 0.2s; +} + +ul.todos button:hover { + opacity: 1; +} + +body.dark { + --bg-1: hsl(0, 0%, 18%); + --bg-2: hsl(0, 0%, 30%); + --bg-3: hsl(0, 0%, 40%); + --fg-1: hsl(0, 0%, 90%); + --fg-2: hsl(0, 0%, 70%); + --fg-3: hsl(0, 0%, 60%); + --link: hsl(206, 96%, 72%); + --link-hover: hsl(206, 96%, 78%); + --link-active: hsl(206, 96%, 64%); +} From dbf8078c620611d6a076ebf3ab65d43016086fda Mon Sep 17 00:00:00 2001 From: Rogerio Luiz Aques de Amorim Date: Fri, 19 Jan 2024 10:35:25 -0300 Subject: [PATCH 09/13] fix support-font-face test not passing --- packages/svelte/src/compiler/phases/1-parse/read/style.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 955c10ef8419..6ed218ce80fb 100644 --- a/packages/svelte/src/compiler/phases/1-parse/read/style.js +++ b/packages/svelte/src/compiler/phases/1-parse/read/style.js @@ -9,7 +9,7 @@ const REGEX_PERCENTAGE = /^\d+(\.\d+)?%/; const REGEX_NTH_OF = /^(even|odd|\+?(\d+|\d*n(\s*[+-]\s*\d+)?)|-\d*n(\s*\+\s*\d+))((?=\s*[,)])|\s+of\s+)/; const REGEX_WHITESPACE_OR_COLON = /[\s:]/; -const REGEX_BRACE_OR_SEMICOLON = /[{;](?=[^"']*$)/; +const REGEX_BRACE_OR_SEMICOLON = /[{;](?=(?:[^']*'[^']*')*[^']*$)/; const REGEX_LEADING_HYPHEN_OR_DIGIT = /-?\d/; const REGEX_VALID_IDENTIFIER_CHAR = /[a-zA-Z0-9_-]/; const REGEX_COMMENT_CLOSE = /\*\//; From b845535327c3cec5d8e422726434e828b17b36e9 Mon Sep 17 00:00:00 2001 From: n0n3br Date: Fri, 19 Jan 2024 13:45:32 -0300 Subject: [PATCH 10/13] add double quotes --- .../src/compiler/phases/1-parse/read/style.js | 2 +- .../semicolon-inside-quotes/input.svelte | 6 +- .../semicolon-inside-quotes/output.json | 76 +++++++++++++------ 3 files changed, 57 insertions(+), 27 deletions(-) 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 6ed218ce80fb..dc17583211d7 100644 --- a/packages/svelte/src/compiler/phases/1-parse/read/style.js +++ b/packages/svelte/src/compiler/phases/1-parse/read/style.js @@ -9,7 +9,7 @@ const REGEX_PERCENTAGE = /^\d+(\.\d+)?%/; const REGEX_NTH_OF = /^(even|odd|\+?(\d+|\d*n(\s*[+-]\s*\d+)?)|-\d*n(\s*\+\s*\d+))((?=\s*[,)])|\s+of\s+)/; const REGEX_WHITESPACE_OR_COLON = /[\s:]/; -const REGEX_BRACE_OR_SEMICOLON = /[{;](?=(?:[^']*'[^']*')*[^']*$)/; +const REGEX_BRACE_OR_SEMICOLON = /[{;](?=(?:[^'"]*'[^'"]*')*[^'"]*$)/; const REGEX_LEADING_HYPHEN_OR_DIGIT = /-?\d/; const REGEX_VALID_IDENTIFIER_CHAR = /[a-zA-Z0-9_-]/; const REGEX_COMMENT_CLOSE = /\*\//; diff --git a/packages/svelte/tests/parser-modern/samples/semicolon-inside-quotes/input.svelte b/packages/svelte/tests/parser-modern/samples/semicolon-inside-quotes/input.svelte index 87932ca32632..1aed29f5a134 100644 --- a/packages/svelte/tests/parser-modern/samples/semicolon-inside-quotes/input.svelte +++ b/packages/svelte/tests/parser-modern/samples/semicolon-inside-quotes/input.svelte @@ -1,6 +1,8 @@ +

+ Semicolon inside quotes +

\ No newline at end of file + diff --git a/packages/svelte/tests/parser-modern/samples/semicolon-inside-quotes/output.json b/packages/svelte/tests/parser-modern/samples/semicolon-inside-quotes/output.json index dadcef3fd558..c6fbb599c7f0 100644 --- a/packages/svelte/tests/parser-modern/samples/semicolon-inside-quotes/output.json +++ b/packages/svelte/tests/parser-modern/samples/semicolon-inside-quotes/output.json @@ -2,7 +2,7 @@ "css": { "type": "Style", "start": 36, - "end": 174, + "end": 205, "attributes": [], "children": [ { @@ -38,7 +38,7 @@ "block": { "type": "Block", "start": 140, - "end": 165, + "end": 196, "children": [ { "type": "Declaration", @@ -46,17 +46,24 @@ "end": 161, "property": "font-weight", "value": "bold" + }, + { + "type": "Declaration", + "start": 165, + "end": 192, + "property": "background", + "value": "url(\"whatever\")" } ] }, "start": 137, - "end": 165 + "end": 196 } ], "content": { "start": 43, - "end": 166, - "styles": "\n\t@import url(\"https://fonts.googleapis.com/css2?family=Poppins:wght@400;700&display=swap\");\n\th1 {\n\t\tfont-weight: bold;\n\t}\n" + "end": 197, + "styles": "\n\t@import url(\"https://fonts.googleapis.com/css2?family=Poppins:wght@400;700&display=swap\");\n\th1 {\n\t\tfont-weight: bold;\n\t\tbackground: url(\"whatever\");\n\t}\n" } }, "js": [], @@ -97,4 +104,4 @@ "transparent": false }, "options": null -} \ No newline at end of file +} From fddaad3ceefe32e6c27aae7b5ade1c913daf2f6f Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 25 Jan 2024 20:12:58 -0500 Subject: [PATCH 12/13] robustify parsing --- .../svelte/src/compiler/phases/1-parse/read/style.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) 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 dc17583211d7..ff9f9a8fecca 100644 --- a/packages/svelte/src/compiler/phases/1-parse/read/style.js +++ b/packages/svelte/src/compiler/phases/1-parse/read/style.js @@ -9,7 +9,6 @@ const REGEX_PERCENTAGE = /^\d+(\.\d+)?%/; const REGEX_NTH_OF = /^(even|odd|\+?(\d+|\d*n(\s*[+-]\s*\d+)?)|-\d*n(\s*\+\s*\d+))((?=\s*[,)])|\s+of\s+)/; const REGEX_WHITESPACE_OR_COLON = /[\s:]/; -const REGEX_BRACE_OR_SEMICOLON = /[{;](?=(?:[^'"]*'[^'"]*')*[^'"]*$)/; const REGEX_LEADING_HYPHEN_OR_DIGIT = /-?\d/; const REGEX_VALID_IDENTIFIER_CHAR = /[a-zA-Z0-9_-]/; const REGEX_COMMENT_CLOSE = /\*\//; @@ -79,7 +78,7 @@ function read_at_rule(parser) { const name = read_identifier(parser); - const prelude = parser.read_until(REGEX_BRACE_OR_SEMICOLON).trim(); + const prelude = read_value(parser); /** @type {import('#compiler').Css.Block | null} */ let block = null; @@ -398,7 +397,7 @@ function read_declaration(parser) { parser.eat(':'); parser.allow_whitespace(); - const value = read_declaration_value(parser); + const value = read_value(parser); const end = parser.index; @@ -419,7 +418,7 @@ function read_declaration(parser) { * @param {import('../index.js').Parser} parser * @returns {string} */ -function read_declaration_value(parser) { +function read_value(parser) { let value = ''; let escaped = false; let in_url = false; @@ -443,7 +442,7 @@ function read_declaration_value(parser) { quote_mark = char; } else if (char === '(' && value.slice(-3) === 'url') { in_url = true; - } else if ((char === ';' || char === '}') && !in_url && !quote_mark) { + } else if ((char === ';' || char === '{' || char === '}') && !in_url && !quote_mark) { return value.trim(); } From a7226db416bbc2ce5651c1bb603338d38fd016f2 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 25 Jan 2024 20:14:06 -0500 Subject: [PATCH 13/13] Update .changeset/seven-hornets-smile.md --- .changeset/seven-hornets-smile.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/seven-hornets-smile.md b/.changeset/seven-hornets-smile.md index 262f4757b102..7ae0106acb91 100644 --- a/.changeset/seven-hornets-smile.md +++ b/.changeset/seven-hornets-smile.md @@ -2,4 +2,4 @@ "svelte": patch --- -fix: improve at-rule parsing +fix: correctly parse at-rules containing special characters in strings