fix: don't wrap pseudo classes inside `:global(...)` with another `:global(...)` (#14267)

fixes #14088
gh-14204
Simon H 1 month ago committed by GitHub
parent 4a85c4157d
commit 36ece1c381
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: don't wrap pseudo classes inside `:global(...)` with another `:global(...)` during migration

@ -40,9 +40,10 @@ class MigrationError extends Error {
*/ */
function migrate_css(state) { function migrate_css(state) {
if (!state.analysis.css.ast?.start) return; if (!state.analysis.css.ast?.start) return;
let code = state.str const css_contents = state.str
.snip(state.analysis.css.ast.start, /** @type {number} */ (state.analysis.css.ast?.end)) .snip(state.analysis.css.ast.start, /** @type {number} */ (state.analysis.css.ast?.end))
.toString(); .toString();
let code = css_contents;
let starting = 0; let starting = 0;
// since we already blank css we can't work directly on `state.str` so we will create a copy that we can update // since we already blank css we can't work directly on `state.str` so we will create a copy that we can update
@ -56,23 +57,28 @@ function migrate_css(state) {
) { ) {
let start = code.indexOf('(') + 1; let start = code.indexOf('(') + 1;
let is_global = false; let is_global = false;
const global_str = ':global'; const global_str = ':global';
const next_global = code.indexOf(global_str); const next_global = code.indexOf(global_str);
const str_between = code.substring(start, next_global); const str_between = code.substring(start, next_global);
if (!str_between.trim()) { if (!str_between.trim()) {
is_global = true; is_global = true;
start += global_str.length; start += global_str.length;
} else {
const prev_global = css_contents.lastIndexOf(global_str, starting);
if (prev_global > -1) {
const end =
find_closing_parenthesis(css_contents.indexOf('(', prev_global) + 1, css_contents) -
starting;
if (end > start) {
starting += end;
code = code.substring(end);
continue;
}
}
} }
let parenthesis = 1;
let end = start; const end = find_closing_parenthesis(start, code);
let char = code[end];
// find the closing parenthesis
while (parenthesis !== 0 && char) {
if (char === '(') parenthesis++;
if (char === ')') parenthesis--;
end++;
char = code[end];
}
if (start && end) { if (start && end) {
if (!is_global && !code.startsWith(':not')) { if (!is_global && !code.startsWith(':not')) {
str.prependLeft(starting + start, ':global('); str.prependLeft(starting + start, ':global(');
@ -89,6 +95,24 @@ function migrate_css(state) {
state.str.update(state.analysis.css.ast?.start, state.analysis.css.ast?.end, str.toString()); state.str.update(state.analysis.css.ast?.start, state.analysis.css.ast?.end, str.toString());
} }
/**
* @param {number} start
* @param {string} code
*/
function find_closing_parenthesis(start, code) {
let parenthesis = 1;
let end = start;
let char = code[end];
// find the closing parenthesis
while (parenthesis !== 0 && char) {
if (char === '(') parenthesis++;
if (char === ')') parenthesis--;
end++;
char = code[end];
}
return end;
}
/** /**
* Does a best-effort migration of Svelte code towards using runes, event attributes and render tags. * Does a best-effort migration of Svelte code towards using runes, event attributes and render tags.
* May throw an error if the code is too complex to migrate automatically. * May throw an error if the code is too complex to migrate automatically.

@ -47,6 +47,8 @@ what if i'm talking about `:has()` in my blog?
div :where(:global(.class:is(span:has(* > *)))){} div :where(:global(.class:is(span:has(* > *)))){}
div :is(:global(.class:is(span:is(:hover)), .x)){} div :is(:global(.class:is(span:is(:hover)), .x)){}
:global(button:has(.is-active)){}
div{ div{
p:has(&){ p:has(&){

@ -47,6 +47,8 @@ what if i'm talking about `:has()` in my blog?
div :where(:global(.class:is(span:has(* > *)))){} div :where(:global(.class:is(span:has(* > *)))){}
div :is(:global(.class:is(span:is(:hover)), .x)){} div :is(:global(.class:is(span:is(:hover)), .x)){}
:global(button:has(.is-active)){}
div{ div{
p:has(:global(&)){ p:has(:global(&)){

Loading…
Cancel
Save