diff --git a/src/compile/render-dom/Renderer.ts b/src/compile/render-dom/Renderer.ts index b1aa025049..d83e415f3b 100644 --- a/src/compile/render-dom/Renderer.ts +++ b/src/compile/render-dom/Renderer.ts @@ -22,7 +22,6 @@ export default class Renderer { hasIntroTransitions: boolean; hasOutroTransitions: boolean; - hasComplexBindings: boolean; constructor(component: Component, options: CompileOptions) { this.component = component; diff --git a/src/compile/render-dom/wrappers/InlineComponent/index.ts b/src/compile/render-dom/wrappers/InlineComponent/index.ts index 447e9c5c42..04bdb66358 100644 --- a/src/compile/render-dom/wrappers/InlineComponent/index.ts +++ b/src/compile/render-dom/wrappers/InlineComponent/index.ts @@ -99,7 +99,6 @@ export default class InlineComponentWrapper extends Wrapper { const name_initial_data = block.getUniqueName(`${name}_initial_data`); const name_changes = block.getUniqueName(`${name}_changes`); let name_updating: string; - let beforecreate: string = null; const updates: string[] = []; @@ -186,9 +185,39 @@ export default class InlineComponentWrapper extends Wrapper { } } - if (this.node.bindings.length) { - renderer.hasComplexBindings = true; + const munged_bindings = this.node.bindings.map(binding => { + const name = component.getUniqueName(`${this.var}_${binding.name}_binding`); + + const contextual_dependencies = Array.from(binding.expression.contextual_dependencies); + const dependencies = Array.from(binding.expression.dependencies); + const lhs = component.source.slice(binding.expression.node.start, binding.expression.node.end).trim(); + + const args = ['value']; + if (contextual_dependencies.length > 0) { + args.push(`{ ${contextual_dependencies.join(', ')} }`); + + block.builders.init.addBlock(deindent` + function ${name}(value) { + ctx.${name}.call(null, value, ctx); + } + `); + } + + const body = deindent` + function ${name}(${args.join(', ')}) { + ${lhs} = value; + ${dependencies.map(dep => `$$make_dirty('${dep}');`)} + } + `; + + component.event_handlers.push({ name, body }); + + return contextual_dependencies.length > 0 + ? `${this.var}.$$bind('${binding.name}', ${name});` + : `${this.var}.$$bind('${binding.name}', ctx.${name});`; + }); + if (this.node.bindings.length) { name_updating = block.alias(`${name}_updating`); block.addVariable(name_updating, '{}'); @@ -238,7 +267,7 @@ export default class InlineComponentWrapper extends Wrapper { if (${switch_value}) { var ${name} = new ${switch_value}(${switch_props}(ctx)); - ${beforecreate} + ${munged_bindings} } ${this.node.handlers.map(handler => deindent` @@ -292,13 +321,7 @@ export default class InlineComponentWrapper extends Wrapper { if (${switch_value}) { ${name} = new ${switch_value}(${switch_props}(ctx)); - ${this.node.bindings.length > 0 && deindent` - #component.$$root._beforecreate.push(() => { - const changed = {}; - ${this.node.bindings.map(binding => deindent` - if (${binding.expression.snippet} === void 0) changed.${binding.name} = 1;`)} - ${name}._bind(changed, ${name}.get()); - });`} + ${munged_bindings} ${name}.$$fragment.c(); ${this.fragment && this.fragment.nodes.map(child => child.remount(name))} @@ -342,7 +365,7 @@ export default class InlineComponentWrapper extends Wrapper { ${componentInitProperties.join(',\n')} }); - ${beforecreate} + ${munged_bindings} ${this.node.ref && `#component.$$refs.${this.node.ref.name} = ${name};`} `); @@ -413,31 +436,6 @@ export default class InlineComponentWrapper extends Wrapper { `); } - this.node.bindings.forEach(binding => { - const binding_name = component.getUniqueName(`${this.var}_${binding.name}_binding`); - - if (binding.expression.contextual_dependencies.size > 0) { - throw new Error(`TODO bindings with contextual dependencies`); - } else { - const lhs = component.source.slice(binding.expression.node.start, binding.expression.node.end); - const deps = Array.from(binding.expression.dependencies); - - component.event_handlers.push({ - name: binding_name, - body: deindent` - function ${binding_name}(value) { - ${lhs} = value; - ${deps.map(dep => `$$make_dirty('${dep}');`)} - } - ` - }); - - block.builders.init.addBlock(deindent` - ${this.var}.$$bind('${binding.name}', ctx.${binding_name}); - `); - } - }); - if (component.options.nestedTransitions) { block.builders.outro.addLine( `if (${name}) ${name}.$$fragment.o(#outrocallback);` diff --git a/src/internal/SvelteComponent.js b/src/internal/SvelteComponent.js index a39b6f819f..4adebf0920 100644 --- a/src/internal/SvelteComponent.js +++ b/src/internal/SvelteComponent.js @@ -60,7 +60,7 @@ export class SvelteComponent { $set(values) { if (this.$$) { this.$$.inject_props(values); - run_all(this.$$onprops); + run_all(this.$$onprops); // TODO should this be deferred until the update? for (const key in values) this.$$make_dirty(key); } diff --git a/src/internal/scheduler.js b/src/internal/scheduler.js index e2646d2755..aaebcb53f9 100644 --- a/src/internal/scheduler.js +++ b/src/internal/scheduler.js @@ -9,7 +9,7 @@ export function schedule_update(component) { dirty_components.push(component); if (!update_scheduled) { update_scheduled = true; - queueMicrotask(flush); + queue_microtask(flush); } } @@ -29,6 +29,6 @@ export function flush() { update_scheduled = false; } -function queueMicrotask(callback) { +function queue_microtask(callback) { Promise.resolve().then(callback); } \ No newline at end of file diff --git a/test/runtime/samples/dynamic-component-bindings/_config.js b/test/runtime/samples/dynamic-component-bindings/_config.js index 700f4099b9..c6c093cbc6 100644 --- a/test/runtime/samples/dynamic-component-bindings/_config.js +++ b/test/runtime/samples/dynamic-component-bindings/_config.js @@ -8,10 +8,10 @@ export default { `, - test(assert, component, target, window) { + async test(assert, component, target, window) { let input = target.querySelector('input'); input.value = 'abc'; - input.dispatchEvent(new window.Event('input')); + await input.dispatchEvent(new window.Event('input')); assert.equal(component.y, 'abc'); @@ -24,7 +24,7 @@ export default { input = target.querySelector('input'); input.checked = true; - input.dispatchEvent(new window.Event('change')); + await input.dispatchEvent(new window.Event('change')); assert.equal(component.z, true); } diff --git a/test/runtime/samples/refs-unset/main.html b/test/runtime/samples/refs-unset/main.html index 8024a67dfd..6dc6d654da 100644 --- a/test/runtime/samples/refs-unset/main.html +++ b/test/runtime/samples/refs-unset/main.html @@ -1,5 +1,6 @@ {#if x}