-
Notifications
You must be signed in to change notification settings - Fork 176
Expand file tree
/
Copy pathlifecycle.ts
More file actions
84 lines (76 loc) · 1.98 KB
/
lifecycle.ts
File metadata and controls
84 lines (76 loc) · 1.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import { isServer } from "solid-js/web";
import {
BeforeLeaveLifecycle,
BeforeLeaveListener,
LocationChange,
NavigateOptions
} from "./types.js";
export function createBeforeLeave(): BeforeLeaveLifecycle {
let listeners = new Set<BeforeLeaveListener>();
function subscribe(listener: BeforeLeaveListener) {
listeners.add(listener);
return () => listeners.delete(listener);
}
let ignore = false;
function confirm(to: string | number, options?: Partial<NavigateOptions>) {
if (ignore) return !(ignore = false);
const e = {
to,
options,
defaultPrevented: false,
preventDefault: () => ((e.defaultPrevented as boolean) = true)
};
for (const l of listeners)
l.listener({
...e,
from: l.location,
retry: (force?: boolean) => {
force && (ignore = true);
l.navigate(to as string, { ...options, resolve: false });
}
});
return !e.defaultPrevented;
}
return {
subscribe,
confirm
};
}
// The following supports browser initiated blocking (eg back/forward)
let depth: number;
export function saveCurrentDepth() {
if (!window.history.state || window.history.state._depth == null) {
window.history.replaceState({ ...window.history.state, _depth: window.history.length - 1 }, "");
}
depth = window.history.state._depth;
}
if (!isServer) {
saveCurrentDepth();
}
export function keepDepth(state: any) {
return {
...state,
_depth: window.history.state && window.history.state._depth
};
}
export function notifyIfNotBlocked(
notify: (value?: string | LocationChange) => void,
block: (delta: number | null) => boolean
) {
let ignore = false;
return () => {
const prevDepth = depth;
saveCurrentDepth();
const delta = prevDepth == null ? null : depth - prevDepth;
if (ignore) {
ignore = false;
return;
}
if (delta && block(delta)) {
ignore = true;
window.history.go(-delta);
} else {
notify();
}
};
}