@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.
Files changed (155) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +70 -0
  3. package/README.zh-CN.md +70 -0
  4. package/dist/error.d.ts +23 -0
  5. package/dist/error.mjs +61 -0
  6. package/dist/increment-id.d.ts +7 -0
  7. package/dist/increment-id.mjs +11 -0
  8. package/dist/index.d.ts +5 -3
  9. package/dist/index.mjs +14 -3
  10. package/dist/index.test.mjs +8 -0
  11. package/dist/location.d.ts +15 -0
  12. package/dist/location.mjs +53 -0
  13. package/dist/location.test.d.ts +8 -0
  14. package/dist/location.test.mjs +370 -0
  15. package/dist/matcher.d.ts +3 -0
  16. package/dist/matcher.mjs +44 -0
  17. package/dist/matcher.test.mjs +1492 -0
  18. package/dist/micro-app.d.ts +18 -0
  19. package/dist/micro-app.dom.test.d.ts +1 -0
  20. package/dist/micro-app.dom.test.mjs +532 -0
  21. package/dist/micro-app.mjs +80 -0
  22. package/dist/navigation.d.ts +43 -0
  23. package/dist/navigation.mjs +143 -0
  24. package/dist/navigation.test.d.ts +1 -0
  25. package/dist/navigation.test.mjs +681 -0
  26. package/dist/options.d.ts +4 -0
  27. package/dist/options.mjs +88 -0
  28. package/dist/route-task.d.ts +40 -0
  29. package/dist/route-task.mjs +75 -0
  30. package/dist/route-task.test.d.ts +1 -0
  31. package/dist/route-task.test.mjs +673 -0
  32. package/dist/route-transition.d.ts +53 -0
  33. package/dist/route-transition.mjs +307 -0
  34. package/dist/route-transition.test.d.ts +1 -0
  35. package/dist/route-transition.test.mjs +146 -0
  36. package/dist/route.d.ts +72 -0
  37. package/dist/route.mjs +194 -0
  38. package/dist/route.test.d.ts +1 -0
  39. package/dist/route.test.mjs +1664 -0
  40. package/dist/router-back.test.d.ts +1 -0
  41. package/dist/router-back.test.mjs +361 -0
  42. package/dist/router-forward.test.d.ts +1 -0
  43. package/dist/router-forward.test.mjs +376 -0
  44. package/dist/router-go.test.d.ts +1 -0
  45. package/dist/router-go.test.mjs +73 -0
  46. package/dist/router-guards-cleanup.test.d.ts +1 -0
  47. package/dist/router-guards-cleanup.test.mjs +437 -0
  48. package/dist/router-link.d.ts +10 -0
  49. package/dist/router-link.mjs +126 -0
  50. package/dist/router-push.test.d.ts +1 -0
  51. package/dist/router-push.test.mjs +115 -0
  52. package/dist/router-replace.test.d.ts +1 -0
  53. package/dist/router-replace.test.mjs +114 -0
  54. package/dist/router-resolve.test.d.ts +1 -0
  55. package/dist/router-resolve.test.mjs +393 -0
  56. package/dist/router-restart-app.dom.test.d.ts +1 -0
  57. package/dist/router-restart-app.dom.test.mjs +616 -0
  58. package/dist/router-window-navigation.test.d.ts +1 -0
  59. package/dist/router-window-navigation.test.mjs +359 -0
  60. package/dist/router.d.ts +109 -102
  61. package/dist/router.mjs +260 -361
  62. package/dist/types.d.ts +246 -0
  63. package/dist/types.mjs +18 -0
  64. package/dist/util.d.ts +26 -0
  65. package/dist/util.mjs +53 -0
  66. package/dist/util.test.d.ts +1 -0
  67. package/dist/util.test.mjs +1020 -0
  68. package/package.json +10 -13
  69. package/src/error.ts +84 -0
  70. package/src/increment-id.ts +12 -0
  71. package/src/index.test.ts +9 -0
  72. package/src/index.ts +54 -3
  73. package/src/location.test.ts +406 -0
  74. package/src/location.ts +96 -0
  75. package/src/matcher.test.ts +1685 -0
  76. package/src/matcher.ts +59 -0
  77. package/src/micro-app.dom.test.ts +708 -0
  78. package/src/micro-app.ts +101 -0
  79. package/src/navigation.test.ts +858 -0
  80. package/src/navigation.ts +195 -0
  81. package/src/options.ts +131 -0
  82. package/src/route-task.test.ts +901 -0
  83. package/src/route-task.ts +105 -0
  84. package/src/route-transition.test.ts +178 -0
  85. package/src/route-transition.ts +425 -0
  86. package/src/route.test.ts +2014 -0
  87. package/src/route.ts +308 -0
  88. package/src/router-back.test.ts +487 -0
  89. package/src/router-forward.test.ts +506 -0
  90. package/src/router-go.test.ts +91 -0
  91. package/src/router-guards-cleanup.test.ts +595 -0
  92. package/src/router-link.ts +235 -0
  93. package/src/router-push.test.ts +140 -0
  94. package/src/router-replace.test.ts +139 -0
  95. package/src/router-resolve.test.ts +475 -0
  96. package/src/router-restart-app.dom.test.ts +783 -0
  97. package/src/router-window-navigation.test.ts +457 -0
  98. package/src/router.ts +289 -470
  99. package/src/types.ts +341 -0
  100. package/src/util.test.ts +1262 -0
  101. package/src/util.ts +116 -0
  102. package/dist/history/abstract.d.ts +0 -29
  103. package/dist/history/abstract.mjs +0 -107
  104. package/dist/history/base.d.ts +0 -79
  105. package/dist/history/base.mjs +0 -275
  106. package/dist/history/html.d.ts +0 -22
  107. package/dist/history/html.mjs +0 -183
  108. package/dist/history/index.d.ts +0 -7
  109. package/dist/history/index.mjs +0 -16
  110. package/dist/matcher/create-matcher.d.ts +0 -5
  111. package/dist/matcher/create-matcher.mjs +0 -218
  112. package/dist/matcher/create-matcher.spec.mjs +0 -0
  113. package/dist/matcher/index.d.ts +0 -1
  114. package/dist/matcher/index.mjs +0 -1
  115. package/dist/task-pipe/index.d.ts +0 -1
  116. package/dist/task-pipe/index.mjs +0 -1
  117. package/dist/task-pipe/task.d.ts +0 -30
  118. package/dist/task-pipe/task.mjs +0 -66
  119. package/dist/utils/bom.d.ts +0 -5
  120. package/dist/utils/bom.mjs +0 -10
  121. package/dist/utils/encoding.d.ts +0 -48
  122. package/dist/utils/encoding.mjs +0 -44
  123. package/dist/utils/guards.d.ts +0 -9
  124. package/dist/utils/guards.mjs +0 -12
  125. package/dist/utils/index.d.ts +0 -7
  126. package/dist/utils/index.mjs +0 -27
  127. package/dist/utils/path.d.ts +0 -60
  128. package/dist/utils/path.mjs +0 -281
  129. package/dist/utils/path.spec.mjs +0 -27
  130. package/dist/utils/scroll.d.ts +0 -25
  131. package/dist/utils/scroll.mjs +0 -59
  132. package/dist/utils/utils.d.ts +0 -16
  133. package/dist/utils/utils.mjs +0 -11
  134. package/dist/utils/warn.d.ts +0 -2
  135. package/dist/utils/warn.mjs +0 -12
  136. package/src/history/abstract.ts +0 -149
  137. package/src/history/base.ts +0 -408
  138. package/src/history/html.ts +0 -228
  139. package/src/history/index.ts +0 -20
  140. package/src/matcher/create-matcher.spec.ts +0 -3
  141. package/src/matcher/create-matcher.ts +0 -293
  142. package/src/matcher/index.ts +0 -1
  143. package/src/task-pipe/index.ts +0 -1
  144. package/src/task-pipe/task.ts +0 -97
  145. package/src/utils/bom.ts +0 -14
  146. package/src/utils/encoding.ts +0 -153
  147. package/src/utils/guards.ts +0 -25
  148. package/src/utils/index.ts +0 -27
  149. package/src/utils/path.spec.ts +0 -32
  150. package/src/utils/path.ts +0 -417
  151. package/src/utils/scroll.ts +0 -120
  152. package/src/utils/utils.ts +0 -30
  153. package/src/utils/warn.ts +0 -13
  154. /package/dist/{matcher/create-matcher.spec.d.ts → index.test.d.ts} +0 -0
  155. /package/dist/{utils/path.spec.d.ts → matcher.test.d.ts} +0 -0
@@ -1,27 +0,0 @@
1
- export {
2
- regexDomain,
3
- normalizePath,
4
- parsePath,
5
- stringifyPath,
6
- normalizeLocation,
7
- isPathWithProtocolOrDomain
8
- } from "./path.mjs";
9
- export { isESModule, inBrowser } from "./utils.mjs";
10
- export { warn } from "./warn.mjs";
11
- export { isSameRoute, isEqualRoute } from "./guards.mjs";
12
- export {
13
- computeScrollPosition,
14
- scrollToPosition,
15
- saveScrollPosition,
16
- getSavedScrollPosition,
17
- getKeepScrollPosition
18
- } from "./scroll.mjs";
19
- export { openWindow } from "./bom.mjs";
20
- export {
21
- encodeHash,
22
- encodeParam,
23
- encodePath,
24
- encodeQueryKey,
25
- encodeQueryValue,
26
- decode
27
- } from "./encoding.mjs";
@@ -1,60 +0,0 @@
1
- import type { Route, RouterBase, RouterLocation, RouterRawLocation } from '../types';
2
- /**
3
- * 判断路径是否以 http 或 https 开头 或者直接是域名开头
4
- */
5
- export declare const regexDomain: RegExp;
6
- /**
7
- * 判断路径是否以 scheme 协议开头
8
- */
9
- export declare const regexScheme: RegExp;
10
- /**
11
- * 判断路径是否以 http(s) 协议开头
12
- */
13
- export declare const regexHttpScheme: RegExp;
14
- /**
15
- * 格式化路径 主要用于拼接嵌套路由的路径
16
- * 返回的格式化后的路径如果有协议则以协议开头,如果没有协议则以/开头
17
- */
18
- export declare function normalizePath(path: string, parentPath?: string): string;
19
- /**
20
- * 路径解析方法
21
- * @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' }
22
- * 输入 /test1/test2?a=1&b=2#123 同样输出 { pathname: '/test1/test2', query: { a: '1', b: '2' }, queryArray: { a: ['1'], b: ['2'] }, hash: '123' }
23
- */
24
- export declare function parsePath(path?: string): {
25
- pathname: string;
26
- query: Record<string, string>;
27
- queryArray: Record<string, string[]>;
28
- hash: string;
29
- };
30
- /**
31
- * 将path query hash合并为完整路径
32
- * @example stringifyPath({ pathname: '/news', query: { a: '1' }, hash: '123' }) 输出 '/news?a=1#123'
33
- */
34
- export declare function stringifyPath({ pathname, query, queryArray, hash }?: {
35
- pathname: string;
36
- query: Record<string, string | undefined>;
37
- queryArray: Record<string, string[]>;
38
- hash: string;
39
- }): string;
40
- /**
41
- * 标准化 RouterLocation 字段
42
- */
43
- export declare function normalizeLocation(rawLocation: RouterRawLocation, base?: RouterBase): RouterLocation & {
44
- path: string;
45
- base: string;
46
- queryArray: Record<string, string[]>;
47
- };
48
- /**
49
- * 判断路径是否以协议或域名开头
50
- */
51
- export declare function isPathWithProtocolOrDomain(location: RouterRawLocation, base?: RouterBase): {
52
- /**
53
- * 是否以协议或域名开头
54
- */
55
- flag: boolean;
56
- /**
57
- * 虚假的 route 信息,内部跳转时无法信任,只有外站跳转时使用
58
- */
59
- route: Route;
60
- };
@@ -1,281 +0,0 @@
1
- import normalizeUrl from "normalize-url";
2
- import URLParse from "url-parse";
3
- import {
4
- decode,
5
- decodeQuery,
6
- encodeHash,
7
- encodeQueryKey,
8
- encodeQueryValue
9
- } from "./encoding.mjs";
10
- import { isValidValue } from "./utils.mjs";
11
- import { assert } from "./warn.mjs";
12
- export const regexDomain = /^(?:https?:\/\/|[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9](\/.*)?/i;
13
- export const regexScheme = /^(?:[a-z][a-z\d+.-]*:.+)/i;
14
- export const regexHttpScheme = /^(http(s)?:\/\/)/;
15
- function removeDuplicateSlashes(url) {
16
- if (url.includes("://")) {
17
- const [base, path] = url.split("://");
18
- const result2 = path.replace(/\/{2,}/g, "/");
19
- return `${base}://${result2}`;
20
- }
21
- const result = url.replace(/\/{2,}/g, "/");
22
- return result;
23
- }
24
- export function normalizePath(path, parentPath) {
25
- let normalizedPath = parentPath ? `${parentPath}/${path}` : `${path}`;
26
- if (!regexHttpScheme.test(normalizedPath) && !normalizedPath.startsWith("/")) {
27
- normalizedPath = `/${normalizedPath}`;
28
- }
29
- return (
30
- // 只有存在父级路由才进行路由拼接
31
- removeDuplicateSlashes(normalizedPath).replace(/\/$/, "") || // 移除结尾的斜杠 /
32
- "/"
33
- );
34
- }
35
- export function parsePath(path = "") {
36
- path = normalizePath(path);
37
- const { pathname, query, hash } = new URLParse(path || "/");
38
- const queryObj = {};
39
- const queryArray = {};
40
- if (query.length > 0) {
41
- query.slice(1).split("&").forEach((item) => {
42
- let [key = "", value = ""] = item.split("=");
43
- key = decode(key);
44
- value = decodeQuery(value);
45
- if (key) {
46
- queryObj[key] = value;
47
- queryArray[key] = (queryArray[key] || []).concat(value);
48
- }
49
- });
50
- }
51
- return {
52
- pathname,
53
- query: queryObj,
54
- queryArray,
55
- hash: decode(hash)
56
- };
57
- }
58
- export function stringifyPath({
59
- pathname = "",
60
- query = {},
61
- queryArray = {},
62
- hash = ""
63
- } = {
64
- pathname: "",
65
- query: {},
66
- queryArray: {},
67
- hash: ""
68
- }) {
69
- const queryString = Object.entries(
70
- Object.assign({}, query, queryArray)
71
- ).reduce((acc, [key, value]) => {
72
- let query2 = "";
73
- const encodedKey = encodeQueryKey(key);
74
- if (Array.isArray(value)) {
75
- query2 = value.reduce((all, item) => {
76
- if (!isValidValue(item)) return all;
77
- const encodedValue = encodeQueryValue(item);
78
- if (encodedValue) {
79
- all = all ? `${all}&${encodedKey}=${encodedValue}` : `${encodedKey}=${encodedValue}`;
80
- }
81
- return all;
82
- }, "");
83
- } else {
84
- const encodedValue = encodeQueryValue(value);
85
- if (isValidValue(value)) {
86
- query2 = `${encodedKey}=${encodedValue}`;
87
- }
88
- }
89
- if (query2) {
90
- acc = acc ? `${acc}&${query2}` : `?${query2}`;
91
- }
92
- return acc;
93
- }, "");
94
- const hashContent = hash.startsWith("#") ? hash.replace(/^#/, "") : hash;
95
- const hashString = hashContent ? `#${encodeHash(hashContent)}` : "";
96
- return `${pathname}${queryString}${hashString}`;
97
- }
98
- export function normalizeLocation(rawLocation, base = "") {
99
- let pathname = "";
100
- let query = {};
101
- let queryArray = {};
102
- let hash = "";
103
- let params;
104
- let state = {};
105
- if (typeof rawLocation === "object") {
106
- const parsedOption = parsePath(rawLocation.path);
107
- pathname = parsedOption.pathname;
108
- if (rawLocation.query || rawLocation.queryArray) {
109
- queryArray = rawLocation.queryArray || {};
110
- query = rawLocation.query || {};
111
- } else {
112
- queryArray = parsedOption.queryArray;
113
- query = parsedOption.query;
114
- }
115
- hash = rawLocation.hash || parsedOption.hash;
116
- params = rawLocation.params;
117
- state = rawLocation.state || {};
118
- } else {
119
- const parsedOption = parsePath(rawLocation);
120
- pathname = parsedOption.pathname;
121
- query = parsedOption.query;
122
- queryArray = parsedOption.queryArray;
123
- hash = parsedOption.hash;
124
- }
125
- const fullPath = stringifyPath({
126
- pathname,
127
- query,
128
- queryArray,
129
- hash
130
- });
131
- const baseString = normalizePath(
132
- typeof base === "function" ? base({
133
- fullPath,
134
- query,
135
- queryArray,
136
- hash
137
- }) : base
138
- );
139
- let path = pathname;
140
- if (regexDomain.test(baseString)) {
141
- const { pathname: pathname2 } = new URLParse(baseString);
142
- path = normalizePath(path.replace(new RegExp(`^(${pathname2})`), ""));
143
- }
144
- path = normalizePath(path.replace(new RegExp(`^(${baseString})`), ""));
145
- const { query: realQuery, queryArray: realQueryArray } = parsePath(fullPath);
146
- const res = {
147
- base: baseString,
148
- path,
149
- query: realQuery,
150
- queryArray: realQueryArray,
151
- hash,
152
- state
153
- };
154
- if (params) res.params = params;
155
- return res;
156
- }
157
- export function isPathWithProtocolOrDomain(location, base = "") {
158
- let url = "";
159
- let state = {};
160
- let baseString = "";
161
- if (typeof base === "string") {
162
- baseString = base;
163
- } else {
164
- baseString = base({
165
- fullPath: "",
166
- query: {},
167
- queryArray: {},
168
- hash: ""
169
- });
170
- }
171
- if (typeof location === "string") {
172
- url = location;
173
- } else {
174
- state = location.state || {};
175
- const {
176
- path,
177
- query: query2 = {},
178
- queryArray: queryArray2,
179
- hash: hash2 = "",
180
- ...nLocation
181
- } = normalizeLocation(location);
182
- url = stringifyPath({
183
- ...nLocation,
184
- query: query2,
185
- queryArray: queryArray2,
186
- pathname: path,
187
- hash: hash2
188
- });
189
- }
190
- try {
191
- url = normalizeUrl(url, {
192
- stripWWW: false,
193
- removeQueryParameters: false
194
- });
195
- } catch (error) {
196
- try {
197
- url = new URL(url, baseString).href;
198
- } catch (error2) {
199
- assert(false, `Invalid URL: ${url}`);
200
- }
201
- }
202
- if (regexScheme.test(url) && !regexHttpScheme.test(url)) {
203
- const {
204
- hash: hash2,
205
- host: host2,
206
- hostname: hostname2,
207
- href: href2,
208
- origin: origin2,
209
- pathname: pathname2,
210
- port: port2,
211
- protocol: protocol2,
212
- search: search2
213
- } = new URL(url);
214
- const route2 = {
215
- hash: hash2,
216
- host: host2,
217
- hostname: hostname2,
218
- href: href2,
219
- origin: origin2,
220
- pathname: pathname2,
221
- port: port2,
222
- protocol: protocol2,
223
- search: search2,
224
- params: {},
225
- query: {},
226
- queryArray: {},
227
- state,
228
- meta: {},
229
- path: pathname2,
230
- fullPath: url,
231
- base: "",
232
- matched: []
233
- };
234
- return {
235
- flag: true,
236
- route: route2
237
- };
238
- }
239
- const {
240
- hash,
241
- host,
242
- hostname,
243
- href,
244
- origin,
245
- pathname,
246
- port,
247
- protocol,
248
- query: search
249
- } = new URLParse(url);
250
- const { query = {}, queryArray } = normalizeLocation(url);
251
- const route = {
252
- href,
253
- origin,
254
- host,
255
- protocol,
256
- hostname,
257
- port,
258
- pathname,
259
- search,
260
- hash,
261
- query,
262
- queryArray,
263
- params: {},
264
- state,
265
- meta: {},
266
- path: pathname,
267
- fullPath: `${pathname}${search}${hash}`,
268
- base: "",
269
- matched: []
270
- };
271
- if (regexDomain.test(url)) {
272
- return {
273
- flag: true,
274
- route
275
- };
276
- }
277
- return {
278
- flag: false,
279
- route
280
- };
281
- }
@@ -1,27 +0,0 @@
1
- import { describe, it } from "vitest";
2
- import { normalizeLocation, normalizePath } from "./path.mjs";
3
- describe("testing normalizeLocation", () => {
4
- it("testing normal domain", ({ expect }) => {
5
- expect(
6
- normalizeLocation(
7
- "http://localhost:5173/en/en/en/en/en",
8
- "http://localhost:5173/en/"
9
- ).path
10
- ).toBe("/en/en/en/en");
11
- });
12
- it("testing path", ({ expect }) => {
13
- expect(
14
- normalizeLocation("/test1/test2?t=https://www-six.betafollowme.com").path
15
- ).toBe("/test1/test2");
16
- });
17
- });
18
- describe("testing normalizePath", () => {
19
- it("testing normal domain", ({ expect }) => {
20
- expect(normalizePath("test2", "test1")).toBe("/test1/test2");
21
- });
22
- it("testing path", ({ expect }) => {
23
- expect(
24
- normalizeLocation("/test1/test2?t=https://www-six.betafollowme.com").path
25
- ).toBe("/test1/test2");
26
- });
27
- });
@@ -1,25 +0,0 @@
1
- import type { RouterRawLocation, ScrollPosition, _ScrollPositionNormalized } from '../types';
2
- /**
3
- * 获取当前滚动位置
4
- */
5
- export declare const computeScrollPosition: () => _ScrollPositionNormalized;
6
- /**
7
- * 滚动到指定位置
8
- */
9
- export declare function scrollToPosition(position: ScrollPosition): void;
10
- /**
11
- * 存储的滚动位置
12
- */
13
- export declare const scrollPositions: Map<string, _ScrollPositionNormalized>;
14
- /**
15
- * 保存滚动位置
16
- */
17
- export declare function saveScrollPosition(key: string, scrollPosition: _ScrollPositionNormalized): void;
18
- /**
19
- * 获取存储的滚动位置
20
- */
21
- export declare function getSavedScrollPosition(key: string): _ScrollPositionNormalized | null;
22
- /**
23
- * 获取跳转配置的保持滚动位置参数
24
- */
25
- export declare function getKeepScrollPosition(location: RouterRawLocation): boolean;
@@ -1,59 +0,0 @@
1
- import { warn } from "./warn.mjs";
2
- export const computeScrollPosition = () => ({
3
- left: window.scrollX,
4
- top: window.scrollY
5
- });
6
- function getElementPosition(el, offset) {
7
- const docRect = document.documentElement.getBoundingClientRect();
8
- const elRect = el.getBoundingClientRect();
9
- return {
10
- behavior: offset.behavior,
11
- left: elRect.left - docRect.left - (offset.left || 0),
12
- top: elRect.top - docRect.top - (offset.top || 0)
13
- };
14
- }
15
- export function scrollToPosition(position) {
16
- let scrollToOptions;
17
- if ("el" in position) {
18
- const positionEl = position.el;
19
- const isIdSelector = typeof positionEl === "string" && positionEl.startsWith("#");
20
- const el = typeof positionEl === "string" ? isIdSelector ? document.getElementById(positionEl.slice(1)) : document.querySelector(positionEl) : positionEl;
21
- if (!el) {
22
- return;
23
- }
24
- scrollToOptions = getElementPosition(el, position);
25
- } else {
26
- scrollToOptions = position;
27
- }
28
- if ("scrollBehavior" in document.documentElement.style) {
29
- window.scrollTo(scrollToOptions);
30
- } else {
31
- window.scrollTo(
32
- scrollToOptions.left != null ? scrollToOptions.left : window.scrollX,
33
- scrollToOptions.top != null ? scrollToOptions.top : window.scrollY
34
- );
35
- }
36
- }
37
- export const scrollPositions = /* @__PURE__ */ new Map();
38
- const POSITION_KEY = "__scroll_position_key";
39
- export function saveScrollPosition(key, scrollPosition) {
40
- scrollPositions.set(key, scrollPosition);
41
- const stateCopy = Object.assign({}, window.history.state);
42
- stateCopy[POSITION_KEY] = scrollPosition;
43
- try {
44
- const protocolAndPath = window.location.protocol + "//" + window.location.host;
45
- const absolutePath = window.location.href.replace(protocolAndPath, "");
46
- window.history.replaceState(stateCopy, "", absolutePath);
47
- } catch (error) {
48
- warn(`Failed to save scroll position.`, error);
49
- }
50
- }
51
- export function getSavedScrollPosition(key) {
52
- const scroll = scrollPositions.get(key) || history.state[POSITION_KEY];
53
- scrollPositions.delete(key);
54
- return scroll || null;
55
- }
56
- export function getKeepScrollPosition(location) {
57
- if (typeof location === "string") return false;
58
- return location.keepScrollPosition || false;
59
- }
@@ -1,16 +0,0 @@
1
- /**
2
- * 是否在浏览器环境
3
- */
4
- export declare const inBrowser: boolean;
5
- /**
6
- * Symbol 是否可用
7
- */
8
- export declare const isSymbolAble: boolean;
9
- /**
10
- * 判断是否是 es module 对象
11
- */
12
- export declare function isESModule(obj: any): boolean;
13
- /**
14
- * 判断是否是合法的值
15
- */
16
- export declare function isValidValue(value: any): boolean;
@@ -1,11 +0,0 @@
1
- export const inBrowser = typeof window !== "undefined";
2
- export const isSymbolAble = typeof Symbol === "function" && typeof Symbol.toStringTag === "symbol";
3
- export function isESModule(obj) {
4
- return Boolean(obj.__esModule) || isSymbolAble && obj[Symbol.toStringTag] === "Module";
5
- }
6
- export function isValidValue(value) {
7
- if (value === null) return false;
8
- if (value === void 0) return false;
9
- if (typeof value === "number" && isNaN(value)) return false;
10
- return true;
11
- }
@@ -1,2 +0,0 @@
1
- export declare function assert(condition: boolean, message: string): void;
2
- export declare function warn(...args: any[]): void;
@@ -1,12 +0,0 @@
1
- export function assert(condition, message) {
2
- if (!condition) {
3
- throw new Error(`[@esmx/router] ${message}`);
4
- }
5
- }
6
- export function warn(...args) {
7
- console.log(
8
- "%c ROUTER WARNING:",
9
- "color: rgb(214, 77, 77); font-weight: bold;",
10
- ...args
11
- );
12
- }
@@ -1,149 +0,0 @@
1
- import type {
2
- Route,
3
- RouteRecord,
4
- RouterInstance,
5
- RouterRawLocation
6
- } from '../types';
7
- import { isPathWithProtocolOrDomain, normalizeLocation } from '../utils';
8
- import { BaseRouterHistory } from './base';
9
-
10
- export class AbstractHistory extends BaseRouterHistory {
11
- index: number;
12
- stack: RouteRecord[];
13
-
14
- constructor(router: RouterInstance) {
15
- super(router);
16
- this.index = -1;
17
- this.stack = [];
18
- }
19
-
20
- async init({ replace }: { replace?: boolean } = { replace: true }) {
21
- const { initUrl } = this.router.options;
22
- if (initUrl !== undefined) {
23
- // 存在 initUrl 则用 initUrl 进行初始化
24
- if (replace) {
25
- await this.replace(initUrl);
26
- } else {
27
- await this.push(initUrl);
28
- }
29
- }
30
- }
31
-
32
- destroy() {}
33
-
34
- // 设置监听函数
35
- setupListeners() {}
36
-
37
- // 服务端判断是否是相同域名
38
- isSameHost(location: RouterRawLocation, route: Route) {
39
- const rawLocation =
40
- typeof location === 'string' ? { path: location } : location;
41
- if (rawLocation.path === undefined) {
42
- rawLocation.path = this.current.fullPath;
43
- }
44
-
45
- // 服务端 base 需要包含域名,判断 base 是否包含传入路径的域名即可
46
- const { base } = normalizeLocation(rawLocation, this.router.base);
47
-
48
- return base.includes(route.hostname);
49
- }
50
-
51
- // 处理外站跳转逻辑
52
- handleOutside(
53
- location: RouterRawLocation,
54
- replace = false,
55
- isTriggerWithWindow = false
56
- ) {
57
- const base = this.router.base;
58
- const { flag, route } = isPathWithProtocolOrDomain(location, base);
59
- if (!flag) {
60
- // 如果不以域名开头则跳出
61
- return false;
62
- }
63
-
64
- const router = this.router;
65
- const { validateOutside, handleOutside } = router.options;
66
-
67
- // 如果域名相同 和 非外站(存在就算同域也会被视为外站的情况) 则跳出
68
- const isSameHost = this.isSameHost(location, route);
69
- if (isSameHost && !validateOutside?.({ router, location, route })) {
70
- return false;
71
- }
72
-
73
- // 如果有配置跳转外站函数,则执行配置函数
74
- handleOutside?.({
75
- router,
76
- route,
77
- replace,
78
- isTriggerWithWindow,
79
- isSameHost
80
- });
81
-
82
- return true;
83
- }
84
-
85
- // 新增路由记录跳转
86
- async push(location: RouterRawLocation) {
87
- await this.jump(location, false);
88
- }
89
-
90
- /**
91
- * 新开浏览器窗口的方法,在服务端会调用 push 作为替代
92
- */
93
- async pushWindow(location: RouterRawLocation) {
94
- await this._jump(location, false, true);
95
- }
96
-
97
- // 替换当前路由记录跳转
98
- async replace(location: RouterRawLocation) {
99
- await this.jump(location, true);
100
- }
101
-
102
- /**
103
- * 替换当前浏览器窗口的方法,在服务端会调用 replace 作为替代
104
- */
105
- async replaceWindow(location: RouterRawLocation) {
106
- await this._jump(location, true, true);
107
- }
108
-
109
- // 跳转方法
110
- async jump(location: RouterRawLocation, replace = false) {
111
- await this._jump(location, replace);
112
- }
113
-
114
- async _jump(
115
- location: RouterRawLocation,
116
- replace = false,
117
- isTriggerWithWindow = false
118
- ) {
119
- if (this.handleOutside(location, replace, isTriggerWithWindow)) {
120
- return;
121
- }
122
-
123
- await this.transitionTo(location, (route) => {
124
- const index = replace ? this.index : this.index + 1;
125
- this.stack = this.stack.slice(0, index).concat(route);
126
- });
127
- }
128
-
129
- go(delta: number): void {
130
- const targetIndex = this.index + delta;
131
- // 浏览器在跳转到不存在的历史记录时不会进行跳转
132
- if (targetIndex < 0 || targetIndex >= this.stack.length) {
133
- return;
134
- }
135
- const route = this.stack[targetIndex];
136
- this.index = targetIndex;
137
- this.updateRoute(route);
138
- }
139
-
140
- /* 路由历史记录前进方法 */
141
- forward() {
142
- this.go(1);
143
- }
144
-
145
- /* 路由历史记录后退方法 */
146
- back() {
147
- this.go(-1);
148
- }
149
- }