1
1
import { derived } from '../../reactivity/deriveds.js' ;
2
2
import { render_effect } from '../../reactivity/effects.js' ;
3
3
import { get } from '../../runtime.js' ;
4
- import { reconcile_html , remove } from '../reconciler.js' ;
4
+ import { hydrate_nodes , hydrating } from '../hydration.js' ;
5
+ import { create_fragment_from_html , remove } from '../reconciler.js' ;
5
6
6
7
/**
7
8
* @param {Element | Text | Comment } anchor
@@ -13,10 +14,53 @@ export function html(anchor, get_value, svg) {
13
14
let value = derived ( get_value ) ;
14
15
15
16
render_effect ( ( ) => {
16
- var dom = reconcile_html ( anchor , get ( value ) , svg ) ;
17
+ var dom = html_to_dom ( anchor , get ( value ) , svg ) ;
17
18
18
19
if ( dom ) {
19
20
return ( ) => remove ( dom ) ;
20
21
}
21
22
} ) ;
22
23
}
24
+
25
+ /**
26
+ * Creates the content for a `@html` tag from its string value,
27
+ * inserts it before the target anchor and returns the new nodes.
28
+ * @template V
29
+ * @param {Element | Text | Comment } target
30
+ * @param {V } value
31
+ * @param {boolean } svg
32
+ * @returns {Element | Comment | (Element | Comment | Text)[] }
33
+ */
34
+ function html_to_dom ( target , value , svg ) {
35
+ if ( hydrating ) return hydrate_nodes ;
36
+
37
+ var html = value + '' ;
38
+ if ( svg ) html = `<svg>${ html } </svg>` ;
39
+
40
+ // Don't use create_fragment_with_script_from_html here because that would mean script tags are executed.
41
+ // @html is basically `.innerHTML = ...` and that doesn't execute scripts either due to security reasons.
42
+ /** @type {DocumentFragment | Element } */
43
+ var node = create_fragment_from_html ( html ) ;
44
+
45
+ if ( svg ) {
46
+ node = /** @type {Element } */ ( node . firstChild ) ;
47
+ }
48
+
49
+ if ( node . childNodes . length === 1 ) {
50
+ var child = /** @type {Text | Element | Comment } */ ( node . firstChild ) ;
51
+ target . before ( child ) ;
52
+ return child ;
53
+ }
54
+
55
+ var nodes = /** @type {Array<Text | Element | Comment> } */ ( [ ...node . childNodes ] ) ;
56
+
57
+ if ( svg ) {
58
+ while ( node . firstChild ) {
59
+ target . before ( node . firstChild ) ;
60
+ }
61
+ } else {
62
+ target . before ( node ) ;
63
+ }
64
+
65
+ return nodes ;
66
+ }
0 commit comments