@@ -43,6 +43,12 @@ const nesting_selector = {
43
43
}
44
44
} ;
45
45
46
+ /**
47
+ * Snippets encountered already (avoids infinite loops)
48
+ * @type {Set<Compiler.AST.SnippetBlock> }
49
+ */
50
+ const seen = new Set ( ) ;
51
+
46
52
/**
47
53
*
48
54
* @param {Compiler.Css.StyleSheet } stylesheet
@@ -60,6 +66,8 @@ export function prune(stylesheet, element) {
60
66
ComplexSelector ( node ) {
61
67
const selectors = get_relative_selectors ( node ) ;
62
68
69
+ seen . clear ( ) ;
70
+
63
71
if (
64
72
apply_selector ( selectors , /** @type {Compiler.Css.Rule } */ ( node . metadata . rule ) , element )
65
73
) {
@@ -193,6 +201,9 @@ function apply_combinator(relative_selector, parent_selectors, rule, node) {
193
201
const parent = path [ i ] ;
194
202
195
203
if ( parent . type === 'SnippetBlock' ) {
204
+ if ( seen . has ( parent ) ) return true ;
205
+ seen . add ( parent ) ;
206
+
196
207
for ( const site of parent . metadata . sites ) {
197
208
if ( apply_combinator ( relative_selector , parent_selectors , rule , site ) ) {
198
209
return true ;
@@ -335,6 +346,8 @@ function relative_selector_might_apply_to_node(relative_selector, rule, element)
335
346
descendant_elements . push ( element ) ;
336
347
}
337
348
349
+ const seen = new Set ( ) ;
350
+
338
351
/**
339
352
* @param {Compiler.SvelteNode } node
340
353
* @param {{ is_child: boolean } } state
@@ -355,6 +368,9 @@ function relative_selector_might_apply_to_node(relative_selector, rule, element)
355
368
}
356
369
} else if ( node . type === 'RenderTag' ) {
357
370
for ( const snippet of node . metadata . snippets ) {
371
+ if ( seen . has ( snippet ) ) continue ;
372
+
373
+ seen . add ( snippet ) ;
358
374
walk_children ( snippet . body , context . state ) ;
359
375
}
360
376
} else {
@@ -618,6 +634,8 @@ function get_following_sibling_elements(element, include_self) {
618
634
// ...then walk them, starting from the node after the one
619
635
// containing the element in question
620
636
637
+ const seen = new Set ( ) ;
638
+
621
639
/** @param {Compiler.SvelteNode } node */
622
640
function get_siblings ( node ) {
623
641
walk ( node , null , {
@@ -629,6 +647,9 @@ function get_following_sibling_elements(element, include_self) {
629
647
} ,
630
648
RenderTag ( node ) {
631
649
for ( const snippet of node . metadata . snippets ) {
650
+ if ( seen . has ( snippet ) ) continue ;
651
+
652
+ seen . add ( snippet ) ;
632
653
get_siblings ( snippet . body ) ;
633
654
}
634
655
}
@@ -804,9 +825,10 @@ function get_element_parent(node) {
804
825
/**
805
826
* @param {Compiler.AST.RegularElement | Compiler.AST.SvelteElement | Compiler.AST.RenderTag | Compiler.AST.Component | Compiler.AST.SvelteComponent | Compiler.AST.SvelteSelf } node
806
827
* @param {boolean } adjacent_only
828
+ * @param {Set<Compiler.AST.SnippetBlock> } seen
807
829
* @returns {Map<Compiler.AST.RegularElement | Compiler.AST.SvelteElement | Compiler.AST.SlotElement | Compiler.AST.RenderTag, NodeExistsValue> }
808
830
*/
809
- function get_possible_element_siblings ( node , adjacent_only ) {
831
+ function get_possible_element_siblings ( node , adjacent_only , seen = new Set ( ) ) {
810
832
/** @type {Map<Compiler.AST.RegularElement | Compiler.AST.SvelteElement | Compiler.AST.SlotElement | Compiler.AST.RenderTag, NodeExistsValue> } */
811
833
const result = new Map ( ) ;
812
834
const path = node . metadata . path ;
@@ -865,8 +887,11 @@ function get_possible_element_siblings(node, adjacent_only) {
865
887
}
866
888
867
889
if ( current . type === 'SnippetBlock' ) {
890
+ if ( seen . has ( current ) ) break ;
891
+ seen . add ( current ) ;
892
+
868
893
for ( const site of current . metadata . sites ) {
869
- const siblings = get_possible_element_siblings ( site , adjacent_only ) ;
894
+ const siblings = get_possible_element_siblings ( site , adjacent_only , seen ) ;
870
895
add_to_map ( siblings , result ) ;
871
896
872
897
if ( adjacent_only && current . metadata . sites . size === 1 && has_definite_elements ( siblings ) ) {
0 commit comments