@mantou/gem 1.6.4 → 1.6.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -38
- package/dist/gem.es.js +3260 -0
- package/dist/gem.umd.js +229 -0
- package/elements/{dialog-base.d.ts → base/dialog.d.ts} +4 -4
- package/elements/base/dialog.d.ts.map +1 -0
- package/elements/{dialog-base.js → base/dialog.js} +26 -28
- package/elements/base/dialog.js.map +1 -0
- package/elements/base/gesture.d.ts +66 -0
- package/elements/base/gesture.d.ts.map +1 -0
- package/elements/base/gesture.js +214 -0
- package/elements/base/gesture.js.map +1 -0
- package/elements/base/link.d.ts +44 -0
- package/elements/base/link.d.ts.map +1 -0
- package/elements/base/link.js +206 -0
- package/elements/base/link.js.map +1 -0
- package/elements/{modal-base.d.ts → base/modal-factory.d.ts} +20 -20
- package/elements/base/modal-factory.d.ts.map +1 -0
- package/elements/{modal-base.js → base/modal-factory.js} +10 -7
- package/elements/base/modal-factory.js.map +1 -0
- package/elements/base/reflect.d.ts +6 -0
- package/elements/base/reflect.d.ts.map +1 -0
- package/elements/base/reflect.js +33 -0
- package/elements/base/reflect.js.map +1 -0
- package/elements/base/route.d.ts +78 -0
- package/elements/base/route.d.ts.map +1 -0
- package/elements/base/route.js +220 -0
- package/elements/base/route.js.map +1 -0
- package/elements/base/title.d.ts +30 -0
- package/elements/base/title.d.ts.map +1 -0
- package/elements/base/title.js +74 -0
- package/elements/base/title.js.map +1 -0
- package/elements/base/unsafe.d.ts +14 -0
- package/elements/base/unsafe.d.ts.map +1 -0
- package/elements/base/unsafe.js +42 -0
- package/elements/base/unsafe.js.map +1 -0
- package/elements/base/use.d.ts +19 -0
- package/elements/base/use.d.ts.map +1 -0
- package/elements/base/use.js +70 -0
- package/elements/base/use.js.map +1 -0
- package/elements/gesture.d.ts +1 -67
- package/elements/gesture.d.ts.map +1 -1
- package/elements/gesture.js +3 -219
- package/elements/gesture.js.map +1 -1
- package/elements/link.d.ts +1 -45
- package/elements/link.d.ts.map +1 -1
- package/elements/link.js +4 -215
- package/elements/link.js.map +1 -1
- package/elements/reflect.d.ts +1 -8
- package/elements/reflect.d.ts.map +1 -1
- package/elements/reflect.js +3 -39
- package/elements/reflect.js.map +1 -1
- package/elements/route.d.ts +1 -81
- package/elements/route.d.ts.map +1 -1
- package/elements/route.js +4 -225
- package/elements/route.js.map +1 -1
- package/elements/title.d.ts +1 -30
- package/elements/title.d.ts.map +1 -1
- package/elements/title.js +3 -75
- package/elements/title.js.map +1 -1
- package/elements/unsafe.d.ts +1 -14
- package/elements/unsafe.d.ts.map +1 -1
- package/elements/unsafe.js +3 -46
- package/elements/unsafe.js.map +1 -1
- package/elements/use.d.ts +1 -19
- package/elements/use.d.ts.map +1 -1
- package/elements/use.js +3 -74
- package/elements/use.js.map +1 -1
- package/helper/i18n.js +47 -58
- package/helper/i18n.js.map +1 -1
- package/helper/request.js +11 -19
- package/helper/request.js.map +1 -1
- package/index.d.ts +5 -4
- package/index.d.ts.map +1 -1
- package/index.js +4 -2
- package/index.js.map +1 -1
- package/lib/element.d.ts.map +1 -1
- package/lib/element.js +1 -1
- package/lib/element.js.map +1 -1
- package/lib/history.d.ts +28 -16
- package/lib/history.d.ts.map +1 -1
- package/lib/history.js +179 -169
- package/lib/history.js.map +1 -1
- package/lib/utils.d.ts +3 -1
- package/lib/utils.d.ts.map +1 -1
- package/lib/utils.js +7 -5
- package/lib/utils.js.map +1 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/package.json +25 -53
- package/src/{umd.ts → dist.ts} +4 -5
- package/src/elements/{dialog-base.ts → base/dialog.ts} +6 -7
- package/src/elements/base/gesture.ts +256 -0
- package/src/elements/base/link.ts +178 -0
- package/src/elements/{modal-base.ts → base/modal-factory.ts} +3 -3
- package/src/elements/base/reflect.ts +29 -0
- package/src/elements/base/route.ts +244 -0
- package/src/elements/base/title.ts +68 -0
- package/src/elements/base/unsafe.ts +37 -0
- package/src/elements/base/use.ts +57 -0
- package/src/elements/gesture.ts +3 -257
- package/src/elements/link.ts +4 -179
- package/src/elements/reflect.ts +3 -31
- package/src/elements/route.ts +4 -248
- package/src/elements/title.ts +3 -68
- package/src/elements/unsafe.ts +3 -37
- package/src/elements/use.ts +3 -57
- package/src/index.ts +4 -6
- package/src/lib/element.ts +2 -1
- package/src/lib/history.ts +183 -195
- package/src/lib/utils.ts +11 -5
- package/src/lib/version.ts +1 -1
- package/src/test/gem-element/advance.test.ts +1 -0
- package/src/test/gem-element/basic.test.ts +1 -0
- package/src/test/gem-element/decorators.test.ts +1 -0
- package/src/test/gem-element/multi.test.ts +1 -0
- package/src/test/history.test.ts +16 -10
- package/src/test/store.test.ts +1 -0
- package/src/test/utils.test.ts +1 -0
- package/elements/dialog-base.d.ts.map +0 -1
- package/elements/dialog-base.js.map +0 -1
- package/elements/modal-base.d.ts.map +0 -1
- package/elements/modal-base.js.map +0 -1
- package/src/examples/base-path/index.ts +0 -44
- package/src/examples/controlled/index.ts +0 -75
- package/src/examples/decorator/chidren.ts +0 -77
- package/src/examples/decorator/index.ts +0 -110
- package/src/examples/dialog/index.ts +0 -148
- package/src/examples/effect/index.ts +0 -45
- package/src/examples/elements/env.ts +0 -7
- package/src/examples/elements/layout.ts +0 -53
- package/src/examples/elements/nav.ts +0 -71
- package/src/examples/elements/source.ts +0 -68
- package/src/examples/gesture/canvas.ts +0 -69
- package/src/examples/gesture/index.ts +0 -97
- package/src/examples/gesture/manifest.json +0 -3
- package/src/examples/hash/index.ts +0 -55
- package/src/examples/i18n/index.ts +0 -63
- package/src/examples/index/index.ts +0 -33
- package/src/examples/index/manifest.json +0 -5
- package/src/examples/light-dom/index.ts +0 -31
- package/src/examples/multi-page/api.ts +0 -9
- package/src/examples/multi-page/index.ts +0 -78
- package/src/examples/multi-page/page-a.ts +0 -16
- package/src/examples/multi-page/page-b.ts +0 -12
- package/src/examples/multi-page/page-c.ts +0 -40
- package/src/examples/multi-page/store.ts +0 -10
- package/src/examples/perf-demo/index.ts +0 -136
- package/src/examples/ref-route/index.ts +0 -109
- package/src/examples/reflect/index.ts +0 -61
- package/src/examples/styled/index.ts +0 -39
- package/src/examples/svg-icon/index.ts +0 -31
- package/src/examples/theme/index.ts +0 -56
- package/src/examples/unsafe/index.ts +0 -29
- package/umd.d.ts +0 -18
- package/umd.d.ts.map +0 -1
- package/umd.js +0 -54
- package/umd.js.LICENSE.txt +0 -13
- package/umd.js.map +0 -1
package/src/lib/history.ts
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
|
-
import { createStore, updateStore,
|
|
1
|
+
import { createStore, updateStore, connect } from './store';
|
|
2
2
|
import { QueryString, cleanObject, GemError, absoluteLocation } from './utils';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const replaceState: typeof history.replaceState = history.replaceState.bind(history);
|
|
4
|
+
const nativeHistory = window.history;
|
|
5
|
+
const nativePushState: typeof nativeHistory.pushState = nativeHistory.pushState.bind(nativeHistory);
|
|
6
|
+
const nativeReplaceState: typeof nativeHistory.replaceState = nativeHistory.replaceState.bind(nativeHistory);
|
|
8
7
|
|
|
9
8
|
let key = 0;
|
|
10
9
|
const getKey = () => `${performance.now()}-${++key}`;
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
export interface HistoryItem {
|
|
11
|
+
export interface HistoryState {
|
|
14
12
|
$hasCloseHandle: boolean;
|
|
15
13
|
$hasOpenHandle: boolean;
|
|
16
14
|
$hasShouldCloseHandle: boolean;
|
|
@@ -18,7 +16,7 @@ export interface HistoryItem {
|
|
|
18
16
|
[index: string]: any;
|
|
19
17
|
}
|
|
20
18
|
|
|
21
|
-
const store = createStore<
|
|
19
|
+
const store = createStore<HistoryState>({
|
|
22
20
|
$hasCloseHandle: false,
|
|
23
21
|
$hasOpenHandle: false,
|
|
24
22
|
$hasShouldCloseHandle: false,
|
|
@@ -34,7 +32,7 @@ export interface UpdateHistoryParams {
|
|
|
34
32
|
open?: () => void; // 按下前进键时执行
|
|
35
33
|
close?: () => void; // 按下返回键时执行
|
|
36
34
|
shouldClose?: () => boolean; // 按下返回键时判断是否执行 close 函数,返回为 false 时不执行,并恢复 history
|
|
37
|
-
data?: any;
|
|
35
|
+
data?: any; // 同 history.state
|
|
38
36
|
}
|
|
39
37
|
|
|
40
38
|
// 实际应用值
|
|
@@ -43,27 +41,6 @@ type HistoryParams = UpdateHistoryParams & { title: string; path: string; query:
|
|
|
43
41
|
// TODO: WeakRef
|
|
44
42
|
const paramsMap = new Map<string, HistoryParams>();
|
|
45
43
|
|
|
46
|
-
declare global {
|
|
47
|
-
interface History {
|
|
48
|
-
store: Store<HistoryItem>;
|
|
49
|
-
// 修改会更改 `history.getParams()` 的值
|
|
50
|
-
basePath?: string;
|
|
51
|
-
// 返回 `history` 当前储存的值, 是一个可变对象,当修改 `basePath` 时会改变
|
|
52
|
-
getParams: () => HistoryParams;
|
|
53
|
-
|
|
54
|
-
push: (params: UpdateHistoryParams) => void;
|
|
55
|
-
replace: (params: UpdateHistoryParams) => void;
|
|
56
|
-
// push 一条历史记录
|
|
57
|
-
// 有 close 处理函数时先执行 closeHandle 在 replace
|
|
58
|
-
// 比如在 modal 打开时跳转页面
|
|
59
|
-
// 不完美:只支持在 1 级 modal 中切换页面
|
|
60
|
-
pushIgnoreCloseHandle: (params: UpdateHistoryParams) => void;
|
|
61
|
-
updateParams: (params: Omit<UpdateHistoryParams, 'path' | 'query' | 'hash' | 'state'>) => void;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
type UpdateHistoryType = 'push' | 'replace';
|
|
66
|
-
|
|
67
44
|
function validData({ $key, $hasCloseHandle, $hasOpenHandle, $hasShouldCloseHandle }: any = {}) {
|
|
68
45
|
if (store.$key === $key) return;
|
|
69
46
|
if ($key) throw new GemError('`$key` is not allowed');
|
|
@@ -73,15 +50,15 @@ function validData({ $key, $hasCloseHandle, $hasOpenHandle, $hasShouldCloseHandl
|
|
|
73
50
|
}
|
|
74
51
|
|
|
75
52
|
function getUrlbarPath(internalPath: string) {
|
|
76
|
-
return
|
|
53
|
+
return gemHistory.basePath ? gemHistory.basePath + internalPath : internalPath;
|
|
77
54
|
}
|
|
78
55
|
|
|
79
56
|
function getInternalPath(urlbarPath: string) {
|
|
80
|
-
if (urlbarPath ===
|
|
81
|
-
return urlbarPath.replace(new RegExp(`^${
|
|
57
|
+
if (urlbarPath === gemHistory.basePath) return '/';
|
|
58
|
+
return urlbarPath.replace(new RegExp(`^${gemHistory.basePath}/`), '/');
|
|
82
59
|
}
|
|
83
60
|
|
|
84
|
-
function
|
|
61
|
+
function normalizeParams(params: UpdateHistoryParams): HistoryParams {
|
|
85
62
|
const current = paramsMap.get(store.$key) || ({} as HistoryParams);
|
|
86
63
|
// 没提供 path 使用当前 path
|
|
87
64
|
const path = params.path ? absoluteLocation(current.path, params.path) : getInternalPath(location.pathname);
|
|
@@ -89,18 +66,19 @@ function initParams(params: UpdateHistoryParams): HistoryParams {
|
|
|
89
66
|
const query = new QueryString(params.query || (params.path ? '' : location.search));
|
|
90
67
|
const pathChanged =
|
|
91
68
|
(params.path && params.path !== current.path) || (params.query && String(params.query) !== String(current.query));
|
|
92
|
-
|
|
69
|
+
// 没提供 title 又没有改变 URL 时使用当前 document.title
|
|
70
|
+
const title = params.title || (pathChanged ? '' : document.title);
|
|
93
71
|
const statusChanged = params.close || params.data || params.open || params.shouldClose;
|
|
94
|
-
// 没提供 hash
|
|
72
|
+
// 没提供 hash 又没有改变 URL 又不是状态更新时使用当前 hash
|
|
95
73
|
const hash = params.hash || (!pathChanged && statusChanged ? decodeURIComponent(location.hash) : '');
|
|
96
74
|
return { ...params, title, path, query, hash };
|
|
97
75
|
}
|
|
98
76
|
|
|
99
|
-
function updateHistory(
|
|
77
|
+
function updateHistory(p: UpdateHistoryParams, native: typeof nativeHistory.pushState) {
|
|
100
78
|
validData(p.data);
|
|
101
|
-
const params =
|
|
79
|
+
const params = normalizeParams(p);
|
|
102
80
|
const { title, path, query, hash, close, open, shouldClose, data } = params;
|
|
103
|
-
const state:
|
|
81
|
+
const state: HistoryState = {
|
|
104
82
|
$hasCloseHandle: !!close,
|
|
105
83
|
$hasOpenHandle: !!open,
|
|
106
84
|
$hasShouldCloseHandle: !!shouldClose,
|
|
@@ -110,197 +88,207 @@ function updateHistory(type: UpdateHistoryType, p: UpdateHistoryParams) {
|
|
|
110
88
|
paramsMap.set(state.$key, params);
|
|
111
89
|
updateStore(cleanObject(store), state);
|
|
112
90
|
const url = getUrlbarPath(path) + new QueryString(query) + hash;
|
|
113
|
-
const
|
|
114
|
-
(
|
|
115
|
-
if (
|
|
91
|
+
const prevHash = decodeURIComponent(location.hash);
|
|
92
|
+
native(state, title, url);
|
|
93
|
+
if (prevHash !== hash) window.dispatchEvent(new CustomEvent('hashchange'));
|
|
116
94
|
}
|
|
117
95
|
|
|
118
96
|
// 跨框架时,调用者对 basePath 无感知
|
|
119
|
-
function updateHistoryByNative(
|
|
97
|
+
function updateHistoryByNative(data: any, title: string, originUrl: string, native: typeof nativeHistory.pushState) {
|
|
120
98
|
validData(data);
|
|
121
99
|
const state = {
|
|
122
100
|
$key: getKey(),
|
|
123
101
|
...(data || {}),
|
|
124
102
|
};
|
|
125
103
|
const { pathname, search, hash } = new URL(originUrl, location.origin + location.pathname);
|
|
126
|
-
const params =
|
|
104
|
+
const params = normalizeParams({ path: pathname, query: new QueryString(search), hash, title, data });
|
|
127
105
|
paramsMap.set(state.$key, params);
|
|
128
106
|
updateStore(cleanObject(store), state);
|
|
129
107
|
const url = getUrlbarPath(pathname) + params.query + hash;
|
|
130
108
|
const prevHash = location.hash;
|
|
131
|
-
(
|
|
109
|
+
native(state, title, url);
|
|
132
110
|
// `location.hash` 和 `hash` 都已经进行了 url 编码,可以直接进行相等判断
|
|
133
111
|
if (prevHash !== hash) window.dispatchEvent(new CustomEvent('hashchange'));
|
|
134
112
|
}
|
|
135
113
|
|
|
136
|
-
|
|
114
|
+
const gemBasePathStore = createStore({
|
|
137
115
|
basePath: '',
|
|
138
116
|
});
|
|
139
117
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
118
|
+
class GemHistory {
|
|
119
|
+
get store() {
|
|
120
|
+
return store;
|
|
143
121
|
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
value: function (params: UpdateHistoryParams) {
|
|
180
|
-
if (store.$hasCloseHandle) {
|
|
181
|
-
paramsMap.get(store.$key)?.close?.();
|
|
182
|
-
history.replace(params);
|
|
183
|
-
} else {
|
|
184
|
-
history.push(params);
|
|
185
|
-
}
|
|
186
|
-
},
|
|
187
|
-
},
|
|
188
|
-
replace: {
|
|
189
|
-
value: function (params: UpdateHistoryParams) {
|
|
190
|
-
updateHistory('replace', params);
|
|
191
|
-
},
|
|
192
|
-
},
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
history.pushState = function (data: any, title: string, path: string) {
|
|
196
|
-
if (path) {
|
|
197
|
-
updateHistoryByNative('push', data, title, path);
|
|
198
|
-
} else {
|
|
199
|
-
updateHistory('push', data);
|
|
122
|
+
get basePath() {
|
|
123
|
+
return gemBasePathStore.basePath;
|
|
124
|
+
}
|
|
125
|
+
set basePath(basePath: string) {
|
|
126
|
+
// 应用初始化的时候设置
|
|
127
|
+
updateStore(gemBasePathStore, { basePath });
|
|
128
|
+
// paramsMap 更新后 ui 才会更新
|
|
129
|
+
Object.assign(paramsMap.get(store.$key), { path: getInternalPath(location.pathname) });
|
|
130
|
+
}
|
|
131
|
+
getParams() {
|
|
132
|
+
return paramsMap.get(store.$key)!;
|
|
133
|
+
}
|
|
134
|
+
updateParams(params: UpdateHistoryParams) {
|
|
135
|
+
Object.assign(paramsMap.get(store.$key), params);
|
|
136
|
+
updateStore(store, {});
|
|
137
|
+
}
|
|
138
|
+
push(params: UpdateHistoryParams) {
|
|
139
|
+
updateHistory(params, nativePushState);
|
|
140
|
+
}
|
|
141
|
+
replace(params: UpdateHistoryParams) {
|
|
142
|
+
updateHistory(params, nativeReplaceState);
|
|
143
|
+
}
|
|
144
|
+
pushIgnoreCloseHandle(params: UpdateHistoryParams) {
|
|
145
|
+
if (store.$hasCloseHandle) {
|
|
146
|
+
paramsMap.get(store.$key)?.close?.();
|
|
147
|
+
this.replace(params);
|
|
148
|
+
} else {
|
|
149
|
+
this.push(params);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
forward() {
|
|
153
|
+
nativeHistory.forward();
|
|
154
|
+
}
|
|
155
|
+
back() {
|
|
156
|
+
nativeHistory.back();
|
|
200
157
|
}
|
|
201
|
-
};
|
|
202
|
-
|
|
203
|
-
history.replaceState = function (data: any, title: string, path: string) {
|
|
204
|
-
updateHistoryByNative('replace', data, title, path);
|
|
205
|
-
};
|
|
206
|
-
|
|
207
|
-
if (!history.state) {
|
|
208
|
-
// 初始化 historyItem
|
|
209
|
-
const { pathname, search, hash } = location;
|
|
210
|
-
history.replace({ path: pathname, query: search, hash });
|
|
211
|
-
} else if (history.state.$hasCloseHandle) {
|
|
212
|
-
updateStore(store, history.state);
|
|
213
|
-
const params = initParams({ title: document.title });
|
|
214
|
-
paramsMap.set(store.$key, params);
|
|
215
|
-
// 有 handle 返回键的页面刷新需要清除返回 handler
|
|
216
|
-
history.back();
|
|
217
|
-
} else {
|
|
218
|
-
// 有 gem 历史的正常普通刷新, 储存 params
|
|
219
|
-
const params = initParams({ title: document.title, hash: location.hash });
|
|
220
|
-
updateStore(store, {
|
|
221
|
-
$key: getKey(),
|
|
222
|
-
...(history.state || {}),
|
|
223
|
-
});
|
|
224
|
-
paramsMap.set(store.$key, params);
|
|
225
158
|
}
|
|
226
159
|
|
|
227
|
-
|
|
160
|
+
// `<gem-**>` 只读写父应用 `basePath`
|
|
161
|
+
const gemHistory = new GemHistory();
|
|
228
162
|
|
|
229
|
-
|
|
230
|
-
const params = paramsMap.get(store.$key);
|
|
231
|
-
if (params) {
|
|
232
|
-
params.title = titleStore.title;
|
|
233
|
-
}
|
|
234
|
-
});
|
|
163
|
+
const gemTitleStore = createStore({ title: '' });
|
|
235
164
|
|
|
236
|
-
|
|
237
|
-
const { title } = history.getParams();
|
|
238
|
-
if (title !== titleStore.title) {
|
|
239
|
-
updateStore(titleStore, { title });
|
|
240
|
-
}
|
|
241
|
-
});
|
|
165
|
+
const _GEMHISTORY = { history: gemHistory, titleStore: gemTitleStore, basePathStore: gemBasePathStore };
|
|
242
166
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
let navigating = false;
|
|
247
|
-
window.addEventListener('popstate', (event) => {
|
|
248
|
-
const newState = event.state as HistoryItem | null;
|
|
249
|
-
if (!newState?.$key) {
|
|
250
|
-
// 比如作为其他 app 的宿主 app
|
|
251
|
-
return;
|
|
252
|
-
}
|
|
253
|
-
if (navigating) {
|
|
254
|
-
navigating = false;
|
|
255
|
-
return;
|
|
167
|
+
declare global {
|
|
168
|
+
interface Window {
|
|
169
|
+
_GEMHISTORY?: typeof _GEMHISTORY;
|
|
256
170
|
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (!window._GEMHISTORY) {
|
|
174
|
+
window._GEMHISTORY = _GEMHISTORY;
|
|
175
|
+
|
|
176
|
+
nativeHistory.pushState = function (state: any, title: string, path: string) {
|
|
177
|
+
updateHistoryByNative(state, title, path, nativePushState);
|
|
178
|
+
};
|
|
257
179
|
|
|
258
|
-
|
|
259
|
-
|
|
180
|
+
nativeHistory.replaceState = function (state: any, title: string, path: string) {
|
|
181
|
+
updateHistoryByNative(state, title, path, nativeReplaceState);
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
// 点击 `<a>`
|
|
185
|
+
window.addEventListener('hashchange', ({ isTrusted }) => {
|
|
186
|
+
if (isTrusted) {
|
|
187
|
+
gemHistory.replace({ hash: decodeURIComponent(location.hash) });
|
|
188
|
+
}
|
|
189
|
+
});
|
|
260
190
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
if (!paramsMap.has(newState.$key)) {
|
|
191
|
+
if (!nativeHistory.state) {
|
|
192
|
+
// 初始化 historyState
|
|
264
193
|
const { pathname, search, hash } = location;
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
194
|
+
gemHistory.replace({ path: pathname, query: search, hash });
|
|
195
|
+
} else if (nativeHistory.state.$hasCloseHandle) {
|
|
196
|
+
updateStore(store, nativeHistory.state);
|
|
197
|
+
const params = normalizeParams({ title: document.title });
|
|
198
|
+
paramsMap.set(store.$key, params);
|
|
199
|
+
// 有 handle 返回键的页面刷新需要清除返回 handler
|
|
200
|
+
gemHistory.back();
|
|
201
|
+
} else {
|
|
202
|
+
// 有 gem 历史的正常普通刷新, 储存 params
|
|
203
|
+
const params = normalizeParams({ title: document.title, hash: location.hash });
|
|
204
|
+
updateStore(store, {
|
|
205
|
+
$key: getKey(),
|
|
206
|
+
...(nativeHistory.state || {}),
|
|
271
207
|
});
|
|
208
|
+
paramsMap.set(store.$key, params);
|
|
272
209
|
}
|
|
273
210
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
const
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
211
|
+
connect(gemTitleStore, () => {
|
|
212
|
+
const params = paramsMap.get(store.$key);
|
|
213
|
+
if (params) {
|
|
214
|
+
params.title = gemTitleStore.title;
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
connect(store, () => {
|
|
219
|
+
const { title } = gemHistory.getParams();
|
|
220
|
+
if (title !== gemTitleStore.title) {
|
|
221
|
+
updateStore(gemTitleStore, { title });
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* 表示 popstate handler 中正在进行导航
|
|
227
|
+
*/
|
|
228
|
+
let navigating = false;
|
|
229
|
+
window.addEventListener('popstate', (event) => {
|
|
230
|
+
const newState = event.state as HistoryState | null;
|
|
231
|
+
if (!newState?.$key) {
|
|
232
|
+
// 比如作为其他框架 app 的宿主 app
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
if (navigating) {
|
|
236
|
+
navigating = false;
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// 处理 forward or back
|
|
241
|
+
// replace 不会触发
|
|
242
|
+
|
|
243
|
+
// 刷新后再导航需要从当前 state 中构建 params
|
|
244
|
+
// 理论上该条历史记录中不会出现事件处理器
|
|
245
|
+
// 子 app 导航也需要从 state 中构建 params
|
|
246
|
+
if (!paramsMap.has(newState.$key)) {
|
|
247
|
+
const { pathname, search, hash } = location;
|
|
248
|
+
paramsMap.set(newState.$key, {
|
|
249
|
+
path: pathname,
|
|
250
|
+
query: new QueryString(search),
|
|
251
|
+
hash,
|
|
252
|
+
title: document.title, // 浏览器缓存的 title
|
|
253
|
+
data: newState,
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// url 变化前 historyItem
|
|
258
|
+
const prevState = store;
|
|
259
|
+
|
|
260
|
+
if (parseFloat(newState.$key) > parseFloat(prevState.$key) && newState.$hasOpenHandle) {
|
|
261
|
+
// 返回键关闭的 modal 能前进键重新打开
|
|
262
|
+
// 刷新后不能工作:刷新后 historyItem 中只有 url
|
|
263
|
+
// 能在子 app 中工作
|
|
264
|
+
paramsMap.get(newState.$key)?.open?.();
|
|
265
|
+
} else if (prevState.$hasCloseHandle) {
|
|
266
|
+
const prevParams = paramsMap.get(prevState.$key);
|
|
267
|
+
const closeHandle = prevParams?.close;
|
|
268
|
+
const shouldCloseHandle = prevParams?.shouldClose;
|
|
269
|
+
const notAllowClose = shouldCloseHandle && !shouldCloseHandle();
|
|
270
|
+
if (notAllowClose) {
|
|
299
271
|
navigating = true;
|
|
300
|
-
|
|
272
|
+
gemHistory.forward(); // 将重新触发 popstate
|
|
273
|
+
return; // 历史记录栈位置没有变化,不需要后面的 updateStore
|
|
274
|
+
} else {
|
|
275
|
+
// handle 返回键
|
|
276
|
+
if (closeHandle) {
|
|
277
|
+
closeHandle();
|
|
278
|
+
} else if (newState.$hasCloseHandle) {
|
|
279
|
+
// 有 modal 的页面刷新会执行 back 触发 popstate
|
|
280
|
+
// 如果是二级 modal 页面刷新
|
|
281
|
+
// 则还需要进行一次 back
|
|
282
|
+
// !!! 不完美:三级 modal 页面刷新不支持返回到初始页面
|
|
283
|
+
navigating = true;
|
|
284
|
+
gemHistory.back();
|
|
285
|
+
}
|
|
301
286
|
}
|
|
302
287
|
}
|
|
303
|
-
}
|
|
304
288
|
|
|
305
|
-
|
|
306
|
-
});
|
|
289
|
+
updateStore(cleanObject(store), newState);
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
const { history, titleStore, basePathStore } = window._GEMHISTORY;
|
|
294
|
+
export { history, titleStore, basePathStore };
|
package/src/lib/utils.ts
CHANGED
|
@@ -209,7 +209,8 @@ export function css(arr: TemplateStringsArray, ...args: any[]) {
|
|
|
209
209
|
return raw(arr, ...args);
|
|
210
210
|
}
|
|
211
211
|
|
|
212
|
-
|
|
212
|
+
// 跨多个 gem 工作
|
|
213
|
+
export const SheetToken = Symbol.for('gem@sheetToken');
|
|
213
214
|
|
|
214
215
|
export type Sheet<T> = {
|
|
215
216
|
[P in keyof T]: P;
|
|
@@ -373,11 +374,16 @@ export function removeItems(target: any[], items: any[]) {
|
|
|
373
374
|
});
|
|
374
375
|
}
|
|
375
376
|
|
|
376
|
-
|
|
377
|
+
type StyleProp = keyof CSSStyleDeclaration | `--${string}`;
|
|
378
|
+
|
|
379
|
+
export type StyleObject = Partial<Record<StyleProp, string | number | undefined>>;
|
|
380
|
+
|
|
381
|
+
// 不支持 webkit 属性
|
|
382
|
+
export function styleMap(object: StyleObject) {
|
|
377
383
|
let styleString = '';
|
|
378
|
-
for (const key in
|
|
379
|
-
if (
|
|
380
|
-
styleString += `${camelToKebabCase(key)}:${
|
|
384
|
+
for (const key in object) {
|
|
385
|
+
if (object[key as StyleProp] !== undefined) {
|
|
386
|
+
styleString += `${camelToKebabCase(key)}:${object[key as StyleProp]};`;
|
|
381
387
|
}
|
|
382
388
|
}
|
|
383
389
|
return styleString;
|
package/src/lib/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Do not modify manually
|
|
2
|
-
export const version = '1.6.
|
|
2
|
+
export const version = '1.6.5';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { fixture, expect, nextFrame } from '@open-wc/testing';
|
|
2
|
+
|
|
2
3
|
import { GemElement, html } from '../../lib/element';
|
|
3
4
|
import { createStore, updateStore } from '../../lib/store';
|
|
4
5
|
import { attribute, property, customElement, emitter, adoptedStyle } from '../../lib/decorators';
|
package/src/test/history.test.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { expect, aTimeout } from '@open-wc/testing';
|
|
2
|
+
|
|
2
3
|
import { history } from '../lib/history';
|
|
3
4
|
|
|
4
5
|
describe('history 测试', () => {
|
|
@@ -38,6 +39,10 @@ describe('history 测试', () => {
|
|
|
38
39
|
await aTimeout(10);
|
|
39
40
|
expect(window.location.pathname).to.equal('/');
|
|
40
41
|
expect(new URLSearchParams(location.search).get('tab')).to.equal('bb');
|
|
42
|
+
expect(() => history.replace({ data: { $key: 'adf' } })).to.throw();
|
|
43
|
+
expect(() => history.replace({ data: { $hasCloseHandle: 'adf' } })).to.throw();
|
|
44
|
+
expect(() => history.replace({ data: { $hasOpenHandle: 'adf' } })).to.throw();
|
|
45
|
+
expect(() => history.replace({ data: { $hasShouldCloseHandle: 'adf' } })).to.throw();
|
|
41
46
|
});
|
|
42
47
|
it('getParams/updateParams', async () => {
|
|
43
48
|
const historyLength = window.history.length;
|
|
@@ -49,16 +54,16 @@ describe('history 测试', () => {
|
|
|
49
54
|
await aTimeout(10);
|
|
50
55
|
expect(history.getParams().title).to.equal('321');
|
|
51
56
|
});
|
|
52
|
-
it('pushState/replaceState', async () => {
|
|
57
|
+
it('Native pushState/replaceState', async () => {
|
|
53
58
|
const historyLength = window.history.length;
|
|
54
|
-
history.pushState({}, 'title', '/a');
|
|
59
|
+
window.history.pushState({}, 'title', '/a');
|
|
55
60
|
await aTimeout(10);
|
|
56
61
|
expect(window.location.pathname).to.equal('/a');
|
|
57
|
-
history.replaceState({}, 'title', '/b?tab=a');
|
|
58
|
-
expect(() => history.replaceState({ $key: 'adf' }, '', '')).to.throw();
|
|
59
|
-
expect(() => history.replaceState({ $hasCloseHandle: 'adf' }, '', '')).to.throw();
|
|
60
|
-
expect(() => history.replaceState({ $hasOpenHandle: 'adf' }, '', '')).to.throw();
|
|
61
|
-
expect(() => history.replaceState({ $hasShouldCloseHandle: 'adf' }, '', '')).to.throw();
|
|
62
|
+
window.history.replaceState({}, 'title', '/b?tab=a');
|
|
63
|
+
expect(() => window.history.replaceState({ $key: 'adf' }, '', '')).to.throw();
|
|
64
|
+
expect(() => window.history.replaceState({ $hasCloseHandle: 'adf' }, '', '')).to.throw();
|
|
65
|
+
expect(() => window.history.replaceState({ $hasOpenHandle: 'adf' }, '', '')).to.throw();
|
|
66
|
+
expect(() => window.history.replaceState({ $hasShouldCloseHandle: 'adf' }, '', '')).to.throw();
|
|
62
67
|
await aTimeout(10);
|
|
63
68
|
expect(window.location.pathname).to.equal('/b');
|
|
64
69
|
expect(new URLSearchParams(location.search).get('tab')).to.equal('a');
|
|
@@ -83,7 +88,7 @@ describe('history 测试', () => {
|
|
|
83
88
|
// 替换 close
|
|
84
89
|
history.replace({ close, open });
|
|
85
90
|
await aTimeout(10);
|
|
86
|
-
expect(history?.state?.$hasOpenHandle).to.true;
|
|
91
|
+
expect(window.history?.state?.$hasOpenHandle).to.true;
|
|
87
92
|
await aTimeout(10);
|
|
88
93
|
expect(window.location.href).to.equal(href);
|
|
89
94
|
// 跳转页面
|
|
@@ -133,14 +138,15 @@ describe('history 测试', () => {
|
|
|
133
138
|
expect(window.location.pathname).to.equal('/d/');
|
|
134
139
|
history.push({ path: '/a' });
|
|
135
140
|
await aTimeout(10);
|
|
141
|
+
expect(history.getParams().path).to.equal('/a');
|
|
136
142
|
expect(window.location.pathname).to.equal('/d/a');
|
|
137
143
|
history.push({ path: '/' });
|
|
138
144
|
await aTimeout(10);
|
|
139
145
|
expect(window.location.pathname).to.equal('/d/');
|
|
140
|
-
history.pushState({}, '', '/');
|
|
146
|
+
window.history.pushState({}, '', '/');
|
|
141
147
|
await aTimeout(10);
|
|
142
148
|
expect(window.location.pathname).to.equal('/d/');
|
|
143
|
-
history.pushState({}, '', '/c');
|
|
149
|
+
window.history.pushState({}, '', '/c');
|
|
144
150
|
await aTimeout(10);
|
|
145
151
|
expect(window.location.pathname).to.equal('/d/c');
|
|
146
152
|
history.basePath = '';
|
package/src/test/store.test.ts
CHANGED
package/src/test/utils.test.ts
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dialog-base.d.ts","sourceRoot":"","sources":["../src/elements/dialog-base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAI5C;;;;;;GAMG;AACH,8BACsB,iBAAkB,SAAQ,UAAU;;IACjD,MAAM,UAAS;IAEtB,KAAK,UAAQ;IAMF,KAAK,SAAM;;IAQtB;;;OAGG;IACH,WAAW,aAUT;IAEF;;;OAGG;IACH,UAAU,aAUR;IAEF,YAAY;IACZ,IAAI,aASF;IAEF,WAAW;IAIX,YAAY;IACZ,KAAK,aAEH;IAEF;;;;;OAKG;IACH,UAAU,aAGR;CACH"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dialog-base.js","sourceRoot":"","sources":["../src/elements/dialog-base.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"modal-base.d.ts","sourceRoot":"","sources":["../src/elements/modal-base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAI5C,QAAA,MAAM,IAAI,eAAsB,CAAC;AAEjC;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;;;;;;;;;;;;;oDAsD1E;;;eAGG;;;;;;;oDAHH;;;eAGG;;;;;;;;;;oDAHH;;;eAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gBAvDgB,WAAW,EAAE;cACf,UAAU,GAAG,IAAI;IAClC;;;OAGG;;;;IAMH,YAAY;;IAKZ,YAAY;;;;IAKZ;;;;OAIG;eACe,GAAC;IAkBnB;;;OAGG;;IAKH;;;OAGG;;IAOH;;OAEG;;;;;;;;;;;;;EAaN"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"modal-base.js","sourceRoot":"","sources":["../src/elements/modal-base.ts"],"names":[],"mappings":"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"}
|