diff --git a/src/runtime/internal/scheduler.ts b/src/runtime/internal/scheduler.ts index 568739e4f8..cc93a6af53 100644 --- a/src/runtime/internal/scheduler.ts +++ b/src/runtime/internal/scheduler.ts @@ -1,7 +1,7 @@ -import { run_all } from './utils'; +import { run_all, Queue } from './utils'; import { set_current_component } from './lifecycle'; -export const dirty_components = []; +export const dirty_components = new Queue(); export const intros = { enabled: false }; export const binding_callbacks = []; @@ -31,17 +31,14 @@ export function add_flush_callback(fn) { flush_callbacks.push(fn); } -let flushing = false; const seen_callbacks = new Set(); export function flush() { - if (flushing) return; - flushing = true; do { // first, call beforeUpdate functions // and update components - for (let i = 0; i < dirty_components.length; i += 1) { - const component = dirty_components[i]; + while (dirty_components.length) { + const component = dirty_components.shift(); set_current_component(component); update(component.$$); } @@ -73,7 +70,6 @@ export function flush() { } update_scheduled = false; - flushing = false; seen_callbacks.clear(); } diff --git a/src/runtime/internal/utils.ts b/src/runtime/internal/utils.ts index 8868e38ee2..582870ec32 100644 --- a/src/runtime/internal/utils.ts +++ b/src/runtime/internal/utils.ts @@ -58,6 +58,40 @@ export function is_empty(obj) { return Object.keys(obj).length === 0; } +export class Queue { + forward: T[]; + reverse: T[]; + + constructor() { + this.forward = []; + this.reverse = []; + } + push(value: T) { + return this.forward.push(value); + } + shift() { + if (this.reverse.length === 0) { + while (this.forward.length) { + this.reverse.push(this.forward.pop()); + } + } + return this.reverse.pop(); + } + get length() { + return this.forward.length + this.reverse.length; + } + set length(len: number) { + if (len === 0) { + this.forward.length = 0; + this.reverse.length = 0; + } else { + while (this.length > len) { + this.shift(); + } + } + } +} + export function validate_store(store, name) { if (store != null && typeof store.subscribe !== 'function') { throw new Error(`'${name}' is not a store with a 'subscribe' method`); diff --git a/test/runtime/samples/component-binding-onMount/Mount.svelte b/test/runtime/samples/component-binding-onMount/Mount.svelte new file mode 100644 index 0000000000..ce3b0c48f8 --- /dev/null +++ b/test/runtime/samples/component-binding-onMount/Mount.svelte @@ -0,0 +1,15 @@ + + +
+

+ Bound? {bound} +

diff --git a/test/runtime/samples/component-binding-onMount/_config.js b/test/runtime/samples/component-binding-onMount/_config.js new file mode 100644 index 0000000000..4ae78b588a --- /dev/null +++ b/test/runtime/samples/component-binding-onMount/_config.js @@ -0,0 +1,11 @@ +export default { + async test({ assert, target }) { + assert.htmlEqual(target.innerHTML, ` +
+

+ Bound? true +

+
+ `); + } +}; diff --git a/test/runtime/samples/component-binding-onMount/main.svelte b/test/runtime/samples/component-binding-onMount/main.svelte new file mode 100644 index 0000000000..971b13c1ce --- /dev/null +++ b/test/runtime/samples/component-binding-onMount/main.svelte @@ -0,0 +1,13 @@ + + +