@@ -881,124 +881,71 @@ function get_element_parent(node) {
881
881
}
882
882
883
883
/**
884
- * Finds the given node's previous sibling in the DOM
885
- *
886
- * The Svelte `<slot>` is just a placeholder and is not actually real. Any children nodes
887
- * in `<slot>` are 'flattened' and considered as the same level as the `<slot>`'s siblings
888
- *
889
- * e.g.
890
- * ```html
891
- * <h1>Heading 1</h1>
892
- * <slot>
893
- * <h2>Heading 2</h2>
894
- * </slot>
895
- * ```
896
- *
897
- * is considered to look like:
898
- * ```html
899
- * <h1>Heading 1</h1>
900
- * <h2>Heading 2</h2>
901
- * ```
902
- * @param {Compiler.SvelteNode } node
903
- * @returns {Compiler.SvelteNode }
904
- */
905
- function find_previous_sibling ( node ) {
906
- /** @type {Compiler.SvelteNode } */
907
- let current_node = node ;
908
-
909
- while (
910
- // @ts -expect-error TODO
911
- ! current_node . prev &&
912
- // @ts -expect-error TODO
913
- current_node . parent ?. type === 'SlotElement'
914
- ) {
915
- // @ts -expect-error TODO
916
- current_node = current_node . parent ;
917
- }
918
-
919
- // @ts -expect-error
920
- current_node = current_node . prev ;
921
-
922
- while ( current_node ?. type === 'SlotElement' ) {
923
- const slot_children = current_node . fragment . nodes ;
924
- if ( slot_children . length > 0 ) {
925
- current_node = slot_children [ slot_children . length - 1 ] ;
926
- } else {
927
- break ;
928
- }
929
- }
930
-
931
- return current_node ;
932
- }
933
-
934
- /**
935
- * @param {Compiler.SvelteNode } node
884
+ * @param {Compiler.AST.RegularElement | Compiler.AST.SvelteElement } element
936
885
* @param {boolean } adjacent_only
937
886
* @returns {Map<Compiler.AST.RegularElement | Compiler.AST.SvelteElement | Compiler.AST.SlotElement | Compiler.AST.RenderTag, NodeExistsValue> }
938
887
*/
939
- function get_possible_element_siblings ( node , adjacent_only ) {
888
+ function get_possible_element_siblings ( element , adjacent_only ) {
940
889
/** @type {Map<Compiler.AST.RegularElement | Compiler.AST.SvelteElement | Compiler.AST.SlotElement | Compiler.AST.RenderTag, NodeExistsValue> } */
941
890
const result = new Map ( ) ;
891
+ const path = element . metadata . path ;
942
892
943
893
/** @type {Compiler.SvelteNode } */
944
- let prev = node ;
945
- while ( ( prev = find_previous_sibling ( prev ) ) ) {
946
- if ( prev . type === 'RegularElement' ) {
947
- const has_slot_attribute = prev . attributes . some (
948
- ( attr ) => attr . type === 'Attribute' && attr . name . toLowerCase ( ) === 'slot'
949
- ) ;
894
+ let current = element ;
895
+
896
+ let i = path . length ;
897
+
898
+ while ( i -- ) {
899
+ const fragment = /** @type {Compiler.AST.Fragment } */ ( path [ i -- ] ) ;
900
+ let j = fragment . nodes . indexOf ( current ) ;
901
+
902
+ while ( j -- ) {
903
+ const node = fragment . nodes [ j ] ;
904
+
905
+ if ( node . type === 'RegularElement' ) {
906
+ const has_slot_attribute = node . attributes . some (
907
+ ( attr ) => attr . type === 'Attribute' && attr . name . toLowerCase ( ) === 'slot'
908
+ ) ;
950
909
951
- if ( ! has_slot_attribute ) {
952
- result . set ( prev , NODE_DEFINITELY_EXISTS ) ;
910
+ if ( ! has_slot_attribute ) {
911
+ result . set ( node , NODE_DEFINITELY_EXISTS ) ;
953
912
954
- if ( adjacent_only ) {
913
+ if ( adjacent_only ) {
914
+ return result ;
915
+ }
916
+ }
917
+ } else if ( is_block ( node ) ) {
918
+ if ( node . type === 'SlotElement' ) {
919
+ result . set ( node , NODE_PROBABLY_EXISTS ) ;
920
+ }
921
+
922
+ const possible_last_child = get_possible_last_child ( node , adjacent_only ) ;
923
+ add_to_map ( possible_last_child , result ) ;
924
+ if ( adjacent_only && has_definite_elements ( possible_last_child ) ) {
955
925
return result ;
956
926
}
927
+ } else if ( node . type === 'RenderTag' || node . type === 'SvelteElement' ) {
928
+ result . set ( node , NODE_PROBABLY_EXISTS ) ;
929
+ // Special case: slots, render tags and svelte:element tags could resolve to no siblings,
930
+ // so we want to continue until we find a definite sibling even with the adjacent-only combinator
957
931
}
958
- } else if ( is_block ( prev ) ) {
959
- const possible_last_child = get_possible_last_child ( prev , adjacent_only ) ;
960
- add_to_map ( possible_last_child , result ) ;
961
- if ( adjacent_only && has_definite_elements ( possible_last_child ) ) {
962
- return result ;
963
- }
964
- } else if (
965
- prev . type === 'SlotElement' ||
966
- prev . type === 'RenderTag' ||
967
- prev . type === 'SvelteElement'
968
- ) {
969
- result . set ( prev , NODE_PROBABLY_EXISTS ) ;
970
- // Special case: slots, render tags and svelte:element tags could resolve to no siblings,
971
- // so we want to continue until we find a definite sibling even with the adjacent-only combinator
972
932
}
973
- }
974
933
975
- /** @type {Compiler.SvelteNode | null } */
976
- let parent = node ;
934
+ current = path [ i ] ;
977
935
978
- while (
979
- // @ts -expect-error TODO
980
- ( parent = parent ?. parent ) &&
981
- is_block ( parent )
982
- ) {
983
- const possible_siblings = get_possible_element_siblings ( parent , adjacent_only ) ;
984
- add_to_map ( possible_siblings , result ) ;
936
+ if ( ! current || ! is_block ( current ) ) break ;
985
937
986
- // @ts -expect-error
987
- if ( parent . type === 'EachBlock' && ! parent . fallback ?. nodes . includes ( node ) ) {
938
+ if ( current . type === 'EachBlock' && fragment === current . body ) {
988
939
// `{#each ...}<a /><b />{/each}` — `<b>` can be previous sibling of `<a />`
989
- add_to_map ( get_possible_last_child ( parent , adjacent_only ) , result ) ;
990
- }
991
-
992
- if ( adjacent_only && has_definite_elements ( possible_siblings ) ) {
993
- break ;
940
+ add_to_map ( get_possible_last_child ( current , adjacent_only ) , result ) ;
994
941
}
995
942
}
996
943
997
944
return result ;
998
945
}
999
946
1000
947
/**
1001
- * @param {Compiler.AST.EachBlock | Compiler.AST.IfBlock | Compiler.AST.AwaitBlock | Compiler.AST.KeyBlock } node
948
+ * @param {Compiler.AST.EachBlock | Compiler.AST.IfBlock | Compiler.AST.AwaitBlock | Compiler.AST.KeyBlock | Compiler.AST.SlotElement } node
1002
949
* @param {boolean } adjacent_only
1003
950
* @returns {Map<Compiler.AST.RegularElement, NodeExistsValue> }
1004
951
*/
@@ -1022,14 +969,15 @@ function get_possible_last_child(node, adjacent_only) {
1022
969
break ;
1023
970
1024
971
case 'KeyBlock' :
972
+ case 'SlotElement' :
1025
973
fragments . push ( node . fragment ) ;
1026
974
break ;
1027
975
}
1028
976
1029
977
/** @type {NodeMap } */
1030
978
const result = new Map ( ) ;
1031
979
1032
- let exhaustive = true ;
980
+ let exhaustive = node . type !== 'SlotElement' ;
1033
981
1034
982
for ( const fragment of fragments ) {
1035
983
if ( fragment == null ) {
@@ -1121,13 +1069,14 @@ function loop_child(children, adjacent_only) {
1121
1069
1122
1070
/**
1123
1071
* @param {Compiler.SvelteNode } node
1124
- * @returns {node is Compiler.AST.IfBlock | Compiler.AST.EachBlock | Compiler.AST.AwaitBlock | Compiler.AST.KeyBlock }
1072
+ * @returns {node is Compiler.AST.IfBlock | Compiler.AST.EachBlock | Compiler.AST.AwaitBlock | Compiler.AST.KeyBlock | Compiler.AST.SlotElement }
1125
1073
*/
1126
1074
function is_block ( node ) {
1127
1075
return (
1128
1076
node . type === 'IfBlock' ||
1129
1077
node . type === 'EachBlock' ||
1130
1078
node . type === 'AwaitBlock' ||
1131
- node . type === 'KeyBlock'
1079
+ node . type === 'KeyBlock' ||
1080
+ node . type === 'SlotElement'
1132
1081
) ;
1133
1082
}
0 commit comments