@mantou/gem 2.2.15 → 2.3.1
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/dist/gem.js +7 -7
- package/dist/gem.mjs +7 -7
- package/elements/base/dialog.d.ts.map +1 -1
- package/elements/base/link.d.ts.map +1 -1
- package/elements/base/link.js +1 -1
- package/elements/base/link.js.map +1 -1
- package/elements/base/modal-factory.d.ts +20 -510
- package/elements/base/modal-factory.d.ts.map +1 -1
- package/elements/base/modal-factory.js +3 -2
- package/elements/base/modal-factory.js.map +1 -1
- package/elements/base/reflect.d.ts +7 -4
- package/elements/base/reflect.d.ts.map +1 -1
- package/elements/base/reflect.js +30 -4
- package/elements/base/reflect.js.map +1 -1
- package/elements/base/route.d.ts +11 -9
- package/elements/base/route.d.ts.map +1 -1
- package/elements/base/route.js +84 -44
- package/elements/base/route.js.map +1 -1
- package/elements/base/title.d.ts.map +1 -1
- package/elements/base/title.js +1 -1
- package/elements/base/title.js.map +1 -1
- package/helper/hmr.js.map +1 -1
- package/helper/i18n.d.ts +21 -17
- package/helper/i18n.d.ts.map +1 -1
- package/helper/i18n.js +172 -116
- package/helper/i18n.js.map +1 -1
- package/helper/logger.d.ts.map +1 -1
- package/helper/mediaquery.d.ts.map +1 -1
- package/helper/request.d.ts +7 -1
- package/helper/request.d.ts.map +1 -1
- package/helper/request.js.map +1 -1
- package/helper/theme.d.ts +8 -4
- package/helper/theme.d.ts.map +1 -1
- package/helper/theme.js +12 -9
- package/helper/theme.js.map +1 -1
- package/lib/decorators.d.ts +3 -2
- package/lib/decorators.d.ts.map +1 -1
- package/lib/decorators.js +29 -44
- package/lib/decorators.js.map +1 -1
- package/lib/directive.d.ts.map +1 -1
- package/lib/history.d.ts +46 -42
- package/lib/history.d.ts.map +1 -1
- package/lib/history.js +19 -37
- package/lib/history.js.map +1 -1
- package/lib/lit-html.d.ts.map +1 -1
- package/lib/lit-html.js.map +1 -1
- package/lib/reactive.d.ts +7 -9
- package/lib/reactive.d.ts.map +1 -1
- package/lib/reactive.js +86 -115
- package/lib/reactive.js.map +1 -1
- package/lib/repeat.d.ts +1 -1
- package/lib/repeat.d.ts.map +1 -1
- package/lib/repeat.js.map +1 -1
- package/lib/server.d.ts +12 -0
- package/lib/server.d.ts.map +1 -1
- package/lib/server.js +2 -0
- package/lib/server.js.map +1 -1
- package/lib/store.d.ts +0 -6
- package/lib/store.d.ts.map +1 -1
- package/lib/store.js +5 -17
- package/lib/store.js.map +1 -1
- package/lib/utils.d.ts.map +1 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.d.ts.map +1 -1
- package/lib/version.js +1 -1
- package/lib/version.js.map +1 -1
- package/package.json +7 -8
- package/src/elements/base/modal-factory.ts +22 -6
- package/src/elements/base/reflect.ts +30 -4
- package/src/elements/base/route.ts +80 -50
- package/src/helper/i18n.ts +184 -127
- package/src/helper/theme.ts +16 -9
- package/src/lib/decorators.ts +36 -49
- package/src/lib/history.ts +19 -32
- package/src/lib/reactive.ts +90 -126
- package/src/lib/server.ts +14 -0
- package/src/lib/store.ts +3 -19
- package/src/lib/version.ts +1 -1
- package/src/test/elements/gesture.test.ts +13 -5
- package/src/test/elements/link.test.ts +12 -2
- package/src/test/elements/reflect.test.ts +20 -1
- package/src/test/elements/route.test.ts +102 -0
- package/src/test/elements/title.test.ts +7 -0
- package/src/test/elements/unsafe.test.ts +22 -0
- package/src/test/gem-element/advance.test.ts +106 -0
- package/src/test/gem-element/basic.test.ts +13 -0
- package/src/test/history.test.ts +19 -0
- package/src/test/theme.test.ts +8 -1
- package/src/test/utils.test.ts +10 -0
- package/src/test/utils.ts +56 -0
package/lib/store.d.ts
CHANGED
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
import { type Updater } from './utils';
|
|
2
2
|
export type Store<T = any> = Updater<T>;
|
|
3
|
-
/** SSR 时当前请求中更新过的有 key 的 store,供 `@mantou/gem-ssr` 使用 */
|
|
4
|
-
export declare const _getUpdatedStores: () => Map<any, any>;
|
|
5
|
-
declare let restoreStore: ((key: string) => object | undefined) | undefined;
|
|
6
|
-
/** 设置客户端恢复 store 的方法,供 `@mantou/gem-ssr` 使用 */
|
|
7
|
-
export declare function _setStoreRestorer(restorer: typeof restoreStore): void;
|
|
8
3
|
/**
|
|
9
4
|
* 创建 store,`key` 用来在 SSR 时同步服务端的值,`swc-plugin-gem` 的 `ssr` 选项会为模块顶层的 store 自动添加
|
|
10
5
|
*/
|
|
@@ -22,5 +17,4 @@ export declare function createStore<T = any>(originStore: T, key?: string): ((va
|
|
|
22
17
|
[Symbol.metadata]: never;
|
|
23
18
|
}, keyof T> & T;
|
|
24
19
|
export declare function connect(store: Store<any>, func: () => void): () => boolean | undefined;
|
|
25
|
-
export {};
|
|
26
20
|
//# sourceMappingURL=store.d.ts.map
|
package/lib/store.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/lib/store.ts"],"names":[],"mappings":"AACA,OAAO,EAA4C,KAAK,OAAO,EAAE,MAAM,SAAS,CAAC;AAEjF,MAAM,MAAM,KAAK,CAAC,CAAC,GAAG,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/lib/store.ts"],"names":[],"mappings":"AACA,OAAO,EAA4C,KAAK,OAAO,EAAE,MAAM,SAAS,CAAC;AAEjF,MAAM,MAAM,KAAK,CAAC,CAAC,GAAG,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;AAOxC;;GAEG;AACH,wBAAgB,WAAW,CAAC,CAAC,GAAG,GAAG,EAAE,WAAW,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,aAIzB,OAAO,CAAC,CAAC,CAAC;;;;;;;;;;;;gBAYjD;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,MAAM,IAAI,6BAK1D"}
|
package/lib/store.js
CHANGED
|
@@ -1,18 +1,8 @@
|
|
|
1
|
-
import { getRequestValue, isolate, isServer } from './server';
|
|
1
|
+
import { getRequestValue, isolate, isServer, ssrHooks } from './server';
|
|
2
2
|
import { addMicrotask, assignState, createUpdater } from './utils';
|
|
3
3
|
/**@internal */
|
|
4
4
|
export const _StoreListenerMap = new WeakMap();
|
|
5
5
|
const createListeners = () => new Set();
|
|
6
|
-
// SSR 时当前请求中更新过的有 key 的 store,渲染后输出到页面中
|
|
7
|
-
const updatedStores = new Map();
|
|
8
|
-
/** SSR 时当前请求中更新过的有 key 的 store,供 `@mantou/gem-ssr` 使用 */
|
|
9
|
-
export const _getUpdatedStores = () => getRequestValue(updatedStores, () => new Map());
|
|
10
|
-
// 客户端读取服务端渲染时 store 的值
|
|
11
|
-
let restoreStore;
|
|
12
|
-
/** 设置客户端恢复 store 的方法,供 `@mantou/gem-ssr` 使用 */
|
|
13
|
-
export function _setStoreRestorer(restorer) {
|
|
14
|
-
restoreStore = restorer;
|
|
15
|
-
}
|
|
16
6
|
/**
|
|
17
7
|
* 创建 store,`key` 用来在 SSR 时同步服务端的值,`swc-plugin-gem` 的 `ssr` 选项会为模块顶层的 store 自动添加
|
|
18
8
|
*/
|
|
@@ -26,13 +16,11 @@ export function createStore(originStore, key) {
|
|
|
26
16
|
return;
|
|
27
17
|
// SSR 时请求中添加的监听器只属于当前请求,其他请求更新 store 时不会触发
|
|
28
18
|
getRequestValue(listeners, createListeners).forEach(addMicrotask);
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
if (key && updated !== updatedStores)
|
|
32
|
-
updated.set(key, store);
|
|
19
|
+
if (key)
|
|
20
|
+
ssrHooks.updateStore?.(key, store);
|
|
33
21
|
}));
|
|
34
|
-
if (key
|
|
35
|
-
assignState(store,
|
|
22
|
+
if (key)
|
|
23
|
+
assignState(store, ssrHooks.createStore?.(key));
|
|
36
24
|
_StoreListenerMap.set(store, listeners);
|
|
37
25
|
return store;
|
|
38
26
|
}
|
package/lib/store.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.js","sourceRoot":"","sources":["../src/lib/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../src/lib/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACxE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAgB,MAAM,SAAS,CAAC;AAIjF,eAAe;AACf,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,OAAO,EAA+B,CAAC;AAE5E,MAAM,eAAe,GAAG,GAAG,EAAE,CAAC,IAAI,GAAG,EAAc,CAAC;AAEpD;;GAEG;AACH,MAAM,UAAU,WAAW,CAAU,WAAc,EAAE,GAAY;IAC/D,MAAM,SAAS,GAAG,eAAe,EAAE,CAAC;IACpC,kBAAkB;IAClB,MAAM,KAAK,GAAG,OAAO,CACnB,aAAa,CAAC,WAAW,EAAE,CAAC,KAAkB,EAAE,EAAE;QAChD,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAC1B,SAAS,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QAChC,IAAI,CAAC,QAAQ;YAAE,OAAO;QACtB,2CAA2C;QAC3C,eAAe,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QAClE,IAAI,GAAG;YAAE,QAAQ,CAAC,WAAW,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC9C,CAAC,CAAC,CACH,CAAC;IACF,IAAI,GAAG;QAAE,WAAW,CAAC,KAAK,EAAE,QAAQ,CAAC,WAAW,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACzD,iBAAiB,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IACxC,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,KAAiB,EAAE,IAAgB;IACzD,MAAM,cAAc,GAAG,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACpD,MAAM,SAAS,GAAG,cAAc,IAAI,eAAe,CAAC,cAAc,EAAE,eAAe,CAAC,CAAC;IACrF,SAAS,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;IACrB,OAAO,GAAG,EAAE,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;AACvC,CAAC"}
|
package/lib/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/lib/utils.ts"],"names":[],"mappings":"AAWA,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,IAAI,QAS5C;AAED,KAAK,UAAU,GAAG;IAChB,IAAI,EAAE,KAAK,CAAC;IACZ,KAAK,EAAE,KAAK,CAAC;IACb,IAAI,EAAE,KAAK,CAAC;IACZ,IAAI,EAAE,KAAK,CAAC;IACZ,QAAQ,EAAE,KAAK,CAAC;IAChB,SAAS,EAAE,KAAK,CAAC;IACjB,MAAM,EAAE,KAAK,CAAC;IACd,SAAS,EAAE,KAAK,CAAC;IACjB,MAAM,EAAE,KAAK,CAAC;IACd,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,KAAK,CAAC;IAC5B,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC;CAC1B,CAAC;AAGF,wBAAgB,WAAW,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,QAOnD;AAGD,wBAAgB,aAAa,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,SAAS,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,GASvE,EAAE,GAAG,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,CACnD;AAED,MAAM,MAAM,OAAO,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;AAGrG,wBAAgB,gBAAgB,CAAC,WAAW,SAAK,EAAE,YAAY,SAAK,UAGnE;AAED,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC;AAElC,wBAAgB,WAAW,CAAC,CAAC,SAAS,WAAW,EAAE,CAAC,SAAS,UAAU,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,EAC5F,MAAM,EAAE,CAAC,EACT,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EACV,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,EACd,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,cAIf;AAED,UAAU,kBAAkB;IAC1B,KAAK,EAAE,KAAK,CAAC;IACb,GAAG,EAAE,KAAK,CAAC;CACZ;AACD,MAAM,WAAW,cAAc,CAAC,CAAC;IAC/B,KAAK,EAAE,CAAC,CAAC;IACT,IAAI,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC;IACzB,IAAI,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC;CAC1B;AAED,qBAAa,UAAU,CAAC,CAAC,GAAG,GAAG,CAAE,SAAQ,WAAW;;IAC1C,gBAAgB,EAAE,CAAC,CAAC,SAAS,MAAM,kBAAkB,EAC3D,IAAI,EAAE,CAAC,EACP,QAAQ,EAAE,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,kBAAkB,CAAC,CAAC,CAAC,KAAK,GAAG,EACjE,OAAO,CAAC,EAAE,OAAO,GAAG,uBAAuB,KACxC,IAAI,CAAC;IAwBV,IAAI,IAAI,WAEP;IAED,IAAI,KAAK,kCAER;IAED,IAAI,IAAI,kCAEP;IAED,aAAa,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,QAAQ,UAAQ;
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/lib/utils.ts"],"names":[],"mappings":"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"}
|
package/lib/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const version = "2.
|
|
1
|
+
export declare const version = "2.3.1";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/lib/version.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/lib/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/lib/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,UAAU,CAAC"}
|
package/lib/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const version = '2.
|
|
1
|
+
export const version = '2.3.1';
|
|
2
2
|
//# sourceMappingURL=version.js.map
|
package/lib/version.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/lib/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,OAAO,GAAG,
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/lib/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mantou/gem",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "💎
|
|
3
|
+
"version": "2.3.1",
|
|
4
|
+
"description": "💎 Build reusable custom elements and web apps on Web Components",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"frontend",
|
|
7
7
|
"web components",
|
|
@@ -31,17 +31,16 @@
|
|
|
31
31
|
],
|
|
32
32
|
"typings": "index.d.ts",
|
|
33
33
|
"scripts": {
|
|
34
|
-
"docs": "
|
|
35
|
-
"docs
|
|
36
|
-
"build:
|
|
37
|
-
"build:module": "tsc -p tsconfig.build.json",
|
|
34
|
+
"docs": "gem-book docs",
|
|
35
|
+
"build:docs": "gem-book build docs",
|
|
36
|
+
"build:module": "tsrs -p tsconfig.build.json",
|
|
38
37
|
"build:lib": "rslib build",
|
|
39
38
|
"build": "pnpm build:module && pnpm build:lib",
|
|
40
39
|
"start": "pnpm build:module --watch",
|
|
41
40
|
"test": "cross-env wtr"
|
|
42
41
|
},
|
|
43
42
|
"devDependencies": {
|
|
44
|
-
"@gemjs/config": "^2.1.
|
|
43
|
+
"@gemjs/config": "^2.1.4",
|
|
45
44
|
"@rslib/core": "^0.23.0",
|
|
46
45
|
"@swc/helpers": "^0.5.23",
|
|
47
46
|
"@types/chai": "^5.0.0",
|
|
@@ -51,7 +50,7 @@
|
|
|
51
50
|
"@web/test-runner": "^0.18.1",
|
|
52
51
|
"chai": "^5.1.1",
|
|
53
52
|
"rimraf": "^3.0.2",
|
|
54
|
-
"
|
|
53
|
+
"tsrs": "^0.18.0-ts7.1.0-dev.20260929"
|
|
55
54
|
},
|
|
56
55
|
"author": "mantou132",
|
|
57
56
|
"license": "MIT",
|
|
@@ -1,9 +1,27 @@
|
|
|
1
1
|
import { aria, mounted, shadow } from '../../lib/decorators';
|
|
2
2
|
import { history } from '../../lib/history';
|
|
3
3
|
import { GemElement } from '../../lib/reactive';
|
|
4
|
+
import type { Store } from '../../lib/store';
|
|
4
5
|
import { connect, createStore } from '../../lib/store';
|
|
5
6
|
|
|
6
7
|
const open = Symbol('open mark');
|
|
8
|
+
// 静态方法返回不可伪造的值,防止子类覆盖
|
|
9
|
+
const final = Symbol();
|
|
10
|
+
|
|
11
|
+
type ModalElement = GemElement & { label: string };
|
|
12
|
+
|
|
13
|
+
export interface ModalClass<T> extends Omit<typeof GemElement, 'prototype'> {
|
|
14
|
+
new (): ModalElement;
|
|
15
|
+
prototype: ModalElement;
|
|
16
|
+
inertStore: HTMLElement[];
|
|
17
|
+
instance: GemElement | null;
|
|
18
|
+
store: Store<{ [open]: boolean } & T>;
|
|
19
|
+
readonly isOpen: boolean;
|
|
20
|
+
open(opts: T): typeof final;
|
|
21
|
+
close(): typeof final;
|
|
22
|
+
closeHandle(): typeof final;
|
|
23
|
+
shouldClose(): boolean;
|
|
24
|
+
}
|
|
7
25
|
|
|
8
26
|
/**
|
|
9
27
|
* 需要使用范型,所以导出一个函数,用来*创建*类似 Confirm 元素的基类;
|
|
@@ -13,9 +31,7 @@ const open = Symbol('open mark');
|
|
|
13
31
|
* 使用 `mounted`/`unmounted` 定义 `open`/`close` 回调;
|
|
14
32
|
* 模拟 top layer:https://github.com/whatwg/html/issues/4633.
|
|
15
33
|
*/
|
|
16
|
-
export function createModalClass<T extends Record<string, unknown>>(options: T) {
|
|
17
|
-
const final = Symbol();
|
|
18
|
-
|
|
34
|
+
export function createModalClass<T extends Record<string, unknown>>(options: T): ModalClass<T> {
|
|
19
35
|
@shadow()
|
|
20
36
|
@aria({ role: 'alertdialog', ariaModal: 'true' })
|
|
21
37
|
class ModalElement extends GemElement {
|
|
@@ -40,7 +56,7 @@ export function createModalClass<T extends Record<string, unknown>>(options: T)
|
|
|
40
56
|
* 自带 100ms 延迟,以允许在其他 Dialog 的 `shouldClose` 中调用此方法;
|
|
41
57
|
* 浏览器 history 为异步 API,需要设置较长延迟;
|
|
42
58
|
*/
|
|
43
|
-
static open(opts: T) {
|
|
59
|
+
static open(opts: T): typeof final {
|
|
44
60
|
const instance = new this();
|
|
45
61
|
this.instance = instance;
|
|
46
62
|
this.inertStore = ([...document.body.children] as HTMLElement[]).filter((e) => !e.inert);
|
|
@@ -63,7 +79,7 @@ export function createModalClass<T extends Record<string, unknown>>(options: T)
|
|
|
63
79
|
* @final
|
|
64
80
|
* UI 中执行关闭
|
|
65
81
|
*/
|
|
66
|
-
static close() {
|
|
82
|
+
static close(): typeof final {
|
|
67
83
|
history.back();
|
|
68
84
|
return final;
|
|
69
85
|
}
|
|
@@ -72,7 +88,7 @@ export function createModalClass<T extends Record<string, unknown>>(options: T)
|
|
|
72
88
|
* @final
|
|
73
89
|
* history 中自动调用
|
|
74
90
|
*/
|
|
75
|
-
static closeHandle() {
|
|
91
|
+
static closeHandle(): typeof final {
|
|
76
92
|
this.inertStore.forEach((e) => (e.inert = false));
|
|
77
93
|
this.instance?.remove();
|
|
78
94
|
this.store({ [open]: false, ...options });
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* 把子节点移动到 `target`(默认 `document.head`)中,用开始和结束注释标记这些节点,
|
|
3
|
+
* 修改 `target` 或者卸载时一起移动或移除
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
* 比如 duoyun-ui 文档站加载示例元素时把 GemReflectElement 渲染的元素清除
|
|
5
|
+
* 服务端渲染时不执行 effect,客户端水合后才移动,使用 `getLogicalParent` 从被移动的节点找到 reflect 元素
|
|
7
6
|
*/
|
|
8
7
|
|
|
9
8
|
import { attribute, effect, property, willMount } from '../../lib/decorators';
|
|
@@ -25,6 +24,31 @@ const getReflectFragment = (startNode: Comment) => {
|
|
|
25
24
|
return result;
|
|
26
25
|
};
|
|
27
26
|
|
|
27
|
+
// 移动到的目标元素和片段开始注释对应的 reflect 元素,向上查找元素时跨越 reflect
|
|
28
|
+
const targets = new WeakSet<Node>();
|
|
29
|
+
const startNodes = new WeakMap<Node, GemReflectElement>();
|
|
30
|
+
|
|
31
|
+
// 向前查找片段的开始注释,遇到其他片段的结束注释时不在片段中
|
|
32
|
+
const getReflectElement = (node: Node) => {
|
|
33
|
+
for (let n = node.previousSibling; n; n = n.previousSibling) {
|
|
34
|
+
const ele = startNodes.get(n);
|
|
35
|
+
if (ele) return ele;
|
|
36
|
+
if (n.nodeValue === END) return;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* 节点的逻辑父元素:被 reflect 移动的节点是 reflect 元素,ShadowRoot 中顶层的节点是宿主,其他是父元素
|
|
42
|
+
*/
|
|
43
|
+
export function getLogicalParent(node: Node): Element | null {
|
|
44
|
+
const parent = node.parentNode;
|
|
45
|
+
if (parent && targets.has(parent)) {
|
|
46
|
+
const ele = getReflectElement(node);
|
|
47
|
+
if (ele) return ele;
|
|
48
|
+
}
|
|
49
|
+
return parent instanceof ShadowRoot ? parent.host : node.parentElement;
|
|
50
|
+
}
|
|
51
|
+
|
|
28
52
|
export class GemReflectElement extends GemElement {
|
|
29
53
|
@attribute method: 'prepend' | 'append';
|
|
30
54
|
|
|
@@ -45,6 +69,8 @@ export class GemReflectElement extends GemElement {
|
|
|
45
69
|
|
|
46
70
|
@effect((i) => [i.target])
|
|
47
71
|
#changeTarget = () => {
|
|
72
|
+
targets.add(this.target);
|
|
73
|
+
startNodes.set(this.#startNode, this);
|
|
48
74
|
(this.#childNodes || [this.#startNode, ...this.childNodes, this.#endNode]).forEach((node, index, arr) => {
|
|
49
75
|
const prev = arr[index - 1];
|
|
50
76
|
if (prev) {
|
|
@@ -9,32 +9,54 @@ import { connect, createStore } from '../../lib/store';
|
|
|
9
9
|
import type { QueryString } from '../../lib/utils';
|
|
10
10
|
import { addListener } from '../../lib/utils';
|
|
11
11
|
|
|
12
|
+
type Params = Record<string, string>;
|
|
13
|
+
type Matcher = (path: string) => Params | null | undefined;
|
|
14
|
+
|
|
12
15
|
const UNNAMED_PARAM_PREFIX = '_';
|
|
13
16
|
|
|
14
|
-
//
|
|
15
|
-
// '/test/:a
|
|
16
|
-
// '/test
|
|
17
|
-
// '/test
|
|
18
|
-
// '/test
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
);
|
|
28
|
-
|
|
17
|
+
// 不支持 `URLPattern` 时转换成正则
|
|
18
|
+
// '/test/:a' /^\/test\/(?<a>[^/]+)$/
|
|
19
|
+
// '/test/:a/b' /^\/test\/(?<a>[^/]+)\/b$/
|
|
20
|
+
// '/test/*' /^\/test\/(?<_0>.*)$/
|
|
21
|
+
// '/test/:a/*' /^\/test\/(?<a>[^/]+)\/(?<_0>.*)$/
|
|
22
|
+
// '/test/*/:b' /^\/test\/(?<_0>.*)\/(?<b>[^/]+)$/
|
|
23
|
+
function createRegExpMatcher(pattern: string): Matcher {
|
|
24
|
+
let i = 0;
|
|
25
|
+
const source = pattern.replace(/:[^/$]+|\*/g, (name) =>
|
|
26
|
+
name === '*' ? `(?<${UNNAMED_PARAM_PREFIX}${i++}>.*)` : `(?<${name.slice(1)}>[^/]+)`,
|
|
27
|
+
);
|
|
28
|
+
const reg = new RegExp(`^${source}$`);
|
|
29
|
+
return (path) => {
|
|
30
|
+
const result = path.match(reg);
|
|
31
|
+
if (!result) return null;
|
|
32
|
+
const params: Params = {};
|
|
33
|
+
for (const key in result.groups) {
|
|
34
|
+
params[key.startsWith(UNNAMED_PARAM_PREFIX) ? key.slice(1) : key] = result.groups[key];
|
|
35
|
+
}
|
|
36
|
+
return params;
|
|
37
|
+
};
|
|
29
38
|
}
|
|
30
39
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
40
|
+
// pattern 开头不含参数和特殊字符的部分
|
|
41
|
+
const LITERAL_PREFIX = /^[\w\-./~]*/;
|
|
42
|
+
|
|
43
|
+
// `URLPattern` 的创建和 `exec` 都比较慢,不含参数时直接比较,否则先检查固定的开头
|
|
44
|
+
function createMatcher(pattern: string): Matcher {
|
|
45
|
+
const literal = LITERAL_PREFIX.exec(pattern)![0];
|
|
46
|
+
if (literal === pattern) return (path) => (path === pattern ? {} : null);
|
|
47
|
+
// 根 layout 的 pattern
|
|
48
|
+
if (pattern === '*') return (path) => ({ 0: path });
|
|
49
|
+
if (!globalThis.URLPattern) return createRegExpMatcher(pattern);
|
|
50
|
+
const urlPattern = new URLPattern({ pathname: pattern });
|
|
51
|
+
// 参数前的 `/` 可能是可选的,例如 `/a/:b?` 匹配 `/a`
|
|
52
|
+
const prefix = literal.replace(/\/$/, '');
|
|
53
|
+
return (path) =>
|
|
54
|
+
path.startsWith(prefix) ? (urlPattern.exec({ pathname: path })?.pathname.groups as Params | undefined) : null;
|
|
36
55
|
}
|
|
37
56
|
|
|
57
|
+
// pattern 来自路由定义,数量有限
|
|
58
|
+
const matchers = new Map<string, Matcher>();
|
|
59
|
+
|
|
38
60
|
/**
|
|
39
61
|
* - 大小写敏感
|
|
40
62
|
* - 匹配成功时返回 params
|
|
@@ -49,22 +71,9 @@ declare global {
|
|
|
49
71
|
* ```
|
|
50
72
|
*/
|
|
51
73
|
export function matchPath(pattern: string, path: string) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
if (!matchResult) return null;
|
|
56
|
-
return matchResult.pathname.groups as Params;
|
|
57
|
-
}
|
|
58
|
-
const reg = new ParamsRegExp(pattern);
|
|
59
|
-
const matchResult = path.match(reg) || `${path}/`.match(reg);
|
|
60
|
-
if (!matchResult) return null;
|
|
61
|
-
const params: Params = {};
|
|
62
|
-
if (matchResult.groups) {
|
|
63
|
-
Object.entries(matchResult.groups).forEach(([key, value]) => {
|
|
64
|
-
params[key.startsWith(UNNAMED_PARAM_PREFIX) ? key.slice(1) : key] = value;
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
return params;
|
|
74
|
+
let match = matchers.get(pattern);
|
|
75
|
+
if (!match) matchers.set(pattern, (match = createMatcher(pattern)));
|
|
76
|
+
return match(path) || match(`${path}/`) || null;
|
|
68
77
|
}
|
|
69
78
|
|
|
70
79
|
export interface RouteItem<T = unknown> {
|
|
@@ -79,7 +88,7 @@ export interface RouteItem<T = unknown> {
|
|
|
79
88
|
getContent?: (
|
|
80
89
|
params: Params,
|
|
81
90
|
renderRoot: DocumentFragment | GemLightRouteElement,
|
|
82
|
-
) => TemplateResult | Promise<TemplateResult
|
|
91
|
+
) => TemplateResult | undefined | Promise<TemplateResult | undefined>;
|
|
83
92
|
title?: string;
|
|
84
93
|
// 用来传递数据
|
|
85
94
|
data?: T;
|
|
@@ -130,6 +139,9 @@ export type RouteTrigger = {
|
|
|
130
139
|
|
|
131
140
|
const scrollPositionMap = new Map<string, number>();
|
|
132
141
|
|
|
142
|
+
// 导航到了新的历史记录,前进、后退和页面加载时为 `false`
|
|
143
|
+
let pushed = false;
|
|
144
|
+
|
|
133
145
|
@light({ penetrable: true })
|
|
134
146
|
export class GemLightRouteElement extends GemElement {
|
|
135
147
|
@boolattribute transition: boolean;
|
|
@@ -148,8 +160,13 @@ export class GemLightRouteElement extends GemElement {
|
|
|
148
160
|
@emitter routechange: Emitter<RouteItem | null>; // path 改变或者 key 改变,包含初始渲染
|
|
149
161
|
@emitter error: Emitter<any>;
|
|
150
162
|
|
|
151
|
-
|
|
152
|
-
|
|
163
|
+
/**
|
|
164
|
+
* 自动让滚动容器恢复滚动位置,导航到新的历史记录时滚动到顶部,
|
|
165
|
+
* 函数返回空值时不处理当前路由,例如只有子路由渲染后才需要滚动
|
|
166
|
+
*/
|
|
167
|
+
@property scrollContainer?: Element | (() => Element | null | undefined);
|
|
168
|
+
/**恢复滚动位置前等待,例如等待异步加载的内容撑开滚动容器 */
|
|
169
|
+
@property scrollWait?: () => Promise<unknown>;
|
|
153
170
|
/**默认当有 `hash` 时不进行滚动 */
|
|
154
171
|
@property scrollIgnoreHash?: boolean;
|
|
155
172
|
|
|
@@ -205,14 +222,24 @@ export class GemLightRouteElement extends GemElement {
|
|
|
205
222
|
});
|
|
206
223
|
};
|
|
207
224
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
225
|
+
// 已经处理过滚动的历史记录,同一条历史记录重新渲染时保持滚动位置
|
|
226
|
+
#scrolledKey?: string;
|
|
227
|
+
|
|
228
|
+
#updateScrollContainerPosition = async () => {
|
|
229
|
+
const container = this.#scrollContainer;
|
|
230
|
+
const key = history.currentKey;
|
|
231
|
+
if (!container || key === this.#scrolledKey) return;
|
|
232
|
+
this.#scrolledKey = key;
|
|
233
|
+
const scrollTop = scrollPositionMap.get(key);
|
|
234
|
+
if (!pushed && scrollTop !== undefined) {
|
|
235
|
+
await this.scrollWait?.();
|
|
236
|
+
// 等待时可能已经导航
|
|
237
|
+
if (key === history.currentKey) container.scroll(0, scrollTop);
|
|
238
|
+
return;
|
|
215
239
|
}
|
|
240
|
+
// 前进、后退或者页面加载时位置未知(例如刷新后),保持浏览器恢复的位置,浏览器只恢复文档的滚动位置
|
|
241
|
+
if (!pushed && container === document.scrollingElement) return;
|
|
242
|
+
if (this.scrollIgnoreHash || !history.getParams().hash) container.scroll(0, 0);
|
|
216
243
|
};
|
|
217
244
|
|
|
218
245
|
#lastLoader?: TemplateResult | Promise<TemplateResult | undefined>;
|
|
@@ -239,10 +266,13 @@ export class GemLightRouteElement extends GemElement {
|
|
|
239
266
|
|
|
240
267
|
@effect((i) => [i.scrollContainer])
|
|
241
268
|
#rememberScrollPosition = () => {
|
|
242
|
-
if (!this
|
|
243
|
-
return addListener(history, 'beforechange', () =>
|
|
244
|
-
|
|
245
|
-
|
|
269
|
+
if (!this.scrollContainer) return;
|
|
270
|
+
return addListener(history, 'beforechange', () => {
|
|
271
|
+
// 前进和后退时浏览器的历史记录已经改变,Gem 的还没有改变
|
|
272
|
+
pushed = globalThis.history.state?.$key === history.currentKey;
|
|
273
|
+
const container = this.#scrollContainer;
|
|
274
|
+
if (container) scrollPositionMap.set(history.currentKey, container.scrollTop);
|
|
275
|
+
});
|
|
246
276
|
};
|
|
247
277
|
|
|
248
278
|
// history or i18n
|