5
5
import 'package:meta/meta.dart' ;
6
6
import 'package:source_span/source_span.dart' ;
7
7
8
- import '../deprecation.dart' ;
9
- import '../evaluation_context.dart' ;
10
- import '../exception.dart' ;
11
8
import '../visitor/any_selector.dart' ;
12
9
import '../visitor/interface/selector.dart' ;
13
10
import '../visitor/serialize.dart' ;
14
11
import 'node.dart' ;
15
- import 'selector/complex.dart' ;
16
12
import 'selector/list.dart' ;
17
13
import 'selector/placeholder.dart' ;
18
14
import 'selector/pseudo.dart' ;
@@ -47,58 +43,12 @@ abstract base class Selector implements AstNode {
47
43
///
48
44
/// @nodoc
49
45
@internal
50
- bool get isInvisible => accept (const _IsInvisibleVisitor (includeBogus: true ));
51
-
52
- // Whether this selector would be invisible even if it didn't have bogus
53
- // combinators.
54
- ///
55
- /// @nodoc
56
- @internal
57
- bool get isInvisibleOtherThanBogusCombinators =>
58
- accept (const _IsInvisibleVisitor (includeBogus: false ));
59
-
60
- /// Whether this selector is not valid CSS.
61
- ///
62
- /// This includes both selectors that are useful exclusively for build-time
63
- /// nesting (`> .foo)` and selectors with invalid combiantors that are still
64
- /// supported for backwards-compatibility reasons (`.foo + ~ .bar` ).
65
- bool get isBogus =>
66
- accept (const _IsBogusVisitor (includeLeadingCombinator: true ));
67
-
68
- /// Whether this selector is bogus other than having a leading combinator.
69
- ///
70
- /// @nodoc
71
- @internal
72
- bool get isBogusOtherThanLeadingCombinator =>
73
- accept (const _IsBogusVisitor (includeLeadingCombinator: false ));
74
-
75
- /// Whether this is a useless selector (that is, it's bogus _and_ it can't be
76
- /// transformed into valid CSS by `@extend` or nesting).
77
- ///
78
- /// @nodoc
79
- @internal
80
- bool get isUseless => accept (const _IsUselessVisitor ());
46
+ bool get isInvisible => accept (const _IsInvisibleVisitor ());
81
47
82
48
final FileSpan span;
83
49
84
50
Selector (this .span);
85
51
86
- /// Prints a warning if `this` is a bogus selector.
87
- ///
88
- /// This may only be called from within a custom Sass function. This will
89
- /// throw a [SassException] in Dart Sass 2.0.0.
90
- void assertNotBogus ({String ? name}) {
91
- if (! isBogus) return ;
92
- warnForDeprecation (
93
- (name == null ? '' : '\$ $name : ' ) +
94
- '$this is not valid CSS.\n '
95
- 'This will be an error in Dart Sass 2.0.0.\n '
96
- '\n '
97
- 'More info: https://sass-lang.com/d/bogus-combinators' ,
98
- Deprecation .bogusCombinators,
99
- );
100
- }
101
-
102
52
/// Calls the appropriate visit method on [visitor] .
103
53
T accept <T >(SelectorVisitor <T > visitor);
104
54
@@ -107,18 +57,11 @@ abstract base class Selector implements AstNode {
107
57
108
58
/// The visitor used to implement [Selector.isInvisible] .
109
59
class _IsInvisibleVisitor with AnySelectorVisitor {
110
- /// Whether to consider selectors with bogus combinators invisible.
111
- final bool includeBogus;
112
-
113
- const _IsInvisibleVisitor ({required this .includeBogus});
60
+ const _IsInvisibleVisitor ();
114
61
115
62
bool visitSelectorList (SelectorList list) =>
116
63
list.components.every (visitComplexSelector);
117
64
118
- bool visitComplexSelector (ComplexSelector complex) =>
119
- super .visitComplexSelector (complex) ||
120
- (includeBogus && complex.isBogusOtherThanLeadingCombinator);
121
-
122
65
bool visitPlaceholderSelector (PlaceholderSelector placeholder) => true ;
123
66
124
67
bool visitPseudoSelector (PseudoSelector pseudo) {
@@ -127,58 +70,9 @@ class _IsInvisibleVisitor with AnySelectorVisitor {
127
70
// it means "doesn't match this selector that matches nothing", so it's
128
71
// equivalent to *. If the entire compound selector is composed of `:not`s
129
72
// with invisible lists, the serializer emits it as `*`.
130
- return pseudo.name == 'not'
131
- ? (includeBogus && selector.isBogus)
132
- : selector.accept (this );
73
+ return pseudo.name != 'not' && selector.accept (this );
133
74
} else {
134
75
return false ;
135
76
}
136
77
}
137
78
}
138
-
139
- /// The visitor used to implement [Selector.isBogus] .
140
- class _IsBogusVisitor with AnySelectorVisitor {
141
- /// Whether to consider selectors with leading combinators as bogus.
142
- final bool includeLeadingCombinator;
143
-
144
- const _IsBogusVisitor ({required this .includeLeadingCombinator});
145
-
146
- bool visitComplexSelector (ComplexSelector complex) {
147
- if (complex.components.isEmpty) {
148
- return complex.leadingCombinators.isNotEmpty;
149
- } else {
150
- return complex.leadingCombinators.length >
151
- (includeLeadingCombinator ? 0 : 1 ) ||
152
- complex.components.last.combinators.isNotEmpty ||
153
- complex.components.any (
154
- (component) =>
155
- component.combinators.length > 1 ||
156
- component.selector.accept (this ),
157
- );
158
- }
159
- }
160
-
161
- bool visitPseudoSelector (PseudoSelector pseudo) {
162
- var selector = pseudo.selector;
163
- if (selector == null ) return false ;
164
-
165
- // The CSS spec specifically allows leading combinators in `:has()`.
166
- return pseudo.name == 'has'
167
- ? selector.isBogusOtherThanLeadingCombinator
168
- : selector.isBogus;
169
- }
170
- }
171
-
172
- /// The visitor used to implement [Selector.isUseless]
173
- class _IsUselessVisitor with AnySelectorVisitor {
174
- const _IsUselessVisitor ();
175
-
176
- bool visitComplexSelector (ComplexSelector complex) =>
177
- complex.leadingCombinators.length > 1 ||
178
- complex.components.any (
179
- (component) =>
180
- component.combinators.length > 1 || component.selector.accept (this ),
181
- );
182
-
183
- bool visitPseudoSelector (PseudoSelector pseudo) => pseudo.isBogus;
184
- }
0 commit comments