@vforsh/argus 0.3.0 → 0.4.0
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/.tsbuildinfo +1 -1
- package/dist/argus.js +5251 -5487
- package/dist/cdp/resolveCdpEndpoint.d.ts.map +1 -1
- package/dist/cdp/resolveCdpEndpoint.js +2 -1
- package/dist/cdp/resolveCdpEndpoint.js.map +1 -1
- package/dist/cli/defineCommand.d.ts +12 -0
- package/dist/cli/defineCommand.d.ts.map +1 -1
- package/dist/cli/defineCommand.js +71 -1
- package/dist/cli/defineCommand.js.map +1 -1
- package/dist/cli/defineWatcherCommand.d.ts +12 -54
- package/dist/cli/defineWatcherCommand.d.ts.map +1 -1
- package/dist/cli/defineWatcherCommand.js +1 -1
- package/dist/cli/defineWatcherCommand.js.map +1 -1
- package/dist/cli/parse.d.ts +1 -2
- package/dist/cli/parse.d.ts.map +1 -1
- package/dist/cli/parse.js +2 -10
- package/dist/cli/parse.js.map +1 -1
- package/dist/cli/plugins/pluginHost.d.ts.map +1 -1
- package/dist/cli/plugins/pluginHost.js +1 -1
- package/dist/cli/plugins/pluginHost.js.map +1 -1
- package/dist/cli/plugins/registerPlugins.d.ts.map +1 -1
- package/dist/cli/plugins/registerPlugins.js +10 -8
- package/dist/cli/plugins/registerPlugins.js.map +1 -1
- package/dist/cli/program.d.ts.map +1 -1
- package/dist/cli/program.js +4 -0
- package/dist/cli/program.js.map +1 -1
- package/dist/cli/register/authCommands.d.ts.map +1 -1
- package/dist/cli/register/authCommands.js +8 -7
- package/dist/cli/register/authCommands.js.map +1 -1
- package/dist/cli/register/chromeCommands.d.ts.map +1 -1
- package/dist/cli/register/chromeCommands.js +12 -27
- package/dist/cli/register/chromeCommands.js.map +1 -1
- package/dist/cli/register/codeCommands.d.ts.map +1 -1
- package/dist/cli/register/codeCommands.js +7 -6
- package/dist/cli/register/codeCommands.js.map +1 -1
- package/dist/cli/register/dialogCommands.d.ts.map +1 -1
- package/dist/cli/register/dialogCommands.js +3 -2
- package/dist/cli/register/dialogCommands.js.map +1 -1
- package/dist/cli/register/domCommandBuilder.d.ts.map +1 -1
- package/dist/cli/register/domCommandBuilder.js +2 -1
- package/dist/cli/register/domCommandBuilder.js.map +1 -1
- package/dist/cli/register/domCommands.d.ts.map +1 -1
- package/dist/cli/register/domCommands.js +7 -6
- package/dist/cli/register/domCommands.js.map +1 -1
- package/dist/cli/register/evalCommands.d.ts.map +1 -1
- package/dist/cli/register/evalCommands.js +30 -49
- package/dist/cli/register/evalCommands.js.map +1 -1
- package/dist/cli/register/extensionCommands.d.ts.map +1 -1
- package/dist/cli/register/extensionCommands.js +1 -1
- package/dist/cli/register/extensionCommands.js.map +1 -1
- package/dist/cli/register/fillCommand.d.ts.map +1 -1
- package/dist/cli/register/fillCommand.js +11 -4
- package/dist/cli/register/fillCommand.js.map +1 -1
- package/dist/cli/register/hoverCommand.d.ts.map +1 -1
- package/dist/cli/register/hoverCommand.js +2 -1
- package/dist/cli/register/hoverCommand.js.map +1 -1
- package/dist/cli/register/keydownCommand.d.ts.map +1 -1
- package/dist/cli/register/keydownCommand.js +2 -1
- package/dist/cli/register/keydownCommand.js.map +1 -1
- package/dist/cli/register/locateCommands.d.ts.map +1 -1
- package/dist/cli/register/locateCommands.js +2 -1
- package/dist/cli/register/locateCommands.js.map +1 -1
- package/dist/cli/register/logsCommands.d.ts.map +1 -1
- package/dist/cli/register/logsCommands.js +8 -10
- package/dist/cli/register/logsCommands.js.map +1 -1
- package/dist/cli/register/netCommands.d.ts +0 -5
- package/dist/cli/register/netCommands.d.ts.map +1 -1
- package/dist/cli/register/netCommands.js +17 -143
- package/dist/cli/register/netCommands.js.map +1 -1
- package/dist/cli/register/pageCommands.d.ts.map +1 -1
- package/dist/cli/register/pageCommands.js +8 -7
- package/dist/cli/register/pageCommands.js.map +1 -1
- package/dist/cli/register/pluginCommands.d.ts.map +1 -1
- package/dist/cli/register/pluginCommands.js +3 -2
- package/dist/cli/register/pluginCommands.js.map +1 -1
- package/dist/cli/register/quickAccessCommands.d.ts.map +1 -1
- package/dist/cli/register/quickAccessCommands.js +16 -31
- package/dist/cli/register/quickAccessCommands.js.map +1 -1
- package/dist/cli/register/recordCommands.d.ts.map +1 -1
- package/dist/cli/register/recordCommands.js +12 -34
- package/dist/cli/register/recordCommands.js.map +1 -1
- package/dist/cli/register/scrollToCommand.d.ts.map +1 -1
- package/dist/cli/register/scrollToCommand.js +2 -1
- package/dist/cli/register/scrollToCommand.js.map +1 -1
- package/dist/cli/register/sharedOptions.d.ts +11 -0
- package/dist/cli/register/sharedOptions.d.ts.map +1 -0
- package/dist/cli/register/sharedOptions.js +10 -0
- package/dist/cli/register/sharedOptions.js.map +1 -0
- package/dist/cli/register/skillCommands.d.ts.map +1 -1
- package/dist/cli/register/skillCommands.js +2 -1
- package/dist/cli/register/skillCommands.js.map +1 -1
- package/dist/cli/register/snapshotCommands.d.ts.map +1 -1
- package/dist/cli/register/snapshotCommands.js +3 -2
- package/dist/cli/register/snapshotCommands.js.map +1 -1
- package/dist/cli/register/storageCommands.d.ts.map +1 -1
- package/dist/cli/register/storageCommands.js +2 -1
- package/dist/cli/register/storageCommands.js.map +1 -1
- package/dist/cli/register/throttleCommands.d.ts.map +1 -1
- package/dist/cli/register/throttleCommands.js +4 -3
- package/dist/cli/register/throttleCommands.js.map +1 -1
- package/dist/cli/register/traceCommands.d.ts.map +1 -1
- package/dist/cli/register/traceCommands.js +10 -30
- package/dist/cli/register/traceCommands.js.map +1 -1
- package/dist/cli/register/watcherCommands.d.ts.map +1 -1
- package/dist/cli/register/watcherCommands.js +12 -24
- package/dist/cli/register/watcherCommands.js.map +1 -1
- package/dist/cli/validation.d.ts +14 -0
- package/dist/cli/validation.d.ts.map +1 -1
- package/dist/cli/validation.js +17 -6
- package/dist/cli/validation.js.map +1 -1
- package/dist/commands/auth.d.ts.map +1 -1
- package/dist/commands/auth.js +3 -2
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/authCookieSupport.d.ts +4 -2
- package/dist/commands/authCookieSupport.d.ts.map +1 -1
- package/dist/commands/authCookieSupport.js +0 -4
- package/dist/commands/authCookieSupport.js.map +1 -1
- package/dist/commands/authCookies.d.ts +4 -4
- package/dist/commands/authCookies.d.ts.map +1 -1
- package/dist/commands/chrome/authState.d.ts +0 -12
- package/dist/commands/chrome/authState.d.ts.map +1 -1
- package/dist/commands/chrome/authState.js +0 -14
- package/dist/commands/chrome/authState.js.map +1 -1
- package/dist/commands/chrome/browser.d.ts.map +1 -1
- package/dist/commands/chrome/browser.js +2 -1
- package/dist/commands/chrome/browser.js.map +1 -1
- package/dist/commands/chrome/shared.d.ts.map +1 -1
- package/dist/commands/chrome/shared.js +3 -2
- package/dist/commands/chrome/shared.js.map +1 -1
- package/dist/commands/chrome/targets.d.ts.map +1 -1
- package/dist/commands/chrome/targets.js +6 -5
- package/dist/commands/chrome/targets.js.map +1 -1
- package/dist/commands/chromeStart.d.ts +10 -0
- package/dist/commands/chromeStart.d.ts.map +1 -1
- package/dist/commands/chromeStart.js +50 -41
- package/dist/commands/chromeStart.js.map +1 -1
- package/dist/commands/code.d.ts +2 -2
- package/dist/commands/code.d.ts.map +1 -1
- package/dist/commands/codeEdit.d.ts.map +1 -1
- package/dist/commands/codeEdit.js +3 -2
- package/dist/commands/codeEdit.js.map +1 -1
- package/dist/commands/configInit.d.ts +1 -0
- package/dist/commands/configInit.d.ts.map +1 -1
- package/dist/commands/configInit.js +17 -14
- package/dist/commands/configInit.js.map +1 -1
- package/dist/commands/dialog.d.ts +4 -4
- package/dist/commands/dialog.d.ts.map +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +14 -10
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/dom/shared.js +1 -1
- package/dist/commands/dom/shared.js.map +1 -1
- package/dist/commands/domAdd.d.ts +1 -1
- package/dist/commands/domAdd.d.ts.map +1 -1
- package/dist/commands/domAdd.js +10 -54
- package/dist/commands/domAdd.js.map +1 -1
- package/dist/commands/domAddScript.d.ts.map +1 -1
- package/dist/commands/domAddScript.js +14 -58
- package/dist/commands/domAddScript.js.map +1 -1
- package/dist/commands/domClick.d.ts +1 -2
- package/dist/commands/domClick.d.ts.map +1 -1
- package/dist/commands/domClick.js +2 -4
- package/dist/commands/domClick.js.map +1 -1
- package/dist/commands/domDrag.d.ts +1 -2
- package/dist/commands/domDrag.d.ts.map +1 -1
- package/dist/commands/domDrag.js +3 -5
- package/dist/commands/domDrag.js.map +1 -1
- package/dist/commands/domFill.d.ts +2 -1
- package/dist/commands/domFill.d.ts.map +1 -1
- package/dist/commands/domFill.js +10 -42
- package/dist/commands/domFill.js.map +1 -1
- package/dist/commands/domFocus.d.ts +1 -1
- package/dist/commands/domFocus.d.ts.map +1 -1
- package/dist/commands/domHover.d.ts +1 -1
- package/dist/commands/domHover.d.ts.map +1 -1
- package/dist/commands/domInfo.d.ts +1 -1
- package/dist/commands/domInfo.d.ts.map +1 -1
- package/dist/commands/domKeydown.d.ts +1 -1
- package/dist/commands/domKeydown.d.ts.map +1 -1
- package/dist/commands/domModify.d.ts.map +1 -1
- package/dist/commands/domModify.js +6 -7
- package/dist/commands/domModify.js.map +1 -1
- package/dist/commands/domRemove.d.ts +1 -1
- package/dist/commands/domRemove.d.ts.map +1 -1
- package/dist/commands/domScroll.d.ts +1 -1
- package/dist/commands/domScroll.d.ts.map +1 -1
- package/dist/commands/domScroll.js +16 -10
- package/dist/commands/domScroll.js.map +1 -1
- package/dist/commands/domScrollTo.d.ts +1 -1
- package/dist/commands/domScrollTo.d.ts.map +1 -1
- package/dist/commands/domSetFile.d.ts +1 -1
- package/dist/commands/domSetFile.d.ts.map +1 -1
- package/dist/commands/domTree.d.ts +1 -1
- package/dist/commands/domTree.d.ts.map +1 -1
- package/dist/commands/eval.d.ts +3 -32
- package/dist/commands/eval.d.ts.map +1 -1
- package/dist/commands/eval.js +14 -33
- package/dist/commands/eval.js.map +1 -1
- package/dist/commands/evalBundle.js +2 -1
- package/dist/commands/evalBundle.js.map +1 -1
- package/dist/commands/evalEmit.d.ts +35 -0
- package/dist/commands/evalEmit.d.ts.map +1 -0
- package/dist/commands/evalEmit.js +65 -0
- package/dist/commands/evalEmit.js.map +1 -0
- package/dist/commands/evalIframe.d.ts +16 -0
- package/dist/commands/evalIframe.d.ts.map +1 -0
- package/dist/commands/evalIframe.js +37 -0
- package/dist/commands/evalIframe.js.map +1 -0
- package/dist/commands/evalShared.d.ts +52 -44
- package/dist/commands/evalShared.d.ts.map +1 -1
- package/dist/commands/evalShared.js +64 -192
- package/dist/commands/evalShared.js.map +1 -1
- package/dist/commands/evalUntil.d.ts +4 -32
- package/dist/commands/evalUntil.d.ts.map +1 -1
- package/dist/commands/evalUntil.js +9 -29
- package/dist/commands/evalUntil.js.map +1 -1
- package/dist/commands/extension/attach.d.ts.map +1 -1
- package/dist/commands/extension/attach.js +12 -28
- package/dist/commands/extension/attach.js.map +1 -1
- package/dist/commands/extension/doctor.d.ts.map +1 -1
- package/dist/commands/extension/doctor.js +10 -1
- package/dist/commands/extension/doctor.js.map +1 -1
- package/dist/commands/extension/failures.d.ts +62 -0
- package/dist/commands/extension/failures.d.ts.map +1 -0
- package/dist/commands/extension/failures.js +70 -0
- package/dist/commands/extension/failures.js.map +1 -0
- package/dist/commands/extension/info.d.ts.map +1 -1
- package/dist/commands/extension/info.js +4 -14
- package/dist/commands/extension/info.js.map +1 -1
- package/dist/commands/extension/install.d.ts.map +1 -1
- package/dist/commands/extension/install.js +12 -22
- package/dist/commands/extension/install.js.map +1 -1
- package/dist/commands/extension/nativeHost.d.ts +22 -0
- package/dist/commands/extension/nativeHost.d.ts.map +1 -1
- package/dist/commands/extension/nativeHost.js +38 -7
- package/dist/commands/extension/nativeHost.js.map +1 -1
- package/dist/commands/extension/remove.d.ts.map +1 -1
- package/dist/commands/extension/remove.js +5 -15
- package/dist/commands/extension/remove.js.map +1 -1
- package/dist/commands/extension/resolveExtensionWatcher.d.ts.map +1 -1
- package/dist/commands/extension/resolveExtensionWatcher.js +3 -2
- package/dist/commands/extension/resolveExtensionWatcher.js.map +1 -1
- package/dist/commands/extension/select.js +11 -23
- package/dist/commands/extension/select.js.map +1 -1
- package/dist/commands/extension/setup.d.ts.map +1 -1
- package/dist/commands/extension/setup.js +8 -30
- package/dist/commands/extension/setup.js.map +1 -1
- package/dist/commands/extension/show.d.ts.map +1 -1
- package/dist/commands/extension/show.js +10 -17
- package/dist/commands/extension/show.js.map +1 -1
- package/dist/commands/extension/status.d.ts.map +1 -1
- package/dist/commands/extension/status.js +5 -14
- package/dist/commands/extension/status.js.map +1 -1
- package/dist/commands/extension/tabAttach.d.ts.map +1 -1
- package/dist/commands/extension/tabAttach.js +2 -2
- package/dist/commands/extension/tabAttach.js.map +1 -1
- package/dist/commands/extension/tabSelection.d.ts.map +1 -1
- package/dist/commands/extension/tabSelection.js +1 -1
- package/dist/commands/extension/tabSelection.js.map +1 -1
- package/dist/commands/extension/tabWatcher.d.ts +7 -1
- package/dist/commands/extension/tabWatcher.d.ts.map +1 -1
- package/dist/commands/extension/tabWatcher.js +17 -21
- package/dist/commands/extension/tabWatcher.js.map +1 -1
- package/dist/commands/extension/tabs.d.ts.map +1 -1
- package/dist/commands/extension/tabs.js +6 -31
- package/dist/commands/extension/tabs.js.map +1 -1
- package/dist/commands/extension/targetSelection.d.ts +10 -23
- package/dist/commands/extension/targetSelection.d.ts.map +1 -1
- package/dist/commands/extension/targetSelection.js +4 -4
- package/dist/commands/extension/targetSelection.js.map +1 -1
- package/dist/commands/extension/targets.js +2 -11
- package/dist/commands/extension/targets.js.map +1 -1
- package/dist/commands/iframeHelper.d.ts +13 -0
- package/dist/commands/iframeHelper.d.ts.map +1 -1
- package/dist/commands/iframeHelper.js +7 -1
- package/dist/commands/iframeHelper.js.map +1 -1
- package/dist/commands/inputSource.d.ts +57 -0
- package/dist/commands/inputSource.d.ts.map +1 -0
- package/dist/commands/inputSource.js +75 -0
- package/dist/commands/inputSource.js.map +1 -0
- package/dist/commands/list.d.ts.map +1 -1
- package/dist/commands/list.js +14 -6
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/logs.d.ts +3 -3
- package/dist/commands/logs.d.ts.map +1 -1
- package/dist/commands/net.d.ts +1 -1
- package/dist/commands/net.d.ts.map +1 -1
- package/dist/commands/netClear.d.ts +1 -1
- package/dist/commands/netClear.d.ts.map +1 -1
- package/dist/commands/netExport.d.ts.map +1 -1
- package/dist/commands/netExport.js +9 -31
- package/dist/commands/netExport.js.map +1 -1
- package/dist/commands/netInspect.d.ts.map +1 -1
- package/dist/commands/netInspect.js +2 -1
- package/dist/commands/netInspect.js.map +1 -1
- package/dist/commands/netMock.d.ts +4 -4
- package/dist/commands/netMock.d.ts.map +1 -1
- package/dist/commands/netMock.js +2 -2
- package/dist/commands/netMock.js.map +1 -1
- package/dist/commands/netRequestClient.d.ts +2 -2
- package/dist/commands/netRequestClient.d.ts.map +1 -1
- package/dist/commands/netRequestClient.js.map +1 -1
- package/dist/commands/netShared.d.ts +22 -0
- package/dist/commands/netShared.d.ts.map +1 -1
- package/dist/commands/netShared.js +43 -16
- package/dist/commands/netShared.js.map +1 -1
- package/dist/commands/netSse.d.ts +1 -1
- package/dist/commands/netSse.d.ts.map +1 -1
- package/dist/commands/netSummary.js +6 -25
- package/dist/commands/netSummary.js.map +1 -1
- package/dist/commands/netWebSocket.d.ts +2 -2
- package/dist/commands/netWebSocket.d.ts.map +1 -1
- package/dist/commands/page.d.ts +8 -0
- package/dist/commands/page.d.ts.map +1 -1
- package/dist/commands/page.js +83 -83
- package/dist/commands/page.js.map +1 -1
- package/dist/commands/pageEmulation.d.ts +3 -3
- package/dist/commands/pageEmulation.d.ts.map +1 -1
- package/dist/commands/pageEmulation.js +17 -12
- package/dist/commands/pageEmulation.js.map +1 -1
- package/dist/commands/pluginConfig.d.ts.map +1 -1
- package/dist/commands/pluginConfig.js +21 -20
- package/dist/commands/pluginConfig.js.map +1 -1
- package/dist/commands/record.d.ts +3 -3
- package/dist/commands/record.d.ts.map +1 -1
- package/dist/commands/record.js +1 -1
- package/dist/commands/record.js.map +1 -1
- package/dist/commands/reload.d.ts +1 -1
- package/dist/commands/reload.d.ts.map +1 -1
- package/dist/commands/resolveTestId.d.ts.map +1 -1
- package/dist/commands/resolveTestId.js +2 -3
- package/dist/commands/resolveTestId.js.map +1 -1
- package/dist/commands/screenshot.d.ts +1 -1
- package/dist/commands/screenshot.d.ts.map +1 -1
- package/dist/commands/snapshot.d.ts +1 -1
- package/dist/commands/snapshot.d.ts.map +1 -1
- package/dist/commands/start.d.ts.map +1 -1
- package/dist/commands/start.js +6 -28
- package/dist/commands/start.js.map +1 -1
- package/dist/commands/startShared.d.ts.map +1 -1
- package/dist/commands/startShared.js +2 -1
- package/dist/commands/startShared.js.map +1 -1
- package/dist/commands/throttle.d.ts +3 -3
- package/dist/commands/throttle.d.ts.map +1 -1
- package/dist/commands/throttle.js +2 -3
- package/dist/commands/throttle.js.map +1 -1
- package/dist/commands/trace.d.ts.map +1 -1
- package/dist/commands/trace.js +2 -2
- package/dist/commands/trace.js.map +1 -1
- package/dist/commands/watcherNativeHost.d.ts.map +1 -1
- package/dist/commands/watcherNativeHost.js +4 -1
- package/dist/commands/watcherNativeHost.js.map +1 -1
- package/dist/commands/watcherPrune.d.ts.map +1 -1
- package/dist/commands/watcherPrune.js +3 -3
- package/dist/commands/watcherPrune.js.map +1 -1
- package/dist/commands/watcherSession.d.ts.map +1 -1
- package/dist/commands/watcherSession.js +2 -1
- package/dist/commands/watcherSession.js.map +1 -1
- package/dist/commands/watcherStatus.d.ts +1 -1
- package/dist/commands/watcherStatus.d.ts.map +1 -1
- package/dist/commands/watcherStatus.js +5 -0
- package/dist/commands/watcherStatus.js.map +1 -1
- package/dist/commands/watcherStop.d.ts.map +1 -1
- package/dist/commands/watcherStop.js +2 -2
- package/dist/commands/watcherStop.js.map +1 -1
- package/dist/config/configContext.d.ts +27 -0
- package/dist/config/configContext.d.ts.map +1 -0
- package/dist/config/configContext.js +57 -0
- package/dist/config/configContext.js.map +1 -0
- package/dist/config/loadConfig.d.ts.map +1 -1
- package/dist/config/loadConfig.js +3 -2
- package/dist/config/loadConfig.js.map +1 -1
- package/dist/eval/evalClient.d.ts.map +1 -1
- package/dist/eval/evalClient.js +2 -1
- package/dist/eval/evalClient.js.map +1 -1
- package/dist/extension/dist/background/service-worker.js +469 -449
- package/dist/extension/dist/background/service-worker.js.map +4 -4
- package/dist/extension/dist/popup/popup.js +279 -234
- package/dist/extension/dist/popup/popup.js.map +4 -4
- package/dist/extension/manifest.json +1 -1
- package/dist/internal.d.ts +22 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +22 -0
- package/dist/internal.js.map +1 -0
- package/dist/output/io.d.ts +8 -9
- package/dist/output/io.d.ts.map +1 -1
- package/dist/output/io.js.map +1 -1
- package/dist/registry.d.ts +1 -4
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +4 -25
- package/dist/registry.js.map +1 -1
- package/dist/runtime-code/format.d.ts.map +1 -1
- package/dist/runtime-code/format.js +2 -1
- package/dist/runtime-code/format.js.map +1 -1
- package/dist/skill/argus/SKILL.md +7 -0
- package/dist/skill/argus/reference/EXTENSION.md +8 -0
- package/dist/watchers/queryParams.d.ts +11 -9
- package/dist/watchers/queryParams.d.ts.map +1 -1
- package/dist/watchers/queryParams.js +63 -86
- package/dist/watchers/queryParams.js.map +1 -1
- package/dist/watchers/requestWatcher.d.ts +7 -25
- package/dist/watchers/requestWatcher.d.ts.map +1 -1
- package/dist/watchers/requestWatcher.js +9 -6
- package/dist/watchers/requestWatcher.js.map +1 -1
- package/dist/watchers/resolveWatcher.d.ts.map +1 -1
- package/dist/watchers/resolveWatcher.js +9 -2
- package/dist/watchers/resolveWatcher.js.map +1 -1
- package/package.json +9 -5
- package/dist/time.d.ts +0 -3
- package/dist/time.d.ts.map +0 -1
- package/dist/time.js +0 -19
- package/dist/time.js.map +0 -1
|
@@ -1,10 +1,125 @@
|
|
|
1
|
+
// src/background/frame-table.ts
|
|
2
|
+
var applyFrameTreeSnapshot = (table, sessionId, node) => {
|
|
3
|
+
if (!node?.frame?.id) {
|
|
4
|
+
return;
|
|
5
|
+
}
|
|
6
|
+
const nextFrameIds = /* @__PURE__ */ new Set();
|
|
7
|
+
mergeFrameTree(table, sessionId, node, nextFrameIds);
|
|
8
|
+
for (const [frameId, frame] of table.frames.entries()) {
|
|
9
|
+
if (frame.sessionId === sessionId && !nextFrameIds.has(frameId)) {
|
|
10
|
+
table.frames.delete(frameId);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
var mergeFrameTree = (table, sessionId, node, nextFrameIds) => {
|
|
15
|
+
if (!node?.frame?.id) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const frameId = node.frame.id;
|
|
19
|
+
nextFrameIds.add(frameId);
|
|
20
|
+
table.frames.set(frameId, toFrameRecord(node.frame, sessionId));
|
|
21
|
+
if (!node.frame.parentId && !sessionId) {
|
|
22
|
+
table.topFrameId = frameId;
|
|
23
|
+
}
|
|
24
|
+
for (const child of node.childFrames ?? []) {
|
|
25
|
+
mergeFrameTree(table, sessionId, child, nextFrameIds);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
var applyFrameEvent = (table, sessionId, method, params) => {
|
|
29
|
+
if (method === "Page.frameNavigated" && params) {
|
|
30
|
+
const frame = params.frame;
|
|
31
|
+
if (!frame?.id) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
table.frames.set(frame.id, toFrameRecord(frame, sessionId));
|
|
35
|
+
if (!frame.parentId && !sessionId && frame.url) {
|
|
36
|
+
table.url = frame.url;
|
|
37
|
+
table.topFrameId = frame.id;
|
|
38
|
+
}
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
if (method === "Page.frameAttached" && params) {
|
|
42
|
+
const frame = params;
|
|
43
|
+
if (!frame.frameId) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
const existing = table.frames.get(frame.frameId);
|
|
47
|
+
table.frames.set(frame.frameId, {
|
|
48
|
+
frameId: frame.frameId,
|
|
49
|
+
parentFrameId: frame.parentFrameId ?? table.topFrameId,
|
|
50
|
+
url: existing?.url ?? "",
|
|
51
|
+
title: existing?.title ?? null,
|
|
52
|
+
sessionId: existing?.sessionId ?? sessionId
|
|
53
|
+
});
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
if (method === "Page.frameDetached" && params) {
|
|
57
|
+
const frame = params;
|
|
58
|
+
if (!frame.frameId) {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
return table.frames.delete(frame.frameId);
|
|
62
|
+
}
|
|
63
|
+
return false;
|
|
64
|
+
};
|
|
65
|
+
var dropSessionFrames = (table, sessionId) => {
|
|
66
|
+
let removed = false;
|
|
67
|
+
for (const [frameId, frame] of table.frames.entries()) {
|
|
68
|
+
if (frame.sessionId === sessionId) {
|
|
69
|
+
table.frames.delete(frameId);
|
|
70
|
+
removed = true;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return removed;
|
|
74
|
+
};
|
|
75
|
+
var serializeFrameTable = (table) => {
|
|
76
|
+
const frames = [...table.frames.values()].sort((a, b) => a.frameId.localeCompare(b.frameId));
|
|
77
|
+
return JSON.stringify({ topFrameId: table.topFrameId, frames });
|
|
78
|
+
};
|
|
79
|
+
var toFrameRecord = (frame, sessionId) => ({
|
|
80
|
+
frameId: frame.id,
|
|
81
|
+
parentFrameId: frame.parentId ?? null,
|
|
82
|
+
url: frame.url ?? "",
|
|
83
|
+
title: frame.name ?? null,
|
|
84
|
+
sessionId
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// src/background/tab-cookies.ts
|
|
88
|
+
var readTabCookies = async (tabId, query = {}) => {
|
|
89
|
+
const storeId = await findCookieStoreId(tabId);
|
|
90
|
+
const cookies = await chrome.cookies.getAll({
|
|
91
|
+
domain: query.domain,
|
|
92
|
+
storeId: storeId ?? void 0,
|
|
93
|
+
url: query.domain ? void 0 : query.url
|
|
94
|
+
});
|
|
95
|
+
return cookies.map((cookie) => ({
|
|
96
|
+
name: cookie.name,
|
|
97
|
+
value: cookie.value,
|
|
98
|
+
domain: cookie.domain,
|
|
99
|
+
path: cookie.path,
|
|
100
|
+
secure: cookie.secure,
|
|
101
|
+
httpOnly: cookie.httpOnly,
|
|
102
|
+
session: cookie.session,
|
|
103
|
+
expires: typeof cookie.expirationDate === "number" ? cookie.expirationDate : null,
|
|
104
|
+
sameSite: cookie.sameSite ?? null
|
|
105
|
+
}));
|
|
106
|
+
};
|
|
107
|
+
var findCookieStoreId = async (tabId) => {
|
|
108
|
+
const stores = await chrome.cookies.getAllCookieStores();
|
|
109
|
+
const store = stores.find((candidate) => candidate.tabIds.includes(tabId));
|
|
110
|
+
return store?.id ?? null;
|
|
111
|
+
};
|
|
112
|
+
|
|
1
113
|
// src/background/debugger-manager.ts
|
|
2
114
|
var FRAME_TREE_SYNC_DELAY_MS = 150;
|
|
3
115
|
var DebuggerManager = class {
|
|
4
116
|
attached = /* @__PURE__ */ new Map();
|
|
5
117
|
eventHandlers = /* @__PURE__ */ new Set();
|
|
6
118
|
detachHandlers = /* @__PURE__ */ new Set();
|
|
119
|
+
framesChangedHandlers = /* @__PURE__ */ new Set();
|
|
7
120
|
frameTreeSyncTimers = /* @__PURE__ */ new Map();
|
|
121
|
+
/** Last published frame table per tab; publishes that change nothing are suppressed. */
|
|
122
|
+
lastPublishedFrames = /* @__PURE__ */ new Map();
|
|
8
123
|
constructor() {
|
|
9
124
|
chrome.debugger.onEvent.addListener((debuggee, method, params) => {
|
|
10
125
|
this.handleCdpEvent(debuggee, method, params);
|
|
@@ -27,6 +142,13 @@ var DebuggerManager = class {
|
|
|
27
142
|
this.detachHandlers.delete(handler);
|
|
28
143
|
};
|
|
29
144
|
}
|
|
145
|
+
/** Subscribe to authoritative frame-table changes (deduplicated; see class doc). */
|
|
146
|
+
onFramesChanged(handler) {
|
|
147
|
+
this.framesChangedHandlers.add(handler);
|
|
148
|
+
return () => {
|
|
149
|
+
this.framesChangedHandlers.delete(handler);
|
|
150
|
+
};
|
|
151
|
+
}
|
|
30
152
|
emitEvent(tabId, method, params, sessionId) {
|
|
31
153
|
for (const handler of this.eventHandlers) {
|
|
32
154
|
handler(tabId, method, params, { sessionId });
|
|
@@ -59,6 +181,7 @@ var DebuggerManager = class {
|
|
|
59
181
|
this.attached.set(tabId, target);
|
|
60
182
|
await this.configureAutoAttach(tabId);
|
|
61
183
|
await this.refreshFrameTree(tabId, null);
|
|
184
|
+
this.lastPublishedFrames.set(tabId, serializeFrameTable(target));
|
|
62
185
|
return target;
|
|
63
186
|
}
|
|
64
187
|
async detach(tabId) {
|
|
@@ -69,6 +192,7 @@ var DebuggerManager = class {
|
|
|
69
192
|
} catch {
|
|
70
193
|
}
|
|
71
194
|
this.attached.delete(tabId);
|
|
195
|
+
this.lastPublishedFrames.delete(tabId);
|
|
72
196
|
}
|
|
73
197
|
async sendCommand(tabId, method, params, sessionId) {
|
|
74
198
|
const target = this.getRequiredTarget(tabId);
|
|
@@ -100,29 +224,35 @@ var DebuggerManager = class {
|
|
|
100
224
|
}
|
|
101
225
|
return [...target.frames.values()];
|
|
102
226
|
}
|
|
227
|
+
/** Current authoritative frame table for a tab, in `frame_snapshot` payload shape. */
|
|
228
|
+
getFrameSnapshot(tabId) {
|
|
229
|
+
return {
|
|
230
|
+
topFrameId: this.attached.get(tabId)?.topFrameId ?? null,
|
|
231
|
+
frames: this.getFrames(tabId)
|
|
232
|
+
};
|
|
233
|
+
}
|
|
103
234
|
/**
|
|
104
|
-
*
|
|
105
|
-
*
|
|
235
|
+
* Re-read `Page.getFrameTree` for the root and every child session, then return the
|
|
236
|
+
* fresh table. Serves `frame_snapshot_request { refresh: true }` (bootstrap and target
|
|
237
|
+
* recovery on the watcher side). Marks the result as published — the caller ships it
|
|
238
|
+
* as the request's reply, so no push should follow for the same state.
|
|
106
239
|
*/
|
|
240
|
+
async resyncFrames(tabId) {
|
|
241
|
+
const target = this.getRequiredTarget(tabId);
|
|
242
|
+
await this.refreshFrameTree(tabId, null);
|
|
243
|
+
for (const sessionId of target.childSessions.keys()) {
|
|
244
|
+
try {
|
|
245
|
+
await this.refreshFrameTree(tabId, sessionId);
|
|
246
|
+
} catch {
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
this.lastPublishedFrames.set(tabId, serializeFrameTable(target));
|
|
250
|
+
return this.getFrameSnapshot(tabId);
|
|
251
|
+
}
|
|
252
|
+
/** Read cookies from the attached tab's cookie store (see tab-cookies.ts). */
|
|
107
253
|
async getCookies(tabId, query = {}) {
|
|
108
254
|
this.getRequiredTarget(tabId);
|
|
109
|
-
|
|
110
|
-
const cookies = await chrome.cookies.getAll({
|
|
111
|
-
domain: query.domain,
|
|
112
|
-
storeId: storeId ?? void 0,
|
|
113
|
-
url: query.domain ? void 0 : query.url
|
|
114
|
-
});
|
|
115
|
-
return cookies.map((cookie) => ({
|
|
116
|
-
name: cookie.name,
|
|
117
|
-
value: cookie.value,
|
|
118
|
-
domain: cookie.domain,
|
|
119
|
-
path: cookie.path,
|
|
120
|
-
secure: cookie.secure,
|
|
121
|
-
httpOnly: cookie.httpOnly,
|
|
122
|
-
session: cookie.session,
|
|
123
|
-
expires: typeof cookie.expirationDate === "number" ? cookie.expirationDate : null,
|
|
124
|
-
sameSite: cookie.sameSite ?? null
|
|
125
|
-
}));
|
|
255
|
+
return readTabCookies(tabId, query);
|
|
126
256
|
}
|
|
127
257
|
async configureAutoAttach(tabId, sessionId) {
|
|
128
258
|
await this.sendCommand(
|
|
@@ -167,11 +297,6 @@ var DebuggerManager = class {
|
|
|
167
297
|
}
|
|
168
298
|
return { tabId: target.tabId, sessionId };
|
|
169
299
|
}
|
|
170
|
-
async findCookieStoreId(tabId) {
|
|
171
|
-
const stores = await chrome.cookies.getAllCookieStores();
|
|
172
|
-
const store = stores.find((candidate) => candidate.tabIds.includes(tabId));
|
|
173
|
-
return store?.id ?? null;
|
|
174
|
-
}
|
|
175
300
|
handleCdpEvent(debuggee, method, params) {
|
|
176
301
|
const tabId = debuggee.tabId;
|
|
177
302
|
if (!tabId || !this.attached.has(tabId)) return;
|
|
@@ -210,6 +335,7 @@ var DebuggerManager = class {
|
|
|
210
335
|
await this.configureAutoAttach(tabId, record.sessionId);
|
|
211
336
|
await this.enableChildSessionDomains(tabId, record.sessionId);
|
|
212
337
|
await this.refreshFrameTree(tabId, record.sessionId);
|
|
338
|
+
this.emitFramesChangedIfNeeded(tabId, "child_attached");
|
|
213
339
|
} catch (error) {
|
|
214
340
|
console.warn("[DebuggerManager] Failed to bootstrap child target:", error);
|
|
215
341
|
}
|
|
@@ -229,106 +355,34 @@ var DebuggerManager = class {
|
|
|
229
355
|
}
|
|
230
356
|
async refreshFrameTree(tabId, sessionId) {
|
|
231
357
|
const result = await this.sendCommand(tabId, "Page.getFrameTree", void 0, sessionId);
|
|
232
|
-
this.replaceFrameTreeSnapshot(tabId, sessionId, result.frameTree);
|
|
233
|
-
}
|
|
234
|
-
/**
|
|
235
|
-
* Each `Page.getFrameTree` result is a full snapshot for that session, so merge the refreshed
|
|
236
|
-
* nodes and then prune frames from the same session that no longer exist after reload.
|
|
237
|
-
*/
|
|
238
|
-
replaceFrameTreeSnapshot(tabId, sessionId, node) {
|
|
239
|
-
if (!node?.frame?.id) {
|
|
240
|
-
return;
|
|
241
|
-
}
|
|
242
|
-
const target = this.attached.get(tabId);
|
|
243
|
-
if (!target) {
|
|
244
|
-
return;
|
|
245
|
-
}
|
|
246
|
-
const nextFrameIds = /* @__PURE__ */ new Set();
|
|
247
|
-
this.mergeFrameTree(tabId, sessionId, node, nextFrameIds);
|
|
248
|
-
this.pruneMissingSessionFrames(tabId, sessionId, nextFrameIds);
|
|
249
|
-
}
|
|
250
|
-
mergeFrameTree(tabId, sessionId, node, nextFrameIds) {
|
|
251
|
-
if (!node?.frame?.id) {
|
|
252
|
-
return;
|
|
253
|
-
}
|
|
254
358
|
const target = this.attached.get(tabId);
|
|
255
359
|
if (!target) {
|
|
256
360
|
return;
|
|
257
361
|
}
|
|
258
|
-
|
|
259
|
-
nextFrameIds.add(frameId);
|
|
260
|
-
target.frames.set(frameId, this.toFrameRecord(node.frame, sessionId));
|
|
261
|
-
if (!node.frame.parentId && !sessionId) {
|
|
262
|
-
target.topFrameId = frameId;
|
|
263
|
-
}
|
|
264
|
-
this.emitEvent(
|
|
265
|
-
tabId,
|
|
266
|
-
"Page.frameNavigated",
|
|
267
|
-
{
|
|
268
|
-
frame: {
|
|
269
|
-
id: frameId,
|
|
270
|
-
parentId: node.frame.parentId ?? null,
|
|
271
|
-
url: node.frame.url ?? "",
|
|
272
|
-
name: node.frame.name ?? null
|
|
273
|
-
}
|
|
274
|
-
},
|
|
275
|
-
sessionId
|
|
276
|
-
);
|
|
277
|
-
for (const child of node.childFrames ?? []) {
|
|
278
|
-
this.mergeFrameTree(tabId, sessionId, child, nextFrameIds);
|
|
279
|
-
}
|
|
362
|
+
applyFrameTreeSnapshot(target, sessionId, result.frameTree);
|
|
280
363
|
}
|
|
281
|
-
|
|
364
|
+
updateStateFromEvent(tabId, sessionId, method, params) {
|
|
282
365
|
const target = this.attached.get(tabId);
|
|
283
366
|
if (!target) {
|
|
284
367
|
return;
|
|
285
368
|
}
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
continue;
|
|
289
|
-
}
|
|
290
|
-
target.frames.delete(frameId);
|
|
291
|
-
this.emitEvent(tabId, "Page.frameDetached", { frameId }, sessionId);
|
|
369
|
+
if (applyFrameEvent(target, sessionId, method, params)) {
|
|
370
|
+
this.lastPublishedFrames.set(tabId, serializeFrameTable(target));
|
|
292
371
|
}
|
|
293
372
|
}
|
|
294
|
-
|
|
373
|
+
/** Publish the tab's frame table through onFramesChanged, unless it matches the last publish. */
|
|
374
|
+
emitFramesChangedIfNeeded(tabId, reason) {
|
|
295
375
|
const target = this.attached.get(tabId);
|
|
296
376
|
if (!target) {
|
|
297
377
|
return;
|
|
298
378
|
}
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
if (!frame?.id) {
|
|
302
|
-
return;
|
|
303
|
-
}
|
|
304
|
-
target.frames.set(frame.id, this.toFrameRecord(frame, sessionId));
|
|
305
|
-
if (!frame.parentId && !sessionId && frame.url) {
|
|
306
|
-
target.url = frame.url;
|
|
307
|
-
target.topFrameId = frame.id;
|
|
308
|
-
}
|
|
309
|
-
return;
|
|
310
|
-
}
|
|
311
|
-
if (method === "Page.frameAttached" && params) {
|
|
312
|
-
const frame = params;
|
|
313
|
-
if (!frame.frameId) {
|
|
314
|
-
return;
|
|
315
|
-
}
|
|
316
|
-
const existing = target.frames.get(frame.frameId);
|
|
317
|
-
target.frames.set(frame.frameId, {
|
|
318
|
-
frameId: frame.frameId,
|
|
319
|
-
parentFrameId: frame.parentFrameId ?? target.topFrameId,
|
|
320
|
-
url: existing?.url ?? "",
|
|
321
|
-
title: existing?.title ?? null,
|
|
322
|
-
sessionId: existing?.sessionId ?? sessionId
|
|
323
|
-
});
|
|
379
|
+
const serialized = serializeFrameTable(target);
|
|
380
|
+
if (this.lastPublishedFrames.get(tabId) === serialized) {
|
|
324
381
|
return;
|
|
325
382
|
}
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
return;
|
|
330
|
-
}
|
|
331
|
-
target.frames.delete(frame.frameId);
|
|
383
|
+
this.lastPublishedFrames.set(tabId, serialized);
|
|
384
|
+
for (const handler of this.framesChangedHandlers) {
|
|
385
|
+
handler(tabId, reason);
|
|
332
386
|
}
|
|
333
387
|
}
|
|
334
388
|
/**
|
|
@@ -346,7 +400,9 @@ var DebuggerManager = class {
|
|
|
346
400
|
}
|
|
347
401
|
const timer = setTimeout(() => {
|
|
348
402
|
this.frameTreeSyncTimers.delete(key);
|
|
349
|
-
void this.refreshFrameTree(tabId, sessionId).
|
|
403
|
+
void this.refreshFrameTree(tabId, sessionId).then(() => {
|
|
404
|
+
this.emitFramesChangedIfNeeded(tabId, "navigation_resync");
|
|
405
|
+
}).catch((error) => {
|
|
350
406
|
console.warn("[DebuggerManager] Failed to refresh frame tree after navigation:", error);
|
|
351
407
|
});
|
|
352
408
|
}, FRAME_TREE_SYNC_DELAY_MS);
|
|
@@ -370,15 +426,6 @@ var DebuggerManager = class {
|
|
|
370
426
|
this.frameTreeSyncTimers.delete(key);
|
|
371
427
|
}
|
|
372
428
|
}
|
|
373
|
-
toFrameRecord(frame, sessionId) {
|
|
374
|
-
return {
|
|
375
|
-
frameId: frame.id,
|
|
376
|
-
parentFrameId: frame.parentId ?? null,
|
|
377
|
-
url: frame.url ?? "",
|
|
378
|
-
title: frame.name ?? null,
|
|
379
|
-
sessionId
|
|
380
|
-
};
|
|
381
|
-
}
|
|
382
429
|
handleDetach(tabId, sessionId, reason) {
|
|
383
430
|
const target = this.attached.get(tabId);
|
|
384
431
|
if (!target) {
|
|
@@ -391,6 +438,7 @@ var DebuggerManager = class {
|
|
|
391
438
|
}
|
|
392
439
|
this.clearAllFrameTreeSync(tabId);
|
|
393
440
|
this.attached.delete(tabId);
|
|
441
|
+
this.lastPublishedFrames.delete(tabId);
|
|
394
442
|
this.emitDetach(tabId, reason);
|
|
395
443
|
}
|
|
396
444
|
dropChildSession(tabId, sessionId) {
|
|
@@ -399,12 +447,8 @@ var DebuggerManager = class {
|
|
|
399
447
|
return;
|
|
400
448
|
}
|
|
401
449
|
target.childSessions.delete(sessionId);
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
continue;
|
|
405
|
-
}
|
|
406
|
-
target.frames.delete(frameId);
|
|
407
|
-
this.emitEvent(tabId, "Page.frameDetached", { frameId }, sessionId);
|
|
450
|
+
if (dropSessionFrames(target, sessionId)) {
|
|
451
|
+
this.emitFramesChangedIfNeeded(tabId, "child_detached");
|
|
408
452
|
}
|
|
409
453
|
}
|
|
410
454
|
};
|
|
@@ -424,7 +468,6 @@ var BridgeClient = class {
|
|
|
424
468
|
port = null;
|
|
425
469
|
hostName;
|
|
426
470
|
messageHandlers = /* @__PURE__ */ new Set();
|
|
427
|
-
connectHandler = null;
|
|
428
471
|
disconnectHandler = null;
|
|
429
472
|
reconnectAttempts = 0;
|
|
430
473
|
maxReconnectAttempts = 5;
|
|
@@ -441,12 +484,6 @@ var BridgeClient = class {
|
|
|
441
484
|
onMessage(handler) {
|
|
442
485
|
this.messageHandlers.add(handler);
|
|
443
486
|
}
|
|
444
|
-
/**
|
|
445
|
-
* Set handler for successful connection.
|
|
446
|
-
*/
|
|
447
|
-
onConnect(handler) {
|
|
448
|
-
this.connectHandler = handler;
|
|
449
|
-
}
|
|
450
487
|
/**
|
|
451
488
|
* Set handler for disconnection.
|
|
452
489
|
*/
|
|
@@ -480,9 +517,6 @@ var BridgeClient = class {
|
|
|
480
517
|
});
|
|
481
518
|
console.log("[BridgeClient] Connected to", this.hostName);
|
|
482
519
|
this.reconnectAttempts = 0;
|
|
483
|
-
if (this.connectHandler) {
|
|
484
|
-
this.connectHandler();
|
|
485
|
-
}
|
|
486
520
|
return true;
|
|
487
521
|
} catch (err) {
|
|
488
522
|
console.error("[BridgeClient] Failed to connect:", err);
|
|
@@ -542,37 +576,13 @@ var BridgeClient = class {
|
|
|
542
576
|
}
|
|
543
577
|
};
|
|
544
578
|
|
|
545
|
-
// src/background/tab-list.ts
|
|
546
|
-
var listBrowserTabs = async (debuggerManager2, filter, options = {}) => {
|
|
547
|
-
const chromeTabs = await chrome.tabs.query({});
|
|
548
|
-
const attachedTargets = debuggerManager2.listAttached();
|
|
549
|
-
const attachedTabIds = new Set(attachedTargets.map((target) => target.tabId));
|
|
550
|
-
let tabs = chromeTabs.filter((tab) => tab.id !== void 0 && tab.url !== void 0).filter((tab) => !tab.url.startsWith("chrome://") && !tab.url.startsWith("chrome-extension://")).map((tab) => ({
|
|
551
|
-
tabId: tab.id,
|
|
552
|
-
url: tab.url,
|
|
553
|
-
title: tab.title ?? "",
|
|
554
|
-
faviconUrl: tab.favIconUrl,
|
|
555
|
-
attached: attachedTabIds.has(tab.id),
|
|
556
|
-
watcherId: options.getWatcherIdForTab?.(tab.id) ?? void 0
|
|
557
|
-
}));
|
|
558
|
-
if (filter?.url) {
|
|
559
|
-
const urlFilter = filter.url.toLowerCase();
|
|
560
|
-
tabs = tabs.filter((tab) => tab.url.toLowerCase().includes(urlFilter));
|
|
561
|
-
}
|
|
562
|
-
if (filter?.title) {
|
|
563
|
-
const titleFilter = filter.title.toLowerCase();
|
|
564
|
-
tabs = tabs.filter((tab) => tab.title.toLowerCase().includes(titleFilter));
|
|
565
|
-
}
|
|
566
|
-
tabs.sort((left, right) => Number(right.attached) - Number(left.attached));
|
|
567
|
-
return tabs;
|
|
568
|
-
};
|
|
569
|
-
|
|
570
579
|
// src/background/cdp-proxy.ts
|
|
571
580
|
var CdpProxy = class {
|
|
572
581
|
debuggerManager;
|
|
573
582
|
bridgeClient;
|
|
574
583
|
removeDebuggerEventForwarding = null;
|
|
575
584
|
removeDebuggerDetachForwarding = null;
|
|
585
|
+
removeFramesChangedForwarding = null;
|
|
576
586
|
constructor(debuggerManager2, bridgeClient) {
|
|
577
587
|
this.debuggerManager = debuggerManager2;
|
|
578
588
|
this.bridgeClient = bridgeClient;
|
|
@@ -599,19 +609,31 @@ var CdpProxy = class {
|
|
|
599
609
|
reason
|
|
600
610
|
});
|
|
601
611
|
});
|
|
612
|
+
this.removeFramesChangedForwarding = this.debuggerManager.onFramesChanged((tabId, reason) => {
|
|
613
|
+
this.bridgeClient.send({
|
|
614
|
+
type: "frame_snapshot",
|
|
615
|
+
tabId,
|
|
616
|
+
reason,
|
|
617
|
+
...this.debuggerManager.getFrameSnapshot(tabId)
|
|
618
|
+
});
|
|
619
|
+
});
|
|
602
620
|
}
|
|
603
621
|
dispose() {
|
|
604
622
|
this.removeDebuggerEventForwarding?.();
|
|
605
623
|
this.removeDebuggerEventForwarding = null;
|
|
606
624
|
this.removeDebuggerDetachForwarding?.();
|
|
607
625
|
this.removeDebuggerDetachForwarding = null;
|
|
626
|
+
this.removeFramesChangedForwarding?.();
|
|
627
|
+
this.removeFramesChangedForwarding = null;
|
|
608
628
|
}
|
|
609
629
|
/**
|
|
610
630
|
* Handle messages from the bridge.
|
|
611
631
|
*/
|
|
612
632
|
setupMessageHandling() {
|
|
613
633
|
this.bridgeClient.onMessage((message) => {
|
|
614
|
-
this.handleMessage(message)
|
|
634
|
+
void this.handleMessage(message).catch((error) => {
|
|
635
|
+
console.error("[CdpProxy] Failed to handle bridge message:", error);
|
|
636
|
+
});
|
|
615
637
|
});
|
|
616
638
|
}
|
|
617
639
|
/**
|
|
@@ -619,9 +641,6 @@ var CdpProxy = class {
|
|
|
619
641
|
*/
|
|
620
642
|
async handleMessage(message) {
|
|
621
643
|
switch (message.type) {
|
|
622
|
-
case "attach_tab":
|
|
623
|
-
await this.handleAttachTab(message);
|
|
624
|
-
break;
|
|
625
644
|
case "detach_tab":
|
|
626
645
|
await this.handleDetachTab(message);
|
|
627
646
|
break;
|
|
@@ -631,8 +650,8 @@ var CdpProxy = class {
|
|
|
631
650
|
case "cookie_query":
|
|
632
651
|
await this.handleCookieQuery(message);
|
|
633
652
|
break;
|
|
634
|
-
case "
|
|
635
|
-
await this.
|
|
653
|
+
case "frame_snapshot_request":
|
|
654
|
+
await this.handleFrameSnapshotRequest(message);
|
|
636
655
|
break;
|
|
637
656
|
case "host_info":
|
|
638
657
|
case "host_ready":
|
|
@@ -643,11 +662,11 @@ var CdpProxy = class {
|
|
|
643
662
|
}
|
|
644
663
|
}
|
|
645
664
|
/**
|
|
646
|
-
* Attach to a tab.
|
|
665
|
+
* Attach to a tab (driven by the popup; the host never requests attachment).
|
|
647
666
|
*/
|
|
648
|
-
async
|
|
667
|
+
async attachTab(tabId) {
|
|
649
668
|
try {
|
|
650
|
-
const target = await this.debuggerManager.attach(
|
|
669
|
+
const target = await this.debuggerManager.attach(tabId);
|
|
651
670
|
this.bridgeClient.send({
|
|
652
671
|
type: "tab_attached",
|
|
653
672
|
tabId: target.tabId,
|
|
@@ -661,9 +680,10 @@ var CdpProxy = class {
|
|
|
661
680
|
console.error("[CdpProxy] Failed to attach:", err);
|
|
662
681
|
this.bridgeClient.send({
|
|
663
682
|
type: "tab_detached",
|
|
664
|
-
tabId
|
|
683
|
+
tabId,
|
|
665
684
|
reason: err instanceof Error ? err.message : "attach_failed"
|
|
666
685
|
});
|
|
686
|
+
throw err;
|
|
667
687
|
}
|
|
668
688
|
}
|
|
669
689
|
/**
|
|
@@ -693,6 +713,26 @@ var CdpProxy = class {
|
|
|
693
713
|
});
|
|
694
714
|
}
|
|
695
715
|
}
|
|
716
|
+
/**
|
|
717
|
+
* Answer a watcher pull for the frame table. With `refresh` the table is re-read from
|
|
718
|
+
* Chrome first; either way the reply is the full current table, so applying it is
|
|
719
|
+
* idempotent on the watcher side.
|
|
720
|
+
*/
|
|
721
|
+
async handleFrameSnapshotRequest(message) {
|
|
722
|
+
let snapshot;
|
|
723
|
+
try {
|
|
724
|
+
snapshot = message.refresh ? await this.debuggerManager.resyncFrames(message.tabId) : this.debuggerManager.getFrameSnapshot(message.tabId);
|
|
725
|
+
} catch {
|
|
726
|
+
snapshot = this.debuggerManager.getFrameSnapshot(message.tabId);
|
|
727
|
+
}
|
|
728
|
+
this.bridgeClient.send({
|
|
729
|
+
type: "frame_snapshot",
|
|
730
|
+
tabId: message.tabId,
|
|
731
|
+
reason: "requested",
|
|
732
|
+
requestId: message.requestId,
|
|
733
|
+
...snapshot
|
|
734
|
+
});
|
|
735
|
+
}
|
|
696
736
|
/**
|
|
697
737
|
* Query browser cookies from the attached tab's cookie store.
|
|
698
738
|
*/
|
|
@@ -717,22 +757,6 @@ var CdpProxy = class {
|
|
|
717
757
|
});
|
|
718
758
|
}
|
|
719
759
|
}
|
|
720
|
-
/**
|
|
721
|
-
* Enable a CDP domain for a tab.
|
|
722
|
-
*/
|
|
723
|
-
async handleEnableDomain(message) {
|
|
724
|
-
try {
|
|
725
|
-
await this.debuggerManager.enableDomain(message.tabId, message.domain);
|
|
726
|
-
} catch (err) {
|
|
727
|
-
console.error("[CdpProxy] Failed to enable domain:", err);
|
|
728
|
-
}
|
|
729
|
-
}
|
|
730
|
-
/**
|
|
731
|
-
* Manually attach to a tab (called from popup).
|
|
732
|
-
*/
|
|
733
|
-
async attachTab(tabId) {
|
|
734
|
-
await this.handleAttachTab({ type: "attach_tab", tabId });
|
|
735
|
-
}
|
|
736
760
|
/**
|
|
737
761
|
* Manually detach from a tab (called from popup).
|
|
738
762
|
*/
|
|
@@ -744,18 +768,60 @@ var CdpProxy = class {
|
|
|
744
768
|
});
|
|
745
769
|
await this.debuggerManager.detach(tabId);
|
|
746
770
|
}
|
|
747
|
-
/**
|
|
748
|
-
* Get list of tabs for popup UI.
|
|
749
|
-
*/
|
|
750
|
-
async getTabsForPopup() {
|
|
751
|
-
return await listBrowserTabs(this.debuggerManager);
|
|
752
|
-
}
|
|
753
771
|
};
|
|
754
772
|
|
|
755
773
|
// src/background/native-hosts.ts
|
|
756
774
|
var BRIDGE_HOST_NAME = "com.vforsh.argus.bridge";
|
|
757
775
|
var CONTROL_HOST_NAME = "com.vforsh.argus.control";
|
|
758
776
|
|
|
777
|
+
// src/background/latch.ts
|
|
778
|
+
var createLatch = () => {
|
|
779
|
+
let open = false;
|
|
780
|
+
let waiters = [];
|
|
781
|
+
return {
|
|
782
|
+
get isOpen() {
|
|
783
|
+
return open;
|
|
784
|
+
},
|
|
785
|
+
wait: (timeoutMs, timeoutMessage) => {
|
|
786
|
+
if (open) {
|
|
787
|
+
return Promise.resolve();
|
|
788
|
+
}
|
|
789
|
+
return new Promise((resolve, reject) => {
|
|
790
|
+
const onOpen = () => {
|
|
791
|
+
clearTimeout(timer);
|
|
792
|
+
resolve();
|
|
793
|
+
};
|
|
794
|
+
const timer = setTimeout(() => {
|
|
795
|
+
waiters = waiters.filter((waiter) => waiter !== onOpen);
|
|
796
|
+
reject(new Error(timeoutMessage));
|
|
797
|
+
}, timeoutMs);
|
|
798
|
+
waiters.push(onOpen);
|
|
799
|
+
});
|
|
800
|
+
},
|
|
801
|
+
signal: () => {
|
|
802
|
+
open = true;
|
|
803
|
+
const pending = waiters;
|
|
804
|
+
waiters = [];
|
|
805
|
+
for (const waiter of pending) {
|
|
806
|
+
waiter();
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
};
|
|
810
|
+
};
|
|
811
|
+
|
|
812
|
+
// ../argus-core/dist/protocol/native-messaging.js
|
|
813
|
+
var NATIVE_MESSAGING_PROTOCOL_VERSION = 2;
|
|
814
|
+
|
|
815
|
+
// src/background/protocol-handshake.ts
|
|
816
|
+
var checkHostProtocol = (message) => {
|
|
817
|
+
const hostVersion = message.protocolVersion;
|
|
818
|
+
if (hostVersion === NATIVE_MESSAGING_PROTOCOL_VERSION) {
|
|
819
|
+
return null;
|
|
820
|
+
}
|
|
821
|
+
const reported = hostVersion == null ? "none (predates the handshake)" : String(hostVersion);
|
|
822
|
+
return `Argus native host speaks native-messaging protocol ${reported}, extension expects ${NATIVE_MESSAGING_PROTOCOL_VERSION}. Update argus (npm i -g @vforsh/argus) and reload the extension.`;
|
|
823
|
+
};
|
|
824
|
+
|
|
759
825
|
// src/background/tab-bridge-session.ts
|
|
760
826
|
var TabBridgeSession = class {
|
|
761
827
|
tabId;
|
|
@@ -766,10 +832,10 @@ var TabBridgeSession = class {
|
|
|
766
832
|
targetInfo = null;
|
|
767
833
|
desiredWatcherId;
|
|
768
834
|
lastMessageAt = null;
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
watcherInfoWaiters = [];
|
|
835
|
+
hostReady = createLatch();
|
|
836
|
+
watcherInfoReceived = createLatch();
|
|
772
837
|
disposed = false;
|
|
838
|
+
protocolMismatch = null;
|
|
773
839
|
constructor(tabId, debuggerManager2, events = {}, options = {}) {
|
|
774
840
|
this.tabId = tabId;
|
|
775
841
|
this.events = events;
|
|
@@ -799,27 +865,10 @@ var TabBridgeSession = class {
|
|
|
799
865
|
if (!sent) {
|
|
800
866
|
throw new Error(`Failed to initialize watcher for tab ${this.tabId}`);
|
|
801
867
|
}
|
|
802
|
-
await this.
|
|
803
|
-
await this.
|
|
868
|
+
await this.awaitLatch(this.hostReady, "did not become ready");
|
|
869
|
+
await this.awaitLatch(this.watcherInfoReceived, "did not report watcher info");
|
|
804
870
|
await this.cdpProxy.attachTab(this.tabId);
|
|
805
871
|
}
|
|
806
|
-
async waitUntilReady(timeoutMs = 3e3) {
|
|
807
|
-
this.assertOpen();
|
|
808
|
-
if (this.ready) {
|
|
809
|
-
return;
|
|
810
|
-
}
|
|
811
|
-
await new Promise((resolve, reject) => {
|
|
812
|
-
const timer = setTimeout(() => {
|
|
813
|
-
this.readyWaiters = this.readyWaiters.filter((waiter) => waiter !== onReady);
|
|
814
|
-
reject(new Error(`Native host session for tab ${this.tabId} did not become ready`));
|
|
815
|
-
}, timeoutMs);
|
|
816
|
-
const onReady = () => {
|
|
817
|
-
clearTimeout(timer);
|
|
818
|
-
resolve();
|
|
819
|
-
};
|
|
820
|
-
this.readyWaiters.push(onReady);
|
|
821
|
-
});
|
|
822
|
-
}
|
|
823
872
|
async detach() {
|
|
824
873
|
if (this.disposed) {
|
|
825
874
|
return;
|
|
@@ -861,27 +910,22 @@ var TabBridgeSession = class {
|
|
|
861
910
|
getLastMessageAt() {
|
|
862
911
|
return this.lastMessageAt;
|
|
863
912
|
}
|
|
864
|
-
async
|
|
913
|
+
async awaitLatch(latch, failure, timeoutMs = 3e3) {
|
|
865
914
|
this.assertOpen();
|
|
866
|
-
|
|
867
|
-
return;
|
|
868
|
-
}
|
|
869
|
-
await new Promise((resolve, reject) => {
|
|
870
|
-
const timer = setTimeout(() => {
|
|
871
|
-
this.watcherInfoWaiters = this.watcherInfoWaiters.filter((waiter) => waiter !== onWatcherInfo);
|
|
872
|
-
reject(new Error(`Native host session for tab ${this.tabId} did not report watcher info`));
|
|
873
|
-
}, timeoutMs);
|
|
874
|
-
const onWatcherInfo = () => {
|
|
875
|
-
clearTimeout(timer);
|
|
876
|
-
resolve();
|
|
877
|
-
};
|
|
878
|
-
this.watcherInfoWaiters.push(onWatcherInfo);
|
|
879
|
-
});
|
|
915
|
+
await latch.wait(timeoutMs, `Native host session for tab ${this.tabId} ${failure}`);
|
|
880
916
|
}
|
|
881
917
|
handleMessage(message) {
|
|
882
918
|
this.lastMessageAt = Date.now();
|
|
883
919
|
switch (message.type) {
|
|
884
|
-
case "host_info":
|
|
920
|
+
case "host_info": {
|
|
921
|
+
const mismatch = checkHostProtocol(message);
|
|
922
|
+
if (mismatch) {
|
|
923
|
+
console.error(`[TabBridgeSession] ${mismatch}`);
|
|
924
|
+
this.protocolMismatch = mismatch;
|
|
925
|
+
this.dispose();
|
|
926
|
+
this.events.onDisconnect?.();
|
|
927
|
+
return;
|
|
928
|
+
}
|
|
885
929
|
this.watcherInfo = {
|
|
886
930
|
watcherId: message.watcherId,
|
|
887
931
|
watcherHost: message.watcherHost,
|
|
@@ -889,10 +933,11 @@ var TabBridgeSession = class {
|
|
|
889
933
|
pid: message.pid
|
|
890
934
|
};
|
|
891
935
|
this.events.onWatcherInfo?.(this.watcherInfo);
|
|
892
|
-
this.
|
|
936
|
+
this.watcherInfoReceived.signal();
|
|
893
937
|
return;
|
|
938
|
+
}
|
|
894
939
|
case "host_ready":
|
|
895
|
-
this.
|
|
940
|
+
this.hostReady.signal();
|
|
896
941
|
return;
|
|
897
942
|
case "target_info":
|
|
898
943
|
this.targetInfo = {
|
|
@@ -905,28 +950,52 @@ var TabBridgeSession = class {
|
|
|
905
950
|
this.events.onTargetInfo?.(this.targetInfo);
|
|
906
951
|
}
|
|
907
952
|
}
|
|
908
|
-
resolveReadyWaiters() {
|
|
909
|
-
this.ready = true;
|
|
910
|
-
const waiters = this.readyWaiters;
|
|
911
|
-
this.readyWaiters = [];
|
|
912
|
-
for (const waiter of waiters) {
|
|
913
|
-
waiter();
|
|
914
|
-
}
|
|
915
|
-
}
|
|
916
|
-
resolveWatcherInfoWaiters() {
|
|
917
|
-
const waiters = this.watcherInfoWaiters;
|
|
918
|
-
this.watcherInfoWaiters = [];
|
|
919
|
-
for (const waiter of waiters) {
|
|
920
|
-
waiter();
|
|
921
|
-
}
|
|
922
|
-
}
|
|
923
953
|
assertOpen() {
|
|
954
|
+
if (this.protocolMismatch) {
|
|
955
|
+
throw new Error(this.protocolMismatch);
|
|
956
|
+
}
|
|
924
957
|
if (this.disposed) {
|
|
925
958
|
throw new Error(`Native host session for tab ${this.tabId} is already closed`);
|
|
926
959
|
}
|
|
927
960
|
}
|
|
928
961
|
};
|
|
929
962
|
|
|
963
|
+
// src/background/tab-list.ts
|
|
964
|
+
var listBrowserTabs = async (debuggerManager2, filter, options = {}) => {
|
|
965
|
+
const chromeTabs = await chrome.tabs.query({});
|
|
966
|
+
const attachedTargets = debuggerManager2.listAttached();
|
|
967
|
+
const attachedTabIds = new Set(attachedTargets.map((target) => target.tabId));
|
|
968
|
+
let tabs = chromeTabs.filter((tab) => tab.id !== void 0 && tab.url !== void 0).filter((tab) => !tab.url.startsWith("chrome://") && !tab.url.startsWith("chrome-extension://")).map((tab) => ({
|
|
969
|
+
tabId: tab.id,
|
|
970
|
+
url: tab.url,
|
|
971
|
+
title: tab.title ?? "",
|
|
972
|
+
faviconUrl: tab.favIconUrl,
|
|
973
|
+
attached: attachedTabIds.has(tab.id),
|
|
974
|
+
watcherId: options.getWatcherIdForTab?.(tab.id) ?? void 0
|
|
975
|
+
}));
|
|
976
|
+
if (filter?.url) {
|
|
977
|
+
const urlFilter = filter.url.toLowerCase();
|
|
978
|
+
tabs = tabs.filter((tab) => tab.url.toLowerCase().includes(urlFilter));
|
|
979
|
+
}
|
|
980
|
+
if (filter?.title) {
|
|
981
|
+
const titleFilter = filter.title.toLowerCase();
|
|
982
|
+
tabs = tabs.filter((tab) => tab.title.toLowerCase().includes(titleFilter));
|
|
983
|
+
}
|
|
984
|
+
tabs.sort((left, right) => Number(right.attached) - Number(left.attached));
|
|
985
|
+
return tabs;
|
|
986
|
+
};
|
|
987
|
+
|
|
988
|
+
// ../argus-core/dist/errorMessage.js
|
|
989
|
+
var formatError = (error) => {
|
|
990
|
+
if (!error) {
|
|
991
|
+
return "unknown error";
|
|
992
|
+
}
|
|
993
|
+
if (error instanceof Error) {
|
|
994
|
+
return error.message;
|
|
995
|
+
}
|
|
996
|
+
return String(error);
|
|
997
|
+
};
|
|
998
|
+
|
|
930
999
|
// src/background/control-bridge-session.ts
|
|
931
1000
|
var ControlBridgeSession = class {
|
|
932
1001
|
bridgeClient;
|
|
@@ -972,7 +1041,13 @@ var ControlBridgeSession = class {
|
|
|
972
1041
|
async handleMessage(message) {
|
|
973
1042
|
this.lastMessageAt = Date.now();
|
|
974
1043
|
switch (message.type) {
|
|
975
|
-
case "host_info":
|
|
1044
|
+
case "host_info": {
|
|
1045
|
+
const mismatch = checkHostProtocol(message);
|
|
1046
|
+
if (mismatch) {
|
|
1047
|
+
console.error(`[ControlBridgeSession] ${mismatch}`);
|
|
1048
|
+
this.bridgeClient.disconnect();
|
|
1049
|
+
return;
|
|
1050
|
+
}
|
|
976
1051
|
this.watcherInfo = {
|
|
977
1052
|
watcherId: message.watcherId,
|
|
978
1053
|
watcherHost: message.watcherHost,
|
|
@@ -981,6 +1056,7 @@ var ControlBridgeSession = class {
|
|
|
981
1056
|
};
|
|
982
1057
|
this.events.onWatcherInfo?.(this.watcherInfo);
|
|
983
1058
|
return;
|
|
1059
|
+
}
|
|
984
1060
|
case "attach_tab_watcher":
|
|
985
1061
|
await this.handleTabAction(message.requestId, () => this.events.onAttachTabWatcher?.(message.tabId, { watcherId: message.watcherId }));
|
|
986
1062
|
return;
|
|
@@ -1010,7 +1086,7 @@ var ControlBridgeSession = class {
|
|
|
1010
1086
|
type: "tab_action_response",
|
|
1011
1087
|
requestId,
|
|
1012
1088
|
ok: false,
|
|
1013
|
-
error: { message:
|
|
1089
|
+
error: { message: formatError(error) }
|
|
1014
1090
|
});
|
|
1015
1091
|
}
|
|
1016
1092
|
}
|
|
@@ -1054,6 +1130,79 @@ var ControlBridgeSession = class {
|
|
|
1054
1130
|
}
|
|
1055
1131
|
};
|
|
1056
1132
|
|
|
1133
|
+
// src/background/page-keyed-store.ts
|
|
1134
|
+
var readStorageValue = async (storageArea, key) => new Promise((resolve, reject) => {
|
|
1135
|
+
storageArea.get(key, (items) => {
|
|
1136
|
+
const error = chrome.runtime.lastError;
|
|
1137
|
+
if (error) {
|
|
1138
|
+
reject(new Error(error.message));
|
|
1139
|
+
return;
|
|
1140
|
+
}
|
|
1141
|
+
resolve(items[key]);
|
|
1142
|
+
});
|
|
1143
|
+
});
|
|
1144
|
+
var writeStorageValue = async (storageArea, items) => new Promise((resolve, reject) => {
|
|
1145
|
+
storageArea.set(items, () => {
|
|
1146
|
+
const error = chrome.runtime.lastError;
|
|
1147
|
+
if (error) {
|
|
1148
|
+
reject(new Error(error.message));
|
|
1149
|
+
return;
|
|
1150
|
+
}
|
|
1151
|
+
resolve();
|
|
1152
|
+
});
|
|
1153
|
+
});
|
|
1154
|
+
var normalizeOptionalText = (value) => {
|
|
1155
|
+
if (typeof value !== "string") {
|
|
1156
|
+
return null;
|
|
1157
|
+
}
|
|
1158
|
+
const trimmed = value.trim();
|
|
1159
|
+
return trimmed === "" ? null : trimmed;
|
|
1160
|
+
};
|
|
1161
|
+
var sortByUpdatedAtDesc = (left, right) => right.updatedAt - left.updatedAt;
|
|
1162
|
+
var createChromeStorePersistence = (storageKey, sanitize, storageArea = chrome.storage.local) => ({
|
|
1163
|
+
load: async () => sanitize(await readStorageValue(storageArea, storageKey)),
|
|
1164
|
+
save: async (entries) => {
|
|
1165
|
+
await writeStorageValue(storageArea, { [storageKey]: entries });
|
|
1166
|
+
}
|
|
1167
|
+
});
|
|
1168
|
+
var PageKeyedStore = class {
|
|
1169
|
+
constructor(persistence, maxEntries, label) {
|
|
1170
|
+
this.persistence = persistence;
|
|
1171
|
+
this.maxEntries = maxEntries;
|
|
1172
|
+
this.label = label;
|
|
1173
|
+
}
|
|
1174
|
+
entries = [];
|
|
1175
|
+
loadPromise = null;
|
|
1176
|
+
saveChain = Promise.resolve();
|
|
1177
|
+
/** Load on first use; later calls await the same load. */
|
|
1178
|
+
async ensureLoaded() {
|
|
1179
|
+
if (!this.loadPromise) {
|
|
1180
|
+
this.loadPromise = this.persistence.load().then((entries) => {
|
|
1181
|
+
this.entries = entries.slice(0, this.maxEntries);
|
|
1182
|
+
}).catch((error) => {
|
|
1183
|
+
console.error(`[${this.label}] Failed to load history:`, error);
|
|
1184
|
+
this.entries = [];
|
|
1185
|
+
});
|
|
1186
|
+
}
|
|
1187
|
+
await this.loadPromise;
|
|
1188
|
+
}
|
|
1189
|
+
/** Persist the current entries, serialized behind any in-flight save. */
|
|
1190
|
+
async persist() {
|
|
1191
|
+
this.saveChain = this.saveChain.catch(() => void 0).then(() => this.persistence.save(this.entries)).catch((error) => {
|
|
1192
|
+
console.error(`[${this.label}] Failed to save history:`, error);
|
|
1193
|
+
});
|
|
1194
|
+
await this.saveChain;
|
|
1195
|
+
}
|
|
1196
|
+
/** Move an entry to the front, replacing any entry with the same page key. */
|
|
1197
|
+
upsert(entry) {
|
|
1198
|
+
this.entries = [entry, ...this.entries.filter((candidate) => candidate.pageKey !== entry.pageKey)].slice(0, this.maxEntries);
|
|
1199
|
+
}
|
|
1200
|
+
/** Find the entry for a page key. */
|
|
1201
|
+
findByPageKey(pageKey) {
|
|
1202
|
+
return this.entries.find((entry) => entry.pageKey === pageKey) ?? null;
|
|
1203
|
+
}
|
|
1204
|
+
};
|
|
1205
|
+
|
|
1057
1206
|
// src/background/target-selection-history.ts
|
|
1058
1207
|
var DEFAULT_STORAGE_KEY = "targetSelectionHistory";
|
|
1059
1208
|
var DEFAULT_MAX_ENTRIES = 20;
|
|
@@ -1079,55 +1228,23 @@ var matchRememberedIframeTarget = (entry, targets) => {
|
|
|
1079
1228
|
}
|
|
1080
1229
|
return pickSingleTargetMatch(iframeTargets, (target) => normalizeTargetTitle(target.title) === rememberedIframe.title);
|
|
1081
1230
|
};
|
|
1082
|
-
var TargetSelectionHistoryStore = class {
|
|
1083
|
-
persistence;
|
|
1084
|
-
maxEntries;
|
|
1085
|
-
entries = [];
|
|
1086
|
-
loadPromise = null;
|
|
1087
|
-
saveChain = Promise.resolve();
|
|
1231
|
+
var TargetSelectionHistoryStore = class extends PageKeyedStore {
|
|
1088
1232
|
constructor(persistence = createChromeStoragePersistence(), options = {}) {
|
|
1089
|
-
|
|
1090
|
-
this.maxEntries = options.maxEntries ?? DEFAULT_MAX_ENTRIES;
|
|
1233
|
+
super(persistence, options.maxEntries ?? DEFAULT_MAX_ENTRIES, "TargetSelectionHistoryStore");
|
|
1091
1234
|
}
|
|
1092
1235
|
async getByPageUrl(pageUrl) {
|
|
1093
1236
|
await this.ensureLoaded();
|
|
1094
|
-
|
|
1095
|
-
return this.entries.find((entry) => entry.pageKey === pageKey) ?? null;
|
|
1237
|
+
return this.findByPageKey(normalizeSelectionPageKey(pageUrl));
|
|
1096
1238
|
}
|
|
1097
1239
|
async remember(pageUrl, target) {
|
|
1098
1240
|
await this.ensureLoaded();
|
|
1099
1241
|
const entry = buildRememberedSelection(pageUrl, target);
|
|
1100
|
-
this.
|
|
1242
|
+
this.upsert(entry);
|
|
1101
1243
|
await this.persist();
|
|
1102
1244
|
return entry;
|
|
1103
1245
|
}
|
|
1104
|
-
async ensureLoaded() {
|
|
1105
|
-
if (!this.loadPromise) {
|
|
1106
|
-
this.loadPromise = this.persistence.load().then((entries) => {
|
|
1107
|
-
this.entries = sanitizeRememberedSelections(entries).slice(0, this.maxEntries);
|
|
1108
|
-
}).catch((error) => {
|
|
1109
|
-
console.error("[TargetSelectionHistoryStore] Failed to load history:", error);
|
|
1110
|
-
this.entries = [];
|
|
1111
|
-
});
|
|
1112
|
-
}
|
|
1113
|
-
await this.loadPromise;
|
|
1114
|
-
}
|
|
1115
|
-
async persist() {
|
|
1116
|
-
this.saveChain = this.saveChain.catch(() => void 0).then(() => this.persistence.save(this.entries)).catch((error) => {
|
|
1117
|
-
console.error("[TargetSelectionHistoryStore] Failed to save history:", error);
|
|
1118
|
-
});
|
|
1119
|
-
await this.saveChain;
|
|
1120
|
-
}
|
|
1121
1246
|
};
|
|
1122
|
-
var createChromeStoragePersistence = (storageArea = chrome.storage.local, storageKey = DEFAULT_STORAGE_KEY) => (
|
|
1123
|
-
load: async () => {
|
|
1124
|
-
const stored = await readStorageValue(storageArea, storageKey);
|
|
1125
|
-
return sanitizeRememberedSelections(Array.isArray(stored) ? stored : []);
|
|
1126
|
-
},
|
|
1127
|
-
save: async (entries) => {
|
|
1128
|
-
await writeStorageValue(storageArea, { [storageKey]: entries });
|
|
1129
|
-
}
|
|
1130
|
-
});
|
|
1247
|
+
var createChromeStoragePersistence = (storageArea = chrome.storage.local, storageKey = DEFAULT_STORAGE_KEY) => createChromeStorePersistence(storageKey, (value) => sanitizeRememberedSelections(Array.isArray(value) ? value : []), storageArea);
|
|
1131
1248
|
var buildRememberedSelection = (pageUrl, target) => {
|
|
1132
1249
|
const base = {
|
|
1133
1250
|
pageKey: normalizeSelectionPageKey(pageUrl),
|
|
@@ -1190,56 +1307,25 @@ var sanitizeRememberedSelection = (entry) => {
|
|
|
1190
1307
|
};
|
|
1191
1308
|
};
|
|
1192
1309
|
function normalizeTargetUrl(url) {
|
|
1193
|
-
return
|
|
1310
|
+
return normalizeOptionalText2(url);
|
|
1194
1311
|
}
|
|
1195
1312
|
function normalizeTargetTitle(title) {
|
|
1196
|
-
return
|
|
1313
|
+
return normalizeOptionalText2(title);
|
|
1197
1314
|
}
|
|
1198
|
-
function
|
|
1315
|
+
function normalizeOptionalText2(value) {
|
|
1199
1316
|
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
|
|
1200
1317
|
}
|
|
1201
|
-
var sortByUpdatedAtDesc = (left, right) => right.updatedAt - left.updatedAt;
|
|
1202
|
-
var readStorageValue = async (storageArea, key) => {
|
|
1203
|
-
return await new Promise((resolve, reject) => {
|
|
1204
|
-
storageArea.get(key, (items) => {
|
|
1205
|
-
const error = chrome.runtime.lastError;
|
|
1206
|
-
if (error) {
|
|
1207
|
-
reject(new Error(error.message));
|
|
1208
|
-
return;
|
|
1209
|
-
}
|
|
1210
|
-
resolve(items[key]);
|
|
1211
|
-
});
|
|
1212
|
-
});
|
|
1213
|
-
};
|
|
1214
|
-
var writeStorageValue = async (storageArea, items) => {
|
|
1215
|
-
await new Promise((resolve, reject) => {
|
|
1216
|
-
storageArea.set(items, () => {
|
|
1217
|
-
const error = chrome.runtime.lastError;
|
|
1218
|
-
if (error) {
|
|
1219
|
-
reject(new Error(error.message));
|
|
1220
|
-
return;
|
|
1221
|
-
}
|
|
1222
|
-
resolve();
|
|
1223
|
-
});
|
|
1224
|
-
});
|
|
1225
|
-
};
|
|
1226
1318
|
|
|
1227
1319
|
// src/background/target-visibility-history.ts
|
|
1228
1320
|
var DEFAULT_STORAGE_KEY2 = "hiddenTargetHistory";
|
|
1229
1321
|
var DEFAULT_MAX_PAGE_ENTRIES = 20;
|
|
1230
|
-
var TargetVisibilityHistoryStore = class {
|
|
1231
|
-
persistence;
|
|
1232
|
-
maxPageEntries;
|
|
1233
|
-
entries = [];
|
|
1234
|
-
loadPromise = null;
|
|
1235
|
-
saveChain = Promise.resolve();
|
|
1322
|
+
var TargetVisibilityHistoryStore = class extends PageKeyedStore {
|
|
1236
1323
|
constructor(persistence = createChromeStoragePersistence2(), options = {}) {
|
|
1237
|
-
|
|
1238
|
-
this.maxPageEntries = options.maxPageEntries ?? DEFAULT_MAX_PAGE_ENTRIES;
|
|
1324
|
+
super(persistence, options.maxPageEntries ?? DEFAULT_MAX_PAGE_ENTRIES, "TargetVisibilityHistoryStore");
|
|
1239
1325
|
}
|
|
1240
1326
|
async getHiddenTargets(pageUrl) {
|
|
1241
1327
|
await this.ensureLoaded();
|
|
1242
|
-
return [...this.
|
|
1328
|
+
return [...this.findByPageKey(normalizeSelectionPageKey(pageUrl))?.targets ?? []];
|
|
1243
1329
|
}
|
|
1244
1330
|
async hide(pageUrl, target) {
|
|
1245
1331
|
await this.ensureLoaded();
|
|
@@ -1248,10 +1334,10 @@ var TargetVisibilityHistoryStore = class {
|
|
|
1248
1334
|
return null;
|
|
1249
1335
|
}
|
|
1250
1336
|
const pageKey = normalizeSelectionPageKey(pageUrl);
|
|
1251
|
-
const existing = this.
|
|
1337
|
+
const existing = this.findByPageKey(normalizeSelectionPageKey(pageUrl));
|
|
1252
1338
|
const targets = uniqueHiddenTargets([hiddenTarget, ...existing?.targets ?? []]);
|
|
1253
1339
|
const entry = { pageKey, pageUrl, updatedAt: Date.now(), targets };
|
|
1254
|
-
this.
|
|
1340
|
+
this.upsert(entry);
|
|
1255
1341
|
await this.persist();
|
|
1256
1342
|
return entry;
|
|
1257
1343
|
}
|
|
@@ -1261,7 +1347,7 @@ var TargetVisibilityHistoryStore = class {
|
|
|
1261
1347
|
if (!hiddenTarget) {
|
|
1262
1348
|
return;
|
|
1263
1349
|
}
|
|
1264
|
-
const existing = this.
|
|
1350
|
+
const existing = this.findByPageKey(normalizeSelectionPageKey(pageUrl));
|
|
1265
1351
|
if (!existing) {
|
|
1266
1352
|
return;
|
|
1267
1353
|
}
|
|
@@ -1274,44 +1360,8 @@ var TargetVisibilityHistoryStore = class {
|
|
|
1274
1360
|
this.entries = this.entries.map((entry) => entry.pageKey === existing.pageKey ? { ...entry, targets, updatedAt: Date.now() } : entry);
|
|
1275
1361
|
await this.persist();
|
|
1276
1362
|
}
|
|
1277
|
-
async isHidden(pageUrl, target) {
|
|
1278
|
-
const hiddenTargets = await this.getHiddenTargets(pageUrl);
|
|
1279
|
-
return hiddenTargets.some((hiddenTarget) => matchesHiddenTarget(hiddenTarget, target));
|
|
1280
|
-
}
|
|
1281
|
-
findEntry(pageUrl) {
|
|
1282
|
-
const pageKey = normalizeSelectionPageKey(pageUrl);
|
|
1283
|
-
return this.entries.find((entry) => entry.pageKey === pageKey) ?? null;
|
|
1284
|
-
}
|
|
1285
|
-
upsertEntry(entry) {
|
|
1286
|
-
this.entries = [entry, ...this.entries.filter((candidate) => candidate.pageKey !== entry.pageKey)].slice(0, this.maxPageEntries);
|
|
1287
|
-
}
|
|
1288
|
-
async ensureLoaded() {
|
|
1289
|
-
if (!this.loadPromise) {
|
|
1290
|
-
this.loadPromise = this.persistence.load().then((entries) => {
|
|
1291
|
-
this.entries = sanitizeHiddenTargetEntries(entries).slice(0, this.maxPageEntries);
|
|
1292
|
-
}).catch((error) => {
|
|
1293
|
-
console.error("[TargetVisibilityHistoryStore] Failed to load history:", error);
|
|
1294
|
-
this.entries = [];
|
|
1295
|
-
});
|
|
1296
|
-
}
|
|
1297
|
-
await this.loadPromise;
|
|
1298
|
-
}
|
|
1299
|
-
async persist() {
|
|
1300
|
-
this.saveChain = this.saveChain.catch(() => void 0).then(() => this.persistence.save(this.entries)).catch((error) => {
|
|
1301
|
-
console.error("[TargetVisibilityHistoryStore] Failed to save history:", error);
|
|
1302
|
-
});
|
|
1303
|
-
await this.saveChain;
|
|
1304
|
-
}
|
|
1305
1363
|
};
|
|
1306
|
-
var createChromeStoragePersistence2 = (storageArea = chrome.storage.local, storageKey = DEFAULT_STORAGE_KEY2) => (
|
|
1307
|
-
load: async () => {
|
|
1308
|
-
const stored = await readStorageValue2(storageArea, storageKey);
|
|
1309
|
-
return sanitizeHiddenTargetEntries(Array.isArray(stored) ? stored : []);
|
|
1310
|
-
},
|
|
1311
|
-
save: async (entries) => {
|
|
1312
|
-
await writeStorageValue2(storageArea, { [storageKey]: entries });
|
|
1313
|
-
}
|
|
1314
|
-
});
|
|
1364
|
+
var createChromeStoragePersistence2 = (storageArea = chrome.storage.local, storageKey = DEFAULT_STORAGE_KEY2) => createChromeStorePersistence(storageKey, (value) => sanitizeHiddenTargetEntries(Array.isArray(value) ? value : []), storageArea);
|
|
1315
1365
|
function matchesHiddenTarget(hiddenTarget, target) {
|
|
1316
1366
|
if (target.type !== "iframe") {
|
|
1317
1367
|
return false;
|
|
@@ -1323,8 +1373,8 @@ function toHiddenTarget(target) {
|
|
|
1323
1373
|
if (target.type !== "iframe") {
|
|
1324
1374
|
return null;
|
|
1325
1375
|
}
|
|
1326
|
-
const url =
|
|
1327
|
-
const title =
|
|
1376
|
+
const url = normalizeOptionalText(target.url);
|
|
1377
|
+
const title = normalizeOptionalText(target.title);
|
|
1328
1378
|
if (!url && !title) {
|
|
1329
1379
|
return null;
|
|
1330
1380
|
}
|
|
@@ -1346,7 +1396,7 @@ function isSameHiddenTarget(left, right) {
|
|
|
1346
1396
|
return left.title === right.title;
|
|
1347
1397
|
}
|
|
1348
1398
|
function sanitizeHiddenTargetEntries(entries) {
|
|
1349
|
-
return entries.map(sanitizeHiddenTargetEntry).filter((entry) => entry !== null).sort(
|
|
1399
|
+
return entries.map(sanitizeHiddenTargetEntry).filter((entry) => entry !== null).sort(sortByUpdatedAtDesc);
|
|
1350
1400
|
}
|
|
1351
1401
|
function sanitizeHiddenTargetEntry(entry) {
|
|
1352
1402
|
const candidate = entry;
|
|
@@ -1369,41 +1419,13 @@ function sanitizeHiddenTarget(target) {
|
|
|
1369
1419
|
if (candidate?.type !== "iframe") {
|
|
1370
1420
|
return null;
|
|
1371
1421
|
}
|
|
1372
|
-
const url =
|
|
1373
|
-
const title =
|
|
1422
|
+
const url = normalizeOptionalText(typeof candidate.url === "string" ? candidate.url : null);
|
|
1423
|
+
const title = normalizeOptionalText(typeof candidate.title === "string" ? candidate.title : null);
|
|
1374
1424
|
if (!url && !title) {
|
|
1375
1425
|
return null;
|
|
1376
1426
|
}
|
|
1377
1427
|
return { type: "iframe", url, title };
|
|
1378
1428
|
}
|
|
1379
|
-
function normalizeOptionalText2(value) {
|
|
1380
|
-
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
|
|
1381
|
-
}
|
|
1382
|
-
var sortByUpdatedAtDesc2 = (left, right) => right.updatedAt - left.updatedAt;
|
|
1383
|
-
var readStorageValue2 = async (storageArea, key) => {
|
|
1384
|
-
return await new Promise((resolve, reject) => {
|
|
1385
|
-
storageArea.get(key, (items) => {
|
|
1386
|
-
const error = chrome.runtime.lastError;
|
|
1387
|
-
if (error) {
|
|
1388
|
-
reject(new Error(error.message));
|
|
1389
|
-
return;
|
|
1390
|
-
}
|
|
1391
|
-
resolve(items[key]);
|
|
1392
|
-
});
|
|
1393
|
-
});
|
|
1394
|
-
};
|
|
1395
|
-
var writeStorageValue2 = async (storageArea, items) => {
|
|
1396
|
-
await new Promise((resolve, reject) => {
|
|
1397
|
-
storageArea.set(items, () => {
|
|
1398
|
-
const error = chrome.runtime.lastError;
|
|
1399
|
-
if (error) {
|
|
1400
|
-
reject(new Error(error.message));
|
|
1401
|
-
return;
|
|
1402
|
-
}
|
|
1403
|
-
resolve();
|
|
1404
|
-
});
|
|
1405
|
-
});
|
|
1406
|
-
};
|
|
1407
1429
|
|
|
1408
1430
|
// src/background/action-badge.ts
|
|
1409
1431
|
var badgeSyncChain = Promise.resolve();
|
|
@@ -1516,10 +1538,8 @@ function createWatcherStatus(debuggerManager2, tabId, session, watcherInfo, curr
|
|
|
1516
1538
|
const readiness = buildWatcherReadiness(debuggerManager2, tabId, session, watcherInfo, currentTarget);
|
|
1517
1539
|
return {
|
|
1518
1540
|
tabId,
|
|
1519
|
-
bridgeConnected: readiness.
|
|
1520
|
-
nativeHostConnected: readiness.nativeHostConnected,
|
|
1541
|
+
bridgeConnected: readiness.bridgeConnected,
|
|
1521
1542
|
watcherReady: readiness.watcherReady,
|
|
1522
|
-
targetReady: readiness.targetReady,
|
|
1523
1543
|
targetState: readiness.targetState,
|
|
1524
1544
|
watcherId: watcherInfo?.watcherId ?? null,
|
|
1525
1545
|
watcherHost: watcherInfo?.watcherHost ?? null,
|
|
@@ -1530,13 +1550,14 @@ function createWatcherStatus(debuggerManager2, tabId, session, watcherInfo, curr
|
|
|
1530
1550
|
};
|
|
1531
1551
|
}
|
|
1532
1552
|
function buildWatcherReadiness(debuggerManager2, tabId, session, watcherInfo, currentTarget) {
|
|
1533
|
-
const
|
|
1534
|
-
const watcherReady =
|
|
1553
|
+
const bridgeConnected = session.isConnected();
|
|
1554
|
+
const watcherReady = bridgeConnected && Boolean(watcherInfo?.watcherId && watcherInfo.watcherHost && watcherInfo.watcherPort != null);
|
|
1535
1555
|
const targetReady = currentTarget?.targetReady ?? getTargetReadiness(debuggerManager2, tabId, currentTarget);
|
|
1536
1556
|
return {
|
|
1537
|
-
|
|
1557
|
+
bridgeConnected,
|
|
1538
1558
|
watcherReady,
|
|
1539
|
-
targetReady
|
|
1559
|
+
// targetReady is not surfaced on its own: the popup only ever renders this
|
|
1560
|
+
// three-state derivation of it.
|
|
1540
1561
|
targetState: targetReady == null ? "not-selected" : targetReady ? "ready" : "rebinding"
|
|
1541
1562
|
};
|
|
1542
1563
|
}
|
|
@@ -1565,9 +1586,14 @@ var controlBridgeSession = new ControlBridgeSession(debuggerManager, {
|
|
|
1565
1586
|
recordEvent("error", "bridge", "Control native host disconnected");
|
|
1566
1587
|
}
|
|
1567
1588
|
});
|
|
1568
|
-
var
|
|
1569
|
-
var
|
|
1570
|
-
|
|
1589
|
+
var attachments = /* @__PURE__ */ new Map();
|
|
1590
|
+
var bridgeSessions = {
|
|
1591
|
+
get: (tabId) => attachments.get(tabId)?.session,
|
|
1592
|
+
has: (tabId) => attachments.has(tabId),
|
|
1593
|
+
keys: () => attachments.keys(),
|
|
1594
|
+
values: () => [...attachments.values()].map((attachment) => attachment.session),
|
|
1595
|
+
entries: () => [...attachments.entries()].map(([tabId, attachment]) => [tabId, attachment.session])
|
|
1596
|
+
};
|
|
1571
1597
|
var targetSelectionHistory = new TargetSelectionHistoryStore();
|
|
1572
1598
|
var targetVisibilityHistory = new TargetVisibilityHistoryStore();
|
|
1573
1599
|
var recentEvents = [];
|
|
@@ -1634,7 +1660,7 @@ async function attachTabFromControl(tabId, options = {}) {
|
|
|
1634
1660
|
}
|
|
1635
1661
|
return { ok: true, tab, watcherId: session.getWatcherInfo()?.watcherId };
|
|
1636
1662
|
} catch (error) {
|
|
1637
|
-
return { ok: false, error:
|
|
1663
|
+
return { ok: false, error: formatError(error) };
|
|
1638
1664
|
}
|
|
1639
1665
|
}
|
|
1640
1666
|
async function detachTabFromControl(tabId) {
|
|
@@ -1648,16 +1674,19 @@ async function detachTabFromControl(tabId) {
|
|
|
1648
1674
|
}
|
|
1649
1675
|
return { ok: true, tab };
|
|
1650
1676
|
} catch (error) {
|
|
1651
|
-
return { ok: false, error:
|
|
1677
|
+
return { ok: false, error: formatError(error) };
|
|
1652
1678
|
}
|
|
1653
1679
|
}
|
|
1654
1680
|
async function buildPopupResponse(message) {
|
|
1681
|
+
return await dispatchPopupAction(message);
|
|
1682
|
+
}
|
|
1683
|
+
async function dispatchPopupAction(message) {
|
|
1655
1684
|
try {
|
|
1656
1685
|
switch (message.action) {
|
|
1657
1686
|
case "getTargets":
|
|
1658
1687
|
return { success: true, tabs: await getTabsWithTargets() };
|
|
1659
1688
|
case "attach": {
|
|
1660
|
-
const tabId =
|
|
1689
|
+
const { tabId } = message;
|
|
1661
1690
|
await attachBridgeSession(tabId);
|
|
1662
1691
|
setSelectedFrame(tabId, null);
|
|
1663
1692
|
await prepareRememberedTargetSelection(tabId);
|
|
@@ -1665,24 +1694,23 @@ async function buildPopupResponse(message) {
|
|
|
1665
1694
|
return { success: true };
|
|
1666
1695
|
}
|
|
1667
1696
|
case "detach": {
|
|
1668
|
-
const tabId =
|
|
1697
|
+
const { tabId } = message;
|
|
1669
1698
|
await detachTab(tabId);
|
|
1670
1699
|
recordEvent("info", "popup", `Detached tab ${tabId}`);
|
|
1671
1700
|
return { success: true };
|
|
1672
1701
|
}
|
|
1673
1702
|
case "focusTab": {
|
|
1674
|
-
const tabId =
|
|
1703
|
+
const { tabId } = message;
|
|
1675
1704
|
await focusTab(tabId);
|
|
1676
1705
|
recordEvent("info", "popup", `Focused tab ${tabId}`);
|
|
1677
1706
|
return { success: true };
|
|
1678
1707
|
}
|
|
1679
1708
|
case "selectTarget": {
|
|
1680
|
-
const tabId =
|
|
1709
|
+
const { tabId, frameId } = message;
|
|
1681
1710
|
const session = bridgeSessions.get(tabId);
|
|
1682
1711
|
if (!session) {
|
|
1683
1712
|
return { success: false, error: `No watcher bridge for tab ${tabId}` };
|
|
1684
1713
|
}
|
|
1685
|
-
const frameId = message.frameId ?? null;
|
|
1686
1714
|
const target = getPopupTarget(debuggerManager, tabId, frameId);
|
|
1687
1715
|
if (!target) {
|
|
1688
1716
|
return { success: false, error: `Unknown target for tab ${tabId}` };
|
|
@@ -1695,15 +1723,15 @@ async function buildPopupResponse(message) {
|
|
|
1695
1723
|
return { success: true };
|
|
1696
1724
|
}
|
|
1697
1725
|
case "hideTarget": {
|
|
1698
|
-
const tabId =
|
|
1699
|
-
const target = getRequiredIframeTarget(debuggerManager, tabId,
|
|
1726
|
+
const { tabId, frameId } = message;
|
|
1727
|
+
const target = getRequiredIframeTarget(debuggerManager, tabId, frameId);
|
|
1700
1728
|
await hideTarget(tabId, target);
|
|
1701
1729
|
recordEvent("info", "popup", `Hid iframe ${target.frameId} on tab ${tabId}`);
|
|
1702
1730
|
return { success: true };
|
|
1703
1731
|
}
|
|
1704
1732
|
case "showTarget": {
|
|
1705
|
-
const tabId =
|
|
1706
|
-
const target = getRequiredIframeTarget(debuggerManager, tabId,
|
|
1733
|
+
const { tabId, frameId } = message;
|
|
1734
|
+
const target = getRequiredIframeTarget(debuggerManager, tabId, frameId);
|
|
1707
1735
|
await showTarget(tabId, target);
|
|
1708
1736
|
recordEvent("info", "popup", `Restored iframe ${target.frameId} on tab ${tabId}`);
|
|
1709
1737
|
return { success: true };
|
|
@@ -1713,8 +1741,6 @@ async function buildPopupResponse(message) {
|
|
|
1713
1741
|
success: true,
|
|
1714
1742
|
status: buildPopupStatusPayload()
|
|
1715
1743
|
};
|
|
1716
|
-
default:
|
|
1717
|
-
return { success: false, error: `Unknown action: ${message.action}` };
|
|
1718
1744
|
}
|
|
1719
1745
|
} catch (err) {
|
|
1720
1746
|
recordEvent("error", "popup", err instanceof Error ? err.message : "Unknown popup error");
|
|
@@ -1724,12 +1750,6 @@ async function buildPopupResponse(message) {
|
|
|
1724
1750
|
};
|
|
1725
1751
|
}
|
|
1726
1752
|
}
|
|
1727
|
-
function requireTabId(message) {
|
|
1728
|
-
if (message.tabId !== void 0) {
|
|
1729
|
-
return message.tabId;
|
|
1730
|
-
}
|
|
1731
|
-
throw new Error("No tabId provided");
|
|
1732
|
-
}
|
|
1733
1753
|
async function attachBridgeSession(tabId, options = {}) {
|
|
1734
1754
|
const existing = bridgeSessions.get(tabId);
|
|
1735
1755
|
if (existing) {
|
|
@@ -1756,7 +1776,7 @@ async function attachBridgeSession(tabId, options = {}) {
|
|
|
1756
1776
|
},
|
|
1757
1777
|
options
|
|
1758
1778
|
);
|
|
1759
|
-
|
|
1779
|
+
attachments.set(tabId, { session });
|
|
1760
1780
|
await connectBridgeSession(tabId, session);
|
|
1761
1781
|
return session;
|
|
1762
1782
|
}
|
|
@@ -1783,16 +1803,11 @@ async function connectBridgeSession(tabId, session) {
|
|
|
1783
1803
|
}
|
|
1784
1804
|
}
|
|
1785
1805
|
function clearTabState(tabId) {
|
|
1786
|
-
selectedFrameByTabId.delete(tabId);
|
|
1787
|
-
clearPendingRememberedTarget(tabId);
|
|
1788
1806
|
destroyBridgeSession(tabId);
|
|
1789
1807
|
}
|
|
1790
1808
|
function pruneStaleBridgeSessions() {
|
|
1791
|
-
for (const [tabId,
|
|
1792
|
-
if (debuggerManager.isAttached(tabId)) {
|
|
1793
|
-
continue;
|
|
1794
|
-
}
|
|
1795
|
-
if (!session.getTargetInfo()) {
|
|
1809
|
+
for (const [tabId, attachment] of attachments.entries()) {
|
|
1810
|
+
if (debuggerManager.isAttached(tabId) || !attachment.session.getTargetInfo()) {
|
|
1796
1811
|
continue;
|
|
1797
1812
|
}
|
|
1798
1813
|
clearTabState(tabId);
|
|
@@ -1800,12 +1815,12 @@ function pruneStaleBridgeSessions() {
|
|
|
1800
1815
|
}
|
|
1801
1816
|
}
|
|
1802
1817
|
function destroyBridgeSession(tabId) {
|
|
1803
|
-
const
|
|
1804
|
-
if (!
|
|
1818
|
+
const attachment = attachments.get(tabId);
|
|
1819
|
+
if (!attachment) {
|
|
1805
1820
|
return;
|
|
1806
1821
|
}
|
|
1807
|
-
|
|
1808
|
-
session.dispose();
|
|
1822
|
+
attachments.delete(tabId);
|
|
1823
|
+
attachment.session.dispose();
|
|
1809
1824
|
}
|
|
1810
1825
|
function buildPopupStatusPayload() {
|
|
1811
1826
|
return {
|
|
@@ -1815,8 +1830,7 @@ function buildPopupStatusPayload() {
|
|
|
1815
1830
|
url: target.url,
|
|
1816
1831
|
title: target.title
|
|
1817
1832
|
})),
|
|
1818
|
-
watchers: getWatcherStatuses()
|
|
1819
|
-
recentEvents
|
|
1833
|
+
watchers: getWatcherStatuses()
|
|
1820
1834
|
};
|
|
1821
1835
|
}
|
|
1822
1836
|
function buildControlDiagnostics() {
|
|
@@ -1904,10 +1918,7 @@ function syncSelectedFrameFromWatcher(targetId) {
|
|
|
1904
1918
|
setSelectedFrame(target.tabId, target.frameId);
|
|
1905
1919
|
}
|
|
1906
1920
|
function getSelectedFrameId(tabId) {
|
|
1907
|
-
|
|
1908
|
-
return void 0;
|
|
1909
|
-
}
|
|
1910
|
-
return selectedFrameByTabId.get(tabId) ?? null;
|
|
1921
|
+
return attachments.get(tabId)?.selectedFrameId;
|
|
1911
1922
|
}
|
|
1912
1923
|
async function rememberTargetSelection(tabId, target) {
|
|
1913
1924
|
const pageUrl = getPageUrlForTab(debuggerManager, tabId);
|
|
@@ -1962,9 +1973,9 @@ async function prepareRememberedTargetSelection(tabId) {
|
|
|
1962
1973
|
await replayRememberedTargetSelection(tabId);
|
|
1963
1974
|
}
|
|
1964
1975
|
async function replayRememberedTargetSelection(tabId) {
|
|
1965
|
-
const
|
|
1966
|
-
const
|
|
1967
|
-
if (!
|
|
1976
|
+
const attachment = attachments.get(tabId);
|
|
1977
|
+
const remembered = attachment?.pendingRememberedTarget;
|
|
1978
|
+
if (!attachment || !remembered) {
|
|
1968
1979
|
return;
|
|
1969
1980
|
}
|
|
1970
1981
|
const target = matchRememberedIframeTarget(
|
|
@@ -1975,7 +1986,7 @@ async function replayRememberedTargetSelection(tabId) {
|
|
|
1975
1986
|
return;
|
|
1976
1987
|
}
|
|
1977
1988
|
try {
|
|
1978
|
-
session.selectTarget(target.frameId);
|
|
1989
|
+
attachment.session.selectTarget(target.frameId);
|
|
1979
1990
|
setSelectedFrame(tabId, target.frameId);
|
|
1980
1991
|
clearPendingRememberedTarget(tabId);
|
|
1981
1992
|
recordEvent("info", "bridge", `Restored iframe ${target.frameId} on tab ${tabId}`);
|
|
@@ -1984,16 +1995,25 @@ async function replayRememberedTargetSelection(tabId) {
|
|
|
1984
1995
|
}
|
|
1985
1996
|
}
|
|
1986
1997
|
function shouldReplayRememberedTarget(tabId, method) {
|
|
1987
|
-
return
|
|
1998
|
+
return attachments.get(tabId)?.pendingRememberedTarget != null && REMEMBERED_TARGET_RETRY_EVENTS.has(method);
|
|
1988
1999
|
}
|
|
1989
2000
|
function setSelectedFrame(tabId, frameId) {
|
|
1990
|
-
|
|
2001
|
+
const attachment = attachments.get(tabId);
|
|
2002
|
+
if (attachment) {
|
|
2003
|
+
attachment.selectedFrameId = frameId;
|
|
2004
|
+
}
|
|
1991
2005
|
}
|
|
1992
2006
|
function setPendingRememberedTarget(tabId, remembered) {
|
|
1993
|
-
|
|
2007
|
+
const attachment = attachments.get(tabId);
|
|
2008
|
+
if (attachment) {
|
|
2009
|
+
attachment.pendingRememberedTarget = remembered;
|
|
2010
|
+
}
|
|
1994
2011
|
}
|
|
1995
2012
|
function clearPendingRememberedTarget(tabId) {
|
|
1996
|
-
|
|
2013
|
+
const attachment = attachments.get(tabId);
|
|
2014
|
+
if (attachment) {
|
|
2015
|
+
delete attachment.pendingRememberedTarget;
|
|
2016
|
+
}
|
|
1997
2017
|
}
|
|
1998
2018
|
console.log("[ServiceWorker] Argus CDP Bridge extension loaded");
|
|
1999
2019
|
void syncActionBadge(debuggerManager);
|