diff --git a/src/internal/transitions.js b/src/internal/transitions.js index 6b2c5ba01e..1ba1c0ff0c 100644 --- a/src/internal/transitions.js +++ b/src/internal/transitions.js @@ -2,6 +2,7 @@ import { identity as linear, noop, run_all } from './utils.js'; import { loop } from './loop.js'; import { create_rule, delete_rule } from './style_manager.js'; import { custom_event } from './dom.js'; +import { add_render_callback } from './scheduler.js'; let promise; @@ -16,6 +17,10 @@ function wait() { return promise; } +function dispatch(node, direction, kind) { + node.dispatchEvent(custom_event(`${direction ? 'intro' : 'outro'}${kind}`)); +} + let outros; export function group_outros() { @@ -239,14 +244,14 @@ export function create_bidirectional_transition(node, fn, params, intro) { if (b) tick(0, 1); running_program = init(program, duration); - node.dispatchEvent(custom_event(`${running_program.b ? 'intro' : 'outro'}start`)); + add_render_callback(() => dispatch(node, b, 'start')) loop(now => { if (pending_program && now > pending_program.start) { running_program = init(pending_program, duration); pending_program = null; - node.dispatchEvent(custom_event(`${running_program.b ? 'intro' : 'outro'}start`)); + dispatch(node, running_program.b, 'start'); if (css) { clear_animation(); @@ -257,7 +262,7 @@ export function create_bidirectional_transition(node, fn, params, intro) { if (running_program) { if (now >= running_program.end) { tick(t = running_program.b, 1 - t); - node.dispatchEvent(custom_event(`${running_program.b ? 'intro' : 'outro'}end`)); + dispatch(node, running_program.b, 'end'); if (!pending_program) { // we're done diff --git a/test/runtime/samples/transition-js-events/_config.js b/test/runtime/samples/transition-js-events/_config.js index 05f4a0c887..00d83cb275 100644 --- a/test/runtime/samples/transition-js-events/_config.js +++ b/test/runtime/samples/transition-js-events/_config.js @@ -1,21 +1,51 @@ export default { props: { - visible: true, + visible: false, things: ['a', 'b', 'c', 'd'] }, - intro: true, + // intro: true, + + html: ` +
waiting...
+ `, + + async test({ assert, component, target, raf }) { + component.visible = true; + + assert.htmlEqual(target.innerHTML, ` +introstart
+a
+b
+c
+d
+ `); - test({ assert, component, target, window, raf }) { raf.tick(50); assert.deepEqual(component.intros.sort(), ['a', 'b', 'c', 'd']); assert.equal(component.intro_count, 4); - raf.tick(100); + await raf.tick(100); assert.equal(component.intro_count, 0); + assert.htmlEqual(target.innerHTML, ` +introend
+a
+b
+c
+d
+ `); + component.visible = false; + assert.htmlEqual(target.innerHTML, ` +outrostart
+a
+b
+c
+d
+ `); + raf.tick(150); assert.deepEqual(component.outros.sort(), ['a', 'b', 'c', 'd']); assert.equal(component.outro_count, 4); @@ -24,12 +54,17 @@ export default { assert.equal(component.outro_count, 0); component.visible = true; - component.$on('intro.start', () => { - throw new Error(`intro.start should fire during set(), not after`); - }); - raf.tick(250); + await raf.tick(250); assert.deepEqual(component.intros.sort(), ['a', 'a', 'b', 'b', 'c', 'c', 'd', 'd']); assert.equal(component.intro_count, 4); + + assert.htmlEqual(target.innerHTML, ` +introstart
+a
+b
+c
+d
+ `); } }; \ No newline at end of file diff --git a/test/runtime/samples/transition-js-events/main.svelte b/test/runtime/samples/transition-js-events/main.svelte index 909cfe981b..22ceb40006 100644 --- a/test/runtime/samples/transition-js-events/main.svelte +++ b/test/runtime/samples/transition-js-events/main.svelte @@ -9,6 +9,8 @@ export let intro_count = 0; export let outro_count = 0; + let status = 'waiting...'; + function foo(node, params) { return { duration: 100, @@ -21,22 +23,28 @@ function introstart(e) { intros.push(e.target.textContent); intro_count += 1; + status = 'introstart'; } function introend(e) { intro_count -= 1; + status = 'introend'; } function outrostart(e) { outros.push(e.target.textContent); outro_count += 1; + status = 'outrostart'; } function outroend(e) { outro_count -= 1; + status = 'outroend'; } +{status}
+ {#each things as thing} {#if visible}