attach DOM to effects

pull/10880/head
Rich Harris 2 years ago
parent 6822decec2
commit 6143f6a6e3

@ -57,9 +57,6 @@ export function key_block(anchor, get_key, render_fn) {
true
);
// @ts-expect-error TODO tidy up
effect.d = block.d;
effects.add(effect);
}
},
@ -69,8 +66,7 @@ export function key_block(anchor, get_key, render_fn) {
key_effect.ondestroy = () => {
for (const e of effects) {
// @ts-expect-error TODO tidy up. ondestroy should be totally unnecessary
if (e.d) remove(e.d);
if (e.dom) remove(e.dom);
}
};
}

@ -60,9 +60,6 @@ export function component(anchor, get_component, render_fn) {
true
);
// @ts-expect-error TODO tidy up
effect.d = block.d;
effects.add(effect);
}
},
@ -72,8 +69,7 @@ export function component(anchor, get_component, render_fn) {
component_effect.ondestroy = () => {
for (const e of effects) {
// @ts-expect-error TODO tidy up. ondestroy should be totally unnecessary
if (e.d) remove(e.d);
if (e.dom) remove(e.dom);
}
};
}

@ -12,16 +12,17 @@ import { is_array } from '../../utils.js';
import { set_should_intro } from '../../render.js';
import { current_each_item_block, set_current_each_item_block } from './each.js';
import { create_block } from './utils.js';
import { current_block } from '../../runtime.js';
import { current_block, current_effect } from '../../runtime.js';
/**
* @param {import('#client').Block} block
* @param {import('#client').Effect} effect
* @param {Element} from
* @param {Element} to
* @returns {void}
*/
function swap_block_dom(block, from, to) {
const dom = block.d;
function swap_block_dom(block, effect, from, to) {
const dom = effect.dom;
if (is_array(dom)) {
for (let i = 0; i < dom.length; i++) {
if (dom[i] === from) {
@ -31,6 +32,7 @@ function swap_block_dom(block, from, to) {
}
} else if (dom === from) {
block.d = to;
effect.dom = to;
}
}
@ -42,6 +44,7 @@ function swap_block_dom(block, from, to) {
* @returns {void}
*/
export function element(anchor, get_tag, is_svg, render_fn) {
const parent_effect = /** @type {import('#client').Effect} */ (current_effect);
const parent_block = /** @type {import('#client').Block} */ (current_block);
const block = create_block();
@ -128,7 +131,7 @@ export function element(anchor, get_tag, is_svg, render_fn) {
anchor.before(element);
if (prev_element) {
swap_block_dom(parent_block, prev_element, element);
swap_block_dom(parent_block, parent_effect, prev_element, element);
prev_element.remove();
}
},

@ -10,7 +10,7 @@ import { remove } from '../reconciler.js';
import { create_block } from './utils.js';
/**
* @param {(anchor: Node | null) => void} render_fn
* @param {(anchor: Node | null) => import('#client').Dom | void} render_fn
* @returns {void}
*/
export function head(render_fn) {
@ -29,19 +29,22 @@ export function head(render_fn) {
}
try {
/** @type {import('#client').Dom | null} */
var dom = null;
const head_effect = render_effect(
() => {
const current = block.d;
if (current !== null) {
remove(current);
block.d = null;
if (dom !== null) {
remove(dom);
head_effect.dom = block.d = dom = null;
}
let anchor = null;
if (!hydrating) {
anchor = empty();
document.head.appendChild(anchor);
}
render_fn(anchor);
dom = render_fn(anchor) ?? null;
},
block,
false

@ -5,7 +5,7 @@ import {
create_fragment_with_script_from_html,
insert
} from './reconciler.js';
import { current_block } from '../runtime.js';
import { current_block, current_effect } from '../runtime.js';
import { is_array } from '../utils.js';
/**
@ -192,6 +192,7 @@ function close_template(dom, is_fragment, anchor) {
insert(current, anchor);
}
/** @type {import('#client').Effect} */ (current_effect).dom = current;
/** @type {import('#client').Block} */ (current_block).d = current;
return current;

@ -38,6 +38,7 @@ function create_effect(type, fn, sync, block = current_block, init = true) {
/** @type {import('#client').Effect} */
const signal = {
parent: current_effect,
dom: null,
block,
deps: null,
f: type | DIRTY,

@ -1,4 +1,4 @@
import type { Block, ComponentContext, Equals, TransitionManager } from '#client';
import type { Block, ComponentContext, Dom, Equals, TransitionManager } from '#client';
import type { EFFECT, PRE_EFFECT, RENDER_EFFECT } from '../constants';
export type EffectType = typeof EFFECT | typeof PRE_EFFECT | typeof RENDER_EFFECT;
@ -37,6 +37,7 @@ export interface Derived<V = unknown> extends Value<V>, Reaction {
export interface Effect extends Reaction {
parent: Effect | null;
dom: Dom | null;
/** The block associated with this effect */
block: null | Block;
/** The associated component context */

Loading…
Cancel
Save