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.
@@ -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
- console.log('[CDP] routeCDPCommand id=' + id + ' (type: ' + typeof id + ') method=' + method + ' clientId=' + (clientId || 'none'));
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({ id: id, method: method, params: params, sessionId: sessionId, clientId: clientId }))
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({ id: id, method: method, params: params, sessionId: sessionId, clientId: clientId });
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({ id: id, method: method, params: params, sessionId: sessionId, clientId: clientId })
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
- WebSocketManager.send(response);
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
- WebSocketManager.send(event);
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 - 配置管理</title>
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">🔄 刷新</button>
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="form-group">
747
- <label>服务器地址</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>📖 客户端连接方式</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>