Skip to content

Commit 6d65cd6

Browse files
committed
(WIP) fix: correctly mark :not selectors
1 parent 7dbe812 commit 6d65cd6

File tree

1 file changed

+37
-17
lines changed
  • packages/svelte/src/compiler/phases/2-analyze/css

1 file changed

+37
-17
lines changed

packages/svelte/src/compiler/phases/2-analyze/css/css-prune.js

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -489,14 +489,17 @@ function relative_selector_might_apply_to_node(relative_selector, rule, element,
489489
}
490490

491491
for (const selector of other_selectors) {
492-
if (selector.type === 'Percentage' || selector.type === 'Nth') continue;
492+
if (selector.type === 'Percentage' || selector.type === 'Nth') {
493+
if (state.inside_not) return true;
494+
continue;
495+
}
493496

494497
const name = selector.name.replace(regex_backslash_and_following_character, '$1');
495498

496499
switch (selector.type) {
497500
case 'PseudoClassSelector': {
498501
if (name === 'host' || name === 'root') {
499-
return false;
502+
return state.inside_not;
500503
}
501504

502505
if (
@@ -514,6 +517,7 @@ function relative_selector_might_apply_to_node(relative_selector, rule, element,
514517

515518
if ((name === 'is' || name === 'where' || name === 'not') && selector.args) {
516519
let matched = false;
520+
let didnt_match = false;
517521

518522
for (const complex_selector of selector.args.children) {
519523
const relative = truncate(complex_selector);
@@ -522,10 +526,12 @@ function relative_selector_might_apply_to_node(relative_selector, rule, element,
522526
if (is_global) {
523527
complex_selector.metadata.used = true;
524528
matched = true;
525-
} else if (name !== 'not' && apply_selector(relative, rule, element, state)) {
529+
didnt_match = true;
530+
} else if (apply_selector(relative, rule, element, { ...state, inside_not: true })) {
526531
complex_selector.metadata.used = true;
527532
matched = true;
528533
} else if (
534+
false &&
529535
name === 'not' &&
530536
!apply_selector(relative, rule, element, { ...state, inside_not: true })
531537
) {
@@ -554,9 +560,12 @@ function relative_selector_might_apply_to_node(relative_selector, rule, element,
554560
// The result may not match a real element, so the only drawback is the missing prune.
555561
complex_selector.metadata.used = true;
556562
matched = true;
563+
didnt_match = true;
557564
for (const selector of relative) {
558565
selector.metadata.scoped = true;
559566
}
567+
} else {
568+
didnt_match = true;
560569
}
561570
}
562571

@@ -578,21 +587,23 @@ function relative_selector_might_apply_to_node(relative_selector, rule, element,
578587
});
579588
}
580589

581-
return false;
590+
return state.inside_not && didnt_match;
582591
}
583592
}
584593

585594
break;
586595
}
587596

588597
case 'PseudoElementSelector': {
589-
break;
598+
return true;
590599
}
591600

592601
case 'AttributeSelector': {
593602
const whitelisted = whitelist_attribute_selector.get(element.name.toLowerCase());
603+
if (whitelisted?.includes(selector.name.toLowerCase())) {
604+
return true;
605+
}
594606
if (
595-
!whitelisted?.includes(selector.name.toLowerCase()) &&
596607
!attribute_matches(
597608
element,
598609
selector.name,
@@ -601,19 +612,20 @@ function relative_selector_might_apply_to_node(relative_selector, rule, element,
601612
selector.flags?.includes('i') ?? false
602613
)
603614
) {
604-
return false;
615+
return state.inside_not;
605616
}
617+
606618
break;
607619
}
608620

609621
case 'ClassSelector': {
610-
if (
611-
!attribute_matches(element, 'class', name, '~=', false) &&
612-
!element.attributes.some(
613-
(attribute) => attribute.type === 'ClassDirective' && attribute.name === name
614-
)
615-
) {
616-
return false;
622+
const matches_class_directive = element.attributes.some(
623+
(attribute) => attribute.type === 'ClassDirective' && attribute.name === name
624+
);
625+
if (!attribute_matches(element, 'class', name, '~=', false) && !matches_class_directive) {
626+
return state.inside_not;
627+
} else if (matches_class_directive) {
628+
return true;
617629
}
618630

619631
break;
@@ -633,26 +645,34 @@ function relative_selector_might_apply_to_node(relative_selector, rule, element,
633645
name !== '*' &&
634646
element.type !== 'SvelteElement'
635647
) {
636-
return false;
648+
return state.inside_not;
649+
} else if (element.type === 'SvelteElement' && state.inside_not) {
650+
return true;
637651
}
638652

639653
break;
640654
}
641655

642656
case 'NestingSelector': {
643657
let matched = false;
658+
let didnt_match = true;
644659

645660
const parent = /** @type {Compiler.Css.Rule} */ (rule.metadata.parent_rule);
646661

647662
for (const complex_selector of parent.prelude.children) {
648663
if (apply_selector(truncate(complex_selector), parent, element, state)) {
649664
complex_selector.metadata.used = true;
650665
matched = true;
666+
} else {
667+
didnt_match = true;
651668
}
652669
}
653670

654671
if (!matched) {
655-
return false;
672+
return state.inside_not;
673+
}
674+
if (state.inside_not && didnt_match) {
675+
return true;
656676
}
657677

658678
break;
@@ -661,7 +681,7 @@ function relative_selector_might_apply_to_node(relative_selector, rule, element,
661681
}
662682

663683
// possible match
664-
return true;
684+
return !state.inside_not;
665685
}
666686

667687
/**

0 commit comments

Comments
 (0)