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

return a promise from init #100

Merged
merged 2 commits into from
Jan 21, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 36 additions & 32 deletions src/runtime/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { detach, findAnchor, scroll_state, which } from './utils';
import { Component, ComponentConstructor, Params, Query, Route, RouteData, ScrollPosition } from './interfaces';
import { Component, ComponentConstructor, Params, Query, Route, RouteData, ScrollPosition, Target } from './interfaces';

export let component: Component;
let target: Node;
Expand All @@ -19,7 +19,7 @@ if ('scrollRestoration' in history) {
history.scrollRestoration = 'manual';
}

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

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

return { route, data: { params, query } };
return { url, route, data: { params, query } };
}
}
}
Expand Down Expand Up @@ -83,35 +83,31 @@ function prepare_route(Component: ComponentConstructor, data: RouteData) {
});
}

function navigate(url: URL, id: number) {
const selected = select_route(url);
if (selected) {
if (id) {
// popstate or initial navigation
cid = id;
} else {
// clicked on a link. preserve scroll state
scroll_history[cid] = scroll_state();

id = cid = ++uid;
scroll_history[cid] = { x: 0, y: 0 };
}
function navigate(target: Target, id: number) {
if (id) {
// popstate or initial navigation
cid = id;
} else {
// clicked on a link. preserve scroll state
scroll_history[cid] = scroll_state();

id = cid = ++uid;
scroll_history[cid] = { x: 0, y: 0 };
}

const loaded = prefetching && prefetching.href === url.href ?
prefetching.promise :
selected.route.load().then(mod => prepare_route(mod.default, selected.data));
cid = id;

prefetching = null;
const loaded = prefetching && prefetching.href === target.url.href ?
prefetching.promise :
target.route.load().then(mod => prepare_route(mod.default, target.data));

const token = current_token = {};
prefetching = null;

loaded.then(({ Component, data }) => {
render(Component, data, scroll_history[id], token);
});
const token = current_token = {};

cid = id;
return true;
}
return loaded.then(({ Component, data }) => {
render(Component, data, scroll_history[id], token);
});
}

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

if (navigate(url, null)) {
const target = select_route(url);
if (target) {
navigate(target, null);
event.preventDefault();
history.pushState({ id: cid }, '', url.href);
}
Expand All @@ -157,7 +155,9 @@ function handle_popstate(event: PopStateEvent) {
scroll_history[cid] = scroll_state();

if (event.state) {
navigate(new URL(window.location.href), event.state.id);
const url = new URL(window.location.href);
const target = select_route(url);
navigate(target, event.state.id);
} else {
// hashchange
cid = ++uid;
Expand Down Expand Up @@ -205,7 +205,7 @@ export function init(_target: Node, _routes: Route[]) {
inited = true;
}

setTimeout(() => {
return Promise.resolve().then(() => {
const { hash, href } = window.location;

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

history.replaceState({ id: uid }, '', href);
navigate(new URL(window.location.href), uid);

const target = select_route(new URL(window.location.href));
return navigate(target, uid);
});
}

export function goto(href: string, opts = { replaceState: false }) {
if (navigate(new URL(href, window.location.href), null)) {
const target = select_route(new URL(href, window.location.href));
if (target) {
navigate(target, null);
if (history) history[opts.replaceState ? 'replaceState' : 'pushState']({ id: cid }, '', href);
} else {
window.location.href = href;
Expand Down
6 changes: 6 additions & 0 deletions src/runtime/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,10 @@ export type Route = {
export type ScrollPosition = {
x: number;
y: number;
};

export type Target = {
url: URL;
route: Route;
data: RouteData;
};
3 changes: 1 addition & 2 deletions test/app/templates/main.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { init } from '../../../runtime.js';

window.init = () => {
init(document.querySelector('#sapper'), __routes__);
window.READY = true;
return init(document.querySelector('#sapper'), __routes__);
};
12 changes: 4 additions & 8 deletions test/common/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ function run(env) {
});

it('navigates to a new page without reloading', () => {
return nightmare.goto(base).init().wait(200)
return nightmare.goto(base).init().wait(100)
.then(() => {
return capture(() => nightmare.click('a[href="/about"]'));
})
Expand All @@ -204,7 +204,6 @@ function run(env) {
return nightmare
.goto(`${base}/about`)
.init()
.wait(100)
.click('.goto')
.wait(() => window.location.pathname === '/blog/what-is-sapper')
.wait(100)
Expand All @@ -218,7 +217,6 @@ function run(env) {
return nightmare
.goto(`${base}/about`)
.init()
.wait(100)
.then(() => {
return capture(() => {
return nightmare
Expand All @@ -235,7 +233,6 @@ function run(env) {
return nightmare
.goto(`${base}/blog/a-very-long-post#four`)
.init()
.wait(100)
.evaluate(() => window.scrollY)
.then(scrollY => {
assert.ok(scrollY > 0, scrollY);
Expand All @@ -245,8 +242,7 @@ function run(env) {
it('reuses prefetch promise', () => {
return nightmare
.goto(`${base}/blog`)
.init()
.wait(200)
.init().wait(100)
.then(() => {
return capture(() => {
return nightmare
Expand Down Expand Up @@ -310,7 +306,7 @@ function run(env) {
it('calls a delete handler', () => {
return nightmare
.goto(`${base}/delete-test`)
.init().wait(100)
.init()
.click('.del')
.wait(() => window.deleted)
.evaluate(() => window.deleted.id)
Expand All @@ -325,7 +321,7 @@ function run(env) {
.evaluate(() => {
window.el = document.querySelector('.hydrate-test');
})
.init().wait(100)
.init()
.evaluate(() => {
return document.querySelector('.hydrate-test') === window.el;
})
Expand Down