@dimina-kit/devtools 0.4.0-dev.20260702182435 → 0.4.0-dev.20260703051110
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/main/app/app.js +5 -25
- package/dist/main/app/native-overview.d.ts +27 -0
- package/dist/main/app/native-overview.js +44 -0
- package/dist/main/index.bundle.js +826 -690
- package/dist/main/ipc/bridge-router.js +180 -141
- package/dist/main/ipc/project-fs.js +39 -21
- package/dist/main/services/automation/handlers/app.js +143 -109
- package/dist/main/services/mcp/tools/simulator-tools.js +118 -97
- package/dist/main/services/network-forward/dispatch-batch.d.ts +22 -0
- package/dist/main/services/network-forward/dispatch-batch.js +21 -0
- package/dist/main/services/network-forward/index.js +5 -20
- package/dist/main/services/projects/create-project-service.js +54 -34
- package/dist/main/services/projects/types.d.ts +1 -32
- package/dist/main/services/service-console/console-api.js +36 -27
- package/dist/main/services/simulator-temp-files/disk.js +109 -86
- package/dist/main/services/workbench-coi-server.js +58 -45
- package/dist/main/utils/logger.d.ts +5 -12
- package/dist/main/utils/logger.js +5 -45
- package/dist/preload/instrumentation/wxml-extract.js +94 -62
- package/dist/preload/runtime/main-api-runner.d.ts +1 -1
- package/dist/preload/windows/main.cjs +284 -565
- package/dist/preload/windows/main.cjs.map +2 -2
- package/dist/preload/windows/simulator.cjs +37 -39
- package/dist/preload/windows/simulator.cjs.map +2 -2
- package/dist/preload/windows/simulator.js +37 -39
- package/dist/render-host/render-inspect.js +63 -52
- package/dist/renderer/assets/index-D-ksyN1p.js +49 -0
- package/dist/renderer/assets/workbenchSettings-COhuFF-i.js +8 -0
- package/dist/renderer/entries/main/index.html +1 -1
- package/dist/renderer/entries/workbench-settings/index.html +1 -1
- package/dist/shared/appdata-accumulator.js +53 -48
- package/dist/shared/open-in-editor-resource-path.d.ts +56 -0
- package/dist/shared/open-in-editor-resource-path.js +133 -0
- package/dist/shared/open-in-editor.d.ts +2 -9
- package/dist/shared/open-in-editor.js +8 -93
- package/dist/shared/types.d.ts +13 -0
- package/dist/simulator/assets/{device-shell-CUl0ILfn.js → device-shell-CiLAPa0I.js} +2 -2
- package/dist/simulator/assets/simulator-Dvnxry3y.js +10 -0
- package/dist/simulator/simulator.html +1 -1
- package/dist/vscode-workbench/assets/__vite-browser-external-CXi6Kz9W.js +1 -0
- package/dist/vscode-workbench/assets/{dist-CS7SQP3K.js → dist-TpGpmMGi.js} +3 -3
- package/dist/vscode-workbench/assets/{iconv-lite-umd-D3q-1-o6.js → iconv-lite-umd-C9tiCAJa.js} +1 -1
- package/dist/vscode-workbench/assets/{index-zjigpZ25.js → index-DJ1HyMZ7.js} +20 -22
- package/dist/vscode-workbench/assets/{jschardet-Cu4ufeHq.js → jschardet-DE1jV513.js} +1 -1
- package/dist/vscode-workbench/index.html +1 -1
- package/package.json +5 -5
- package/dist/renderer/assets/index-B-Dqb7G0.js +0 -49
- package/dist/renderer/assets/workbenchSettings-Bim9ol9R.js +0 -8
- package/dist/simulator/assets/simulator-Dz8iGcgy.js +0 -10
- package/dist/vscode-workbench/assets/__vite-browser-external-B0DTNerG.js +0 -1
|
@@ -13,6 +13,54 @@
|
|
|
13
13
|
* through bridge-router (SERVICE_PUBLISH). Both feed this one accumulator so the
|
|
14
14
|
* decode/merge/page-only/init-gate policy can't drift between modes.
|
|
15
15
|
*/
|
|
16
|
+
/** Parse a service/worker message payload; a non-string is passed through as-is. */
|
|
17
|
+
function parseMessagePayload(message) {
|
|
18
|
+
if (typeof message !== 'string')
|
|
19
|
+
return message;
|
|
20
|
+
try {
|
|
21
|
+
return JSON.parse(message);
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Decode a `ub` (update batch) body into patch entries, PAGE modules only —
|
|
29
|
+
* component-module updates are dropped (see `decodeWorkerMessage`).
|
|
30
|
+
*/
|
|
31
|
+
function decodeUpdateBatchBody(rawBody) {
|
|
32
|
+
const body = rawBody;
|
|
33
|
+
if (!body || typeof body !== 'object')
|
|
34
|
+
return null;
|
|
35
|
+
if (typeof body.bridgeId !== 'string' || !Array.isArray(body.updates))
|
|
36
|
+
return null;
|
|
37
|
+
const out = [];
|
|
38
|
+
for (const u of body.updates) {
|
|
39
|
+
if (!u || typeof u.moduleId !== 'string')
|
|
40
|
+
continue;
|
|
41
|
+
if (!u.moduleId.startsWith('page_'))
|
|
42
|
+
continue;
|
|
43
|
+
out.push({ mode: 'patch', bridgeId: body.bridgeId, moduleId: u.moduleId, data: u.data });
|
|
44
|
+
}
|
|
45
|
+
return out.length > 0 ? out : null;
|
|
46
|
+
}
|
|
47
|
+
/** Decode a `page_*` instance-init body into its single init entry. */
|
|
48
|
+
function decodePageInitBody(moduleId, rawBody) {
|
|
49
|
+
const body = rawBody;
|
|
50
|
+
if (!body || typeof body !== 'object')
|
|
51
|
+
return null;
|
|
52
|
+
if (typeof body.bridgeId !== 'string' || typeof body.path !== 'string')
|
|
53
|
+
return null;
|
|
54
|
+
if (!body.data || typeof body.data !== 'object')
|
|
55
|
+
return null;
|
|
56
|
+
return [{
|
|
57
|
+
mode: 'init',
|
|
58
|
+
bridgeId: body.bridgeId,
|
|
59
|
+
moduleId,
|
|
60
|
+
componentPath: body.path,
|
|
61
|
+
data: body.data,
|
|
62
|
+
}];
|
|
63
|
+
}
|
|
16
64
|
/**
|
|
17
65
|
* Decode a service→render message into AppData entries, or null when it is not
|
|
18
66
|
* AppData-relevant. Policy: surface PAGE entries only — component entries are
|
|
@@ -20,63 +68,20 @@
|
|
|
20
68
|
* and never receive pageUnload, which would manifest as ghost tabs).
|
|
21
69
|
*/
|
|
22
70
|
export function decodeWorkerMessage(message) {
|
|
23
|
-
|
|
24
|
-
if (typeof payload === 'string') {
|
|
25
|
-
try {
|
|
26
|
-
payload = JSON.parse(payload);
|
|
27
|
-
}
|
|
28
|
-
catch {
|
|
29
|
-
return null;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
71
|
+
const payload = parseMessagePayload(message);
|
|
32
72
|
if (!payload || typeof payload !== 'object')
|
|
33
73
|
return null;
|
|
34
74
|
const record = payload;
|
|
35
|
-
if (record.type === 'ub')
|
|
36
|
-
|
|
37
|
-
if (!body || typeof body !== 'object')
|
|
38
|
-
return null;
|
|
39
|
-
if (typeof body.bridgeId !== 'string' || !Array.isArray(body.updates))
|
|
40
|
-
return null;
|
|
41
|
-
const out = [];
|
|
42
|
-
for (const u of body.updates) {
|
|
43
|
-
if (!u || typeof u.moduleId !== 'string')
|
|
44
|
-
continue;
|
|
45
|
-
if (!u.moduleId.startsWith('page_'))
|
|
46
|
-
continue;
|
|
47
|
-
out.push({ mode: 'patch', bridgeId: body.bridgeId, moduleId: u.moduleId, data: u.data });
|
|
48
|
-
}
|
|
49
|
-
return out.length > 0 ? out : null;
|
|
50
|
-
}
|
|
75
|
+
if (record.type === 'ub')
|
|
76
|
+
return decodeUpdateBatchBody(record.body);
|
|
51
77
|
if (typeof record.type === 'string' && record.type.startsWith('page_')) {
|
|
52
|
-
|
|
53
|
-
if (!body || typeof body !== 'object')
|
|
54
|
-
return null;
|
|
55
|
-
if (typeof body.bridgeId !== 'string' || typeof body.path !== 'string')
|
|
56
|
-
return null;
|
|
57
|
-
if (!body.data || typeof body.data !== 'object')
|
|
58
|
-
return null;
|
|
59
|
-
return [{
|
|
60
|
-
mode: 'init',
|
|
61
|
-
bridgeId: body.bridgeId,
|
|
62
|
-
moduleId: record.type,
|
|
63
|
-
componentPath: body.path,
|
|
64
|
-
data: body.data,
|
|
65
|
-
}];
|
|
78
|
+
return decodePageInitBody(record.type, record.body);
|
|
66
79
|
}
|
|
67
80
|
return null;
|
|
68
81
|
}
|
|
69
82
|
/** main→worker direction: container signals page teardown so cache can evict. */
|
|
70
83
|
export function decodeOutgoingMessage(message) {
|
|
71
|
-
|
|
72
|
-
if (typeof payload === 'string') {
|
|
73
|
-
try {
|
|
74
|
-
payload = JSON.parse(payload);
|
|
75
|
-
}
|
|
76
|
-
catch {
|
|
77
|
-
return null;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
84
|
+
const payload = parseMessagePayload(message);
|
|
80
85
|
if (!payload || typeof payload !== 'object')
|
|
81
86
|
return null;
|
|
82
87
|
const r = payload;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure DevTools-resource-URL → project-relative-path resolution for the
|
|
3
|
+
* "open in editor" pipeline.
|
|
4
|
+
*
|
|
5
|
+
* Every function here is `.toString()`-injected verbatim into the DevTools
|
|
6
|
+
* front-end realm by `buildDevtoolsProjectSourceLinksScript` (in
|
|
7
|
+
* `open-in-editor.ts`), alongside being called directly from the main process.
|
|
8
|
+
* That constrains each function to be self-contained (no closures over
|
|
9
|
+
* module-level state beyond calling the OTHER functions in this file, which
|
|
10
|
+
* the injection site also stringifies into the same scope) — no electron / DOM
|
|
11
|
+
* / node deps.
|
|
12
|
+
*/
|
|
13
|
+
export interface ProjectSourceContext {
|
|
14
|
+
/** Absolute project root on disk. */
|
|
15
|
+
projectRoot: string;
|
|
16
|
+
/** Resource server base URL used by the compiled miniapp. */
|
|
17
|
+
resourceBaseUrl: string;
|
|
18
|
+
appId: string;
|
|
19
|
+
/** Compiler output package root (`main` for the primary package). */
|
|
20
|
+
outputRoot: string;
|
|
21
|
+
}
|
|
22
|
+
export declare function decodePathname(pathname: string): string;
|
|
23
|
+
export declare function normalizeSlashPath(value: string): string;
|
|
24
|
+
export declare function safeRelativePath(segments: string[]): string | null;
|
|
25
|
+
/**
|
|
26
|
+
* Taro/webpack build + runtime chunks are compiled output, not hand-written
|
|
27
|
+
* source. They also collide: dimina's own service runtime attributes its
|
|
28
|
+
* `log()` helper to a `common.js` on the SAME dev-server origin as the
|
|
29
|
+
* project's compiled `common.js` chunk, so the two are URL-indistinguishable
|
|
30
|
+
* and a dimina-core frame would otherwise open the project's chunk. Drop these
|
|
31
|
+
* well-known chunk basenames so a click falls through to the DevTools Sources
|
|
32
|
+
* panel instead of opening the wrong (or generated) file.
|
|
33
|
+
*/
|
|
34
|
+
export declare function excludeBuildChunk(rel: string | null): string | null;
|
|
35
|
+
/**
|
|
36
|
+
* Real host filesystem paths use well-known absolute roots; when they are
|
|
37
|
+
* outside the active project they are runtime/devtools frames, not sources.
|
|
38
|
+
*/
|
|
39
|
+
export declare function isOutsideKnownRoot(normalizedRaw: string): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Chromium may hand the open-resource hook a raw absolute filesystem path
|
|
42
|
+
* (already project-rooted). Returns `undefined` (not `null`) when the raw
|
|
43
|
+
* value is not under `projectRoot` at all, so the caller can distinguish "not
|
|
44
|
+
* this shape" from "matched, but excluded as a build chunk" (`null`).
|
|
45
|
+
*/
|
|
46
|
+
export declare function resolveFilesystemRawPath(normalizedRaw: string, projectRoot: string): string | null | undefined;
|
|
47
|
+
export declare function parseResourceUrl(raw: string, base: URL): URL | null;
|
|
48
|
+
export declare function resolveFileProtocolPath(resource: URL, projectRoot: string): string | null;
|
|
49
|
+
export declare function resolveHttpProtocolPath(resource: URL, base: URL, context: ProjectSourceContext): string | null;
|
|
50
|
+
/**
|
|
51
|
+
* Map a resource URL/path to a project-relative POSIX path, or null when it is
|
|
52
|
+
* not a mappable project source (framework frame, different origin, escapes
|
|
53
|
+
* the project root, or an excluded build chunk).
|
|
54
|
+
*/
|
|
55
|
+
export declare function projectAwareResourcePath(resourceUrl: string, context: ProjectSourceContext): string | null;
|
|
56
|
+
//# sourceMappingURL=open-in-editor-resource-path.d.ts.map
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure DevTools-resource-URL → project-relative-path resolution for the
|
|
3
|
+
* "open in editor" pipeline.
|
|
4
|
+
*
|
|
5
|
+
* Every function here is `.toString()`-injected verbatim into the DevTools
|
|
6
|
+
* front-end realm by `buildDevtoolsProjectSourceLinksScript` (in
|
|
7
|
+
* `open-in-editor.ts`), alongside being called directly from the main process.
|
|
8
|
+
* That constrains each function to be self-contained (no closures over
|
|
9
|
+
* module-level state beyond calling the OTHER functions in this file, which
|
|
10
|
+
* the injection site also stringifies into the same scope) — no electron / DOM
|
|
11
|
+
* / node deps.
|
|
12
|
+
*/
|
|
13
|
+
export function decodePathname(pathname) {
|
|
14
|
+
return pathname.split('/').map((segment) => {
|
|
15
|
+
try {
|
|
16
|
+
return decodeURIComponent(segment);
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return segment;
|
|
20
|
+
}
|
|
21
|
+
}).join('/');
|
|
22
|
+
}
|
|
23
|
+
export function normalizeSlashPath(value) {
|
|
24
|
+
return decodePathname(value.replace(/\\/g, '/')).replace(/\/+/g, '/');
|
|
25
|
+
}
|
|
26
|
+
export function safeRelativePath(segments) {
|
|
27
|
+
if (segments.length === 0 || segments.some((segment) => !segment || segment === '.' || segment === '..')) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
return segments.join('/');
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Taro/webpack build + runtime chunks are compiled output, not hand-written
|
|
34
|
+
* source. They also collide: dimina's own service runtime attributes its
|
|
35
|
+
* `log()` helper to a `common.js` on the SAME dev-server origin as the
|
|
36
|
+
* project's compiled `common.js` chunk, so the two are URL-indistinguishable
|
|
37
|
+
* and a dimina-core frame would otherwise open the project's chunk. Drop these
|
|
38
|
+
* well-known chunk basenames so a click falls through to the DevTools Sources
|
|
39
|
+
* panel instead of opening the wrong (or generated) file.
|
|
40
|
+
*/
|
|
41
|
+
export function excludeBuildChunk(rel) {
|
|
42
|
+
if (!rel)
|
|
43
|
+
return rel;
|
|
44
|
+
const baseName = rel.split('/').pop();
|
|
45
|
+
return baseName === 'common.js' || baseName === 'vendors.js' || baseName === 'runtime.js'
|
|
46
|
+
|| baseName === 'taro.js' || baseName === 'babelHelpers.js'
|
|
47
|
+
? null
|
|
48
|
+
: rel;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Real host filesystem paths use well-known absolute roots; when they are
|
|
52
|
+
* outside the active project they are runtime/devtools frames, not sources.
|
|
53
|
+
*/
|
|
54
|
+
export function isOutsideKnownRoot(normalizedRaw) {
|
|
55
|
+
return /^\/(?:Volumes|Users|home|private|tmp|var|opt|Applications)\//.test(normalizedRaw);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Chromium may hand the open-resource hook a raw absolute filesystem path
|
|
59
|
+
* (already project-rooted). Returns `undefined` (not `null`) when the raw
|
|
60
|
+
* value is not under `projectRoot` at all, so the caller can distinguish "not
|
|
61
|
+
* this shape" from "matched, but excluded as a build chunk" (`null`).
|
|
62
|
+
*/
|
|
63
|
+
export function resolveFilesystemRawPath(normalizedRaw, projectRoot) {
|
|
64
|
+
if (!projectRoot)
|
|
65
|
+
return undefined;
|
|
66
|
+
if (normalizedRaw !== projectRoot && !normalizedRaw.startsWith(`${projectRoot}/`))
|
|
67
|
+
return undefined;
|
|
68
|
+
const relative = normalizedRaw.slice(projectRoot.length).replace(/^\/+/, '');
|
|
69
|
+
return excludeBuildChunk(safeRelativePath(relative.split('/').filter(Boolean)));
|
|
70
|
+
}
|
|
71
|
+
export function parseResourceUrl(raw, base) {
|
|
72
|
+
try {
|
|
73
|
+
return raw.startsWith('/') && !raw.startsWith('//') ? new URL(raw, base.origin) : new URL(raw);
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
export function resolveFileProtocolPath(resource, projectRoot) {
|
|
80
|
+
const filePath = normalizeSlashPath(resource.pathname);
|
|
81
|
+
if (!projectRoot || (filePath !== projectRoot && !filePath.startsWith(`${projectRoot}/`)))
|
|
82
|
+
return null;
|
|
83
|
+
return excludeBuildChunk(safeRelativePath(filePath.slice(projectRoot.length).replace(/^\/+/, '').split('/').filter(Boolean)));
|
|
84
|
+
}
|
|
85
|
+
export function resolveHttpProtocolPath(resource, base, context) {
|
|
86
|
+
if (resource.protocol !== 'http:' && resource.protocol !== 'https:')
|
|
87
|
+
return null;
|
|
88
|
+
if (resource.origin !== base.origin)
|
|
89
|
+
return null;
|
|
90
|
+
let segments = decodePathname(resource.pathname).split('/').filter(Boolean);
|
|
91
|
+
if (context.appId && segments[0] === context.appId) {
|
|
92
|
+
segments = segments.slice(1);
|
|
93
|
+
if (context.outputRoot && segments[0] === context.outputRoot)
|
|
94
|
+
segments = segments.slice(1);
|
|
95
|
+
}
|
|
96
|
+
return excludeBuildChunk(safeRelativePath(segments));
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Map a resource URL/path to a project-relative POSIX path, or null when it is
|
|
100
|
+
* not a mappable project source (framework frame, different origin, escapes
|
|
101
|
+
* the project root, or an excluded build chunk).
|
|
102
|
+
*/
|
|
103
|
+
export function projectAwareResourcePath(resourceUrl, context) {
|
|
104
|
+
let base;
|
|
105
|
+
try {
|
|
106
|
+
base = new URL(context.resourceBaseUrl);
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
const projectRoot = normalizeSlashPath(context.projectRoot).replace(/\/$/, '');
|
|
112
|
+
const raw = resourceUrl.trim();
|
|
113
|
+
if (!raw)
|
|
114
|
+
return null;
|
|
115
|
+
const normalizedRaw = normalizeSlashPath(raw);
|
|
116
|
+
const filesystemRelative = resolveFilesystemRawPath(normalizedRaw, projectRoot);
|
|
117
|
+
if (filesystemRelative !== undefined)
|
|
118
|
+
return filesystemRelative;
|
|
119
|
+
if (isOutsideKnownRoot(normalizedRaw))
|
|
120
|
+
return null;
|
|
121
|
+
// Reject relative runtime labels such as `service.js` or
|
|
122
|
+
// `electron/js2c/renderer_init`; project source locations must be an
|
|
123
|
+
// absolute URL/path so they can be scoped to the active project.
|
|
124
|
+
if (!raw.startsWith('/') && !/^[a-z][a-z0-9+.-]*:/i.test(raw))
|
|
125
|
+
return null;
|
|
126
|
+
const resource = parseResourceUrl(raw, base);
|
|
127
|
+
if (!resource)
|
|
128
|
+
return null;
|
|
129
|
+
if (resource.protocol === 'file:')
|
|
130
|
+
return resolveFileProtocolPath(resource, projectRoot);
|
|
131
|
+
return resolveHttpProtocolPath(resource, base, context);
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=open-in-editor-resource-path.js.map
|
|
@@ -16,6 +16,8 @@
|
|
|
16
16
|
* node deps so it is unit-testable and shared by main + the injected front-end
|
|
17
17
|
* snippet's expectations.
|
|
18
18
|
*/
|
|
19
|
+
import { type ProjectSourceContext } from './open-in-editor-resource-path.js';
|
|
20
|
+
export type { ProjectSourceContext } from './open-in-editor-resource-path.js';
|
|
19
21
|
/**
|
|
20
22
|
* Sentinel scheme for the encoded "open in editor" request. A bare custom scheme
|
|
21
23
|
* (no `//authority`) keeps the encoded payload entirely in the URL's path/query,
|
|
@@ -32,15 +34,6 @@ export interface OpenInEditorRequest {
|
|
|
32
34
|
/** 0-based column as reported by DevTools (may be undefined). */
|
|
33
35
|
column?: number;
|
|
34
36
|
}
|
|
35
|
-
export interface ProjectSourceContext {
|
|
36
|
-
/** Absolute project root on disk. */
|
|
37
|
-
projectRoot: string;
|
|
38
|
-
/** Resource server base URL used by the compiled miniapp. */
|
|
39
|
-
resourceBaseUrl: string;
|
|
40
|
-
appId: string;
|
|
41
|
-
/** Compiler output package root (`main` for the primary package). */
|
|
42
|
-
outputRoot: string;
|
|
43
|
-
}
|
|
44
37
|
/**
|
|
45
38
|
* Encode an open-in-editor request as a sentinel URL the DevTools front-end can
|
|
46
39
|
* hand to `InspectorFrontendHost.openInNewTab(...)`. All fields ride in the
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
* node deps so it is unit-testable and shared by main + the injected front-end
|
|
17
17
|
* snippet's expectations.
|
|
18
18
|
*/
|
|
19
|
+
import { decodePathname, excludeBuildChunk, isOutsideKnownRoot, normalizeSlashPath, parseResourceUrl, projectAwareResourcePath, resolveFileProtocolPath, resolveFilesystemRawPath, resolveHttpProtocolPath, safeRelativePath, } from './open-in-editor-resource-path.js';
|
|
19
20
|
/**
|
|
20
21
|
* Sentinel scheme for the encoded "open in editor" request. A bare custom scheme
|
|
21
22
|
* (no `//authority`) keeps the encoded payload entirely in the URL's path/query,
|
|
@@ -138,98 +139,6 @@ export function resourceUrlToProjectRelativePath(resourceUrl, expectedOriginOrCo
|
|
|
138
139
|
return null;
|
|
139
140
|
return segments.slice(1).join('/');
|
|
140
141
|
}
|
|
141
|
-
function decodePathname(pathname) {
|
|
142
|
-
return pathname.split('/').map((segment) => {
|
|
143
|
-
try {
|
|
144
|
-
return decodeURIComponent(segment);
|
|
145
|
-
}
|
|
146
|
-
catch {
|
|
147
|
-
return segment;
|
|
148
|
-
}
|
|
149
|
-
}).join('/');
|
|
150
|
-
}
|
|
151
|
-
function normalizeSlashPath(value) {
|
|
152
|
-
return decodePathname(value.replace(/\\/g, '/')).replace(/\/+/g, '/');
|
|
153
|
-
}
|
|
154
|
-
function safeRelativePath(segments) {
|
|
155
|
-
if (segments.length === 0 || segments.some((segment) => !segment || segment === '.' || segment === '..')) {
|
|
156
|
-
return null;
|
|
157
|
-
}
|
|
158
|
-
return segments.join('/');
|
|
159
|
-
}
|
|
160
|
-
function projectAwareResourcePath(resourceUrl, context) {
|
|
161
|
-
let base;
|
|
162
|
-
try {
|
|
163
|
-
base = new URL(context.resourceBaseUrl);
|
|
164
|
-
}
|
|
165
|
-
catch {
|
|
166
|
-
return null;
|
|
167
|
-
}
|
|
168
|
-
const projectRoot = normalizeSlashPath(context.projectRoot).replace(/\/$/, '');
|
|
169
|
-
const raw = resourceUrl.trim();
|
|
170
|
-
if (!raw)
|
|
171
|
-
return null;
|
|
172
|
-
// Taro/webpack build + runtime chunks are compiled output, not hand-written
|
|
173
|
-
// source. They also collide: dimina's own service runtime attributes its
|
|
174
|
-
// `log()` helper to a `common.js` on the SAME dev-server origin as the
|
|
175
|
-
// project's compiled `common.js` chunk, so the two are URL-indistinguishable
|
|
176
|
-
// and a dimina-core frame would otherwise open the project's chunk. Drop these
|
|
177
|
-
// well-known chunk basenames so a click falls through to the DevTools Sources
|
|
178
|
-
// panel instead of opening the wrong (or generated) file. Inlined (not a module
|
|
179
|
-
// const) because this function is `.toString()`-injected into the DevTools realm.
|
|
180
|
-
const excludeBuildChunk = (rel) => {
|
|
181
|
-
if (!rel)
|
|
182
|
-
return rel;
|
|
183
|
-
const base = rel.split('/').pop();
|
|
184
|
-
return base === 'common.js' || base === 'vendors.js' || base === 'runtime.js'
|
|
185
|
-
|| base === 'taro.js' || base === 'babelHelpers.js'
|
|
186
|
-
? null
|
|
187
|
-
: rel;
|
|
188
|
-
};
|
|
189
|
-
// Chromium may hand the open-resource hook a raw absolute filesystem path.
|
|
190
|
-
const normalizedRaw = normalizeSlashPath(raw);
|
|
191
|
-
if (projectRoot && (normalizedRaw === projectRoot || normalizedRaw.startsWith(`${projectRoot}/`))) {
|
|
192
|
-
const relative = normalizedRaw.slice(projectRoot.length).replace(/^\/+/, '');
|
|
193
|
-
return excludeBuildChunk(safeRelativePath(relative.split('/').filter(Boolean)));
|
|
194
|
-
}
|
|
195
|
-
// Sourcemap sources commonly use virtual root paths such as `/pages/x.js`.
|
|
196
|
-
// Real host filesystem paths use well-known absolute roots; when they are
|
|
197
|
-
// outside the active project they are runtime/devtools frames, not sources.
|
|
198
|
-
if (/^\/(?:Volumes|Users|home|private|tmp|var|opt|Applications)\//.test(normalizedRaw)) {
|
|
199
|
-
return null;
|
|
200
|
-
}
|
|
201
|
-
// Reject relative runtime labels such as `service.js` or
|
|
202
|
-
// `electron/js2c/renderer_init`; project source locations must be an
|
|
203
|
-
// absolute URL/path so they can be scoped to the active project.
|
|
204
|
-
if (!raw.startsWith('/') && !/^[a-z][a-z0-9+.-]*:/i.test(raw))
|
|
205
|
-
return null;
|
|
206
|
-
let resource;
|
|
207
|
-
try {
|
|
208
|
-
resource = raw.startsWith('/') && !raw.startsWith('//')
|
|
209
|
-
? new URL(raw, base.origin)
|
|
210
|
-
: new URL(raw);
|
|
211
|
-
}
|
|
212
|
-
catch {
|
|
213
|
-
return null;
|
|
214
|
-
}
|
|
215
|
-
if (resource.protocol === 'file:') {
|
|
216
|
-
const filePath = normalizeSlashPath(resource.pathname);
|
|
217
|
-
if (!projectRoot || (filePath !== projectRoot && !filePath.startsWith(`${projectRoot}/`)))
|
|
218
|
-
return null;
|
|
219
|
-
return excludeBuildChunk(safeRelativePath(filePath.slice(projectRoot.length).replace(/^\/+/, '').split('/').filter(Boolean)));
|
|
220
|
-
}
|
|
221
|
-
if (resource.protocol !== 'http:' && resource.protocol !== 'https:')
|
|
222
|
-
return null;
|
|
223
|
-
if (resource.origin !== base.origin)
|
|
224
|
-
return null;
|
|
225
|
-
let segments = decodePathname(resource.pathname).split('/').filter(Boolean);
|
|
226
|
-
if (context.appId && segments[0] === context.appId) {
|
|
227
|
-
segments = segments.slice(1);
|
|
228
|
-
if (context.outputRoot && segments[0] === context.outputRoot)
|
|
229
|
-
segments = segments.slice(1);
|
|
230
|
-
}
|
|
231
|
-
return excludeBuildChunk(safeRelativePath(segments));
|
|
232
|
-
}
|
|
233
142
|
/** Read the project/source routing metadata carried by a service-host spawn URL. */
|
|
234
143
|
export function projectSourceContextFromServiceHostUrl(serviceHostUrl, activeProjectRoot) {
|
|
235
144
|
let url;
|
|
@@ -286,10 +195,16 @@ export function buildDevtoolsProjectSourceLinksScript(context) {
|
|
|
286
195
|
}
|
|
287
196
|
|
|
288
197
|
const cfg = ${config}
|
|
289
|
-
const diminaProjectSourcePath = ${projectAwareResourcePath.toString()}
|
|
290
198
|
const decodePathname = ${decodePathname.toString()}
|
|
291
199
|
const normalizeSlashPath = ${normalizeSlashPath.toString()}
|
|
292
200
|
const safeRelativePath = ${safeRelativePath.toString()}
|
|
201
|
+
const excludeBuildChunk = ${excludeBuildChunk.toString()}
|
|
202
|
+
const isOutsideKnownRoot = ${isOutsideKnownRoot.toString()}
|
|
203
|
+
const resolveFilesystemRawPath = ${resolveFilesystemRawPath.toString()}
|
|
204
|
+
const parseResourceUrl = ${parseResourceUrl.toString()}
|
|
205
|
+
const resolveFileProtocolPath = ${resolveFileProtocolPath.toString()}
|
|
206
|
+
const resolveHttpProtocolPath = ${resolveHttpProtocolPath.toString()}
|
|
207
|
+
const diminaProjectSourcePath = ${projectAwareResourcePath.toString()}
|
|
293
208
|
const observedRoots = new Set()
|
|
294
209
|
const observers = []
|
|
295
210
|
const clickBindings = []
|
package/dist/shared/types.d.ts
CHANGED
|
@@ -199,19 +199,32 @@ export interface ProjectsProvider {
|
|
|
199
199
|
getCompileConfig?(dirPath: string): unknown;
|
|
200
200
|
saveCompileConfig?(dirPath: string, cfg: unknown): void | Promise<void>;
|
|
201
201
|
}
|
|
202
|
+
/**
|
|
203
|
+
* A template the user can pick from in the "新建项目" dialog. Exactly one of
|
|
204
|
+
* `source` or `generate` should be supplied; if both are omitted, the
|
|
205
|
+
* service refuses to materialise the template.
|
|
206
|
+
*/
|
|
202
207
|
export interface ProjectTemplate {
|
|
208
|
+
/** Stable identifier. Used by host whitelists and the `templateId` field of CreateProjectInput. */
|
|
203
209
|
id: string;
|
|
210
|
+
/** Human-readable label shown in the dialog. */
|
|
204
211
|
name: string;
|
|
205
212
|
description?: string;
|
|
206
213
|
icon?: string;
|
|
214
|
+
/** Copy-tree source. `path` must be absolute. */
|
|
207
215
|
source?: {
|
|
208
216
|
type: 'directory';
|
|
209
217
|
path: string;
|
|
210
218
|
};
|
|
219
|
+
/** Programmatic generator. `target` is the absolute destination directory. */
|
|
211
220
|
generate?: (target: string, opts: {
|
|
212
221
|
name: string;
|
|
213
222
|
}) => Promise<void>;
|
|
214
223
|
}
|
|
224
|
+
/**
|
|
225
|
+
* Payload returned from the create-project dialog. The service uses this to
|
|
226
|
+
* scaffold disk content and to register the project with the provider.
|
|
227
|
+
*/
|
|
215
228
|
export interface CreateProjectInput {
|
|
216
229
|
name: string;
|
|
217
230
|
path: string;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{n as e,r as t,t as n}from"./jsx-runtime-CDK-o-S0.js";import{t as r}from"./bridge-channels-zhsumfky.js";var i=t(),a=new Set([`audioListen`]);function o(e){return a.has(e)}function s(e,t,n,r){let i=e.apiRegistry[t];if(!i)return r({ok:!1,errMsg:`${t}:fail no handler`}),Promise.resolve();let a=o(t)||(n&&typeof n==`object`&&!Array.isArray(n)?n.keep===!0:!1);return new Promise(o=>{let s=!1,c=e=>{if(s){a&&e.ok&&r({...e,keep:!0});return}s=!0,r(a&&e.ok?{...e,keep:!0}:e),o()},l=Symbol(`sim-cb-success`),u=Symbol(`sim-cb-fail`),d=Symbol(`sim-cb-complete`),f=!1,p=Object.create(e);p.createCallbackFunction=e=>{if(e!=null)return(e===l||e===u)&&(f=!0),(...n)=>{let r=n[0];e===l?c({ok:!0,result:r}):e===u?c({ok:!1,errMsg:r&&typeof r==`object`&&`errMsg`in r?String(r.errMsg):`${t}:fail`,result:r}):e===d&&!a&&c({ok:!0,result:r})}};let m=n&&typeof n==`object`&&!Array.isArray(n)?{...n}:{};m.success=l,m.fail=u,m.complete=d;try{let e=i.call(p,m);if(e&&typeof e.then==`function`){Promise.resolve(e).then(e=>c({ok:!0,result:e}),e=>{c({ok:!1,errMsg:`${t}:fail ${e instanceof Error?e.message:String(e)}`})});return}if(s)return;if(a){o();return}if(f){o();return}c({ok:!0,result:e})}catch(e){c({ok:!1,errMsg:`${t}:fail ${e instanceof Error?e.message:String(e)}`})}})}var c=n();function l({platform:e,statusBarHeight:t,textStyle:n}){let r=e===`ios`?87:95,i=t+(e===`ios`?4:6),a=e===`ios`?7:10;return(0,c.jsxs)(`div`,{className:`menu-capsule menu-capsule--${n}`,style:{width:r,height:32,top:i,right:a},"aria-hidden":`true`,children:[(0,c.jsxs)(`div`,{className:`menu-capsule__more`,children:[(0,c.jsx)(`span`,{}),(0,c.jsx)(`span`,{}),(0,c.jsx)(`span`,{})]}),(0,c.jsx)(`div`,{className:`menu-capsule__divider`}),(0,c.jsx)(`div`,{className:`menu-capsule__close`,children:(0,c.jsx)(`svg`,{viewBox:`0 0 16 16`,width:`12`,height:`12`,"aria-hidden":`true`,children:(0,c.jsx)(`path`,{d:`M4 4l8 8M12 4l-8 8`,stroke:`currentColor`,strokeWidth:`1.5`,fill:`none`,strokeLinecap:`round`})})})]})}var u={linear:`linear`,easeIn:`ease-in`,easeOut:`ease-out`,easeInOut:`ease-in-out`};function d({state:e,stackDepth:t,platform:n,statusBarHeight:r,navBarHeight:a,onBack:o,onHome:s}){let d=(0,i.useMemo)(()=>{if(!e.colorAnimation||e.colorAnimation.durationMs<=0)return;let t=u[e.colorAnimation.timingFunc]??`linear`;return`background-color ${e.colorAnimation.durationMs}ms ${t}, color ${e.colorAnimation.durationMs}ms ${t}`},[e.colorAnimation]),f=e.style===`custom`,p=t>1,m=!p&&e.homeButtonVisible,h=n===`ios`?`center`:`left`,g={backgroundColor:e.backgroundColor,color:e.textStyle===`white`?`#ffffff`:`#000000`,height:r+a,paddingTop:r,transition:d};return(0,c.jsxs)(`header`,{className:`nav-bar nav-bar--${n} nav-bar--${e.textStyle}${f?` nav-bar--custom`:``}`,style:g,"aria-hidden":f,children:[!f&&(0,c.jsxs)(`div`,{className:`nav-bar__row`,style:{height:a,justifyContent:h===`center`?`center`:`flex-start`},children:[(p||m)&&(0,c.jsxs)(`div`,{className:`nav-bar__leading`,children:[p&&(0,c.jsx)(`button`,{type:`button`,className:`nav-bar__back`,"aria-label":`Back`,onClick:o,children:(0,c.jsx)(`svg`,{viewBox:`0 0 24 24`,width:`24`,height:`24`,"aria-hidden":`true`,children:(0,c.jsx)(`path`,{d:`M15 18l-6-6 6-6`,stroke:`currentColor`,strokeWidth:`2`,fill:`none`,strokeLinecap:`round`,strokeLinejoin:`round`})})}),m&&(0,c.jsx)(`button`,{type:`button`,className:`nav-bar__home`,"aria-label":`Home`,onClick:s,children:(0,c.jsx)(`svg`,{viewBox:`0 0 24 24`,width:`22`,height:`22`,"aria-hidden":`true`,children:(0,c.jsx)(`path`,{d:`M3 12l9-9 9 9M5 10v10h14V10`,stroke:`currentColor`,strokeWidth:`2`,fill:`none`,strokeLinecap:`round`,strokeLinejoin:`round`})})})]}),(0,c.jsxs)(`div`,{className:`nav-bar__title nav-bar__title--${h}`,style:{color:e.textStyle===`white`?`#ffffff`:`#000000`},children:[e.loading&&(0,c.jsx)(`span`,{className:`nav-bar__spinner`,"aria-hidden":`true`}),(0,c.jsx)(`span`,{className:`nav-bar__title-text`,children:e.title})]})]}),(0,c.jsx)(l,{platform:n,statusBarHeight:r,textStyle:e.textStyle})]})}function f(e){return{title:e?.title??``,backgroundColor:e?.backgroundColor??`#000000`,textStyle:e?.textStyle??`white`,style:e?.style??`default`,loading:e?.loading??!1,homeButtonVisible:e?.homeButtonVisible??!1,colorAnimation:e?.colorAnimation}}function p(e){switch(e){case`notch`:return{width:164,height:30,top:0,bottomOnly:!0};case`dynamic-island`:return{width:124,height:36,top:11,bottomOnly:!1};default:return null}}function m({height:e,notchType:t,textStyle:n}){let r=p(t);return(0,c.jsxs)(`div`,{className:`device-statusbar`,style:{height:e,color:n===`black`?`#000000`:`#ffffff`},"aria-hidden":`true`,children:[(0,c.jsx)(`span`,{className:`device-statusbar__time`,children:`9:41`}),r&&(0,c.jsx)(`div`,{className:`device-statusbar__notch`,style:{width:r.width,height:r.height,top:r.top,borderRadius:r.bottomOnly?`0 0 ${Math.round(r.height*.6)}px ${Math.round(r.height*.6)}px`:`${r.height/2}px`}}),(0,c.jsxs)(`div`,{className:`device-statusbar__icons`,children:[(0,c.jsx)(`span`,{className:`device-statusbar__signal`}),(0,c.jsx)(`span`,{className:`device-statusbar__wifi`}),(0,c.jsx)(`span`,{className:`device-statusbar__battery`})]})]})}function h({state:e,currentPath:t,resourceBaseUrl:n,appId:r,onSwitch:i,bottomInset:a=0}){if(!e.config||!e.visible)return null;let{color:o,selectedColor:s,backgroundColor:l,borderStyle:u,list:d}=e.config,f=o||`#999999`,p=s||`#1890ff`;return(0,c.jsx)(`div`,{className:`dmb-tab-bar`,style:{backgroundColor:l||`#ffffff`,borderTopColor:u===`white`?`#ffffff`:`#e0e0e0`,paddingBottom:a},role:`tablist`,"aria-label":`TabBar`,children:d.map((a,o)=>{let s=g(a.pagePath),l=s===t,u=_(l?a.selectedIconPath??a.iconPath:a.iconPath,n,r),d=e.badges[o]??``,m=e.redDots[o]??!1;return(0,c.jsxs)(`button`,{type:`button`,className:`dmb-tab-bar__item${l?` is-selected`:``}`,role:`tab`,"aria-selected":l,onClick:()=>i(s),children:[u&&(0,c.jsx)(`span`,{className:`dmb-tab-bar__icon-slot`,children:(0,c.jsx)(`img`,{className:`dmb-tab-bar__icon`,src:u,alt:``,onError:e=>{e.currentTarget.style.display=`none`}})}),(0,c.jsx)(`span`,{className:`dmb-tab-bar__text`,style:{color:l?p:f},children:a.text||``}),d&&(0,c.jsx)(`span`,{className:`dmb-tab-bar__badge`,children:d}),!d&&m&&(0,c.jsx)(`span`,{className:`dmb-tab-bar__red-dot`})]},`${s}-${o}`)})})}function g(e){return e?e.replace(/^\/+/,``):``}function _(e,t,n){if(!e)return null;let r=e.trim();if(!r)return null;if(/^(?:data:|blob:|https?:|\/\/)/i.test(r))return r;if(!t)return null;let i=r.replace(/^\/+/,``).replace(/^\.\//,``);return i.startsWith(`${n}/`)?v(t,i):v(t,`${n}/main/${i}`)}function v(e,t){return`${e.endsWith(`/`)?e:`${e}/`}${t.replace(/^\/+/,``)}`}function y(){let[{toast:t,dialog:n},r]=(0,i.useState)(()=>e.getState());return(0,i.useEffect)(()=>e.subscribe(r),[]),(0,c.jsxs)(c.Fragment,{children:[t&&(0,c.jsx)(b,{toast:t}),n?.kind===`modal`&&(0,c.jsx)(S,{dialog:n}),n?.kind===`actionSheet`&&(0,c.jsx)(C,{dialog:n})]})}function b({toast:t}){(0,i.useEffect)(()=>{if(!Number.isFinite(t.duration))return;let n=window.setTimeout(()=>e.dismissToast(t),t.duration);return()=>window.clearTimeout(n)},[t]);let n=t.icon!==`none`||!!t.image;return(0,c.jsxs)(`div`,{className:`dmui-overlay`,"aria-live":`polite`,children:[t.mask&&(0,c.jsx)(`div`,{className:`dmui-mask dmui-mask--transparent`}),(0,c.jsxs)(`div`,{className:`dmui-toast${n?``:` dmui-toast--text`}`,role:`alert`,children:[t.image?(0,c.jsx)(`img`,{className:`dmui-toast__image`,src:t.image,alt:``}):(0,c.jsx)(x,{icon:t.icon}),t.title&&(0,c.jsx)(`div`,{className:`dmui-toast__title`,children:t.title})]})]})}function x({icon:e}){return e===`success`?(0,c.jsx)(`svg`,{className:`dmui-toast__icon`,viewBox:`0 0 24 24`,"aria-hidden":`true`,children:(0,c.jsx)(`path`,{d:`M5 13l4 4L19 7`})}):e===`error`?(0,c.jsx)(`svg`,{className:`dmui-toast__icon`,viewBox:`0 0 24 24`,"aria-hidden":`true`,children:(0,c.jsx)(`path`,{d:`M6 6l12 12M18 6L6 18`})}):e===`loading`?(0,c.jsx)(`span`,{className:`dmui-toast__spinner`,"aria-hidden":`true`}):null}function S({dialog:e}){let[t,n]=(0,i.useState)(``),r=(0,i.useRef)(null);return(0,i.useEffect)(()=>{e.editable&&r.current?.focus()},[e.editable]),(0,c.jsxs)(`div`,{className:`dmui-overlay`,children:[(0,c.jsx)(`div`,{className:`dmui-mask`}),(0,c.jsxs)(`div`,{className:`dmui-modal`,role:`dialog`,"aria-modal":`true`,children:[e.title&&(0,c.jsx)(`div`,{className:`dmui-modal__title`,children:e.title}),e.editable?(0,c.jsx)(`input`,{ref:r,className:`dmui-modal__input`,value:t,placeholder:e.placeholderText,onChange:e=>n(e.target.value)}):e.content&&(0,c.jsx)(`div`,{className:`dmui-modal__content`,children:e.content}),(0,c.jsxs)(`div`,{className:`dmui-modal__actions`,children:[e.showCancel&&(0,c.jsx)(`button`,{type:`button`,className:`dmui-modal__button`,style:{color:e.cancelColor},onClick:()=>e.onResult(!1),children:e.cancelText}),(0,c.jsx)(`button`,{type:`button`,className:`dmui-modal__button`,style:{color:e.confirmColor},onClick:()=>e.onResult(!0,t),children:e.confirmText})]})]})]})}function C({dialog:e}){return(0,c.jsxs)(`div`,{className:`dmui-overlay`,children:[(0,c.jsx)(`div`,{className:`dmui-mask`,onClick:()=>e.onSelect(-1)}),(0,c.jsxs)(`div`,{className:`dmui-action-sheet`,role:`menu`,children:[(0,c.jsx)(`div`,{className:`dmui-action-sheet__items`,children:e.itemList.map((t,n)=>(0,c.jsx)(`button`,{type:`button`,className:`dmui-action-sheet__item`,style:{color:e.itemColor},onClick:()=>e.onSelect(n),children:t},n))}),(0,c.jsx)(`button`,{type:`button`,className:`dmui-action-sheet__cancel`,onClick:()=>e.onSelect(-1),children:`取消`})]})]})}function w(e){if(!e)return{config:null,visible:!1,badges:[],redDots:[]};let t=e.list.length;return{config:T(e),visible:!0,badges:Array.from({length:t},()=>``),redDots:Array.from({length:t},()=>!1)}}function T(e){return{...e,list:e.list.map(e=>({...e}))}}function E(e,t){switch(t.kind){case`reset`:return{state:w(t.config),ok:!0,errMsg:`reset:ok`};case`visibility`:return{state:{...e,visible:t.visible},ok:!0,errMsg:t.visible?`showTabBar:ok`:`hideTabBar:ok`};case`apply`:return D(e,t.name,t.params)}}function D(e,t,n){if(!e.config)return{state:e,ok:!1,errMsg:`${t}:fail tabBar not configured`};switch(t){case`setTabBarStyle`:return O(e,n);case`setTabBarItem`:return k(e,n);case`showTabBar`:return{state:{...e,visible:!0},ok:!0,errMsg:`showTabBar:ok`};case`hideTabBar`:return{state:{...e,visible:!1},ok:!0,errMsg:`hideTabBar:ok`};case`setTabBarBadge`:return A(e,n);case`removeTabBarBadge`:return j(e,n);case`showTabBarRedDot`:return M(e,n,!0);case`hideTabBarRedDot`:return M(e,n,!1)}}function O(e,t){if(!e.config)return{state:e,ok:!1,errMsg:`setTabBarStyle:fail tabBar not configured`};let n={...e.config},r=(e,t)=>{let r=P(t);r&&(n[e]=r)};return r(`color`,t.color),r(`selectedColor`,t.selectedColor),r(`backgroundColor`,t.backgroundColor),(t.borderStyle===`black`||t.borderStyle===`white`)&&(n.borderStyle=t.borderStyle),{state:{...e,config:n},ok:!0,errMsg:`setTabBarStyle:ok`}}function k(e,t){let n=N(e,t);if(n.err)return{state:e,ok:!1,errMsg:`setTabBarItem:fail ${n.err}`};if(!e.config)return{state:e,ok:!1,errMsg:`setTabBarItem:fail tabBar not configured`};let r=e.config.list[n.index],i={...r,text:typeof t.text==`string`?t.text:r.text,iconPath:typeof t.iconPath==`string`?t.iconPath:r.iconPath,selectedIconPath:typeof t.selectedIconPath==`string`?t.selectedIconPath:r.selectedIconPath},a=[...e.config.list];return a[n.index]=i,{state:{...e,config:{...e.config,list:a}},ok:!0,errMsg:`setTabBarItem:ok`}}function A(e,t){let n=N(e,t);if(n.err)return{state:e,ok:!1,errMsg:`setTabBarBadge:fail ${n.err}`};let r=[...e.badges];r[n.index]=String(t.text??``);let i=[...e.redDots];return i[n.index]=!1,{state:{...e,badges:r,redDots:i},ok:!0,errMsg:`setTabBarBadge:ok`}}function j(e,t){let n=N(e,t);if(n.err)return{state:e,ok:!1,errMsg:`removeTabBarBadge:fail ${n.err}`};let r=[...e.badges];return r[n.index]=``,{state:{...e,badges:r},ok:!0,errMsg:`removeTabBarBadge:ok`}}function M(e,t,n){let r=N(e,t);if(r.err)return{state:e,ok:!1,errMsg:`${n?`showTabBarRedDot`:`hideTabBarRedDot`}:fail ${r.err}`};let i=[...e.redDots];i[r.index]=n;let a=[...e.badges];return n&&(a[r.index]=``),{state:{...e,redDots:i,badges:a},ok:!0,errMsg:`${n?`showTabBarRedDot`:`hideTabBarRedDot`}:ok`}}function N(e,t){let n=e.config?.list??[],r=t.index,i=Number(r);return n.length?r==null||!Number.isInteger(i)||i<0||i>=n.length?{index:-1,err:`invalid index ${r}`}:{index:i,err:null}:{index:-1,err:`tabBar not configured`}}function P(e){if(typeof e!=`string`)return null;let t=e.trim();return!t||t.length>64?null:/[<>"';{}()\\]/.test(t)?/^(?:rgb|rgba|hsl|hsla)\(\s*[\d.,%\s/-]+\)$/i.test(t)?t:null:t}function F(e){return e?e.replace(/^\/+/,``):``}function I(e){let[t,n]=(typeof e==`string`?e:``).split(`?`),r={};if(n)for(let e of n.split(`&`)){if(!e)continue;let t=e.indexOf(`=`),n=t>=0?e.slice(0,t):e,i=t>=0?e.slice(t+1):``;n&&(r[decodeURIComponent(n)]=decodeURIComponent(i))}return{pagePath:F(t),query:r}}function L(e){let t={};return e.isTab&&(t[e.pagePath]=[e]),{stack:[e],tabStacks:t,currentTabPath:e.isTab?e.pagePath:null}}function R(e){return e.currentTabPath?{...e.tabStacks,[e.currentTabPath]:[...e.stack]}:e.tabStacks}function z(e,t){let n=e.stack[e.stack.length-1],r=[...e.stack,t];return{next:{...e,stack:r,tabStacks:e.currentTabPath?{...e.tabStacks,[e.currentTabPath]:r}:e.tabStacks},effects:n?[{kind:`lifecycle`,bridgeId:n.bridgeId,event:`pageHide`}]:[]}}function B(e,t){if(e.stack.length<=1)return{error:`no page to back`};let n=Math.min(Math.max(1,Number.isFinite(t)?t:1),e.stack.length-1),r=e.stack.slice(e.stack.length-n),i=e.stack.slice(0,e.stack.length-n),a=i[i.length-1],o={...e,stack:i,tabStacks:e.currentTabPath?{...e.tabStacks,[e.currentTabPath]:i}:e.tabStacks,currentTabPath:a.isTab?a.pagePath:e.currentTabPath},s=[];for(let e of r)s.push({kind:`lifecycle`,bridgeId:e.bridgeId,event:`pageUnload`}),s.push({kind:`closePage`,bridgeId:e.bridgeId});return s.push({kind:`lifecycle`,bridgeId:a.bridgeId,event:`pageShow`}),{next:o,effects:s}}function V(e,t){let n=e.stack[e.stack.length-1],r=[...e.stack.slice(0,e.stack.length-1),t],i={...e,stack:r,tabStacks:e.currentTabPath?{...e.tabStacks,[e.currentTabPath]:r}:e.tabStacks},a=[];return n&&(a.push({kind:`lifecycle`,bridgeId:n.bridgeId,event:`pageUnload`}),a.push({kind:`closePage`,bridgeId:n.bridgeId})),{next:i,effects:a}}function H(e,t){let n=new Set;for(let t of e.stack)n.add(t.bridgeId);for(let t of Object.values(e.tabStacks))for(let e of t)n.add(e.bridgeId);n.delete(t.bridgeId);let r=t.isTab?{[t.pagePath]:[t]}:{},i={stack:[t],tabStacks:r,currentTabPath:t.isTab?t.pagePath:null},a=[];for(let e of n)a.push({kind:`lifecycle`,bridgeId:e,event:`pageUnload`}),a.push({kind:`closePage`,bridgeId:e});return{next:i,effects:a}}function U(e,t,n){let r=e.stack[e.stack.length-1],i=R(e),a,o=i[t];if(o&&o.length>0)a=o;else if(n)a=[n];else throw Error(`[page-stack] switchTab to ${t} requires either a cached substack or a freshly-opened entry`);let s={...e,stack:a,tabStacks:{...i,[t]:a},currentTabPath:t},c=a[a.length-1],l=[];return r&&r.bridgeId!==c.bridgeId&&l.push({kind:`lifecycle`,bridgeId:r.bridgeId,event:`pageHide`}),n||l.push({kind:`lifecycle`,bridgeId:c.bridgeId,event:`pageShow`}),{next:s,effects:l}}function W(e){let t=new Map,n=e.stack[e.stack.length-1]?.bridgeId,r=e=>{t.has(e.bridgeId)||t.set(e.bridgeId,{entry:e,visible:e.bridgeId===n})};for(let t of Object.values(e.tabStacks))for(let e of t)r(e);for(let t of e.stack)r(t);return Array.from(t.values())}function G(e,t){let n=e.navigationBarBackgroundColor??`#ffffff`,r=e.navigationBarTextStyle??`black`,i=e.navigationStyle??`default`;return f({title:e.navigationBarTitleText??t,backgroundColor:n,textStyle:r,style:i,homeButtonVisible:e.homeButton===!0})}function K(e,t,n){switch(t){case`setNavigationBarTitle`:return{...e,title:typeof n.title==`string`?n.title:e.title};case`setNavigationBarColor`:return J(e,n);case`showNavigationBarLoading`:return{...e,loading:!0};case`hideNavigationBarLoading`:return{...e,loading:!1};case`hideHomeButton`:return{...e,homeButtonVisible:!1};default:return e}}var q=[`linear`,`easeIn`,`easeOut`,`easeInOut`];function J(e,t){let n=typeof t.frontColor==`string`?t.frontColor.toLowerCase():void 0,r=n===`#ffffff`?`white`:n===`#000000`?`black`:e.textStyle,i=typeof t.backgroundColor==`string`?t.backgroundColor:e.backgroundColor,a=(()=>{let e=t.animation;if(!e||typeof e!=`object`)return;let n=e,r=typeof n.duration==`number`&&Number.isFinite(n.duration)?Math.max(0,n.duration):0,i=typeof n.timingFunc==`string`?n.timingFunc:`linear`;return{durationMs:r,timingFunc:q.includes(i)?i:`linear`}})();return{...e,textStyle:r,backgroundColor:i,colorAnimation:a}}function Y(e,t,n){let r=e=>e.bridgeId===t?{...e,navBar:n(e.navBar)}:e,i=e.stack.map(r),a={};for(let[t,n]of Object.entries(e.tabStacks))a[t]=n.map(r);return{...e,stack:i,tabStacks:a}}var X=44,Z=24,Q=44;function $({miniApp:e,bridgeId:t,platform:n=`ios`}){let[a,o]=(0,i.useState)(()=>e.getInitialDevice());(0,i.useEffect)(()=>e.onSimulatorEvent(r.DEVICE_CHANGE,o),[e]);let l=a?.safeAreaInsets.top??(n===`ios`?X:Z),u=a?.safeAreaInsets.bottom??0,f=a?.notchType??`none`,p=(0,i.useMemo)(()=>e.getRenderPreloadUrl(),[e]),g=(0,i.useMemo)(()=>e.getTabBarConfig(),[e]),_=(0,i.useMemo)(()=>({bridgeId:t,pagePath:F(e.pagePath),query:{...e.query},isTab:!!e.getTabBarConfig()?.list.some(t=>F(t.pagePath)===F(e.pagePath)),windowConfig:e.rootWindowConfig??{},navBar:G(e.rootWindowConfig??{},e.appId)}),[e,t]),[{shell:v,tabBar:b},x]=(0,i.useState)(()=>({shell:L(_),tabBar:w(g)})),S=(0,i.useRef)({shell:v,tabBar:b});(0,i.useEffect)(()=>{S.current={shell:v,tabBar:b}},[v,b]);let C=(0,i.useCallback)(t=>{for(let n of t)n.kind===`lifecycle`?e.notifyLifecycle(n.bridgeId,n.event):n.kind===`closePage`&&e.closePage(n.bridgeId)},[e]);(0,i.useEffect)(()=>e.onSimulatorEvent(r.NAV_BAR,e=>{x(t=>({...t,shell:Y(t.shell,e.bridgeId,t=>K(t,e.name,e.params))}))}),[e]),(0,i.useEffect)(()=>e.onSessionEvent(r.TAB_ACTION,t=>{let n=E(S.current.tabBar,{kind:`apply`,name:t.name,params:t.params});x(e=>({...e,tabBar:n.state})),e.notifyNavCallback({ok:n.ok,errMsg:n.errMsg,callbacks:t.callbacks})}),[e]);let T=(0,i.useCallback)(async t=>{let n=(n,r)=>e.notifyNavCallback({ok:n,errMsg:r,callbacks:t.callbacks});try{switch(t.name){case`navigateTo`:await ee(e,S,x,C,t,n);break;case`navigateBack`:te(S,x,C,t,n);break;case`redirectTo`:await ne(e,S,x,C,t,n);break;case`reLaunch`:await re(e,S,x,C,t,n);break;case`switchTab`:await ie(e,S,x,C,t,n);break}}catch(e){n(!1,`${t.name}:fail ${e instanceof Error?e.message:String(e)}`)}},[e,C]);(0,i.useEffect)(()=>e.onSessionEvent(r.NAV_ACTION,e=>{T(e)}),[T,e]),(0,i.useEffect)(()=>e.onSessionEvent(r.API_CALL,t=>{s(e,t.name,t.params,n=>{e.notifyApiResponse({requestId:t.requestId,ok:n.ok,result:n.result,errMsg:n.errMsg,keep:n.keep})})}),[e]);let D=(0,i.useCallback)(()=>{if(S.current.shell.stack.length<=1)return;let t=S.current.shell.stack;T({appSessionId:e.appSessionId??``,bridgeId:t[t.length-1].bridgeId,name:`navigateBack`,params:{delta:1},callbacks:{}})},[e,T]),O=(0,i.useCallback)(t=>{let n=S.current.shell;t===n.currentTabPath&&n.stack.length===1||T({appSessionId:e.appSessionId??``,bridgeId:n.stack[n.stack.length-1].bridgeId,name:`switchTab`,params:{url:`/${t}`},callbacks:{}})},[e,T]),k=v.stack[v.stack.length-1],A=W(v);return(0,i.useEffect)(()=>{e.notifyActivePage(k.bridgeId)},[e,k.bridgeId]),(0,i.useEffect)(()=>{e.notifyPageStack(v.stack.map(e=>({pagePath:e.pagePath,query:e.query})))},[e,v.stack]),(0,c.jsx)(`main`,{className:`device-shell-root`,children:(0,c.jsxs)(`section`,{className:`device-shell`,"aria-label":`Dimina simulator`,style:a?{width:a.screenWidth,height:a.screenHeight}:void 0,children:[(0,c.jsx)(m,{height:l,notchType:f,textStyle:k.navBar.textStyle}),(0,c.jsx)(d,{state:k.navBar,stackDepth:v.stack.length,platform:n,statusBarHeight:l,navBarHeight:Q,onBack:D}),(0,c.jsx)(`div`,{className:`device-shell__viewport`,children:A.map(({entry:t,visible:n})=>(0,c.jsx)(`webview`,{className:`device-shell__webview`,src:e.createRenderHostUrl(t.bridgeId,t.pagePath,t.isTab),preload:p,allowpopups:`true`,style:{display:n?`flex`:`none`,zIndex:n?100:1}},t.bridgeId))}),k.isTab&&(0,c.jsx)(h,{state:b,currentPath:v.currentTabPath,resourceBaseUrl:e.resourceBaseUrl,appId:e.appId,onSwitch:O,bottomInset:u}),(0,c.jsx)(y,{}),u>0&&(0,c.jsx)(`div`,{className:`device-shell__home-indicator`,style:{height:u},"aria-hidden":`true`})]})})}async function ee(e,t,n,r,i,a){let{pagePath:o,query:s}=I(i.params.url);if(!o){a(!1,`navigateTo:fail invalid url`);return}if(e.getTabBarConfig()?.list.some(e=>F(e.pagePath)===o)){a(!1,`navigateTo:fail can not navigateTo a tabbar page`);return}let c=await e.openPage(o,s),l={bridgeId:c.bridgeId,pagePath:c.pagePath,query:s,isTab:c.isTab,windowConfig:c.windowConfig,navBar:G(c.windowConfig,e.appId)},{next:u,effects:d}=z(t.current.shell,l);n(e=>({...e,shell:u})),r(d),a(!0,`navigateTo:ok`)}function te(e,t,n,r,i){let a=r.params.delta,o=Number.isFinite(Number(a))?Number(a):1,s=B(e.current.shell,o);if(`error`in s){i(!1,`navigateBack:fail ${s.error}`);return}t(e=>({...e,shell:s.next})),n(s.effects),i(!0,`navigateBack:ok`)}async function ne(e,t,n,r,i,a){let{pagePath:o,query:s}=I(i.params.url);if(!o){a(!1,`redirectTo:fail invalid url`);return}if(e.getTabBarConfig()?.list.some(e=>F(e.pagePath)===o)){a(!1,`redirectTo:fail can not redirectTo a tabbar page`);return}let c=await e.openPage(o,s),l={bridgeId:c.bridgeId,pagePath:c.pagePath,query:s,isTab:c.isTab,windowConfig:c.windowConfig,navBar:G(c.windowConfig,e.appId)},{next:u,effects:d}=V(t.current.shell,l);n(e=>({...e,shell:u})),r(d),a(!0,`redirectTo:ok`)}async function re(e,t,n,r,i,a){let{pagePath:o,query:s}=I(i.params.url);if(!o){a(!1,`reLaunch:fail invalid url`);return}let c=await e.openPage(o,s),l={bridgeId:c.bridgeId,pagePath:c.pagePath,query:s,isTab:c.isTab,windowConfig:c.windowConfig,navBar:G(c.windowConfig,e.appId)},{next:u,effects:d}=H(t.current.shell,l);n(e=>({...e,shell:u})),r(d),a(!0,`reLaunch:ok`)}async function ie(e,t,n,r,i,a){let{pagePath:o}=I(i.params.url);if(!o){a(!1,`switchTab:fail invalid url`);return}if(!e.getTabBarConfig()?.list.some(e=>F(e.pagePath)===o)){a(!1,`switchTab:fail not a tabBar page: ${o}`);return}let s=t.current.shell.tabStacks[o],c=null;if(!s||s.length===0){let t=await e.openPage(o,{});c={bridgeId:t.bridgeId,pagePath:t.pagePath,query:{},isTab:!0,windowConfig:t.windowConfig,navBar:G(t.windowConfig,e.appId)}}let{next:l,effects:u}=U(t.current.shell,o,c);n(e=>({...e,shell:l})),r(u),a(!0,`switchTab:ok`)}export{$ as DeviceShell};
|
|
2
|
-
//# sourceMappingURL=device-shell-
|
|
1
|
+
import{n as e,r as t,t as n}from"./jsx-runtime-CDK-o-S0.js";import{t as r}from"./bridge-channels-zhsumfky.js";var i=t(),a=new Set([`audioListen`]);function o(e){return a.has(e)}function s(e,t,n,r){let i=e.apiRegistry[t];if(!i)return r({ok:!1,errMsg:`${t}:fail no handler`}),Promise.resolve();let a=o(t)||(n&&typeof n==`object`&&!Array.isArray(n)?n.keep===!0:!1);return new Promise(o=>{let s=!1,c=e=>{if(s){a&&e.ok&&r({...e,keep:!0});return}s=!0,r(a&&e.ok?{...e,keep:!0}:e),o()},l=Symbol(`sim-cb-success`),u=Symbol(`sim-cb-fail`),d=Symbol(`sim-cb-complete`),f=!1,p=Object.create(e);p.createCallbackFunction=e=>{if(e!=null)return(e===l||e===u)&&(f=!0),(...n)=>{let r=n[0];e===l?c({ok:!0,result:r}):e===u?c({ok:!1,errMsg:r&&typeof r==`object`&&`errMsg`in r?String(r.errMsg):`${t}:fail`,result:r}):e===d&&!a&&c({ok:!0,result:r})}};let m=n&&typeof n==`object`&&!Array.isArray(n)?{...n}:{};m.success=l,m.fail=u,m.complete=d;try{let e=i.call(p,m);if(e&&typeof e.then==`function`){Promise.resolve(e).then(e=>c({ok:!0,result:e}),e=>{c({ok:!1,errMsg:`${t}:fail ${e instanceof Error?e.message:String(e)}`})});return}if(s)return;if(a){o();return}if(f){o();return}c({ok:!0,result:e})}catch(e){c({ok:!1,errMsg:`${t}:fail ${e instanceof Error?e.message:String(e)}`})}})}var c=n();function l({platform:e,statusBarHeight:t,textStyle:n}){let r=e===`ios`?87:95,i=t+(e===`ios`?4:6),a=e===`ios`?7:10;return(0,c.jsxs)(`div`,{className:`menu-capsule menu-capsule--${n}`,style:{width:r,height:32,top:i,right:a},"aria-hidden":`true`,children:[(0,c.jsxs)(`div`,{className:`menu-capsule__more`,children:[(0,c.jsx)(`span`,{}),(0,c.jsx)(`span`,{}),(0,c.jsx)(`span`,{})]}),(0,c.jsx)(`div`,{className:`menu-capsule__divider`}),(0,c.jsx)(`div`,{className:`menu-capsule__close`,children:(0,c.jsx)(`svg`,{viewBox:`0 0 16 16`,width:`12`,height:`12`,"aria-hidden":`true`,children:(0,c.jsx)(`path`,{d:`M4 4l8 8M12 4l-8 8`,stroke:`currentColor`,strokeWidth:`1.5`,fill:`none`,strokeLinecap:`round`})})})]})}var u={linear:`linear`,easeIn:`ease-in`,easeOut:`ease-out`,easeInOut:`ease-in-out`};function d({state:e,stackDepth:t,platform:n,statusBarHeight:r,navBarHeight:a,onBack:o,onHome:s}){let d=(0,i.useMemo)(()=>{if(!e.colorAnimation||e.colorAnimation.durationMs<=0)return;let t=u[e.colorAnimation.timingFunc]??`linear`;return`background-color ${e.colorAnimation.durationMs}ms ${t}, color ${e.colorAnimation.durationMs}ms ${t}`},[e.colorAnimation]),f=e.style===`custom`,p=t>1,m=!p&&e.homeButtonVisible,h=n===`ios`?`center`:`left`,g={backgroundColor:e.backgroundColor,color:e.textStyle===`white`?`#ffffff`:`#000000`,height:r+a,paddingTop:r,transition:d};return(0,c.jsxs)(`header`,{className:`nav-bar nav-bar--${n} nav-bar--${e.textStyle}${f?` nav-bar--custom`:``}`,style:g,"aria-hidden":f,children:[!f&&(0,c.jsxs)(`div`,{className:`nav-bar__row`,style:{height:a,justifyContent:h===`center`?`center`:`flex-start`},children:[(p||m)&&(0,c.jsxs)(`div`,{className:`nav-bar__leading`,children:[p&&(0,c.jsx)(`button`,{type:`button`,className:`nav-bar__back`,"aria-label":`Back`,onClick:o,children:(0,c.jsx)(`svg`,{viewBox:`0 0 24 24`,width:`24`,height:`24`,"aria-hidden":`true`,children:(0,c.jsx)(`path`,{d:`M15 18l-6-6 6-6`,stroke:`currentColor`,strokeWidth:`2`,fill:`none`,strokeLinecap:`round`,strokeLinejoin:`round`})})}),m&&(0,c.jsx)(`button`,{type:`button`,className:`nav-bar__home`,"aria-label":`Home`,onClick:s,children:(0,c.jsx)(`svg`,{viewBox:`0 0 24 24`,width:`22`,height:`22`,"aria-hidden":`true`,children:(0,c.jsx)(`path`,{d:`M3 12l9-9 9 9M5 10v10h14V10`,stroke:`currentColor`,strokeWidth:`2`,fill:`none`,strokeLinecap:`round`,strokeLinejoin:`round`})})})]}),(0,c.jsxs)(`div`,{className:`nav-bar__title nav-bar__title--${h}`,style:{color:e.textStyle===`white`?`#ffffff`:`#000000`},children:[e.loading&&(0,c.jsx)(`span`,{className:`nav-bar__spinner`,"aria-hidden":`true`}),(0,c.jsx)(`span`,{className:`nav-bar__title-text`,children:e.title})]})]}),(0,c.jsx)(l,{platform:n,statusBarHeight:r,textStyle:e.textStyle})]})}function f(e){return{title:e?.title??``,backgroundColor:e?.backgroundColor??`#000000`,textStyle:e?.textStyle??`white`,style:e?.style??`default`,loading:e?.loading??!1,homeButtonVisible:e?.homeButtonVisible??!1,colorAnimation:e?.colorAnimation}}function p(e){switch(e){case`notch`:return{width:164,height:30,top:0,bottomOnly:!0};case`dynamic-island`:return{width:124,height:36,top:11,bottomOnly:!1};default:return null}}function m({height:e,notchType:t,textStyle:n}){let r=p(t);return(0,c.jsxs)(`div`,{className:`device-statusbar`,style:{height:e,color:n===`black`?`#000000`:`#ffffff`},"aria-hidden":`true`,children:[(0,c.jsx)(`span`,{className:`device-statusbar__time`,children:`9:41`}),r&&(0,c.jsx)(`div`,{className:`device-statusbar__notch`,style:{width:r.width,height:r.height,top:r.top,borderRadius:r.bottomOnly?`0 0 ${Math.round(r.height*.6)}px ${Math.round(r.height*.6)}px`:`${r.height/2}px`}}),(0,c.jsxs)(`div`,{className:`device-statusbar__icons`,children:[(0,c.jsx)(`span`,{className:`device-statusbar__signal`}),(0,c.jsx)(`span`,{className:`device-statusbar__wifi`}),(0,c.jsx)(`span`,{className:`device-statusbar__battery`})]})]})}function h({state:e,currentPath:t,resourceBaseUrl:n,appId:r,onSwitch:i,bottomInset:a=0}){if(!e.config||!e.visible)return null;let{color:o,selectedColor:s,backgroundColor:l,borderStyle:u,list:d}=e.config,f=o||`#999999`,p=s||`#1890ff`;return(0,c.jsx)(`div`,{className:`dmb-tab-bar`,style:{backgroundColor:l||`#ffffff`,borderTopColor:u===`white`?`#ffffff`:`#e0e0e0`,paddingBottom:a},role:`tablist`,"aria-label":`TabBar`,children:d.map((a,o)=>{let s=g(a.pagePath),l=s===t,u=_(l?a.selectedIconPath??a.iconPath:a.iconPath,n,r),d=e.badges[o]??``,m=e.redDots[o]??!1;return(0,c.jsxs)(`button`,{type:`button`,className:`dmb-tab-bar__item${l?` is-selected`:``}`,role:`tab`,"aria-selected":l,onClick:()=>i(s),children:[u&&(0,c.jsx)(`span`,{className:`dmb-tab-bar__icon-slot`,children:(0,c.jsx)(`img`,{className:`dmb-tab-bar__icon`,src:u,alt:``,onError:e=>{e.currentTarget.style.display=`none`}})}),(0,c.jsx)(`span`,{className:`dmb-tab-bar__text`,style:{color:l?p:f},children:a.text||``}),d&&(0,c.jsx)(`span`,{className:`dmb-tab-bar__badge`,children:d}),!d&&m&&(0,c.jsx)(`span`,{className:`dmb-tab-bar__red-dot`})]},`${s}-${o}`)})})}function g(e){return e?e.replace(/^\/+/,``):``}function _(e,t,n){if(!e)return null;let r=e.trim();if(!r)return null;if(/^(?:data:|blob:|https?:|\/\/)/i.test(r))return r;if(!t)return null;let i=r.replace(/^\/+/,``).replace(/^\.\//,``);return i.startsWith(`${n}/`)?v(t,i):v(t,`${n}/main/${i}`)}function v(e,t){return`${e.endsWith(`/`)?e:`${e}/`}${t.replace(/^\/+/,``)}`}function y(){let[{toast:t,dialog:n},r]=(0,i.useState)(()=>e.getState());return(0,i.useEffect)(()=>e.subscribe(r),[]),(0,c.jsxs)(c.Fragment,{children:[t&&(0,c.jsx)(b,{toast:t}),n?.kind===`modal`&&(0,c.jsx)(S,{dialog:n}),n?.kind===`actionSheet`&&(0,c.jsx)(C,{dialog:n})]})}function b({toast:t}){(0,i.useEffect)(()=>{if(!Number.isFinite(t.duration))return;let n=window.setTimeout(()=>e.dismissToast(t),t.duration);return()=>window.clearTimeout(n)},[t]);let n=t.icon!==`none`||!!t.image;return(0,c.jsxs)(`div`,{className:`dmui-overlay`,"aria-live":`polite`,children:[t.mask&&(0,c.jsx)(`div`,{className:`dmui-mask dmui-mask--transparent`}),(0,c.jsxs)(`div`,{className:`dmui-toast${n?``:` dmui-toast--text`}`,role:`alert`,children:[t.image?(0,c.jsx)(`img`,{className:`dmui-toast__image`,src:t.image,alt:``}):(0,c.jsx)(x,{icon:t.icon}),t.title&&(0,c.jsx)(`div`,{className:`dmui-toast__title`,children:t.title})]})]})}function x({icon:e}){return e===`success`?(0,c.jsx)(`svg`,{className:`dmui-toast__icon`,viewBox:`0 0 24 24`,"aria-hidden":`true`,children:(0,c.jsx)(`path`,{d:`M5 13l4 4L19 7`})}):e===`error`?(0,c.jsx)(`svg`,{className:`dmui-toast__icon`,viewBox:`0 0 24 24`,"aria-hidden":`true`,children:(0,c.jsx)(`path`,{d:`M6 6l12 12M18 6L6 18`})}):e===`loading`?(0,c.jsx)(`span`,{className:`dmui-toast__spinner`,"aria-hidden":`true`}):null}function S({dialog:e}){let[t,n]=(0,i.useState)(``),r=(0,i.useRef)(null);return(0,i.useEffect)(()=>{e.editable&&r.current?.focus()},[e.editable]),(0,c.jsxs)(`div`,{className:`dmui-overlay`,children:[(0,c.jsx)(`div`,{className:`dmui-mask`}),(0,c.jsxs)(`div`,{className:`dmui-modal`,role:`dialog`,"aria-modal":`true`,children:[e.title&&(0,c.jsx)(`div`,{className:`dmui-modal__title`,children:e.title}),e.editable?(0,c.jsx)(`input`,{ref:r,className:`dmui-modal__input`,value:t,placeholder:e.placeholderText,onChange:e=>n(e.target.value)}):e.content&&(0,c.jsx)(`div`,{className:`dmui-modal__content`,children:e.content}),(0,c.jsxs)(`div`,{className:`dmui-modal__actions`,children:[e.showCancel&&(0,c.jsx)(`button`,{type:`button`,className:`dmui-modal__button`,style:{color:e.cancelColor},onClick:()=>e.onResult(!1),children:e.cancelText}),(0,c.jsx)(`button`,{type:`button`,className:`dmui-modal__button`,style:{color:e.confirmColor},onClick:()=>e.onResult(!0,t),children:e.confirmText})]})]})]})}function C({dialog:e}){return(0,c.jsxs)(`div`,{className:`dmui-overlay`,children:[(0,c.jsx)(`div`,{className:`dmui-mask`,onClick:()=>e.onSelect(-1)}),(0,c.jsxs)(`div`,{className:`dmui-action-sheet`,role:`menu`,children:[(0,c.jsx)(`div`,{className:`dmui-action-sheet__items`,children:e.itemList.map((t,n)=>(0,c.jsx)(`button`,{type:`button`,className:`dmui-action-sheet__item`,style:{color:e.itemColor},onClick:()=>e.onSelect(n),children:t},n))}),(0,c.jsx)(`button`,{type:`button`,className:`dmui-action-sheet__cancel`,onClick:()=>e.onSelect(-1),children:`取消`})]})]})}function w(e){if(!e)return{config:null,visible:!1,badges:[],redDots:[]};let t=e.list.length;return{config:T(e),visible:!0,badges:Array.from({length:t},()=>``),redDots:Array.from({length:t},()=>!1)}}function T(e){return{...e,list:e.list.map(e=>({...e}))}}function E(e,t){switch(t.kind){case`reset`:return{state:w(t.config),ok:!0,errMsg:`reset:ok`};case`visibility`:return{state:{...e,visible:t.visible},ok:!0,errMsg:t.visible?`showTabBar:ok`:`hideTabBar:ok`};case`apply`:return D(e,t.name,t.params)}}function D(e,t,n){if(!e.config)return{state:e,ok:!1,errMsg:`${t}:fail tabBar not configured`};switch(t){case`setTabBarStyle`:return O(e,n);case`setTabBarItem`:return k(e,n);case`showTabBar`:return{state:{...e,visible:!0},ok:!0,errMsg:`showTabBar:ok`};case`hideTabBar`:return{state:{...e,visible:!1},ok:!0,errMsg:`hideTabBar:ok`};case`setTabBarBadge`:return A(e,n);case`removeTabBarBadge`:return j(e,n);case`showTabBarRedDot`:return M(e,n,!0);case`hideTabBarRedDot`:return M(e,n,!1)}}function O(e,t){if(!e.config)return{state:e,ok:!1,errMsg:`setTabBarStyle:fail tabBar not configured`};let n={...e.config},r=(e,t)=>{let r=P(t);r&&(n[e]=r)};return r(`color`,t.color),r(`selectedColor`,t.selectedColor),r(`backgroundColor`,t.backgroundColor),(t.borderStyle===`black`||t.borderStyle===`white`)&&(n.borderStyle=t.borderStyle),{state:{...e,config:n},ok:!0,errMsg:`setTabBarStyle:ok`}}function k(e,t){let n=N(e,t);if(n.err)return{state:e,ok:!1,errMsg:`setTabBarItem:fail ${n.err}`};if(!e.config)return{state:e,ok:!1,errMsg:`setTabBarItem:fail tabBar not configured`};let r=e.config.list[n.index],i={...r,text:typeof t.text==`string`?t.text:r.text,iconPath:typeof t.iconPath==`string`?t.iconPath:r.iconPath,selectedIconPath:typeof t.selectedIconPath==`string`?t.selectedIconPath:r.selectedIconPath},a=[...e.config.list];return a[n.index]=i,{state:{...e,config:{...e.config,list:a}},ok:!0,errMsg:`setTabBarItem:ok`}}function A(e,t){let n=N(e,t);if(n.err)return{state:e,ok:!1,errMsg:`setTabBarBadge:fail ${n.err}`};let r=[...e.badges];r[n.index]=String(t.text??``);let i=[...e.redDots];return i[n.index]=!1,{state:{...e,badges:r,redDots:i},ok:!0,errMsg:`setTabBarBadge:ok`}}function j(e,t){let n=N(e,t);if(n.err)return{state:e,ok:!1,errMsg:`removeTabBarBadge:fail ${n.err}`};let r=[...e.badges];return r[n.index]=``,{state:{...e,badges:r},ok:!0,errMsg:`removeTabBarBadge:ok`}}function M(e,t,n){let r=N(e,t);if(r.err)return{state:e,ok:!1,errMsg:`${n?`showTabBarRedDot`:`hideTabBarRedDot`}:fail ${r.err}`};let i=[...e.redDots];i[r.index]=n;let a=[...e.badges];return n&&(a[r.index]=``),{state:{...e,redDots:i,badges:a},ok:!0,errMsg:`${n?`showTabBarRedDot`:`hideTabBarRedDot`}:ok`}}function N(e,t){let n=e.config?.list??[],r=t.index,i=Number(r);return n.length?r==null||!Number.isInteger(i)||i<0||i>=n.length?{index:-1,err:`invalid index ${r}`}:{index:i,err:null}:{index:-1,err:`tabBar not configured`}}function P(e){if(typeof e!=`string`)return null;let t=e.trim();return!t||t.length>64?null:/[<>"';{}()\\]/.test(t)?/^(?:rgb|rgba|hsl|hsla)\(\s*[\d.,%\s/-]+\)$/i.test(t)?t:null:t}function F(e){return e?e.replace(/^\/+/,``):``}function I(e){if(!e)return null;let t=e.indexOf(`=`),n=t>=0?e.slice(0,t):e,r=t>=0?e.slice(t+1):``;return n?[decodeURIComponent(n),decodeURIComponent(r)]:null}function L(e){let t={};for(let n of e.split(`&`)){let e=I(n);e&&(t[e[0]]=e[1])}return t}function R(e){let[t,n]=(typeof e==`string`?e:``).split(`?`);return{pagePath:F(t),query:n?L(n):{}}}function z(e){let t={};return e.isTab&&(t[e.pagePath]=[e]),{stack:[e],tabStacks:t,currentTabPath:e.isTab?e.pagePath:null}}function B(e){return e.currentTabPath?{...e.tabStacks,[e.currentTabPath]:[...e.stack]}:e.tabStacks}function V(e,t){let n=e.stack[e.stack.length-1],r=[...e.stack,t];return{next:{...e,stack:r,tabStacks:e.currentTabPath?{...e.tabStacks,[e.currentTabPath]:r}:e.tabStacks},effects:n?[{kind:`lifecycle`,bridgeId:n.bridgeId,event:`pageHide`}]:[]}}function H(e,t){if(e.stack.length<=1)return{error:`no page to back`};let n=Math.min(Math.max(1,Number.isFinite(t)?t:1),e.stack.length-1),r=e.stack.slice(e.stack.length-n),i=e.stack.slice(0,e.stack.length-n),a=i[i.length-1],o={...e,stack:i,tabStacks:e.currentTabPath?{...e.tabStacks,[e.currentTabPath]:i}:e.tabStacks,currentTabPath:a.isTab?a.pagePath:e.currentTabPath},s=[];for(let e of r)s.push({kind:`lifecycle`,bridgeId:e.bridgeId,event:`pageUnload`}),s.push({kind:`closePage`,bridgeId:e.bridgeId});return s.push({kind:`lifecycle`,bridgeId:a.bridgeId,event:`pageShow`}),{next:o,effects:s}}function U(e,t){let n=e.stack[e.stack.length-1],r=[...e.stack.slice(0,e.stack.length-1),t],i={...e,stack:r,tabStacks:e.currentTabPath?{...e.tabStacks,[e.currentTabPath]:r}:e.tabStacks},a=[];return n&&(a.push({kind:`lifecycle`,bridgeId:n.bridgeId,event:`pageUnload`}),a.push({kind:`closePage`,bridgeId:n.bridgeId})),{next:i,effects:a}}function W(e,t){let n=new Set;for(let t of e.stack)n.add(t.bridgeId);for(let t of Object.values(e.tabStacks))for(let e of t)n.add(e.bridgeId);n.delete(t.bridgeId);let r=t.isTab?{[t.pagePath]:[t]}:{},i={stack:[t],tabStacks:r,currentTabPath:t.isTab?t.pagePath:null},a=[];for(let e of n)a.push({kind:`lifecycle`,bridgeId:e,event:`pageUnload`}),a.push({kind:`closePage`,bridgeId:e});return{next:i,effects:a}}function G(e,t,n){let r=e.stack[e.stack.length-1],i=B(e),a,o=i[t];if(o&&o.length>0)a=o;else if(n)a=[n];else throw Error(`[page-stack] switchTab to ${t} requires either a cached substack or a freshly-opened entry`);let s={...e,stack:a,tabStacks:{...i,[t]:a},currentTabPath:t},c=a[a.length-1],l=[];return r&&r.bridgeId!==c.bridgeId&&l.push({kind:`lifecycle`,bridgeId:r.bridgeId,event:`pageHide`}),n||l.push({kind:`lifecycle`,bridgeId:c.bridgeId,event:`pageShow`}),{next:s,effects:l}}function K(e){let t=new Map,n=e.stack[e.stack.length-1]?.bridgeId,r=e=>{t.has(e.bridgeId)||t.set(e.bridgeId,{entry:e,visible:e.bridgeId===n})};for(let t of Object.values(e.tabStacks))for(let e of t)r(e);for(let t of e.stack)r(t);return Array.from(t.values())}function q(e,t){let n=e.navigationBarBackgroundColor??`#ffffff`,r=e.navigationBarTextStyle??`black`,i=e.navigationStyle??`default`;return f({title:e.navigationBarTitleText??t,backgroundColor:n,textStyle:r,style:i,homeButtonVisible:e.homeButton===!0})}function J(e,t,n){switch(t){case`setNavigationBarTitle`:return{...e,title:typeof n.title==`string`?n.title:e.title};case`setNavigationBarColor`:return X(e,n);case`showNavigationBarLoading`:return{...e,loading:!0};case`hideNavigationBarLoading`:return{...e,loading:!1};case`hideHomeButton`:return{...e,homeButtonVisible:!1};default:return e}}var Y=[`linear`,`easeIn`,`easeOut`,`easeInOut`];function X(e,t){let n=typeof t.frontColor==`string`?t.frontColor.toLowerCase():void 0,r=n===`#ffffff`?`white`:n===`#000000`?`black`:e.textStyle,i=typeof t.backgroundColor==`string`?t.backgroundColor:e.backgroundColor,a=(()=>{let e=t.animation;if(!e||typeof e!=`object`)return;let n=e,r=typeof n.duration==`number`&&Number.isFinite(n.duration)?Math.max(0,n.duration):0,i=typeof n.timingFunc==`string`?n.timingFunc:`linear`;return{durationMs:r,timingFunc:Y.includes(i)?i:`linear`}})();return{...e,textStyle:r,backgroundColor:i,colorAnimation:a}}function Z(e,t,n){let r=e=>e.bridgeId===t?{...e,navBar:n(e.navBar)}:e,i=e.stack.map(r),a={};for(let[t,n]of Object.entries(e.tabStacks))a[t]=n.map(r);return{...e,stack:i,tabStacks:a}}var Q=44,$=24,ee=44;function te({miniApp:e,bridgeId:t,platform:n=`ios`}){let[a,o]=(0,i.useState)(()=>e.getInitialDevice());(0,i.useEffect)(()=>e.onSimulatorEvent(r.DEVICE_CHANGE,o),[e]);let l=a?.safeAreaInsets.top??(n===`ios`?Q:$),u=a?.safeAreaInsets.bottom??0,f=a?.notchType??`none`,p=(0,i.useMemo)(()=>e.getRenderPreloadUrl(),[e]),g=(0,i.useMemo)(()=>e.getTabBarConfig(),[e]),_=(0,i.useMemo)(()=>({bridgeId:t,pagePath:F(e.pagePath),query:{...e.query},isTab:!!e.getTabBarConfig()?.list.some(t=>F(t.pagePath)===F(e.pagePath)),windowConfig:e.rootWindowConfig??{},navBar:q(e.rootWindowConfig??{},e.appId)}),[e,t]),[{shell:v,tabBar:b},x]=(0,i.useState)(()=>({shell:z(_),tabBar:w(g)})),S=(0,i.useRef)({shell:v,tabBar:b});(0,i.useEffect)(()=>{S.current={shell:v,tabBar:b}},[v,b]);let C=(0,i.useCallback)(t=>{for(let n of t)n.kind===`lifecycle`?e.notifyLifecycle(n.bridgeId,n.event):n.kind===`closePage`&&e.closePage(n.bridgeId)},[e]);(0,i.useEffect)(()=>e.onSimulatorEvent(r.NAV_BAR,e=>{x(t=>({...t,shell:Z(t.shell,e.bridgeId,t=>J(t,e.name,e.params))}))}),[e]),(0,i.useEffect)(()=>e.onSessionEvent(r.TAB_ACTION,t=>{let n=E(S.current.tabBar,{kind:`apply`,name:t.name,params:t.params});x(e=>({...e,tabBar:n.state})),e.notifyNavCallback({ok:n.ok,errMsg:n.errMsg,callbacks:t.callbacks})}),[e]);let T=(0,i.useCallback)(async t=>{let n=(n,r)=>e.notifyNavCallback({ok:n,errMsg:r,callbacks:t.callbacks});try{switch(t.name){case`navigateTo`:await ne(e,S,x,C,t,n);break;case`navigateBack`:re(S,x,C,t,n);break;case`redirectTo`:await ie(e,S,x,C,t,n);break;case`reLaunch`:await ae(e,S,x,C,t,n);break;case`switchTab`:await oe(e,S,x,C,t,n);break}}catch(e){n(!1,`${t.name}:fail ${e instanceof Error?e.message:String(e)}`)}},[e,C]);(0,i.useEffect)(()=>e.onSessionEvent(r.NAV_ACTION,e=>{T(e)}),[T,e]),(0,i.useEffect)(()=>e.onSessionEvent(r.API_CALL,t=>{s(e,t.name,t.params,n=>{e.notifyApiResponse({requestId:t.requestId,ok:n.ok,result:n.result,errMsg:n.errMsg,keep:n.keep})})}),[e]);let D=(0,i.useCallback)(()=>{if(S.current.shell.stack.length<=1)return;let t=S.current.shell.stack;T({appSessionId:e.appSessionId??``,bridgeId:t[t.length-1].bridgeId,name:`navigateBack`,params:{delta:1},callbacks:{}})},[e,T]),O=(0,i.useCallback)(t=>{let n=S.current.shell;t===n.currentTabPath&&n.stack.length===1||T({appSessionId:e.appSessionId??``,bridgeId:n.stack[n.stack.length-1].bridgeId,name:`switchTab`,params:{url:`/${t}`},callbacks:{}})},[e,T]),k=v.stack[v.stack.length-1],A=K(v);return(0,i.useEffect)(()=>{e.notifyActivePage(k.bridgeId)},[e,k.bridgeId]),(0,i.useEffect)(()=>{e.notifyPageStack(v.stack.map(e=>({pagePath:e.pagePath,query:e.query})))},[e,v.stack]),(0,c.jsx)(`main`,{className:`device-shell-root`,children:(0,c.jsxs)(`section`,{className:`device-shell`,"aria-label":`Dimina simulator`,style:a?{width:a.screenWidth,height:a.screenHeight}:void 0,children:[(0,c.jsx)(m,{height:l,notchType:f,textStyle:k.navBar.textStyle}),(0,c.jsx)(d,{state:k.navBar,stackDepth:v.stack.length,platform:n,statusBarHeight:l,navBarHeight:ee,onBack:D}),(0,c.jsx)(`div`,{className:`device-shell__viewport`,children:A.map(({entry:t,visible:n})=>(0,c.jsx)(`webview`,{className:`device-shell__webview`,src:e.createRenderHostUrl(t.bridgeId,t.pagePath,t.isTab),preload:p,allowpopups:`true`,style:{display:n?`flex`:`none`,zIndex:n?100:1}},t.bridgeId))}),k.isTab&&(0,c.jsx)(h,{state:b,currentPath:v.currentTabPath,resourceBaseUrl:e.resourceBaseUrl,appId:e.appId,onSwitch:O,bottomInset:u}),(0,c.jsx)(y,{}),u>0&&(0,c.jsx)(`div`,{className:`device-shell__home-indicator`,style:{height:u},"aria-hidden":`true`})]})})}async function ne(e,t,n,r,i,a){let{pagePath:o,query:s}=R(i.params.url);if(!o){a(!1,`navigateTo:fail invalid url`);return}if(e.getTabBarConfig()?.list.some(e=>F(e.pagePath)===o)){a(!1,`navigateTo:fail can not navigateTo a tabbar page`);return}let c=await e.openPage(o,s),l={bridgeId:c.bridgeId,pagePath:c.pagePath,query:s,isTab:c.isTab,windowConfig:c.windowConfig,navBar:q(c.windowConfig,e.appId)},{next:u,effects:d}=V(t.current.shell,l);n(e=>({...e,shell:u})),r(d),a(!0,`navigateTo:ok`)}function re(e,t,n,r,i){let a=r.params.delta,o=Number.isFinite(Number(a))?Number(a):1,s=H(e.current.shell,o);if(`error`in s){i(!1,`navigateBack:fail ${s.error}`);return}t(e=>({...e,shell:s.next})),n(s.effects),i(!0,`navigateBack:ok`)}async function ie(e,t,n,r,i,a){let{pagePath:o,query:s}=R(i.params.url);if(!o){a(!1,`redirectTo:fail invalid url`);return}if(e.getTabBarConfig()?.list.some(e=>F(e.pagePath)===o)){a(!1,`redirectTo:fail can not redirectTo a tabbar page`);return}let c=await e.openPage(o,s),l={bridgeId:c.bridgeId,pagePath:c.pagePath,query:s,isTab:c.isTab,windowConfig:c.windowConfig,navBar:q(c.windowConfig,e.appId)},{next:u,effects:d}=U(t.current.shell,l);n(e=>({...e,shell:u})),r(d),a(!0,`redirectTo:ok`)}async function ae(e,t,n,r,i,a){let{pagePath:o,query:s}=R(i.params.url);if(!o){a(!1,`reLaunch:fail invalid url`);return}let c=await e.openPage(o,s),l={bridgeId:c.bridgeId,pagePath:c.pagePath,query:s,isTab:c.isTab,windowConfig:c.windowConfig,navBar:q(c.windowConfig,e.appId)},{next:u,effects:d}=W(t.current.shell,l);n(e=>({...e,shell:u})),r(d),a(!0,`reLaunch:ok`)}async function oe(e,t,n,r,i,a){let{pagePath:o}=R(i.params.url);if(!o){a(!1,`switchTab:fail invalid url`);return}if(!e.getTabBarConfig()?.list.some(e=>F(e.pagePath)===o)){a(!1,`switchTab:fail not a tabBar page: ${o}`);return}let s=t.current.shell.tabStacks[o],c=null;if(!s||s.length===0){let t=await e.openPage(o,{});c={bridgeId:t.bridgeId,pagePath:t.pagePath,query:{},isTab:!0,windowConfig:t.windowConfig,navBar:q(t.windowConfig,e.appId)}}let{next:l,effects:u}=G(t.current.shell,o,c);n(e=>({...e,shell:l})),r(u),a(!0,`switchTab:ok`)}export{te as DeviceShell};
|
|
2
|
+
//# sourceMappingURL=device-shell-CiLAPa0I.js.map
|