From cbf8b13658ce6edf72ba4d952fbe99693a28aaf9 Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Fri, 1 Nov 2019 17:13:08 +0800 Subject: [PATCH] fix window bindings to store --- .../compile/render_dom/wrappers/Window.ts | 10 +- test/helpers.js | 1 + .../window-binding-scroll-store/expected.js | 133 ++++++++++++++++++ .../window-binding-scroll-store/input.svelte | 15 ++ .../window-binding-scroll-store/_config.js | 31 ++++ .../window-binding-scroll-store/main.svelte | 15 ++ 6 files changed, 203 insertions(+), 2 deletions(-) create mode 100644 test/js/samples/window-binding-scroll-store/expected.js create mode 100644 test/js/samples/window-binding-scroll-store/input.svelte create mode 100644 test/runtime/samples/window-binding-scroll-store/_config.js create mode 100644 test/runtime/samples/window-binding-scroll-store/main.svelte diff --git a/src/compiler/compile/render_dom/wrappers/Window.ts b/src/compiler/compile/render_dom/wrappers/Window.ts index 90846f8a7c..e36f55722a 100644 --- a/src/compiler/compile/render_dom/wrappers/Window.ts +++ b/src/compiler/compile/render_dom/wrappers/Window.ts @@ -127,7 +127,11 @@ export default class WindowWrapper extends Wrapper { component.partly_hoisted.push(b` function ${id}() { - ${props.map(prop => b`$$invalidate('${prop.name}', ${prop.name} = @_window.${prop.value});`)} + ${props.map(prop => + prop.name[0] === '$' + ? b`${prop.name.slice(1)}.set(${prop.name} = @_window.${prop.value});` + : b`$$invalidate('${prop.name}', ${prop.name} = @_window.${prop.value});` + )} } `); @@ -165,9 +169,11 @@ export default class WindowWrapper extends Wrapper { referenced: true }); + const invalidate = name[0] === '$' ? b`${name.slice(1)}.set(${name} = @_navigator.onLine)` : b`$$invalidate('${name}', ${name} = @_navigator.onLine);`; + component.partly_hoisted.push(b` function ${id}() { - $$invalidate('${name}', ${name} = @_navigator.onLine); + ${invalidate} } `); diff --git a/test/helpers.js b/test/helpers.js index 6ac20eed8b..5a2d1403f0 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -52,6 +52,7 @@ global.document = window.document; global.navigator = window.navigator; global.getComputedStyle = window.getComputedStyle; global.requestAnimationFrame = null; // placeholder, filled in using set_raf +global.window = window; // add missing ecmascript globals to window for (const key of Object.getOwnPropertyNames(global)) { diff --git a/test/js/samples/window-binding-scroll-store/expected.js b/test/js/samples/window-binding-scroll-store/expected.js new file mode 100644 index 0000000000..6237991da0 --- /dev/null +++ b/test/js/samples/window-binding-scroll-store/expected.js @@ -0,0 +1,133 @@ +import { + SvelteComponent, + add_render_callback, + append, + component_subscribe, + detach, + element, + init, + insert, + listen, + noop, + safe_not_equal, + set_data, + set_style, + space, + text +} from "svelte/internal"; + +import { writable, derived } from "svelte/store"; + +function create_fragment(ctx) { + let scrolling = false; + + let clear_scrolling = () => { + scrolling = false; + }; + + let scrolling_timeout; + let p; + let t0; + let t1; + let t2; + let t3; + let t4; + let t5; + let t6; + let t7; + let t8; + let div; + let dispose; + add_render_callback(ctx.onwindowscroll); + + return { + c() { + p = element("p"); + t0 = text("scroll y is "); + t1 = text(ctx.$y); + t2 = text(". "); + t3 = text(ctx.$y); + t4 = text(" * "); + t5 = text(ctx.$y); + t6 = text(" = "); + t7 = text(ctx.$y_squared); + t8 = space(); + div = element("div"); + set_style(p, "position", "fixed"); + set_style(p, "top", "1em"); + set_style(p, "left", "1em"); + set_style(div, "height", "9999px"); + + dispose = listen(window, "scroll", () => { + scrolling = true; + clearTimeout(scrolling_timeout); + scrolling_timeout = setTimeout(clear_scrolling, 100); + ctx.onwindowscroll(); + }); + }, + m(target, anchor) { + insert(target, p, anchor); + append(p, t0); + append(p, t1); + append(p, t2); + append(p, t3); + append(p, t4); + append(p, t5); + append(p, t6); + append(p, t7); + insert(target, t8, anchor); + insert(target, div, anchor); + }, + p(changed, ctx) { + if (changed.$y && !scrolling) { + scrolling = true; + clearTimeout(scrolling_timeout); + scrollTo(window.pageXOffset, ctx.$y); + scrolling_timeout = setTimeout(clear_scrolling, 100); + } + + if (changed.$y) set_data(t1, ctx.$y); + if (changed.$y) set_data(t3, ctx.$y); + if (changed.$y) set_data(t5, ctx.$y); + if (changed.$y_squared) set_data(t7, ctx.$y_squared); + }, + i: noop, + o: noop, + d(detaching) { + if (detaching) detach(p); + if (detaching) detach(t8); + if (detaching) detach(div); + dispose(); + } + }; +} + +function instance($$self, $$props, $$invalidate) { + let $y; + let $y_squared; + const y = writable(0); + component_subscribe($$self, y, value => $$invalidate("$y", $y = value)); + const y_squared = derived(y, $y => $y * $y); + component_subscribe($$self, y_squared, value => $$invalidate("$y_squared", $y_squared = value)); + + function onwindowscroll() { + y.set($y = window.pageYOffset); + } + + return { + y, + y_squared, + $y, + $y_squared, + onwindowscroll + }; +} + +class Component extends SvelteComponent { + constructor(options) { + super(); + init(this, options, instance, create_fragment, safe_not_equal, {}); + } +} + +export default Component; \ No newline at end of file diff --git a/test/js/samples/window-binding-scroll-store/input.svelte b/test/js/samples/window-binding-scroll-store/input.svelte new file mode 100644 index 0000000000..fe225520d7 --- /dev/null +++ b/test/js/samples/window-binding-scroll-store/input.svelte @@ -0,0 +1,15 @@ + + + + +

+ scroll y is {$y}. {$y} * {$y} = {$y_squared} +

+ +
+ +
\ No newline at end of file diff --git a/test/runtime/samples/window-binding-scroll-store/_config.js b/test/runtime/samples/window-binding-scroll-store/_config.js new file mode 100644 index 0000000000..abddb86765 --- /dev/null +++ b/test/runtime/samples/window-binding-scroll-store/_config.js @@ -0,0 +1,31 @@ +export default { + skip_if_ssr: true, + + async test({ assert, component, target, window }) { + assert.equal(window.pageYOffset, 0); + + const event = new window.Event('scroll'); + Object.defineProperties(window, { + pageYOffset: { + value: 234, + configurable: true, + }, + }); + + await window.dispatchEvent(event); + + assert.htmlEqual( + target.innerHTML, + `

scroll\ny\nis\n234.\n234\n*\n234\n=\n54756

` + ); + }, + + after_test() { + Object.defineProperties(window, { + pageYOffset: { + value: 0, + configurable: true, + }, + }); + }, +}; diff --git a/test/runtime/samples/window-binding-scroll-store/main.svelte b/test/runtime/samples/window-binding-scroll-store/main.svelte new file mode 100644 index 0000000000..fe225520d7 --- /dev/null +++ b/test/runtime/samples/window-binding-scroll-store/main.svelte @@ -0,0 +1,15 @@ + + + + +

+ scroll y is {$y}. {$y} * {$y} = {$y_squared} +

+ +
+ +
\ No newline at end of file