Skip to content
This repository was archived by the owner on Jan 11, 2023. It is now read-only.

Commit a09c33d

Browse files
committed
return a promise from init - fixes #99
1 parent 4590aa3 commit a09c33d

File tree

4 files changed

+46
-41
lines changed

4 files changed

+46
-41
lines changed

src/runtime/index.ts

+36-32
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { detach, findAnchor, scroll_state, which } from './utils';
2-
import { Component, ComponentConstructor, Params, Query, Route, RouteData, ScrollPosition } from './interfaces';
2+
import { Component, ComponentConstructor, Params, Query, Route, RouteData, ScrollPosition, Target } from './interfaces';
33

44
export let component: Component;
55
let target: Node;
@@ -19,7 +19,7 @@ if ('scrollRestoration' in history) {
1919
history.scrollRestoration = 'manual';
2020
}
2121

22-
function select_route(url: URL): { route: Route, data: RouteData } {
22+
function select_route(url: URL): Target {
2323
if (url.origin !== window.location.origin) return null;
2424

2525
for (const route of routes) {
@@ -30,7 +30,7 @@ function select_route(url: URL): { route: Route, data: RouteData } {
3030
const query: Record<string, string | true> = {};
3131
for (const [key, value] of url.searchParams) query[key] = value || true;
3232

33-
return { route, data: { params, query } };
33+
return { url, route, data: { params, query } };
3434
}
3535
}
3636
}
@@ -83,35 +83,31 @@ function prepare_route(Component: ComponentConstructor, data: RouteData) {
8383
});
8484
}
8585

86-
function navigate(url: URL, id: number) {
87-
const selected = select_route(url);
88-
if (selected) {
89-
if (id) {
90-
// popstate or initial navigation
91-
cid = id;
92-
} else {
93-
// clicked on a link. preserve scroll state
94-
scroll_history[cid] = scroll_state();
95-
96-
id = cid = ++uid;
97-
scroll_history[cid] = { x: 0, y: 0 };
98-
}
86+
function navigate(target: Target, id: number) {
87+
if (id) {
88+
// popstate or initial navigation
89+
cid = id;
90+
} else {
91+
// clicked on a link. preserve scroll state
92+
scroll_history[cid] = scroll_state();
93+
94+
id = cid = ++uid;
95+
scroll_history[cid] = { x: 0, y: 0 };
96+
}
9997

100-
const loaded = prefetching && prefetching.href === url.href ?
101-
prefetching.promise :
102-
selected.route.load().then(mod => prepare_route(mod.default, selected.data));
98+
cid = id;
10399

104-
prefetching = null;
100+
const loaded = prefetching && prefetching.href === target.url.href ?
101+
prefetching.promise :
102+
target.route.load().then(mod => prepare_route(mod.default, target.data));
105103

106-
const token = current_token = {};
104+
prefetching = null;
107105

108-
loaded.then(({ Component, data }) => {
109-
render(Component, data, scroll_history[id], token);
110-
});
106+
const token = current_token = {};
111107

112-
cid = id;
113-
return true;
114-
}
108+
return loaded.then(({ Component, data }) => {
109+
render(Component, data, scroll_history[id], token);
110+
});
115111
}
116112

117113
function handle_click(event: MouseEvent) {
@@ -147,7 +143,9 @@ function handle_click(event: MouseEvent) {
147143
// Don't handle hash changes
148144
if (url.pathname === window.location.pathname && url.search === window.location.search) return;
149145

150-
if (navigate(url, null)) {
146+
const target = select_route(url);
147+
if (target) {
148+
navigate(target, null);
151149
event.preventDefault();
152150
history.pushState({ id: cid }, '', url.href);
153151
}
@@ -157,7 +155,9 @@ function handle_popstate(event: PopStateEvent) {
157155
scroll_history[cid] = scroll_state();
158156

159157
if (event.state) {
160-
navigate(new URL(window.location.href), event.state.id);
158+
const url = new URL(window.location.href);
159+
const target = select_route(url);
160+
navigate(target, event.state.id);
161161
} else {
162162
// hashchange
163163
cid = ++uid;
@@ -205,7 +205,7 @@ export function init(_target: Node, _routes: Route[]) {
205205
inited = true;
206206
}
207207

208-
setTimeout(() => {
208+
return Promise.resolve().then(() => {
209209
const { hash, href } = window.location;
210210

211211
const deep_linked = hash && document.querySelector(hash);
@@ -214,12 +214,16 @@ export function init(_target: Node, _routes: Route[]) {
214214
scroll_state();
215215

216216
history.replaceState({ id: uid }, '', href);
217-
navigate(new URL(window.location.href), uid);
217+
218+
const target = select_route(new URL(window.location.href));
219+
return navigate(target, uid);
218220
});
219221
}
220222

221223
export function goto(href: string, opts = { replaceState: false }) {
222-
if (navigate(new URL(href, window.location.href), null)) {
224+
const target = select_route(new URL(href, window.location.href));
225+
if (target) {
226+
navigate(target, null);
223227
if (history) history[opts.replaceState ? 'replaceState' : 'pushState']({ id: cid }, '', href);
224228
} else {
225229
window.location.href = href;

src/runtime/interfaces.ts

+6
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,10 @@ export type Route = {
2020
export type ScrollPosition = {
2121
x: number;
2222
y: number;
23+
};
24+
25+
export type Target = {
26+
url: URL;
27+
route: Route;
28+
data: RouteData;
2329
};

test/app/templates/main.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { init } from '../../../runtime.js';
22

33
window.init = () => {
4-
init(document.querySelector('#sapper'), __routes__);
5-
window.READY = true;
4+
return init(document.querySelector('#sapper'), __routes__);
65
};

test/common/test.js

+3-7
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ function run(env) {
183183
});
184184

185185
it('navigates to a new page without reloading', () => {
186-
return nightmare.goto(base).init().wait(200)
186+
return nightmare.goto(base).init().wait(100)
187187
.then(() => {
188188
return capture(() => nightmare.click('a[href="/about"]'));
189189
})
@@ -204,7 +204,6 @@ function run(env) {
204204
return nightmare
205205
.goto(`${base}/about`)
206206
.init()
207-
.wait(100)
208207
.click('.goto')
209208
.wait(() => window.location.pathname === '/blog/what-is-sapper')
210209
.wait(100)
@@ -218,7 +217,6 @@ function run(env) {
218217
return nightmare
219218
.goto(`${base}/about`)
220219
.init()
221-
.wait(100)
222220
.then(() => {
223221
return capture(() => {
224222
return nightmare
@@ -235,7 +233,6 @@ function run(env) {
235233
return nightmare
236234
.goto(`${base}/blog/a-very-long-post#four`)
237235
.init()
238-
.wait(100)
239236
.evaluate(() => window.scrollY)
240237
.then(scrollY => {
241238
assert.ok(scrollY > 0, scrollY);
@@ -246,7 +243,6 @@ function run(env) {
246243
return nightmare
247244
.goto(`${base}/blog`)
248245
.init()
249-
.wait(200)
250246
.then(() => {
251247
return capture(() => {
252248
return nightmare
@@ -310,7 +306,7 @@ function run(env) {
310306
it('calls a delete handler', () => {
311307
return nightmare
312308
.goto(`${base}/delete-test`)
313-
.init().wait(100)
309+
.init()
314310
.click('.del')
315311
.wait(() => window.deleted)
316312
.evaluate(() => window.deleted.id)
@@ -325,7 +321,7 @@ function run(env) {
325321
.evaluate(() => {
326322
window.el = document.querySelector('.hydrate-test');
327323
})
328-
.init().wait(100)
324+
.init()
329325
.evaluate(() => {
330326
return document.querySelector('.hydrate-test') === window.el;
331327
})

0 commit comments

Comments
 (0)