Skip to content

Commit 324221b

Browse files
authored
Generate :is() within :is() and :has() (#2648)
1 parent 75555e6 commit 324221b

File tree

11 files changed

+756
-122
lines changed

11 files changed

+756
-122
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,16 @@
1010
* **Breaking change:** A variable definition may now only have a single
1111
`!global` flag or `!default` flag, or one of each.
1212

13+
* **Potentially breaking bug fix:** In some cases involving a `:has()` selector
14+
with a leading combinator being `@extend`ed by a selector that contained its
15+
own combinators, `@extend` used to generate incorrect selectors. This has been
16+
fixed.
17+
18+
* When extending selectors in `:is()`, `:has()`, or `:where()`, `@extend` will
19+
now generate `:is()` selectors rather than manually combining selectors, since
20+
there are no browser compatibility concerns in that context. This fixes
21+
several related extension bugs in this context.
22+
1323
### Bogus Combinators
1424

1525
* **Breaking change:** Selectors with more than one combinator in a row, such as

lib/src/ast/selector/list.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,16 @@ final class SelectorList extends Selector {
6363
/// [relative selector]: https://www.w3.org/TR/selectors-4/#relative-selector
6464
bool get isRelative => components.every((complex) => complex.isRelative);
6565

66+
/// If this selector list is composed of a single complex selector, returns
67+
/// it.
68+
///
69+
/// Otherwise, returns null.
70+
///
71+
/// @nodoc
72+
@internal
73+
ComplexSelector? get singleComplex =>
74+
components.length == 1 ? components.first : null;
75+
6676
/// Throws a [SassException] if `this` isn't a CSS selector that's valid in
6777
/// various places in the document, depending on the arguments passed.
6878
///

lib/src/ast/selector/pseudo.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,14 @@ final class PseudoSelector extends SimpleSelector {
119119
normalizedName = unvendor(name),
120120
super(span);
121121

122+
/// A shorthand for creating an `:is()` selector.
123+
///
124+
/// @nodoc
125+
@internal
126+
factory PseudoSelector.isSelector(
127+
Iterable<ComplexSelector> components, FileSpan span) =>
128+
PseudoSelector('is', span, selector: SelectorList(components, span));
129+
122130
/// Returns whether [name] is the name of a pseudo-element that can be written
123131
/// with pseudo-class syntax (`:before`, `:after`, `:first-line`, or
124132
/// `:first-letter`)

lib/src/extend/empty_extension_store.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,6 @@ final class EmptyExtensionStore implements ExtensionStore {
5555
EmptyExtensionStore(),
5656
{},
5757
);
58+
59+
void trimModernSelectors() {}
5860
}

0 commit comments

Comments
 (0)