wait until flush complete before unlocking bindings - fixes #2356

pull/2415/head
Richard Harris 5 years ago
parent b03cfcf09d
commit 5535110066

@ -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);
@ -333,9 +330,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);
}
`);
@ -343,9 +340,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);
}
`);
}
@ -353,7 +350,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])};
}
`;
@ -452,8 +449,6 @@ export default class InlineComponentWrapper extends Wrapper {
else if (${switch_value}) {
${name}.$set(${name_changes});
}
${postupdates.length > 0 && `${postupdates.join(' = ')} = false;`}
`);
}
@ -497,7 +492,6 @@ export default class InlineComponentWrapper extends Wrapper {
block.builders.update.add_block(deindent`
${updates}
${name}.$set(${name_changes});
${postupdates.length > 0 && `${postupdates.join(' = ')} = false;`}
`);
}

@ -85,15 +85,9 @@ export function init(component, options, instance, create_fragment, not_equal, p
$$.ctx = instance
? instance(component, props, (key, value) => {
if ($$.ctx) {
const changed = not_equal(value, $$.ctx[key]);
if (ready && changed) {
if ($$.bound[key]) $$.bound[key](value);
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;

@ -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;
}

@ -2,14 +2,15 @@
import Two from './Two.svelte';
export let list;
export let i;
function handle_click() {
list = [...list, {}];
}
</script>
{#each list as item}
<Two bind:value={item.value}/>
{#each list as item, j}
<Two bind:value={item.value} {i} {j}/>
{/each}
<button on:click={handle_click}>

@ -1,3 +1,4 @@
<script>
export let value = 'x';
export let i, j;
export let value = `${i}:${j}`;
</script>

@ -3,7 +3,7 @@ export default {
<button>click me</button>
<button>click me</button>
<p>{"value":"x"}</p>
<p>{"value":"0:0"}</p>
<p></p>
`,
@ -16,8 +16,8 @@ export default {
<button>click me</button>
<button>click me</button>
<p>{"value":"x"}</p>
<p>{"value":"x"}</p>
<p>{"value":"0:0"}</p>
<p>{"value":"1:0"}</p>
`);
}
};

@ -7,8 +7,8 @@
};
</script>
<One bind:list={obj.a}/>
<One bind:list={obj.b}/>
<One bind:list={obj.a} i={0}/>
<One bind:list={obj.b} i={1}/>
<p>{obj.a.map(JSON.stringify)}</p>
<p>{obj.b.map(JSON.stringify)}</p>

@ -2,14 +2,15 @@
import Two from './Two.svelte';
export let list;
export let i;
function handle_click() {
list = [...list, {}];
}
</script>
{#each list as item}
<Two bind:value={item.value}/>
{#each list as item, j}
<Two bind:value={item.value} {i} {j}/>
{/each}
<button on:click={handle_click}>

@ -1,3 +1,4 @@
<script>
export let value = { x: true };
export let i, j;
export let value = { i, j };
</script>

@ -3,7 +3,7 @@ export default {
<button>click me</button>
<button>click me</button>
<p>{"value":{"x":true}}</p>
<p>{"value":{"i":0,"j":0}}</p>
<p></p>
`,
@ -16,8 +16,8 @@ export default {
<button>click me</button>
<button>click me</button>
<p>{"value":{"x":true}}</p>
<p>{"value":{"x":true}}</p>
<p>{"value":{"i":0,"j":0}}</p>
<p>{"value":{"i":1,"j":0}}</p>
`);
}
};

@ -7,8 +7,8 @@
};
</script>
<One bind:list={obj.a}/>
<One bind:list={obj.b}/>
<One bind:list={obj.a} i={0}/>
<One bind:list={obj.b} i={1}/>
<p>{obj.a.map(JSON.stringify)}</p>
<p>{obj.b.map(JSON.stringify)}</p>

@ -2,14 +2,15 @@
import Two from './Two.svelte';
export let list;
export let i;
function handle_click() {
list = [...list, {}];
}
</script>
{#each list as item}
<Two bind:value={item.value}/>
{#each list as item, j}
<Two bind:value={item.value} {i} {j}/>
{/each}
<button on:click={handle_click}>

@ -1,9 +1,10 @@
<script>
import { onMount } from 'svelte';
export let i, j;
export let value;
onMount(() => {
value = { x: true };
value = { i, j };
});
</script>

@ -1,11 +1,17 @@
export default {
skip: 1,
html: `
<button>click me</button>
<button>click me</button>
<p>{"value":{"x":true}}</p>
<p>{"value":{"i":0,"j":0}}</p>
<p></p>
`,
ssrHtml: `
<button>click me</button>
<button>click me</button>
<p>{}</p>
<p></p>
`,
@ -18,8 +24,8 @@ export default {
<button>click me</button>
<button>click me</button>
<p>{"value":{"x":true}}</p>
<p>{"value":{"x":true}}</p>
<p>{"value":{"i":0,"j":0}}</p>
<p>{"value":{"i":1,"j":0}}</p>
`);
}
};

@ -7,8 +7,8 @@
};
</script>
<One bind:list={obj.a}/>
<One bind:list={obj.b}/>
<One bind:list={obj.a} i={0}/>
<One bind:list={obj.b} i={1}/>
<p>{obj.a.map(JSON.stringify)}</p>
<p>{obj.b.map(JSON.stringify)}</p>
Loading…
Cancel
Save