Skip to content

Commit

Permalink
set window scroll from bindings on initialisation - fixes #938
Browse files Browse the repository at this point in the history
  • Loading branch information
Rich-Harris committed Apr 29, 2018
1 parent dbab1a8 commit 9e9a078
Show file tree
Hide file tree
Showing 8 changed files with 44 additions and 12 deletions.
4 changes: 2 additions & 2 deletions src/compile/dom/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { Ast, CompileOptions, Node } from '../../interfaces';
export class DomTarget {
blocks: (Block|string)[];
readonly: Set<string>;
metaBindings: string[];
metaBindings: CodeBuilder;

hasIntroTransitions: boolean;
hasOutroTransitions: boolean;
Expand All @@ -29,7 +29,7 @@ export class DomTarget {
this.readonly = new Set();

// initial values for e.g. window.innerWidth, if there's a <svelte:window> meta tag
this.metaBindings = [];
this.metaBindings = new CodeBuilder();
}
}

Expand Down
40 changes: 30 additions & 10 deletions src/compile/nodes/Window.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,14 +121,10 @@ export default class Window extends Node {
const property = properties[binding.name] || binding.name;

if (!events[associatedEvent]) events[associatedEvent] = [];
events[associatedEvent].push(
`${binding.value.node.name}: this.${property}`
);

// add initial value
compiler.target.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`);
Expand All @@ -137,13 +133,37 @@ export default class Window extends Node {

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}`;

compiler.target.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 => {
compiler.target.metaBindings.addLine(
`this._state.${prop.name} = window.${prop.value};`
);
});
}

const handlerBody = deindent`
Expand All @@ -154,7 +174,7 @@ export default class Window extends Node {
${compiler.options.dev && `component._updatingReadonlyProperty = true;`}
#component.set({
${props}
${props.map(prop => `${prop.name}: this.${prop.value}`)}
});
${compiler.options.dev && `component._updatingReadonlyProperty = false;`}
Expand Down
1 change: 1 addition & 0 deletions test/js/samples/computed-collapsed-if/expected-bundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ function create_main_fragment(component, ctx) {
function SvelteComponent(options) {
init(this, options);
this._state = assign({}, options.data);

this._recompute({ x: 1 }, this._state);

this._fragment = create_main_fragment(this, this._state);
Expand Down
1 change: 1 addition & 0 deletions test/js/samples/computed-collapsed-if/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ function create_main_fragment(component, ctx) {
function SvelteComponent(options) {
init(this, options);
this._state = assign({}, options.data);

this._recompute({ x: 1 }, this._state);

this._fragment = create_main_fragment(this, this._state);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ function SvelteComponent(options) {
if (!options || (!options.target && !options.root)) throw new Error("'target' is a required option");
init(this, options);
this._state = assign({ Math : Math }, options.data);

this._recompute({ foo: 1 }, this._state);
if (!('foo' in this._state)) console.warn("<SvelteComponent> was created without expected data property 'foo'");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ function SvelteComponent(options) {
if (!options || (!options.target && !options.root)) throw new Error("'target' is a required option");
init(this, options);
this._state = assign({ Math : Math }, options.data);

this._recompute({ foo: 1 }, this._state);
if (!('foo' in this._state)) console.warn("<SvelteComponent> was created without expected data property 'foo'");

Expand Down
4 changes: 4 additions & 0 deletions test/js/samples/window-binding-scroll/expected-bundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,10 @@ function create_main_fragment(component, ctx) {
function SvelteComponent(options) {
init(this, options);
this._state = assign({}, options.data);
if ("y" in this._state) {
window.scrollTo(window.pageXOffset, this._state.y);
}

this._state.y = window.pageYOffset;

this._fragment = create_main_fragment(this, this._state);
Expand Down
4 changes: 4 additions & 0 deletions test/js/samples/window-binding-scroll/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ function create_main_fragment(component, ctx) {
function SvelteComponent(options) {
init(this, options);
this._state = assign({}, options.data);
if ("y" in this._state) {
window.scrollTo(window.pageXOffset, this._state.y);
}

this._state.y = window.pageYOffset;

this._fragment = create_main_fragment(this, this._state);
Expand Down

0 comments on commit 9e9a078

Please sign in to comment.