From afbda369a15970fd6c282d860800a946d0ca10ae Mon Sep 17 00:00:00 2001 From: daiwei Date: Wed, 23 Oct 2024 18:01:30 +0800 Subject: [PATCH 1/5] fix(compiler-sfc): properly rewrite :is with non-pseudo selector --- packages/compiler-sfc/__tests__/compileStyle.spec.ts | 6 ++++++ packages/compiler-sfc/src/style/pluginScoped.ts | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/compiler-sfc/__tests__/compileStyle.spec.ts b/packages/compiler-sfc/__tests__/compileStyle.spec.ts index b76414364dc..d6687a6b4d1 100644 --- a/packages/compiler-sfc/__tests__/compileStyle.spec.ts +++ b/packages/compiler-sfc/__tests__/compileStyle.spec.ts @@ -243,6 +243,12 @@ color: red } .div[data-v-test]:is(.foo:hover) { color: blue; }"`) + + expect(compileScoped(`#app :is(.foo) { color: red; }`)) + .toMatchInlineSnapshot(` + "#app :is(.foo[data-v-test]) { color: red; + }" + `) }) test('media query', () => { diff --git a/packages/compiler-sfc/src/style/pluginScoped.ts b/packages/compiler-sfc/src/style/pluginScoped.ts index b0224cf20d8..130ea1e3c75 100644 --- a/packages/compiler-sfc/src/style/pluginScoped.ts +++ b/packages/compiler-sfc/src/style/pluginScoped.ts @@ -225,7 +225,7 @@ function rewriteSelector( (n.type !== 'pseudo' && n.type !== 'combinator') || (n.type === 'pseudo' && (n.value === ':is' || n.value === ':where') && - !node) + (!node || !n.nodes.some(n => n.nodes.some(x => x.type === 'pseudo')))) ) { node = n } From 8d9f49c9658370ad337a5a9ed327b1cb93cbbf55 Mon Sep 17 00:00:00 2001 From: daiwei Date: Tue, 20 May 2025 21:48:48 +0800 Subject: [PATCH 2/5] test: add more tests --- .../__tests__/compileStyle.spec.ts | 18 ++++++++++++++++++ .../compiler-sfc/src/style/pluginScoped.ts | 9 ++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/packages/compiler-sfc/__tests__/compileStyle.spec.ts b/packages/compiler-sfc/__tests__/compileStyle.spec.ts index d6687a6b4d1..af8c874c5f5 100644 --- a/packages/compiler-sfc/__tests__/compileStyle.spec.ts +++ b/packages/compiler-sfc/__tests__/compileStyle.spec.ts @@ -249,6 +249,24 @@ color: red "#app :is(.foo[data-v-test]) { color: red; }" `) + + expect(compileScoped(`#app :is(:is(.foo)) { color: red; }`)) + .toMatchInlineSnapshot(` + "#app :is(:is(.foo[data-v-test])) { color: red; + }" + `) + + expect(compileScoped(`#app :where(.foo) { color: red; }`)) + .toMatchInlineSnapshot(` + "#app :where(.foo[data-v-test]) { color: red; + }" + `) + + expect(compileScoped(`#app :where(:where(.foo)) { color: red; }`)) + .toMatchInlineSnapshot(` + "#app :where(:where(.foo[data-v-test])) { color: red; + }" + `) }) test('media query', () => { diff --git a/packages/compiler-sfc/src/style/pluginScoped.ts b/packages/compiler-sfc/src/style/pluginScoped.ts index 130ea1e3c75..375993479be 100644 --- a/packages/compiler-sfc/src/style/pluginScoped.ts +++ b/packages/compiler-sfc/src/style/pluginScoped.ts @@ -225,7 +225,14 @@ function rewriteSelector( (n.type !== 'pseudo' && n.type !== 'combinator') || (n.type === 'pseudo' && (n.value === ':is' || n.value === ':where') && - (!node || !n.nodes.some(n => n.nodes.some(x => x.type === 'pseudo')))) + (!node || + n.nodes.some( + s => + // has nested :is or :where + s.nodes.some(x => x.type === n.type && x.value === n.value) || + // has non-pseudo selector + !s.nodes.some(x => x.type === 'pseudo'), + ))) ) { node = n } From 74dfcf7381057671e794fc94651e143f6b863b2a Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Tue, 20 May 2025 13:54:03 +0000 Subject: [PATCH 3/5] [autofix.ci] apply automated fixes --- packages/compiler-sfc/__tests__/compileStyle.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/compiler-sfc/__tests__/compileStyle.spec.ts b/packages/compiler-sfc/__tests__/compileStyle.spec.ts index 40e158f0c78..dcefa7332b7 100644 --- a/packages/compiler-sfc/__tests__/compileStyle.spec.ts +++ b/packages/compiler-sfc/__tests__/compileStyle.spec.ts @@ -247,7 +247,7 @@ color: red .div[data-v-test]:is(.foo:hover) { color: blue; }" `) - + expect(compileScoped(`#app :is(.foo) { color: red; }`)) .toMatchInlineSnapshot(` "#app :is(.foo[data-v-test]) { color: red; From 759d5b408a9344ebb2d1d2cb113ac32b5e825ff5 Mon Sep 17 00:00:00 2001 From: daiwei Date: Wed, 21 May 2025 08:21:37 +0800 Subject: [PATCH 4/5] test: add more tests --- .../compiler-sfc/__tests__/compileStyle.spec.ts | 12 ++++++++++++ packages/compiler-sfc/src/style/pluginScoped.ts | 16 +++++++++++----- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/packages/compiler-sfc/__tests__/compileStyle.spec.ts b/packages/compiler-sfc/__tests__/compileStyle.spec.ts index dcefa7332b7..0c595185c3d 100644 --- a/packages/compiler-sfc/__tests__/compileStyle.spec.ts +++ b/packages/compiler-sfc/__tests__/compileStyle.spec.ts @@ -271,6 +271,18 @@ color: red "#app :where(:where(.foo[data-v-test])) { color: red; }" `) + + expect(compileScoped(`#app :is(:where(.foo)) { color: red; }`)) + .toMatchInlineSnapshot(` + "#app :is(:where(.foo[data-v-test])) { color: red; + }" + `) + + expect(compileScoped(`#app :where(:is(.foo)) { color: red; }`)) + .toMatchInlineSnapshot(` + "#app :where(:is(.foo[data-v-test])) { color: red; + }" + `) }) test('media query', () => { diff --git a/packages/compiler-sfc/src/style/pluginScoped.ts b/packages/compiler-sfc/src/style/pluginScoped.ts index fe323b47a6c..57f6a580afc 100644 --- a/packages/compiler-sfc/src/style/pluginScoped.ts +++ b/packages/compiler-sfc/src/style/pluginScoped.ts @@ -222,13 +222,12 @@ function rewriteSelector( if ( (n.type !== 'pseudo' && n.type !== 'combinator') || - (n.type === 'pseudo' && - (n.value === ':is' || n.value === ':where') && + (isPseudoClassIsOrWhere(n) && (!node || n.nodes.some( s => // has nested :is or :where - s.nodes.some(x => x.type === n.type && x.value === n.value) || + s.nodes.some(x => isPseudoClassIsOrWhere(x)) || // has non-pseudo selector !s.nodes.some(x => x.type === 'pseudo'), ))) @@ -250,8 +249,7 @@ function rewriteSelector( } if (node) { - const { type, value } = node as selectorParser.Node - if (type === 'pseudo' && (value === ':is' || value === ':where')) { + if (isPseudoClassIsOrWhere(node)) { ;(node as selectorParser.Pseudo).nodes.forEach(value => rewriteSelector(id, rule, value, selectorRoot, deep, slotted), ) @@ -288,6 +286,14 @@ function isSpaceCombinator(node: selectorParser.Node) { return node.type === 'combinator' && /^\s+$/.test(node.value) } +function isPseudoClassIsOrWhere( + node: selectorParser.Node, +): node is selectorParser.Pseudo { + return ( + node.type === 'pseudo' && (node.value === ':is' || node.value === ':where') + ) +} + function extractAndWrapNodes(parentNode: Rule | AtRule) { if (!parentNode.nodes) return const nodes = parentNode.nodes.filter( From 4e2c116770871b596a181cd5402497e33e5f22e8 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Sat, 24 May 2025 13:15:38 +0000 Subject: [PATCH 5/5] [autofix.ci] apply automated fixes --- packages/compiler-sfc/src/style/pluginScoped.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/compiler-sfc/src/style/pluginScoped.ts b/packages/compiler-sfc/src/style/pluginScoped.ts index 71758861eb4..262e3174d84 100644 --- a/packages/compiler-sfc/src/style/pluginScoped.ts +++ b/packages/compiler-sfc/src/style/pluginScoped.ts @@ -223,7 +223,9 @@ function rewriteSelector( } if ( - (n.type !== 'pseudo' && n.type !== 'combinator' && n.type !== 'universal') || + (n.type !== 'pseudo' && + n.type !== 'combinator' && + n.type !== 'universal') || (isPseudoClassIsOrWhere(n) && (!node || n.nodes.some(