tidy up a bit

pull/12215/head
Rich Harris 2 months ago
parent 54e3a2fa15
commit 17c95e232b

@ -1,9 +1,6 @@
import { derived } from '../../reactivity/deriveds.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, hydrate_start, hydrating } from '../hydration.js';
import { create_fragment_from_html, remove } from '../reconciler.js';
import { block, branch, destroy_effect } from '../../reactivity/effects.js';
import { get_start, hydrate_nodes, hydrating } from '../hydration.js';
import { create_fragment_from_html } from '../reconciler.js';
import { assign_nodes } from '../template.js';
/**
@ -31,10 +28,7 @@ export function html(anchor, get_value, svg, mathml) {
effect = branch(() => {
if (hydrating) {
assign_nodes(
hydrate_start.previousSibling ?? hydrate_start,
hydrate_nodes[hydrate_nodes.length - 1]
);
assign_nodes(get_start(), hydrate_nodes[hydrate_nodes.length - 1]);
return;
}
@ -66,48 +60,3 @@ 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} anchor
* @param {V} value
* @param {boolean} svg
* @param {boolean} mathml
* @returns {Element | Comment | (Element | Comment | Text)[]}
*/
function html_to_dom(anchor, value, svg, mathml) {
if (hydrating) return hydrate_nodes;
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);
}
if (node.childNodes.length === 1) {
var child = /** @type {Text | Element | Comment} */ (node.firstChild);
anchor.before(child);
return child;
}
var nodes = /** @type {Array<Text | Element | Comment>} */ ([...node.childNodes]);
if (svg || mathml) {
while (node.firstChild) {
anchor.before(node.firstChild);
}
} else {
anchor.before(node);
}
return nodes;
}

@ -30,6 +30,17 @@ export function set_hydrate_nodes(nodes) {
hydrate_start = nodes && nodes[0];
}
/**
* When assigning nodes to an effect during hydration, we typically want the hydration boundary comment node
* immediately before `hydrate_start`. In some cases, this comment doesn't exist because we optimized it away.
* TODO it might be worth storing this value separately rather than retrieving it with `previousSibling`
*/
export function get_start() {
return /** @type {import('#client').TemplateNode} */ (
hydrate_start.previousSibling ?? hydrate_start
);
}
/**
* This function is only called when `hydrating` is true. If passed a `<!--[-->` opening
* hydration marker, it finds the corresponding closing marker and sets `hydrate_nodes`

@ -1,4 +1,4 @@
import { hydrate_nodes, hydrate_start, hydrating } from './hydration.js';
import { get_start, hydrate_nodes, hydrate_start, hydrating } from './hydration.js';
import { empty } from './operations.js';
import { create_fragment_from_html } from './reconciler.js';
import { current_effect } from '../runtime.js';
@ -11,18 +11,16 @@ import { queue_micro_task } from './task.js';
/**
*
* @param {import('#client').TemplateNode | null | undefined} start
* @param {import('#client').TemplateNode | undefined | null} start
* @param {import('#client').TemplateNode} end
*/
export function assign_nodes(start, end) {
const effect = /** @type {import('#client').Effect} */ (current_effect);
if (effect.nodes === null) {
effect.nodes = { start, end };
} else {
if (effect.nodes.start === undefined) {
effect.nodes.start = start;
}
effect.nodes = { start, anchor: null, end };
} else if (effect.nodes.start === undefined) {
effect.nodes.start = start;
}
}
@ -44,10 +42,7 @@ export function template(content, flags) {
return () => {
if (hydrating) {
assign_nodes(
hydrate_start.previousSibling ?? hydrate_start,
hydrate_nodes[hydrate_nodes.length - 1]
);
assign_nodes(get_start(), hydrate_nodes[hydrate_nodes.length - 1]);
return hydrate_start;
}
@ -121,10 +116,7 @@ export function ns_template(content, flags, ns = 'svg') {
return () => {
if (hydrating) {
assign_nodes(
hydrate_start.previousSibling ?? hydrate_start,
hydrate_nodes[hydrate_nodes.length - 1]
);
assign_nodes(get_start(), hydrate_nodes[hydrate_nodes.length - 1]);
return hydrate_start;
}
@ -254,10 +246,7 @@ export function text(anchor) {
export function comment(flags = 0) {
// we're not delegating to `template` here for performance reasons
if (hydrating) {
assign_nodes(
hydrate_start.previousSibling ?? hydrate_start,
hydrate_nodes[hydrate_nodes.length - 1]
);
assign_nodes(get_start(), hydrate_nodes[hydrate_nodes.length - 1]);
return hydrate_start;
}

@ -305,7 +305,7 @@ export function template_effect(fn) {
*/
export function block(anchor, flags, fn) {
const effect = create_effect(RENDER_EFFECT | BLOCK_EFFECT | flags, fn, true);
if (anchor !== null) effect.nodes = { start: null, end: anchor };
if (anchor !== null) effect.nodes = { start: null, anchor: null, end: anchor };
return effect;
}

@ -36,7 +36,11 @@ export interface Derived<V = unknown> extends Value<V>, Reaction {
export interface Effect extends Reaction {
parent: Effect | null;
nodes: null | { start: undefined | null | TemplateNode; end: TemplateNode };
nodes: null | {
start: undefined | null | TemplateNode;
anchor: null | TemplateNode;
end: TemplateNode;
};
/** The associated component context */
ctx: null | ComponentContext;
/** The effect function */

Loading…
Cancel
Save