From e881013a7908e968f626015613db583b0058e104 Mon Sep 17 00:00:00 2001 From: 7nik Date: Thu, 19 Jun 2025 11:16:05 +0300 Subject: [PATCH 1/2] fix: address css class matching regression --- .changeset/big-carpets-stare.md | 5 +++++ .../phases/2-analyze/css/css-prune.js | 21 +++++++++++++------ .../css/samples/class-directive/_config.js | 8 +++---- .../css/samples/class-directive/expected.css | 1 + .../css/samples/class-directive/input.svelte | 3 ++- 5 files changed, 27 insertions(+), 11 deletions(-) create mode 100644 .changeset/big-carpets-stare.md diff --git a/.changeset/big-carpets-stare.md b/.changeset/big-carpets-stare.md new file mode 100644 index 000000000000..eabe29bb887e --- /dev/null +++ b/.changeset/big-carpets-stare.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: address css class matching regression diff --git a/packages/svelte/src/compiler/phases/2-analyze/css/css-prune.js b/packages/svelte/src/compiler/phases/2-analyze/css/css-prune.js index b9a5688a87d0..79e8fbb02c08 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/css/css-prune.js +++ b/packages/svelte/src/compiler/phases/2-analyze/css/css-prune.js @@ -628,10 +628,11 @@ function attribute_matches(node, name, expected_value, operator, case_insensitiv if (attribute.type === 'SpreadAttribute') return true; if (attribute.type === 'BindDirective' && attribute.name === name) return true; + const name_lower = name.toLowerCase(); // match attributes against the corresponding directive but bail out on exact matching - if (attribute.type === 'StyleDirective' && name.toLowerCase() === 'style') return true; - if (attribute.type === 'ClassDirective' && name.toLowerCase() === 'class') { - if (operator == '~=') { + if (attribute.type === 'StyleDirective' && name_lower === 'style') return true; + if (attribute.type === 'ClassDirective' && name_lower === 'class') { + if (operator === '~=') { if (attribute.name === expected_value) return true; } else { return true; @@ -639,13 +640,21 @@ function attribute_matches(node, name, expected_value, operator, case_insensitiv } if (attribute.type !== 'Attribute') continue; - if (attribute.name.toLowerCase() !== name.toLowerCase()) continue; + if (attribute.name.toLowerCase() !== name_lower) continue; if (attribute.value === true) return operator === null; if (expected_value === null) return true; if (is_text_attribute(attribute)) { - return test_attribute(operator, expected_value, case_insensitive, attribute.value[0].data); + const matches = test_attribute( + operator, + expected_value, + case_insensitive, + attribute.value[0].data + ); + // continue if we still may match against a class/style directive + if (!matches && (name_lower === 'class' || name_lower === 'style')) continue; + return matches; } const chunks = get_attribute_chunks(attribute.value); @@ -654,7 +663,7 @@ function attribute_matches(node, name, expected_value, operator, case_insensitiv /** @type {string[]} */ let prev_values = []; for (const chunk of chunks) { - const current_possible_values = get_possible_values(chunk, name === 'class'); + const current_possible_values = get_possible_values(chunk, name_lower === 'class'); // impossible to find out all combinations if (!current_possible_values) return true; diff --git a/packages/svelte/tests/css/samples/class-directive/_config.js b/packages/svelte/tests/css/samples/class-directive/_config.js index 28e9fbc81512..51da130d840f 100644 --- a/packages/svelte/tests/css/samples/class-directive/_config.js +++ b/packages/svelte/tests/css/samples/class-directive/_config.js @@ -6,14 +6,14 @@ export default test({ code: 'css_unused_selector', message: 'Unused CSS selector ".third"\nhttps://svelte.dev/e/css_unused_selector', start: { - line: 6, + line: 7, column: 2, - character: 115 + character: 166 }, end: { - line: 6, + line: 7, column: 8, - character: 121 + character: 172 } } ] diff --git a/packages/svelte/tests/css/samples/class-directive/expected.css b/packages/svelte/tests/css/samples/class-directive/expected.css index 1d7d3d4dee61..3b2cf83c306b 100644 --- a/packages/svelte/tests/css/samples/class-directive/expected.css +++ b/packages/svelte/tests/css/samples/class-directive/expected.css @@ -1,3 +1,4 @@ .first.svelte-xyz { color: green } .second.svelte-xyz { color: green } + .zero.first.second.svelte-xyz { color: green } /* (unused) .third { color: red }*/ diff --git a/packages/svelte/tests/css/samples/class-directive/input.svelte b/packages/svelte/tests/css/samples/class-directive/input.svelte index cf0033596415..e387b50c49da 100644 --- a/packages/svelte/tests/css/samples/class-directive/input.svelte +++ b/packages/svelte/tests/css/samples/class-directive/input.svelte @@ -1,7 +1,8 @@ -
+
\ No newline at end of file From 8d9ce53d35780d0744be087f5e482ba3359bad2f Mon Sep 17 00:00:00 2001 From: 7nik Date: Thu, 19 Jun 2025 12:45:27 +0300 Subject: [PATCH 2/2] address feedback --- .../tests/css/samples/class-directive/_config.js | 10 +++++----- .../tests/css/samples/class-directive/expected.css | 7 ++++--- .../tests/css/samples/class-directive/input.svelte | 9 +++++---- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/packages/svelte/tests/css/samples/class-directive/_config.js b/packages/svelte/tests/css/samples/class-directive/_config.js index 51da130d840f..abeb8b632994 100644 --- a/packages/svelte/tests/css/samples/class-directive/_config.js +++ b/packages/svelte/tests/css/samples/class-directive/_config.js @@ -4,16 +4,16 @@ export default test({ warnings: [ { code: 'css_unused_selector', - message: 'Unused CSS selector ".third"\nhttps://svelte.dev/e/css_unused_selector', + message: 'Unused CSS selector ".forth"\nhttps://svelte.dev/e/css_unused_selector', start: { - line: 7, + line: 8, column: 2, - character: 166 + character: 190 }, end: { - line: 7, + line: 8, column: 8, - character: 172 + character: 196 } } ] diff --git a/packages/svelte/tests/css/samples/class-directive/expected.css b/packages/svelte/tests/css/samples/class-directive/expected.css index 3b2cf83c306b..b3a74baee5c0 100644 --- a/packages/svelte/tests/css/samples/class-directive/expected.css +++ b/packages/svelte/tests/css/samples/class-directive/expected.css @@ -1,4 +1,5 @@ - .first.svelte-xyz { color: green } + + .zero.first.svelte-xyz { color: green } .second.svelte-xyz { color: green } - .zero.first.second.svelte-xyz { color: green } - /* (unused) .third { color: red }*/ + .third.svelte-xyz { color: green } + /* (unused) .forth { color: red }*/ diff --git a/packages/svelte/tests/css/samples/class-directive/input.svelte b/packages/svelte/tests/css/samples/class-directive/input.svelte index e387b50c49da..70075f89d49d 100644 --- a/packages/svelte/tests/css/samples/class-directive/input.svelte +++ b/packages/svelte/tests/css/samples/class-directive/input.svelte @@ -1,8 +1,9 @@ -
+
+
\ No newline at end of file pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy