From d6f25a6a21e7fe458c4b044076cc82abb7173bf4 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sun, 28 Oct 2018 08:32:20 -0400 Subject: [PATCH] redo 9e9a078d on top of current master --- src/compile/render-dom/Renderer.ts | 5 ++- src/compile/render-dom/wrappers/Window.ts | 40 ++++++++++++++----- .../samples/window-binding-scroll/expected.js | 1 - 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/compile/render-dom/Renderer.ts b/src/compile/render-dom/Renderer.ts index c49a110d85..9ed6210457 100644 --- a/src/compile/render-dom/Renderer.ts +++ b/src/compile/render-dom/Renderer.ts @@ -2,6 +2,7 @@ import Block from './Block'; import { CompileOptions } from '../../interfaces'; import Component from '../Component'; import FragmentWrapper from './wrappers/Fragment'; +import CodeBuilder from '../../utils/CodeBuilder'; export default class Renderer { component: Component; // TODO Maybe Renderer shouldn't know about Component? @@ -10,7 +11,7 @@ export default class Renderer { blocks: (Block | string)[]; readonly: Set; slots: Set; - metaBindings: string[]; + metaBindings: CodeBuilder; bindingGroups: string[]; block: Block; @@ -35,7 +36,7 @@ export default class Renderer { this.fileVar = options.dev && this.component.getUniqueName('file'); // initial values for e.g. window.innerWidth, if there's a meta tag - this.metaBindings = []; + this.metaBindings = new CodeBuilder(); this.bindingGroups = []; diff --git a/src/compile/render-dom/wrappers/Window.ts b/src/compile/render-dom/wrappers/Window.ts index 8adb3b053e..c26cf5ecb1 100644 --- a/src/compile/render-dom/wrappers/Window.ts +++ b/src/compile/render-dom/wrappers/Window.ts @@ -97,14 +97,10 @@ export default class WindowWrapper extends Wrapper { const property = properties[binding.name] || binding.name; if (!events[associatedEvent]) events[associatedEvent] = []; - events[associatedEvent].push( - `${binding.value.node.name}: this.${property}` - ); - - // add initial value - renderer.metaBindings.push( - `this._state.${binding.value.node.name} = window.${property};` - ); + events[associatedEvent].push({ + name: binding.value.node.name, + value: property + }); }); const lock = block.getUniqueName(`window_updating`); @@ -113,13 +109,35 @@ export default class WindowWrapper extends Wrapper { Object.keys(events).forEach(event => { const handlerName = block.getUniqueName(`onwindow${event}`); - const props = events[event].join(',\n'); + const props = events[event]; if (event === 'scroll') { // TODO other bidirectional bindings... block.addVariable(lock, 'false'); block.addVariable(clear, `function() { ${lock} = false; }`); block.addVariable(timeout); + + const condition = [ + bindings.scrollX && `"${bindings.scrollX}" in this._state`, + bindings.scrollY && `"${bindings.scrollY}" in this._state` + ].filter(Boolean).join(' || '); + + const x = bindings.scrollX && `this._state.${bindings.scrollX}`; + const y = bindings.scrollY && `this._state.${bindings.scrollY}`; + + renderer.metaBindings.addBlock(deindent` + if (${condition}) { + window.scrollTo(${x || 'window.pageXOffset'}, ${y || 'window.pageYOffset'}); + } + ${x && `${x} = window.pageXOffset;`} + ${y && `${y} = window.pageYOffset;`} + `); + } else { + props.forEach(prop => { + renderer.metaBindings.addLine( + `this._state.${prop.name} = window.${prop.value};` + ); + }); } const handlerBody = deindent` @@ -130,7 +148,7 @@ export default class WindowWrapper extends Wrapper { ${component.options.dev && `component._updatingReadonlyProperty = true;`} #component.set({ - ${props} + ${props.map(prop => `${prop.name}: this.${prop.value}`)} }); ${component.options.dev && `component._updatingReadonlyProperty = false;`} @@ -185,7 +203,7 @@ export default class WindowWrapper extends Wrapper { `); // add initial value - renderer.metaBindings.push( + renderer.metaBindings.addLine( `this._state.${bindings.online} = navigator.onLine;` ); diff --git a/test/js/samples/window-binding-scroll/expected.js b/test/js/samples/window-binding-scroll/expected.js index 0a2da39892..6fc66443b9 100644 --- a/test/js/samples/window-binding-scroll/expected.js +++ b/test/js/samples/window-binding-scroll/expected.js @@ -59,7 +59,6 @@ function SvelteComponent(options) { if ("y" in this._state) { window.scrollTo(window.pageXOffset, this._state.y); } - this._state.y = window.pageYOffset; this._intro = true;