diff --git a/src/compile/render-dom/wrappers/InlineComponent/index.ts b/src/compile/render-dom/wrappers/InlineComponent/index.ts index df81b13a54..c696f4813c 100644 --- a/src/compile/render-dom/wrappers/InlineComponent/index.ts +++ b/src/compile/render-dom/wrappers/InlineComponent/index.ts @@ -112,7 +112,6 @@ export default class InlineComponentWrapper extends Wrapper { const statements: string[] = []; const updates: string[] = []; - const postupdates: string[] = []; let props; const name_changes = block.get_unique_name(`${name}_changes`); @@ -311,8 +310,6 @@ export default class InlineComponentWrapper extends Wrapper { } `); - postupdates.push(updating); - const contextual_dependencies = Array.from(binding.expression.contextual_dependencies); const dependencies = Array.from(binding.expression.dependencies); @@ -334,9 +331,9 @@ export default class InlineComponentWrapper extends Wrapper { block.builders.init.add_block(deindent` function ${name}(${value}) { - if (ctx.${name}.call(null, ${value}, ctx)) { - ${updating} = true; - } + ctx.${name}.call(null, ${value}, ctx); + ${updating} = true; + @add_flush_callback(() => ${updating} = false); } `); @@ -344,9 +341,9 @@ export default class InlineComponentWrapper extends Wrapper { } else { block.builders.init.add_block(deindent` function ${name}(${value}) { - if (ctx.${name}.call(null, ${value})) { - ${updating} = true; - } + ctx.${name}.call(null, ${value}); + ${updating} = true; + @add_flush_callback(() => ${updating} = false); } `); } @@ -354,7 +351,7 @@ export default class InlineComponentWrapper extends Wrapper { const body = deindent` function ${name}(${args.join(', ')}) { ${lhs} = ${value}; - return ${component.invalidate(dependencies[0])} + ${component.invalidate(dependencies[0])}; } `; @@ -453,8 +450,6 @@ export default class InlineComponentWrapper extends Wrapper { else if (${switch_value}) { ${name}.$set(${name_changes}); } - - ${postupdates.length > 0 && `${postupdates.join(' = ')} = false;`} `); } @@ -498,7 +493,6 @@ export default class InlineComponentWrapper extends Wrapper { block.builders.update.add_block(deindent` ${updates} ${name}.$set(${name_changes}); - ${postupdates.length > 0 && `${postupdates.join(' = ')} = false;`} `); } diff --git a/src/internal/Component.js b/src/internal/Component.js index 4a7293ddae..530a48da59 100644 --- a/src/internal/Component.js +++ b/src/internal/Component.js @@ -85,16 +85,9 @@ export function init(component, options, instance, create_fragment, not_equal, p $$.ctx = instance ? instance(component, props, (key, value) => { - if ($$.bound[key]) $$.bound[key](value); - - if ($$.ctx) { - const changed = not_equal(value, $$.ctx[key]); - if (ready && changed) { - make_dirty(component, key); - } - - $$.ctx[key] = value; - return changed; + if ($$.ctx && not_equal($$.ctx[key], $$.ctx[key] = value)) { + if ($$.bound[key]) $$.bound[key](value); + if (ready) make_dirty(component, key); } }) : props; diff --git a/src/internal/scheduler.js b/src/internal/scheduler.js index b2b5bd5200..bc4f01197b 100644 --- a/src/internal/scheduler.js +++ b/src/internal/scheduler.js @@ -7,6 +7,7 @@ export const intros = { enabled: false }; let update_promise; const binding_callbacks = []; const render_callbacks = []; +const flush_callbacks = []; export function schedule_update() { if (!update_promise) { @@ -15,10 +16,6 @@ export function schedule_update() { } } -export function add_render_callback(fn) { - render_callbacks.push(fn); -} - export function tick() { schedule_update(); return update_promise; @@ -28,6 +25,14 @@ export function add_binding_callback(fn) { binding_callbacks.push(fn); } +export function add_render_callback(fn) { + render_callbacks.push(fn); +} + +export function add_flush_callback(fn) { + flush_callbacks.push(fn); +} + export function flush() { const seen_callbacks = new Set(); @@ -56,6 +61,10 @@ export function flush() { } } while (dirty_components.length); + while (flush_callbacks.length) { + flush_callbacks.pop()(); + } + update_promise = null; } diff --git a/test/runtime/samples/component-binding-blowback-d/One.svelte b/test/runtime/samples/component-binding-blowback-d/One.svelte new file mode 100644 index 0000000000..f86da72ff2 --- /dev/null +++ b/test/runtime/samples/component-binding-blowback-d/One.svelte @@ -0,0 +1,18 @@ + + +{#each list as item, j} + +{/each} + + \ No newline at end of file diff --git a/test/runtime/samples/component-binding-blowback-d/Two.svelte b/test/runtime/samples/component-binding-blowback-d/Two.svelte new file mode 100644 index 0000000000..b33a987b75 --- /dev/null +++ b/test/runtime/samples/component-binding-blowback-d/Two.svelte @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/test/runtime/samples/component-binding-blowback-d/_config.js b/test/runtime/samples/component-binding-blowback-d/_config.js new file mode 100644 index 0000000000..1716eb6ff9 --- /dev/null +++ b/test/runtime/samples/component-binding-blowback-d/_config.js @@ -0,0 +1,23 @@ +export default { + html: ` + + + +

{"value":"0:0"}

+

+ `, + + async test({ assert, target, window }) { + const button = target.querySelectorAll('button')[1]; + + await button.dispatchEvent(new window.Event('click')); + + assert.htmlEqual(target.innerHTML, ` + + + +

{"value":"0:0"}

+

{"value":"1:0"}

+ `); + } +}; diff --git a/test/runtime/samples/component-binding-blowback-d/main.svelte b/test/runtime/samples/component-binding-blowback-d/main.svelte new file mode 100644 index 0000000000..d6e9412618 --- /dev/null +++ b/test/runtime/samples/component-binding-blowback-d/main.svelte @@ -0,0 +1,14 @@ + + + + + +

{obj.a.map(JSON.stringify)}

+

{obj.b.map(JSON.stringify)}

\ No newline at end of file diff --git a/test/runtime/samples/component-binding-blowback-e/One.svelte b/test/runtime/samples/component-binding-blowback-e/One.svelte new file mode 100644 index 0000000000..f86da72ff2 --- /dev/null +++ b/test/runtime/samples/component-binding-blowback-e/One.svelte @@ -0,0 +1,18 @@ + + +{#each list as item, j} + +{/each} + + \ No newline at end of file diff --git a/test/runtime/samples/component-binding-blowback-e/Two.svelte b/test/runtime/samples/component-binding-blowback-e/Two.svelte new file mode 100644 index 0000000000..a622f559e2 --- /dev/null +++ b/test/runtime/samples/component-binding-blowback-e/Two.svelte @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/test/runtime/samples/component-binding-blowback-e/_config.js b/test/runtime/samples/component-binding-blowback-e/_config.js new file mode 100644 index 0000000000..1c0e6aa0e1 --- /dev/null +++ b/test/runtime/samples/component-binding-blowback-e/_config.js @@ -0,0 +1,23 @@ +export default { + html: ` + + + +

{"value":{"i":0,"j":0}}

+

+ `, + + async test({ assert, target, window }) { + const button = target.querySelectorAll('button')[1]; + + await button.dispatchEvent(new window.Event('click')); + + assert.htmlEqual(target.innerHTML, ` + + + +

{"value":{"i":0,"j":0}}

+

{"value":{"i":1,"j":0}}

+ `); + } +}; diff --git a/test/runtime/samples/component-binding-blowback-e/main.svelte b/test/runtime/samples/component-binding-blowback-e/main.svelte new file mode 100644 index 0000000000..d6e9412618 --- /dev/null +++ b/test/runtime/samples/component-binding-blowback-e/main.svelte @@ -0,0 +1,14 @@ + + + + + +

{obj.a.map(JSON.stringify)}

+

{obj.b.map(JSON.stringify)}

\ No newline at end of file diff --git a/test/runtime/samples/component-binding-blowback-f/One.svelte b/test/runtime/samples/component-binding-blowback-f/One.svelte new file mode 100644 index 0000000000..f86da72ff2 --- /dev/null +++ b/test/runtime/samples/component-binding-blowback-f/One.svelte @@ -0,0 +1,18 @@ + + +{#each list as item, j} + +{/each} + + \ No newline at end of file diff --git a/test/runtime/samples/component-binding-blowback-f/Two.svelte b/test/runtime/samples/component-binding-blowback-f/Two.svelte new file mode 100644 index 0000000000..94caa7878d --- /dev/null +++ b/test/runtime/samples/component-binding-blowback-f/Two.svelte @@ -0,0 +1,10 @@ + \ No newline at end of file diff --git a/test/runtime/samples/component-binding-blowback-f/_config.js b/test/runtime/samples/component-binding-blowback-f/_config.js new file mode 100644 index 0000000000..46f6b379f6 --- /dev/null +++ b/test/runtime/samples/component-binding-blowback-f/_config.js @@ -0,0 +1,31 @@ +export default { + html: ` + + + +

{"value":{"i":0,"j":0}}

+

+ `, + + ssrHtml: ` + + + +

{}

+

+ `, + + async test({ assert, target, window }) { + const button = target.querySelectorAll('button')[1]; + + await button.dispatchEvent(new window.Event('click')); + + assert.htmlEqual(target.innerHTML, ` + + + +

{"value":{"i":0,"j":0}}

+

{"value":{"i":1,"j":0}}

+ `); + } +}; diff --git a/test/runtime/samples/component-binding-blowback-f/main.svelte b/test/runtime/samples/component-binding-blowback-f/main.svelte new file mode 100644 index 0000000000..d6e9412618 --- /dev/null +++ b/test/runtime/samples/component-binding-blowback-f/main.svelte @@ -0,0 +1,14 @@ + + + + + +

{obj.a.map(JSON.stringify)}

+

{obj.b.map(JSON.stringify)}

\ No newline at end of file