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

Commit 13c2b0c

Browse files
committed
Organize routing functions
1 parent d654504 commit 13c2b0c

File tree

6 files changed

+272
-256
lines changed

6 files changed

+272
-256
lines changed

runtime/src/app/app.ts

Lines changed: 18 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
11
import { writable } from 'svelte/store';
22
import App from '@sapper/internal/App.svelte';
3-
import { Query } from '@sapper/internal/shared';
3+
import {
4+
extract_query,
5+
init,
6+
load_current_page,
7+
select_target
8+
} from './router';
49
import {
510
DOMComponentLoader,
611
DOMComponentModule,
712
ErrorComponent,
8-
ignore,
913
components,
10-
root_comp,
11-
routes
14+
root_comp
1215
} from '@sapper/internal/manifest-client';
1316
import {
1417
HydratedTarget,
1518
Target,
16-
ScrollPosition,
1719
Redirect,
1820
Page
1921
} from './types';
@@ -71,69 +73,23 @@ export function set_target(element) {
7173
target = element;
7274
}
7375

74-
export let uid = 1;
75-
export function set_uid(n) {
76-
uid = n;
77-
}
76+
export default function start(opts: {
77+
target: Node
78+
}): Promise<void> {
79+
set_target(opts.target);
7880

79-
export let cid: number;
80-
export function set_cid(n) {
81-
cid = n;
82-
}
81+
init(initial_data.baseUrl, handle_target);
8382

84-
const _history = typeof history !== 'undefined' ? history : {
85-
pushState: (state: any, title: string, href: string) => {},
86-
replaceState: (state: any, title: string, href: string) => {},
87-
scrollRestoration: ''
88-
};
89-
export { _history as history };
90-
91-
export const scroll_history: Record<string, ScrollPosition> = {};
92-
93-
export function extract_query(search: string) {
94-
const query = Object.create(null);
95-
if (search.length > 0) {
96-
search.slice(1).split('&').forEach(searchParam => {
97-
const [, key, value = ''] = /([^=]*)(?:=(.*))?/.exec(decodeURIComponent(searchParam.replace(/\+/g, ' ')));
98-
if (typeof query[key] === 'string') query[key] = [<string>query[key]];
99-
if (typeof query[key] === 'object') (query[key] as string[]).push(value);
100-
else query[key] = value;
83+
if (initial_data.error) {
84+
return Promise.resolve().then(() => {
85+
return handle_error(new URL(location.href));
10186
});
10287
}
103-
return query;
104-
}
105-
106-
export function select_target(url: URL): Target {
107-
if (url.origin !== location.origin) return null;
108-
if (!url.pathname.startsWith(initial_data.baseUrl)) return null;
109-
110-
let path = url.pathname.slice(initial_data.baseUrl.length);
111-
112-
if (path === '') {
113-
path = '/';
114-
}
11588

116-
// avoid accidental clashes between server routes and page routes
117-
if (ignore.some(pattern => pattern.test(path))) return;
118-
119-
for (let i = 0; i < routes.length; i += 1) {
120-
const route = routes[i];
121-
122-
const match = route.pattern.exec(path);
123-
124-
if (match) {
125-
const query: Query = extract_query(url.search);
126-
const part = route.parts[route.parts.length - 1];
127-
const params = part.params ? part.params(match) : {};
128-
129-
const page = { host: location.host, path, query, params };
130-
131-
return { href: url.href, route, match, page };
132-
}
133-
}
89+
return load_current_page();
13490
}
13591

136-
export function handle_error(url: URL) {
92+
function handle_error(url: URL) {
13793
const { host, pathname, search } = location;
13894
const { session, preloaded, status, error } = initial_data;
13995

@@ -162,29 +118,7 @@ export function handle_error(url: URL) {
162118
render([], props, { host, path: pathname, query, params: {} });
163119
}
164120

165-
export function scroll_state() {
166-
return {
167-
x: pageXOffset,
168-
y: pageYOffset
169-
};
170-
}
171-
172-
export async function navigate(dest: Target, id: number, noscroll?: boolean, hash?: string): Promise<any> {
173-
if (id) {
174-
// popstate or initial navigation
175-
cid = id;
176-
} else {
177-
const current_scroll = scroll_state();
178-
179-
// clicked on a link. preserve scroll state
180-
scroll_history[cid] = current_scroll;
181-
182-
id = cid = ++uid;
183-
scroll_history[cid] = noscroll ? current_scroll : { x: 0, y: 0 };
184-
}
185-
186-
cid = id;
187-
121+
async function handle_target(dest: Target): Promise<void> {
188122
if (root_component) stores.preloading.set(true);
189123

190124
const loaded = prefetching && prefetching.href === dest.href ?
@@ -204,28 +138,6 @@ export async function navigate(dest: Target, id: number, noscroll?: boolean, has
204138
const { props, branch } = loaded_result;
205139
await render(branch, props, dest.page);
206140
}
207-
if (document.activeElement && (document.activeElement instanceof HTMLElement)) document.activeElement.blur();
208-
209-
if (!noscroll) {
210-
let scroll = scroll_history[id];
211-
212-
if (hash) {
213-
// scroll is an element id (from a hash), we need to compute y.
214-
const deep_linked = document.getElementById(hash.slice(1));
215-
216-
if (deep_linked) {
217-
scroll = {
218-
x: 0,
219-
y: deep_linked.getBoundingClientRect().top + scrollY
220-
};
221-
}
222-
}
223-
224-
scroll_history[cid] = scroll;
225-
if (scroll) {
226-
redirect ? scrollTo(0, 0) : scrollTo(scroll.x, scroll.y);
227-
}
228-
}
229141
}
230142

231143
async function render(branch: any[], props: any, page: Page) {

runtime/src/app/goto/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { history, select_target, navigate, cid } from '../app';
1+
import { cid, history, navigate, select_target } from '../router';
22

33
export default function goto(
44
href: string,

runtime/src/app/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { CONTEXT_KEY } from '@sapper/internal/shared';
33

44
export const stores = () => getContext(CONTEXT_KEY);
55

6-
export { default as start } from './start/index';
6+
export { default as start } from './app';
77
export { default as goto } from './goto/index';
88
export { default as prefetch } from './prefetch/index';
99
export { default as prefetchRoutes } from './prefetchRoutes/index';

runtime/src/app/prefetch/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { select_target, prefetching, set_prefetching, hydrate_target } from '../app';
1+
import { prefetching, set_prefetching, hydrate_target } from '../app';
2+
import { select_target } from '../router';
23

34
export default function prefetch(href: string) {
45
const target = select_target(new URL(href, document.baseURI));

0 commit comments

Comments
 (0)