flush bindings in separate phase before render callbacks

pull/1864/head
Rich Harris 7 years ago
parent 0142031374
commit a1400eba07

@ -550,7 +550,7 @@ export default class ElementWrapper extends Wrapper {
renderer.hasComplexBindings = true; renderer.hasComplexBindings = true;
block.builders.hydrate.addLine( block.builders.hydrate.addLine(
`if (${someInitialStateIsUndefined}) @after_render(() => ${callee}.call(${this.var}));` `if (${someInitialStateIsUndefined}) @add_render_callback(() => ${callee}.call(${this.var}));`
); );
} }
@ -558,7 +558,7 @@ export default class ElementWrapper extends Wrapper {
renderer.hasComplexBindings = true; renderer.hasComplexBindings = true;
block.builders.hydrate.addLine( block.builders.hydrate.addLine(
`@after_render(() => ${callee}.call(${this.var}));` `@add_render_callback(() => ${callee}.call(${this.var}));`
); );
} }
}); });
@ -669,7 +669,7 @@ export default class ElementWrapper extends Wrapper {
block.builders.intro.addConditional(`@intro.enabled`, deindent` block.builders.intro.addConditional(`@intro.enabled`, deindent`
if (${name}) ${name}.invalidate(); if (${name}) ${name}.invalidate();
@after_render(() => { @add_render_callback(() => {
if (!${name}) ${name} = @wrapTransition(#component, ${this.var}, ${fn}, ${snippet}, true); if (!${name}) ${name} = @wrapTransition(#component, ${this.var}, ${fn}, ${snippet}, true);
${name}.run(1); ${name}.run(1);
}); });
@ -704,7 +704,7 @@ export default class ElementWrapper extends Wrapper {
} }
block.builders.intro.addConditional(`@intro.enabled`, deindent` block.builders.intro.addConditional(`@intro.enabled`, deindent`
@after_render(() => { @add_render_callback(() => {
${introName} = @wrapTransition(#component, ${this.var}, ${fn}, ${snippet}, true); ${introName} = @wrapTransition(#component, ${this.var}, ${fn}, ${snippet}, true);
${introName}.run(1); ${introName}.run(1);
}); });

@ -257,7 +257,7 @@ export default class InlineComponentWrapper extends Wrapper {
component.partly_hoisted.push(body); component.partly_hoisted.push(body);
return `${this.var}.$$bind('${binding.name}', ${name});`; return `@add_binding_callback(() => ${this.var}.$$bind('${binding.name}', ${name}));`;
}); });
const munged_handlers = this.node.handlers.map(handler => { const munged_handlers = this.node.handlers.map(handler => {

@ -119,7 +119,7 @@ export default class WindowWrapper extends Wrapper {
block.builders.init.addBlock(deindent` block.builders.init.addBlock(deindent`
window.addEventListener("${event}", ctx.${handler_name}); window.addEventListener("${event}", ctx.${handler_name});
@after_render(ctx.${handler_name}); @add_render_callback(ctx.${handler_name});
`); `);
block.builders.destroy.addBlock(deindent` block.builders.destroy.addBlock(deindent`

@ -1,4 +1,4 @@
import { after_render, flush, intro, schedule_update } from './scheduler.js'; import { add_render_callback, flush, intro, schedule_update } from './scheduler.js';
import { set_current_component } from './lifecycle.js' import { set_current_component } from './lifecycle.js'
import { is_function, run, run_all, noop } from './utils.js'; import { is_function, run, run_all, noop } from './utils.js';
import { blankObject } from './utils.js'; import { blankObject } from './utils.js';
@ -111,7 +111,7 @@ export class $$Component {
// onMount happens after the initial afterRender. Because // onMount happens after the initial afterRender. Because
// afterRender callbacks happen in reverse order (inner first) // afterRender callbacks happen in reverse order (inner first)
// we schedule onMount callbacks before afterRender callbacks // we schedule onMount callbacks before afterRender callbacks
after_render(() => { add_render_callback(() => {
const onDestroy = this.$$onMount.map(run).filter(is_function); const onDestroy = this.$$onMount.map(run).filter(is_function);
if (this.$$onDestroy) { if (this.$$onDestroy) {
this.$$onDestroy.push(...onDestroy); this.$$onDestroy.push(...onDestroy);
@ -123,7 +123,7 @@ export class $$Component {
this.$$onMount = []; this.$$onMount = [];
}); });
this.$$afterRender.forEach(after_render); this.$$afterRender.forEach(add_render_callback);
} }
$$update() { $$update() {
@ -132,7 +132,7 @@ export class $$Component {
this.$$.inject_refs(this.$$refs); this.$$.inject_refs(this.$$refs);
this.$$dirty = null; this.$$dirty = null;
this.$$afterRender.forEach(after_render); this.$$afterRender.forEach(add_render_callback);
} }
} }

@ -1,7 +1,8 @@
let update_scheduled = false; let update_scheduled = false;
let dirty_components = []; let dirty_components = [];
const after_render_callbacks = []; const binding_callbacks = [];
const render_callbacks = [];
export const intro = { enabled: false }; export const intro = { enabled: false };
@ -13,8 +14,12 @@ export function schedule_update(component) {
} }
} }
export function after_render(fn) { export function add_render_callback(fn) {
after_render_callbacks.push(fn); render_callbacks.push(fn);
}
export function add_binding_callback(fn) {
binding_callbacks.push(fn);
} }
export function flush() { export function flush() {
@ -27,11 +32,13 @@ export function flush() {
dirty_components.shift().$$update(); dirty_components.shift().$$update();
} }
while (binding_callbacks.length) binding_callbacks.pop()();
// then, once components are updated, call // then, once components are updated, call
// afterRender functions. This may cause // afterRender functions. This may cause
// subsequent updates... // subsequent updates...
while (after_render_callbacks.length) { while (render_callbacks.length) {
const callback = after_render_callbacks.pop(); const callback = render_callbacks.pop();
if (!seen_callbacks.has(callback)) { if (!seen_callbacks.has(callback)) {
callback(); callback();

@ -21,7 +21,7 @@ function tryToReadFile(file) {
describe("ssr", () => { describe("ssr", () => {
before(() => { before(() => {
require("../../ssr/register")({ require("../../register")({
extensions: ['.svelte', '.html'], extensions: ['.svelte', '.html'],
store: true store: true
}); });
@ -112,7 +112,7 @@ describe("ssr", () => {
const compileOptions = config.compileOptions || {}; const compileOptions = config.compileOptions || {};
require("../../ssr/register")(compileOptions); require("../../register")(compileOptions);
try { try {
const component = require(`../runtime/samples/${dir}/main.html`); const component = require(`../runtime/samples/${dir}/main.html`);

Loading…
Cancel
Save