@dimina-kit/devtools 0.3.2-dev.20260601115343 → 0.3.2-dev.20260610114009
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +49 -59
- package/dist/main/api.d.ts +1 -2
- package/dist/main/api.js +5 -1
- package/dist/main/app/app.d.ts +15 -5
- package/dist/main/app/app.js +249 -122
- package/dist/main/app/bootstrap.d.ts +16 -0
- package/dist/main/app/bootstrap.js +20 -0
- package/dist/main/app/launch.d.ts +8 -4
- package/dist/main/app/launch.js +9 -4
- package/dist/main/index.bundle.js +6071 -1863
- package/dist/main/index.js +9 -1
- package/dist/main/ipc/app.d.ts +1 -1
- package/dist/main/ipc/bridge-router.d.ts +61 -0
- package/dist/main/ipc/bridge-router.js +1333 -0
- package/dist/main/ipc/panels.d.ts +1 -1
- package/dist/main/ipc/panels.js +6 -2
- package/dist/main/ipc/popover.d.ts +1 -1
- package/dist/main/ipc/project-fs.d.ts +1 -1
- package/dist/main/ipc/projects.d.ts +1 -1
- package/dist/main/ipc/session.d.ts +1 -1
- package/dist/main/ipc/settings.d.ts +1 -1
- package/dist/main/ipc/simulator-module.d.ts +6 -0
- package/dist/main/ipc/simulator-module.js +9 -1
- package/dist/main/ipc/simulator.d.ts +2 -2
- package/dist/main/ipc/simulator.js +29 -5
- package/dist/main/ipc/toolbar.d.ts +1 -1
- package/dist/main/ipc/views.d.ts +1 -1
- package/dist/main/ipc/views.js +40 -2
- package/dist/main/runtime/devtools-backend.d.ts +17 -0
- package/dist/main/runtime/devtools-backend.js +49 -0
- package/dist/main/runtime/miniapp-runtime.d.ts +39 -0
- package/dist/main/runtime/miniapp-runtime.js +17 -0
- package/dist/main/services/automation/exec.d.ts +27 -2
- package/dist/main/services/automation/exec.js +37 -3
- package/dist/main/services/automation/handlers/app.js +127 -11
- package/dist/main/services/automation/handlers/page.js +36 -19
- package/dist/main/services/automation/index.js +40 -13
- package/dist/main/services/automation/wait-active-page.d.ts +56 -0
- package/dist/main/services/automation/wait-active-page.js +71 -0
- package/dist/main/services/console-forward/index.d.ts +36 -0
- package/dist/main/services/console-forward/index.js +81 -0
- package/dist/main/services/dimina-resource-server.d.ts +7 -0
- package/dist/main/services/dimina-resource-server.js +99 -0
- package/dist/main/services/elements-forward/index.d.ts +66 -0
- package/dist/main/services/elements-forward/index.js +583 -0
- package/dist/main/services/layout/index.d.ts +22 -0
- package/dist/main/services/layout/index.js +25 -0
- package/dist/main/services/mcp/index.d.ts +1 -0
- package/dist/main/services/mcp/index.js +3 -0
- package/dist/main/services/mcp/server.d.ts +1 -1
- package/dist/main/services/mcp/server.js +1 -1
- package/dist/main/services/mcp/target-manager.d.ts +35 -0
- package/dist/main/services/mcp/target-manager.js +63 -1
- package/dist/main/services/mcp/tools/context-tools.js +15 -1
- package/dist/main/services/module.d.ts +1 -1
- package/dist/main/services/network-forward/index.d.ts +190 -0
- package/dist/main/services/network-forward/index.js +765 -0
- package/dist/main/services/notifications/renderer-notifier.d.ts +11 -0
- package/dist/main/services/notifications/renderer-notifier.js +7 -1
- package/dist/main/services/render-inspect/index.d.ts +41 -0
- package/dist/main/services/render-inspect/index.js +88 -0
- package/dist/main/services/safe-area/index.d.ts +17 -0
- package/dist/main/services/safe-area/index.js +59 -0
- package/dist/main/services/service-host-pool/pool.d.ts +197 -0
- package/dist/main/services/service-host-pool/pool.js +364 -0
- package/dist/main/services/simulator/custom-apis.d.ts +34 -0
- package/dist/main/services/simulator/custom-apis.js +22 -0
- package/dist/main/services/simulator-appdata/index.d.ts +35 -0
- package/dist/main/services/simulator-appdata/index.js +71 -0
- package/dist/main/services/simulator-current-page/index.d.ts +24 -0
- package/dist/main/services/simulator-current-page/index.js +19 -0
- package/dist/main/services/simulator-storage/index.d.ts +37 -2
- package/dist/main/services/simulator-storage/index.js +209 -32
- package/dist/main/services/simulator-storage/service-storage-ops.d.ts +40 -0
- package/dist/main/services/simulator-storage/service-storage-ops.js +67 -0
- package/dist/main/services/simulator-temp-files/index.d.ts +1 -1
- package/dist/main/services/simulator-temp-files/index.js +39 -17
- package/dist/main/services/simulator-wxml/index.d.ts +29 -0
- package/dist/main/services/simulator-wxml/index.js +28 -0
- package/dist/main/services/toolbar/toolbar-store.d.ts +3 -3
- package/dist/main/services/toolbar/toolbar-store.js +1 -18
- package/dist/main/services/views/devtools-tabs.d.ts +47 -0
- package/dist/main/services/views/devtools-tabs.js +95 -0
- package/dist/main/services/views/miniapp-partition.d.ts +80 -0
- package/dist/main/services/views/miniapp-partition.js +138 -0
- package/dist/main/services/views/simulator-session-policy.d.ts +28 -0
- package/dist/main/services/views/simulator-session-policy.js +82 -0
- package/dist/main/services/views/view-manager.d.ts +125 -0
- package/dist/main/services/views/view-manager.js +852 -4
- package/dist/main/services/workbench-context.d.ts +67 -7
- package/dist/main/services/workbench-context.js +6 -1
- package/dist/main/services/workspace/workspace-service.js +7 -13
- package/dist/main/utils/ipc-registry.d.ts +1 -1
- package/dist/main/utils/ipc-registry.js +21 -4
- package/dist/main/utils/paths.d.ts +15 -0
- package/dist/main/utils/paths.js +19 -0
- package/dist/main/utils/sender-policy.d.ts +9 -3
- package/dist/main/utils/sender-policy.js +18 -4
- package/dist/main/utils/theme.d.ts +1 -1
- package/dist/main/utils/theme.js +1 -1
- package/dist/main/windows/main-window/create.d.ts +0 -6
- package/dist/main/windows/main-window/create.js +6 -80
- package/dist/main/windows/main-window/events.d.ts +1 -1
- package/dist/main/windows/main-window/events.js +1 -1
- package/dist/main/windows/service-host-window/create.d.ts +67 -0
- package/dist/main/windows/service-host-window/create.js +138 -0
- package/dist/native-host/common/common.js +368 -0
- package/dist/native-host/container/pageFrame.css +1 -0
- package/dist/native-host/render/render.js +9334 -0
- package/dist/native-host/service/service.js +6 -0
- package/dist/preload/index.d.ts +2 -0
- package/dist/preload/index.js +6 -0
- package/dist/preload/instrumentation/app-data.d.ts +18 -20
- package/dist/preload/instrumentation/app-data.js +23 -160
- package/dist/preload/instrumentation/wxml-extract.d.ts +1 -1
- package/dist/preload/instrumentation/wxml-extract.js +1 -1
- package/dist/preload/runtime/bridge.d.ts +3 -8
- package/dist/preload/runtime/bridge.js +2 -32
- package/dist/preload/runtime/custom-apis.js +20 -17
- package/dist/preload/runtime/host-toolbar-advertiser.d.ts +27 -0
- package/dist/preload/runtime/host-toolbar-advertiser.js +55 -0
- package/dist/preload/runtime/main-api-runner.d.ts +9 -0
- package/dist/preload/runtime/main-api-runner.js +85 -0
- package/dist/preload/runtime/native-host.d.ts +43 -0
- package/dist/preload/runtime/native-host.js +83 -0
- package/dist/preload/shared/expose.d.ts +10 -5
- package/dist/preload/shared/expose.js +30 -12
- package/dist/preload/shared/sid-registry.d.ts +11 -0
- package/dist/preload/shared/sid-registry.js +38 -0
- package/dist/preload/windows/host-toolbar.cjs +161 -0
- package/dist/preload/windows/host-toolbar.cjs.map +7 -0
- package/dist/preload/windows/host-toolbar.d.ts +2 -0
- package/dist/preload/windows/host-toolbar.js +12 -0
- package/dist/preload/windows/main.cjs +1935 -0
- package/dist/preload/windows/main.cjs.map +4 -4
- package/dist/preload/windows/simulator.cjs +925 -0
- package/dist/preload/windows/simulator.cjs.map +7 -0
- package/dist/preload/windows/simulator.js +244 -574
- package/dist/render-host/pageFrame.html +29 -0
- package/dist/render-host/preload.cjs +154 -0
- package/dist/render-host/render-inspect.js +295 -0
- package/dist/renderer/assets/index-CcJKzatF.js +50 -0
- package/dist/renderer/assets/{input-CCYS8Ave.js → input-QGx6FFX1.js} +2 -2
- package/dist/renderer/assets/ipc-transport-BT4QYQqu.css +1 -0
- package/dist/renderer/assets/{ipc-transport-Bn4KXvhu.js → ipc-transport-DvZvwK-Z.js} +2 -2
- package/dist/renderer/assets/{popover-CH4rwpdt.js → popover-BOH1If1J.js} +2 -2
- package/dist/renderer/assets/select-C7JQ8G5N.js +2 -0
- package/dist/renderer/assets/{settings-CMTB-t0x.js → settings-DpAbTJyF.js} +2 -2
- package/dist/renderer/assets/{settings-api-Csdngf9Z.js → settings-api-RD2IZF53.js} +2 -2
- package/dist/renderer/assets/{workbenchSettings-CODFCzOg.js → workbenchSettings-CNJX4Qna.js} +2 -2
- package/dist/renderer/entries/main/index.html +5 -5
- package/dist/renderer/entries/popover/index.html +5 -5
- package/dist/renderer/entries/settings/index.html +5 -5
- package/dist/renderer/entries/workbench-settings/index.html +4 -4
- package/dist/service-host/preload.cjs +254 -0
- package/dist/service-host/service.html +10 -0
- package/dist/service-host/sourcemap-rewrite.cjs +58 -0
- package/dist/service-host/sync-api-patch.js +20 -0
- package/dist/service-host/sync-impls/menu-button-geometry.js +8 -0
- package/dist/service-host/sync-impls/menu-button.js +16 -0
- package/dist/service-host/sync-impls/storage.js +50 -0
- package/dist/service-host/sync-impls/system-info.js +54 -0
- package/dist/shared/appdata-accumulator.d.ts +95 -0
- package/dist/shared/appdata-accumulator.js +213 -0
- package/dist/shared/bridge-channels.d.ts +378 -0
- package/dist/shared/bridge-channels.js +81 -0
- package/dist/shared/ipc-channels.d.ts +84 -1
- package/dist/shared/ipc-channels.js +90 -10
- package/dist/shared/ipc-schemas.d.ts +59 -2
- package/dist/shared/ipc-schemas.js +64 -3
- package/dist/shared/open-in-editor.d.ts +71 -0
- package/dist/shared/open-in-editor.js +138 -0
- package/dist/shared/simulator-api-metadata.d.ts +21 -0
- package/dist/shared/simulator-api-metadata.js +23 -0
- package/dist/shared/types.d.ts +2 -39
- package/dist/simulator/assets/device-shell-DsdcNEkt.css +1 -0
- package/dist/simulator/assets/device-shell-fH2cI-3q.js +2 -0
- package/dist/simulator/assets/jsx-runtime-P6ZegaOf.js +2 -0
- package/dist/simulator/assets/simulator-DHylZf9Z.js +10 -0
- package/dist/simulator/assets/simulator-mini-app-BDNu5n26.js +2 -0
- package/dist/simulator/device-shell/menu-button-geometry.js +8 -0
- package/dist/simulator/simulator.html +2 -112
- package/package.json +12 -12
- package/dist/main/utils/disposable.d.ts +0 -18
- package/dist/main/utils/disposable.js +0 -67
- package/dist/renderer/assets/index-BDMxXUfn.js +0 -50
- package/dist/renderer/assets/ipc-transport-Cu7tubyg.css +0 -1
- package/dist/renderer/assets/select-Ct4-sijm.js +0 -2
- package/dist/simulator/assets/simulator-B4e3c6_O.js +0 -9
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Customize the embedded Chrome DevTools front-end's panel tab bar.
|
|
3
|
+
*
|
|
4
|
+
* The right-panel DevTools (a WebContents rendering `devtools://`, attached to the
|
|
5
|
+
* service-host via `setDevToolsWebContents` + `openDevTools`) shows ALL its panels
|
|
6
|
+
* by default. For the mini-app workflow only Elements / Console / Network are
|
|
7
|
+
* meaningful in the default tab bar — but we do NOT want to delete the rest: they
|
|
8
|
+
* stay reachable on demand via the command menu (Cmd+Shift+P → "Show Sources" …).
|
|
9
|
+
*
|
|
10
|
+
* ── How (registry, not DOM) ─────────────────────────────────────────────────
|
|
11
|
+
* The modern ESM DevTools front-end does NOT expose `UI.ViewManager` on
|
|
12
|
+
* `globalThis`, so the tab bar can't be driven through the view manager. Panels
|
|
13
|
+
* register themselves via `registerViewExtension({id, location:'panel', persistence})`
|
|
14
|
+
* into a module-level registry; the official mutators are `registerViewExtension`,
|
|
15
|
+
* `getRegisteredViewExtensions` and `maybeRemoveViewExtension`. We:
|
|
16
|
+
* 1. `import('./ui/legacy/legacy.js')` to reach those functions (the real export
|
|
17
|
+
* path on Electron 41 / Chromium ~138, verified at runtime);
|
|
18
|
+
* 2. whitelist-patch `registerViewExtension` so any future non-kept panel comes
|
|
19
|
+
* in with `persistence:'transient'` (hidden from the default bar);
|
|
20
|
+
* 3. for the already-registered non-kept panels, `maybeRemoveViewExtension(id)`
|
|
21
|
+
* then re-register a copy with `persistence:'transient'`.
|
|
22
|
+
* Transient views are not shown in the default tab bar but stay in the command
|
|
23
|
+
* menu — and because this is DevTools' own panel path, there is NO `>>` overflow
|
|
24
|
+
* or `×` close-button residue (which a DOM `display:none` hack leaves behind).
|
|
25
|
+
*
|
|
26
|
+
* ── Locale infobar ──────────────────────────────────────────────────────────
|
|
27
|
+
* The "DevTools is now available in 中文" banner is suppressed via the official
|
|
28
|
+
* host preference `disable-locale-info-bar` (a GLOBAL setting that lives in host
|
|
29
|
+
* preferences, NOT page localStorage), set through `InspectorFrontendHost.setPreference`.
|
|
30
|
+
*
|
|
31
|
+
* ── Degradation ─────────────────────────────────────────────────────────────
|
|
32
|
+
* If the ESM module can't be resolved, a bounded DOM `display:none` fallback hides
|
|
33
|
+
* the non-kept tabs (by visible name) so the bar still looks right. Everything is
|
|
34
|
+
* wrapped in try/catch in the injected realm and silently no-ops on any failure.
|
|
35
|
+
*/
|
|
36
|
+
/**
|
|
37
|
+
* Canonical DevTools panel view ids kept in the DEFAULT tab bar (stable front-end
|
|
38
|
+
* ids, unchanged for many Chromium releases): `elements`, `console`, `network`.
|
|
39
|
+
*/
|
|
40
|
+
export declare const DEVTOOLS_KEPT_VIEW_IDS: readonly string[];
|
|
41
|
+
/**
|
|
42
|
+
* Build the `executeJavaScript` source injected into the DevTools front-end
|
|
43
|
+
* WebContents. The kept ids + display names are carried as JSON data literals
|
|
44
|
+
* (never interpolated as bare code), same discipline as the other injectors.
|
|
45
|
+
*/
|
|
46
|
+
export declare function buildCustomizeTabsScript(keptIds?: readonly string[]): string;
|
|
47
|
+
//# sourceMappingURL=devtools-tabs.d.ts.map
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Customize the embedded Chrome DevTools front-end's panel tab bar.
|
|
3
|
+
*
|
|
4
|
+
* The right-panel DevTools (a WebContents rendering `devtools://`, attached to the
|
|
5
|
+
* service-host via `setDevToolsWebContents` + `openDevTools`) shows ALL its panels
|
|
6
|
+
* by default. For the mini-app workflow only Elements / Console / Network are
|
|
7
|
+
* meaningful in the default tab bar — but we do NOT want to delete the rest: they
|
|
8
|
+
* stay reachable on demand via the command menu (Cmd+Shift+P → "Show Sources" …).
|
|
9
|
+
*
|
|
10
|
+
* ── How (registry, not DOM) ─────────────────────────────────────────────────
|
|
11
|
+
* The modern ESM DevTools front-end does NOT expose `UI.ViewManager` on
|
|
12
|
+
* `globalThis`, so the tab bar can't be driven through the view manager. Panels
|
|
13
|
+
* register themselves via `registerViewExtension({id, location:'panel', persistence})`
|
|
14
|
+
* into a module-level registry; the official mutators are `registerViewExtension`,
|
|
15
|
+
* `getRegisteredViewExtensions` and `maybeRemoveViewExtension`. We:
|
|
16
|
+
* 1. `import('./ui/legacy/legacy.js')` to reach those functions (the real export
|
|
17
|
+
* path on Electron 41 / Chromium ~138, verified at runtime);
|
|
18
|
+
* 2. whitelist-patch `registerViewExtension` so any future non-kept panel comes
|
|
19
|
+
* in with `persistence:'transient'` (hidden from the default bar);
|
|
20
|
+
* 3. for the already-registered non-kept panels, `maybeRemoveViewExtension(id)`
|
|
21
|
+
* then re-register a copy with `persistence:'transient'`.
|
|
22
|
+
* Transient views are not shown in the default tab bar but stay in the command
|
|
23
|
+
* menu — and because this is DevTools' own panel path, there is NO `>>` overflow
|
|
24
|
+
* or `×` close-button residue (which a DOM `display:none` hack leaves behind).
|
|
25
|
+
*
|
|
26
|
+
* ── Locale infobar ──────────────────────────────────────────────────────────
|
|
27
|
+
* The "DevTools is now available in 中文" banner is suppressed via the official
|
|
28
|
+
* host preference `disable-locale-info-bar` (a GLOBAL setting that lives in host
|
|
29
|
+
* preferences, NOT page localStorage), set through `InspectorFrontendHost.setPreference`.
|
|
30
|
+
*
|
|
31
|
+
* ── Degradation ─────────────────────────────────────────────────────────────
|
|
32
|
+
* If the ESM module can't be resolved, a bounded DOM `display:none` fallback hides
|
|
33
|
+
* the non-kept tabs (by visible name) so the bar still looks right. Everything is
|
|
34
|
+
* wrapped in try/catch in the injected realm and silently no-ops on any failure.
|
|
35
|
+
*/
|
|
36
|
+
/**
|
|
37
|
+
* Canonical DevTools panel view ids kept in the DEFAULT tab bar (stable front-end
|
|
38
|
+
* ids, unchanged for many Chromium releases): `elements`, `console`, `network`.
|
|
39
|
+
*/
|
|
40
|
+
export const DEVTOOLS_KEPT_VIEW_IDS = ['elements', 'console', 'network'];
|
|
41
|
+
/**
|
|
42
|
+
* Build the `executeJavaScript` source injected into the DevTools front-end
|
|
43
|
+
* WebContents. The kept ids + display names are carried as JSON data literals
|
|
44
|
+
* (never interpolated as bare code), same discipline as the other injectors.
|
|
45
|
+
*/
|
|
46
|
+
export function buildCustomizeTabsScript(keptIds = DEVTOOLS_KEPT_VIEW_IDS) {
|
|
47
|
+
// Kept panels are matched by view id (registry path) and by visible NAME (DOM
|
|
48
|
+
// fallback path); the DevTools UI may be EN or ZH, so include both.
|
|
49
|
+
const NAME_MAP = {
|
|
50
|
+
elements: ['Elements', '元素'], console: ['Console', '控制台'], network: ['Network', '网络'],
|
|
51
|
+
};
|
|
52
|
+
const keepNames = keptIds.flatMap((id) => NAME_MAP[id] ?? [id]);
|
|
53
|
+
const keepIdsJson = JSON.stringify(JSON.stringify([...keptIds]));
|
|
54
|
+
const keepNamesJson = JSON.stringify(JSON.stringify(keepNames));
|
|
55
|
+
return `(function(){try{
|
|
56
|
+
var KEEPID = new Set(JSON.parse(${keepIdsJson}));
|
|
57
|
+
var KEEPNAME = new Set(JSON.parse(${keepNamesJson}));
|
|
58
|
+
// (1) Locale infobar — official host-preference suppression (NOT localStorage).
|
|
59
|
+
try { var IFH=globalThis.InspectorFrontendHost; if(IFH&&typeof IFH.setPreference==='function'){ IFH.setPreference('disable-locale-info-bar','true'); } }catch(_){}
|
|
60
|
+
function deepCollect(sel,cap){ var out=[],seen=0,stack=[document]; while(stack.length&&seen<(cap||40000)){ var root=stack.pop(); try{var m=root.querySelectorAll?root.querySelectorAll(sel):[];for(var i=0;i<m.length;i++)out.push(m[i]);}catch(_){} try{var all=root.querySelectorAll?root.querySelectorAll('*'):[];for(var j=0;j<all.length;j++){seen++;if(all[j].shadowRoot)stack.push(all[j].shadowRoot);}}catch(_){} } return out; }
|
|
61
|
+
function txt(el){ return ((el&&el.textContent)||'').replace(/\\s+/g,' ').trim(); }
|
|
62
|
+
var PATHS=['./ui/legacy/legacy.js','./ui/legacy/ViewManager.js','devtools://devtools/bundled/ui/legacy/legacy.js'];
|
|
63
|
+
(async function(){
|
|
64
|
+
var VM=null,maybeRemove=null,origReg=null,reg=null,getReg=null;
|
|
65
|
+
for(var i=0;i<PATHS.length;i++){ try{ var m=await import(PATHS[i]); if(!m)continue; var v=m.ViewManager||m;
|
|
66
|
+
var mr=(v&&typeof v.maybeRemoveViewExtension==='function')?v.maybeRemoveViewExtension.bind(v):(typeof m.maybeRemoveViewExtension==='function'?m.maybeRemoveViewExtension:null);
|
|
67
|
+
if(mr){ VM=v;maybeRemove=mr;
|
|
68
|
+
origReg=(v&&typeof v.registerViewExtension==='function')?v.registerViewExtension:m.registerViewExtension; reg=origReg;
|
|
69
|
+
getReg=(v&&typeof v.getRegisteredViewExtensions==='function')?v.getRegisteredViewExtensions.bind(v):(typeof m.getRegisteredViewExtensions==='function'?m.getRegisteredViewExtensions:null);
|
|
70
|
+
break; } }catch(_){} }
|
|
71
|
+
if(maybeRemove){
|
|
72
|
+
// (2) future non-kept panels register as transient
|
|
73
|
+
try{ if(origReg&&VM){ VM.registerViewExtension=function(r){ try{ if(r&&String(r.location)==='panel'&&!KEEPID.has(r.id)){ r.persistence='transient'; } }catch(_){} return origReg.apply(this,arguments); }; reg=VM.registerViewExtension; } }catch(_){}
|
|
74
|
+
// (3) already-registered non-kept panels -> remove + re-register transient
|
|
75
|
+
var exts=[]; try{ if(getReg) exts=getReg()||[]; }catch(_){}
|
|
76
|
+
var handled=false;
|
|
77
|
+
for(var e=0;e<exts.length;e++){ try{ var ex=exts[e]; var eid=ex&&ex.id; if(!eid||KEEPID.has(eid)) continue; if(String(ex.location)!=='panel') continue;
|
|
78
|
+
maybeRemove(eid);
|
|
79
|
+
var nr={}; try{ nr=Object.assign({},ex); }catch(_){ for(var k in ex){ try{nr[k]=ex[k];}catch(__){} } }
|
|
80
|
+
nr.persistence='transient';
|
|
81
|
+
try{ reg(nr); }catch(_){ try{ origReg(nr); }catch(__){} }
|
|
82
|
+
handled=true;
|
|
83
|
+
}catch(_){} }
|
|
84
|
+
// fallback: registrations not enumerable -> at least clear the bar by id
|
|
85
|
+
if(!handled){ var FALL=['timeline','resources','heap-profiler','sources','security','lighthouse','chrome-recorder','coverage','linear-memory-inspector','sensors','rendering','animations','autofill-view','medias','issues-pane']; for(var fr=0;fr<FALL.length;fr++){ try{ if(!KEEPID.has(FALL[fr])) maybeRemove(FALL[fr]); }catch(_){} } }
|
|
86
|
+
} else { domFallback(); }
|
|
87
|
+
})();
|
|
88
|
+
// DOM fallback: only if the ESM module couldn't be resolved at all.
|
|
89
|
+
function domFallback(){ var cachedBar=null;
|
|
90
|
+
function findBar(){ if(cachedBar&&cachedBar.isConnected)return cachedBar; cachedBar=null; var tabs=deepCollect('[role="tab"]'); var a=null; for(var i=0;i<tabs.length;i++){if(KEEPNAME.has(txt(tabs[i]))){a=tabs[i];break;}} if(!a)return null; var p=a.parentElement; while(p){try{if(p.querySelectorAll('[role="tab"]').length>1){cachedBar=p;return p;}}catch(_){} p=p.parentElement;} cachedBar=a.parentElement; return cachedBar; }
|
|
91
|
+
function apply(){ try{ var bar=findBar(); if(bar){ var bts=bar.querySelectorAll('[role="tab"]'); for(var b=0;b<bts.length;b++){var bt=bts[b]; if(KEEPNAME.has(txt(bt)))continue; try{if(bt.style)bt.style.display='none';}catch(_){}} try{var more=bar.querySelector('[aria-label*="More tabs"],.tabbed-pane-header-tabs-drop-down-container'); if(more&&more.style)more.style.display='none';}catch(_){} } }catch(_){} }
|
|
92
|
+
var tr=0,t=setInterval(function(){tr++;try{apply();}catch(_){}if(tr>120)clearInterval(t);},60); try{apply();}catch(_){} }
|
|
93
|
+
}catch(_){}})()`;
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=devtools-tabs.js.map
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-project session partition for the native-host miniapp runtime (P0 debt).
|
|
3
|
+
*
|
|
4
|
+
* Historically every project's miniapp webContents — the simulator content
|
|
5
|
+
* WebContentsView, its nested render-host `<webview>` guests, AND the
|
|
6
|
+
* service-host window — shared ONE hard-coded `persist:simulator` Electron
|
|
7
|
+
* session. Cookies / localStorage / cache / IndexedDB written by project A were
|
|
8
|
+
* visible to (and clobbered by) project B; two projects open at once cross-
|
|
9
|
+
* contaminate and "clear storage" on one nukes the other.
|
|
10
|
+
*
|
|
11
|
+
* The fix derives a STABLE per-project partition from the project identity (the
|
|
12
|
+
* miniapp `appId`, which flows in via the simulator URL `?appId=` and the spawn
|
|
13
|
+
* path's `appId`). Same project → same partition (storage survives a relaunch);
|
|
14
|
+
* different projects → different partitions (no cross-contamination). The shape
|
|
15
|
+
* mirrors the IDE state of the art (WeChat's static partition, ByteDance's
|
|
16
|
+
* `persist:miniapp-<id>` dynamic partition).
|
|
17
|
+
*
|
|
18
|
+
* The protocol handlers (`difile://`, `dmb-resource`) and webRequest policies
|
|
19
|
+
* (referer / CORS) that the simulator runtime needs were installed once on the
|
|
20
|
+
* single `persist:simulator` session. With per-project partitions those have to
|
|
21
|
+
* be (re)applied to EACH project session the first time it is used. The setup
|
|
22
|
+
* sites register a partition-agnostic configurator here; `configureMiniappSession`
|
|
23
|
+
* runs every registered configurator exactly once per partition.
|
|
24
|
+
*
|
|
25
|
+
* Partition CLEANUP (reclaiming on-disk `persist:` data) is intentionally NOT
|
|
26
|
+
* done here — leaving the data on disk is the whole point of a `persist:`
|
|
27
|
+
* partition (cache/storage survives a relaunch). That is a separate concern.
|
|
28
|
+
*/
|
|
29
|
+
import type { Session } from 'electron';
|
|
30
|
+
/** The legacy single-session partition. Still used by the pre-warm pool (which
|
|
31
|
+
* is intentionally NOT isolation-aware — see `serviceHostSpec`) and as the
|
|
32
|
+
* fallback when a project key cannot be derived. */
|
|
33
|
+
export declare const SHARED_MINIAPP_PARTITION = "persist:simulator";
|
|
34
|
+
/**
|
|
35
|
+
* Derive a stable, filesystem-safe partition key from a project `appId`.
|
|
36
|
+
*
|
|
37
|
+
* `appId` is the project identity (e.g. a `wxapp…` id). We pass through the
|
|
38
|
+
* characters Electron is happy to put in a session partition / on-disk folder
|
|
39
|
+
* name (`[A-Za-z0-9_-]`) verbatim so the common case is human-legible, and fold
|
|
40
|
+
* anything else into a short deterministic hash suffix so two appIds that differ
|
|
41
|
+
* only in stripped characters never collide. The same `appId` always yields the
|
|
42
|
+
* same key (so storage survives a relaunch); different `appId`s yield different
|
|
43
|
+
* keys.
|
|
44
|
+
*/
|
|
45
|
+
export declare function miniappPartitionKey(appId: string): string;
|
|
46
|
+
/**
|
|
47
|
+
* The Electron session partition for a project. Returns the SHARED partition
|
|
48
|
+
* when `appId` is empty/unknown (so the runtime still has a session to load on,
|
|
49
|
+
* matching the legacy behavior) and a `persist:miniapp-<key>` partition
|
|
50
|
+
* otherwise.
|
|
51
|
+
*/
|
|
52
|
+
export declare function miniappPartition(appId: string | null | undefined): string;
|
|
53
|
+
type SessionConfigurator = (sess: Session, partition: string) => void;
|
|
54
|
+
/**
|
|
55
|
+
* Register a configurator that runs against every miniapp partition session.
|
|
56
|
+
* Already-configured partitions are (re)configured immediately so registration
|
|
57
|
+
* order does not matter. Returns a disposer that unregisters the configurator
|
|
58
|
+
* (it does not undo work already applied to live sessions).
|
|
59
|
+
*/
|
|
60
|
+
export declare function registerMiniappSessionConfigurator(fn: SessionConfigurator): () => void;
|
|
61
|
+
/**
|
|
62
|
+
* Ensure a partition's session has every registered configurator applied. Safe
|
|
63
|
+
* to call repeatedly per partition (idempotent — each partition is configured
|
|
64
|
+
* once). Call this before loading project content on `partition`.
|
|
65
|
+
*
|
|
66
|
+
* Returns `null` when there is nothing to configure (no configurator registered)
|
|
67
|
+
* so the partition derivation stays independent of any live Electron session —
|
|
68
|
+
* the partition is a constructor-time fact, not a side effect of touching the
|
|
69
|
+
* session API. Setup sites register configurators at app boot; in unit tests
|
|
70
|
+
* that mock `electron` without a `session` export this short-circuits cleanly.
|
|
71
|
+
*/
|
|
72
|
+
export declare function configureMiniappSession(partition: string): Session | null;
|
|
73
|
+
/**
|
|
74
|
+
* Test-only: drop the configurator + configured-partition bookkeeping so each
|
|
75
|
+
* test starts from a clean slate. (Module-level state otherwise leaks across
|
|
76
|
+
* unit tests that mock `electron`.)
|
|
77
|
+
*/
|
|
78
|
+
export declare function __resetMiniappSessionConfigForTests(): void;
|
|
79
|
+
export {};
|
|
80
|
+
//# sourceMappingURL=miniapp-partition.d.ts.map
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-project session partition for the native-host miniapp runtime (P0 debt).
|
|
3
|
+
*
|
|
4
|
+
* Historically every project's miniapp webContents — the simulator content
|
|
5
|
+
* WebContentsView, its nested render-host `<webview>` guests, AND the
|
|
6
|
+
* service-host window — shared ONE hard-coded `persist:simulator` Electron
|
|
7
|
+
* session. Cookies / localStorage / cache / IndexedDB written by project A were
|
|
8
|
+
* visible to (and clobbered by) project B; two projects open at once cross-
|
|
9
|
+
* contaminate and "clear storage" on one nukes the other.
|
|
10
|
+
*
|
|
11
|
+
* The fix derives a STABLE per-project partition from the project identity (the
|
|
12
|
+
* miniapp `appId`, which flows in via the simulator URL `?appId=` and the spawn
|
|
13
|
+
* path's `appId`). Same project → same partition (storage survives a relaunch);
|
|
14
|
+
* different projects → different partitions (no cross-contamination). The shape
|
|
15
|
+
* mirrors the IDE state of the art (WeChat's static partition, ByteDance's
|
|
16
|
+
* `persist:miniapp-<id>` dynamic partition).
|
|
17
|
+
*
|
|
18
|
+
* The protocol handlers (`difile://`, `dmb-resource`) and webRequest policies
|
|
19
|
+
* (referer / CORS) that the simulator runtime needs were installed once on the
|
|
20
|
+
* single `persist:simulator` session. With per-project partitions those have to
|
|
21
|
+
* be (re)applied to EACH project session the first time it is used. The setup
|
|
22
|
+
* sites register a partition-agnostic configurator here; `configureMiniappSession`
|
|
23
|
+
* runs every registered configurator exactly once per partition.
|
|
24
|
+
*
|
|
25
|
+
* Partition CLEANUP (reclaiming on-disk `persist:` data) is intentionally NOT
|
|
26
|
+
* done here — leaving the data on disk is the whole point of a `persist:`
|
|
27
|
+
* partition (cache/storage survives a relaunch). That is a separate concern.
|
|
28
|
+
*/
|
|
29
|
+
import * as electron from 'electron';
|
|
30
|
+
/** The legacy single-session partition. Still used by the pre-warm pool (which
|
|
31
|
+
* is intentionally NOT isolation-aware — see `serviceHostSpec`) and as the
|
|
32
|
+
* fallback when a project key cannot be derived. */
|
|
33
|
+
export const SHARED_MINIAPP_PARTITION = 'persist:simulator';
|
|
34
|
+
const PARTITION_PREFIX = 'persist:miniapp-';
|
|
35
|
+
/**
|
|
36
|
+
* Derive a stable, filesystem-safe partition key from a project `appId`.
|
|
37
|
+
*
|
|
38
|
+
* `appId` is the project identity (e.g. a `wxapp…` id). We pass through the
|
|
39
|
+
* characters Electron is happy to put in a session partition / on-disk folder
|
|
40
|
+
* name (`[A-Za-z0-9_-]`) verbatim so the common case is human-legible, and fold
|
|
41
|
+
* anything else into a short deterministic hash suffix so two appIds that differ
|
|
42
|
+
* only in stripped characters never collide. The same `appId` always yields the
|
|
43
|
+
* same key (so storage survives a relaunch); different `appId`s yield different
|
|
44
|
+
* keys.
|
|
45
|
+
*/
|
|
46
|
+
export function miniappPartitionKey(appId) {
|
|
47
|
+
const safe = appId.replace(/[^A-Za-z0-9_-]/g, '');
|
|
48
|
+
// Folding may have dropped distinguishing characters; if the input was not
|
|
49
|
+
// already fully safe, append a deterministic hash of the RAW appId so two
|
|
50
|
+
// distinct appIds can never alias onto the same key.
|
|
51
|
+
if (safe === appId && safe.length > 0)
|
|
52
|
+
return safe;
|
|
53
|
+
const hash = djb2(appId).toString(36);
|
|
54
|
+
return safe.length > 0 ? `${safe}-${hash}` : hash;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* The Electron session partition for a project. Returns the SHARED partition
|
|
58
|
+
* when `appId` is empty/unknown (so the runtime still has a session to load on,
|
|
59
|
+
* matching the legacy behavior) and a `persist:miniapp-<key>` partition
|
|
60
|
+
* otherwise.
|
|
61
|
+
*/
|
|
62
|
+
export function miniappPartition(appId) {
|
|
63
|
+
if (!appId)
|
|
64
|
+
return SHARED_MINIAPP_PARTITION;
|
|
65
|
+
return `${PARTITION_PREFIX}${miniappPartitionKey(appId)}`;
|
|
66
|
+
}
|
|
67
|
+
/** Small, stable string hash (djb2). Not cryptographic — only needs to be
|
|
68
|
+
* deterministic and collision-resistant enough to disambiguate appIds. */
|
|
69
|
+
function djb2(input) {
|
|
70
|
+
let h = 5381;
|
|
71
|
+
for (let i = 0; i < input.length; i++) {
|
|
72
|
+
h = ((h << 5) + h + input.charCodeAt(i)) >>> 0;
|
|
73
|
+
}
|
|
74
|
+
return h;
|
|
75
|
+
}
|
|
76
|
+
const configurators = new Set();
|
|
77
|
+
const configuredPartitions = new Set();
|
|
78
|
+
/**
|
|
79
|
+
* Register a configurator that runs against every miniapp partition session.
|
|
80
|
+
* Already-configured partitions are (re)configured immediately so registration
|
|
81
|
+
* order does not matter. Returns a disposer that unregisters the configurator
|
|
82
|
+
* (it does not undo work already applied to live sessions).
|
|
83
|
+
*/
|
|
84
|
+
export function registerMiniappSessionConfigurator(fn) {
|
|
85
|
+
configurators.add(fn);
|
|
86
|
+
for (const partition of configuredPartitions) {
|
|
87
|
+
try {
|
|
88
|
+
fn(electron.session.fromPartition(partition), partition);
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
console.warn('[miniapp-partition] configurator failed for', partition, err);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return () => {
|
|
95
|
+
configurators.delete(fn);
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Ensure a partition's session has every registered configurator applied. Safe
|
|
100
|
+
* to call repeatedly per partition (idempotent — each partition is configured
|
|
101
|
+
* once). Call this before loading project content on `partition`.
|
|
102
|
+
*
|
|
103
|
+
* Returns `null` when there is nothing to configure (no configurator registered)
|
|
104
|
+
* so the partition derivation stays independent of any live Electron session —
|
|
105
|
+
* the partition is a constructor-time fact, not a side effect of touching the
|
|
106
|
+
* session API. Setup sites register configurators at app boot; in unit tests
|
|
107
|
+
* that mock `electron` without a `session` export this short-circuits cleanly.
|
|
108
|
+
*/
|
|
109
|
+
export function configureMiniappSession(partition) {
|
|
110
|
+
// Record that this partition should be configured even if no configurator is
|
|
111
|
+
// registered YET — a later `registerMiniappSessionConfigurator` back-fills it.
|
|
112
|
+
const alreadyConfigured = configuredPartitions.has(partition);
|
|
113
|
+
configuredPartitions.add(partition);
|
|
114
|
+
if (configurators.size === 0)
|
|
115
|
+
return null;
|
|
116
|
+
const sess = electron.session.fromPartition(partition);
|
|
117
|
+
if (alreadyConfigured)
|
|
118
|
+
return sess;
|
|
119
|
+
for (const fn of configurators) {
|
|
120
|
+
try {
|
|
121
|
+
fn(sess, partition);
|
|
122
|
+
}
|
|
123
|
+
catch (err) {
|
|
124
|
+
console.warn('[miniapp-partition] configurator failed for', partition, err);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return sess;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Test-only: drop the configurator + configured-partition bookkeeping so each
|
|
131
|
+
* test starts from a clean slate. (Module-level state otherwise leaks across
|
|
132
|
+
* unit tests that mock `electron`.)
|
|
133
|
+
*/
|
|
134
|
+
export function __resetMiniappSessionConfigForTests() {
|
|
135
|
+
configurators.clear();
|
|
136
|
+
configuredPartitions.clear();
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=miniapp-partition.js.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Referer + CORS webRequest policy for the simulator runtime's sessions.
|
|
3
|
+
*
|
|
4
|
+
* The native render/service hosts fetch the compiled `<appId>/…` resources
|
|
5
|
+
* cross-origin and need a WeChat-style page-frame `Referer`; this installs that
|
|
6
|
+
* policy on the shared fallback session AND on every per-project
|
|
7
|
+
* `persist:miniapp-<key>` partition (current + future) via the partition
|
|
8
|
+
* configurator registry, so isolated projects load resources identically.
|
|
9
|
+
*
|
|
10
|
+
* TEARDOWN: a `webRequest` listener is per-session and there is exactly one
|
|
11
|
+
* slot per (session, event) — re-installing replaces, never stacks. But the
|
|
12
|
+
* configurator registration itself leaks if discarded: re-creating the
|
|
13
|
+
* WorkbenchApp in the same process would register a second configurator that
|
|
14
|
+
* keeps firing for every future partition. So this returns a {@link Disposable}
|
|
15
|
+
* that unregisters the configurator AND clears the listeners off every session
|
|
16
|
+
* it touched. Wire it into the context registry like any other module.
|
|
17
|
+
*/
|
|
18
|
+
import { type Disposable } from '@dimina-kit/electron-deck/main';
|
|
19
|
+
/**
|
|
20
|
+
* Install the simulator referer/CORS policy on the shared fallback session and
|
|
21
|
+
* register a configurator so every per-project partition session gets it too.
|
|
22
|
+
* Returns a disposable that unregisters the configurator and clears the policy
|
|
23
|
+
* off every session it installed on — call its teardown when the owning
|
|
24
|
+
* context is disposed so re-creating the app never leaks a duplicate
|
|
25
|
+
* configurator/listener.
|
|
26
|
+
*/
|
|
27
|
+
export declare function setupSimulatorSessionPolicy(): Disposable;
|
|
28
|
+
//# sourceMappingURL=simulator-session-policy.d.ts.map
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Referer + CORS webRequest policy for the simulator runtime's sessions.
|
|
3
|
+
*
|
|
4
|
+
* The native render/service hosts fetch the compiled `<appId>/…` resources
|
|
5
|
+
* cross-origin and need a WeChat-style page-frame `Referer`; this installs that
|
|
6
|
+
* policy on the shared fallback session AND on every per-project
|
|
7
|
+
* `persist:miniapp-<key>` partition (current + future) via the partition
|
|
8
|
+
* configurator registry, so isolated projects load resources identically.
|
|
9
|
+
*
|
|
10
|
+
* TEARDOWN: a `webRequest` listener is per-session and there is exactly one
|
|
11
|
+
* slot per (session, event) — re-installing replaces, never stacks. But the
|
|
12
|
+
* configurator registration itself leaks if discarded: re-creating the
|
|
13
|
+
* WorkbenchApp in the same process would register a second configurator that
|
|
14
|
+
* keeps firing for every future partition. So this returns a {@link Disposable}
|
|
15
|
+
* that unregisters the configurator AND clears the listeners off every session
|
|
16
|
+
* it touched. Wire it into the context registry like any other module.
|
|
17
|
+
*/
|
|
18
|
+
import { session } from 'electron';
|
|
19
|
+
import { toDisposable } from '@dimina-kit/electron-deck/main';
|
|
20
|
+
import { getSimulatorServicewechatReferer } from '../simulator/referer.js';
|
|
21
|
+
import { registerMiniappSessionConfigurator, SHARED_MINIAPP_PARTITION, } from './miniapp-partition.js';
|
|
22
|
+
/** Apply the simulator runtime's referer + CORS webRequest policy to one
|
|
23
|
+
* session. Each session installs its own listeners (a webRequest listener is
|
|
24
|
+
* per-session), so this runs once per partition. */
|
|
25
|
+
function applySimulatorWebRequestPolicy(simulatorSession) {
|
|
26
|
+
simulatorSession.webRequest.onBeforeSendHeaders((details, callback) => {
|
|
27
|
+
const forcedReferer = getSimulatorServicewechatReferer();
|
|
28
|
+
if (forcedReferer) {
|
|
29
|
+
details.requestHeaders['Referer'] = forcedReferer;
|
|
30
|
+
}
|
|
31
|
+
callback({ requestHeaders: details.requestHeaders });
|
|
32
|
+
});
|
|
33
|
+
simulatorSession.webRequest.onHeadersReceived((details, callback) => {
|
|
34
|
+
const headers = details.responseHeaders ?? {};
|
|
35
|
+
// CORS for the native render/service hosts to fetch compiled app resources
|
|
36
|
+
// cross-origin. (The COOP/COEP cross-origin-isolation headers were only for
|
|
37
|
+
// the removed default-path SharedArrayBuffer sync Worker — dropped.)
|
|
38
|
+
headers['access-control-allow-origin'] = ['*'];
|
|
39
|
+
headers['access-control-allow-headers'] = ['*'];
|
|
40
|
+
headers['access-control-allow-methods'] = ['*'];
|
|
41
|
+
callback({ responseHeaders: headers });
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/** Remove the policy listeners from a session (passing `null` clears the slot). */
|
|
45
|
+
function clearSimulatorWebRequestPolicy(simulatorSession) {
|
|
46
|
+
try {
|
|
47
|
+
simulatorSession.webRequest.onBeforeSendHeaders(null);
|
|
48
|
+
simulatorSession.webRequest.onHeadersReceived(null);
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
// Session already gone (app shutdown) — nothing to clear.
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Install the simulator referer/CORS policy on the shared fallback session and
|
|
56
|
+
* register a configurator so every per-project partition session gets it too.
|
|
57
|
+
* Returns a disposable that unregisters the configurator and clears the policy
|
|
58
|
+
* off every session it installed on — call its teardown when the owning
|
|
59
|
+
* context is disposed so re-creating the app never leaks a duplicate
|
|
60
|
+
* configurator/listener.
|
|
61
|
+
*/
|
|
62
|
+
export function setupSimulatorSessionPolicy() {
|
|
63
|
+
const configured = new Set();
|
|
64
|
+
function install(sess) {
|
|
65
|
+
if (configured.has(sess))
|
|
66
|
+
return;
|
|
67
|
+
configured.add(sess);
|
|
68
|
+
applySimulatorWebRequestPolicy(sess);
|
|
69
|
+
}
|
|
70
|
+
// Shared fallback session (pre-warm pool + unknown-appId path).
|
|
71
|
+
install(session.fromPartition(SHARED_MINIAPP_PARTITION));
|
|
72
|
+
// Every per-project miniapp partition session (current + future) gets the
|
|
73
|
+
// same referer/CORS policy so isolated projects load resources identically.
|
|
74
|
+
const unregister = registerMiniappSessionConfigurator((sess) => install(sess));
|
|
75
|
+
return toDisposable(() => {
|
|
76
|
+
unregister();
|
|
77
|
+
for (const sess of configured)
|
|
78
|
+
clearSimulatorWebRequestPolicy(sess);
|
|
79
|
+
configured.clear();
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=simulator-session-policy.js.map
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { WebContents } from 'electron';
|
|
2
|
+
import type { NativeDeviceInfo } from '../../../shared/ipc-channels.js';
|
|
2
3
|
import { type WorkbenchContext } from '../workbench-context.js';
|
|
3
4
|
/**
|
|
4
5
|
* Context surface used by the ViewManager. We only need a small slice of the
|
|
@@ -7,8 +8,41 @@ import { type WorkbenchContext } from '../workbench-context.js';
|
|
|
7
8
|
export interface ViewManagerContext {
|
|
8
9
|
windows: WorkbenchContext['windows'];
|
|
9
10
|
rendererDir: string;
|
|
11
|
+
/**
|
|
12
|
+
* Per-webContents connection registry (foundation.md §4). The native-host
|
|
13
|
+
* simulator WebContentsView is acquired here so the registry tracks that
|
|
14
|
+
* trusted webContents and tears its per-wc resources (the custom-api bridge
|
|
15
|
+
* `ipcMain.on`) down deterministically on destroy — see P1 DoD #3. Required:
|
|
16
|
+
* `createWorkbenchContext` always supplies it.
|
|
17
|
+
*/
|
|
18
|
+
connections: WorkbenchContext['connections'];
|
|
19
|
+
/**
|
|
20
|
+
* Absolute path to the simulator preload bundle. Only consumed by the
|
|
21
|
+
* native-host simulator WebContentsView (`attachNativeSimulator`); the
|
|
22
|
+
* default `<webview>` path gets its preload from the session-registered
|
|
23
|
+
* frame preload instead. Optional so partial test contexts compile.
|
|
24
|
+
*/
|
|
25
|
+
preloadPath?: string;
|
|
10
26
|
panels: string[];
|
|
11
27
|
notify: WorkbenchContext['notify'];
|
|
28
|
+
bridge?: WorkbenchContext['bridge'];
|
|
29
|
+
/**
|
|
30
|
+
* Native-host network forwarder. `attachNativeSimulator` hands it the freshly
|
|
31
|
+
* created simulator WebContentsView (`attachSimulator`) so it can attach the
|
|
32
|
+
* CDP debugger, and the DevTools front-end host wc (`setDevtoolsHost`) so it can
|
|
33
|
+
* inject that WCV's Network.* events into the native Network tab (service-host
|
|
34
|
+
* console line is the fallback). Optional so partial test contexts compile.
|
|
35
|
+
*/
|
|
36
|
+
networkForward?: WorkbenchContext['networkForward'];
|
|
37
|
+
/**
|
|
38
|
+
* Per-context registry of host-registered simulator custom APIs. The
|
|
39
|
+
* native-host simulator is a top-level WebContentsView with no embedder
|
|
40
|
+
* renderer, so `attachNativeSimulator` dispatches the simulator-side
|
|
41
|
+
* `__diminaCustomApis` bridge straight to this registry (the default
|
|
42
|
+
* `<webview>` path proxies through the trusted main renderer instead).
|
|
43
|
+
* Optional so partial test contexts compile.
|
|
44
|
+
*/
|
|
45
|
+
simulatorApis?: WorkbenchContext['simulatorApis'];
|
|
12
46
|
/**
|
|
13
47
|
* Header bar height in px, used to position overlay views below the header.
|
|
14
48
|
* Optional here so partial test contexts compile; `createWorkbenchContext`
|
|
@@ -36,6 +70,19 @@ export interface ViewManager {
|
|
|
36
70
|
* tab; otherwise the view is created but not added yet).
|
|
37
71
|
*/
|
|
38
72
|
attachSimulator(simWcId: number, simWidth: number): void;
|
|
73
|
+
/**
|
|
74
|
+
* NATIVE-HOST ONLY. Create the simulator itself as a top-level
|
|
75
|
+
* WebContentsView (not a renderer `<webview>` guest) loading `simulatorUrl`,
|
|
76
|
+
* position it in the simulator panel region, and treat its webContents as
|
|
77
|
+
* THE simulator webContents (so `getSimulatorWebContents` resolves it and the
|
|
78
|
+
* spawn/SIMULATOR_EVENTS pipeline flows through it). This is required because
|
|
79
|
+
* Electron force-disables the `<webview>` tag inside a webview guest, so the
|
|
80
|
+
* default `<webview>`-in-`<webview>` topology can never host DeviceShell's
|
|
81
|
+
* per-page render-host `<webview>`s. A top-level WebContentsView's webContents
|
|
82
|
+
* is NOT a guest and CAN host them. Then wires the DevTools/console view on
|
|
83
|
+
* top of it via `attachSimulator`. No-op (logs) when `preloadPath` is unset.
|
|
84
|
+
*/
|
|
85
|
+
attachNativeSimulator(simulatorUrl: string, simWidth: number): void;
|
|
39
86
|
/**
|
|
40
87
|
* Destroy and null out the simulator view (e.g. on simulator detach).
|
|
41
88
|
* Also destroys the cached settings view and hides the popover —
|
|
@@ -75,6 +122,35 @@ export interface ViewManager {
|
|
|
75
122
|
getSettingsWebContentsId(): number | null;
|
|
76
123
|
/** Return the webContents ID of the popover overlay if alive, else null. */
|
|
77
124
|
getPopoverWebContentsId(): number | null;
|
|
125
|
+
/**
|
|
126
|
+
* Return the webContents ID of the host-toolbar overlay if alive, else null.
|
|
127
|
+
* The host-toolbar WCV is the one overlay whose OWN renderer drives an IPC
|
|
128
|
+
* channel back to main (the reverse size-advertiser), so the sender policy
|
|
129
|
+
* must trust its id — see `createWorkbenchSenderPolicy`.
|
|
130
|
+
*/
|
|
131
|
+
getHostToolbarWebContentsId(): number | null;
|
|
132
|
+
/**
|
|
133
|
+
* NATIVE-HOST ONLY. Position the simulator content WebContentsView over the
|
|
134
|
+
* renderer-measured simulator panel REGION rect (the flex:1 placeholder slot,
|
|
135
|
+
* CSS px from the main window content top-left, which maps 1:1 to overlay
|
|
136
|
+
* setBounds DIP) and apply the device zoom. The WCV fills the region as a
|
|
137
|
+
* plain rectangle; DeviceShell draws + scrolls the phone inside. No-op in the
|
|
138
|
+
* default `<webview>` path (`nativeSimulatorView` is null). See
|
|
139
|
+
* `computeNativeSimulatorViewParams`.
|
|
140
|
+
*/
|
|
141
|
+
setNativeSimulatorViewBounds(params: {
|
|
142
|
+
x: number;
|
|
143
|
+
y: number;
|
|
144
|
+
width: number;
|
|
145
|
+
height: number;
|
|
146
|
+
zoom: number;
|
|
147
|
+
}): void;
|
|
148
|
+
/**
|
|
149
|
+
* NATIVE-HOST ONLY. Re-push the selected device's CSS `env(safe-area-inset-*)`
|
|
150
|
+
* override to every attached render-host guest (on device change). New guests
|
|
151
|
+
* pick it up automatically when they attach (`did-attach-webview`).
|
|
152
|
+
*/
|
|
153
|
+
reapplySafeArea(device: NativeDeviceInfo | null): void;
|
|
78
154
|
/** Update lastSimWidth; reposition simulator + settings if they are added. */
|
|
79
155
|
resize(simWidth: number): void;
|
|
80
156
|
/** Show or hide the simulator overlay based on visibility flag. */
|
|
@@ -91,6 +167,55 @@ export interface ViewManager {
|
|
|
91
167
|
width: number;
|
|
92
168
|
height: number;
|
|
93
169
|
}): void;
|
|
170
|
+
/**
|
|
171
|
+
* Apply a renderer-measured rectangle to the host-controllable toolbar
|
|
172
|
+
* WebContentsView (the strip above the devtools header). Forward anchor,
|
|
173
|
+
* mirroring `setSimulatorDevtoolsBounds`. `{ width: 0, height: 0 }` is
|
|
174
|
+
* treated as "hide" — the view is removed from the contentView but its
|
|
175
|
+
* WebContents (and the host's loaded content) stays alive. Lazily creates
|
|
176
|
+
* the view on the first non-empty rect.
|
|
177
|
+
*/
|
|
178
|
+
setHostToolbarBounds(bounds: {
|
|
179
|
+
x: number;
|
|
180
|
+
y: number;
|
|
181
|
+
width: number;
|
|
182
|
+
height: number;
|
|
183
|
+
}): void;
|
|
184
|
+
/**
|
|
185
|
+
* Reverse size-advertiser sink: the toolbar WCV's own renderer advertises
|
|
186
|
+
* its intrinsic content height (block-axis extent); we store it and push it
|
|
187
|
+
* to the main-window renderer so the placeholder div resizes (closing the
|
|
188
|
+
* dynamic-height loop).
|
|
189
|
+
*/
|
|
190
|
+
setHostToolbarHeight(extent: number): void;
|
|
191
|
+
/**
|
|
192
|
+
* Host-facing control surface for the toolbar WebContentsView. The downstream
|
|
193
|
+
* host loads its own content into it (`loadURL` / `loadFile`) and fully drives
|
|
194
|
+
* it. Lazily creates the underlying view on the first load call.
|
|
195
|
+
*/
|
|
196
|
+
readonly hostToolbar: HostToolbarControl;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* The control object the downstream host uses to own the toolbar
|
|
200
|
+
* WebContentsView. Lazily backed by the view-manager's `hostToolbarView`.
|
|
201
|
+
*/
|
|
202
|
+
export interface HostToolbarControl {
|
|
203
|
+
/** Load a URL into the toolbar view (lazy-creates the view). */
|
|
204
|
+
loadURL(url: string): Promise<void>;
|
|
205
|
+
/** Load a local file into the toolbar view (lazy-creates the view). */
|
|
206
|
+
loadFile(path: string): Promise<void>;
|
|
207
|
+
/** The toolbar view's live WebContents, or null if not yet created/destroyed. */
|
|
208
|
+
readonly webContents: WebContents | null;
|
|
209
|
+
/** Remove the toolbar view from the contentView and reset it (kept alive). */
|
|
210
|
+
hide(): void;
|
|
211
|
+
/**
|
|
212
|
+
* Override the preload used when the toolbar view is first created. The
|
|
213
|
+
* host-shell (`launch(config)`) passes the host-controlled
|
|
214
|
+
* `toolbar.preloadPath` here; the host owns the bridge (it calls
|
|
215
|
+
* `exposeWorkbenchBridge()` itself). Must be set before the first
|
|
216
|
+
* `loadURL`/`loadFile`; `null` restores the built-in size-advertiser preload.
|
|
217
|
+
*/
|
|
218
|
+
setPreloadPath(path: string | null): void;
|
|
94
219
|
}
|
|
95
220
|
/**
|
|
96
221
|
* Build a ViewManager bound to the given context. The returned object is the
|