Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 1 commit into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/hot-ladybugs-clap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte': patch
---

fix: don't wrap pseudo classes inside `:global(...)` with another `:global(...)` during migration
46 changes: 35 additions & 11 deletions packages/svelte/src/compiler/migrate/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,10 @@ class MigrationError extends Error {
*/
function migrate_css(state) {
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))
.toString();
let code = css_contents;
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
Expand All @@ -56,23 +57,28 @@ function migrate_css(state) {
) {
let start = code.indexOf('(') + 1;
let is_global = false;

const global_str = ':global';
const next_global = code.indexOf(global_str);
const str_between = code.substring(start, next_global);
if (!str_between.trim()) {
is_global = true;
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;
let char = code[end];
// find the closing parenthesis
while (parenthesis !== 0 && char) {
if (char === '(') parenthesis++;
if (char === ')') parenthesis--;
end++;
char = code[end];
}

const end = find_closing_parenthesis(start, code);
if (start && end) {
if (!is_global && !code.startsWith(':not')) {
str.prependLeft(starting + start, ':global(');
Expand All @@ -89,6 +95,24 @@ function migrate_css(state) {
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.
* May throw an error if the code is too complex to migrate automatically.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ what if i'm talking about `:has()` in my blog?
div :where(:global(.class:is(span:has(* > *)))){}
div :is(:global(.class:is(span:is(:hover)), .x)){}

:global(button:has(.is-active)){}

div{
p:has(&){

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ what if i'm talking about `:has()` in my blog?
div :where(:global(.class:is(span:has(* > *)))){}
div :is(:global(.class:is(span:is(:hover)), .x)){}

:global(button:has(.is-active)){}

div{
p:has(:global(&)){

Expand Down
Loading