diff --git a/index.mjs b/index.mjs index 44031c35c8..1ba5890537 100644 --- a/index.mjs +++ b/index.mjs @@ -3,5 +3,6 @@ export { onDestroy, beforeUpdate, afterUpdate, + nextTick, createEventDispatcher } from './internal'; diff --git a/src/internal/Component.js b/src/internal/Component.js index 8df1d7aee5..4eac8d57af 100644 --- a/src/internal/Component.js +++ b/src/internal/Component.js @@ -1,4 +1,4 @@ -import { add_render_callback, flush, intros, schedule_update } from './scheduler.js'; +import { add_render_callback, flush, intros, schedule_update, dirty_components } from './scheduler.js'; import { current_component, set_current_component } from './lifecycle.js' import { is_function, run, run_all, noop } from './utils.js'; import { blankObject } from './utils.js'; @@ -46,7 +46,8 @@ function destroy(component, detach) { function make_dirty(component, key) { if (!component.$$.dirty) { - schedule_update(component); + dirty_components.push(component); + schedule_update(); component.$$.dirty = {}; } component.$$.dirty[key] = true; diff --git a/src/internal/scheduler.js b/src/internal/scheduler.js index 962c321fd6..0626db2a97 100644 --- a/src/internal/scheduler.js +++ b/src/internal/scheduler.js @@ -1,15 +1,13 @@ import { run_all } from './utils.js'; -let update_scheduled = false; +export let dirty_components = []; +export const intros = { enabled: false }; -let dirty_components = []; +let update_scheduled = false; const binding_callbacks = []; const render_callbacks = []; -export const intros = { enabled: false }; - -export function schedule_update(component) { - dirty_components.push(component); +export function schedule_update() { if (!update_scheduled) { update_scheduled = true; queue_microtask(flush); @@ -20,6 +18,11 @@ export function add_render_callback(fn) { render_callbacks.push(fn); } +export function nextTick(fn) { + add_render_callback(fn); + schedule_update(); +} + export function add_binding_callback(fn) { binding_callbacks.push(fn); } diff --git a/test/runtime/samples/lifecycle-next-tick/_config.js b/test/runtime/samples/lifecycle-next-tick/_config.js new file mode 100644 index 0000000000..35a66f7a09 --- /dev/null +++ b/test/runtime/samples/lifecycle-next-tick/_config.js @@ -0,0 +1,30 @@ +export default { + async test({ assert, component, target, window }) { + const buttons = target.querySelectorAll('button'); + const click = new window.MouseEvent('click'); + + await buttons[0].dispatchEvent(click); + assert.deepEqual(component.snapshots, [ + 'before 0', + 'after 1' + ]); + + await buttons[0].dispatchEvent(click); + assert.deepEqual(component.snapshots, [ + 'before 0', + 'after 1', + 'before 1', + 'after 2' + ]); + + await buttons[1].dispatchEvent(click); + assert.deepEqual(component.snapshots, [ + 'before 0', + 'after 1', + 'before 1', + 'after 2', + 'before 2', + 'after 2' + ]); + } +}; diff --git a/test/runtime/samples/lifecycle-next-tick/main.html b/test/runtime/samples/lifecycle-next-tick/main.html new file mode 100644 index 0000000000..f7a889d433 --- /dev/null +++ b/test/runtime/samples/lifecycle-next-tick/main.html @@ -0,0 +1,24 @@ + + + + \ No newline at end of file