UNPKG

3.06 kBJavaScriptView Raw
1import { Action, createBrowserHistory, createHashHistory } from 'history';
2import { RouterConfig } from './router';
3export let history;
4let basename = '/';
5class MpaHistory {
6 constructor() {
7 this.back = window.history.back;
8 this.forward = window.history.forward;
9 this.pushState = this.eventState('pushState');
10 this.replaceState = this.eventState('replaceState');
11 }
12 get location() {
13 return {
14 pathname: window.location.pathname,
15 search: window.location.search,
16 hash: window.location.hash,
17 key: `${window.history.length}`,
18 state: window.history.state
19 };
20 }
21 createHref(_to) {
22 throw new Error('Method not implemented.');
23 }
24 parseUrl(to) {
25 let url = to.pathname || '';
26 if (RouterConfig.isPage(url)) {
27 url += '.html';
28 }
29 if (to.search) {
30 url += `?${to.search}`;
31 }
32 if (to.hash) {
33 url += `#${to.hash}`;
34 }
35 return url;
36 }
37 push(to, _state = {}) {
38 window.location.pathname = this.parseUrl(to);
39 // this.pushState(_state, '', this.parseUrl(to))
40 }
41 replace(to, _state = {}) {
42 window.location.replace(this.parseUrl(to));
43 // this.replaceState(_state, '', this.parseUrl(to))
44 }
45 go(delta) {
46 window.history.go(delta);
47 }
48 listen(listener) {
49 function callback(e) {
50 if (e.action === 'pushState') {
51 listener({ action: Action.Push, location: this.location });
52 }
53 else if (e.action === 'replaceState') {
54 listener({ action: Action.Replace, location: this.location });
55 }
56 else {
57 // NOTE: 这里包括 back、forward、go 三种可能,并非是 POP 事件
58 listener({ action: Action.Pop, location: this.location });
59 }
60 }
61 window.addEventListener('popstate', callback);
62 return () => {
63 window.removeEventListener('popstate', callback);
64 };
65 }
66 block(_blocker) {
67 throw new Error('Method not implemented.');
68 }
69 eventState(action) {
70 return (data, unused, url) => {
71 const wrapper = window.history[action](data, unused, url);
72 const evt = new Event(action);
73 evt.action = action;
74 evt.state = data;
75 evt.unused = unused;
76 evt.url = url;
77 window.dispatchEvent(evt);
78 return wrapper;
79 };
80 }
81}
82export function setHistoryMode(mode, base = '/') {
83 const options = {
84 window
85 };
86 basename = base;
87 if (mode === 'browser') {
88 history = createBrowserHistory(options);
89 }
90 else if (mode === 'multi') {
91 history = new MpaHistory();
92 }
93 else {
94 // default is hash
95 history = createHashHistory(options);
96 }
97}
98export function prependBasename(url = '') {
99 return basename.replace(/\/$/, '') + '/' + url.replace(/^\//, '');
100}