1
1
import { namespace_svg } from '../../../../constants.js' ;
2
- import { hydrate_anchor , hydrate_start , hydrating } from '../hydration.js' ;
2
+ import { hydrating , set_hydrate_nodes } from '../hydration.js' ;
3
3
import { empty } from '../operations.js' ;
4
4
import {
5
5
block ,
@@ -37,15 +37,15 @@ function swap_block_dom(effect, from, to) {
37
37
}
38
38
39
39
/**
40
- * @param {Comment } anchor
40
+ * @param {Comment | Element } node
41
41
* @param {() => string } get_tag
42
42
* @param {boolean } is_svg
43
43
* @param {undefined | ((element: Element, anchor: Node | null) => void) } render_fn,
44
44
* @param {undefined | (() => string) } get_namespace
45
45
* @param {undefined | [number, number] } location
46
46
* @returns {void }
47
47
*/
48
- export function element ( anchor , get_tag , is_svg , render_fn , get_namespace , location ) {
48
+ export function element ( node , get_tag , is_svg , render_fn , get_namespace , location ) {
49
49
const parent_effect = /** @type {import('#client').Effect } */ ( current_effect ) ;
50
50
const filename = DEV && location && current_component_context ?. function . filename ;
51
51
@@ -56,7 +56,9 @@ export function element(anchor, get_tag, is_svg, render_fn, get_namespace, locat
56
56
let current_tag ;
57
57
58
58
/** @type {null | Element } */
59
- let element = null ;
59
+ let element = hydrating && node . nodeType === 1 ? /** @type {Element } */ ( node ) : null ;
60
+
61
+ let anchor = /** @type {Comment } */ ( hydrating && element ? element . nextSibling : node ) ;
60
62
61
63
/** @type {import('#client').Effect | null } */
62
64
let effect ;
@@ -75,6 +77,7 @@ export function element(anchor, get_tag, is_svg, render_fn, get_namespace, locat
75
77
: is_svg || next_tag === 'svg'
76
78
? namespace_svg
77
79
: null ;
80
+
78
81
// Assumption: Noone changes the namespace but not the tag (what would that even mean?)
79
82
if ( next_tag === tag ) return ;
80
83
@@ -104,7 +107,7 @@ export function element(anchor, get_tag, is_svg, render_fn, get_namespace, locat
104
107
effect = branch ( ( ) => {
105
108
const prev_element = element ;
106
109
element = hydrating
107
- ? /** @type {Element } */ ( hydrate_start )
110
+ ? /** @type {Element } */ ( element )
108
111
: ns
109
112
? document . createElementNS ( ns , next_tag )
110
113
: document . createElement ( next_tag ) ;
@@ -123,9 +126,13 @@ export function element(anchor, get_tag, is_svg, render_fn, get_namespace, locat
123
126
if ( render_fn ) {
124
127
// If hydrating, use the existing ssr comment as the anchor so that the
125
128
// inner open and close methods can pick up the existing nodes correctly
126
- var child_anchor = hydrating
127
- ? element . firstChild && hydrate_anchor ( /** @type {Comment } */ ( element . firstChild ) )
128
- : element . appendChild ( empty ( ) ) ;
129
+ var child_anchor = hydrating ? element . lastChild : element . appendChild ( empty ( ) ) ;
130
+
131
+ if ( hydrating && child_anchor ) {
132
+ set_hydrate_nodes (
133
+ /** @type {import('#client').TemplateNode[] } */ ( [ ...element . childNodes ] ) . slice ( 0 , - 1 )
134
+ ) ;
135
+ }
129
136
130
137
// `child_anchor` is undefined if this is a void element, but we still
131
138
// need to call `render_fn` in order to run actions etc. If the element
@@ -136,11 +143,13 @@ export function element(anchor, get_tag, is_svg, render_fn, get_namespace, locat
136
143
137
144
anchor . before ( element ) ;
138
145
139
- if ( prev_element ) {
140
- swap_block_dom ( parent_effect , prev_element , element ) ;
141
- prev_element . remove ( ) ;
142
- } else if ( ! hydrating ) {
143
- push_template_node ( element , parent_effect ) ;
146
+ if ( ! hydrating ) {
147
+ if ( prev_element ) {
148
+ swap_block_dom ( parent_effect , prev_element , element ) ;
149
+ prev_element . remove ( ) ;
150
+ } else {
151
+ push_template_node ( element , parent_effect ) ;
152
+ }
144
153
}
145
154
} ) ;
146
155
}
0 commit comments