@esmx/router 3.0.0-rc.17 → 3.0.0-rc.19
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/LICENSE +1 -1
- package/README.md +70 -0
- package/README.zh-CN.md +70 -0
- package/dist/error.d.ts +23 -0
- package/dist/error.mjs +61 -0
- package/dist/increment-id.d.ts +7 -0
- package/dist/increment-id.mjs +11 -0
- package/dist/index.d.ts +5 -3
- package/dist/index.mjs +14 -3
- package/dist/index.test.mjs +8 -0
- package/dist/location.d.ts +15 -0
- package/dist/location.mjs +53 -0
- package/dist/location.test.d.ts +8 -0
- package/dist/location.test.mjs +370 -0
- package/dist/matcher.d.ts +3 -0
- package/dist/matcher.mjs +44 -0
- package/dist/matcher.test.mjs +1492 -0
- package/dist/micro-app.d.ts +18 -0
- package/dist/micro-app.dom.test.d.ts +1 -0
- package/dist/micro-app.dom.test.mjs +532 -0
- package/dist/micro-app.mjs +80 -0
- package/dist/navigation.d.ts +43 -0
- package/dist/navigation.mjs +143 -0
- package/dist/navigation.test.d.ts +1 -0
- package/dist/navigation.test.mjs +681 -0
- package/dist/options.d.ts +4 -0
- package/dist/options.mjs +88 -0
- package/dist/route-task.d.ts +40 -0
- package/dist/route-task.mjs +75 -0
- package/dist/route-task.test.d.ts +1 -0
- package/dist/route-task.test.mjs +673 -0
- package/dist/route-transition.d.ts +53 -0
- package/dist/route-transition.mjs +307 -0
- package/dist/route-transition.test.d.ts +1 -0
- package/dist/route-transition.test.mjs +146 -0
- package/dist/route.d.ts +72 -0
- package/dist/route.mjs +194 -0
- package/dist/route.test.d.ts +1 -0
- package/dist/route.test.mjs +1664 -0
- package/dist/router-back.test.d.ts +1 -0
- package/dist/router-back.test.mjs +361 -0
- package/dist/router-forward.test.d.ts +1 -0
- package/dist/router-forward.test.mjs +376 -0
- package/dist/router-go.test.d.ts +1 -0
- package/dist/router-go.test.mjs +73 -0
- package/dist/router-guards-cleanup.test.d.ts +1 -0
- package/dist/router-guards-cleanup.test.mjs +437 -0
- package/dist/router-link.d.ts +10 -0
- package/dist/router-link.mjs +126 -0
- package/dist/router-push.test.d.ts +1 -0
- package/dist/router-push.test.mjs +115 -0
- package/dist/router-replace.test.d.ts +1 -0
- package/dist/router-replace.test.mjs +114 -0
- package/dist/router-resolve.test.d.ts +1 -0
- package/dist/router-resolve.test.mjs +393 -0
- package/dist/router-restart-app.dom.test.d.ts +1 -0
- package/dist/router-restart-app.dom.test.mjs +616 -0
- package/dist/router-window-navigation.test.d.ts +1 -0
- package/dist/router-window-navigation.test.mjs +359 -0
- package/dist/router.d.ts +109 -102
- package/dist/router.mjs +260 -361
- package/dist/types.d.ts +246 -0
- package/dist/types.mjs +18 -0
- package/dist/util.d.ts +26 -0
- package/dist/util.mjs +53 -0
- package/dist/util.test.d.ts +1 -0
- package/dist/util.test.mjs +1020 -0
- package/package.json +10 -13
- package/src/error.ts +84 -0
- package/src/increment-id.ts +12 -0
- package/src/index.test.ts +9 -0
- package/src/index.ts +54 -3
- package/src/location.test.ts +406 -0
- package/src/location.ts +96 -0
- package/src/matcher.test.ts +1685 -0
- package/src/matcher.ts +59 -0
- package/src/micro-app.dom.test.ts +708 -0
- package/src/micro-app.ts +101 -0
- package/src/navigation.test.ts +858 -0
- package/src/navigation.ts +195 -0
- package/src/options.ts +131 -0
- package/src/route-task.test.ts +901 -0
- package/src/route-task.ts +105 -0
- package/src/route-transition.test.ts +178 -0
- package/src/route-transition.ts +425 -0
- package/src/route.test.ts +2014 -0
- package/src/route.ts +308 -0
- package/src/router-back.test.ts +487 -0
- package/src/router-forward.test.ts +506 -0
- package/src/router-go.test.ts +91 -0
- package/src/router-guards-cleanup.test.ts +595 -0
- package/src/router-link.ts +235 -0
- package/src/router-push.test.ts +140 -0
- package/src/router-replace.test.ts +139 -0
- package/src/router-resolve.test.ts +475 -0
- package/src/router-restart-app.dom.test.ts +783 -0
- package/src/router-window-navigation.test.ts +457 -0
- package/src/router.ts +289 -470
- package/src/types.ts +341 -0
- package/src/util.test.ts +1262 -0
- package/src/util.ts +116 -0
- package/dist/history/abstract.d.ts +0 -29
- package/dist/history/abstract.mjs +0 -107
- package/dist/history/base.d.ts +0 -79
- package/dist/history/base.mjs +0 -275
- package/dist/history/html.d.ts +0 -22
- package/dist/history/html.mjs +0 -183
- package/dist/history/index.d.ts +0 -7
- package/dist/history/index.mjs +0 -16
- package/dist/matcher/create-matcher.d.ts +0 -5
- package/dist/matcher/create-matcher.mjs +0 -218
- package/dist/matcher/create-matcher.spec.mjs +0 -0
- package/dist/matcher/index.d.ts +0 -1
- package/dist/matcher/index.mjs +0 -1
- package/dist/task-pipe/index.d.ts +0 -1
- package/dist/task-pipe/index.mjs +0 -1
- package/dist/task-pipe/task.d.ts +0 -30
- package/dist/task-pipe/task.mjs +0 -66
- package/dist/utils/bom.d.ts +0 -5
- package/dist/utils/bom.mjs +0 -10
- package/dist/utils/encoding.d.ts +0 -48
- package/dist/utils/encoding.mjs +0 -44
- package/dist/utils/guards.d.ts +0 -9
- package/dist/utils/guards.mjs +0 -12
- package/dist/utils/index.d.ts +0 -7
- package/dist/utils/index.mjs +0 -27
- package/dist/utils/path.d.ts +0 -60
- package/dist/utils/path.mjs +0 -281
- package/dist/utils/path.spec.mjs +0 -27
- package/dist/utils/scroll.d.ts +0 -25
- package/dist/utils/scroll.mjs +0 -59
- package/dist/utils/utils.d.ts +0 -16
- package/dist/utils/utils.mjs +0 -11
- package/dist/utils/warn.d.ts +0 -2
- package/dist/utils/warn.mjs +0 -12
- package/src/history/abstract.ts +0 -149
- package/src/history/base.ts +0 -408
- package/src/history/html.ts +0 -228
- package/src/history/index.ts +0 -20
- package/src/matcher/create-matcher.spec.ts +0 -3
- package/src/matcher/create-matcher.ts +0 -293
- package/src/matcher/index.ts +0 -1
- package/src/task-pipe/index.ts +0 -1
- package/src/task-pipe/task.ts +0 -97
- package/src/utils/bom.ts +0 -14
- package/src/utils/encoding.ts +0 -153
- package/src/utils/guards.ts +0 -25
- package/src/utils/index.ts +0 -27
- package/src/utils/path.spec.ts +0 -32
- package/src/utils/path.ts +0 -417
- package/src/utils/scroll.ts +0 -120
- package/src/utils/utils.ts +0 -30
- package/src/utils/warn.ts +0 -13
- /package/dist/{matcher/create-matcher.spec.d.ts → index.test.d.ts} +0 -0
- /package/dist/{utils/path.spec.d.ts → matcher.test.d.ts} +0 -0
package/src/utils/path.ts
DELETED
|
@@ -1,417 +0,0 @@
|
|
|
1
|
-
import normalizeUrl from 'normalize-url';
|
|
2
|
-
import URLParse from 'url-parse';
|
|
3
|
-
|
|
4
|
-
import type {
|
|
5
|
-
HistoryState,
|
|
6
|
-
Route,
|
|
7
|
-
RouterBase,
|
|
8
|
-
RouterLocation,
|
|
9
|
-
RouterRawLocation
|
|
10
|
-
} from '../types';
|
|
11
|
-
import {
|
|
12
|
-
decode,
|
|
13
|
-
decodeQuery,
|
|
14
|
-
encodeHash,
|
|
15
|
-
encodeQueryKey,
|
|
16
|
-
encodeQueryValue
|
|
17
|
-
} from './encoding';
|
|
18
|
-
import { isValidValue } from './utils';
|
|
19
|
-
import { assert, warn } from './warn';
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* 判断路径是否以 http 或 https 开头 或者直接是域名开头
|
|
23
|
-
*/
|
|
24
|
-
export const regexDomain =
|
|
25
|
-
/^(?:https?:\/\/|[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9](\/.*)?/i;
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* 判断路径是否以 scheme 协议开头
|
|
29
|
-
*/
|
|
30
|
-
export const regexScheme = /^(?:[a-z][a-z\d+.-]*:.+)/i;
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* 判断路径是否以 http(s) 协议开头
|
|
34
|
-
*/
|
|
35
|
-
export const regexHttpScheme = /^(http(s)?:\/\/)/;
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* 去除URL路径中重复的斜杠,但不改变协议部分的双斜杠。
|
|
39
|
-
*
|
|
40
|
-
* @param url 需要处理的URL字符串。
|
|
41
|
-
* @returns 处理后的URL,重复的斜杠被去除。
|
|
42
|
-
*/
|
|
43
|
-
function removeDuplicateSlashes(url: string): string {
|
|
44
|
-
// 正则表达式匹配除了://之外的连续两个或以上斜杠,并替换为一个斜杠
|
|
45
|
-
if (url.includes('://')) {
|
|
46
|
-
const [base, path] = url.split('://');
|
|
47
|
-
const result = path.replace(/\/{2,}/g, '/');
|
|
48
|
-
return `${base}://${result}`;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const result = url.replace(/\/{2,}/g, '/');
|
|
52
|
-
return result;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* 格式化路径 主要用于拼接嵌套路由的路径
|
|
57
|
-
* 返回的格式化后的路径如果有协议则以协议开头,如果没有协议则以/开头
|
|
58
|
-
*/
|
|
59
|
-
export function normalizePath(path: string, parentPath?: string) {
|
|
60
|
-
// 如果path以/开头 说明是绝对路径,不需要拼接路径
|
|
61
|
-
// 按 Hanson 要求,不提供绝对路径
|
|
62
|
-
// if (path.startsWith('/')) {
|
|
63
|
-
// return removeDuplicateSlashes(path);
|
|
64
|
-
// }
|
|
65
|
-
let normalizedPath = parentPath ? `${parentPath}/${path}` : `${path}`;
|
|
66
|
-
|
|
67
|
-
// 当解析的路径不是以http 或 https 协议开头时,给开头加上/
|
|
68
|
-
if (
|
|
69
|
-
!regexHttpScheme.test(normalizedPath) &&
|
|
70
|
-
!normalizedPath.startsWith('/')
|
|
71
|
-
) {
|
|
72
|
-
normalizedPath = `/${normalizedPath}`;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
return (
|
|
76
|
-
// 只有存在父级路由才进行路由拼接
|
|
77
|
-
removeDuplicateSlashes(normalizedPath) // 将多个斜杠 / 替换为单个斜杠 /
|
|
78
|
-
.replace(/\/$/, '') || // 移除结尾的斜杠 /
|
|
79
|
-
'/' // 为空字符串时至少返回单个 /
|
|
80
|
-
);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* 路径解析方法
|
|
85
|
-
* @example 输入 https://www.google.com/test1/test2?a=1&b=2#123 输出 { pathname: '/test1/test2', query: { a: '1', b: '2' }, queryArray: { a: ['1'], b: ['2'] }, hash: '123' }
|
|
86
|
-
* 输入 /test1/test2?a=1&b=2#123 同样输出 { pathname: '/test1/test2', query: { a: '1', b: '2' }, queryArray: { a: ['1'], b: ['2'] }, hash: '123' }
|
|
87
|
-
*/
|
|
88
|
-
export function parsePath(path = ''): {
|
|
89
|
-
pathname: string;
|
|
90
|
-
query: Record<string, string>;
|
|
91
|
-
queryArray: Record<string, string[]>;
|
|
92
|
-
hash: string;
|
|
93
|
-
} {
|
|
94
|
-
path = normalizePath(path);
|
|
95
|
-
const { pathname, query, hash } = new URLParse(path || '/');
|
|
96
|
-
const queryObj = {};
|
|
97
|
-
const queryArray = {};
|
|
98
|
-
if (query.length > 0) {
|
|
99
|
-
query
|
|
100
|
-
.slice(1)
|
|
101
|
-
.split('&')
|
|
102
|
-
.forEach((item) => {
|
|
103
|
-
let [key = '', value = ''] = item.split('=');
|
|
104
|
-
key = decode(key);
|
|
105
|
-
value = decodeQuery(value);
|
|
106
|
-
if (key) {
|
|
107
|
-
queryObj[key] = value;
|
|
108
|
-
queryArray[key] = (queryArray[key] || []).concat(value);
|
|
109
|
-
}
|
|
110
|
-
// queryArray[key] = [
|
|
111
|
-
// ...(queryArray[key] || []),
|
|
112
|
-
// ...(value !== undefined ? [value] : [])
|
|
113
|
-
// ];
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
return {
|
|
117
|
-
pathname,
|
|
118
|
-
query: queryObj,
|
|
119
|
-
queryArray,
|
|
120
|
-
hash: decode(hash)
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* 将path query hash合并为完整路径
|
|
126
|
-
* @example stringifyPath({ pathname: '/news', query: { a: '1' }, hash: '123' }) 输出 '/news?a=1#123'
|
|
127
|
-
*/
|
|
128
|
-
export function stringifyPath(
|
|
129
|
-
{
|
|
130
|
-
pathname = '',
|
|
131
|
-
query = {},
|
|
132
|
-
queryArray = {},
|
|
133
|
-
hash = ''
|
|
134
|
-
}: {
|
|
135
|
-
pathname: string;
|
|
136
|
-
/* 按 Hanson 要求加入 undefined 类型 */
|
|
137
|
-
query: Record<string, string | undefined>;
|
|
138
|
-
queryArray: Record<string, string[]>;
|
|
139
|
-
hash: string;
|
|
140
|
-
} = {
|
|
141
|
-
pathname: '',
|
|
142
|
-
query: {},
|
|
143
|
-
queryArray: {},
|
|
144
|
-
hash: ''
|
|
145
|
-
}
|
|
146
|
-
): string {
|
|
147
|
-
const queryString = Object.entries(
|
|
148
|
-
Object.assign({}, query, queryArray)
|
|
149
|
-
).reduce((acc, [key, value]) => {
|
|
150
|
-
let query = '';
|
|
151
|
-
const encodedKey = encodeQueryKey(key);
|
|
152
|
-
|
|
153
|
-
if (Array.isArray(value)) {
|
|
154
|
-
query = value.reduce((all, item) => {
|
|
155
|
-
if (!isValidValue(item)) return all;
|
|
156
|
-
const encodedValue = encodeQueryValue(item);
|
|
157
|
-
if (encodedValue) {
|
|
158
|
-
all = all
|
|
159
|
-
? `${all}&${encodedKey}=${encodedValue}`
|
|
160
|
-
: `${encodedKey}=${encodedValue}`;
|
|
161
|
-
}
|
|
162
|
-
return all;
|
|
163
|
-
}, '');
|
|
164
|
-
} else {
|
|
165
|
-
const encodedValue = encodeQueryValue(value);
|
|
166
|
-
if (isValidValue(value)) {
|
|
167
|
-
query = `${encodedKey}=${encodedValue}`;
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
if (query) {
|
|
172
|
-
acc = acc ? `${acc}&${query}` : `?${query}`;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
return acc;
|
|
176
|
-
}, '');
|
|
177
|
-
|
|
178
|
-
const hashContent = hash.startsWith('#') ? hash.replace(/^#/, '') : hash;
|
|
179
|
-
const hashString = hashContent ? `#${encodeHash(hashContent)}` : '';
|
|
180
|
-
return `${pathname}${queryString}${hashString}`;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* 标准化 RouterLocation 字段
|
|
185
|
-
*/
|
|
186
|
-
export function normalizeLocation(
|
|
187
|
-
rawLocation: RouterRawLocation,
|
|
188
|
-
base: RouterBase = ''
|
|
189
|
-
): RouterLocation & {
|
|
190
|
-
path: string;
|
|
191
|
-
base: string;
|
|
192
|
-
queryArray: Record<string, string[]>;
|
|
193
|
-
} {
|
|
194
|
-
let pathname = '';
|
|
195
|
-
/* 按 Hanson 要求加入 undefined 类型 */
|
|
196
|
-
let query: Record<string, string | undefined> = {};
|
|
197
|
-
let queryArray: Record<string, string[]> = {};
|
|
198
|
-
let hash = '';
|
|
199
|
-
let params: Record<string, string> | undefined;
|
|
200
|
-
let state: HistoryState = {};
|
|
201
|
-
|
|
202
|
-
if (typeof rawLocation === 'object') {
|
|
203
|
-
const parsedOption = parsePath(rawLocation.path);
|
|
204
|
-
pathname = parsedOption.pathname;
|
|
205
|
-
|
|
206
|
-
// 只有在rawLocation初始传入了 query 或 queryArray 时才使用 rawLocation
|
|
207
|
-
if (rawLocation.query || rawLocation.queryArray) {
|
|
208
|
-
queryArray = rawLocation.queryArray || {};
|
|
209
|
-
query = rawLocation.query || {};
|
|
210
|
-
} else {
|
|
211
|
-
queryArray = parsedOption.queryArray;
|
|
212
|
-
query = parsedOption.query;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
hash = rawLocation.hash || parsedOption.hash;
|
|
216
|
-
|
|
217
|
-
params = rawLocation.params; // params 不使用默认值
|
|
218
|
-
state = rawLocation.state || {};
|
|
219
|
-
} else {
|
|
220
|
-
const parsedOption = parsePath(rawLocation);
|
|
221
|
-
pathname = parsedOption.pathname;
|
|
222
|
-
query = parsedOption.query;
|
|
223
|
-
queryArray = parsedOption.queryArray;
|
|
224
|
-
hash = parsedOption.hash;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
const fullPath = stringifyPath({
|
|
228
|
-
pathname,
|
|
229
|
-
query,
|
|
230
|
-
queryArray,
|
|
231
|
-
hash
|
|
232
|
-
});
|
|
233
|
-
const baseString = normalizePath(
|
|
234
|
-
typeof base === 'function'
|
|
235
|
-
? base({
|
|
236
|
-
fullPath,
|
|
237
|
-
query,
|
|
238
|
-
queryArray,
|
|
239
|
-
hash
|
|
240
|
-
})
|
|
241
|
-
: base
|
|
242
|
-
);
|
|
243
|
-
|
|
244
|
-
let path = pathname;
|
|
245
|
-
// 如果 base 部分包含域名
|
|
246
|
-
if (regexDomain.test(baseString)) {
|
|
247
|
-
const { pathname } = new URLParse(baseString);
|
|
248
|
-
path = normalizePath(path.replace(new RegExp(`^(${pathname})`), ''));
|
|
249
|
-
}
|
|
250
|
-
path = normalizePath(path.replace(new RegExp(`^(${baseString})`), ''));
|
|
251
|
-
|
|
252
|
-
const { query: realQuery, queryArray: realQueryArray } =
|
|
253
|
-
parsePath(fullPath);
|
|
254
|
-
|
|
255
|
-
const res: RouterLocation & {
|
|
256
|
-
path: string;
|
|
257
|
-
base: string;
|
|
258
|
-
queryArray: Record<string, string[]>;
|
|
259
|
-
} = {
|
|
260
|
-
base: baseString,
|
|
261
|
-
path,
|
|
262
|
-
query: realQuery,
|
|
263
|
-
queryArray: realQueryArray,
|
|
264
|
-
hash,
|
|
265
|
-
state
|
|
266
|
-
};
|
|
267
|
-
if (params) res.params = params;
|
|
268
|
-
return res;
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
/**
|
|
272
|
-
* 判断路径是否以协议或域名开头
|
|
273
|
-
*/
|
|
274
|
-
export function isPathWithProtocolOrDomain(
|
|
275
|
-
location: RouterRawLocation,
|
|
276
|
-
base: RouterBase = ''
|
|
277
|
-
): {
|
|
278
|
-
/**
|
|
279
|
-
* 是否以协议或域名开头
|
|
280
|
-
*/
|
|
281
|
-
flag: boolean;
|
|
282
|
-
/**
|
|
283
|
-
* 虚假的 route 信息,内部跳转时无法信任,只有外站跳转时使用
|
|
284
|
-
*/
|
|
285
|
-
route: Route;
|
|
286
|
-
} {
|
|
287
|
-
let url = '';
|
|
288
|
-
let state = {};
|
|
289
|
-
let baseString = '';
|
|
290
|
-
if (typeof base === 'string') {
|
|
291
|
-
baseString = base;
|
|
292
|
-
} else {
|
|
293
|
-
baseString = base({
|
|
294
|
-
fullPath: '',
|
|
295
|
-
query: {},
|
|
296
|
-
queryArray: {},
|
|
297
|
-
hash: ''
|
|
298
|
-
});
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
if (typeof location === 'string') {
|
|
302
|
-
url = location;
|
|
303
|
-
} else {
|
|
304
|
-
state = location.state || {};
|
|
305
|
-
const {
|
|
306
|
-
path,
|
|
307
|
-
query = {},
|
|
308
|
-
queryArray,
|
|
309
|
-
hash = '',
|
|
310
|
-
...nLocation
|
|
311
|
-
} = normalizeLocation(location);
|
|
312
|
-
url = stringifyPath({
|
|
313
|
-
...nLocation,
|
|
314
|
-
query,
|
|
315
|
-
queryArray,
|
|
316
|
-
pathname: path,
|
|
317
|
-
hash
|
|
318
|
-
});
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
try {
|
|
322
|
-
url = normalizeUrl(url, {
|
|
323
|
-
stripWWW: false,
|
|
324
|
-
removeQueryParameters: false
|
|
325
|
-
});
|
|
326
|
-
} catch (error) {
|
|
327
|
-
try {
|
|
328
|
-
url = new URL(url, baseString).href;
|
|
329
|
-
} catch (error) {
|
|
330
|
-
assert(false, `Invalid URL: ${url}`);
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
// 如果以 scheme 协议开头 并且不是 http(s) 协议开头 则认为是外站跳转
|
|
335
|
-
if (regexScheme.test(url) && !regexHttpScheme.test(url)) {
|
|
336
|
-
const {
|
|
337
|
-
hash,
|
|
338
|
-
host,
|
|
339
|
-
hostname,
|
|
340
|
-
href,
|
|
341
|
-
origin,
|
|
342
|
-
pathname,
|
|
343
|
-
port,
|
|
344
|
-
protocol,
|
|
345
|
-
search
|
|
346
|
-
} = new URL(url);
|
|
347
|
-
const route: Route = {
|
|
348
|
-
hash,
|
|
349
|
-
host,
|
|
350
|
-
hostname,
|
|
351
|
-
href,
|
|
352
|
-
origin,
|
|
353
|
-
pathname,
|
|
354
|
-
port,
|
|
355
|
-
protocol,
|
|
356
|
-
search,
|
|
357
|
-
params: {},
|
|
358
|
-
query: {},
|
|
359
|
-
queryArray: {},
|
|
360
|
-
state,
|
|
361
|
-
meta: {},
|
|
362
|
-
path: pathname,
|
|
363
|
-
fullPath: url,
|
|
364
|
-
base: '',
|
|
365
|
-
matched: []
|
|
366
|
-
};
|
|
367
|
-
return {
|
|
368
|
-
flag: true,
|
|
369
|
-
route
|
|
370
|
-
};
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
const {
|
|
374
|
-
hash,
|
|
375
|
-
host,
|
|
376
|
-
hostname,
|
|
377
|
-
href,
|
|
378
|
-
origin,
|
|
379
|
-
pathname,
|
|
380
|
-
port,
|
|
381
|
-
protocol,
|
|
382
|
-
query: search
|
|
383
|
-
} = new URLParse(url);
|
|
384
|
-
const { query = {}, queryArray } = normalizeLocation(url);
|
|
385
|
-
const route: Route = {
|
|
386
|
-
href,
|
|
387
|
-
origin,
|
|
388
|
-
host,
|
|
389
|
-
protocol,
|
|
390
|
-
hostname,
|
|
391
|
-
port,
|
|
392
|
-
pathname,
|
|
393
|
-
search,
|
|
394
|
-
hash,
|
|
395
|
-
query,
|
|
396
|
-
queryArray,
|
|
397
|
-
params: {},
|
|
398
|
-
state,
|
|
399
|
-
meta: {},
|
|
400
|
-
path: pathname,
|
|
401
|
-
fullPath: `${pathname}${search}${hash}`,
|
|
402
|
-
base: '',
|
|
403
|
-
matched: []
|
|
404
|
-
};
|
|
405
|
-
|
|
406
|
-
if (regexDomain.test(url)) {
|
|
407
|
-
return {
|
|
408
|
-
flag: true,
|
|
409
|
-
route
|
|
410
|
-
};
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
return {
|
|
414
|
-
flag: false,
|
|
415
|
-
route
|
|
416
|
-
};
|
|
417
|
-
}
|
package/src/utils/scroll.ts
DELETED
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
RouterRawLocation,
|
|
3
|
-
ScrollPosition,
|
|
4
|
-
ScrollPositionCoordinates,
|
|
5
|
-
_ScrollPositionNormalized
|
|
6
|
-
} from '../types';
|
|
7
|
-
import { warn } from './warn';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* 获取当前滚动位置
|
|
11
|
-
*/
|
|
12
|
-
export const computeScrollPosition = (): _ScrollPositionNormalized => ({
|
|
13
|
-
left: window.scrollX,
|
|
14
|
-
top: window.scrollY
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* 获取元素位置
|
|
19
|
-
*/
|
|
20
|
-
function getElementPosition(
|
|
21
|
-
el: Element,
|
|
22
|
-
offset: ScrollPositionCoordinates
|
|
23
|
-
): _ScrollPositionNormalized {
|
|
24
|
-
const docRect = document.documentElement.getBoundingClientRect();
|
|
25
|
-
const elRect = el.getBoundingClientRect();
|
|
26
|
-
|
|
27
|
-
return {
|
|
28
|
-
behavior: offset.behavior,
|
|
29
|
-
left: elRect.left - docRect.left - (offset.left || 0),
|
|
30
|
-
top: elRect.top - docRect.top - (offset.top || 0)
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* 滚动到指定位置
|
|
36
|
-
*/
|
|
37
|
-
export function scrollToPosition(position: ScrollPosition): void {
|
|
38
|
-
let scrollToOptions: ScrollPositionCoordinates;
|
|
39
|
-
|
|
40
|
-
if ('el' in position) {
|
|
41
|
-
const positionEl = position.el;
|
|
42
|
-
const isIdSelector =
|
|
43
|
-
typeof positionEl === 'string' && positionEl.startsWith('#');
|
|
44
|
-
|
|
45
|
-
const el =
|
|
46
|
-
typeof positionEl === 'string'
|
|
47
|
-
? isIdSelector
|
|
48
|
-
? document.getElementById(positionEl.slice(1))
|
|
49
|
-
: document.querySelector(positionEl)
|
|
50
|
-
: positionEl;
|
|
51
|
-
|
|
52
|
-
if (!el) {
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
scrollToOptions = getElementPosition(el, position);
|
|
56
|
-
} else {
|
|
57
|
-
scrollToOptions = position;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if ('scrollBehavior' in document.documentElement.style) {
|
|
61
|
-
window.scrollTo(scrollToOptions);
|
|
62
|
-
} else {
|
|
63
|
-
window.scrollTo(
|
|
64
|
-
scrollToOptions.left != null
|
|
65
|
-
? scrollToOptions.left
|
|
66
|
-
: window.scrollX,
|
|
67
|
-
scrollToOptions.top != null ? scrollToOptions.top : window.scrollY
|
|
68
|
-
);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* 存储的滚动位置
|
|
74
|
-
*/
|
|
75
|
-
export const scrollPositions = new Map<string, _ScrollPositionNormalized>();
|
|
76
|
-
|
|
77
|
-
const POSITION_KEY = '__scroll_position_key';
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* 保存滚动位置
|
|
81
|
-
*/
|
|
82
|
-
export function saveScrollPosition(
|
|
83
|
-
key: string,
|
|
84
|
-
scrollPosition: _ScrollPositionNormalized
|
|
85
|
-
) {
|
|
86
|
-
scrollPositions.set(key, scrollPosition);
|
|
87
|
-
// preserve existing history state as it could be overriden by the user
|
|
88
|
-
const stateCopy = Object.assign({}, window.history.state);
|
|
89
|
-
stateCopy[POSITION_KEY] = scrollPosition;
|
|
90
|
-
|
|
91
|
-
try {
|
|
92
|
-
const protocolAndPath =
|
|
93
|
-
window.location.protocol + '//' + window.location.host;
|
|
94
|
-
const absolutePath = window.location.href.replace(protocolAndPath, '');
|
|
95
|
-
window.history.replaceState(stateCopy, '', absolutePath);
|
|
96
|
-
} catch (error) {
|
|
97
|
-
warn(`Failed to save scroll position.`, error);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* 获取存储的滚动位置
|
|
103
|
-
*/
|
|
104
|
-
export function getSavedScrollPosition(
|
|
105
|
-
key: string
|
|
106
|
-
): _ScrollPositionNormalized | null {
|
|
107
|
-
const scroll = scrollPositions.get(key) || history.state[POSITION_KEY];
|
|
108
|
-
|
|
109
|
-
// 保存的滚动位置信息不应当被多次使用, 下一次应当使用新保存的位置信息
|
|
110
|
-
scrollPositions.delete(key);
|
|
111
|
-
return scroll || null;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* 获取跳转配置的保持滚动位置参数
|
|
116
|
-
*/
|
|
117
|
-
export function getKeepScrollPosition(location: RouterRawLocation): boolean {
|
|
118
|
-
if (typeof location === 'string') return false;
|
|
119
|
-
return location.keepScrollPosition || false;
|
|
120
|
-
}
|
package/src/utils/utils.ts
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 是否在浏览器环境
|
|
3
|
-
*/
|
|
4
|
-
export const inBrowser = typeof window !== 'undefined';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Symbol 是否可用
|
|
8
|
-
*/
|
|
9
|
-
export const isSymbolAble =
|
|
10
|
-
typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol';
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* 判断是否是 es module 对象
|
|
14
|
-
*/
|
|
15
|
-
export function isESModule(obj: any): boolean {
|
|
16
|
-
return (
|
|
17
|
-
Boolean(obj.__esModule) ||
|
|
18
|
-
(isSymbolAble && obj[Symbol.toStringTag] === 'Module')
|
|
19
|
-
);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* 判断是否是合法的值
|
|
24
|
-
*/
|
|
25
|
-
export function isValidValue(value: any): boolean {
|
|
26
|
-
if (value === null) return false;
|
|
27
|
-
if (value === undefined) return false;
|
|
28
|
-
if (typeof value === 'number' && isNaN(value)) return false;
|
|
29
|
-
return true;
|
|
30
|
-
}
|
package/src/utils/warn.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
export function assert(condition: boolean, message: string) {
|
|
2
|
-
if (!condition) {
|
|
3
|
-
throw new Error(`[@esmx/router] ${message}`);
|
|
4
|
-
}
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export function warn(...args: any[]) {
|
|
8
|
-
console.log(
|
|
9
|
-
'%c ROUTER WARNING:',
|
|
10
|
-
'color: rgb(214, 77, 77); font-weight: bold;',
|
|
11
|
-
...args
|
|
12
|
-
);
|
|
13
|
-
}
|
|
File without changes
|
|
File without changes
|