1- import { get_possible_values } from './gather_possible_values .js' ;
2- import { regex_starts_with_whitespace , regex_ends_with_whitespace } from '../.. /patterns.js' ;
3- import { error } from '../../../ errors.js' ;
1+ import { get_possible_values } from './utils .js' ;
2+ import { regex_starts_with_whitespace , regex_ends_with_whitespace } from '../phases /patterns.js' ;
3+ import { error } from '../errors.js' ;
44import { Stylesheet , Rule } from './Stylesheet.js' ;
55
66const NO_MATCH = 'NO_MATCH' ;
@@ -14,8 +14,6 @@ const NodeExist = /** @type {const} */ ({
1414
1515/**
1616 * @typedef {typeof NodeExist[keyof typeof NodeExist] } NodeExistsValue
17- * @typedef {Array<RelativeSelector> } ComplexSelector
18- * @typedef {Array<ComplexSelector> } SelectorList
1917 * @typedef {import("#compiler").Css.SimpleSelector & { use_wrapper: { used: boolean }, visible: boolean } } SimpleSelectorWithData
2018 * */
2119
@@ -24,23 +22,23 @@ const whitelist_attribute_selector = new Map([
2422 [ 'dialog' , new Set ( [ 'open' ] ) ]
2523] ) ;
2624
27- export default class Selector {
28- /** @type {import('#compiler').Css.Selector } */
25+ export class ComplexSelector {
26+ /** @type {import('#compiler').Css.ComplexSelector } */
2927 node ;
3028
3129 /** @type {Stylesheet } */
3230 stylesheet ;
3331
34- /** @type {SelectorList } */
32+ /** @type {RelativeSelector[][] } */
3533 selector_list ;
3634
37- /** @type {SelectorList } */
35+ /** @type {RelativeSelector[][] } */
3836 local_selector_list ;
3937
4038 used = false ;
4139
4240 /**
43- * @param {import('#compiler').Css.Selector } node
41+ * @param {import('#compiler').Css.ComplexSelector } node
4442 * @param {Stylesheet } stylesheet
4543 * @param {Rule } rule
4644 */
@@ -150,7 +148,7 @@ export default class Selector {
150148 }
151149 }
152150
153- /** @param {import('../.. /types.js').ComponentAnalysis } analysis */
151+ /** @param {import('../phases /types.js').ComponentAnalysis } analysis */
154152 validate ( analysis ) {
155153 this . validate_global_placement ( ) ;
156154 this . validate_global_with_multiple_selectors ( ) ;
@@ -197,7 +195,7 @@ export default class Selector {
197195 }
198196 }
199197
200- /** @param {import('../.. /types.js').ComponentAnalysis } analysis */
198+ /** @param {import('../phases /types.js').ComponentAnalysis } analysis */
201199 validate_invalid_combinator_without_selector ( analysis ) {
202200 for ( const complex_selector of this . selector_list ) {
203201 for ( const relative_selector of complex_selector ) {
@@ -238,20 +236,22 @@ export default class Selector {
238236}
239237
240238/**
241- * @param {RelativeSelector[] } blocks
239+ * @param {RelativeSelector[] } relative_selectors
242240 * @param {import('#compiler').RegularElement | import('#compiler').SvelteElement | null } node
243241 * @param {Stylesheet } stylesheet
244242 * @returns {boolean }
245243 */
246- function apply_selector ( blocks , node , stylesheet ) {
247- const block = blocks . pop ( ) ;
248- if ( ! block ) return false ;
244+ function apply_selector ( relative_selectors , node , stylesheet ) {
245+ const relative_selector = relative_selectors . pop ( ) ;
246+ if ( ! relative_selector ) return false ;
249247 if ( ! node ) {
250248 return (
251- ( block . global && blocks . every ( ( block ) => block . global ) ) || ( block . host && blocks . length === 0 )
249+ ( relative_selector . global &&
250+ relative_selectors . every ( ( relative_selector ) => relative_selector . global ) ) ||
251+ ( relative_selector . host && relative_selectors . length === 0 )
252252 ) ;
253253 }
254- const applies = block_might_apply_to_node ( block , node ) ;
254+ const applies = block_might_apply_to_node ( relative_selector , node ) ;
255255
256256 if ( applies === NO_MATCH ) {
257257 return false ;
@@ -260,28 +260,31 @@ function apply_selector(blocks, node, stylesheet) {
260260 /**
261261 * Mark both the compound selector and the node it selects as encapsulated,
262262 * for transformation in a later step
263- * @param {RelativeSelector } block
263+ * @param {RelativeSelector } relative_selector
264264 * @param {import('#compiler').RegularElement | import('#compiler').SvelteElement } node
265265 */
266- function mark ( block , node ) {
267- block . should_encapsulate = true ;
266+ function mark ( relative_selector , node ) {
267+ relative_selector . should_encapsulate = true ;
268268 stylesheet . nodes_with_css_class . add ( node ) ;
269269 return true ;
270270 }
271271
272272 if ( applies === UNKNOWN_SELECTOR ) {
273- return mark ( block , node ) ;
273+ return mark ( relative_selector , node ) ;
274274 }
275275
276- if ( block . combinator ) {
277- if ( block . combinator . type === 'Combinator' && block . combinator . name === ' ' ) {
278- for ( const ancestor_block of blocks ) {
276+ if ( relative_selector . combinator ) {
277+ if (
278+ relative_selector . combinator . type === 'Combinator' &&
279+ relative_selector . combinator . name === ' '
280+ ) {
281+ for ( const ancestor_block of relative_selectors ) {
279282 if ( ancestor_block . global ) {
280283 continue ;
281284 }
282285
283286 if ( ancestor_block . host ) {
284- return mark ( block , node ) ;
287+ return mark ( relative_selector , node ) ;
285288 }
286289
287290 /** @type {import('#compiler').RegularElement | import('#compiler').SvelteElement | null } */
@@ -294,40 +297,51 @@ function apply_selector(blocks, node, stylesheet) {
294297 }
295298 }
296299 if ( matched ) {
297- return mark ( block , node ) ;
300+ return mark ( relative_selector , node ) ;
298301 }
299302 }
300303
301- if ( blocks . every ( ( block ) => block . global ) ) {
302- return mark ( block , node ) ;
304+ if ( relative_selectors . every ( ( relative_selector ) => relative_selector . global ) ) {
305+ return mark ( relative_selector , node ) ;
303306 }
304307
305308 return false ;
306- } else if ( block . combinator . name === '>' ) {
307- const has_global_parent = blocks . every ( ( block ) => block . global ) ;
308- if ( has_global_parent || apply_selector ( blocks , get_element_parent ( node ) , stylesheet ) ) {
309- return mark ( block , node ) ;
309+ } else if ( relative_selector . combinator . name === '>' ) {
310+ const has_global_parent = relative_selectors . every (
311+ ( relative_selector ) => relative_selector . global
312+ ) ;
313+ if (
314+ has_global_parent ||
315+ apply_selector ( relative_selectors , get_element_parent ( node ) , stylesheet )
316+ ) {
317+ return mark ( relative_selector , node ) ;
310318 }
311319
312320 return false ;
313- } else if ( block . combinator . name === '+' || block . combinator . name === '~' ) {
314- const siblings = get_possible_element_siblings ( node , block . combinator . name === '+' ) ;
321+ } else if (
322+ relative_selector . combinator . name === '+' ||
323+ relative_selector . combinator . name === '~'
324+ ) {
325+ const siblings = get_possible_element_siblings (
326+ node ,
327+ relative_selector . combinator . name === '+'
328+ ) ;
315329 let has_match = false ;
316330
317331 // NOTE: if we have :global(), we couldn't figure out what is selected within `:global` due to the
318332 // css-tree limitation that does not parse the inner selector of :global
319333 // so unless we are sure there will be no sibling to match, we will consider it as matched
320- const has_global = blocks . some ( ( block ) => block . global ) ;
334+ const has_global = relative_selectors . some ( ( relative_selector ) => relative_selector . global ) ;
321335 if ( has_global ) {
322336 if ( siblings . size === 0 && get_element_parent ( node ) !== null ) {
323337 return false ;
324338 }
325- return mark ( block , node ) ;
339+ return mark ( relative_selector , node ) ;
326340 }
327341
328342 for ( const possible_sibling of siblings . keys ( ) ) {
329- if ( apply_selector ( blocks . slice ( ) , possible_sibling , stylesheet ) ) {
330- mark ( block , node ) ;
343+ if ( apply_selector ( relative_selectors . slice ( ) , possible_sibling , stylesheet ) ) {
344+ mark ( relative_selector , node ) ;
331345 has_match = true ;
332346 }
333347 }
@@ -336,25 +350,25 @@ function apply_selector(blocks, node, stylesheet) {
336350 }
337351
338352 // TODO other combinators
339- return mark ( block , node ) ;
353+ return mark ( relative_selector , node ) ;
340354 }
341355
342- return mark ( block , node ) ;
356+ return mark ( relative_selector , node ) ;
343357}
344358
345359const regex_backslash_and_following_character = / \\ ( .) / g;
346360
347361/**
348- * @param {RelativeSelector } block
362+ * @param {RelativeSelector } relative_selector
349363 * @param {import('#compiler').RegularElement | import('#compiler').SvelteElement } node
350364 * @returns {NO_MATCH | POSSIBLE_MATCH | UNKNOWN_SELECTOR }
351365 */
352- function block_might_apply_to_node ( block , node ) {
353- if ( block . host || block . root ) return NO_MATCH ;
366+ function block_might_apply_to_node ( relative_selector , node ) {
367+ if ( relative_selector . host || relative_selector . root ) return NO_MATCH ;
354368
355- let i = block . compound . selectors . length ;
369+ let i = relative_selector . compound . selectors . length ;
356370 while ( i -- ) {
357- const selector = block . compound . selectors [ i ] ;
371+ const selector = relative_selector . compound . selectors [ i ] ;
358372
359373 if ( selector . type === 'Percentage' || selector . type === 'Nth' ) continue ;
360374
@@ -364,7 +378,7 @@ function block_might_apply_to_node(block, node) {
364378 return NO_MATCH ;
365379 }
366380 if (
367- block . compound . selectors . length === 1 &&
381+ relative_selector . compound . selectors . length === 1 &&
368382 selector . type === 'PseudoClassSelector' &&
369383 name === 'global'
370384 ) {
@@ -683,22 +697,22 @@ function get_possible_element_siblings(node, adjacent_only) {
683697}
684698
685699/**
686- * @param {import('#compiler').EachBlock | import('#compiler').IfBlock | import('#compiler').AwaitBlock } block
700+ * @param {import('#compiler').EachBlock | import('#compiler').IfBlock | import('#compiler').AwaitBlock } relative_selector
687701 * @param {boolean } adjacent_only
688702 * @returns {Map<import('#compiler').RegularElement, NodeExistsValue> }
689703 */
690- function get_possible_last_child ( block , adjacent_only ) {
704+ function get_possible_last_child ( relative_selector , adjacent_only ) {
691705 /** @typedef {Map<import('#compiler').RegularElement, NodeExistsValue> } NodeMap */
692706
693707 /** @type {NodeMap } */
694708 const result = new Map ( ) ;
695- if ( block . type === 'EachBlock' ) {
709+ if ( relative_selector . type === 'EachBlock' ) {
696710 /** @type {NodeMap } */
697- const each_result = loop_child ( block . body . nodes , adjacent_only ) ;
711+ const each_result = loop_child ( relative_selector . body . nodes , adjacent_only ) ;
698712
699713 /** @type {NodeMap } */
700- const else_result = block . fallback
701- ? loop_child ( block . fallback . nodes , adjacent_only )
714+ const else_result = relative_selector . fallback
715+ ? loop_child ( relative_selector . fallback . nodes , adjacent_only )
702716 : new Map ( ) ;
703717 const not_exhaustive = ! has_definite_elements ( else_result ) ;
704718 if ( not_exhaustive ) {
@@ -707,13 +721,13 @@ function get_possible_last_child(block, adjacent_only) {
707721 }
708722 add_to_map ( each_result , result ) ;
709723 add_to_map ( else_result , result ) ;
710- } else if ( block . type === 'IfBlock' ) {
724+ } else if ( relative_selector . type === 'IfBlock' ) {
711725 /** @type {NodeMap } */
712- const if_result = loop_child ( block . consequent . nodes , adjacent_only ) ;
726+ const if_result = loop_child ( relative_selector . consequent . nodes , adjacent_only ) ;
713727
714728 /** @type {NodeMap } */
715- const else_result = block . alternate
716- ? loop_child ( block . alternate . nodes , adjacent_only )
729+ const else_result = relative_selector . alternate
730+ ? loop_child ( relative_selector . alternate . nodes , adjacent_only )
717731 : new Map ( ) ;
718732 const not_exhaustive = ! has_definite_elements ( if_result ) || ! has_definite_elements ( else_result ) ;
719733 if ( not_exhaustive ) {
@@ -722,17 +736,21 @@ function get_possible_last_child(block, adjacent_only) {
722736 }
723737 add_to_map ( if_result , result ) ;
724738 add_to_map ( else_result , result ) ;
725- } else if ( block . type === 'AwaitBlock' ) {
739+ } else if ( relative_selector . type === 'AwaitBlock' ) {
726740 /** @type {NodeMap } */
727- const pending_result = block . pending
728- ? loop_child ( block . pending . nodes , adjacent_only )
741+ const pending_result = relative_selector . pending
742+ ? loop_child ( relative_selector . pending . nodes , adjacent_only )
729743 : new Map ( ) ;
730744
731745 /** @type {NodeMap } */
732- const then_result = block . then ? loop_child ( block . then . nodes , adjacent_only ) : new Map ( ) ;
746+ const then_result = relative_selector . then
747+ ? loop_child ( relative_selector . then . nodes , adjacent_only )
748+ : new Map ( ) ;
733749
734750 /** @type {NodeMap } */
735- const catch_result = block . catch ? loop_child ( block . catch . nodes , adjacent_only ) : new Map ( ) ;
751+ const catch_result = relative_selector . catch
752+ ? loop_child ( relative_selector . catch . nodes , adjacent_only )
753+ : new Map ( ) ;
736754 const not_exhaustive =
737755 ! has_definite_elements ( pending_result ) ||
738756 ! has_definite_elements ( then_result ) ||
@@ -933,9 +951,9 @@ class CompoundSelector {
933951/**
934952 * Groups selectors and inserts parent blocks into nested rules.
935953 *
936- * @param {import('#compiler').Css.Selector } selector - The selector to group and analyze.
954+ * @param {import('#compiler').Css.ComplexSelector } selector - The selector to group and analyze.
937955 * @param {Rule } rule
938- * @returns {SelectorList } - The grouped selectors with parent's blocks inserted if nested.
956+ * @returns {RelativeSelector[][] } - The grouped selectors with parent's blocks inserted if nested.
939957 */
940958function group_selectors ( selector , rule ) {
941959 // TODO this logic isn't quite right, as it doesn't properly account for atrules
@@ -945,21 +963,19 @@ function group_selectors(selector, rule) {
945963 . flat ( ) ;
946964
947965 return parent_selector_list . map ( ( parent_complex_selector ) => {
948- const block_group = selector_to_blocks (
966+ return selector_to_blocks (
949967 [ ...selector . children ] ,
950968 [ ...parent_complex_selector ] // Clone the parent's blocks to avoid modifying the original array
951969 ) ;
952-
953- return block_group ;
954970 } ) ;
955971 }
956972
957973 return [ selector_to_blocks ( [ ...selector . children ] , null ) ] ;
958974}
959975
960976/**
961- * @param {import('#compiler').Css.Selector ["children"] } children
962- * @param {ComplexSelector | null } parent_complex_selector - The parent rule's selectors to insert/swap into the nesting selector positions.
977+ * @param {import('#compiler').Css.ComplexSelector ["children"] } children
978+ * @param {RelativeSelector[] | null } parent_complex_selector - The parent rule's selectors to insert/swap into the nesting selector positions.
963979 */
964980function selector_to_blocks ( children , parent_complex_selector ) {
965981 let block = new RelativeSelector ( null , new CompoundSelector ( ) ) ;
@@ -997,8 +1013,8 @@ function selector_to_blocks(children, parent_complex_selector) {
9971013}
9981014
9991015/**
1000- * @param {ComplexSelector } parent_complex_selector - The parent blocks to insert into the nesting selector positions.
1001- * @returns {import('#compiler').Css.Selector ["children"] } - The parent selectors to insert into the nesting selector positions.
1016+ * @param {RelativeSelector[] } parent_complex_selector - The parent blocks to insert into the nesting selector positions.
1017+ * @returns {import('#compiler').Css.ComplexSelector ["children"] } - The parent selectors to insert into the nesting selector positions.
10021018 */
10031019function get_parent_selectors ( parent_complex_selector ) {
10041020 const parent_selectors = [ ] ;
@@ -1027,8 +1043,8 @@ function get_parent_selectors(parent_complex_selector) {
10271043 * b { c & { color: red }} -> so we need to insert ' ' after c so children needs to look like [c, " ",b]
10281044 * .x { & { color: red }} -> no combinator, so children needs to look like .x.x
10291045 *
1030- * @param {import('#compiler').Css.Selector ["children"] } children
1031- * @param {ComplexSelector } parent_complex_selector - The parent blocks to insert into the nesting selector positions.
1046+ * @param {import('#compiler').Css.ComplexSelector ["children"] } children
1047+ * @param {RelativeSelector[] } parent_complex_selector - The parent blocks to insert into the nesting selector positions.
10321048 */
10331049function nest_fake_parents ( children , parent_complex_selector ) {
10341050 const nested_selector_indexes = children . reduce ( ( indexes , child , index ) => {
0 commit comments