cdp-tunnel 2.7.10 → 2.8.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.
@@ -1,6 +1,19 @@
1
1
  var SpecialHandler = (function() {
2
2
  var _groupQueue = new Map();
3
3
 
4
+ function _getState(ctx) {
5
+ return ctx._state;
6
+ }
7
+
8
+ function _getWSManager(ctx) {
9
+ return ctx._wsManager;
10
+ }
11
+
12
+ function _getConnectionTag(ctx) {
13
+ var wm = ctx._wsManager;
14
+ return (wm && wm.config && wm.config.tag) || null;
15
+ }
16
+
4
17
  function muteTabIfNeeded(tabId) {
5
18
  Config.getAutoMute(function(enabled) {
6
19
  if (!enabled) return;
@@ -15,8 +28,9 @@ var SpecialHandler = (function() {
15
28
  }
16
29
 
17
30
  function targetSetAutoAttach(context) {
31
+ var state = _getState(context);
18
32
  var params = context.params;
19
- State.setAutoAttachConfig({
33
+ state.setAutoAttachConfig({
20
34
  autoAttach: !!(params && params.autoAttach),
21
35
  waitForDebuggerOnStart: !!(params && params.waitForDebuggerOnStart),
22
36
  flatten: !(params && params.flatten === false)
@@ -31,6 +45,7 @@ var SpecialHandler = (function() {
31
45
  }
32
46
 
33
47
  function targetAttachToTarget(context) {
48
+ var state = _getState(context);
34
49
  var params = context.params;
35
50
  var targetId = params && params.targetId;
36
51
  var clientId = context.clientId;
@@ -43,31 +58,32 @@ var SpecialHandler = (function() {
43
58
  throw new Error('Target not found');
44
59
  }
45
60
 
46
- var isAlreadyAttached = State.isTabAttached(tabId);
61
+ var isAlreadyAttached = state.isTabAttached(tabId);
47
62
 
48
63
  if (isAlreadyAttached) {
49
64
  var newSessionId = CDPUtils.generateSessionId();
50
- State.mapSession(newSessionId, tabId, targetId);
65
+ state.mapSession(newSessionId, tabId, targetId);
51
66
  muteTabIfNeeded(tabId);
52
67
  Logger.info('[CDP] Created additional session:', newSessionId, 'for tab:', tabId);
53
68
  return { sessionId: newSessionId };
54
69
  }
55
70
 
56
- return DebuggerManager.attach(tabId).then(function(attached) {
71
+ return DebuggerManager.attach(tabId, state).then(function(attached) {
57
72
  if (!attached) {
58
73
  throw new Error('Failed to attach');
59
74
  }
60
75
 
61
76
  var sessionId = CDPUtils.generateSessionId();
62
- State.mapSession(sessionId, tabId, targetId);
77
+ state.mapSession(sessionId, tabId, targetId);
63
78
 
64
79
  if (clientId) {
65
- State.setTabIdToClientId(tabId, clientId);
80
+ state.setTabIdToClientId(tabId, clientId);
66
81
  }
67
82
 
68
- if (State.isCDPCreatedTab(tabId)) {
69
- addTabToAutomationGroup(tabId, clientId);
70
- } else { State.addPreExistingTab(tabId);
83
+ if (state.isCDPCreatedTab(tabId)) {
84
+ addTabToAutomationGroup(tabId, clientId, null, context);
85
+ } else {
86
+ state.addPreExistingTab(tabId);
71
87
  Logger.info('[CDP] Target.attachToTarget: user tab not CDP-created, treating as pre-existing. tabId:', tabId);
72
88
  }
73
89
 
@@ -77,17 +93,18 @@ var SpecialHandler = (function() {
77
93
  }
78
94
 
79
95
  function targetDetachFromTarget(context) {
96
+ var state = _getState(context);
80
97
  var params = context.params;
81
98
  var sessionId = params && params.sessionId;
82
99
  if (!sessionId) {
83
100
  return Promise.resolve({});
84
101
  }
85
102
 
86
- var tabId = State.getTabIdBySession(sessionId);
87
- State.unmapSession(sessionId);
103
+ var tabId = state.getTabIdBySession(sessionId);
104
+ state.unmapSession(sessionId);
88
105
 
89
- if (tabId && !State.hasOtherSessionForTab(tabId)) {
90
- return DebuggerManager.detach(tabId).then(function() {
106
+ if (tabId && !state.hasOtherSessionForTab(tabId)) {
107
+ return DebuggerManager.detach(tabId, state).then(function() {
91
108
  return {};
92
109
  }).catch(function() {
93
110
  return {};
@@ -97,6 +114,8 @@ var SpecialHandler = (function() {
97
114
  }
98
115
 
99
116
  function targetCreateTarget(context) {
117
+ var state = _getState(context);
118
+ var wsManager = _getWSManager(context);
100
119
  var params = context.params;
101
120
  var url = (params && params.url) || 'about:blank';
102
121
  var browserContextId = (params && params.browserContextId) || 'default';
@@ -104,7 +123,6 @@ var SpecialHandler = (function() {
104
123
  var needsNavigate = url !== 'about:blank' && url !== '';
105
124
 
106
125
  return new Promise(function(resolve, reject) {
107
- // Step 1: 先创建 about:blank (不加载任何资源,tab bar 闪烁最小)
108
126
  chrome.tabs.create({ url: 'about:blank', active: false }, function(tab) {
109
127
  if (!tab || !tab.id) {
110
128
  reject(new Error('Failed to create tab'));
@@ -112,19 +130,16 @@ var SpecialHandler = (function() {
112
130
  }
113
131
 
114
132
  if (clientId) {
115
- State.setTabIdToClientId(tab.id, clientId);
133
+ state.setTabIdToClientId(tab.id, clientId);
116
134
  }
117
135
 
118
- State.addCDPCreatedTab(tab.id);
136
+ state.addCDPCreatedTab(tab.id);
119
137
 
120
- // Step 2: 立刻分组折叠 (用户在 tab bar 上看不到)
121
- groupTabSilently(tab.id, clientId).then(function() {
122
- // Step 3: 获取 targetId 并 attach debugger
138
+ groupTabSilently(tab.id, clientId, context).then(function() {
123
139
  return getTargetIdByTabId(tab.id).then(function(targetId) {
124
- return emitAutoAttachEvents(tab.id, targetId, browserContextId).then(function() {
125
- // Step 4: 折叠+attach 完成后,再导航到真实 URL
140
+ return emitAutoAttachEvents(tab.id, targetId, browserContextId, context).then(function() {
126
141
  if (needsNavigate) {
127
- State.addPendingCreatedTabUrl(url);
142
+ state.addPendingCreatedTabUrl(url);
128
143
  return navigateTabQuietly(tab.id, url).then(function() {
129
144
  resolve({ targetId: targetId });
130
145
  });
@@ -140,11 +155,11 @@ var SpecialHandler = (function() {
140
155
  });
141
156
  }
142
157
 
143
- function groupTabSilently(tabId, clientId) {
158
+ function groupTabSilently(tabId, clientId, context) {
144
159
  return new Promise(function(resolve) {
145
160
  addTabToAutomationGroup(tabId, clientId, function(success) {
146
161
  setTimeout(resolve, 50);
147
- });
162
+ }, context);
148
163
  });
149
164
  }
150
165
 
@@ -154,13 +169,12 @@ var SpecialHandler = (function() {
154
169
  if (chrome.runtime.lastError) {
155
170
  Logger.warn('[NavigateQuietly] Failed:', chrome.runtime.lastError.message);
156
171
  }
157
- // 不管成功失败都 resolve,让调用者继续
158
172
  resolve();
159
173
  });
160
174
  });
161
175
  }
162
176
 
163
- function addTabToAutomationGroup(tabId, clientId, callback) {
177
+ function addTabToAutomationGroup(tabId, clientId, callback, context) {
164
178
  var key = clientId || '__no_client__';
165
179
  var prev = _groupQueue.get(key) || Promise.resolve();
166
180
 
@@ -173,7 +187,7 @@ var SpecialHandler = (function() {
173
187
  _addTabToAutomationGroupInner(tabId, clientId, function(success) {
174
188
  clearTimeout(timeoutId);
175
189
  resolve(success);
176
- });
190
+ }, context);
177
191
  });
178
192
  }).catch(function(err) {
179
193
  Logger.error('[addTabToAutomationGroup] queue error:', err.message || err);
@@ -192,10 +206,15 @@ var SpecialHandler = (function() {
192
206
  }
193
207
  }
194
208
 
195
- function _addTabToAutomationGroupInner(tabId, clientId, callback) {
209
+ function _addTabToAutomationGroupInner(tabId, clientId, callback, context) {
210
+ var state = context ? _getState(context) : null;
211
+ var wsManager = context ? _getWSManager(context) : null;
212
+
196
213
  Logger.info('[TabGroup] Starting addTabToAutomationGroup for tabId:', tabId, 'clientId:', clientId);
197
214
 
198
- WebSocketManager.send({ type: 'tabgroup-debug', tabId: tabId, clientId: clientId, phase: 'start' });
215
+ if (wsManager) {
216
+ wsManager.send({ type: 'tabgroup-debug', tabId: tabId, clientId: clientId, phase: 'start' });
217
+ }
199
218
 
200
219
  setTimeout(function() {
201
220
  try {
@@ -207,7 +226,7 @@ var SpecialHandler = (function() {
207
226
 
208
227
  var groupClientId = clientId;
209
228
  if (!groupClientId) {
210
- var cdpClients = State.getCDPClients() || [];
229
+ var cdpClients = state ? state.getCDPClients() : [];
211
230
  if (cdpClients.length > 0 && cdpClients[0] && cdpClients[0].id) {
212
231
  groupClientId = cdpClients[0].id;
213
232
  Logger.warn('[TabGroup] No clientId for tab:', tabId, 'fallback to first client:', groupClientId);
@@ -217,49 +236,53 @@ var SpecialHandler = (function() {
217
236
  return;
218
237
  }
219
238
  }
220
- var baseName = CDPUtils.getGroupBaseName(groupClientId);
239
+ var baseName = CDPUtils.getGroupBaseName(groupClientId, _getConnectionTag(context));
221
240
 
222
241
  Logger.info('[TabGroup] Grouping tab immediately for:', baseName);
223
- doGroup(tabId, groupClientId, baseName, 0, callback);
242
+ doGroup(tabId, groupClientId, baseName, 0, callback, context);
224
243
  }
225
244
 
226
- function doGroup(tabId, clientId, baseName, retries, callback) {
245
+ function doGroup(tabId, clientId, baseName, retries, callback, context) {
246
+ var state = context ? _getState(context) : null;
247
+ var wsManager = context ? _getWSManager(context) : null;
227
248
  retries = retries || 0;
228
249
  Logger.info('[TabGroup] doGroup: tabId=' + tabId + ' clientId=' + (clientId || 'none') + ' baseName=' + baseName + ' retry=' + retries);
229
250
  if (!chrome.tabGroups) {
230
251
  Logger.warn('[TabGroup] chrome.tabGroups API not available (headless mode?), skipping grouping for tab:', tabId);
231
- EventBuilder.send('CDPTunnel.debug', { source: 'doGroup', phase: 'skip', reason: 'tabGroups-unavailable', tabId: tabId });
252
+ EventBuilder.send('CDPTunnel.debug', { source: 'doGroup', phase: 'skip', reason: 'tabGroups-unavailable', tabId: tabId }, null, wsManager);
232
253
  if (callback) callback(false);
233
254
  return;
234
255
  }
235
- var cachedGroupId = State.getGroupIdForClient(clientId);
256
+ var cachedGroupId = state ? state.getGroupIdForClient(clientId) : null;
236
257
  if (cachedGroupId) {
237
258
  Logger.info('[TabGroup] Using cached groupId:', cachedGroupId, 'for client:', clientId);
238
259
  chrome.tabs.group({ tabIds: tabId, groupId: cachedGroupId }, function(result) {
239
260
  if (!chrome.runtime.lastError) {
240
- updateTabGroupName(clientId);
261
+ updateTabGroupName(clientId, state, wsManager);
241
262
  Logger.info('[TabGroup] Tab', tabId, 'added to cached group:', cachedGroupId);
242
263
  if (callback) callback(true);
243
264
  return;
244
265
  }
245
266
  Logger.warn('[TabGroup] Cached groupId', cachedGroupId, 'failed:', chrome.runtime.lastError.message, '— falling back to query');
246
- doGroupQuery(tabId, clientId, baseName, retries, callback);
267
+ doGroupQuery(tabId, clientId, baseName, retries, callback, context);
247
268
  });
248
269
  return;
249
270
  }
250
- doGroupQuery(tabId, clientId, baseName, retries, callback);
271
+ doGroupQuery(tabId, clientId, baseName, retries, callback, context);
251
272
  }
252
273
 
253
- function doGroupQuery(tabId, clientId, baseName, retries, callback) {
274
+ function doGroupQuery(tabId, clientId, baseName, retries, callback, context) {
275
+ var state = context ? _getState(context) : null;
276
+ var wsManager = context ? _getWSManager(context) : null;
254
277
  chrome.tabGroups.query({}, function(allGroups) {
255
278
  if (chrome.runtime.lastError) {
256
279
  Logger.error('[TabGroup] tabGroups.query failed:', chrome.runtime.lastError.message);
257
- EventBuilder.send('CDPTunnel.debug', { source: 'doGroup', phase: 'query', error: chrome.runtime.lastError.message });
280
+ EventBuilder.send('CDPTunnel.debug', { source: 'doGroup', phase: 'query', error: chrome.runtime.lastError.message }, null, wsManager);
258
281
  }
259
282
  if (!allGroups) {
260
283
  Logger.error('[TabGroup] tabGroups.query returned null');
261
284
  if (retries < 3) {
262
- setTimeout(function() { doGroup(tabId, clientId, baseName, retries + 1, callback); }, 500);
285
+ setTimeout(function() { doGroup(tabId, clientId, baseName, retries + 1, callback, context); }, 500);
263
286
  } else {
264
287
  if (callback) callback(false);
265
288
  }
@@ -272,15 +295,15 @@ var SpecialHandler = (function() {
272
295
  chrome.tabs.group({ tabIds: tabId, groupId: existing.id }, function(result) {
273
296
  if (chrome.runtime.lastError) {
274
297
  Logger.error('[TabGroup] Failed to add tab to group:', chrome.runtime.lastError.message, 'retries:', retries);
275
- EventBuilder.send('CDPTunnel.debug', { source: 'doGroup', phase: 'addToExisting', error: chrome.runtime.lastError.message, tabId: tabId, groupId: existing.id });
298
+ EventBuilder.send('CDPTunnel.debug', { source: 'doGroup', phase: 'addToExisting', error: chrome.runtime.lastError.message, tabId: tabId, groupId: existing.id }, null, wsManager);
276
299
  if (retries < 3) {
277
- setTimeout(function() { doGroup(tabId, clientId, baseName, retries + 1, callback); }, 500);
300
+ setTimeout(function() { doGroup(tabId, clientId, baseName, retries + 1, callback, context); }, 500);
278
301
  } else {
279
302
  if (callback) callback(false);
280
303
  }
281
304
  } else {
282
- State.setGroupIdForClient(clientId, existing.id);
283
- updateTabGroupName(clientId);
305
+ if (state) state.setGroupIdForClient(clientId, existing.id);
306
+ updateTabGroupName(clientId, state, wsManager);
284
307
  Logger.info('[TabGroup] Tab', tabId, 'added to existing group:', existing.id);
285
308
  if (callback) callback(true);
286
309
  }
@@ -290,16 +313,16 @@ var SpecialHandler = (function() {
290
313
  chrome.tabs.group({ tabIds: tabId }, function(groupId) {
291
314
  if (chrome.runtime.lastError) {
292
315
  Logger.error('[TabGroup] Failed to create group:', chrome.runtime.lastError.message, 'retries:', retries);
293
- EventBuilder.send('CDPTunnel.debug', { source: 'doGroup', phase: 'createGroup', error: chrome.runtime.lastError.message, tabId: tabId });
316
+ EventBuilder.send('CDPTunnel.debug', { source: 'doGroup', phase: 'createGroup', error: chrome.runtime.lastError.message, tabId: tabId }, null, wsManager);
294
317
  if (retries < 3) {
295
- setTimeout(function() { doGroup(tabId, clientId, baseName, retries + 1, callback); }, 500);
318
+ setTimeout(function() { doGroup(tabId, clientId, baseName, retries + 1, callback, context); }, 500);
296
319
  } else {
297
320
  if (callback) callback(false);
298
321
  }
299
322
  return;
300
323
  }
301
324
  Logger.info('[TabGroup] chrome.tabs.group returned groupId:', groupId);
302
- EventBuilder.send('CDPTunnel.debug', { source: 'doGroup', phase: 'groupCreated', tabId: tabId, groupId: groupId });
325
+ EventBuilder.send('CDPTunnel.debug', { source: 'doGroup', phase: 'groupCreated', tabId: tabId, groupId: groupId }, null, wsManager);
303
326
  if (groupId) {
304
327
  if (chrome.tabGroups) {
305
328
  chrome.tabGroups.update(groupId, {
@@ -309,16 +332,16 @@ var SpecialHandler = (function() {
309
332
  }, function() {
310
333
  if (chrome.runtime.lastError) {
311
334
  Logger.error('[TabGroup] Failed to update group:', chrome.runtime.lastError.message);
312
- EventBuilder.send('CDPTunnel.debug', { source: 'doGroup', phase: 'updateGroup', error: chrome.runtime.lastError.message, groupId: groupId });
335
+ EventBuilder.send('CDPTunnel.debug', { source: 'doGroup', phase: 'updateGroup', error: chrome.runtime.lastError.message, groupId: groupId }, null, wsManager);
313
336
  } else {
314
- State.setGroupIdForClient(clientId, groupId);
315
- updateTabGroupName(clientId);
337
+ if (state) state.setGroupIdForClient(clientId, groupId);
338
+ updateTabGroupName(clientId, state, wsManager);
316
339
  Logger.info('[TabGroup] Group updated:', groupId, baseName);
317
340
  }
318
341
  if (callback) callback(true);
319
342
  });
320
343
  } else {
321
- State.setGroupIdForClient(clientId, groupId);
344
+ if (state) state.setGroupIdForClient(clientId, groupId);
322
345
  Logger.info('[TabGroup] Group created but tabGroups.update unavailable (headless):', groupId);
323
346
  if (callback) callback(true);
324
347
  }
@@ -331,18 +354,20 @@ var SpecialHandler = (function() {
331
354
  });
332
355
  }
333
356
 
334
- function updateTabGroupName(clientId) {
357
+ function updateTabGroupName(clientId, state, wsManager) {
335
358
  if (!clientId) return;
336
-
337
- var groupId = State.getGroupIdForClient(clientId);
359
+
360
+ var groupId = state ? state.getGroupIdForClient(clientId) : null;
338
361
  if (!groupId) return;
339
-
362
+
363
+ var connectionTag = (wsManager && wsManager.config && wsManager.config.tag) || null;
364
+
340
365
  chrome.tabs.query({ groupId: groupId }, function(tabs) {
341
366
  if (chrome.runtime.lastError || !tabs) return;
342
-
343
- var baseName = CDPUtils.getGroupBaseName(clientId);
367
+
368
+ var baseName = CDPUtils.getGroupBaseName(clientId, connectionTag);
344
369
  var newName = baseName + ' (' + tabs.length + ')';
345
-
370
+
346
371
  chrome.tabGroups.update(groupId, {
347
372
  title: newName
348
373
  }, function() {
@@ -354,7 +379,7 @@ var SpecialHandler = (function() {
354
379
  });
355
380
  });
356
381
  }
357
-
382
+
358
383
  function targetActivateTarget(context) {
359
384
  var params = context.params;
360
385
  var targetId = params && params.targetId;
@@ -371,22 +396,23 @@ var SpecialHandler = (function() {
371
396
  }
372
397
 
373
398
  function targetCloseTarget(context) {
399
+ var state = _getState(context);
374
400
  var params = context.params;
375
401
  var targetId = params && params.targetId;
376
402
  if (targetId) {
377
- var tabId = State.getTabIdByTargetId(targetId);
403
+ var tabId = state.getTabIdByTargetId(targetId);
378
404
  if (tabId) {
379
- var closeClientId = State.getClientIdByTabId(tabId);
405
+ var closeClientId = state.getClientIdByTabId(tabId);
380
406
  return new Promise(function(resolve) {
381
407
  chrome.tabs.remove(tabId, function() {
382
- State.removeAttachedTab(tabId);
408
+ state.removeAttachedTab(tabId);
383
409
  if (closeClientId) {
384
- updateTabGroupName(closeClientId);
410
+ updateTabGroupName(closeClientId, state, _getWSManager(context));
385
411
  }
386
412
  resolve({ success: true });
387
413
  });
388
414
  }).catch(function() {
389
- State.removeAttachedTab(tabId);
415
+ state.removeAttachedTab(tabId);
390
416
  return { success: true };
391
417
  });
392
418
  }
@@ -395,52 +421,55 @@ var SpecialHandler = (function() {
395
421
  }
396
422
 
397
423
  function pageStartScreencast(context) {
424
+ var state = _getState(context);
398
425
  var params = context.params;
399
426
  var sessionId = context.sessionId;
400
- var tabId = sessionId ? State.getTabIdBySession(sessionId) : State.getCurrentTabId();
427
+ var tabId = sessionId ? state.getTabIdBySession(sessionId) : state.getCurrentTabId();
401
428
 
402
429
  return checkTabVisibility(tabId).then(function(isVisible) {
403
430
  if (!isVisible) {
404
- return Screencast.startPolling(tabId, params, sessionId).then(function() {
431
+ return Screencast.startPolling(tabId, params, sessionId, state).then(function() {
405
432
  return {};
406
433
  });
407
434
  }
408
- return ForwardHandler.execute({ id: context.id, method: 'Page.startScreencast', params: params, sessionId: sessionId });
435
+ return ForwardHandler.execute(context);
409
436
  });
410
437
  }
411
438
 
412
439
  function pageStopScreencast(context) {
440
+ var state = _getState(context);
413
441
  var sessionId = context.sessionId;
414
- var tabId = sessionId ? State.getTabIdBySession(sessionId) : State.getCurrentTabId();
415
- var session = tabId ? State.getScreencastSession(tabId) : null;
416
-
442
+ var tabId = sessionId ? state.getTabIdBySession(sessionId) : state.getCurrentTabId();
443
+ var session = tabId ? state.getScreencastSession(tabId) : null;
444
+
417
445
  if (session) {
418
- Screencast.stopPolling(tabId);
446
+ Screencast.stopPolling(tabId, state);
419
447
  }
420
-
448
+
421
449
  return {};
422
450
  }
423
451
 
424
452
  function pageScreencastFrameAck(context) {
425
- var params = context.params;
453
+ var state = _getState(context);
426
454
  var sessionId = context.sessionId;
427
- var tabId = sessionId ? State.getTabIdBySession(sessionId) : State.getCurrentTabId();
428
- var session = tabId ? State.getScreencastSession(tabId) : null;
429
-
455
+ var tabId = sessionId ? state.getTabIdBySession(sessionId) : state.getCurrentTabId();
456
+ var session = tabId ? state.getScreencastSession(tabId) : null;
457
+
430
458
  if (session) {
431
- Screencast.ackFrame(tabId, params && params.sessionId);
459
+ Screencast.ackFrame(tabId, (context.params && context.params.sessionId), state);
432
460
  return {};
433
461
  }
434
-
462
+
435
463
  return {};
436
464
  }
437
465
 
438
466
  function runtimeRunIfWaitingForDebugger(context) {
467
+ var state = _getState(context);
439
468
  var sessionId = context.sessionId;
440
- var tabId = sessionId ? State.getTabIdBySession(sessionId) : State.getCurrentTabId();
469
+ var tabId = sessionId ? state.getTabIdBySession(sessionId) : state.getCurrentTabId();
441
470
 
442
- if (tabId && State.isPendingDebuggerTab(tabId)) {
443
- State.removePendingDebuggerTab(tabId);
471
+ if (tabId && state.isPendingDebuggerTab(tabId)) {
472
+ state.removePendingDebuggerTab(tabId);
444
473
  }
445
474
  return {};
446
475
  }
@@ -484,8 +513,10 @@ function checkTabVisibility(tabId) {
484
513
  }
485
514
 
486
515
  function emitAutoAttachForExistingTargets(context) {
516
+ var state = _getState(context);
517
+ var wsManager = _getWSManager(context);
487
518
  var clientId = context ? context.clientId : null;
488
- var config = State.getAutoAttachConfig();
519
+ var config = state.getAutoAttachConfig();
489
520
 
490
521
  return chrome.debugger.getTargets().then(function(targets) {
491
522
  var promises = [];
@@ -498,15 +529,15 @@ function checkTabVisibility(tabId) {
498
529
 
499
530
  var targetId = target.id;
500
531
  var tabId = target.tabId;
501
- var hasEmitted = State.hasEmittedTarget(targetId);
532
+ var hasEmitted = state.hasEmittedTarget(targetId);
502
533
 
503
534
  if (hasEmitted) {
504
535
  Logger.info('[CDP] Target already emitted, skipping:', targetId);
505
536
  return;
506
537
  }
507
538
 
508
- var isCDPCreated = State.isCDPCreatedTab(tabId);
509
- var isOwnedByClient = isCDPCreated && State.getClientIdByTabId(tabId) === clientId;
539
+ var isCDPCreated = state.isCDPCreatedTab(tabId);
540
+ var isOwnedByClient = isCDPCreated && state.getClientIdByTabId(tabId) === clientId;
510
541
  var otherClientOwns = isCDPCreated && !isOwnedByClient;
511
542
 
512
543
  if (!isCDPCreated) {
@@ -516,35 +547,35 @@ function checkTabVisibility(tabId) {
516
547
 
517
548
  if (otherClientOwns) {
518
549
  Logger.info('[CDP] Skipping other-client tab:', targetId, 'tabId:', tabId);
519
- State.addEmittedTarget(targetId);
550
+ state.addEmittedTarget(targetId);
520
551
  return;
521
552
  }
522
553
 
523
- State.addEmittedTarget(targetId);
554
+ state.addEmittedTarget(targetId);
524
555
  var targetInfo = LocalHandler.mapToTargetInfo(target);
525
-
556
+
526
557
  Logger.info('[CDP] Emitting CDP-owned target:', targetId, 'tabId:', tabId);
527
558
 
528
559
  var attachLogic = function(attached) {
529
560
  var sessionId = CDPUtils.generateSessionId();
530
- State.mapSession(sessionId, tabId, targetId);
561
+ state.mapSession(sessionId, tabId, targetId);
531
562
 
532
563
  if (config.waitForDebuggerOnStart) {
533
- State.addPendingDebuggerTab(tabId);
564
+ state.addPendingDebuggerTab(tabId);
534
565
  }
535
566
 
536
567
  EventBuilder.send('Target.attachedToTarget', {
537
568
  sessionId: sessionId,
538
569
  targetInfo: Object.assign({}, targetInfo, { attached: true }),
539
570
  waitingForDebugger: config.waitForDebuggerOnStart || false
540
- });
571
+ }, null, wsManager);
541
572
  };
542
573
 
543
574
  if (target.attached) {
544
575
  promises.push(Promise.resolve().then(function() { attachLogic(true); }));
545
576
  } else {
546
577
  promises.push(
547
- DebuggerManager.attach(tabId).then(function(attached) {
578
+ DebuggerManager.attach(tabId, state).then(function(attached) {
548
579
  if (!attached) return;
549
580
  attachLogic(attached);
550
581
  })
@@ -556,54 +587,48 @@ function checkTabVisibility(tabId) {
556
587
  });
557
588
  }
558
589
 
559
- function emitAutoAttachEvents(tabId, targetId, browserContextId) {
560
- if (State.hasEmittedTarget(targetId)) {
590
+ function emitAutoAttachEvents(tabId, targetId, browserContextId, context) {
591
+ var state = _getState(context);
592
+ var wsManager = _getWSManager(context);
593
+ if (state.hasEmittedTarget(targetId)) {
561
594
  Logger.info('[CDP] Target already emitted, skipping emitAutoAttachEvents:', targetId);
562
595
  return Promise.resolve();
563
596
  }
564
-
565
- State.addEmittedTarget(targetId);
597
+
598
+ state.addEmittedTarget(targetId);
566
599
 
567
600
  return LocalHandler.getTargetInfoById(targetId).then(function(targetInfo) {
568
601
  if (browserContextId && browserContextId !== 'default') {
569
602
  targetInfo.browserContextId = browserContextId;
570
603
  }
571
- EventBuilder.send('Target.targetCreated', { targetInfo: targetInfo });
604
+ EventBuilder.send('Target.targetCreated', { targetInfo: targetInfo }, null, wsManager);
572
605
 
573
- return DebuggerManager.attach(tabId).then(function(attached) {
606
+ return DebuggerManager.attach(tabId, state).then(function(attached) {
574
607
  if (!attached) return;
575
608
 
576
609
  var sessionId = CDPUtils.generateSessionId();
577
- State.mapSession(sessionId, tabId, targetId);
610
+ state.mapSession(sessionId, tabId, targetId);
578
611
 
579
- var config = State.getAutoAttachConfig();
612
+ var config = state.getAutoAttachConfig();
580
613
  if (config.waitForDebuggerOnStart) {
581
- State.addPendingDebuggerTab(tabId);
614
+ state.addPendingDebuggerTab(tabId);
582
615
  }
583
616
 
584
617
  EventBuilder.send('Target.attachedToTarget', {
585
618
  sessionId: sessionId,
586
619
  targetInfo: targetInfo,
587
620
  waitingForDebugger: config.waitForDebuggerOnStart
588
- });
621
+ }, null, wsManager);
589
622
  });
590
623
  });
591
624
  }
592
625
 
593
626
  function pageCreateIsolatedWorld(context) {
594
- var params = context.params;
595
- var sessionId = context.sessionId;
596
- var tabId = sessionId ? State.getTabIdBySession(sessionId) : State.getCurrentTabId();
597
-
598
- return ForwardHandler.execute({ id: context.id, method: 'Page.createIsolatedWorld', params: params, sessionId: sessionId });
627
+ return ForwardHandler.execute(context);
599
628
  }
600
629
 
601
630
  function pageAddScriptToEvaluateOnNewDocument(context) {
602
- var params = context.params;
603
- var sessionId = context.sessionId;
604
- var tabId = sessionId ? State.getTabIdBySession(sessionId) : State.getCurrentTabId();
605
-
606
- return ForwardHandler.execute({ id: context.id, method: 'Page.addScriptToEvaluateOnNewDocument', params: params, sessionId: sessionId });
631
+ return ForwardHandler.execute(context);
607
632
  }
608
633
 
609
634
  function domSetFileInputFiles(context) {
@@ -612,7 +637,7 @@ function checkTabVisibility(tabId) {
612
637
  var files = params && params.files;
613
638
 
614
639
  if (!files || !Array.isArray(files) || files.length === 0) {
615
- return ForwardHandler.execute({ id: context.id, method: 'DOM.setFileInputFiles', params: params, sessionId: sessionId });
640
+ return ForwardHandler.execute(context);
616
641
  }
617
642
 
618
643
  var hasUrl = files.some(function(f) {
@@ -620,16 +645,17 @@ function checkTabVisibility(tabId) {
620
645
  });
621
646
 
622
647
  if (!hasUrl) {
623
- return ForwardHandler.execute({ id: context.id, method: 'DOM.setFileInputFiles', params: params, sessionId: sessionId });
648
+ return ForwardHandler.execute(context);
624
649
  }
625
650
 
626
651
  Logger.info('[CDP] DOM.setFileInputFiles: 检测到远程 URL, 开始下载...');
627
652
 
628
653
  return downloadRemoteFiles(files).then(function(localFiles) {
629
654
  Logger.info('[CDP] DOM.setFileInputFiles: 下载完成, 本地路径:', localFiles);
630
-
655
+
631
656
  var newParams = Object.assign({}, params, { files: localFiles });
632
- return ForwardHandler.execute({ id: context.id, method: 'DOM.setFileInputFiles', params: newParams, sessionId: sessionId });
657
+ var newContext = Object.assign({}, context, { params: newParams });
658
+ return ForwardHandler.execute(newContext);
633
659
  });
634
660
  }
635
661
 
@@ -647,7 +673,7 @@ function checkTabVisibility(tabId) {
647
673
  function downloadRemoteFile(url) {
648
674
  return new Promise(function(resolve, reject) {
649
675
  var filename = 'cdp_upload_' + Date.now() + '_' + url.split('/').pop().split('?')[0];
650
-
676
+
651
677
  chrome.downloads.download({
652
678
  url: url,
653
679
  filename: filename,
@@ -668,7 +694,7 @@ function checkTabVisibility(tabId) {
668
694
  reject(new Error('Download item not found'));
669
695
  return;
670
696
  }
671
-
697
+
672
698
  var filePath = results[0].filename;
673
699
  Logger.info('[CDP] 下载完成, 本地路径:', filePath);
674
700
  resolve(filePath);