cdp-tunnel 2.7.9 → 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.
- package/extension-new/background.js +234 -130
- package/extension-new/cdp/handler/forward.js +9 -7
- package/extension-new/cdp/handler/local.js +60 -39
- package/extension-new/cdp/handler/special.js +145 -119
- package/extension-new/cdp/index.js +16 -7
- package/extension-new/cdp/response.js +12 -4
- package/extension-new/config-page-preview.html +174 -57
- package/extension-new/config-page.js +169 -70
- package/extension-new/core/connection-manager.js +120 -0
- package/extension-new/core/connection-state.js +355 -0
- package/extension-new/core/debugger.js +65 -52
- package/extension-new/core/state.js +87 -438
- package/extension-new/core/websocket.js +345 -279
- package/extension-new/features/screencast.js +42 -20
- package/extension-new/manifest.json +3 -2
- package/extension-new/utils/config.js +83 -2
- package/extension-new/utils/helpers.js +5 -4
- package/package.json +1 -1
|
@@ -58,26 +58,35 @@ var CDP_HANDLERS = {
|
|
|
58
58
|
'DOM.setFileInputFiles': { type: 'SPECIAL', handler: SpecialHandler.domSetFileInputFiles }
|
|
59
59
|
};
|
|
60
60
|
|
|
61
|
-
function routeCDPCommand(message) {
|
|
61
|
+
function routeCDPCommand(message, connState, wsManager) {
|
|
62
62
|
var id = message.id;
|
|
63
63
|
var method = message.method;
|
|
64
64
|
var params = message.params;
|
|
65
65
|
var sessionId = message.sessionId;
|
|
66
66
|
var clientId = message.clientId;
|
|
67
|
+
var state = connState;
|
|
67
68
|
|
|
68
|
-
|
|
69
|
+
if (!state) {
|
|
70
|
+
var entry = ConnectionManager.getPrimaryConnection();
|
|
71
|
+
state = entry ? entry.state : null;
|
|
72
|
+
wsManager = wsManager || (entry ? entry.wsManager : null);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
console.log('[CDP] routeCDPCommand id=' + id + ' (type: ' + typeof id + ') method=' + method + ' clientId=' + (clientId || 'none') + ' connId=' + (message.connectionId || 'none'));
|
|
69
76
|
|
|
70
77
|
var route = CDP_HANDLERS[method];
|
|
71
78
|
var logType = route ? route.type : 'FORWARD';
|
|
72
79
|
Logger.info('[CDP] RECV id=' + id + ' method=' + method + ' type=' + logType + ' sessionId=' + (sessionId || 'null') + ' clientId=' + (clientId || 'null'));
|
|
73
80
|
|
|
81
|
+
var ctx = { id: id, method: method, params: params, sessionId: sessionId, clientId: clientId, _state: state, _wsManager: wsManager };
|
|
82
|
+
|
|
74
83
|
return new Promise(function(resolve) {
|
|
75
84
|
if (route) {
|
|
76
|
-
Promise.resolve(route.handler(
|
|
85
|
+
Promise.resolve(route.handler(ctx))
|
|
77
86
|
.then(function(result) {
|
|
78
87
|
if (result === null && route.type === 'SPECIAL') {
|
|
79
88
|
Logger.info('[CDP] SPECIAL null -> FORWARD id=' + id + ' method=' + method);
|
|
80
|
-
return ForwardHandler.execute(
|
|
89
|
+
return ForwardHandler.execute(ctx);
|
|
81
90
|
}
|
|
82
91
|
return result;
|
|
83
92
|
})
|
|
@@ -90,7 +99,7 @@ function routeCDPCommand(message) {
|
|
|
90
99
|
resolve({ error: { code: error.code || -32000, message: error.message || String(error) } });
|
|
91
100
|
});
|
|
92
101
|
} else {
|
|
93
|
-
ForwardHandler.execute(
|
|
102
|
+
ForwardHandler.execute(ctx)
|
|
94
103
|
.then(function(result) {
|
|
95
104
|
Logger.info('[CDP] SEND id=' + id + ' method=' + method + ' hasError=false (forwarded)');
|
|
96
105
|
resolve({ result: result });
|
|
@@ -102,9 +111,9 @@ function routeCDPCommand(message) {
|
|
|
102
111
|
}
|
|
103
112
|
}).then(function(response) {
|
|
104
113
|
if (response.error) {
|
|
105
|
-
ResponseBuilder.send(id, null, sessionId, response.error.message);
|
|
114
|
+
ResponseBuilder.send(id, null, sessionId, response.error.message, wsManager);
|
|
106
115
|
} else {
|
|
107
|
-
ResponseBuilder.send(id, response.result, sessionId);
|
|
116
|
+
ResponseBuilder.send(id, response.result, sessionId, null, wsManager);
|
|
108
117
|
}
|
|
109
118
|
return response;
|
|
110
119
|
});
|
|
@@ -11,14 +11,18 @@ var ResponseBuilder = (function() {
|
|
|
11
11
|
return response;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
function send(id, result, sessionId, errorMessage) {
|
|
14
|
+
function send(id, result, sessionId, errorMessage, wsManager) {
|
|
15
15
|
var response;
|
|
16
16
|
if (errorMessage) {
|
|
17
17
|
response = ResponseBuilder.error(id, errorMessage, sessionId);
|
|
18
18
|
} else {
|
|
19
19
|
response = ResponseBuilder.success(id, result, sessionId);
|
|
20
20
|
}
|
|
21
|
-
|
|
21
|
+
if (wsManager) {
|
|
22
|
+
wsManager.send(response);
|
|
23
|
+
} else {
|
|
24
|
+
WebSocketManager.send(response);
|
|
25
|
+
}
|
|
22
26
|
return response;
|
|
23
27
|
}
|
|
24
28
|
|
|
@@ -36,9 +40,13 @@ var EventBuilder = (function() {
|
|
|
36
40
|
return event;
|
|
37
41
|
}
|
|
38
42
|
|
|
39
|
-
function send(method, params, sessionId) {
|
|
43
|
+
function send(method, params, sessionId, wsManager) {
|
|
40
44
|
var event = EventBuilder.build(method, params, sessionId);
|
|
41
|
-
|
|
45
|
+
if (wsManager) {
|
|
46
|
+
wsManager.send(event);
|
|
47
|
+
} else {
|
|
48
|
+
WebSocketManager.send(event);
|
|
49
|
+
}
|
|
42
50
|
console.log('[EventBuilder.send]', method);
|
|
43
51
|
return event;
|
|
44
52
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>CDP Bridge -
|
|
6
|
+
<title>CDP Bridge - 连接管理</title>
|
|
7
7
|
<style>
|
|
8
8
|
* {
|
|
9
9
|
margin: 0;
|
|
@@ -215,6 +215,124 @@
|
|
|
215
215
|
min-height: 0;
|
|
216
216
|
}
|
|
217
217
|
|
|
218
|
+
/* --- Connection Config List --- */
|
|
219
|
+
.conn-config-list {
|
|
220
|
+
display: flex;
|
|
221
|
+
flex-direction: column;
|
|
222
|
+
gap: 8px;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
.conn-config-item {
|
|
226
|
+
display: flex;
|
|
227
|
+
align-items: center;
|
|
228
|
+
padding: 10px 12px;
|
|
229
|
+
background: #f9fafb;
|
|
230
|
+
border-radius: 8px;
|
|
231
|
+
gap: 10px;
|
|
232
|
+
border: 2px solid transparent;
|
|
233
|
+
transition: border-color 0.2s, background 0.2s;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
.conn-config-item:hover {
|
|
237
|
+
background: #f3f4f6;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
.conn-config-item.active {
|
|
241
|
+
border-color: #10b981;
|
|
242
|
+
background: rgba(16, 185, 129, 0.05);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
.status-dot {
|
|
246
|
+
display: inline-block;
|
|
247
|
+
width: 10px;
|
|
248
|
+
height: 10px;
|
|
249
|
+
border-radius: 50%;
|
|
250
|
+
flex-shrink: 0;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
.status-dot.connected { background: #4caf50; box-shadow: 0 0 0 2px rgba(76, 175, 80, 0.2); }
|
|
254
|
+
.status-dot.error { background: #f44336; box-shadow: 0 0 0 2px rgba(244, 67, 54, 0.2); }
|
|
255
|
+
.status-dot.disabled { background: #9e9e9e; }
|
|
256
|
+
|
|
257
|
+
.conn-config-item input[type="checkbox"] {
|
|
258
|
+
width: 16px;
|
|
259
|
+
height: 16px;
|
|
260
|
+
cursor: pointer;
|
|
261
|
+
flex-shrink: 0;
|
|
262
|
+
accent-color: #667eea;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
.conn-config-info {
|
|
266
|
+
flex: 1;
|
|
267
|
+
min-width: 0;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
.conn-config-tag {
|
|
271
|
+
font-weight: 600;
|
|
272
|
+
font-size: 13px;
|
|
273
|
+
color: #1f2937;
|
|
274
|
+
margin-bottom: 2px;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
.conn-config-url {
|
|
278
|
+
font-size: 11px;
|
|
279
|
+
color: #6b7280;
|
|
280
|
+
white-space: nowrap;
|
|
281
|
+
overflow: hidden;
|
|
282
|
+
text-overflow: ellipsis;
|
|
283
|
+
font-family: 'Monaco', 'Menlo', monospace;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
.conn-config-item .btn-delete {
|
|
287
|
+
padding: 4px 10px;
|
|
288
|
+
border: none;
|
|
289
|
+
background: transparent;
|
|
290
|
+
color: #9ca3af;
|
|
291
|
+
border-radius: 4px;
|
|
292
|
+
cursor: pointer;
|
|
293
|
+
font-size: 12px;
|
|
294
|
+
transition: all 0.2s;
|
|
295
|
+
flex-shrink: 0;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
.conn-config-item .btn-delete:hover {
|
|
299
|
+
background: #fef2f2;
|
|
300
|
+
color: #dc2626;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/* --- Add Connection Form --- */
|
|
304
|
+
.add-conn-form {
|
|
305
|
+
display: flex;
|
|
306
|
+
align-items: center;
|
|
307
|
+
gap: 8px;
|
|
308
|
+
margin-top: 10px;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
.add-conn-form input {
|
|
312
|
+
padding: 8px 10px;
|
|
313
|
+
border: 1px solid #d1d5db;
|
|
314
|
+
border-radius: 6px;
|
|
315
|
+
font-size: 13px;
|
|
316
|
+
outline: none;
|
|
317
|
+
transition: border-color 0.2s;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
.add-conn-form input:focus {
|
|
321
|
+
border-color: #667eea;
|
|
322
|
+
box-shadow: 0 0 0 2px rgba(102, 126, 234, 0.1);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
.add-conn-form .input-tag {
|
|
326
|
+
width: 100px;
|
|
327
|
+
flex-shrink: 0;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
.add-conn-form .input-url {
|
|
331
|
+
flex: 1;
|
|
332
|
+
min-width: 0;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/* --- Existing UI components --- */
|
|
218
336
|
.connection-list {
|
|
219
337
|
display: flex;
|
|
220
338
|
flex-direction: column;
|
|
@@ -253,21 +371,10 @@
|
|
|
253
371
|
box-shadow: 0 0 0 2px rgba(16, 185, 129, 0.2);
|
|
254
372
|
}
|
|
255
373
|
|
|
256
|
-
.connection-item .status-indicator.busy {
|
|
257
|
-
background: #f59e0b;
|
|
258
|
-
box-shadow: 0 0 0 2px rgba(245, 158, 11, 0.2);
|
|
259
|
-
animation: blink 0.5s infinite;
|
|
260
|
-
}
|
|
261
|
-
|
|
262
374
|
.connection-item .status-indicator.offline {
|
|
263
375
|
background: #9ca3af;
|
|
264
376
|
}
|
|
265
377
|
|
|
266
|
-
@keyframes blink {
|
|
267
|
-
0%, 100% { opacity: 1; }
|
|
268
|
-
50% { opacity: 0.5; }
|
|
269
|
-
}
|
|
270
|
-
|
|
271
378
|
.connection-item .connection-info {
|
|
272
379
|
flex: 1;
|
|
273
380
|
min-width: 0;
|
|
@@ -298,11 +405,6 @@
|
|
|
298
405
|
color: #2563eb;
|
|
299
406
|
}
|
|
300
407
|
|
|
301
|
-
.connection-item .connection-tag.puppeteer {
|
|
302
|
-
background: #fef3c7;
|
|
303
|
-
color: #d97706;
|
|
304
|
-
}
|
|
305
|
-
|
|
306
408
|
.connection-item .connection-tag.cdp {
|
|
307
409
|
background: #e0e7ff;
|
|
308
410
|
color: #4f46e5;
|
|
@@ -316,28 +418,6 @@
|
|
|
316
418
|
color: #6b7280;
|
|
317
419
|
}
|
|
318
420
|
|
|
319
|
-
.connection-item .page-info {
|
|
320
|
-
display: flex;
|
|
321
|
-
align-items: center;
|
|
322
|
-
gap: 4px;
|
|
323
|
-
max-width: 200px;
|
|
324
|
-
overflow: hidden;
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
.connection-item .page-title {
|
|
328
|
-
color: #1f2937;
|
|
329
|
-
white-space: nowrap;
|
|
330
|
-
overflow: hidden;
|
|
331
|
-
text-overflow: ellipsis;
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
.connection-item .connection-meta {
|
|
335
|
-
text-align: right;
|
|
336
|
-
flex-shrink: 0;
|
|
337
|
-
font-size: 11px;
|
|
338
|
-
color: #9ca3af;
|
|
339
|
-
}
|
|
340
|
-
|
|
341
421
|
.connection-item .connection-actions {
|
|
342
422
|
display: flex;
|
|
343
423
|
gap: 4px;
|
|
@@ -370,11 +450,6 @@
|
|
|
370
450
|
color: #1f2937;
|
|
371
451
|
}
|
|
372
452
|
|
|
373
|
-
.connection-item .action-btn.danger:hover {
|
|
374
|
-
background: #fef2f2;
|
|
375
|
-
color: #dc2626;
|
|
376
|
-
}
|
|
377
|
-
|
|
378
453
|
.sidebar {
|
|
379
454
|
display: flex;
|
|
380
455
|
flex-direction: column;
|
|
@@ -493,6 +568,30 @@
|
|
|
493
568
|
margin: 16px 0;
|
|
494
569
|
}
|
|
495
570
|
|
|
571
|
+
.config-item {
|
|
572
|
+
display: flex;
|
|
573
|
+
justify-content: space-between;
|
|
574
|
+
align-items: center;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
.plugin-id-row {
|
|
578
|
+
display: flex;
|
|
579
|
+
justify-content: space-between;
|
|
580
|
+
align-items: center;
|
|
581
|
+
margin-top: 12px;
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
.plugin-id-label {
|
|
585
|
+
font-size: 12px;
|
|
586
|
+
color: #6b7280;
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
.plugin-id-value {
|
|
590
|
+
font-size: 11px;
|
|
591
|
+
color: #4a9eff;
|
|
592
|
+
font-family: monospace;
|
|
593
|
+
}
|
|
594
|
+
|
|
496
595
|
.usage-guide {
|
|
497
596
|
background: #f9fafb;
|
|
498
597
|
border-radius: 8px;
|
|
@@ -699,6 +798,27 @@
|
|
|
699
798
|
|
|
700
799
|
<div class="content-grid">
|
|
701
800
|
<div class="left-panel">
|
|
801
|
+
<!-- Connection Config Card -->
|
|
802
|
+
<div class="card">
|
|
803
|
+
<div class="card-header">
|
|
804
|
+
<h3>连接配置</h3>
|
|
805
|
+
</div>
|
|
806
|
+
<div class="card-body">
|
|
807
|
+
<div class="conn-config-list" id="connConfigList">
|
|
808
|
+
<div class="empty-state">
|
|
809
|
+
<div class="icon">🔗</div>
|
|
810
|
+
<div class="title">暂无连接配置</div>
|
|
811
|
+
<div class="desc">在下方添加一个 WebSocket 连接</div>
|
|
812
|
+
</div>
|
|
813
|
+
</div>
|
|
814
|
+
<div class="add-conn-form">
|
|
815
|
+
<input type="text" class="input-tag" id="newConnTag" placeholder="名称">
|
|
816
|
+
<input type="text" class="input-url" id="newConnUrl" placeholder="ws://localhost:58288/plugin">
|
|
817
|
+
<button class="btn btn-primary btn-sm" id="addConnBtn">添加连接</button>
|
|
818
|
+
</div>
|
|
819
|
+
</div>
|
|
820
|
+
</div>
|
|
821
|
+
|
|
702
822
|
<div class="card">
|
|
703
823
|
<div class="card-header">
|
|
704
824
|
<h3>
|
|
@@ -723,7 +843,7 @@
|
|
|
723
843
|
受控页面
|
|
724
844
|
<span class="badge" id="pageCount">0 个</span>
|
|
725
845
|
</h3>
|
|
726
|
-
<button class="btn btn-secondary btn-sm" id="refreshBtn"
|
|
846
|
+
<button class="btn btn-secondary btn-sm" id="refreshBtn">刷新</button>
|
|
727
847
|
</div>
|
|
728
848
|
<div class="card-body">
|
|
729
849
|
<div class="connection-list" id="pageList">
|
|
@@ -743,27 +863,23 @@
|
|
|
743
863
|
<h3>插件配置</h3>
|
|
744
864
|
</div>
|
|
745
865
|
<div class="card-body">
|
|
746
|
-
<div class="
|
|
747
|
-
<label
|
|
748
|
-
<input type="text" id="serverAddress" value="ws://localhost:9221/plugin" placeholder="ws://your-server:9221/plugin">
|
|
749
|
-
<div class="description">WebSocket 服务器地址,插件将连接到此服务器</div>
|
|
750
|
-
</div>
|
|
751
|
-
<button class="btn btn-primary btn-block" id="connectBtn">🔗 保存并连接</button>
|
|
752
|
-
|
|
753
|
-
<div class="config-item" style="display: flex; justify-content: space-between; align-items: center; margin-top: 12px;">
|
|
754
|
-
<label style="font-size: 13px; color: #666;">
|
|
755
|
-
🔇 自动静音新标签页
|
|
756
|
-
</label>
|
|
866
|
+
<div class="config-item">
|
|
867
|
+
<label style="font-size: 13px; color: #666;">🔇 自动静音新标签页</label>
|
|
757
868
|
<label class="toggle-switch">
|
|
758
869
|
<input type="checkbox" id="autoMuteToggle" checked>
|
|
759
870
|
<span class="toggle-slider"></span>
|
|
760
871
|
</label>
|
|
761
872
|
</div>
|
|
762
873
|
|
|
874
|
+
<div class="plugin-id-row">
|
|
875
|
+
<span class="plugin-id-label">插件 ID:</span>
|
|
876
|
+
<span class="plugin-id-value" id="pluginIdDisplay">-</span>
|
|
877
|
+
</div>
|
|
878
|
+
|
|
763
879
|
<div class="divider"></div>
|
|
764
880
|
|
|
765
881
|
<div class="usage-guide">
|
|
766
|
-
<h4
|
|
882
|
+
<h4>客户端连接方式</h4>
|
|
767
883
|
<p>插件连接后,客户端通过 CDP 端点连接:</p>
|
|
768
884
|
<div class="example">
|
|
769
885
|
<pre><span class="comment">// Playwright</span>
|
|
@@ -803,6 +919,7 @@
|
|
|
803
919
|
<span class="message">操作成功</span>
|
|
804
920
|
</div>
|
|
805
921
|
|
|
922
|
+
<script src="utils/config.js"></script>
|
|
806
923
|
<script src="config-page.js"></script>
|
|
807
924
|
</body>
|
|
808
925
|
</html>
|