11import { derived } from '../../reactivity/deriveds.js' ;
22import { render_effect } from '../../reactivity/effects.js' ;
33import { 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' ;
56
67/**
78 * @param {Element | Text | Comment } anchor
@@ -13,10 +14,53 @@ export function html(anchor, get_value, svg) {
1314 let value = derived ( get_value ) ;
1415
1516 render_effect ( ( ) => {
16- var dom = reconcile_html ( anchor , get ( value ) , svg ) ;
17+ var dom = html_to_dom ( anchor , get ( value ) , svg ) ;
1718
1819 if ( dom ) {
1920 return ( ) => remove ( dom ) ;
2021 }
2122 } ) ;
2223}
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