UNPKG

1.65 kBTypeScriptView Raw
1const location = new URL('', 'http://example.com');
2
3let listeners: (() => void)[] = [];
4let entries = [{ state: null, href: location.href }];
5let index = 0;
6
7let currentState: any = null;
8
9const history = {
10 get state() {
11 return currentState;
12 },
13
14 pushState(state: any, _: string, path: string) {
15 Object.assign(location, new URL(path, location.origin));
16
17 currentState = state;
18 entries = entries.slice(0, index + 1);
19 entries.push({ state, href: location.href });
20 index = entries.length - 1;
21 },
22
23 replaceState(state: any, _: string, path: string) {
24 Object.assign(location, new URL(path, location.origin));
25
26 currentState = state;
27 entries[index] = { state, href: location.href };
28 },
29
30 go(n: number) {
31 setTimeout(() => {
32 if (
33 (n > 0 && n < entries.length - index) ||
34 (n < 0 && Math.abs(n) <= index)
35 ) {
36 index += n;
37 const entry = entries[index];
38 Object.assign(location, new URL(entry.href));
39 currentState = entry.state;
40 listeners.forEach((cb) => cb());
41 }
42 }, 0);
43 },
44
45 back() {
46 this.go(-1);
47 },
48
49 forward() {
50 this.go(1);
51 },
52};
53
54const addEventListener = (type: 'popstate', listener: () => void) => {
55 if (type === 'popstate') {
56 listeners.push(listener);
57 }
58};
59
60const removeEventListener = (type: 'popstate', listener: () => void) => {
61 if (type === 'popstate') {
62 listeners = listeners.filter((cb) => cb !== listener);
63 }
64};
65
66const window = {
67 document: { title: '' },
68 location,
69 history,
70 addEventListener,
71 removeEventListener,
72 get window() {
73 return window;
74 },
75};
76
77export default window;