chore: more transition code-golfing (#9536)

pull/9343/head
Dominic Gannaway 1 year ago committed by GitHub
parent 699c337908
commit bd2a586fea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,5 @@
---
'svelte': patch
---
chore: more transition code-golfing

@ -35,8 +35,14 @@ export function create_root_block(intro) {
/** @returns {import('./types.js').IfBlock} */ /** @returns {import('./types.js').IfBlock} */
export function create_if_block() { export function create_if_block() {
return { return {
// current // alternate transitions
c: false, a: null,
// alternate effect
ae: null,
// consequent transitions
c: null,
// consequent effect
ce: null,
// dom // dom
d: null, d: null,
// effect // effect
@ -46,7 +52,9 @@ export function create_if_block() {
// transition // transition
r: null, r: null,
// type // type
t: IF_BLOCK t: IF_BLOCK,
// value
v: false
}; };
} }

@ -70,7 +70,7 @@ import {
} from './hydration.js'; } from './hydration.js';
import { array_from, define_property, get_descriptor, get_descriptors, is_array } from './utils.js'; import { array_from, define_property, get_descriptor, get_descriptors, is_array } from './utils.js';
import { is_promise } from '../common.js'; import { is_promise } from '../common.js';
import { bind_transition, remove_in_transitions, trigger_transitions } from './transitions.js'; import { bind_transition, trigger_transitions } from './transitions.js';
/** @type {Set<string>} */ /** @type {Set<string>} */
const all_registerd_events = new Set(); const all_registerd_events = new Set();
@ -1355,8 +1355,6 @@ export function slot(anchor_node, slot_fn, slot_props, fallback_fn) {
function if_block(anchor_node, condition_fn, consequent_fn, alternate_fn) { function if_block(anchor_node, condition_fn, consequent_fn, alternate_fn) {
const block = create_if_block(); const block = create_if_block();
hydrate_block_anchor(anchor_node); hydrate_block_anchor(anchor_node);
const consequent_transitions = new Set();
const alternate_transitions = new Set();
const previous_hydration_fragment = current_hydration_fragment; const previous_hydration_fragment = current_hydration_fragment;
/** @type {null | import('./types.js').TemplateNode | Array<import('./types.js').TemplateNode>} */ /** @type {null | import('./types.js').TemplateNode | Array<import('./types.js').TemplateNode>} */
@ -1366,59 +1364,32 @@ function if_block(anchor_node, condition_fn, consequent_fn, alternate_fn) {
let has_mounted = false; let has_mounted = false;
let has_mounted_branch = false; let has_mounted_branch = false;
block.r =
/**
* @param {import('./types.js').Transition} transition
* @returns {void}
*/
(transition) => {
// block.current
if (block.c) {
consequent_transitions.add(transition);
transition.f(() => {
consequent_transitions.delete(transition);
remove_in_transitions(consequent_transitions);
if (consequent_transitions.size === 0) {
execute_effect(consequent_effect);
}
});
} else {
alternate_transitions.add(transition);
transition.f(() => {
alternate_transitions.delete(transition);
remove_in_transitions(alternate_transitions);
if (alternate_transitions.size === 0) {
execute_effect(alternate_effect);
}
});
}
};
const if_effect = render_effect( const if_effect = render_effect(
() => { () => {
const result = !!condition_fn(); const result = !!condition_fn();
if (block.c !== result || !has_mounted) { if (block.v !== result || !has_mounted) {
block.c = result; block.v = result;
if (has_mounted) { if (has_mounted) {
const consequent_transitions = block.c;
const alternate_transitions = block.a;
if (result) { if (result) {
remove_in_transitions(alternate_transitions); if (alternate_transitions === null || alternate_transitions.size === 0) {
if (alternate_transitions.size === 0) {
execute_effect(alternate_effect); execute_effect(alternate_effect);
} else { } else {
trigger_transitions(alternate_transitions, 'out'); trigger_transitions(alternate_transitions, 'out');
} }
if (consequent_transitions.size === 0) { if (consequent_transitions === null || consequent_transitions.size === 0) {
execute_effect(consequent_effect); execute_effect(consequent_effect);
} else { } else {
trigger_transitions(consequent_transitions, 'in'); trigger_transitions(consequent_transitions, 'in');
} }
} else { } else {
remove_in_transitions(consequent_transitions); if (consequent_transitions === null || consequent_transitions.size === 0) {
if (consequent_transitions.size === 0) {
execute_effect(consequent_effect); execute_effect(consequent_effect);
} else { } else {
trigger_transitions(consequent_transitions, 'out'); trigger_transitions(consequent_transitions, 'out');
} }
if (alternate_transitions.size === 0) { if (alternate_transitions === null || alternate_transitions.size === 0) {
execute_effect(alternate_effect); execute_effect(alternate_effect);
} else { } else {
trigger_transitions(alternate_transitions, 'in'); trigger_transitions(alternate_transitions, 'in');
@ -1455,7 +1426,7 @@ function if_block(anchor_node, condition_fn, consequent_fn, alternate_fn) {
remove(consequent_dom); remove(consequent_dom);
consequent_dom = null; consequent_dom = null;
} }
if (block.c) { if (block.v) {
consequent_fn(anchor_node); consequent_fn(anchor_node);
if (!has_mounted_branch) { if (!has_mounted_branch) {
// Restore previous fragment so that Svelte continues to operate in hydration mode // Restore previous fragment so that Svelte continues to operate in hydration mode
@ -1469,6 +1440,7 @@ function if_block(anchor_node, condition_fn, consequent_fn, alternate_fn) {
block, block,
true true
); );
block.ce = consequent_effect;
// Managed effect // Managed effect
const alternate_effect = render_effect( const alternate_effect = render_effect(
() => { () => {
@ -1476,7 +1448,7 @@ function if_block(anchor_node, condition_fn, consequent_fn, alternate_fn) {
remove(alternate_dom); remove(alternate_dom);
alternate_dom = null; alternate_dom = null;
} }
if (!block.c) { if (!block.v) {
if (alternate_fn !== null) { if (alternate_fn !== null) {
alternate_fn(anchor_node); alternate_fn(anchor_node);
} }
@ -1492,6 +1464,7 @@ function if_block(anchor_node, condition_fn, consequent_fn, alternate_fn) {
block, block,
true true
); );
block.ae = alternate_effect;
push_destroy_fn(if_effect, () => { push_destroy_fn(if_effect, () => {
if (consequent_dom !== null) { if (consequent_dom !== null) {
remove(consequent_dom); remove(consequent_dom);
@ -1676,7 +1649,6 @@ export function component(anchor_node, component_fn, render_fn) {
transitions.add(transition); transitions.add(transition);
transition.f(() => { transition.f(() => {
transitions.delete(transition); transitions.delete(transition);
remove_in_transitions(transitions);
if (transitions.size === 0) { if (transitions.size === 0) {
if (render.e !== null) { if (render.e !== null) {
if (render.d !== null) { if (render.d !== null) {
@ -1724,7 +1696,6 @@ export function component(anchor_node, component_fn, render_fn) {
return; return;
} }
const transitions = render.s; const transitions = render.s;
remove_in_transitions(transitions);
if (transitions.size === 0) { if (transitions.size === 0) {
if (render.d !== null) { if (render.d !== null) {
remove(render.d); remove(render.d);
@ -1804,7 +1775,6 @@ function await_block(anchor_node, input, pending_fn, then_fn, catch_fn) {
transitions.add(transition); transitions.add(transition);
transition.f(() => { transition.f(() => {
transitions.delete(transition); transitions.delete(transition);
remove_in_transitions(transitions);
if (transitions.size === 0) { if (transitions.size === 0) {
if (render.e !== null) { if (render.e !== null) {
if (render.d !== null) { if (render.d !== null) {
@ -1861,7 +1831,6 @@ function await_block(anchor_node, input, pending_fn, then_fn, catch_fn) {
return; return;
} }
const transitions = render.s; const transitions = render.s;
remove_in_transitions(transitions);
if (transitions.size === 0) { if (transitions.size === 0) {
if (render.d !== null) { if (render.d !== null) {
remove(render.d); remove(render.d);
@ -1966,7 +1935,6 @@ export function key(anchor_node, key, render_fn) {
transitions.add(transition); transitions.add(transition);
transition.f(() => { transition.f(() => {
transitions.delete(transition); transitions.delete(transition);
remove_in_transitions(transitions);
if (transitions.size === 0) { if (transitions.size === 0) {
if (render.e !== null) { if (render.e !== null) {
if (render.d !== null) { if (render.d !== null) {
@ -2007,7 +1975,6 @@ export function key(anchor_node, key, render_fn) {
return; return;
} }
const transitions = render.s; const transitions = render.s;
remove_in_transitions(transitions);
if (transitions.size === 0) { if (transitions.size === 0) {
if (render.d !== null) { if (render.d !== null) {
remove(render.d); remove(render.d);
@ -2195,7 +2162,6 @@ function each(anchor_node, collection, flags, key_fn, render_fn, fallback_fn, re
transitions.add(transition); transitions.add(transition);
transition.f(() => { transition.f(() => {
transitions.delete(transition); transitions.delete(transition);
remove_in_transitions(transitions);
if (transitions.size === 0) { if (transitions.size === 0) {
if (fallback.e !== null) { if (fallback.e !== null) {
if (fallback.d !== null) { if (fallback.d !== null) {

@ -15,6 +15,7 @@ import {
current_effect, current_effect,
destroy_signal, destroy_signal,
effect, effect,
execute_effect,
managed_effect, managed_effect,
managed_pre_effect, managed_pre_effect,
mark_subtree_inert, mark_subtree_inert,
@ -418,7 +419,8 @@ export function bind_transition(dom, transition_fn, props_fn, direction, global)
const block = current_block; const block = current_block;
const props = props_fn === null ? {} : props_fn(); const props = props_fn === null ? {} : props_fn();
let skip_intro = true; let can_show_intro_on_mount = true;
let can_apply_lazy_transitions = false;
/** @type {import('./types.js').Block | null} */ /** @type {import('./types.js').Block | null} */
let transition_block = block; let transition_block = block;
@ -429,19 +431,22 @@ export function bind_transition(dom, transition_fn, props_fn, direction, global)
transition_block.r = each_item_transition; transition_block.r = each_item_transition;
transition_block = transition_block.p; transition_block = transition_block.p;
} else if (transition_block.t === AWAIT_BLOCK && transition_block.n /* pending */) { } else if (transition_block.t === AWAIT_BLOCK && transition_block.n /* pending */) {
skip_intro = false; can_show_intro_on_mount = false;
} else if (transition_block.t === IF_BLOCK) {
transition_block.r = if_block_transition;
} }
if (skip_intro) { if (!can_apply_lazy_transitions && can_show_intro_on_mount) {
skip_intro = transition_block.e === null; can_show_intro_on_mount = transition_block.e === null;
} }
if (!skip_intro || !global) { if (!can_show_intro_on_mount || !global) {
break; can_apply_lazy_transitions = true;
} }
} else if ( } else if (
!can_apply_lazy_transitions &&
transition_block.t === ROOT_BLOCK && transition_block.t === ROOT_BLOCK &&
(transition_block.e !== null || transition_block.i) (transition_block.e !== null || transition_block.i)
) { ) {
skip_intro = false; can_show_intro_on_mount = false;
} }
transition_block = transition_block.p; transition_block = transition_block.p;
} }
@ -467,7 +472,7 @@ export function bind_transition(dom, transition_fn, props_fn, direction, global)
transition = create_transition(dom, init, direction, transition_effect); transition = create_transition(dom, init, direction, transition_effect);
const is_intro = direction === 'in'; const is_intro = direction === 'in';
const show_intro = !skip_intro && (is_intro || direction === 'both'); const show_intro = !can_show_intro_on_mount && (is_intro || direction === 'both');
if (show_intro) { if (show_intro) {
transition.p = transition.i(); transition.p = transition.i();
@ -483,7 +488,7 @@ export function bind_transition(dom, transition_fn, props_fn, direction, global)
/** @type {import('./types.js').Block | null} */ /** @type {import('./types.js').Block | null} */
let transition_block = block; let transition_block = block;
while (transition_block !== null) { while (!is_intro && transition_block !== null) {
const parent = transition_block.p; const parent = transition_block.p;
if (is_transition_block(transition_block)) { if (is_transition_block(transition_block)) {
if (transition_block.r !== null) { if (transition_block.r !== null) {
@ -491,7 +496,7 @@ export function bind_transition(dom, transition_fn, props_fn, direction, global)
} }
if ( if (
parent === null || parent === null ||
(!global && (transition_block.t !== IF_BLOCK || parent.t !== IF_BLOCK || parent.c)) (!global && (transition_block.t !== IF_BLOCK || parent.t !== IF_BLOCK || parent.v))
) { ) {
break; break;
} }
@ -510,18 +515,6 @@ export function bind_transition(dom, transition_fn, props_fn, direction, global)
} }
} }
/**
* @param {Set<import('./types.js').Transition>} transitions
*/
export function remove_in_transitions(transitions) {
for (let transition of transitions) {
const direction = transition.r;
if (direction === 'in') {
transitions.delete(transition);
}
}
}
/** /**
* @param {Set<import('./types.js').Transition>} transitions * @param {Set<import('./types.js').Transition>} transitions
* @param {'in' | 'out' | 'key'} target_direction * @param {'in' | 'out' | 'key'} target_direction
@ -567,6 +560,43 @@ export function trigger_transitions(transitions, target_direction, from) {
} }
} }
/**
* @this {import('./types.js').IfBlock}
* @param {import('./types.js').Transition} transition
* @returns {void}
*/
function if_block_transition(transition) {
const block = this;
// block.value === true
if (block.v) {
let consequent_transitions = block.c;
if (consequent_transitions === null) {
consequent_transitions = block.c = new Set();
}
consequent_transitions.add(transition);
transition.f(() => {
const c = /** @type {Set<import('./types.js').Transition>} */ (consequent_transitions);
c.delete(transition);
if (c.size === 0) {
execute_effect(/** @type {import('./types.js').EffectSignal} */ (block.ce));
}
});
} else {
let alternate_transitions = block.a;
if (alternate_transitions === null) {
alternate_transitions = block.a = new Set();
}
alternate_transitions.add(transition);
transition.f(() => {
const a = /** @type {Set<import('./types.js').Transition>} */ (alternate_transitions);
a.delete(transition);
if (a.size === 0) {
execute_effect(/** @type {import('./types.js').EffectSignal} */ (block.ae));
}
});
}
}
/** /**
* @this {import('./types.js').EachItemBlock} * @this {import('./types.js').EachItemBlock}
* @param {import('./types.js').Transition} transition * @param {import('./types.js').Transition} transition

@ -165,16 +165,24 @@ export type RootBlock = {
}; };
export type IfBlock = { export type IfBlock = {
/** current */ /** value */
c: boolean; v: boolean;
/** dom */ /** dom */
d: null | TemplateNode | Array<TemplateNode>; d: null | TemplateNode | Array<TemplateNode>;
/** effect */ /** effect */
e: null | ComputationSignal; e: null | EffectSignal;
/** parent */ /** parent */
p: Block; p: Block;
/** transition */ /** transition */
r: null | ((transition: Transition) => void); r: null | ((transition: Transition) => void);
/** consequent transitions */
c: null | Set<Transition>;
/** alternate transitions */
a: null | Set<Transition>;
/** effect */
ce: null | EffectSignal;
/** effect */
ae: null | EffectSignal;
/** type */ /** type */
t: typeof IF_BLOCK; t: typeof IF_BLOCK;
}; };
@ -183,7 +191,7 @@ export type KeyBlock = {
/** dom */ /** dom */
d: null | TemplateNode | Array<TemplateNode>; d: null | TemplateNode | Array<TemplateNode>;
/** effect */ /** effect */
e: null | ComputationSignal; e: null | EffectSignal;
/** parent */ /** parent */
p: Block; p: Block;
/** transition */ /** transition */

Loading…
Cancel
Save