pull/12215/head
Rich Harris 2 months ago
parent 1a14f8c0b9
commit 27b38cdd9f

@ -1,5 +1,5 @@
import { derived } from '../../reactivity/deriveds.js';
import { render_effect } from '../../reactivity/effects.js';
import { block, branch, destroy_effect, render_effect } from '../../reactivity/effects.js';
import { get } from '../../runtime.js';
import { is_array } from '../../utils.js';
import { hydrate_nodes, hydrating } from '../hydration.js';
@ -14,22 +14,53 @@ import { assign_nodes } from '../template.js';
* @returns {void}
*/
export function html(anchor, get_value, svg, mathml) {
let value = derived(get_value);
var value = '';
render_effect(() => {
var dom = html_to_dom(anchor, get(value), svg, mathml);
/** @type {import('#client').Effect | null} */
var effect;
if (dom) {
if (is_array(dom)) {
assign_nodes(dom[0], dom[dom.length - 1]);
} else {
assign_nodes(dom, dom);
}
block(anchor, 0, () => {
if (value === (value = get_value())) return;
return () => {
remove(dom);
};
if (effect) {
destroy_effect(effect);
effect = null;
}
if (value === '') return;
effect = branch(() => {
if (hydrating) {
assign_nodes(hydrate_nodes[0], hydrate_nodes[hydrate_nodes.length - 1]);
return;
}
var html = value + '';
if (svg) html = `<svg>${html}</svg>`;
else if (mathml) html = `<math>${html}</math>`;
// Don't use create_fragment_with_script_from_html here because that would mean script tags are executed.
// @html is basically `.innerHTML = ...` and that doesn't execute scripts either due to security reasons.
/** @type {DocumentFragment | Element} */
var node = create_fragment_from_html(html);
if (svg || mathml) {
node = /** @type {Element} */ (node.firstChild);
}
assign_nodes(
/** @type {import('#client').TemplateNode} */ (node.firstChild),
/** @type {import('#client').TemplateNode} */ (node.lastChild)
);
if (svg || mathml) {
while (node.firstChild) {
anchor.before(node.firstChild);
}
} else {
anchor.before(node);
}
});
});
}
@ -37,13 +68,13 @@ export function html(anchor, get_value, svg, mathml) {
* Creates the content for a `@html` tag from its string value,
* inserts it before the target anchor and returns the new nodes.
* @template V
* @param {Element | Text | Comment} target
* @param {Element | Text | Comment} anchor
* @param {V} value
* @param {boolean} svg
* @param {boolean} mathml
* @returns {Element | Comment | (Element | Comment | Text)[]}
*/
function html_to_dom(target, value, svg, mathml) {
function html_to_dom(anchor, value, svg, mathml) {
if (hydrating) return hydrate_nodes;
var html = value + '';
@ -61,7 +92,7 @@ function html_to_dom(target, value, svg, mathml) {
if (node.childNodes.length === 1) {
var child = /** @type {Text | Element | Comment} */ (node.firstChild);
target.before(child);
anchor.before(child);
return child;
}
@ -69,10 +100,10 @@ function html_to_dom(target, value, svg, mathml) {
if (svg || mathml) {
while (node.firstChild) {
target.before(node.firstChild);
anchor.before(node.firstChild);
}
} else {
target.before(node);
anchor.before(node);
}
return nodes;

@ -85,11 +85,15 @@ export function first_child(fragment, is_text) {
// text node to hydrate — we must therefore create one
if (is_text && hydrate_start?.nodeType !== 3) {
var text = empty();
var dom = /** @type {import('#client').TemplateNode[]} */ (
/** @type {import('#client').Effect} */ (current_effect).dom
);
// var dom = /** @type {import('#client').TemplateNode[]} */ (
// /** @type {import('#client').Effect} */ (current_effect).dom
// );
dom.unshift(text);
if (current_effect.nodes.start === hydrate_start) {
current_effect.nodes.start = text;
}
// dom.unshift(text);
hydrate_start?.before(text);
return text;
@ -126,6 +130,8 @@ export function sibling(node, is_text = false) {
/** @type {import('#client').Effect} */ (current_effect).dom
);
// TODO something needs to happen here but i'm not quite sure what
dom.unshift(text);
next_sibling?.before(text);

@ -121,7 +121,7 @@ function create_effect(type, fn, sync) {
sync &&
effect.deps === null &&
effect.first === null &&
effect.dom === null &&
effect.nodes === null &&
effect.teardown === null;
if (!inert && !is_root) {
@ -339,8 +339,6 @@ export function execute_effect_teardown(effect) {
* @returns {void}
*/
export function destroy_effect(effect, remove_dom = true) {
var dom = effect.dom;
var removed = false;
if (remove_dom) {
@ -351,10 +349,6 @@ export function destroy_effect(effect, remove_dom = true) {
removed = true;
}
if (dom !== null && remove_dom) {
// remove(dom);
}
destroy_effect_children(effect, remove_dom && !removed);
remove_reactions(effect, 0);
set_signal_status(effect, DESTROYED);
@ -379,7 +373,6 @@ export function destroy_effect(effect, remove_dom = true) {
effect.prev =
effect.teardown =
effect.ctx =
effect.dom =
effect.deps =
effect.parent =
effect.fn =

Loading…
Cancel
Save