@dimina-kit/devtools 0.4.0-dev.20260624040247 → 0.4.0-dev.20260624084417
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/index.bundle.js +265 -29
- package/dist/main/services/elements-forward/index.js +37 -3
- package/dist/main/services/render-inspect/index.js +182 -6
- package/dist/main/services/views/devtools-tabs.d.ts +4 -1
- package/dist/main/services/views/devtools-tabs.js +21 -3
- package/dist/main/services/views/view-manager.js +7 -6
- package/dist/preload/instrumentation/wxml-extract.js +53 -7
- package/dist/render-host/render-inspect.js +24 -23
- package/dist/renderer/assets/index-BMqriQNr.js +50 -0
- package/dist/renderer/entries/main/index.html +1 -1
- package/dist/shared/open-in-editor.d.ts +9 -2
- package/dist/shared/open-in-editor.js +140 -17
- package/dist/simulator/assets/device-shell-CPCnCp1L.js +2 -0
- package/dist/simulator/assets/{simulator-CtyXt_4V.js → simulator-gMBWKDeO.js} +3 -3
- package/dist/simulator/simulator.html +1 -1
- package/package.json +6 -6
- package/dist/renderer/assets/index-PtsdWlGu.js +0 -50
- package/dist/simulator/assets/device-shell-TtcSXwhb.js +0 -2
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
overflow: hidden;
|
|
29
29
|
}
|
|
30
30
|
</style>
|
|
31
|
-
<script type="module" crossorigin src="../../assets/index-
|
|
31
|
+
<script type="module" crossorigin src="../../assets/index-BMqriQNr.js"></script>
|
|
32
32
|
<link rel="modulepreload" crossorigin href="../../assets/chunk-DPI0Y_ll.js">
|
|
33
33
|
<link rel="modulepreload" crossorigin href="../../assets/ipc-transport-DSBmaWpJ.js">
|
|
34
34
|
<link rel="modulepreload" crossorigin href="../../assets/editor.api2-BTaYmRq7.js">
|
|
@@ -82,8 +82,15 @@ export declare function projectSourceContextFromServiceHostUrl(serviceHostUrl: s
|
|
|
82
82
|
/**
|
|
83
83
|
* Build the DevTools-front-end glue for project source links.
|
|
84
84
|
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
85
|
+
* Primary transport is a capture-phase click interceptor: a project-source link
|
|
86
|
+
* click is redirected to `InspectorFrontendHost.openInNewTab(<sentinel>)` (which
|
|
87
|
+
* Electron surfaces as `devtools-open-url` on the inspected wc) and the default
|
|
88
|
+
* DevTools Sources reveal is suppressed. This survives current Chromium DevTools,
|
|
89
|
+
* where the legacy `Host.InspectorFrontendHost.setOpenResourceHandler` hook is
|
|
90
|
+
* gone (the host moved to the top-level `InspectorFrontendHost` global and that
|
|
91
|
+
* method no longer exists). The `setOpenResourceHandler` registration below is
|
|
92
|
+
* kept as a no-op-when-absent fallback for older fronts. Only locations that map
|
|
93
|
+
* to the active project are forwarded; a DOM observer expands Chromium's
|
|
87
94
|
* basename-only console labels to project-relative paths.
|
|
88
95
|
*/
|
|
89
96
|
export declare function buildDevtoolsProjectSourceLinksScript(context: ProjectSourceContext): string;
|
|
@@ -169,11 +169,28 @@ function projectAwareResourcePath(resourceUrl, context) {
|
|
|
169
169
|
const raw = resourceUrl.trim();
|
|
170
170
|
if (!raw)
|
|
171
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
|
+
};
|
|
172
189
|
// Chromium may hand the open-resource hook a raw absolute filesystem path.
|
|
173
190
|
const normalizedRaw = normalizeSlashPath(raw);
|
|
174
191
|
if (projectRoot && (normalizedRaw === projectRoot || normalizedRaw.startsWith(`${projectRoot}/`))) {
|
|
175
192
|
const relative = normalizedRaw.slice(projectRoot.length).replace(/^\/+/, '');
|
|
176
|
-
return safeRelativePath(relative.split('/').filter(Boolean));
|
|
193
|
+
return excludeBuildChunk(safeRelativePath(relative.split('/').filter(Boolean)));
|
|
177
194
|
}
|
|
178
195
|
// Sourcemap sources commonly use virtual root paths such as `/pages/x.js`.
|
|
179
196
|
// Real host filesystem paths use well-known absolute roots; when they are
|
|
@@ -199,7 +216,7 @@ function projectAwareResourcePath(resourceUrl, context) {
|
|
|
199
216
|
const filePath = normalizeSlashPath(resource.pathname);
|
|
200
217
|
if (!projectRoot || (filePath !== projectRoot && !filePath.startsWith(`${projectRoot}/`)))
|
|
201
218
|
return null;
|
|
202
|
-
return safeRelativePath(filePath.slice(projectRoot.length).replace(/^\/+/, '').split('/').filter(Boolean));
|
|
219
|
+
return excludeBuildChunk(safeRelativePath(filePath.slice(projectRoot.length).replace(/^\/+/, '').split('/').filter(Boolean)));
|
|
203
220
|
}
|
|
204
221
|
if (resource.protocol !== 'http:' && resource.protocol !== 'https:')
|
|
205
222
|
return null;
|
|
@@ -211,7 +228,7 @@ function projectAwareResourcePath(resourceUrl, context) {
|
|
|
211
228
|
if (context.outputRoot && segments[0] === context.outputRoot)
|
|
212
229
|
segments = segments.slice(1);
|
|
213
230
|
}
|
|
214
|
-
return safeRelativePath(segments);
|
|
231
|
+
return excludeBuildChunk(safeRelativePath(segments));
|
|
215
232
|
}
|
|
216
233
|
/** Read the project/source routing metadata carried by a service-host spawn URL. */
|
|
217
234
|
export function projectSourceContextFromServiceHostUrl(serviceHostUrl, activeProjectRoot) {
|
|
@@ -245,8 +262,15 @@ export function projectSourceContextFromServiceHostUrl(serviceHostUrl, activePro
|
|
|
245
262
|
/**
|
|
246
263
|
* Build the DevTools-front-end glue for project source links.
|
|
247
264
|
*
|
|
248
|
-
*
|
|
249
|
-
*
|
|
265
|
+
* Primary transport is a capture-phase click interceptor: a project-source link
|
|
266
|
+
* click is redirected to `InspectorFrontendHost.openInNewTab(<sentinel>)` (which
|
|
267
|
+
* Electron surfaces as `devtools-open-url` on the inspected wc) and the default
|
|
268
|
+
* DevTools Sources reveal is suppressed. This survives current Chromium DevTools,
|
|
269
|
+
* where the legacy `Host.InspectorFrontendHost.setOpenResourceHandler` hook is
|
|
270
|
+
* gone (the host moved to the top-level `InspectorFrontendHost` global and that
|
|
271
|
+
* method no longer exists). The `setOpenResourceHandler` registration below is
|
|
272
|
+
* kept as a no-op-when-absent fallback for older fronts. Only locations that map
|
|
273
|
+
* to the active project are forwarded; a DOM observer expands Chromium's
|
|
250
274
|
* basename-only console labels to project-relative paths.
|
|
251
275
|
*/
|
|
252
276
|
export function buildDevtoolsProjectSourceLinksScript(context) {
|
|
@@ -268,6 +292,7 @@ export function buildDevtoolsProjectSourceLinksScript(context) {
|
|
|
268
292
|
const safeRelativePath = ${safeRelativePath.toString()}
|
|
269
293
|
const observedRoots = new Set()
|
|
270
294
|
const observers = []
|
|
295
|
+
const clickBindings = []
|
|
271
296
|
let timer = null
|
|
272
297
|
const state = {
|
|
273
298
|
dispose() {
|
|
@@ -278,11 +303,106 @@ export function buildDevtoolsProjectSourceLinksScript(context) {
|
|
|
278
303
|
for (const observer of observers.splice(0)) {
|
|
279
304
|
try { observer.disconnect() } catch (_) {}
|
|
280
305
|
}
|
|
306
|
+
for (const binding of clickBindings.splice(0)) {
|
|
307
|
+
try { binding.target.removeEventListener('click', binding.fn, true) } catch (_) {}
|
|
308
|
+
}
|
|
281
309
|
observedRoots.clear()
|
|
282
310
|
},
|
|
283
311
|
}
|
|
284
312
|
globalThis[stateKey] = state
|
|
285
313
|
|
|
314
|
+
// The InspectorFrontendHost that owns openInNewTab. Across DevTools
|
|
315
|
+
// versions it lives on the top-level \`InspectorFrontendHost\` global, the
|
|
316
|
+
// legacy \`Host.InspectorFrontendHost\`, or \`DevToolsHost\`; resolve at call
|
|
317
|
+
// time so a late-bootstrapped host is still found.
|
|
318
|
+
function resolveOpenInNewTabHost() {
|
|
319
|
+
const candidates = [
|
|
320
|
+
globalThis.InspectorFrontendHost,
|
|
321
|
+
globalThis.Host && globalThis.Host.InspectorFrontendHost,
|
|
322
|
+
globalThis.DevToolsHost,
|
|
323
|
+
]
|
|
324
|
+
for (const host of candidates) {
|
|
325
|
+
if (host && typeof host.openInNewTab === 'function') return host
|
|
326
|
+
}
|
|
327
|
+
return null
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// Encode (url, 0-based line, 0-based column) as the sentinel the main
|
|
331
|
+
// process decodes from \`devtools-open-url\` and routes to Monaco.
|
|
332
|
+
function openInEditor(url, line, column) {
|
|
333
|
+
const host = resolveOpenInNewTabHost()
|
|
334
|
+
if (!host) return false
|
|
335
|
+
const p = new URLSearchParams()
|
|
336
|
+
p.set('u', String(url))
|
|
337
|
+
if (typeof line === 'number' && isFinite(line)) p.set('l', String(line))
|
|
338
|
+
if (typeof column === 'number' && isFinite(column)) p.set('c', String(column))
|
|
339
|
+
try { host.openInNewTab(${scheme} + ':?' + p.toString()) } catch (_) { return false }
|
|
340
|
+
return true
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// Resolve a clicked link element to a project source location. Returns
|
|
344
|
+
// the FULL resource url (the main process re-maps it against the active
|
|
345
|
+
// project) plus its display line/column when present.
|
|
346
|
+
function projectLocationForLink(link) {
|
|
347
|
+
if (!link) return null
|
|
348
|
+
const candidates = [
|
|
349
|
+
link.getAttribute && link.getAttribute('data-url'),
|
|
350
|
+
link.getAttribute && link.getAttribute('href'),
|
|
351
|
+
link.getAttribute && link.getAttribute('title'),
|
|
352
|
+
]
|
|
353
|
+
for (const candidate of candidates) {
|
|
354
|
+
if (!candidate) continue
|
|
355
|
+
const location = splitLocation(candidate)
|
|
356
|
+
if (!diminaProjectSourcePath(location.url, cfg)) continue
|
|
357
|
+
const suffix = location.suffix
|
|
358
|
+
|| ((String(link.textContent || '').match(/(:\\d+(?::\\d+)?)$/) || [])[1] || '')
|
|
359
|
+
return { url: location.url, suffix }
|
|
360
|
+
}
|
|
361
|
+
return null
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// DevTools shows 1-based line:column in link text; the main process
|
|
365
|
+
// contract expects 0-based (it re-adds 1). Convert here.
|
|
366
|
+
function parseSuffix(suffix) {
|
|
367
|
+
const m = String(suffix || '').match(/^:(\\d+)(?::(\\d+))?$/)
|
|
368
|
+
if (!m) return { line: undefined, column: undefined }
|
|
369
|
+
const line = Math.max(0, parseInt(m[1], 10) - 1)
|
|
370
|
+
const column = m[2] != null ? Math.max(0, parseInt(m[2], 10) - 1) : undefined
|
|
371
|
+
return { line, column }
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// Capture-phase click handler: route a project-source link click to
|
|
375
|
+
// Monaco instead of the DevTools Sources panel. Plain primary clicks only
|
|
376
|
+
// — modified clicks (cmd/ctrl/shift/alt, middle button) fall through to
|
|
377
|
+
// DevTools so its own "open in new tab" / multi-select still work.
|
|
378
|
+
function onLinkClick(event) {
|
|
379
|
+
if (event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return
|
|
380
|
+
const path = typeof event.composedPath === 'function' ? event.composedPath() : []
|
|
381
|
+
let link = null
|
|
382
|
+
for (const node of path) {
|
|
383
|
+
if (node && node.nodeType === 1 && node.classList && node.classList.contains('devtools-link')) {
|
|
384
|
+
link = node
|
|
385
|
+
break
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
if (!link) return
|
|
389
|
+
const location = projectLocationForLink(link)
|
|
390
|
+
if (!location) return
|
|
391
|
+
const { line, column } = parseSuffix(location.suffix)
|
|
392
|
+
if (!openInEditor(location.url, line, column)) return
|
|
393
|
+
event.preventDefault()
|
|
394
|
+
event.stopImmediatePropagation()
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
function bindClicks(target) {
|
|
398
|
+
if (!target || !target.addEventListener) return
|
|
399
|
+
for (const binding of clickBindings) {
|
|
400
|
+
if (binding.target === target) return
|
|
401
|
+
}
|
|
402
|
+
target.addEventListener('click', onLinkClick, true)
|
|
403
|
+
clickBindings.push({ target, fn: onLinkClick })
|
|
404
|
+
}
|
|
405
|
+
|
|
286
406
|
function splitLocation(value) {
|
|
287
407
|
const raw = String(value || '')
|
|
288
408
|
const match = raw.match(/^(.*?)(?::(\\d+))(?::(\\d+))?$/)
|
|
@@ -313,6 +433,7 @@ export function buildDevtoolsProjectSourceLinksScript(context) {
|
|
|
313
433
|
function observeRoot(root) {
|
|
314
434
|
if (!root || !root.querySelectorAll || observedRoots.has(root)) return
|
|
315
435
|
observedRoots.add(root)
|
|
436
|
+
bindClicks(root)
|
|
316
437
|
|
|
317
438
|
const observer = new MutationObserver((records) => {
|
|
318
439
|
for (const record of records) {
|
|
@@ -347,23 +468,25 @@ export function buildDevtoolsProjectSourceLinksScript(context) {
|
|
|
347
468
|
|
|
348
469
|
observeRoot(document)
|
|
349
470
|
|
|
471
|
+
// Fallback for older DevTools fronts that still expose the
|
|
472
|
+
// setOpenResourceHandler hook. On current Chromium the method is gone,
|
|
473
|
+
// so this poll simply times out and the capture-phase click interceptor
|
|
474
|
+
// is the only live path. When the hook IS present the interceptor still
|
|
475
|
+
// wins (it runs in capture and stops propagation), so the two never
|
|
476
|
+
// double-open the same click.
|
|
350
477
|
let tries = 0
|
|
351
478
|
timer = setInterval(() => {
|
|
352
479
|
tries++
|
|
353
480
|
try {
|
|
354
|
-
const
|
|
355
|
-
|
|
356
|
-
if (host && typeof host.setOpenResourceHandler === 'function'
|
|
357
|
-
&& typeof host.openInNewTab === 'function') {
|
|
481
|
+
const host = resolveOpenInNewTabHost()
|
|
482
|
+
if (host && typeof host.setOpenResourceHandler === 'function') {
|
|
358
483
|
host.setOpenResourceHandler((url, lineNumber, columnNumber) => {
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
host.openInNewTab(${scheme} + ':?' + p.toString())
|
|
366
|
-
} catch (_) {}
|
|
484
|
+
if (!diminaProjectSourcePath(String(url), cfg)) return
|
|
485
|
+
openInEditor(
|
|
486
|
+
String(url),
|
|
487
|
+
typeof lineNumber === 'number' ? lineNumber : undefined,
|
|
488
|
+
typeof columnNumber === 'number' ? columnNumber : undefined,
|
|
489
|
+
)
|
|
367
490
|
})
|
|
368
491
|
clearInterval(timer)
|
|
369
492
|
timer = null
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{n as e,t}from"./jsx-runtime-P6ZegaOf.js";import{t as n}from"./bridge-channels-BUQ5AbvJ.js";var r=e(),i=new Set([`audioListen`]);function a(e){return i.has(e)}function o(e,t,n,r){let i=e.apiRegistry[t];if(!i)return r({ok:!1,errMsg:`${t}:fail no handler`}),Promise.resolve();let o=a(t)||(n&&typeof n==`object`&&!Array.isArray(n)?n.keep===!0:!1);return new Promise(a=>{let s=!1,c=e=>{if(s){o&&e.ok&&r({...e,keep:!0});return}s=!0,r(o&&e.ok?{...e,keep:!0}:e),a()},l=Symbol(`sim-cb-success`),u=Symbol(`sim-cb-fail`),d=Symbol(`sim-cb-complete`),f=Object.create(e);f.createCallbackFunction=e=>{if(e!=null)return(...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})}};let p=n&&typeof n==`object`&&!Array.isArray(n)?{...n}:{},m=p.success!==void 0&&p.success!==null,h=p.fail!==void 0&&p.fail!==null,g=p.complete!==void 0&&p.complete!==null;p.success=l,p.fail=u,g&&(p.complete=d);try{let e=i.call(f,p);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}!m&&!h&&(o?a():c({ok:!0,result:e}))}catch(e){c({ok:!1,errMsg:`${t}:fail ${e instanceof Error?e.message:String(e)}`})}})}var s=t();function c({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,s.jsxs)(`div`,{className:`menu-capsule menu-capsule--${n}`,style:{width:r,height:32,top:i,right:a},"aria-hidden":`true`,children:[(0,s.jsxs)(`div`,{className:`menu-capsule__more`,children:[(0,s.jsx)(`span`,{}),(0,s.jsx)(`span`,{}),(0,s.jsx)(`span`,{})]}),(0,s.jsx)(`div`,{className:`menu-capsule__divider`}),(0,s.jsx)(`div`,{className:`menu-capsule__close`,children:(0,s.jsx)(`svg`,{viewBox:`0 0 16 16`,width:`12`,height:`12`,"aria-hidden":`true`,children:(0,s.jsx)(`path`,{d:`M4 4l8 8M12 4l-8 8`,stroke:`currentColor`,strokeWidth:`1.5`,fill:`none`,strokeLinecap:`round`})})})]})}var l={linear:`linear`,easeIn:`ease-in`,easeOut:`ease-out`,easeInOut:`ease-in-out`};function u({state:e,stackDepth:t,platform:n,statusBarHeight:i,navBarHeight:a,onBack:o,onHome:u}){let d=(0,r.useMemo)(()=>{if(!e.colorAnimation||e.colorAnimation.durationMs<=0)return;let t=l[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:i+a,paddingTop:i,transition:d};return(0,s.jsxs)(`header`,{className:`nav-bar nav-bar--${n} nav-bar--${e.textStyle}${f?` nav-bar--custom`:``}`,style:g,"aria-hidden":f,children:[!f&&(0,s.jsxs)(`div`,{className:`nav-bar__row`,style:{height:a,justifyContent:h===`center`?`center`:`flex-start`},children:[(p||m)&&(0,s.jsxs)(`div`,{className:`nav-bar__leading`,children:[p&&(0,s.jsx)(`button`,{type:`button`,className:`nav-bar__back`,"aria-label":`Back`,onClick:o,children:(0,s.jsx)(`svg`,{viewBox:`0 0 24 24`,width:`24`,height:`24`,"aria-hidden":`true`,children:(0,s.jsx)(`path`,{d:`M15 18l-6-6 6-6`,stroke:`currentColor`,strokeWidth:`2`,fill:`none`,strokeLinecap:`round`,strokeLinejoin:`round`})})}),m&&(0,s.jsx)(`button`,{type:`button`,className:`nav-bar__home`,"aria-label":`Home`,onClick:u,children:(0,s.jsx)(`svg`,{viewBox:`0 0 24 24`,width:`22`,height:`22`,"aria-hidden":`true`,children:(0,s.jsx)(`path`,{d:`M3 12l9-9 9 9M5 10v10h14V10`,stroke:`currentColor`,strokeWidth:`2`,fill:`none`,strokeLinecap:`round`,strokeLinejoin:`round`})})})]}),(0,s.jsxs)(`div`,{className:`nav-bar__title nav-bar__title--${h}`,style:{color:e.textStyle===`white`?`#ffffff`:`#000000`},children:[e.loading&&(0,s.jsx)(`span`,{className:`nav-bar__spinner`,"aria-hidden":`true`}),(0,s.jsx)(`span`,{className:`nav-bar__title-text`,children:e.title})]})]}),(0,s.jsx)(c,{platform:n,statusBarHeight:i,textStyle:e.textStyle})]})}function d(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 f(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 p({height:e,notchType:t,textStyle:n}){let r=f(t);return(0,s.jsxs)(`div`,{className:`device-statusbar`,style:{height:e,color:n===`black`?`#000000`:`#ffffff`},"aria-hidden":`true`,children:[(0,s.jsx)(`span`,{className:`device-statusbar__time`,children:`9:41`}),r&&(0,s.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,s.jsxs)(`div`,{className:`device-statusbar__icons`,children:[(0,s.jsx)(`span`,{className:`device-statusbar__signal`}),(0,s.jsx)(`span`,{className:`device-statusbar__wifi`}),(0,s.jsx)(`span`,{className:`device-statusbar__battery`})]})]})}function m({state:e,currentPath:t,resourceBaseUrl:n,appId:r,onSwitch:i,bottomInset:a=0}){if(!e.config||!e.visible)return null;let{color:o,selectedColor:c,backgroundColor:l,borderStyle:u,list:d}=e.config,f=o||`#999999`,p=c||`#1890ff`;return(0,s.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 c=h(a.pagePath),l=c===t,u=g(l?a.selectedIconPath??a.iconPath:a.iconPath,n,r),d=e.badges[o]??``,m=e.redDots[o]??!1;return(0,s.jsxs)(`button`,{type:`button`,className:`dmb-tab-bar__item${l?` is-selected`:``}`,role:`tab`,"aria-selected":l,onClick:()=>i(c),children:[u&&(0,s.jsx)(`span`,{className:`dmb-tab-bar__icon-slot`,children:(0,s.jsx)(`img`,{className:`dmb-tab-bar__icon`,src:u,alt:``,onError:e=>{e.currentTarget.style.display=`none`}})}),(0,s.jsx)(`span`,{className:`dmb-tab-bar__text`,style:{color:l?p:f},children:a.text||``}),d&&(0,s.jsx)(`span`,{className:`dmb-tab-bar__badge`,children:d}),!d&&m&&(0,s.jsx)(`span`,{className:`dmb-tab-bar__red-dot`})]},`${c}-${o}`)})})}function h(e){return e?e.replace(/^\/+/,``):``}function g(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}/`)?_(t,i):_(t,`${n}/main/${i}`)}function _(e,t){return`${e.endsWith(`/`)?e:`${e}/`}${t.replace(/^\/+/,``)}`}function v(e){if(!e)return{config:null,visible:!1,badges:[],redDots:[]};let t=e.list.length;return{config:y(e),visible:!0,badges:Array.from({length:t},()=>``),redDots:Array.from({length:t},()=>!1)}}function y(e){return{...e,list:e.list.map(e=>({...e}))}}function b(e,t){switch(t.kind){case`reset`:return{state:v(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 x(e,t.name,t.params)}}function x(e,t,n){if(!e.config)return{state:e,ok:!1,errMsg:`${t}:fail tabBar not configured`};switch(t){case`setTabBarStyle`:return S(e,n);case`setTabBarItem`:return C(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 w(e,n);case`removeTabBarBadge`:return T(e,n);case`showTabBarRedDot`:return E(e,n,!0);case`hideTabBarRedDot`:return E(e,n,!1)}}function S(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=O(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 C(e,t){let n=D(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 w(e,t){let n=D(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 T(e,t){let n=D(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 E(e,t,n){let r=D(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 D(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 O(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 k(e){return e?e.replace(/^\/+/,``):``}function A(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:k(t),query:r}}function j(e){let t={};return e.isTab&&(t[e.pagePath]=[e]),{stack:[e],tabStacks:t,currentTabPath:e.isTab?e.pagePath:null}}function M(e){return e.currentTabPath?{...e.tabStacks,[e.currentTabPath]:[...e.stack]}:e.tabStacks}function N(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 P(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 F(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 I(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 L(e,t,n){let r=e.stack[e.stack.length-1],i=M(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 R(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 z(e,t){let n=e.navigationBarBackgroundColor??`#ffffff`,r=e.navigationBarTextStyle??`black`,i=e.navigationStyle??`default`;return d({title:e.navigationBarTitleText??t,backgroundColor:n,textStyle:r,style:i,homeButtonVisible:e.homeButton===!0})}function B(e,t,n){switch(t){case`setNavigationBarTitle`:return{...e,title:typeof n.title==`string`?n.title:e.title};case`setNavigationBarColor`:return H(e,n);case`showNavigationBarLoading`:return{...e,loading:!0};case`hideNavigationBarLoading`:return{...e,loading:!1};case`hideHomeButton`:return{...e,homeButtonVisible:!1};default:return e}}var V=[`linear`,`easeIn`,`easeOut`,`easeInOut`];function H(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:V.includes(i)?i:`linear`}})();return{...e,textStyle:r,backgroundColor:i,colorAnimation:a}}function U(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 W=44,G=24,K=44;function q({miniApp:e,bridgeId:t,platform:i=`ios`}){let[a,c]=(0,r.useState)(()=>e.getInitialDevice());(0,r.useEffect)(()=>e.onSimulatorEvent(n.DEVICE_CHANGE,c),[e]);let l=a?.safeAreaInsets.top??(i===`ios`?W:G),d=a?.safeAreaInsets.bottom??0,f=a?.notchType??`none`,h=(0,r.useMemo)(()=>e.getRenderPreloadUrl(),[e]),g=(0,r.useMemo)(()=>e.getTabBarConfig(),[e]),_=(0,r.useMemo)(()=>({bridgeId:t,pagePath:k(e.pagePath),query:{...e.query},isTab:!!e.getTabBarConfig()?.list.some(t=>k(t.pagePath)===k(e.pagePath)),windowConfig:e.rootWindowConfig??{},navBar:z(e.rootWindowConfig??{},e.appId)}),[e,t]),[{shell:y,tabBar:x},S]=(0,r.useState)(()=>({shell:j(_),tabBar:v(g)})),C=(0,r.useRef)({shell:y,tabBar:x});(0,r.useEffect)(()=>{C.current={shell:y,tabBar:x}},[y,x]);let w=(0,r.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,r.useEffect)(()=>e.onSimulatorEvent(n.NAV_BAR,e=>{S(t=>({...t,shell:U(t.shell,e.bridgeId,t=>B(t,e.name,e.params))}))}),[e]),(0,r.useEffect)(()=>e.onSimulatorEvent(n.TAB_ACTION,t=>{let n=b(C.current.tabBar,{kind:`apply`,name:t.name,params:t.params});S(e=>({...e,tabBar:n.state})),e.notifyNavCallback({ok:n.ok,errMsg:n.errMsg,callbacks:t.callbacks})}),[e]);let T=(0,r.useCallback)(async t=>{let n=(n,r)=>e.notifyNavCallback({ok:n,errMsg:r,callbacks:t.callbacks});try{switch(t.name){case`navigateTo`:await J(e,C,S,w,t,n);break;case`navigateBack`:Y(C,S,w,t,n);break;case`redirectTo`:await X(e,C,S,w,t,n);break;case`reLaunch`:await Z(e,C,S,w,t,n);break;case`switchTab`:await Q(e,C,S,w,t,n);break}}catch(e){n(!1,`${t.name}:fail ${e instanceof Error?e.message:String(e)}`)}},[e,w]);(0,r.useEffect)(()=>e.onSimulatorEvent(n.NAV_ACTION,e=>{T(e)}),[T,e]),(0,r.useEffect)(()=>e.onSimulatorEvent(n.API_CALL,t=>{o(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 E=(0,r.useCallback)(()=>{if(C.current.shell.stack.length<=1)return;let t=C.current.shell.stack;T({appSessionId:e.appSessionId??``,bridgeId:t[t.length-1].bridgeId,name:`navigateBack`,params:{delta:1},callbacks:{}})},[e,T]),D=(0,r.useCallback)(t=>{let n=C.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]),O=y.stack[y.stack.length-1],A=R(y);return(0,r.useEffect)(()=>{e.notifyActivePage(O.bridgeId)},[e,O.bridgeId]),(0,r.useEffect)(()=>{e.notifyPageStack(y.stack.map(e=>({pagePath:e.pagePath,query:e.query})))},[e,y.stack]),(0,s.jsx)(`main`,{className:`device-shell-root`,children:(0,s.jsxs)(`section`,{className:`device-shell`,"aria-label":`Dimina simulator`,style:a?{width:a.screenWidth,height:a.screenHeight}:void 0,children:[(0,s.jsx)(p,{height:l,notchType:f,textStyle:O.navBar.textStyle}),(0,s.jsx)(u,{state:O.navBar,stackDepth:y.stack.length,platform:i,statusBarHeight:l,navBarHeight:K,onBack:E}),(0,s.jsx)(`div`,{className:`device-shell__viewport`,children:A.map(({entry:t,visible:n})=>(0,s.jsx)(`webview`,{className:`device-shell__webview`,src:e.createRenderHostUrl(t.bridgeId,t.pagePath,t.isTab),preload:h,allowpopups:`true`,style:{display:n?`flex`:`none`,zIndex:n?100:1}},t.bridgeId))}),O.isTab&&(0,s.jsx)(m,{state:x,currentPath:y.currentTabPath,resourceBaseUrl:e.resourceBaseUrl,appId:e.appId,onSwitch:D,bottomInset:d}),d>0&&(0,s.jsx)(`div`,{className:`device-shell__home-indicator`,style:{height:d},"aria-hidden":`true`})]})})}async function J(e,t,n,r,i,a){let{pagePath:o,query:s}=A(i.params.url);if(!o){a(!1,`navigateTo:fail invalid url`);return}if(e.getTabBarConfig()?.list.some(e=>k(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:z(c.windowConfig,e.appId)},{next:u,effects:d}=N(t.current.shell,l);n(e=>({...e,shell:u})),r(d),a(!0,`navigateTo:ok`)}function Y(e,t,n,r,i){let a=r.params.delta,o=Number.isFinite(Number(a))?Number(a):1,s=P(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 X(e,t,n,r,i,a){let{pagePath:o,query:s}=A(i.params.url);if(!o){a(!1,`redirectTo:fail invalid url`);return}if(e.getTabBarConfig()?.list.some(e=>k(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:z(c.windowConfig,e.appId)},{next:u,effects:d}=F(t.current.shell,l);n(e=>({...e,shell:u})),r(d),a(!0,`redirectTo:ok`)}async function Z(e,t,n,r,i,a){let{pagePath:o,query:s}=A(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:z(c.windowConfig,e.appId)},{next:u,effects:d}=I(t.current.shell,l);n(e=>({...e,shell:u})),r(d),a(!0,`reLaunch:ok`)}async function Q(e,t,n,r,i,a){let{pagePath:o}=A(i.params.url);if(!o){a(!1,`switchTab:fail invalid url`);return}if(!e.getTabBarConfig()?.list.some(e=>k(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:z(t.windowConfig,e.appId)}}let{next:l,effects:u}=L(t.current.shell,o,c);n(e=>({...e,shell:l})),r(u),a(!0,`switchTab:ok`)}export{q as DeviceShell};
|
|
2
|
+
//# sourceMappingURL=device-shell-CPCnCp1L.js.map
|