cdp-tunnel 2.9.1 → 2.9.3
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/extension-new/background.js +11 -1
- package/extension-new/cdp/handler/special.js +1 -2
- package/extension-new/config-page-preview.html +31 -0
- package/extension-new/config-page.js +23 -1
- package/extension-new/core/websocket.js +4 -1
- package/extension-new/manifest.json +1 -1
- package/extension-new/popup.html +6 -0
- package/extension-new/popup.js +42 -1
- package/package.json +1 -1
|
@@ -338,6 +338,15 @@ importScripts('features/automation-badge.js');
|
|
|
338
338
|
});
|
|
339
339
|
});
|
|
340
340
|
|
|
341
|
+
function getCdpAddress(wsUrl, mode) {
|
|
342
|
+
var match = (wsUrl || '').match(/:\/\/([^\/]+):(\d+)/);
|
|
343
|
+
if (!match) return '';
|
|
344
|
+
var host = match[1];
|
|
345
|
+
var port = parseInt(match[2], 10);
|
|
346
|
+
if (mode === 'takeover') port += 1;
|
|
347
|
+
return 'http://' + host + ':' + port;
|
|
348
|
+
}
|
|
349
|
+
|
|
341
350
|
chrome.runtime.onInstalled.addListener(function(details) {
|
|
342
351
|
Logger.info('[Runtime] Extension installed/updated:', details.reason);
|
|
343
352
|
State.persist(null, false);
|
|
@@ -466,7 +475,8 @@ importScripts('features/automation-badge.js');
|
|
|
466
475
|
status = 'error';
|
|
467
476
|
}
|
|
468
477
|
}
|
|
469
|
-
|
|
478
|
+
var cdpAddress = getCdpAddress(conn.url, conn.mode || 'create');
|
|
479
|
+
return { id: conn.id, tag: conn.tag, url: conn.url, mode: conn.mode || 'create', status: status, attachedCount: attachedCount, cdpAddress: cdpAddress };
|
|
470
480
|
});
|
|
471
481
|
sendResponse({ connections: list });
|
|
472
482
|
});
|
|
@@ -84,8 +84,7 @@ var SpecialHandler = (function() {
|
|
|
84
84
|
addTabToAutomationGroup(tabId, clientId, null, context);
|
|
85
85
|
} else if (context.mode === 'takeover') {
|
|
86
86
|
state.addPreExistingTab(tabId);
|
|
87
|
-
|
|
88
|
-
Logger.info('[CDP TAKEOVER] Target.attachToTarget: added to TAKE group. tabId:', tabId);
|
|
87
|
+
Logger.info('[CDP TAKEOVER] Target.attachToTarget: attached without grouping. tabId:', tabId);
|
|
89
88
|
} else {
|
|
90
89
|
state.addPreExistingTab(tabId);
|
|
91
90
|
Logger.info('[CDP] Target.attachToTarget: user tab not CDP-created, treating as pre-existing. tabId:', tabId);
|
|
@@ -283,6 +283,37 @@
|
|
|
283
283
|
font-family: 'Monaco', 'Menlo', monospace;
|
|
284
284
|
}
|
|
285
285
|
|
|
286
|
+
.conn-config-cdp {
|
|
287
|
+
font-size: 11px;
|
|
288
|
+
color: #374151;
|
|
289
|
+
font-family: 'Monaco', 'Menlo', monospace;
|
|
290
|
+
margin-top: 2px;
|
|
291
|
+
display: flex;
|
|
292
|
+
align-items: center;
|
|
293
|
+
gap: 4px;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
.conn-config-cdp .cdp-addr {
|
|
297
|
+
color: #2563eb;
|
|
298
|
+
font-weight: 600;
|
|
299
|
+
cursor: pointer;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
.conn-config-cdp .btn-copy-cdp {
|
|
303
|
+
border: none;
|
|
304
|
+
background: transparent;
|
|
305
|
+
cursor: pointer;
|
|
306
|
+
font-size: 12px;
|
|
307
|
+
padding: 0 4px;
|
|
308
|
+
opacity: 0.5;
|
|
309
|
+
transition: opacity 0.2s;
|
|
310
|
+
line-height: 1;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
.conn-config-cdp .btn-copy-cdp:hover {
|
|
314
|
+
opacity: 1;
|
|
315
|
+
}
|
|
316
|
+
|
|
286
317
|
.conn-config-item .btn-delete {
|
|
287
318
|
padding: 4px 10px;
|
|
288
319
|
border: none;
|
|
@@ -95,13 +95,15 @@
|
|
|
95
95
|
connections.forEach(function(conn) {
|
|
96
96
|
var statusClass = getStatusClass(conn.id, conn.enabled);
|
|
97
97
|
var isActive = conn.enabled && statusClass === 'connected';
|
|
98
|
+
var cdpAddr = getCdpAddress(conn.url, conn.mode);
|
|
98
99
|
html +=
|
|
99
100
|
'<div class="conn-config-item' + (isActive ? ' active' : '') + '" data-id="' + conn.id + '">' +
|
|
100
101
|
'<input type="checkbox" class="conn-toggle" data-id="' + conn.id + '"' + (conn.enabled ? ' checked' : '') + ' title="启用/禁用">' +
|
|
101
102
|
'<span class="status-dot ' + statusClass + '" title="' + statusClass + '"></span>' +
|
|
102
103
|
'<div class="conn-config-info">' +
|
|
103
104
|
'<div class="conn-config-tag">' + (conn.mode === 'takeover' ? '🔗 ' : '🆕 ') + escapeHtml(conn.tag) + '</div>' +
|
|
104
|
-
'<div class="conn-config-url" title="' + escapeAttr(conn.url) + '">' + escapeHtml(conn.url) + '</div>' +
|
|
105
|
+
'<div class="conn-config-url" title="' + escapeAttr(conn.url) + '">WS: ' + escapeHtml(conn.url) + '</div>' +
|
|
106
|
+
(cdpAddr ? '<div class="conn-config-cdp">CDP: <span class="cdp-addr" data-cdp="' + escapeAttr(cdpAddr) + '">' + escapeHtml(cdpAddr) + '</span> <button class="btn-copy-cdp" data-cdp="' + escapeAttr(cdpAddr) + '" title="复制 CDP 地址">📋</button></div>' : '') +
|
|
105
107
|
'</div>' +
|
|
106
108
|
'<button class="btn-delete" data-id="' + conn.id + '" title="删除">删除</button>' +
|
|
107
109
|
'</div>';
|
|
@@ -297,6 +299,15 @@
|
|
|
297
299
|
return (s || '').replace(/&/g, '&').replace(/"/g, '"').replace(/</g, '<').replace(/>/g, '>');
|
|
298
300
|
}
|
|
299
301
|
|
|
302
|
+
function getCdpAddress(wsUrl, mode) {
|
|
303
|
+
var match = (wsUrl || '').match(/:\/\/([^\/]+):(\d+)/);
|
|
304
|
+
if (!match) return '';
|
|
305
|
+
var host = match[1];
|
|
306
|
+
var port = parseInt(match[2], 10);
|
|
307
|
+
if (mode === 'takeover') port += 1;
|
|
308
|
+
return 'http://' + host + ':' + port;
|
|
309
|
+
}
|
|
310
|
+
|
|
300
311
|
function init() {
|
|
301
312
|
if (typeof chrome !== 'undefined' && chrome.storage) {
|
|
302
313
|
chrome.storage.local.get(['autoMute'], function(result) {
|
|
@@ -365,6 +376,17 @@
|
|
|
365
376
|
});
|
|
366
377
|
|
|
367
378
|
elements.connConfigList.addEventListener('click', function(e) {
|
|
379
|
+
var copyBtn = e.target.closest('.btn-copy-cdp');
|
|
380
|
+
if (copyBtn) {
|
|
381
|
+
var addr = copyBtn.dataset.cdp;
|
|
382
|
+
if (addr) {
|
|
383
|
+
navigator.clipboard.writeText(addr).then(function() {
|
|
384
|
+
showToast('已复制: ' + addr);
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
|
|
368
390
|
var toggleEl = e.target.closest('.conn-toggle');
|
|
369
391
|
if (toggleEl) {
|
|
370
392
|
var connId = toggleEl.dataset.id;
|
|
@@ -269,7 +269,6 @@ var WebSocketConnection = (function() {
|
|
|
269
269
|
var sessions = self.state.findSessionsByTabId(tid);
|
|
270
270
|
sessions.forEach(function(sid) { self.state.unmapSession(sid); });
|
|
271
271
|
});
|
|
272
|
-
self.state.removeGroupForClient(takeClientId);
|
|
273
272
|
self.state.removeCDPClient(takeClientId);
|
|
274
273
|
if (self.state.getCDPClients().length === 0) {
|
|
275
274
|
self.state.setHasConnectedClient(false);
|
|
@@ -541,6 +540,10 @@ var WebSocketConnection = (function() {
|
|
|
541
540
|
WebSocketConnection.prototype._createGroupForClient = function(clientId, mode) {
|
|
542
541
|
var self = this;
|
|
543
542
|
if (!clientId || !chrome.tabGroups) return;
|
|
543
|
+
if (mode === 'takeover') {
|
|
544
|
+
Logger.info('[WS:' + self.connectionId + '] Skipping group creation for takeover mode, clientId:', clientId);
|
|
545
|
+
return;
|
|
546
|
+
}
|
|
544
547
|
|
|
545
548
|
if (self._groupCreationPending.has(clientId)) {
|
|
546
549
|
Logger.info('[WS:' + self.connectionId + '] Group creation already pending for client:', clientId);
|
package/extension-new/popup.html
CHANGED
|
@@ -23,6 +23,12 @@ body { width: 320px; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI',
|
|
|
23
23
|
.conn-tag { font-weight: 600; font-size: 13px; color: #e0e0e0; }
|
|
24
24
|
.conn-url { color: #888; font-size: 11px; font-family: 'SF Mono', Menlo, monospace; word-break: break-all; margin-top: 3px; line-height: 1.4; }
|
|
25
25
|
|
|
26
|
+
.conn-cdp { color: #4a9eff; font-size: 11px; font-family: 'SF Mono', Menlo, monospace; margin-top: 2px; display: flex; align-items: center; gap: 2px; }
|
|
27
|
+
.conn-cdp-label { color: #888; }
|
|
28
|
+
.conn-cdp-value { font-weight: 600; }
|
|
29
|
+
.conn-cdp-copy { background: none; border: none; cursor: pointer; font-size: 11px; padding: 0 2px; opacity: 0.5; transition: opacity 0.15s; }
|
|
30
|
+
.conn-cdp-copy:hover { opacity: 1; }
|
|
31
|
+
|
|
26
32
|
.empty-hint { text-align: center; padding: 16px 10px; color: #777; font-size: 12px; }
|
|
27
33
|
|
|
28
34
|
.stats-row { display: flex; gap: 16px; padding: 8px 0; font-size: 12px; color: #aaa; }
|
package/extension-new/popup.js
CHANGED
|
@@ -14,6 +14,15 @@
|
|
|
14
14
|
});
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
function getCdpAddress(wsUrl, mode) {
|
|
18
|
+
var match = (wsUrl || '').match(/:\/\/([^\/]+):(\d+)/);
|
|
19
|
+
if (!match) return '';
|
|
20
|
+
var host = match[1];
|
|
21
|
+
var port = parseInt(match[2], 10);
|
|
22
|
+
if (mode === 'takeover') port += 1;
|
|
23
|
+
return 'http://' + host + ':' + port;
|
|
24
|
+
}
|
|
25
|
+
|
|
17
26
|
function renderConnectionList(connections) {
|
|
18
27
|
connectionList.innerHTML = '';
|
|
19
28
|
|
|
@@ -43,10 +52,42 @@
|
|
|
43
52
|
|
|
44
53
|
var url = document.createElement('div');
|
|
45
54
|
url.className = 'conn-url';
|
|
46
|
-
url.textContent = conn.url;
|
|
55
|
+
url.textContent = 'WS: ' + conn.url;
|
|
47
56
|
|
|
48
57
|
item.appendChild(header);
|
|
49
58
|
item.appendChild(url);
|
|
59
|
+
|
|
60
|
+
var cdpAddr = conn.cdpAddress || getCdpAddress(conn.url, conn.mode);
|
|
61
|
+
if (cdpAddr) {
|
|
62
|
+
var cdpRow = document.createElement('div');
|
|
63
|
+
cdpRow.className = 'conn-cdp';
|
|
64
|
+
|
|
65
|
+
var cdpLabel = document.createElement('span');
|
|
66
|
+
cdpLabel.className = 'conn-cdp-label';
|
|
67
|
+
cdpLabel.textContent = 'CDP: ';
|
|
68
|
+
|
|
69
|
+
var cdpValue = document.createElement('span');
|
|
70
|
+
cdpValue.className = 'conn-cdp-value';
|
|
71
|
+
cdpValue.textContent = cdpAddr;
|
|
72
|
+
|
|
73
|
+
var copyBtn = document.createElement('button');
|
|
74
|
+
copyBtn.className = 'conn-cdp-copy';
|
|
75
|
+
copyBtn.textContent = '📋';
|
|
76
|
+
copyBtn.title = '复制';
|
|
77
|
+
copyBtn.addEventListener('click', function(ev) {
|
|
78
|
+
ev.stopPropagation();
|
|
79
|
+
navigator.clipboard.writeText(cdpAddr).then(function() {
|
|
80
|
+
copyBtn.textContent = '✓';
|
|
81
|
+
setTimeout(function() { copyBtn.textContent = '📋'; }, 1200);
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
cdpRow.appendChild(cdpLabel);
|
|
86
|
+
cdpRow.appendChild(cdpValue);
|
|
87
|
+
cdpRow.appendChild(copyBtn);
|
|
88
|
+
item.appendChild(cdpRow);
|
|
89
|
+
}
|
|
90
|
+
|
|
50
91
|
connectionList.appendChild(item);
|
|
51
92
|
});
|
|
52
93
|
}
|
package/package.json
CHANGED