@vforsh/argus 0.3.1 → 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 +5285 -5575
- 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 +27 -57
- 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 +5 -5
- 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 +1 -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 +1 -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 -25
- package/dist/commands/extension/targetSelection.d.ts.map +1 -1
- package/dist/commands/extension/targetSelection.js +2 -2
- 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 +465 -448
- 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/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
358
|
const target = this.attached.get(tabId);
|
|
243
359
|
if (!target) {
|
|
244
360
|
return;
|
|
245
361
|
}
|
|
246
|
-
|
|
247
|
-
this.mergeFrameTree(tabId, sessionId, node, nextFrameIds);
|
|
248
|
-
this.pruneMissingSessionFrames(tabId, sessionId, nextFrameIds);
|
|
362
|
+
applyFrameTreeSnapshot(target, sessionId, result.frameTree);
|
|
249
363
|
}
|
|
250
|
-
|
|
251
|
-
if (!node?.frame?.id) {
|
|
252
|
-
return;
|
|
253
|
-
}
|
|
254
|
-
const target = this.attached.get(tabId);
|
|
255
|
-
if (!target) {
|
|
256
|
-
return;
|
|
257
|
-
}
|
|
258
|
-
const frameId = node.frame.id;
|
|
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
|
-
}
|
|
280
|
-
}
|
|
281
|
-
pruneMissingSessionFrames(tabId, sessionId, nextFrameIds) {
|
|
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
|
-
}
|
|
379
|
+
const serialized = serializeFrameTable(target);
|
|
380
|
+
if (this.lastPublishedFrames.get(tabId) === serialized) {
|
|
309
381
|
return;
|
|
310
382
|
}
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
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
|
-
});
|
|
324
|
-
return;
|
|
325
|
-
}
|
|
326
|
-
if (method === "Page.frameDetached" && params) {
|
|
327
|
-
const frame = params;
|
|
328
|
-
if (!frame.frameId) {
|
|
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,12 +609,22 @@ 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.
|
|
@@ -621,9 +641,6 @@ var CdpProxy = class {
|
|
|
621
641
|
*/
|
|
622
642
|
async handleMessage(message) {
|
|
623
643
|
switch (message.type) {
|
|
624
|
-
case "attach_tab":
|
|
625
|
-
await this.handleAttachTab(message);
|
|
626
|
-
break;
|
|
627
644
|
case "detach_tab":
|
|
628
645
|
await this.handleDetachTab(message);
|
|
629
646
|
break;
|
|
@@ -633,8 +650,8 @@ var CdpProxy = class {
|
|
|
633
650
|
case "cookie_query":
|
|
634
651
|
await this.handleCookieQuery(message);
|
|
635
652
|
break;
|
|
636
|
-
case "
|
|
637
|
-
await this.
|
|
653
|
+
case "frame_snapshot_request":
|
|
654
|
+
await this.handleFrameSnapshotRequest(message);
|
|
638
655
|
break;
|
|
639
656
|
case "host_info":
|
|
640
657
|
case "host_ready":
|
|
@@ -645,11 +662,11 @@ var CdpProxy = class {
|
|
|
645
662
|
}
|
|
646
663
|
}
|
|
647
664
|
/**
|
|
648
|
-
* Attach to a tab.
|
|
665
|
+
* Attach to a tab (driven by the popup; the host never requests attachment).
|
|
649
666
|
*/
|
|
650
|
-
async
|
|
667
|
+
async attachTab(tabId) {
|
|
651
668
|
try {
|
|
652
|
-
const target = await this.debuggerManager.attach(
|
|
669
|
+
const target = await this.debuggerManager.attach(tabId);
|
|
653
670
|
this.bridgeClient.send({
|
|
654
671
|
type: "tab_attached",
|
|
655
672
|
tabId: target.tabId,
|
|
@@ -663,7 +680,7 @@ var CdpProxy = class {
|
|
|
663
680
|
console.error("[CdpProxy] Failed to attach:", err);
|
|
664
681
|
this.bridgeClient.send({
|
|
665
682
|
type: "tab_detached",
|
|
666
|
-
tabId
|
|
683
|
+
tabId,
|
|
667
684
|
reason: err instanceof Error ? err.message : "attach_failed"
|
|
668
685
|
});
|
|
669
686
|
throw err;
|
|
@@ -696,6 +713,26 @@ var CdpProxy = class {
|
|
|
696
713
|
});
|
|
697
714
|
}
|
|
698
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
|
+
}
|
|
699
736
|
/**
|
|
700
737
|
* Query browser cookies from the attached tab's cookie store.
|
|
701
738
|
*/
|
|
@@ -720,22 +757,6 @@ var CdpProxy = class {
|
|
|
720
757
|
});
|
|
721
758
|
}
|
|
722
759
|
}
|
|
723
|
-
/**
|
|
724
|
-
* Enable a CDP domain for a tab.
|
|
725
|
-
*/
|
|
726
|
-
async handleEnableDomain(message) {
|
|
727
|
-
try {
|
|
728
|
-
await this.debuggerManager.enableDomain(message.tabId, message.domain);
|
|
729
|
-
} catch (err) {
|
|
730
|
-
console.error("[CdpProxy] Failed to enable domain:", err);
|
|
731
|
-
}
|
|
732
|
-
}
|
|
733
|
-
/**
|
|
734
|
-
* Manually attach to a tab (called from popup).
|
|
735
|
-
*/
|
|
736
|
-
async attachTab(tabId) {
|
|
737
|
-
await this.handleAttachTab({ type: "attach_tab", tabId });
|
|
738
|
-
}
|
|
739
760
|
/**
|
|
740
761
|
* Manually detach from a tab (called from popup).
|
|
741
762
|
*/
|
|
@@ -747,18 +768,60 @@ var CdpProxy = class {
|
|
|
747
768
|
});
|
|
748
769
|
await this.debuggerManager.detach(tabId);
|
|
749
770
|
}
|
|
750
|
-
/**
|
|
751
|
-
* Get list of tabs for popup UI.
|
|
752
|
-
*/
|
|
753
|
-
async getTabsForPopup() {
|
|
754
|
-
return await listBrowserTabs(this.debuggerManager);
|
|
755
|
-
}
|
|
756
771
|
};
|
|
757
772
|
|
|
758
773
|
// src/background/native-hosts.ts
|
|
759
774
|
var BRIDGE_HOST_NAME = "com.vforsh.argus.bridge";
|
|
760
775
|
var CONTROL_HOST_NAME = "com.vforsh.argus.control";
|
|
761
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
|
+
|
|
762
825
|
// src/background/tab-bridge-session.ts
|
|
763
826
|
var TabBridgeSession = class {
|
|
764
827
|
tabId;
|
|
@@ -769,10 +832,10 @@ var TabBridgeSession = class {
|
|
|
769
832
|
targetInfo = null;
|
|
770
833
|
desiredWatcherId;
|
|
771
834
|
lastMessageAt = null;
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
watcherInfoWaiters = [];
|
|
835
|
+
hostReady = createLatch();
|
|
836
|
+
watcherInfoReceived = createLatch();
|
|
775
837
|
disposed = false;
|
|
838
|
+
protocolMismatch = null;
|
|
776
839
|
constructor(tabId, debuggerManager2, events = {}, options = {}) {
|
|
777
840
|
this.tabId = tabId;
|
|
778
841
|
this.events = events;
|
|
@@ -802,27 +865,10 @@ var TabBridgeSession = class {
|
|
|
802
865
|
if (!sent) {
|
|
803
866
|
throw new Error(`Failed to initialize watcher for tab ${this.tabId}`);
|
|
804
867
|
}
|
|
805
|
-
await this.
|
|
806
|
-
await this.
|
|
868
|
+
await this.awaitLatch(this.hostReady, "did not become ready");
|
|
869
|
+
await this.awaitLatch(this.watcherInfoReceived, "did not report watcher info");
|
|
807
870
|
await this.cdpProxy.attachTab(this.tabId);
|
|
808
871
|
}
|
|
809
|
-
async waitUntilReady(timeoutMs = 3e3) {
|
|
810
|
-
this.assertOpen();
|
|
811
|
-
if (this.ready) {
|
|
812
|
-
return;
|
|
813
|
-
}
|
|
814
|
-
await new Promise((resolve, reject) => {
|
|
815
|
-
const timer = setTimeout(() => {
|
|
816
|
-
this.readyWaiters = this.readyWaiters.filter((waiter) => waiter !== onReady);
|
|
817
|
-
reject(new Error(`Native host session for tab ${this.tabId} did not become ready`));
|
|
818
|
-
}, timeoutMs);
|
|
819
|
-
const onReady = () => {
|
|
820
|
-
clearTimeout(timer);
|
|
821
|
-
resolve();
|
|
822
|
-
};
|
|
823
|
-
this.readyWaiters.push(onReady);
|
|
824
|
-
});
|
|
825
|
-
}
|
|
826
872
|
async detach() {
|
|
827
873
|
if (this.disposed) {
|
|
828
874
|
return;
|
|
@@ -864,27 +910,22 @@ var TabBridgeSession = class {
|
|
|
864
910
|
getLastMessageAt() {
|
|
865
911
|
return this.lastMessageAt;
|
|
866
912
|
}
|
|
867
|
-
async
|
|
913
|
+
async awaitLatch(latch, failure, timeoutMs = 3e3) {
|
|
868
914
|
this.assertOpen();
|
|
869
|
-
|
|
870
|
-
return;
|
|
871
|
-
}
|
|
872
|
-
await new Promise((resolve, reject) => {
|
|
873
|
-
const timer = setTimeout(() => {
|
|
874
|
-
this.watcherInfoWaiters = this.watcherInfoWaiters.filter((waiter) => waiter !== onWatcherInfo);
|
|
875
|
-
reject(new Error(`Native host session for tab ${this.tabId} did not report watcher info`));
|
|
876
|
-
}, timeoutMs);
|
|
877
|
-
const onWatcherInfo = () => {
|
|
878
|
-
clearTimeout(timer);
|
|
879
|
-
resolve();
|
|
880
|
-
};
|
|
881
|
-
this.watcherInfoWaiters.push(onWatcherInfo);
|
|
882
|
-
});
|
|
915
|
+
await latch.wait(timeoutMs, `Native host session for tab ${this.tabId} ${failure}`);
|
|
883
916
|
}
|
|
884
917
|
handleMessage(message) {
|
|
885
918
|
this.lastMessageAt = Date.now();
|
|
886
919
|
switch (message.type) {
|
|
887
|
-
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
|
+
}
|
|
888
929
|
this.watcherInfo = {
|
|
889
930
|
watcherId: message.watcherId,
|
|
890
931
|
watcherHost: message.watcherHost,
|
|
@@ -892,10 +933,11 @@ var TabBridgeSession = class {
|
|
|
892
933
|
pid: message.pid
|
|
893
934
|
};
|
|
894
935
|
this.events.onWatcherInfo?.(this.watcherInfo);
|
|
895
|
-
this.
|
|
936
|
+
this.watcherInfoReceived.signal();
|
|
896
937
|
return;
|
|
938
|
+
}
|
|
897
939
|
case "host_ready":
|
|
898
|
-
this.
|
|
940
|
+
this.hostReady.signal();
|
|
899
941
|
return;
|
|
900
942
|
case "target_info":
|
|
901
943
|
this.targetInfo = {
|
|
@@ -908,28 +950,52 @@ var TabBridgeSession = class {
|
|
|
908
950
|
this.events.onTargetInfo?.(this.targetInfo);
|
|
909
951
|
}
|
|
910
952
|
}
|
|
911
|
-
resolveReadyWaiters() {
|
|
912
|
-
this.ready = true;
|
|
913
|
-
const waiters = this.readyWaiters;
|
|
914
|
-
this.readyWaiters = [];
|
|
915
|
-
for (const waiter of waiters) {
|
|
916
|
-
waiter();
|
|
917
|
-
}
|
|
918
|
-
}
|
|
919
|
-
resolveWatcherInfoWaiters() {
|
|
920
|
-
const waiters = this.watcherInfoWaiters;
|
|
921
|
-
this.watcherInfoWaiters = [];
|
|
922
|
-
for (const waiter of waiters) {
|
|
923
|
-
waiter();
|
|
924
|
-
}
|
|
925
|
-
}
|
|
926
953
|
assertOpen() {
|
|
954
|
+
if (this.protocolMismatch) {
|
|
955
|
+
throw new Error(this.protocolMismatch);
|
|
956
|
+
}
|
|
927
957
|
if (this.disposed) {
|
|
928
958
|
throw new Error(`Native host session for tab ${this.tabId} is already closed`);
|
|
929
959
|
}
|
|
930
960
|
}
|
|
931
961
|
};
|
|
932
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
|
+
|
|
933
999
|
// src/background/control-bridge-session.ts
|
|
934
1000
|
var ControlBridgeSession = class {
|
|
935
1001
|
bridgeClient;
|
|
@@ -975,7 +1041,13 @@ var ControlBridgeSession = class {
|
|
|
975
1041
|
async handleMessage(message) {
|
|
976
1042
|
this.lastMessageAt = Date.now();
|
|
977
1043
|
switch (message.type) {
|
|
978
|
-
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
|
+
}
|
|
979
1051
|
this.watcherInfo = {
|
|
980
1052
|
watcherId: message.watcherId,
|
|
981
1053
|
watcherHost: message.watcherHost,
|
|
@@ -984,6 +1056,7 @@ var ControlBridgeSession = class {
|
|
|
984
1056
|
};
|
|
985
1057
|
this.events.onWatcherInfo?.(this.watcherInfo);
|
|
986
1058
|
return;
|
|
1059
|
+
}
|
|
987
1060
|
case "attach_tab_watcher":
|
|
988
1061
|
await this.handleTabAction(message.requestId, () => this.events.onAttachTabWatcher?.(message.tabId, { watcherId: message.watcherId }));
|
|
989
1062
|
return;
|
|
@@ -1013,7 +1086,7 @@ var ControlBridgeSession = class {
|
|
|
1013
1086
|
type: "tab_action_response",
|
|
1014
1087
|
requestId,
|
|
1015
1088
|
ok: false,
|
|
1016
|
-
error: { message:
|
|
1089
|
+
error: { message: formatError(error) }
|
|
1017
1090
|
});
|
|
1018
1091
|
}
|
|
1019
1092
|
}
|
|
@@ -1057,6 +1130,79 @@ var ControlBridgeSession = class {
|
|
|
1057
1130
|
}
|
|
1058
1131
|
};
|
|
1059
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
|
+
|
|
1060
1206
|
// src/background/target-selection-history.ts
|
|
1061
1207
|
var DEFAULT_STORAGE_KEY = "targetSelectionHistory";
|
|
1062
1208
|
var DEFAULT_MAX_ENTRIES = 20;
|
|
@@ -1082,55 +1228,23 @@ var matchRememberedIframeTarget = (entry, targets) => {
|
|
|
1082
1228
|
}
|
|
1083
1229
|
return pickSingleTargetMatch(iframeTargets, (target) => normalizeTargetTitle(target.title) === rememberedIframe.title);
|
|
1084
1230
|
};
|
|
1085
|
-
var TargetSelectionHistoryStore = class {
|
|
1086
|
-
persistence;
|
|
1087
|
-
maxEntries;
|
|
1088
|
-
entries = [];
|
|
1089
|
-
loadPromise = null;
|
|
1090
|
-
saveChain = Promise.resolve();
|
|
1231
|
+
var TargetSelectionHistoryStore = class extends PageKeyedStore {
|
|
1091
1232
|
constructor(persistence = createChromeStoragePersistence(), options = {}) {
|
|
1092
|
-
|
|
1093
|
-
this.maxEntries = options.maxEntries ?? DEFAULT_MAX_ENTRIES;
|
|
1233
|
+
super(persistence, options.maxEntries ?? DEFAULT_MAX_ENTRIES, "TargetSelectionHistoryStore");
|
|
1094
1234
|
}
|
|
1095
1235
|
async getByPageUrl(pageUrl) {
|
|
1096
1236
|
await this.ensureLoaded();
|
|
1097
|
-
|
|
1098
|
-
return this.entries.find((entry) => entry.pageKey === pageKey) ?? null;
|
|
1237
|
+
return this.findByPageKey(normalizeSelectionPageKey(pageUrl));
|
|
1099
1238
|
}
|
|
1100
1239
|
async remember(pageUrl, target) {
|
|
1101
1240
|
await this.ensureLoaded();
|
|
1102
1241
|
const entry = buildRememberedSelection(pageUrl, target);
|
|
1103
|
-
this.
|
|
1242
|
+
this.upsert(entry);
|
|
1104
1243
|
await this.persist();
|
|
1105
1244
|
return entry;
|
|
1106
1245
|
}
|
|
1107
|
-
async ensureLoaded() {
|
|
1108
|
-
if (!this.loadPromise) {
|
|
1109
|
-
this.loadPromise = this.persistence.load().then((entries) => {
|
|
1110
|
-
this.entries = sanitizeRememberedSelections(entries).slice(0, this.maxEntries);
|
|
1111
|
-
}).catch((error) => {
|
|
1112
|
-
console.error("[TargetSelectionHistoryStore] Failed to load history:", error);
|
|
1113
|
-
this.entries = [];
|
|
1114
|
-
});
|
|
1115
|
-
}
|
|
1116
|
-
await this.loadPromise;
|
|
1117
|
-
}
|
|
1118
|
-
async persist() {
|
|
1119
|
-
this.saveChain = this.saveChain.catch(() => void 0).then(() => this.persistence.save(this.entries)).catch((error) => {
|
|
1120
|
-
console.error("[TargetSelectionHistoryStore] Failed to save history:", error);
|
|
1121
|
-
});
|
|
1122
|
-
await this.saveChain;
|
|
1123
|
-
}
|
|
1124
1246
|
};
|
|
1125
|
-
var createChromeStoragePersistence = (storageArea = chrome.storage.local, storageKey = DEFAULT_STORAGE_KEY) => (
|
|
1126
|
-
load: async () => {
|
|
1127
|
-
const stored = await readStorageValue(storageArea, storageKey);
|
|
1128
|
-
return sanitizeRememberedSelections(Array.isArray(stored) ? stored : []);
|
|
1129
|
-
},
|
|
1130
|
-
save: async (entries) => {
|
|
1131
|
-
await writeStorageValue(storageArea, { [storageKey]: entries });
|
|
1132
|
-
}
|
|
1133
|
-
});
|
|
1247
|
+
var createChromeStoragePersistence = (storageArea = chrome.storage.local, storageKey = DEFAULT_STORAGE_KEY) => createChromeStorePersistence(storageKey, (value) => sanitizeRememberedSelections(Array.isArray(value) ? value : []), storageArea);
|
|
1134
1248
|
var buildRememberedSelection = (pageUrl, target) => {
|
|
1135
1249
|
const base = {
|
|
1136
1250
|
pageKey: normalizeSelectionPageKey(pageUrl),
|
|
@@ -1193,56 +1307,25 @@ var sanitizeRememberedSelection = (entry) => {
|
|
|
1193
1307
|
};
|
|
1194
1308
|
};
|
|
1195
1309
|
function normalizeTargetUrl(url) {
|
|
1196
|
-
return
|
|
1310
|
+
return normalizeOptionalText2(url);
|
|
1197
1311
|
}
|
|
1198
1312
|
function normalizeTargetTitle(title) {
|
|
1199
|
-
return
|
|
1313
|
+
return normalizeOptionalText2(title);
|
|
1200
1314
|
}
|
|
1201
|
-
function
|
|
1315
|
+
function normalizeOptionalText2(value) {
|
|
1202
1316
|
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
|
|
1203
1317
|
}
|
|
1204
|
-
var sortByUpdatedAtDesc = (left, right) => right.updatedAt - left.updatedAt;
|
|
1205
|
-
var readStorageValue = async (storageArea, key) => {
|
|
1206
|
-
return await new Promise((resolve, reject) => {
|
|
1207
|
-
storageArea.get(key, (items) => {
|
|
1208
|
-
const error = chrome.runtime.lastError;
|
|
1209
|
-
if (error) {
|
|
1210
|
-
reject(new Error(error.message));
|
|
1211
|
-
return;
|
|
1212
|
-
}
|
|
1213
|
-
resolve(items[key]);
|
|
1214
|
-
});
|
|
1215
|
-
});
|
|
1216
|
-
};
|
|
1217
|
-
var writeStorageValue = async (storageArea, items) => {
|
|
1218
|
-
await new Promise((resolve, reject) => {
|
|
1219
|
-
storageArea.set(items, () => {
|
|
1220
|
-
const error = chrome.runtime.lastError;
|
|
1221
|
-
if (error) {
|
|
1222
|
-
reject(new Error(error.message));
|
|
1223
|
-
return;
|
|
1224
|
-
}
|
|
1225
|
-
resolve();
|
|
1226
|
-
});
|
|
1227
|
-
});
|
|
1228
|
-
};
|
|
1229
1318
|
|
|
1230
1319
|
// src/background/target-visibility-history.ts
|
|
1231
1320
|
var DEFAULT_STORAGE_KEY2 = "hiddenTargetHistory";
|
|
1232
1321
|
var DEFAULT_MAX_PAGE_ENTRIES = 20;
|
|
1233
|
-
var TargetVisibilityHistoryStore = class {
|
|
1234
|
-
persistence;
|
|
1235
|
-
maxPageEntries;
|
|
1236
|
-
entries = [];
|
|
1237
|
-
loadPromise = null;
|
|
1238
|
-
saveChain = Promise.resolve();
|
|
1322
|
+
var TargetVisibilityHistoryStore = class extends PageKeyedStore {
|
|
1239
1323
|
constructor(persistence = createChromeStoragePersistence2(), options = {}) {
|
|
1240
|
-
|
|
1241
|
-
this.maxPageEntries = options.maxPageEntries ?? DEFAULT_MAX_PAGE_ENTRIES;
|
|
1324
|
+
super(persistence, options.maxPageEntries ?? DEFAULT_MAX_PAGE_ENTRIES, "TargetVisibilityHistoryStore");
|
|
1242
1325
|
}
|
|
1243
1326
|
async getHiddenTargets(pageUrl) {
|
|
1244
1327
|
await this.ensureLoaded();
|
|
1245
|
-
return [...this.
|
|
1328
|
+
return [...this.findByPageKey(normalizeSelectionPageKey(pageUrl))?.targets ?? []];
|
|
1246
1329
|
}
|
|
1247
1330
|
async hide(pageUrl, target) {
|
|
1248
1331
|
await this.ensureLoaded();
|
|
@@ -1251,10 +1334,10 @@ var TargetVisibilityHistoryStore = class {
|
|
|
1251
1334
|
return null;
|
|
1252
1335
|
}
|
|
1253
1336
|
const pageKey = normalizeSelectionPageKey(pageUrl);
|
|
1254
|
-
const existing = this.
|
|
1337
|
+
const existing = this.findByPageKey(normalizeSelectionPageKey(pageUrl));
|
|
1255
1338
|
const targets = uniqueHiddenTargets([hiddenTarget, ...existing?.targets ?? []]);
|
|
1256
1339
|
const entry = { pageKey, pageUrl, updatedAt: Date.now(), targets };
|
|
1257
|
-
this.
|
|
1340
|
+
this.upsert(entry);
|
|
1258
1341
|
await this.persist();
|
|
1259
1342
|
return entry;
|
|
1260
1343
|
}
|
|
@@ -1264,7 +1347,7 @@ var TargetVisibilityHistoryStore = class {
|
|
|
1264
1347
|
if (!hiddenTarget) {
|
|
1265
1348
|
return;
|
|
1266
1349
|
}
|
|
1267
|
-
const existing = this.
|
|
1350
|
+
const existing = this.findByPageKey(normalizeSelectionPageKey(pageUrl));
|
|
1268
1351
|
if (!existing) {
|
|
1269
1352
|
return;
|
|
1270
1353
|
}
|
|
@@ -1277,44 +1360,8 @@ var TargetVisibilityHistoryStore = class {
|
|
|
1277
1360
|
this.entries = this.entries.map((entry) => entry.pageKey === existing.pageKey ? { ...entry, targets, updatedAt: Date.now() } : entry);
|
|
1278
1361
|
await this.persist();
|
|
1279
1362
|
}
|
|
1280
|
-
async isHidden(pageUrl, target) {
|
|
1281
|
-
const hiddenTargets = await this.getHiddenTargets(pageUrl);
|
|
1282
|
-
return hiddenTargets.some((hiddenTarget) => matchesHiddenTarget(hiddenTarget, target));
|
|
1283
|
-
}
|
|
1284
|
-
findEntry(pageUrl) {
|
|
1285
|
-
const pageKey = normalizeSelectionPageKey(pageUrl);
|
|
1286
|
-
return this.entries.find((entry) => entry.pageKey === pageKey) ?? null;
|
|
1287
|
-
}
|
|
1288
|
-
upsertEntry(entry) {
|
|
1289
|
-
this.entries = [entry, ...this.entries.filter((candidate) => candidate.pageKey !== entry.pageKey)].slice(0, this.maxPageEntries);
|
|
1290
|
-
}
|
|
1291
|
-
async ensureLoaded() {
|
|
1292
|
-
if (!this.loadPromise) {
|
|
1293
|
-
this.loadPromise = this.persistence.load().then((entries) => {
|
|
1294
|
-
this.entries = sanitizeHiddenTargetEntries(entries).slice(0, this.maxPageEntries);
|
|
1295
|
-
}).catch((error) => {
|
|
1296
|
-
console.error("[TargetVisibilityHistoryStore] Failed to load history:", error);
|
|
1297
|
-
this.entries = [];
|
|
1298
|
-
});
|
|
1299
|
-
}
|
|
1300
|
-
await this.loadPromise;
|
|
1301
|
-
}
|
|
1302
|
-
async persist() {
|
|
1303
|
-
this.saveChain = this.saveChain.catch(() => void 0).then(() => this.persistence.save(this.entries)).catch((error) => {
|
|
1304
|
-
console.error("[TargetVisibilityHistoryStore] Failed to save history:", error);
|
|
1305
|
-
});
|
|
1306
|
-
await this.saveChain;
|
|
1307
|
-
}
|
|
1308
1363
|
};
|
|
1309
|
-
var createChromeStoragePersistence2 = (storageArea = chrome.storage.local, storageKey = DEFAULT_STORAGE_KEY2) => (
|
|
1310
|
-
load: async () => {
|
|
1311
|
-
const stored = await readStorageValue2(storageArea, storageKey);
|
|
1312
|
-
return sanitizeHiddenTargetEntries(Array.isArray(stored) ? stored : []);
|
|
1313
|
-
},
|
|
1314
|
-
save: async (entries) => {
|
|
1315
|
-
await writeStorageValue2(storageArea, { [storageKey]: entries });
|
|
1316
|
-
}
|
|
1317
|
-
});
|
|
1364
|
+
var createChromeStoragePersistence2 = (storageArea = chrome.storage.local, storageKey = DEFAULT_STORAGE_KEY2) => createChromeStorePersistence(storageKey, (value) => sanitizeHiddenTargetEntries(Array.isArray(value) ? value : []), storageArea);
|
|
1318
1365
|
function matchesHiddenTarget(hiddenTarget, target) {
|
|
1319
1366
|
if (target.type !== "iframe") {
|
|
1320
1367
|
return false;
|
|
@@ -1326,8 +1373,8 @@ function toHiddenTarget(target) {
|
|
|
1326
1373
|
if (target.type !== "iframe") {
|
|
1327
1374
|
return null;
|
|
1328
1375
|
}
|
|
1329
|
-
const url =
|
|
1330
|
-
const title =
|
|
1376
|
+
const url = normalizeOptionalText(target.url);
|
|
1377
|
+
const title = normalizeOptionalText(target.title);
|
|
1331
1378
|
if (!url && !title) {
|
|
1332
1379
|
return null;
|
|
1333
1380
|
}
|
|
@@ -1349,7 +1396,7 @@ function isSameHiddenTarget(left, right) {
|
|
|
1349
1396
|
return left.title === right.title;
|
|
1350
1397
|
}
|
|
1351
1398
|
function sanitizeHiddenTargetEntries(entries) {
|
|
1352
|
-
return entries.map(sanitizeHiddenTargetEntry).filter((entry) => entry !== null).sort(
|
|
1399
|
+
return entries.map(sanitizeHiddenTargetEntry).filter((entry) => entry !== null).sort(sortByUpdatedAtDesc);
|
|
1353
1400
|
}
|
|
1354
1401
|
function sanitizeHiddenTargetEntry(entry) {
|
|
1355
1402
|
const candidate = entry;
|
|
@@ -1372,41 +1419,13 @@ function sanitizeHiddenTarget(target) {
|
|
|
1372
1419
|
if (candidate?.type !== "iframe") {
|
|
1373
1420
|
return null;
|
|
1374
1421
|
}
|
|
1375
|
-
const url =
|
|
1376
|
-
const title =
|
|
1422
|
+
const url = normalizeOptionalText(typeof candidate.url === "string" ? candidate.url : null);
|
|
1423
|
+
const title = normalizeOptionalText(typeof candidate.title === "string" ? candidate.title : null);
|
|
1377
1424
|
if (!url && !title) {
|
|
1378
1425
|
return null;
|
|
1379
1426
|
}
|
|
1380
1427
|
return { type: "iframe", url, title };
|
|
1381
1428
|
}
|
|
1382
|
-
function normalizeOptionalText2(value) {
|
|
1383
|
-
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
|
|
1384
|
-
}
|
|
1385
|
-
var sortByUpdatedAtDesc2 = (left, right) => right.updatedAt - left.updatedAt;
|
|
1386
|
-
var readStorageValue2 = async (storageArea, key) => {
|
|
1387
|
-
return await new Promise((resolve, reject) => {
|
|
1388
|
-
storageArea.get(key, (items) => {
|
|
1389
|
-
const error = chrome.runtime.lastError;
|
|
1390
|
-
if (error) {
|
|
1391
|
-
reject(new Error(error.message));
|
|
1392
|
-
return;
|
|
1393
|
-
}
|
|
1394
|
-
resolve(items[key]);
|
|
1395
|
-
});
|
|
1396
|
-
});
|
|
1397
|
-
};
|
|
1398
|
-
var writeStorageValue2 = async (storageArea, items) => {
|
|
1399
|
-
await new Promise((resolve, reject) => {
|
|
1400
|
-
storageArea.set(items, () => {
|
|
1401
|
-
const error = chrome.runtime.lastError;
|
|
1402
|
-
if (error) {
|
|
1403
|
-
reject(new Error(error.message));
|
|
1404
|
-
return;
|
|
1405
|
-
}
|
|
1406
|
-
resolve();
|
|
1407
|
-
});
|
|
1408
|
-
});
|
|
1409
|
-
};
|
|
1410
1429
|
|
|
1411
1430
|
// src/background/action-badge.ts
|
|
1412
1431
|
var badgeSyncChain = Promise.resolve();
|
|
@@ -1519,10 +1538,8 @@ function createWatcherStatus(debuggerManager2, tabId, session, watcherInfo, curr
|
|
|
1519
1538
|
const readiness = buildWatcherReadiness(debuggerManager2, tabId, session, watcherInfo, currentTarget);
|
|
1520
1539
|
return {
|
|
1521
1540
|
tabId,
|
|
1522
|
-
bridgeConnected: readiness.
|
|
1523
|
-
nativeHostConnected: readiness.nativeHostConnected,
|
|
1541
|
+
bridgeConnected: readiness.bridgeConnected,
|
|
1524
1542
|
watcherReady: readiness.watcherReady,
|
|
1525
|
-
targetReady: readiness.targetReady,
|
|
1526
1543
|
targetState: readiness.targetState,
|
|
1527
1544
|
watcherId: watcherInfo?.watcherId ?? null,
|
|
1528
1545
|
watcherHost: watcherInfo?.watcherHost ?? null,
|
|
@@ -1533,13 +1550,14 @@ function createWatcherStatus(debuggerManager2, tabId, session, watcherInfo, curr
|
|
|
1533
1550
|
};
|
|
1534
1551
|
}
|
|
1535
1552
|
function buildWatcherReadiness(debuggerManager2, tabId, session, watcherInfo, currentTarget) {
|
|
1536
|
-
const
|
|
1537
|
-
const watcherReady =
|
|
1553
|
+
const bridgeConnected = session.isConnected();
|
|
1554
|
+
const watcherReady = bridgeConnected && Boolean(watcherInfo?.watcherId && watcherInfo.watcherHost && watcherInfo.watcherPort != null);
|
|
1538
1555
|
const targetReady = currentTarget?.targetReady ?? getTargetReadiness(debuggerManager2, tabId, currentTarget);
|
|
1539
1556
|
return {
|
|
1540
|
-
|
|
1557
|
+
bridgeConnected,
|
|
1541
1558
|
watcherReady,
|
|
1542
|
-
targetReady
|
|
1559
|
+
// targetReady is not surfaced on its own: the popup only ever renders this
|
|
1560
|
+
// three-state derivation of it.
|
|
1543
1561
|
targetState: targetReady == null ? "not-selected" : targetReady ? "ready" : "rebinding"
|
|
1544
1562
|
};
|
|
1545
1563
|
}
|
|
@@ -1568,9 +1586,14 @@ var controlBridgeSession = new ControlBridgeSession(debuggerManager, {
|
|
|
1568
1586
|
recordEvent("error", "bridge", "Control native host disconnected");
|
|
1569
1587
|
}
|
|
1570
1588
|
});
|
|
1571
|
-
var
|
|
1572
|
-
var
|
|
1573
|
-
|
|
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
|
+
};
|
|
1574
1597
|
var targetSelectionHistory = new TargetSelectionHistoryStore();
|
|
1575
1598
|
var targetVisibilityHistory = new TargetVisibilityHistoryStore();
|
|
1576
1599
|
var recentEvents = [];
|
|
@@ -1637,7 +1660,7 @@ async function attachTabFromControl(tabId, options = {}) {
|
|
|
1637
1660
|
}
|
|
1638
1661
|
return { ok: true, tab, watcherId: session.getWatcherInfo()?.watcherId };
|
|
1639
1662
|
} catch (error) {
|
|
1640
|
-
return { ok: false, error:
|
|
1663
|
+
return { ok: false, error: formatError(error) };
|
|
1641
1664
|
}
|
|
1642
1665
|
}
|
|
1643
1666
|
async function detachTabFromControl(tabId) {
|
|
@@ -1651,16 +1674,19 @@ async function detachTabFromControl(tabId) {
|
|
|
1651
1674
|
}
|
|
1652
1675
|
return { ok: true, tab };
|
|
1653
1676
|
} catch (error) {
|
|
1654
|
-
return { ok: false, error:
|
|
1677
|
+
return { ok: false, error: formatError(error) };
|
|
1655
1678
|
}
|
|
1656
1679
|
}
|
|
1657
1680
|
async function buildPopupResponse(message) {
|
|
1681
|
+
return await dispatchPopupAction(message);
|
|
1682
|
+
}
|
|
1683
|
+
async function dispatchPopupAction(message) {
|
|
1658
1684
|
try {
|
|
1659
1685
|
switch (message.action) {
|
|
1660
1686
|
case "getTargets":
|
|
1661
1687
|
return { success: true, tabs: await getTabsWithTargets() };
|
|
1662
1688
|
case "attach": {
|
|
1663
|
-
const tabId =
|
|
1689
|
+
const { tabId } = message;
|
|
1664
1690
|
await attachBridgeSession(tabId);
|
|
1665
1691
|
setSelectedFrame(tabId, null);
|
|
1666
1692
|
await prepareRememberedTargetSelection(tabId);
|
|
@@ -1668,24 +1694,23 @@ async function buildPopupResponse(message) {
|
|
|
1668
1694
|
return { success: true };
|
|
1669
1695
|
}
|
|
1670
1696
|
case "detach": {
|
|
1671
|
-
const tabId =
|
|
1697
|
+
const { tabId } = message;
|
|
1672
1698
|
await detachTab(tabId);
|
|
1673
1699
|
recordEvent("info", "popup", `Detached tab ${tabId}`);
|
|
1674
1700
|
return { success: true };
|
|
1675
1701
|
}
|
|
1676
1702
|
case "focusTab": {
|
|
1677
|
-
const tabId =
|
|
1703
|
+
const { tabId } = message;
|
|
1678
1704
|
await focusTab(tabId);
|
|
1679
1705
|
recordEvent("info", "popup", `Focused tab ${tabId}`);
|
|
1680
1706
|
return { success: true };
|
|
1681
1707
|
}
|
|
1682
1708
|
case "selectTarget": {
|
|
1683
|
-
const tabId =
|
|
1709
|
+
const { tabId, frameId } = message;
|
|
1684
1710
|
const session = bridgeSessions.get(tabId);
|
|
1685
1711
|
if (!session) {
|
|
1686
1712
|
return { success: false, error: `No watcher bridge for tab ${tabId}` };
|
|
1687
1713
|
}
|
|
1688
|
-
const frameId = message.frameId ?? null;
|
|
1689
1714
|
const target = getPopupTarget(debuggerManager, tabId, frameId);
|
|
1690
1715
|
if (!target) {
|
|
1691
1716
|
return { success: false, error: `Unknown target for tab ${tabId}` };
|
|
@@ -1698,15 +1723,15 @@ async function buildPopupResponse(message) {
|
|
|
1698
1723
|
return { success: true };
|
|
1699
1724
|
}
|
|
1700
1725
|
case "hideTarget": {
|
|
1701
|
-
const tabId =
|
|
1702
|
-
const target = getRequiredIframeTarget(debuggerManager, tabId,
|
|
1726
|
+
const { tabId, frameId } = message;
|
|
1727
|
+
const target = getRequiredIframeTarget(debuggerManager, tabId, frameId);
|
|
1703
1728
|
await hideTarget(tabId, target);
|
|
1704
1729
|
recordEvent("info", "popup", `Hid iframe ${target.frameId} on tab ${tabId}`);
|
|
1705
1730
|
return { success: true };
|
|
1706
1731
|
}
|
|
1707
1732
|
case "showTarget": {
|
|
1708
|
-
const tabId =
|
|
1709
|
-
const target = getRequiredIframeTarget(debuggerManager, tabId,
|
|
1733
|
+
const { tabId, frameId } = message;
|
|
1734
|
+
const target = getRequiredIframeTarget(debuggerManager, tabId, frameId);
|
|
1710
1735
|
await showTarget(tabId, target);
|
|
1711
1736
|
recordEvent("info", "popup", `Restored iframe ${target.frameId} on tab ${tabId}`);
|
|
1712
1737
|
return { success: true };
|
|
@@ -1716,8 +1741,6 @@ async function buildPopupResponse(message) {
|
|
|
1716
1741
|
success: true,
|
|
1717
1742
|
status: buildPopupStatusPayload()
|
|
1718
1743
|
};
|
|
1719
|
-
default:
|
|
1720
|
-
return { success: false, error: `Unknown action: ${message.action}` };
|
|
1721
1744
|
}
|
|
1722
1745
|
} catch (err) {
|
|
1723
1746
|
recordEvent("error", "popup", err instanceof Error ? err.message : "Unknown popup error");
|
|
@@ -1727,12 +1750,6 @@ async function buildPopupResponse(message) {
|
|
|
1727
1750
|
};
|
|
1728
1751
|
}
|
|
1729
1752
|
}
|
|
1730
|
-
function requireTabId(message) {
|
|
1731
|
-
if (message.tabId !== void 0) {
|
|
1732
|
-
return message.tabId;
|
|
1733
|
-
}
|
|
1734
|
-
throw new Error("No tabId provided");
|
|
1735
|
-
}
|
|
1736
1753
|
async function attachBridgeSession(tabId, options = {}) {
|
|
1737
1754
|
const existing = bridgeSessions.get(tabId);
|
|
1738
1755
|
if (existing) {
|
|
@@ -1759,7 +1776,7 @@ async function attachBridgeSession(tabId, options = {}) {
|
|
|
1759
1776
|
},
|
|
1760
1777
|
options
|
|
1761
1778
|
);
|
|
1762
|
-
|
|
1779
|
+
attachments.set(tabId, { session });
|
|
1763
1780
|
await connectBridgeSession(tabId, session);
|
|
1764
1781
|
return session;
|
|
1765
1782
|
}
|
|
@@ -1786,16 +1803,11 @@ async function connectBridgeSession(tabId, session) {
|
|
|
1786
1803
|
}
|
|
1787
1804
|
}
|
|
1788
1805
|
function clearTabState(tabId) {
|
|
1789
|
-
selectedFrameByTabId.delete(tabId);
|
|
1790
|
-
clearPendingRememberedTarget(tabId);
|
|
1791
1806
|
destroyBridgeSession(tabId);
|
|
1792
1807
|
}
|
|
1793
1808
|
function pruneStaleBridgeSessions() {
|
|
1794
|
-
for (const [tabId,
|
|
1795
|
-
if (debuggerManager.isAttached(tabId)) {
|
|
1796
|
-
continue;
|
|
1797
|
-
}
|
|
1798
|
-
if (!session.getTargetInfo()) {
|
|
1809
|
+
for (const [tabId, attachment] of attachments.entries()) {
|
|
1810
|
+
if (debuggerManager.isAttached(tabId) || !attachment.session.getTargetInfo()) {
|
|
1799
1811
|
continue;
|
|
1800
1812
|
}
|
|
1801
1813
|
clearTabState(tabId);
|
|
@@ -1803,12 +1815,12 @@ function pruneStaleBridgeSessions() {
|
|
|
1803
1815
|
}
|
|
1804
1816
|
}
|
|
1805
1817
|
function destroyBridgeSession(tabId) {
|
|
1806
|
-
const
|
|
1807
|
-
if (!
|
|
1818
|
+
const attachment = attachments.get(tabId);
|
|
1819
|
+
if (!attachment) {
|
|
1808
1820
|
return;
|
|
1809
1821
|
}
|
|
1810
|
-
|
|
1811
|
-
session.dispose();
|
|
1822
|
+
attachments.delete(tabId);
|
|
1823
|
+
attachment.session.dispose();
|
|
1812
1824
|
}
|
|
1813
1825
|
function buildPopupStatusPayload() {
|
|
1814
1826
|
return {
|
|
@@ -1818,8 +1830,7 @@ function buildPopupStatusPayload() {
|
|
|
1818
1830
|
url: target.url,
|
|
1819
1831
|
title: target.title
|
|
1820
1832
|
})),
|
|
1821
|
-
watchers: getWatcherStatuses()
|
|
1822
|
-
recentEvents
|
|
1833
|
+
watchers: getWatcherStatuses()
|
|
1823
1834
|
};
|
|
1824
1835
|
}
|
|
1825
1836
|
function buildControlDiagnostics() {
|
|
@@ -1907,10 +1918,7 @@ function syncSelectedFrameFromWatcher(targetId) {
|
|
|
1907
1918
|
setSelectedFrame(target.tabId, target.frameId);
|
|
1908
1919
|
}
|
|
1909
1920
|
function getSelectedFrameId(tabId) {
|
|
1910
|
-
|
|
1911
|
-
return void 0;
|
|
1912
|
-
}
|
|
1913
|
-
return selectedFrameByTabId.get(tabId) ?? null;
|
|
1921
|
+
return attachments.get(tabId)?.selectedFrameId;
|
|
1914
1922
|
}
|
|
1915
1923
|
async function rememberTargetSelection(tabId, target) {
|
|
1916
1924
|
const pageUrl = getPageUrlForTab(debuggerManager, tabId);
|
|
@@ -1965,9 +1973,9 @@ async function prepareRememberedTargetSelection(tabId) {
|
|
|
1965
1973
|
await replayRememberedTargetSelection(tabId);
|
|
1966
1974
|
}
|
|
1967
1975
|
async function replayRememberedTargetSelection(tabId) {
|
|
1968
|
-
const
|
|
1969
|
-
const
|
|
1970
|
-
if (!
|
|
1976
|
+
const attachment = attachments.get(tabId);
|
|
1977
|
+
const remembered = attachment?.pendingRememberedTarget;
|
|
1978
|
+
if (!attachment || !remembered) {
|
|
1971
1979
|
return;
|
|
1972
1980
|
}
|
|
1973
1981
|
const target = matchRememberedIframeTarget(
|
|
@@ -1978,7 +1986,7 @@ async function replayRememberedTargetSelection(tabId) {
|
|
|
1978
1986
|
return;
|
|
1979
1987
|
}
|
|
1980
1988
|
try {
|
|
1981
|
-
session.selectTarget(target.frameId);
|
|
1989
|
+
attachment.session.selectTarget(target.frameId);
|
|
1982
1990
|
setSelectedFrame(tabId, target.frameId);
|
|
1983
1991
|
clearPendingRememberedTarget(tabId);
|
|
1984
1992
|
recordEvent("info", "bridge", `Restored iframe ${target.frameId} on tab ${tabId}`);
|
|
@@ -1987,16 +1995,25 @@ async function replayRememberedTargetSelection(tabId) {
|
|
|
1987
1995
|
}
|
|
1988
1996
|
}
|
|
1989
1997
|
function shouldReplayRememberedTarget(tabId, method) {
|
|
1990
|
-
return
|
|
1998
|
+
return attachments.get(tabId)?.pendingRememberedTarget != null && REMEMBERED_TARGET_RETRY_EVENTS.has(method);
|
|
1991
1999
|
}
|
|
1992
2000
|
function setSelectedFrame(tabId, frameId) {
|
|
1993
|
-
|
|
2001
|
+
const attachment = attachments.get(tabId);
|
|
2002
|
+
if (attachment) {
|
|
2003
|
+
attachment.selectedFrameId = frameId;
|
|
2004
|
+
}
|
|
1994
2005
|
}
|
|
1995
2006
|
function setPendingRememberedTarget(tabId, remembered) {
|
|
1996
|
-
|
|
2007
|
+
const attachment = attachments.get(tabId);
|
|
2008
|
+
if (attachment) {
|
|
2009
|
+
attachment.pendingRememberedTarget = remembered;
|
|
2010
|
+
}
|
|
1997
2011
|
}
|
|
1998
2012
|
function clearPendingRememberedTarget(tabId) {
|
|
1999
|
-
|
|
2013
|
+
const attachment = attachments.get(tabId);
|
|
2014
|
+
if (attachment) {
|
|
2015
|
+
delete attachment.pendingRememberedTarget;
|
|
2016
|
+
}
|
|
2000
2017
|
}
|
|
2001
2018
|
console.log("[ServiceWorker] Argus CDP Bridge extension loaded");
|
|
2002
2019
|
void syncActionBadge(debuggerManager);
|