cdp-tunnel 2.7.8 → 2.7.10
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.
|
@@ -142,10 +142,57 @@ importScripts('features/automation-badge.js');
|
|
|
142
142
|
State.removeTabIdToClientId(tabId);
|
|
143
143
|
});
|
|
144
144
|
|
|
145
|
+
if (chrome.tabGroups) {
|
|
146
|
+
chrome.tabGroups.onRemoved.addListener(function(group) {
|
|
147
|
+
if (!group) return;
|
|
148
|
+
var removedGroupId = group.id;
|
|
149
|
+
Logger.info('[TabGroups] Group removed:', removedGroupId);
|
|
150
|
+
|
|
151
|
+
var clients = State.getCDPClients() || [];
|
|
152
|
+
for (var i = 0; i < clients.length; i++) {
|
|
153
|
+
var clientId = clients[i].id;
|
|
154
|
+
if (State.getGroupIdForClient(clientId) === removedGroupId) {
|
|
155
|
+
Logger.info('[TabGroups] Clearing cached groupId for client:', clientId);
|
|
156
|
+
State.setGroupIdForClient(clientId, null);
|
|
157
|
+
|
|
158
|
+
var attached = State.getAttachedTabIds();
|
|
159
|
+
attached.forEach(function(tid) {
|
|
160
|
+
if (State.getClientIdByTabId(tid) === clientId && !State.isPreExistingTab(tid)) {
|
|
161
|
+
Logger.info('[TabGroups] Re-grouping tab', tid, 'for client:', clientId);
|
|
162
|
+
SpecialHandler.addTabToAutomationGroup(tid, clientId);
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
|
|
145
171
|
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
|
|
146
172
|
if (changeInfo.status === 'complete' && State.isTabAttached(tabId)) {
|
|
147
173
|
// 不再注入自动化标识,改为通过标签分组区分
|
|
148
174
|
}
|
|
175
|
+
|
|
176
|
+
if (changeInfo.groupId !== undefined && changeInfo.groupId === -1) {
|
|
177
|
+
if (State.isTabAttached(tabId) && !State.isPreExistingTab(tabId)) {
|
|
178
|
+
var clientId = State.getClientIdByTabId(tabId);
|
|
179
|
+
if (clientId) {
|
|
180
|
+
var cachedGroupId = State.getGroupIdForClient(clientId);
|
|
181
|
+
if (cachedGroupId) {
|
|
182
|
+
Logger.info('[Tabs] Tab', tabId, 'left group, re-adding to cached group:', cachedGroupId);
|
|
183
|
+
chrome.tabs.group({ tabIds: tabId, groupId: cachedGroupId }, function() {
|
|
184
|
+
if (chrome.runtime.lastError) {
|
|
185
|
+
Logger.warn('[Tabs] Failed to re-add tab to group:', chrome.runtime.lastError.message);
|
|
186
|
+
SpecialHandler.addTabToAutomationGroup(tabId, clientId);
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
} else {
|
|
190
|
+
Logger.info('[Tabs] Tab', tabId, 'left group, no cached groupId — delegating to addTabToAutomationGroup');
|
|
191
|
+
SpecialHandler.addTabToAutomationGroup(tabId, clientId);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
149
196
|
});
|
|
150
197
|
|
|
151
198
|
chrome.tabs.onCreated.addListener(function(tab) {
|
|
@@ -165,8 +165,13 @@ var SpecialHandler = (function() {
|
|
|
165
165
|
var prev = _groupQueue.get(key) || Promise.resolve();
|
|
166
166
|
|
|
167
167
|
var next = prev.then(function() {
|
|
168
|
-
return new Promise(function(resolve) {
|
|
168
|
+
return new Promise(function(resolve, reject) {
|
|
169
|
+
var timeoutId = setTimeout(function() {
|
|
170
|
+
reject(new Error('addTabToAutomationGroup timeout after 10s'));
|
|
171
|
+
}, 10000);
|
|
172
|
+
|
|
169
173
|
_addTabToAutomationGroupInner(tabId, clientId, function(success) {
|
|
174
|
+
clearTimeout(timeoutId);
|
|
170
175
|
resolve(success);
|
|
171
176
|
});
|
|
172
177
|
});
|
|
@@ -251,7 +256,16 @@ var SpecialHandler = (function() {
|
|
|
251
256
|
Logger.error('[TabGroup] tabGroups.query failed:', chrome.runtime.lastError.message);
|
|
252
257
|
EventBuilder.send('CDPTunnel.debug', { source: 'doGroup', phase: 'query', error: chrome.runtime.lastError.message });
|
|
253
258
|
}
|
|
254
|
-
|
|
259
|
+
if (!allGroups) {
|
|
260
|
+
Logger.error('[TabGroup] tabGroups.query returned null');
|
|
261
|
+
if (retries < 3) {
|
|
262
|
+
setTimeout(function() { doGroup(tabId, clientId, baseName, retries + 1, callback); }, 500);
|
|
263
|
+
} else {
|
|
264
|
+
if (callback) callback(false);
|
|
265
|
+
}
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
Logger.info('[TabGroup] query result: ' + allGroups.length + ' groups');
|
|
255
269
|
var existing = CDPUtils.findGroupByName(allGroups, baseName);
|
|
256
270
|
if (existing) {
|
|
257
271
|
Logger.info('[TabGroup] Found existing group:', existing.id, 'title:', existing.title);
|
|
@@ -3,6 +3,7 @@ var WebSocketManager = (function() {
|
|
|
3
3
|
var _isSending = false;
|
|
4
4
|
var _maxQueueSize = 100;
|
|
5
5
|
var _bufferThreshold = 512 * 1024;
|
|
6
|
+
var _groupCreationPending = new Set();
|
|
6
7
|
|
|
7
8
|
function connect() {
|
|
8
9
|
var ws = State.getWs();
|
|
@@ -197,13 +198,14 @@ var WebSocketManager = (function() {
|
|
|
197
198
|
Logger.info('[WS] Client connected, resuming event forwarding');
|
|
198
199
|
State.setHasConnectedClient(true);
|
|
199
200
|
State.addCDPClient(message.clientId, message.clientId);
|
|
200
|
-
|
|
201
|
+
createGroupForClient(message.clientId);
|
|
201
202
|
broadcastStateUpdate();
|
|
202
203
|
break;
|
|
203
204
|
|
|
204
205
|
case 'client-disconnected':
|
|
205
206
|
Logger.info('[WS] Client disconnected:', message.clientId);
|
|
206
207
|
var discClientId = message.clientId;
|
|
208
|
+
_groupCreationPending.delete(discClientId);
|
|
207
209
|
closeTabGroupByClientId(discClientId).then(function() {
|
|
208
210
|
return new Promise(function(resolve) {
|
|
209
211
|
closeTabsByClientId(discClientId, resolve);
|
|
@@ -221,7 +223,6 @@ var WebSocketManager = (function() {
|
|
|
221
223
|
State.removeCDPClient(discClientId);
|
|
222
224
|
if (State.getCDPClients().length === 0) {
|
|
223
225
|
State.setHasConnectedClient(false);
|
|
224
|
-
stopGroupMonitor();
|
|
225
226
|
}
|
|
226
227
|
broadcastStateUpdate();
|
|
227
228
|
});
|
|
@@ -231,11 +232,6 @@ var WebSocketManager = (function() {
|
|
|
231
232
|
Logger.info('[WS] Received client list:', message.clients);
|
|
232
233
|
State.setCDPClients(message.clients || []);
|
|
233
234
|
State.setHasConnectedClient((message.clients || []).length > 0);
|
|
234
|
-
if ((message.clients || []).length > 0) {
|
|
235
|
-
startGroupMonitor();
|
|
236
|
-
} else {
|
|
237
|
-
stopGroupMonitor();
|
|
238
|
-
}
|
|
239
235
|
broadcastStateUpdate();
|
|
240
236
|
break;
|
|
241
237
|
|
|
@@ -459,57 +455,50 @@ var WebSocketManager = (function() {
|
|
|
459
455
|
});
|
|
460
456
|
}
|
|
461
457
|
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
458
|
+
function createGroupForClient(clientId) {
|
|
459
|
+
if (!clientId || !chrome.tabGroups) return;
|
|
460
|
+
|
|
461
|
+
if (_groupCreationPending.has(clientId)) {
|
|
462
|
+
Logger.info('[WS] Group creation already pending for client:', clientId);
|
|
463
|
+
return;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
var existingGroupId = State.getGroupIdForClient(clientId);
|
|
467
|
+
if (existingGroupId) {
|
|
468
|
+
Logger.info('[WS] Group already cached for client:', clientId, 'groupId:', existingGroupId);
|
|
469
|
+
return;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
_groupCreationPending.add(clientId);
|
|
473
|
+
|
|
474
|
+
var baseName = CDPUtils.getGroupBaseName(clientId);
|
|
475
|
+
chrome.tabs.query({ currentWindow: true }, function(tabs) {
|
|
476
|
+
if (!tabs || tabs.length === 0) {
|
|
477
|
+
Logger.warn('[WS] No tabs found for group creation');
|
|
478
|
+
_groupCreationPending.delete(clientId);
|
|
479
|
+
return;
|
|
480
|
+
}
|
|
481
|
+
var windowId = tabs[0].windowId;
|
|
482
|
+
chrome.tabs.group({ createProperties: { windowId: windowId } }, function(groupId) {
|
|
483
|
+
if (chrome.runtime.lastError) {
|
|
484
|
+
Logger.warn('[WS] Failed to create group on connect:', chrome.runtime.lastError.message);
|
|
485
|
+
_groupCreationPending.delete(clientId);
|
|
478
486
|
return;
|
|
479
487
|
}
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
Logger.info('[Monitor] Tab', tabId, 'escaped! Forcing regroup for client:', clientId);
|
|
489
|
-
if (groupId) {
|
|
490
|
-
chrome.tabs.group({ tabIds: tabId, groupId: groupId }, function() {
|
|
491
|
-
if (chrome.runtime.lastError) {
|
|
492
|
-
Logger.error('[Monitor] Failed to re-add tab', tabId, 'to group', groupId, ':', chrome.runtime.lastError?.message);
|
|
493
|
-
State.removeGroupForClient(clientId);
|
|
494
|
-
SpecialHandler.addTabToAutomationGroup(tabId, clientId);
|
|
495
|
-
} else {
|
|
496
|
-
Logger.info('[Monitor] Re-added tab', tabId, 'to existing group:', groupId);
|
|
497
|
-
}
|
|
498
|
-
});
|
|
499
|
-
} else {
|
|
500
|
-
Logger.info('[Monitor] No cached groupId for client', clientId, '— delegating to addTabToAutomationGroup for tab', tabId);
|
|
501
|
-
SpecialHandler.addTabToAutomationGroup(tabId, clientId);
|
|
488
|
+
_groupCreationPending.delete(clientId);
|
|
489
|
+
chrome.tabGroups.update(groupId, {
|
|
490
|
+
title: baseName,
|
|
491
|
+
color: CDPUtils.getGroupColorForClient(clientId),
|
|
492
|
+
collapsed: true
|
|
493
|
+
}, function() {
|
|
494
|
+
if (chrome.runtime.lastError) {
|
|
495
|
+
Logger.warn('[WS] Failed to set group title:', chrome.runtime.lastError.message);
|
|
502
496
|
}
|
|
503
497
|
});
|
|
498
|
+
State.setGroupIdForClient(clientId, groupId);
|
|
499
|
+
Logger.info('[WS] Created group for client:', clientId, 'groupId:', groupId, 'title:', baseName);
|
|
504
500
|
});
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
function stopGroupMonitor() {
|
|
509
|
-
if (_groupMonitorTimer) {
|
|
510
|
-
clearInterval(_groupMonitorTimer);
|
|
511
|
-
_groupMonitorTimer = null;
|
|
512
|
-
}
|
|
501
|
+
});
|
|
513
502
|
}
|
|
514
503
|
|
|
515
504
|
function handleServerRestart() {
|
package/package.json
CHANGED