diff --git a/src/runtime/internal/scheduler.ts b/src/runtime/internal/scheduler.ts index 568739e4f8..61628c495d 100644 --- a/src/runtime/internal/scheduler.ts +++ b/src/runtime/internal/scheduler.ts @@ -33,6 +33,8 @@ export function add_flush_callback(fn) { let flushing = false; const seen_callbacks = new Set(); +let dirty_binding_component_map = new Map(); + export function flush() { if (flushing) return; flushing = true; @@ -43,14 +45,19 @@ export function flush() { for (let i = 0; i < dirty_components.length; i += 1) { const component = dirty_components[i]; set_current_component(component); - update(component.$$); + const is_dirty_from_binding = dirty_binding_component_map.has(component.constructor.name); + update(component.$$, is_dirty_from_binding); } + dirty_binding_component_map = new Map(); set_current_component(null); dirty_components.length = 0; - while (binding_callbacks.length) binding_callbacks.pop()(); - + while (binding_callbacks.length) { + binding_callbacks.pop()(); + } + dirty_components.forEach((i) => + dirty_binding_component_map.set(i.constructor.name, i)); // then, once components are updated, call // afterUpdate functions. This may cause // subsequent updates... @@ -77,14 +84,14 @@ export function flush() { seen_callbacks.clear(); } -function update($$) { +function update($$, is_dirty_from_binding) { if ($$.fragment !== null) { $$.update(); - run_all($$.before_update); + if (!is_dirty_from_binding) run_all($$.before_update); const dirty = $$.dirty; $$.dirty = [-1]; $$.fragment && $$.fragment.p($$.ctx, dirty); - + // if (!is_dirty_from_binding) run_all($$.after_update); $$.after_update.forEach(add_render_callback); } } diff --git a/test/runtime/samples/lifecycle-render-order-for-children-with-binding/Item.svelte b/test/runtime/samples/lifecycle-render-order-for-children-with-binding/Item.svelte new file mode 100755 index 0000000000..85d47d5245 --- /dev/null +++ b/test/runtime/samples/lifecycle-render-order-for-children-with-binding/Item.svelte @@ -0,0 +1,30 @@ + + +
  • + {logRender()} +
  • diff --git a/test/runtime/samples/lifecycle-render-order-for-children-with-binding/_config.js b/test/runtime/samples/lifecycle-render-order-for-children-with-binding/_config.js new file mode 100644 index 0000000000..32bc35d49c --- /dev/null +++ b/test/runtime/samples/lifecycle-render-order-for-children-with-binding/_config.js @@ -0,0 +1,49 @@ +import order from './order.js'; + +export default { + skip_if_ssr: true, + before_test() { + order.length = 0; + }, + test({ assert, compileOptions }) { + if (compileOptions.hydratable) { + assert.deepEqual(order, [ + '0: beforeUpdate', + '0: render', + '1: beforeUpdate', + '1: render', + '2: beforeUpdate', + '2: render', + '3: beforeUpdate', + '3: render', + '1: onMount', + '1: afterUpdate', + '2: onMount', + '2: afterUpdate', + '3: onMount', + '3: afterUpdate', + '0: onMount', + '0: afterUpdate' + ]); + } else { + assert.deepEqual(order, [ + '0: beforeUpdate', + '0: render', + '1: beforeUpdate', + '2: beforeUpdate', + '3: beforeUpdate', + '1: render', + '2: render', + '3: render', + '1: onMount', + '1: afterUpdate', + '2: onMount', + '2: afterUpdate', + '3: onMount', + '3: afterUpdate', + '0: onMount', + '0: afterUpdate' + ]); + } + } +}; diff --git a/test/runtime/samples/lifecycle-render-order-for-children-with-binding/main.svelte b/test/runtime/samples/lifecycle-render-order-for-children-with-binding/main.svelte new file mode 100644 index 0000000000..c5061d3218 --- /dev/null +++ b/test/runtime/samples/lifecycle-render-order-for-children-with-binding/main.svelte @@ -0,0 +1,34 @@ + + +{logRender()} + + + diff --git a/test/runtime/samples/lifecycle-render-order-for-children-with-binding/order.js b/test/runtime/samples/lifecycle-render-order-for-children-with-binding/order.js new file mode 100644 index 0000000000..d6d1738de6 --- /dev/null +++ b/test/runtime/samples/lifecycle-render-order-for-children-with-binding/order.js @@ -0,0 +1 @@ +export default [];