@vforsh/argus-watcher 0.1.6 → 0.1.8

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.
Files changed (55) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/cdp/text-filter.js.map +1 -1
  3. package/dist/http/routes/domSelectorRoute.d.ts +16 -0
  4. package/dist/http/routes/domSelectorRoute.d.ts.map +1 -0
  5. package/dist/http/routes/domSelectorRoute.js +31 -0
  6. package/dist/http/routes/domSelectorRoute.js.map +1 -0
  7. package/dist/http/routes/postDomClick.d.ts.map +1 -1
  8. package/dist/http/routes/postDomClick.js +2 -7
  9. package/dist/http/routes/postDomClick.js.map +1 -1
  10. package/dist/http/routes/postDomFocus.d.ts.map +1 -1
  11. package/dist/http/routes/postDomFocus.js +6 -17
  12. package/dist/http/routes/postDomFocus.js.map +1 -1
  13. package/dist/http/routes/postDomHover.d.ts.map +1 -1
  14. package/dist/http/routes/postDomHover.js +6 -17
  15. package/dist/http/routes/postDomHover.js.map +1 -1
  16. package/dist/http/routes/postDomInfo.d.ts.map +1 -1
  17. package/dist/http/routes/postDomInfo.js +6 -18
  18. package/dist/http/routes/postDomInfo.js.map +1 -1
  19. package/dist/http/routes/postDomRemove.d.ts.map +1 -1
  20. package/dist/http/routes/postDomRemove.js +6 -17
  21. package/dist/http/routes/postDomRemove.js.map +1 -1
  22. package/dist/http/routes/postDomTree.d.ts.map +1 -1
  23. package/dist/http/routes/postDomTree.js +6 -18
  24. package/dist/http/routes/postDomTree.js.map +1 -1
  25. package/dist/http/routes/postReload.d.ts.map +1 -1
  26. package/dist/http/routes/postReload.js +2 -1
  27. package/dist/http/routes/postReload.js.map +1 -1
  28. package/dist/http/server.d.ts +2 -0
  29. package/dist/http/server.d.ts.map +1 -1
  30. package/dist/http/server.js.map +1 -1
  31. package/dist/index.d.ts +1 -1
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +3 -395
  34. package/dist/index.js.map +1 -1
  35. package/dist/sources/extension-delegating-session.d.ts +21 -0
  36. package/dist/sources/extension-delegating-session.d.ts.map +1 -0
  37. package/dist/sources/extension-delegating-session.js +62 -0
  38. package/dist/sources/extension-delegating-session.js.map +1 -0
  39. package/dist/sources/extension-frame-state.d.ts +28 -1
  40. package/dist/sources/extension-frame-state.d.ts.map +1 -1
  41. package/dist/sources/extension-frame-state.js +54 -2
  42. package/dist/sources/extension-frame-state.js.map +1 -1
  43. package/dist/sources/extension-session-events.d.ts +21 -0
  44. package/dist/sources/extension-session-events.d.ts.map +1 -0
  45. package/dist/sources/extension-session-events.js +103 -0
  46. package/dist/sources/extension-session-events.js.map +1 -0
  47. package/dist/sources/extension-source.d.ts +0 -4
  48. package/dist/sources/extension-source.d.ts.map +1 -1
  49. package/dist/sources/extension-source.js +74 -190
  50. package/dist/sources/extension-source.js.map +1 -1
  51. package/dist/startWatcherRuntime.d.ts +6 -0
  52. package/dist/startWatcherRuntime.d.ts.map +1 -0
  53. package/dist/startWatcherRuntime.js +414 -0
  54. package/dist/startWatcherRuntime.js.map +1 -0
  55. package/package.json +1 -1
@@ -1,6 +1,8 @@
1
1
  export const createEmptyFrameState = () => ({
2
2
  topFrameId: null,
3
3
  requestedFrameId: null,
4
+ requestedFrameHint: null,
5
+ requestedFrameDetached: false,
4
6
  activeFrameId: null,
5
7
  activeAttachedAt: null,
6
8
  frames: new Map(),
@@ -103,15 +105,65 @@ export const parseExecutionContext = (params) => {
103
105
  isDefault: record.context.auxData?.isDefault === true,
104
106
  };
105
107
  };
108
+ export const createRequestedFrameHint = (frame) => {
109
+ if (!frame) {
110
+ return null;
111
+ }
112
+ return {
113
+ url: frame.url || null,
114
+ title: frame.title?.trim() || null,
115
+ };
116
+ };
106
117
  /**
107
118
  * Selection is about the user's intended target, not whether every frame-scoped command is ready.
108
119
  * Once the watcher knows the frame exists we can switch the active target; commands that require
109
120
  * an execution context still guard that separately at execution time.
110
121
  */
111
- export const resolveRequestedFrameId = (state, requestedFrameId) => {
122
+ export const resolveRequestedFrameId = (state, requestedFrameId, requestedFrameHint) => {
112
123
  if (!requestedFrameId) {
113
124
  return null;
114
125
  }
115
- return state.frames.has(requestedFrameId) ? requestedFrameId : null;
126
+ if (state.frames.has(requestedFrameId)) {
127
+ return requestedFrameId;
128
+ }
129
+ if (!requestedFrameHint) {
130
+ return null;
131
+ }
132
+ const urlMatch = requestedFrameHint.url == null ? null : findSingleMatchingFrameId(state, (frame) => frame.url === requestedFrameHint.url);
133
+ if (urlMatch) {
134
+ return urlMatch;
135
+ }
136
+ if (requestedFrameHint.url != null || !requestedFrameHint.title) {
137
+ return null;
138
+ }
139
+ return findSingleMatchingFrameId(state, (frame) => frame.title?.trim() === requestedFrameHint.title);
140
+ };
141
+ /**
142
+ * Pending iframe selections have two valid states:
143
+ * - `pending`: the iframe has never become active in this attachment yet, so keep waiting silently.
144
+ * - `page`: the iframe was active and then disappeared, so report the page while we wait for a safe rematch.
145
+ */
146
+ export const resolveRequestedTarget = (state) => {
147
+ if (state.requestedFrameId == null) {
148
+ return { kind: 'page' };
149
+ }
150
+ const nextFrameId = resolveRequestedFrameId(state, state.requestedFrameId, state.requestedFrameHint);
151
+ if (nextFrameId) {
152
+ return { kind: 'frame', frameId: nextFrameId };
153
+ }
154
+ return state.requestedFrameDetached ? { kind: 'page' } : { kind: 'pending' };
155
+ };
156
+ const findSingleMatchingFrameId = (state, predicate) => {
157
+ let matchId = null;
158
+ for (const frame of state.frames.values()) {
159
+ if (!predicate(frame)) {
160
+ continue;
161
+ }
162
+ if (matchId) {
163
+ return null;
164
+ }
165
+ matchId = frame.frameId;
166
+ }
167
+ return matchId;
116
168
  };
117
169
  //# sourceMappingURL=extension-frame-state.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"extension-frame-state.js","sourceRoot":"","sources":["../../src/sources/extension-frame-state.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"extension-frame-state.js","sourceRoot":"","sources":["../../src/sources/extension-frame-state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { ExtensionSession } from '../native-messaging/session-manager.js';
2
+ import type { CdpSourceEvents } from './types.js';
3
+ import { type ExtensionFrameState } from './extension-frame-state.js';
4
+ type RegisterExtensionSessionEventsOptions = {
5
+ session: ExtensionSession;
6
+ events: CdpSourceEvents;
7
+ ignoreMatcher?: ((url: string) => boolean) | null;
8
+ stripUrlPrefixes?: string[];
9
+ getOrCreateFrameState: (tabId: number) => ExtensionFrameState;
10
+ reconcileTargetSelection: (session: ExtensionSession) => boolean;
11
+ removeFrame: (tabId: number, frameId: string) => void;
12
+ refreshFrameTitle: (session: ExtensionSession, frameId: string, contextId?: number) => Promise<void>;
13
+ emitTargetChanged: (session: ExtensionSession) => void;
14
+ setCurrentSession: (session: ExtensionSession) => void;
15
+ };
16
+ /**
17
+ * Subscribe to extension-backed CDP events and funnel them back through the shared frame-state helpers.
18
+ */
19
+ export declare const registerExtensionSessionEventHandlers: ({ session, events, ignoreMatcher, stripUrlPrefixes, getOrCreateFrameState, reconcileTargetSelection, removeFrame, refreshFrameTitle, emitTargetChanged, setCurrentSession, }: RegisterExtensionSessionEventsOptions) => void;
20
+ export {};
21
+ //# sourceMappingURL=extension-session-events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension-session-events.d.ts","sourceRoot":"","sources":["../../src/sources/extension-session-events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAA;AAC9E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,EAAqC,KAAK,mBAAmB,EAAE,MAAM,4BAA4B,CAAA;AAGxG,KAAK,qCAAqC,GAAG;IAC5C,OAAO,EAAE,gBAAgB,CAAA;IACzB,MAAM,EAAE,eAAe,CAAA;IACvB,aAAa,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,IAAI,CAAA;IACjD,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC3B,qBAAqB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,mBAAmB,CAAA;IAC7D,wBAAwB,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,OAAO,CAAA;IAChE,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;IACrD,iBAAiB,EAAE,CAAC,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACpG,iBAAiB,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,CAAA;IACtD,iBAAiB,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,CAAA;CACtD,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,qCAAqC,GAAI,8KAWnD,qCAAqC,KAAG,IA2G1C,CAAA"}
@@ -0,0 +1,103 @@
1
+ import { parseExecutionContext, parseFrame } from './extension-frame-state.js';
2
+ import { toConsoleEvent, toExceptionEvent } from './extension-log-events.js';
3
+ /**
4
+ * Subscribe to extension-backed CDP events and funnel them back through the shared frame-state helpers.
5
+ */
6
+ export const registerExtensionSessionEventHandlers = ({ session, events, ignoreMatcher, stripUrlPrefixes, getOrCreateFrameState, reconcileTargetSelection, removeFrame, refreshFrameTitle, emitTargetChanged, setCurrentSession, }) => {
7
+ session.handle.onEvent('Runtime.executionContextCreated', (params, meta) => {
8
+ const context = parseExecutionContext(params);
9
+ if (!context?.isDefault || !context.frameId) {
10
+ return;
11
+ }
12
+ const state = getOrCreateFrameState(session.tabId);
13
+ state.executionContexts.set(context.frameId, context.id);
14
+ const frame = state.frames.get(context.frameId);
15
+ if (frame) {
16
+ frame.sessionId = meta.sessionId ?? null;
17
+ }
18
+ void refreshFrameTitle(session, context.frameId, context.id);
19
+ reconcileTargetSelection(session);
20
+ });
21
+ session.handle.onEvent('Runtime.executionContextsCleared', () => {
22
+ const state = getOrCreateFrameState(session.tabId);
23
+ state.executionContexts.clear();
24
+ state.pendingTitleLoads.clear();
25
+ });
26
+ session.handle.onEvent('Runtime.executionContextDestroyed', (params) => {
27
+ const record = params;
28
+ if (record.executionContextId == null) {
29
+ return;
30
+ }
31
+ const state = getOrCreateFrameState(session.tabId);
32
+ for (const [frameId, contextId] of state.executionContexts.entries()) {
33
+ if (contextId === record.executionContextId) {
34
+ state.executionContexts.delete(frameId);
35
+ state.pendingTitleLoads.delete(frameId);
36
+ }
37
+ }
38
+ });
39
+ session.handle.onEvent('Page.frameNavigated', (params, meta) => {
40
+ const frame = parseFrame(params);
41
+ if (!frame) {
42
+ return;
43
+ }
44
+ const state = getOrCreateFrameState(session.tabId);
45
+ state.frames.set(frame.frameId, frame);
46
+ frame.sessionId = meta.sessionId ?? null;
47
+ if (!frame.parentFrameId) {
48
+ if (!meta.sessionId) {
49
+ state.topFrameId = frame.frameId;
50
+ session.url = frame.url;
51
+ }
52
+ else if (state.topFrameId == null) {
53
+ state.topFrameId = frame.parentFrameId;
54
+ }
55
+ }
56
+ else if (state.executionContexts.has(frame.frameId)) {
57
+ void refreshFrameTitle(session, frame.frameId);
58
+ }
59
+ setCurrentSession(session);
60
+ if (!frame.parentFrameId && !meta.sessionId) {
61
+ events.onPageNavigation?.({ url: frame.url, title: session.title ?? null });
62
+ }
63
+ if (reconcileTargetSelection(session)) {
64
+ return;
65
+ }
66
+ if ((!frame.parentFrameId && state.activeFrameId == null) || state.activeFrameId === frame.frameId) {
67
+ emitTargetChanged(session);
68
+ }
69
+ });
70
+ session.handle.onEvent('Page.frameAttached', (params, meta) => {
71
+ const record = params;
72
+ if (!record.frameId) {
73
+ return;
74
+ }
75
+ const state = getOrCreateFrameState(session.tabId);
76
+ state.frames.set(record.frameId, {
77
+ frameId: record.frameId,
78
+ parentFrameId: record.parentFrameId ?? state.topFrameId ?? null,
79
+ url: '',
80
+ title: null,
81
+ sessionId: meta.sessionId ?? null,
82
+ });
83
+ reconcileTargetSelection(session);
84
+ });
85
+ session.handle.onEvent('Page.frameDetached', (params) => {
86
+ const record = params;
87
+ if (!record.frameId) {
88
+ return;
89
+ }
90
+ removeFrame(session.tabId, record.frameId);
91
+ reconcileTargetSelection(session);
92
+ });
93
+ session.handle.onEvent('Page.domContentEventFired', () => {
94
+ events.onPageLoad?.();
95
+ });
96
+ session.handle.onEvent('Runtime.consoleAPICalled', (params) => {
97
+ events.onLog(toConsoleEvent(params, session, { ignoreMatcher, stripUrlPrefixes }));
98
+ });
99
+ session.handle.onEvent('Runtime.exceptionThrown', (params) => {
100
+ events.onLog(toExceptionEvent(params, session, { ignoreMatcher, stripUrlPrefixes }));
101
+ });
102
+ };
103
+ //# sourceMappingURL=extension-session-events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension-session-events.js","sourceRoot":"","sources":["../../src/sources/extension-session-events.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,3 @@
1
- /**
2
- * Extension source for CDP access via Chrome extension Native Messaging.
3
- * Wraps SessionManager and provides a unified source interface.
4
- */
5
1
  import type { CdpSourceHandle, CdpSourceBaseOptions } from './types.js';
6
2
  export type ExtensionSourceOptions = CdpSourceBaseOptions;
7
3
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"extension-source.d.ts","sourceRoot":"","sources":["../../src/sources/extension-source.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAmB,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAmBxF,MAAM,MAAM,sBAAsB,GAAG,oBAAoB,CAAA;AAEzD;;;GAGG;AACH,eAAO,MAAM,qBAAqB,GAAI,SAAS,sBAAsB,KAAG,eAskBvE,CAAA"}
1
+ {"version":3,"file":"extension-source.d.ts","sourceRoot":"","sources":["../../src/sources/extension-source.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAmB,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAmBxF,MAAM,MAAM,sBAAsB,GAAG,oBAAoB,CAAA;AAEzD;;;GAGG;AACH,eAAO,MAAM,qBAAqB,GAAI,SAAS,sBAAsB,KAAG,eAycvE,CAAA"}
@@ -1,11 +1,8 @@
1
- /**
2
- * Extension source for CDP access via Chrome extension Native Messaging.
3
- * Wraps SessionManager and provides a unified source interface.
4
- */
5
1
  import { createNativeMessaging } from '../native-messaging/messaging.js';
6
2
  import { SessionManager } from '../native-messaging/session-manager.js';
7
- import { buildFrameTargets, buildPageTarget, collectFrameTree, createEmptyFrameState, createNotAttachedError, frameToTarget, formatPageTargetId, parseExecutionContext, parseExtensionTargetId, parseFrame, resolveRequestedFrameId, } from './extension-frame-state.js';
8
- import { toConsoleEvent, toExceptionEvent } from './extension-log-events.js';
3
+ import { buildFrameTargets, buildPageTarget, collectFrameTree, createRequestedFrameHint, createEmptyFrameState, createNotAttachedError, frameToTarget, formatPageTargetId, parseExtensionTargetId, resolveRequestedTarget, } from './extension-frame-state.js';
4
+ import { createDelegatingSession } from './extension-delegating-session.js';
5
+ import { registerExtensionSessionEventHandlers } from './extension-session-events.js';
9
6
  /**
10
7
  * Create an extension source that connects to Chrome via Native Messaging.
11
8
  * Returns a handle that can be used to control the source and access CDP session.
@@ -47,20 +44,21 @@ export const createExtensionSource = (options) => {
47
44
  emitStatus(null, reason);
48
45
  events.onDetach?.(reason);
49
46
  },
50
- onTabsUpdated: () => {
51
- // Tabs list updated - no action needed
52
- },
47
+ onTabsUpdated: () => { },
53
48
  onTargetSelected: (tabId, frameId) => {
54
49
  const session = currentSession;
55
50
  if (!session || session.tabId !== tabId) {
56
- getOrCreateFrameState(tabId).requestedFrameId = frameId;
51
+ const state = getOrCreateFrameState(tabId);
52
+ setRequestedTargetSelection(state, frameId);
57
53
  return;
58
54
  }
59
55
  requestTargetSelection(session, frameId);
60
56
  },
61
57
  });
62
58
  // Proxy session follows the currently selected page/frame target inside the attached tab.
63
- const proxySession = createDelegatingSession({
59
+ const { session: proxySession, controller: proxyController } = createDelegatingSession({
60
+ getCurrentSession: () => currentSession,
61
+ requireCurrentSession: getCurrentExtensionSession,
64
62
  getTargetContext: () => getCurrentTargetContext() ?? { kind: 'page' },
65
63
  mapParams: (method, params) => {
66
64
  const targetContext = getCurrentTargetContext();
@@ -76,11 +74,14 @@ export const createExtensionSource = (options) => {
76
74
  };
77
75
  },
78
76
  });
79
- // Page session always stays at the top-level tab context so page-level features
80
- // (indicator, inject-on-attach, similar lifecycle hooks) don't accidentally run inside an iframe.
81
- const pageSession = createDelegatingSession({
77
+ delegatingSessions.add(proxyController);
78
+ // Page session stays pinned to the top-level tab for page-scoped features like the indicator and inject-on-attach.
79
+ const { session: pageSession, controller: pageController } = createDelegatingSession({
80
+ getCurrentSession: () => currentSession,
81
+ requireCurrentSession: getCurrentExtensionSession,
82
82
  getTargetContext: () => ({ kind: 'page' }),
83
83
  });
84
+ delegatingSessions.add(pageController);
84
85
  messaging.start();
85
86
  sendHostInfo();
86
87
  messaging.onDisconnect(() => {
@@ -115,7 +116,8 @@ export const createExtensionSource = (options) => {
115
116
  const target = parseExtensionTargetId(targetId);
116
117
  const session = currentSession;
117
118
  if (!session || session.tabId !== target.tabId) {
118
- getOrCreateFrameState(target.tabId).requestedFrameId = target.frameId;
119
+ const state = getOrCreateFrameState(target.tabId);
120
+ setRequestedTargetSelection(state, target.frameId);
119
121
  sessionManager.attachTab(target.tabId);
120
122
  return;
121
123
  }
@@ -157,10 +159,24 @@ export const createExtensionSource = (options) => {
157
159
  for (const controller of delegatingSessions) {
158
160
  controller.dispose();
159
161
  }
162
+ delegatingSessions.clear();
160
163
  }
161
164
  async function bootstrapAttachedSession(session) {
162
165
  try {
163
- registerSessionEventHandlers(session);
166
+ registerExtensionSessionEventHandlers({
167
+ session,
168
+ events,
169
+ ignoreMatcher,
170
+ stripUrlPrefixes,
171
+ getOrCreateFrameState,
172
+ reconcileTargetSelection,
173
+ removeFrame,
174
+ refreshFrameTitle,
175
+ emitTargetChanged,
176
+ setCurrentSession: (nextSession) => {
177
+ currentSession = nextSession;
178
+ },
179
+ });
164
180
  await enableBootstrapDomains(session);
165
181
  await refreshFrameTree(session);
166
182
  if (currentSession?.tabId !== session.tabId) {
@@ -188,103 +204,6 @@ export const createExtensionSource = (options) => {
188
204
  await session.handle.sendAndWait('Runtime.enable');
189
205
  await session.handle.sendAndWait('Page.enable');
190
206
  }
191
- function registerSessionEventHandlers(session) {
192
- session.handle.onEvent('Runtime.executionContextCreated', (params, meta) => {
193
- const context = parseExecutionContext(params);
194
- if (!context?.isDefault || !context.frameId) {
195
- return;
196
- }
197
- const state = getOrCreateFrameState(session.tabId);
198
- state.executionContexts.set(context.frameId, context.id);
199
- const frame = state.frames.get(context.frameId);
200
- if (frame) {
201
- frame.sessionId = meta.sessionId ?? null;
202
- }
203
- void refreshFrameTitle(session, context.frameId, context.id);
204
- reconcileTargetSelection(session);
205
- });
206
- session.handle.onEvent('Runtime.executionContextsCleared', () => {
207
- const state = getOrCreateFrameState(session.tabId);
208
- state.executionContexts.clear();
209
- state.pendingTitleLoads.clear();
210
- });
211
- session.handle.onEvent('Runtime.executionContextDestroyed', (params) => {
212
- const record = params;
213
- if (record.executionContextId == null) {
214
- return;
215
- }
216
- const state = getOrCreateFrameState(session.tabId);
217
- for (const [frameId, contextId] of state.executionContexts.entries()) {
218
- if (contextId === record.executionContextId) {
219
- state.executionContexts.delete(frameId);
220
- state.pendingTitleLoads.delete(frameId);
221
- }
222
- }
223
- });
224
- session.handle.onEvent('Page.frameNavigated', (params, meta) => {
225
- const frame = parseFrame(params);
226
- if (!frame) {
227
- return;
228
- }
229
- const state = getOrCreateFrameState(session.tabId);
230
- state.frames.set(frame.frameId, frame);
231
- frame.sessionId = meta.sessionId ?? null;
232
- if (!frame.parentFrameId) {
233
- if (!meta.sessionId) {
234
- state.topFrameId = frame.frameId;
235
- session.url = frame.url;
236
- }
237
- else if (state.topFrameId == null) {
238
- state.topFrameId = frame.parentFrameId;
239
- }
240
- }
241
- else if (state.executionContexts.has(frame.frameId)) {
242
- void refreshFrameTitle(session, frame.frameId);
243
- }
244
- currentSession = session;
245
- if (!frame.parentFrameId && !meta.sessionId) {
246
- events.onPageNavigation?.({ url: frame.url, title: session.title ?? null });
247
- }
248
- if (reconcileTargetSelection(session)) {
249
- return;
250
- }
251
- if ((!frame.parentFrameId && state.activeFrameId == null) || state.activeFrameId === frame.frameId) {
252
- emitTargetChanged(session);
253
- }
254
- });
255
- session.handle.onEvent('Page.frameAttached', (params, meta) => {
256
- const record = params;
257
- if (!record.frameId) {
258
- return;
259
- }
260
- const state = getOrCreateFrameState(session.tabId);
261
- state.frames.set(record.frameId, {
262
- frameId: record.frameId,
263
- parentFrameId: record.parentFrameId ?? state.topFrameId ?? null,
264
- url: '',
265
- title: null,
266
- sessionId: meta.sessionId ?? null,
267
- });
268
- reconcileTargetSelection(session);
269
- });
270
- session.handle.onEvent('Page.frameDetached', (params) => {
271
- const record = params;
272
- if (!record.frameId) {
273
- return;
274
- }
275
- removeFrame(session.tabId, record.frameId);
276
- reconcileTargetSelection(session);
277
- });
278
- session.handle.onEvent('Page.domContentEventFired', () => {
279
- events.onPageLoad?.();
280
- });
281
- session.handle.onEvent('Runtime.consoleAPICalled', (params) => {
282
- events.onLog(toConsoleEvent(params, session, { ignoreMatcher, stripUrlPrefixes }));
283
- });
284
- session.handle.onEvent('Runtime.exceptionThrown', (params) => {
285
- events.onLog(toExceptionEvent(params, session, { ignoreMatcher, stripUrlPrefixes }));
286
- });
287
- }
288
207
  function getCurrentTargetContext() {
289
208
  const session = currentSession;
290
209
  if (!session) {
@@ -373,9 +292,15 @@ export const createExtensionSource = (options) => {
373
292
  }
374
293
  function requestTargetSelection(session, frameId) {
375
294
  const state = getOrCreateFrameState(session.tabId);
376
- state.requestedFrameId = frameId;
295
+ setRequestedTargetSelection(state, frameId);
377
296
  reconcileTargetSelection(session);
378
297
  }
298
+ function setRequestedTargetSelection(state, frameId) {
299
+ const frame = frameId ? state.frames.get(frameId) : null;
300
+ state.requestedFrameId = frameId;
301
+ state.requestedFrameHint = createRequestedFrameHint(frame);
302
+ state.requestedFrameDetached = false;
303
+ }
379
304
  /**
380
305
  * Popup selection can arrive before the iframe's session is fully bootstrapped.
381
306
  * Keep the request pending until the frame is discovered instead of routing commands
@@ -383,25 +308,36 @@ export const createExtensionSource = (options) => {
383
308
  */
384
309
  function reconcileTargetSelection(session) {
385
310
  const state = getOrCreateFrameState(session.tabId);
386
- const nextActiveFrameId = resolveRequestedFrameId(state, state.requestedFrameId);
387
- if (state.requestedFrameId == null) {
388
- if (state.activeFrameId == null) {
389
- if (state.activeAttachedAt == null) {
390
- state.activeAttachedAt = Date.now();
391
- emitTargetChanged(session);
392
- return true;
393
- }
394
- return false;
395
- }
396
- state.activeFrameId = null;
397
- state.activeAttachedAt = Date.now();
398
- emitTargetChanged(session);
399
- return true;
311
+ const resolution = resolveRequestedTarget(state);
312
+ if (resolution.kind === 'page') {
313
+ state.requestedFrameDetached = false;
314
+ return activatePageTarget(session, state);
400
315
  }
401
- if (nextActiveFrameId == null || state.activeFrameId === nextActiveFrameId) {
316
+ if (resolution.kind === 'pending') {
402
317
  return false;
403
318
  }
404
- state.activeFrameId = nextActiveFrameId;
319
+ state.requestedFrameDetached = false;
320
+ if (state.activeFrameId === resolution.frameId) {
321
+ return false;
322
+ }
323
+ return activateFrameTarget(session, state, resolution.frameId);
324
+ }
325
+ function activatePageTarget(session, state) {
326
+ if (state.activeFrameId == null) {
327
+ if (state.activeAttachedAt == null) {
328
+ state.activeAttachedAt = Date.now();
329
+ emitTargetChanged(session);
330
+ return true;
331
+ }
332
+ return false;
333
+ }
334
+ state.activeFrameId = null;
335
+ state.activeAttachedAt = Date.now();
336
+ emitTargetChanged(session);
337
+ return true;
338
+ }
339
+ function activateFrameTarget(session, state, frameId) {
340
+ state.activeFrameId = frameId;
405
341
  state.activeAttachedAt = Date.now();
406
342
  emitTargetChanged(session);
407
343
  return true;
@@ -418,8 +354,14 @@ export const createExtensionSource = (options) => {
418
354
  for (const childId of childIds) {
419
355
  removeFrame(tabId, childId);
420
356
  }
421
- if (state.requestedFrameId === frameId) {
422
- state.requestedFrameId = null;
357
+ /**
358
+ * Keep the user's requested iframe selection across reload/navigation detaches.
359
+ * Frame ids are ephemeral, so the stored frame hint lets selection survive a fresh id after reload.
360
+ */
361
+ if (state.activeFrameId === frameId) {
362
+ state.requestedFrameDetached = state.requestedFrameId === frameId;
363
+ state.activeFrameId = null;
364
+ state.activeAttachedAt = null;
423
365
  }
424
366
  state.frames.delete(frameId);
425
367
  state.executionContexts.delete(frameId);
@@ -467,55 +409,6 @@ export const createExtensionSource = (options) => {
467
409
  state.pendingTitleLoads.delete(frameId);
468
410
  }
469
411
  }
470
- function createDelegatingSession(config) {
471
- const subscriptions = new Set();
472
- const rebindSubscriptions = () => {
473
- // Delegating sessions are created before a tab may be attached, so event listeners
474
- // must follow the active extension session instead of binding once and going stale.
475
- for (const subscription of subscriptions) {
476
- subscription.unbind();
477
- if (!currentSession) {
478
- continue;
479
- }
480
- subscription.off = currentSession.handle.onEvent(subscription.method, subscription.handler);
481
- }
482
- };
483
- const disposeSubscriptions = () => {
484
- for (const subscription of subscriptions) {
485
- subscription.unbind();
486
- }
487
- subscriptions.clear();
488
- };
489
- const controller = {
490
- rebind: rebindSubscriptions,
491
- dispose: () => {
492
- disposeSubscriptions();
493
- delegatingSessions.delete(controller);
494
- },
495
- };
496
- delegatingSessions.add(controller);
497
- controller.rebind();
498
- return {
499
- isAttached: () => currentSession?.handle.isAttached() ?? false,
500
- sendAndWait: async (method, params, options) => {
501
- const session = getCurrentExtensionSession();
502
- const targetContext = config.getTargetContext();
503
- const nextParams = config.mapParams ? config.mapParams(method, params) : params;
504
- const nextOptions = targetContext.kind === 'frame' && targetContext.sessionId ? { ...(options ?? {}), sessionId: targetContext.sessionId } : options;
505
- return session.handle.sendAndWait(method, nextParams, nextOptions);
506
- },
507
- onEvent: (method, handler) => {
508
- const subscription = createDelegatingEventSubscription(method, handler);
509
- subscriptions.add(subscription);
510
- controller.rebind();
511
- return () => {
512
- subscription.unbind();
513
- subscriptions.delete(subscription);
514
- };
515
- },
516
- getTargetContext: config.getTargetContext,
517
- };
518
- }
519
412
  };
520
413
  /**
521
414
  * Convert TabInfo to CdpSourceTarget.
@@ -528,13 +421,4 @@ const tabToTarget = (tab) => ({
528
421
  faviconUrl: tab.faviconUrl,
529
422
  attached: tab.attached,
530
423
  });
531
- const createDelegatingEventSubscription = (method, handler) => ({
532
- method,
533
- handler,
534
- off: null,
535
- unbind() {
536
- this.off?.();
537
- this.off = null;
538
- },
539
- });
540
424
  //# sourceMappingURL=extension-source.js.map