@@ -3,7 +3,18 @@ import { walk } from 'zimmerframe';
3
3
import { is_keyframes_node , regex_css_name_boundary , remove_css_prefix } from '../../css.js' ;
4
4
import { merge_with_preprocessor_map } from '../../../utils/mapped_code.js' ;
5
5
6
- /** @typedef {{ code: MagicString, dev: boolean, hash: string, selector: string, keyframes: string[] } } State */
6
+ /**
7
+ * @typedef {{
8
+ * code: MagicString;
9
+ * dev: boolean;
10
+ * hash: string;
11
+ * selector: string;
12
+ * keyframes: string[];
13
+ * specificity: {
14
+ * bumped: boolean
15
+ * }
16
+ * }} State
17
+ */
7
18
8
19
/**
9
20
*
@@ -20,7 +31,10 @@ export function render_stylesheet(source, analysis, options) {
20
31
dev : options . dev ,
21
32
hash : analysis . css . hash ,
22
33
selector : `.${ analysis . css . hash } ` ,
23
- keyframes : analysis . css . keyframes
34
+ keyframes : analysis . css . keyframes ,
35
+ specificity : {
36
+ bumped : false
37
+ }
24
38
} ;
25
39
26
40
const ast = /** @type {import('#compiler').Css.StyleSheet } */ ( analysis . css . ast ) ;
@@ -124,7 +138,7 @@ const visitors = {
124
138
125
139
next ( ) ;
126
140
} ,
127
- SelectorList ( node , { state, next } ) {
141
+ SelectorList ( node , { state, next, path } ) {
128
142
const used = node . children . filter ( ( s ) => s . metadata . used ) ;
129
143
130
144
if ( used . length < node . children . length ) {
@@ -159,7 +173,11 @@ const visitors = {
159
173
}
160
174
}
161
175
162
- next ( ) ;
176
+ const parent = /** @type {import('#compiler').Css.Node } */ ( path . at ( - 1 ) ) ;
177
+ next ( {
178
+ ...state ,
179
+ specificity : parent . type === 'Rule' ? { bumped : false } : state . specificity
180
+ } ) ;
163
181
} ,
164
182
ComplexSelector ( node , context ) {
165
183
/** @param {import('#compiler').Css.SimpleSelector } selector */
@@ -169,8 +187,6 @@ const visitors = {
169
187
. remove ( selector . end - 1 , selector . end ) ;
170
188
}
171
189
172
- let first = true ;
173
-
174
190
for ( const relative_selector of node . children ) {
175
191
if ( relative_selector . metadata . is_global ) {
176
192
remove_global_pseudo_class ( relative_selector . selectors [ 0 ] ) ;
@@ -192,9 +208,9 @@ const visitors = {
192
208
// encapsulated selector gets a +0-1-0 specificity bump. thereafter,
193
209
// we use a `:where` selector, which does not affect specificity
194
210
let modifier = context . state . selector ;
195
- if ( ! first ) modifier = `:where(${ modifier } )` ;
211
+ if ( context . state . specificity . bumped ) modifier = `:where(${ modifier } )` ;
196
212
197
- first = false ;
213
+ context . state . specificity . bumped = true ;
198
214
199
215
// TODO err... can this happen?
200
216
for ( const selector of relative_selector . selectors ) {
@@ -225,7 +241,6 @@ const visitors = {
225
241
226
242
break ;
227
243
}
228
- first = false ;
229
244
}
230
245
}
231
246
0 commit comments