cdp-tunnel 1.0.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/.github/workflows/publish.yml +92 -0
- package/.github/workflows/release-assets.yml +50 -0
- package/LICENSE +81 -0
- package/PUBLISH.md +65 -0
- package/README.md +228 -0
- package/cli/guide.html +753 -0
- package/cli/icon.svg +13 -0
- package/cli/icon128.png +0 -0
- package/cli/index.js +357 -0
- package/docs/README_CN.md +204 -0
- package/docs/config-page-screenshot.png +0 -0
- package/extension-new/background.js +294 -0
- package/extension-new/cdp/handler/forward.js +44 -0
- package/extension-new/cdp/handler/local.js +233 -0
- package/extension-new/cdp/handler/special.js +442 -0
- package/extension-new/cdp/index.js +104 -0
- package/extension-new/cdp/response.js +49 -0
- package/extension-new/config-page-preview.html +769 -0
- package/extension-new/config-page.js +318 -0
- package/extension-new/core/debugger.js +310 -0
- package/extension-new/core/state.js +384 -0
- package/extension-new/core/websocket.js +326 -0
- package/extension-new/features/automation-badge.js +113 -0
- package/extension-new/features/screencast.js +221 -0
- package/extension-new/icons/icon128.png +0 -0
- package/extension-new/icons/icon16.png +0 -0
- package/extension-new/icons/icon48.png +0 -0
- package/extension-new/manifest.json +39 -0
- package/extension-new/popup.html +72 -0
- package/extension-new/popup.js +34 -0
- package/extension-new/utils/config.js +20 -0
- package/extension-new/utils/diagnostics.js +560 -0
- package/extension-new/utils/helpers.js +25 -0
- package/extension-new/utils/logger.js +64 -0
- package/package.json +42 -0
- package/server/modules/config.js +28 -0
- package/server/modules/logger.js +197 -0
- package/server/proxy-server.js +1431 -0
- package/tests/playwright-demo.js +45 -0
- package/tests/playwright-interactive.js +261 -0
- package/tests/playwright-multi-demo.js +60 -0
- package/tests/playwright-multi.js +85 -0
- package/tests/playwright-single.js +41 -0
- package/tests/screenshot-config.js +35 -0
- package/tests/test-client.js +89 -0
- package/tests/test-multi-client.js +129 -0
package/cli/guide.html
ADDED
|
@@ -0,0 +1,753 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>CDP Tunnel - 安装向导</title>
|
|
7
|
+
<style>
|
|
8
|
+
* {
|
|
9
|
+
margin: 0;
|
|
10
|
+
padding: 0;
|
|
11
|
+
box-sizing: border-box;
|
|
12
|
+
}
|
|
13
|
+
body {
|
|
14
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Microsoft YaHei', sans-serif;
|
|
15
|
+
background: #f5f5f5;
|
|
16
|
+
min-height: 100vh;
|
|
17
|
+
display: flex;
|
|
18
|
+
flex-direction: column;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/* 顶部标题 */
|
|
22
|
+
.header {
|
|
23
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
24
|
+
color: white;
|
|
25
|
+
padding: 20px 30px;
|
|
26
|
+
display: flex;
|
|
27
|
+
align-items: center;
|
|
28
|
+
gap: 15px;
|
|
29
|
+
}
|
|
30
|
+
.header-icon {
|
|
31
|
+
width: 40px;
|
|
32
|
+
height: 40px;
|
|
33
|
+
}
|
|
34
|
+
.header-icon svg {
|
|
35
|
+
width: 100%;
|
|
36
|
+
height: 100%;
|
|
37
|
+
}
|
|
38
|
+
.header-title h1 {
|
|
39
|
+
font-size: 20px;
|
|
40
|
+
margin-bottom: 4px;
|
|
41
|
+
}
|
|
42
|
+
.header-title p {
|
|
43
|
+
font-size: 13px;
|
|
44
|
+
opacity: 0.9;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/* 主内容区 */
|
|
48
|
+
.main-container {
|
|
49
|
+
flex: 1;
|
|
50
|
+
display: flex;
|
|
51
|
+
overflow: hidden;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/* 左侧步骤条 */
|
|
55
|
+
.sidebar {
|
|
56
|
+
width: 280px;
|
|
57
|
+
background: white;
|
|
58
|
+
border-right: 1px solid #e8eaed;
|
|
59
|
+
display: flex;
|
|
60
|
+
flex-direction: column;
|
|
61
|
+
overflow: hidden;
|
|
62
|
+
}
|
|
63
|
+
.sidebar-header {
|
|
64
|
+
padding: 24px 20px;
|
|
65
|
+
border-bottom: 1px solid #e8eaed;
|
|
66
|
+
text-align: center;
|
|
67
|
+
}
|
|
68
|
+
.sidebar-icon {
|
|
69
|
+
width: 64px;
|
|
70
|
+
height: 64px;
|
|
71
|
+
margin: 0 auto 12px;
|
|
72
|
+
}
|
|
73
|
+
.sidebar-icon svg {
|
|
74
|
+
width: 100%;
|
|
75
|
+
height: 100%;
|
|
76
|
+
border-radius: 16px;
|
|
77
|
+
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
|
78
|
+
}
|
|
79
|
+
.sidebar-title {
|
|
80
|
+
font-size: 16px;
|
|
81
|
+
font-weight: 600;
|
|
82
|
+
color: #333;
|
|
83
|
+
}
|
|
84
|
+
.sidebar-subtitle {
|
|
85
|
+
font-size: 12px;
|
|
86
|
+
color: #5f6368;
|
|
87
|
+
margin-top: 4px;
|
|
88
|
+
}
|
|
89
|
+
.sidebar-steps {
|
|
90
|
+
flex: 1;
|
|
91
|
+
overflow-y: auto;
|
|
92
|
+
padding: 16px 0;
|
|
93
|
+
}
|
|
94
|
+
.step-item {
|
|
95
|
+
display: flex;
|
|
96
|
+
align-items: flex-start;
|
|
97
|
+
gap: 12px;
|
|
98
|
+
padding: 16px 20px;
|
|
99
|
+
cursor: pointer;
|
|
100
|
+
transition: all 0.2s;
|
|
101
|
+
border-left: 3px solid transparent;
|
|
102
|
+
}
|
|
103
|
+
.step-item:hover {
|
|
104
|
+
background: #f8f9fa;
|
|
105
|
+
}
|
|
106
|
+
.step-item.active {
|
|
107
|
+
background: #e8f0fe;
|
|
108
|
+
border-left-color: #1a73e8;
|
|
109
|
+
}
|
|
110
|
+
.step-item.completed {
|
|
111
|
+
border-left-color: #34a853;
|
|
112
|
+
}
|
|
113
|
+
.step-number {
|
|
114
|
+
width: 28px;
|
|
115
|
+
height: 28px;
|
|
116
|
+
border-radius: 50%;
|
|
117
|
+
background: #e8eaed;
|
|
118
|
+
color: #5f6368;
|
|
119
|
+
display: flex;
|
|
120
|
+
align-items: center;
|
|
121
|
+
justify-content: center;
|
|
122
|
+
font-size: 13px;
|
|
123
|
+
font-weight: bold;
|
|
124
|
+
flex-shrink: 0;
|
|
125
|
+
}
|
|
126
|
+
.step-item.active .step-number {
|
|
127
|
+
background: #1a73e8;
|
|
128
|
+
color: white;
|
|
129
|
+
}
|
|
130
|
+
.step-item.completed .step-number {
|
|
131
|
+
background: #34a853;
|
|
132
|
+
color: white;
|
|
133
|
+
}
|
|
134
|
+
.step-info {
|
|
135
|
+
flex: 1;
|
|
136
|
+
}
|
|
137
|
+
.step-name {
|
|
138
|
+
font-size: 14px;
|
|
139
|
+
font-weight: 500;
|
|
140
|
+
color: #333;
|
|
141
|
+
margin-bottom: 4px;
|
|
142
|
+
}
|
|
143
|
+
.step-item.active .step-name {
|
|
144
|
+
color: #1a73e8;
|
|
145
|
+
}
|
|
146
|
+
.step-desc {
|
|
147
|
+
font-size: 12px;
|
|
148
|
+
color: #5f6368;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/* 右侧内容区 */
|
|
152
|
+
.content {
|
|
153
|
+
flex: 1;
|
|
154
|
+
padding: 30px;
|
|
155
|
+
overflow-y: auto;
|
|
156
|
+
}
|
|
157
|
+
.content-panel {
|
|
158
|
+
display: none;
|
|
159
|
+
max-width: 700px;
|
|
160
|
+
}
|
|
161
|
+
.content-panel.active {
|
|
162
|
+
display: block;
|
|
163
|
+
animation: fadeIn 0.3s;
|
|
164
|
+
}
|
|
165
|
+
@keyframes fadeIn {
|
|
166
|
+
from { opacity: 0; transform: translateX(20px); }
|
|
167
|
+
to { opacity: 1; transform: translateX(0); }
|
|
168
|
+
}
|
|
169
|
+
.panel-title {
|
|
170
|
+
font-size: 24px;
|
|
171
|
+
color: #333;
|
|
172
|
+
margin-bottom: 20px;
|
|
173
|
+
}
|
|
174
|
+
.panel-desc {
|
|
175
|
+
color: #5f6368;
|
|
176
|
+
font-size: 15px;
|
|
177
|
+
line-height: 1.8;
|
|
178
|
+
margin-bottom: 25px;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/* Chrome 扩展程序弹窗 - 一比一还原 */
|
|
182
|
+
.chrome-popup {
|
|
183
|
+
background: white;
|
|
184
|
+
border-radius: 12px;
|
|
185
|
+
box-shadow: 0 4px 20px rgba(0,0,0,0.15);
|
|
186
|
+
width: 360px;
|
|
187
|
+
margin: 20px auto;
|
|
188
|
+
overflow: hidden;
|
|
189
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
190
|
+
}
|
|
191
|
+
.chrome-popup-header {
|
|
192
|
+
display: flex;
|
|
193
|
+
align-items: center;
|
|
194
|
+
justify-content: space-between;
|
|
195
|
+
padding: 16px 20px;
|
|
196
|
+
border-bottom: 1px solid #e8eaed;
|
|
197
|
+
}
|
|
198
|
+
.chrome-popup-title {
|
|
199
|
+
font-size: 16px;
|
|
200
|
+
font-weight: 500;
|
|
201
|
+
color: #202124;
|
|
202
|
+
}
|
|
203
|
+
.chrome-popup-close {
|
|
204
|
+
width: 20px;
|
|
205
|
+
height: 20px;
|
|
206
|
+
display: flex;
|
|
207
|
+
align-items: center;
|
|
208
|
+
justify-content: center;
|
|
209
|
+
color: #5f6368;
|
|
210
|
+
font-size: 18px;
|
|
211
|
+
cursor: pointer;
|
|
212
|
+
}
|
|
213
|
+
.chrome-popup-section {
|
|
214
|
+
padding: 12px 0;
|
|
215
|
+
}
|
|
216
|
+
.chrome-popup-section-title {
|
|
217
|
+
font-size: 11px;
|
|
218
|
+
color: #5f6368;
|
|
219
|
+
padding: 0 20px 8px;
|
|
220
|
+
font-weight: 500;
|
|
221
|
+
}
|
|
222
|
+
.chrome-popup-item {
|
|
223
|
+
display: flex;
|
|
224
|
+
align-items: center;
|
|
225
|
+
padding: 10px 20px;
|
|
226
|
+
gap: 12px;
|
|
227
|
+
}
|
|
228
|
+
.chrome-popup-item:hover {
|
|
229
|
+
background: #f8f9fa;
|
|
230
|
+
}
|
|
231
|
+
.chrome-popup-icon {
|
|
232
|
+
width: 28px;
|
|
233
|
+
height: 28px;
|
|
234
|
+
border-radius: 6px;
|
|
235
|
+
display: flex;
|
|
236
|
+
align-items: center;
|
|
237
|
+
justify-content: center;
|
|
238
|
+
flex-shrink: 0;
|
|
239
|
+
}
|
|
240
|
+
.chrome-popup-icon svg {
|
|
241
|
+
width: 100%;
|
|
242
|
+
height: 100%;
|
|
243
|
+
border-radius: 6px;
|
|
244
|
+
}
|
|
245
|
+
.chrome-popup-icon img {
|
|
246
|
+
width: 100%;
|
|
247
|
+
height: 100%;
|
|
248
|
+
border-radius: 6px;
|
|
249
|
+
}
|
|
250
|
+
.chrome-popup-name {
|
|
251
|
+
flex: 1;
|
|
252
|
+
font-size: 14px;
|
|
253
|
+
color: #202124;
|
|
254
|
+
}
|
|
255
|
+
.chrome-popup-pin {
|
|
256
|
+
width: 20px;
|
|
257
|
+
height: 20px;
|
|
258
|
+
display: flex;
|
|
259
|
+
align-items: center;
|
|
260
|
+
justify-content: center;
|
|
261
|
+
color: #1a73e8;
|
|
262
|
+
font-size: 16px;
|
|
263
|
+
}
|
|
264
|
+
.chrome-popup-menu {
|
|
265
|
+
width: 20px;
|
|
266
|
+
height: 20px;
|
|
267
|
+
display: flex;
|
|
268
|
+
align-items: center;
|
|
269
|
+
justify-content: center;
|
|
270
|
+
color: #5f6368;
|
|
271
|
+
font-size: 16px;
|
|
272
|
+
}
|
|
273
|
+
.chrome-popup-footer {
|
|
274
|
+
display: flex;
|
|
275
|
+
align-items: center;
|
|
276
|
+
padding: 12px 20px;
|
|
277
|
+
border-top: 1px solid #e8eaed;
|
|
278
|
+
gap: 12px;
|
|
279
|
+
cursor: pointer;
|
|
280
|
+
}
|
|
281
|
+
.chrome-popup-footer:hover {
|
|
282
|
+
background: #f8f9fa;
|
|
283
|
+
}
|
|
284
|
+
.chrome-popup-footer-icon {
|
|
285
|
+
width: 20px;
|
|
286
|
+
height: 20px;
|
|
287
|
+
display: flex;
|
|
288
|
+
align-items: center;
|
|
289
|
+
justify-content: center;
|
|
290
|
+
color: #5f6368;
|
|
291
|
+
}
|
|
292
|
+
.chrome-popup-footer-text {
|
|
293
|
+
font-size: 14px;
|
|
294
|
+
color: #202124;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/* 高亮动画 */
|
|
298
|
+
.highlight-pulse {
|
|
299
|
+
animation: pulse 1.5s infinite;
|
|
300
|
+
box-shadow: 0 0 0 0 rgba(234, 67, 53, 0.7);
|
|
301
|
+
}
|
|
302
|
+
@keyframes pulse {
|
|
303
|
+
0% { box-shadow: 0 0 0 0 rgba(234, 67, 53, 0.7); }
|
|
304
|
+
70% { box-shadow: 0 0 0 10px rgba(234, 67, 53, 0); }
|
|
305
|
+
100% { box-shadow: 0 0 0 0 rgba(234, 67, 53, 0); }
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/* 箭头提示 */
|
|
309
|
+
.arrow-hint {
|
|
310
|
+
position: absolute;
|
|
311
|
+
color: #ea4335;
|
|
312
|
+
font-weight: bold;
|
|
313
|
+
font-size: 13px;
|
|
314
|
+
display: flex;
|
|
315
|
+
align-items: center;
|
|
316
|
+
gap: 5px;
|
|
317
|
+
animation: bounce 1s infinite;
|
|
318
|
+
}
|
|
319
|
+
@keyframes bounce {
|
|
320
|
+
0%, 100% { transform: translateY(0); }
|
|
321
|
+
50% { transform: translateY(-5px); }
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/* 提示框 */
|
|
325
|
+
.tip-box {
|
|
326
|
+
background: #e8f0fe;
|
|
327
|
+
border-left: 4px solid #1a73e8;
|
|
328
|
+
padding: 16px;
|
|
329
|
+
border-radius: 0 8px 8px 0;
|
|
330
|
+
margin: 20px 0;
|
|
331
|
+
}
|
|
332
|
+
.tip-box.warning {
|
|
333
|
+
background: #fce8e6;
|
|
334
|
+
border-left-color: #ea4335;
|
|
335
|
+
}
|
|
336
|
+
.tip-box.success {
|
|
337
|
+
background: #e6f4ea;
|
|
338
|
+
border-left-color: #34a853;
|
|
339
|
+
}
|
|
340
|
+
.tip-box h4 {
|
|
341
|
+
color: #1a73e8;
|
|
342
|
+
margin-bottom: 8px;
|
|
343
|
+
font-size: 14px;
|
|
344
|
+
}
|
|
345
|
+
.tip-box.warning h4 {
|
|
346
|
+
color: #ea4335;
|
|
347
|
+
}
|
|
348
|
+
.tip-box.success h4 {
|
|
349
|
+
color: #34a853;
|
|
350
|
+
}
|
|
351
|
+
.tip-box p, .tip-box li {
|
|
352
|
+
color: #333;
|
|
353
|
+
font-size: 14px;
|
|
354
|
+
line-height: 1.8;
|
|
355
|
+
}
|
|
356
|
+
.tip-box ul {
|
|
357
|
+
margin-left: 20px;
|
|
358
|
+
margin-top: 8px;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/* 路径显示 */
|
|
362
|
+
.path-box {
|
|
363
|
+
background: #f8f9fa;
|
|
364
|
+
border: 2px dashed #1a73e8;
|
|
365
|
+
border-radius: 8px;
|
|
366
|
+
padding: 16px;
|
|
367
|
+
margin: 20px 0;
|
|
368
|
+
font-family: 'Monaco', 'Menlo', monospace;
|
|
369
|
+
font-size: 14px;
|
|
370
|
+
color: #333;
|
|
371
|
+
word-break: break-all;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/* 复制按钮 */
|
|
375
|
+
.btn-copy {
|
|
376
|
+
display: inline-flex;
|
|
377
|
+
align-items: center;
|
|
378
|
+
gap: 6px;
|
|
379
|
+
background: #1a73e8;
|
|
380
|
+
color: white;
|
|
381
|
+
border: none;
|
|
382
|
+
padding: 10px 16px;
|
|
383
|
+
border-radius: 6px;
|
|
384
|
+
font-size: 14px;
|
|
385
|
+
cursor: pointer;
|
|
386
|
+
transition: all 0.2s;
|
|
387
|
+
white-space: nowrap;
|
|
388
|
+
}
|
|
389
|
+
.btn-copy:hover {
|
|
390
|
+
background: #1557b0;
|
|
391
|
+
}
|
|
392
|
+
.btn-copy:active {
|
|
393
|
+
transform: scale(0.95);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/* 底部按钮区 */
|
|
397
|
+
.footer {
|
|
398
|
+
background: white;
|
|
399
|
+
border-top: 1px solid #e8eaed;
|
|
400
|
+
padding: 20px 30px;
|
|
401
|
+
display: flex;
|
|
402
|
+
justify-content: space-between;
|
|
403
|
+
align-items: center;
|
|
404
|
+
}
|
|
405
|
+
.btn {
|
|
406
|
+
padding: 12px 30px;
|
|
407
|
+
border-radius: 8px;
|
|
408
|
+
font-size: 15px;
|
|
409
|
+
cursor: pointer;
|
|
410
|
+
transition: all 0.2s;
|
|
411
|
+
border: none;
|
|
412
|
+
}
|
|
413
|
+
.btn-prev {
|
|
414
|
+
background: white;
|
|
415
|
+
color: #5f6368;
|
|
416
|
+
border: 1px solid #dadce0;
|
|
417
|
+
}
|
|
418
|
+
.btn-prev:hover {
|
|
419
|
+
background: #f1f3f4;
|
|
420
|
+
}
|
|
421
|
+
.btn-next {
|
|
422
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
423
|
+
color: white;
|
|
424
|
+
}
|
|
425
|
+
.btn-next:hover {
|
|
426
|
+
opacity: 0.9;
|
|
427
|
+
transform: translateY(-2px);
|
|
428
|
+
}
|
|
429
|
+
.btn:disabled {
|
|
430
|
+
opacity: 0.5;
|
|
431
|
+
cursor: not-allowed;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
/* 成功页面 */
|
|
435
|
+
.success-page {
|
|
436
|
+
text-align: center;
|
|
437
|
+
padding: 60px 20px;
|
|
438
|
+
}
|
|
439
|
+
.success-icon {
|
|
440
|
+
font-size: 80px;
|
|
441
|
+
margin-bottom: 20px;
|
|
442
|
+
}
|
|
443
|
+
.success-title {
|
|
444
|
+
font-size: 28px;
|
|
445
|
+
color: #34a853;
|
|
446
|
+
margin-bottom: 15px;
|
|
447
|
+
}
|
|
448
|
+
.success-text {
|
|
449
|
+
color: #5f6368;
|
|
450
|
+
font-size: 15px;
|
|
451
|
+
margin-bottom: 30px;
|
|
452
|
+
line-height: 1.8;
|
|
453
|
+
}
|
|
454
|
+
</style>
|
|
455
|
+
</head>
|
|
456
|
+
<body>
|
|
457
|
+
<!-- 使用真实图标 -->
|
|
458
|
+
|
|
459
|
+
<!-- 顶部标题 -->
|
|
460
|
+
<div class="header">
|
|
461
|
+
<div class="header-icon">
|
|
462
|
+
<img src="icon128.png" alt="CDP Tunnel" style="width: 100%; height: 100%; border-radius: 8px;">
|
|
463
|
+
</div>
|
|
464
|
+
<div class="header-title">
|
|
465
|
+
<h1>CDP Tunnel 安装向导</h1>
|
|
466
|
+
<p>一步一步引导你完成安装</p>
|
|
467
|
+
</div>
|
|
468
|
+
</div>
|
|
469
|
+
|
|
470
|
+
<!-- 主内容区 -->
|
|
471
|
+
<div class="main-container">
|
|
472
|
+
<!-- 左侧步骤条 -->
|
|
473
|
+
<div class="sidebar">
|
|
474
|
+
<div class="sidebar-header">
|
|
475
|
+
<div class="sidebar-icon">
|
|
476
|
+
<img src="icon128.png" alt="CDP Tunnel" style="width: 100%; height: 100%; border-radius: 16px; box-shadow: 0 4px 12px rgba(0,0,0,0.15);">
|
|
477
|
+
</div>
|
|
478
|
+
<div class="sidebar-title">CDP Tunnel</div>
|
|
479
|
+
<div class="sidebar-subtitle">安装向导</div>
|
|
480
|
+
</div>
|
|
481
|
+
<div class="sidebar-steps">
|
|
482
|
+
<div class="step-item active" onclick="goToStep(1)" id="sidebar-step1">
|
|
483
|
+
<div class="step-number">1</div>
|
|
484
|
+
<div class="step-info">
|
|
485
|
+
<div class="step-name">打开扩展页面</div>
|
|
486
|
+
<div class="step-desc">进入 Chrome 扩展管理</div>
|
|
487
|
+
</div>
|
|
488
|
+
</div>
|
|
489
|
+
<div class="step-item" onclick="goToStep(2)" id="sidebar-step2">
|
|
490
|
+
<div class="step-number">2</div>
|
|
491
|
+
<div class="step-info">
|
|
492
|
+
<div class="step-name">开启开发者模式</div>
|
|
493
|
+
<div class="step-desc">允许加载本地扩展</div>
|
|
494
|
+
</div>
|
|
495
|
+
</div>
|
|
496
|
+
<div class="step-item" onclick="goToStep(3)" id="sidebar-step3">
|
|
497
|
+
<div class="step-number">3</div>
|
|
498
|
+
<div class="step-info">
|
|
499
|
+
<div class="step-name">选择扩展目录</div>
|
|
500
|
+
<div class="step-desc">加载 extension-new</div>
|
|
501
|
+
</div>
|
|
502
|
+
</div>
|
|
503
|
+
<div class="step-item" onclick="goToStep(4)" id="sidebar-step4">
|
|
504
|
+
<div class="step-number">4</div>
|
|
505
|
+
<div class="step-info">
|
|
506
|
+
<div class="step-name">固定扩展并连接</div>
|
|
507
|
+
<div class="step-desc">固定到工具栏并连接</div>
|
|
508
|
+
</div>
|
|
509
|
+
</div>
|
|
510
|
+
<div class="step-item" onclick="goToStep(5)" id="sidebar-step5">
|
|
511
|
+
<div class="step-number">5</div>
|
|
512
|
+
<div class="step-info">
|
|
513
|
+
<div class="step-name">验证安装</div>
|
|
514
|
+
<div class="step-desc">确认连接成功</div>
|
|
515
|
+
</div>
|
|
516
|
+
</div>
|
|
517
|
+
</div>
|
|
518
|
+
</div>
|
|
519
|
+
|
|
520
|
+
<!-- 右侧内容区 -->
|
|
521
|
+
<div class="content">
|
|
522
|
+
<!-- 步骤 1 -->
|
|
523
|
+
<div class="content-panel active" id="panel1">
|
|
524
|
+
<h2 class="panel-title">第一步:打开 Chrome 扩展页面</h2>
|
|
525
|
+
<p class="panel-desc">
|
|
526
|
+
首先,我们需要进入 Chrome 的扩展管理页面。
|
|
527
|
+
</p>
|
|
528
|
+
<div class="tip-box">
|
|
529
|
+
<h4>📋 请复制下面的地址,在 Chrome 地址栏粘贴并回车</h4>
|
|
530
|
+
<div style="display: flex; gap: 10px; margin-top: 12px;">
|
|
531
|
+
<code id="chrome-url" style="flex: 1; background: #f1f3f4; padding: 10px 12px; border-radius: 6px; font-family: monospace; font-size: 14px;">chrome://extensions/</code>
|
|
532
|
+
<button class="btn-copy" onclick="copyToClipboard()">
|
|
533
|
+
<span>📋</span>
|
|
534
|
+
<span>复制</span>
|
|
535
|
+
</button>
|
|
536
|
+
</div>
|
|
537
|
+
<p id="copy-tip" style="margin-top: 8px; font-size: 12px; color: #34a853; display: none;">✓ 已复制到剪贴板!</p>
|
|
538
|
+
</div>
|
|
539
|
+
</div>
|
|
540
|
+
|
|
541
|
+
<!-- 步骤 2 -->
|
|
542
|
+
<div class="content-panel" id="panel2">
|
|
543
|
+
<h2 class="panel-title">第二步:开启开发者模式</h2>
|
|
544
|
+
<p class="panel-desc">
|
|
545
|
+
这是最关键的一步!必须先开启开发者模式,才能加载本地扩展。
|
|
546
|
+
</p>
|
|
547
|
+
<div class="tip-box warning">
|
|
548
|
+
<h4>⚠️ 注意</h4>
|
|
549
|
+
<p>请看页面右上角,找到「开发者模式」开关,点击它变成蓝色开启状态</p>
|
|
550
|
+
</div>
|
|
551
|
+
</div>
|
|
552
|
+
|
|
553
|
+
<!-- 步骤 3 -->
|
|
554
|
+
<div class="content-panel" id="panel3">
|
|
555
|
+
<h2 class="panel-title">第三步:选择扩展目录</h2>
|
|
556
|
+
<p class="panel-desc">
|
|
557
|
+
点击「加载已解压的扩展程序」按钮,然后在弹出的窗口中选择下面的文件夹:
|
|
558
|
+
</p>
|
|
559
|
+
<div class="path-box">
|
|
560
|
+
{{EXTENSION_PATH}}
|
|
561
|
+
</div>
|
|
562
|
+
<div class="tip-box warning">
|
|
563
|
+
<h4>⚠️ 重要提示</h4>
|
|
564
|
+
<ul>
|
|
565
|
+
<li>必须选择 <strong>extension-new</strong> 文件夹<strong>本身</strong></li>
|
|
566
|
+
<li>不要选择文件夹里面的文件</li>
|
|
567
|
+
<li>选择后点击「选择文件夹」按钮</li>
|
|
568
|
+
</ul>
|
|
569
|
+
</div>
|
|
570
|
+
</div>
|
|
571
|
+
|
|
572
|
+
<!-- 步骤 4 -->
|
|
573
|
+
<div class="content-panel" id="panel4">
|
|
574
|
+
<h2 class="panel-title">第四步:固定扩展并连接服务器</h2>
|
|
575
|
+
|
|
576
|
+
<div class="tip-box" style="margin-bottom: 20px;">
|
|
577
|
+
<h4>📌 第一步:把扩展固定到工具栏</h4>
|
|
578
|
+
<p style="margin-bottom: 12px;">刚安装的扩展可能在「拼图图标」里面,建议先固定到工具栏:</p>
|
|
579
|
+
<ul>
|
|
580
|
+
<li>点击 Chrome 右上角的 <strong>拼图图标</strong> 🧩</li>
|
|
581
|
+
<li>找到 <strong>CDP Tunnel</strong></li>
|
|
582
|
+
<li>点击旁边的<strong>图钉图标</strong> 📌 固定到工具栏</li>
|
|
583
|
+
</ul>
|
|
584
|
+
</div>
|
|
585
|
+
|
|
586
|
+
<!-- Chrome 扩展程序弹窗 - 一比一还原 -->
|
|
587
|
+
<div class="chrome-popup" style="position: relative;">
|
|
588
|
+
<div class="arrow-hint" style="top: 85px; right: 50px;">
|
|
589
|
+
<span style="font-size: 20px;">👆</span>
|
|
590
|
+
<span>点击图钉</span>
|
|
591
|
+
</div>
|
|
592
|
+
<div class="chrome-popup-header">
|
|
593
|
+
<div class="chrome-popup-title">扩展程序</div>
|
|
594
|
+
<div class="chrome-popup-close">×</div>
|
|
595
|
+
</div>
|
|
596
|
+
<div class="chrome-popup-section">
|
|
597
|
+
<div class="chrome-popup-section-title">已请求访问权限</div>
|
|
598
|
+
<div class="chrome-popup-item">
|
|
599
|
+
<div class="chrome-popup-icon">
|
|
600
|
+
<img src="icon128.png" alt="CDP" style="width: 28px; height: 28px; border-radius: 6px;">
|
|
601
|
+
</div>
|
|
602
|
+
<div class="chrome-popup-name">CDP Tunnel</div>
|
|
603
|
+
<div class="chrome-popup-pin highlight-pulse">📌</div>
|
|
604
|
+
<div class="chrome-popup-menu">⋮</div>
|
|
605
|
+
</div>
|
|
606
|
+
</div>
|
|
607
|
+
<div class="chrome-popup-section">
|
|
608
|
+
<div class="chrome-popup-section-title">不需要任何访问权限</div>
|
|
609
|
+
<div class="chrome-popup-item">
|
|
610
|
+
<div class="chrome-popup-icon" style="background: #ea4335; color: white; font-size: 12px; font-weight: bold;">ABP</div>
|
|
611
|
+
<div class="chrome-popup-name">Adblock Plus</div>
|
|
612
|
+
<div class="chrome-popup-pin">📌</div>
|
|
613
|
+
<div class="chrome-popup-menu">⋮</div>
|
|
614
|
+
</div>
|
|
615
|
+
<div class="chrome-popup-item">
|
|
616
|
+
<div class="chrome-popup-icon" style="background: #fbbc04; color: white; font-size: 12px; font-weight: bold;">A</div>
|
|
617
|
+
<div class="chrome-popup-name">Apifox Browser Extension</div>
|
|
618
|
+
<div class="chrome-popup-pin">📌</div>
|
|
619
|
+
<div class="chrome-popup-menu">⋮</div>
|
|
620
|
+
</div>
|
|
621
|
+
</div>
|
|
622
|
+
<div class="chrome-popup-footer">
|
|
623
|
+
<div class="chrome-popup-footer-icon">⚙️</div>
|
|
624
|
+
<div class="chrome-popup-footer-text">管理扩展程序</div>
|
|
625
|
+
</div>
|
|
626
|
+
</div>
|
|
627
|
+
|
|
628
|
+
<div class="tip-box" style="margin-top: 25px;">
|
|
629
|
+
<h4>🔌 第二步:连接服务器</h4>
|
|
630
|
+
<ul>
|
|
631
|
+
<li>点击工具栏上的 <img src="icon128.png" alt="CDP" style="width: 16px; height: 16px; vertical-align: middle; border-radius: 4px;"> <strong>CDP Tunnel</strong> 图标</li>
|
|
632
|
+
<li>会弹出配置窗口</li>
|
|
633
|
+
<li>确认地址是:<code style="background: rgba(0,0,0,0.1); padding: 2px 6px; border-radius: 4px;">ws://localhost:9221/plugin</code></li>
|
|
634
|
+
<li>点击「保存并连接」按钮</li>
|
|
635
|
+
</ul>
|
|
636
|
+
</div>
|
|
637
|
+
</div>
|
|
638
|
+
|
|
639
|
+
<!-- 步骤 5 -->
|
|
640
|
+
<div class="content-panel" id="panel5">
|
|
641
|
+
<div class="success-page">
|
|
642
|
+
<div class="success-icon">🎉</div>
|
|
643
|
+
<h2 class="success-title">安装完成!</h2>
|
|
644
|
+
<p class="success-text">
|
|
645
|
+
现在回到终端(命令行窗口),运行下面的命令验证连接:
|
|
646
|
+
</p>
|
|
647
|
+
<div class="path-box" style="max-width: 400px; margin: 0 auto 30px; text-align: center;">
|
|
648
|
+
cdp-tunnel status
|
|
649
|
+
</div>
|
|
650
|
+
<div class="tip-box success" style="max-width: 500px; margin: 0 auto; text-align: left;">
|
|
651
|
+
<h4>✅ 验证成功标志</h4>
|
|
652
|
+
<p>如果看到 <span style="color: #34a853; font-weight: bold;">「扩展: 已连接」</span>,恭喜你,全部完成了!</p>
|
|
653
|
+
</div>
|
|
654
|
+
</div>
|
|
655
|
+
</div>
|
|
656
|
+
</div>
|
|
657
|
+
</div>
|
|
658
|
+
|
|
659
|
+
<!-- 底部按钮 -->
|
|
660
|
+
<div class="footer">
|
|
661
|
+
<button class="btn btn-prev" id="prevBtn" onclick="prevStep()">上一步</button>
|
|
662
|
+
<button class="btn btn-next" id="nextBtn" onclick="nextStep()">下一步</button>
|
|
663
|
+
</div>
|
|
664
|
+
|
|
665
|
+
<script>
|
|
666
|
+
let currentStep = 1;
|
|
667
|
+
const totalSteps = 5;
|
|
668
|
+
|
|
669
|
+
function updateUI() {
|
|
670
|
+
// 更新左侧步骤条
|
|
671
|
+
for (let i = 1; i <= totalSteps; i++) {
|
|
672
|
+
const item = document.getElementById('sidebar-step' + i);
|
|
673
|
+
if (i < currentStep) {
|
|
674
|
+
item.classList.add('completed');
|
|
675
|
+
item.classList.remove('active');
|
|
676
|
+
item.querySelector('.step-number').innerHTML = '✓';
|
|
677
|
+
} else if (i === currentStep) {
|
|
678
|
+
item.classList.add('active');
|
|
679
|
+
item.classList.remove('completed');
|
|
680
|
+
item.querySelector('.step-number').innerHTML = i;
|
|
681
|
+
} else {
|
|
682
|
+
item.classList.remove('active', 'completed');
|
|
683
|
+
item.querySelector('.step-number').innerHTML = i;
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
// 更新右侧内容
|
|
688
|
+
for (let i = 1; i <= totalSteps; i++) {
|
|
689
|
+
const panel = document.getElementById('panel' + i);
|
|
690
|
+
if (i === currentStep) {
|
|
691
|
+
panel.classList.add('active');
|
|
692
|
+
} else {
|
|
693
|
+
panel.classList.remove('active');
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
// 更新按钮
|
|
698
|
+
document.getElementById('prevBtn').disabled = currentStep === 1;
|
|
699
|
+
document.getElementById('nextBtn').textContent = currentStep === totalSteps ? '完成' : '下一步';
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
function nextStep() {
|
|
703
|
+
if (currentStep < totalSteps) {
|
|
704
|
+
currentStep++;
|
|
705
|
+
updateUI();
|
|
706
|
+
} else {
|
|
707
|
+
alert('安装向导完成!请在终端运行 cdp-tunnel status 验证连接。');
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
function prevStep() {
|
|
712
|
+
if (currentStep > 1) {
|
|
713
|
+
currentStep--;
|
|
714
|
+
updateUI();
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
function goToStep(step) {
|
|
719
|
+
currentStep = step;
|
|
720
|
+
updateUI();
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
function copyToClipboard() {
|
|
724
|
+
const url = document.getElementById('chrome-url').textContent;
|
|
725
|
+
navigator.clipboard.writeText(url).then(() => {
|
|
726
|
+
const tip = document.getElementById('copy-tip');
|
|
727
|
+
tip.style.display = 'block';
|
|
728
|
+
setTimeout(() => {
|
|
729
|
+
tip.style.display = 'none';
|
|
730
|
+
}, 2000);
|
|
731
|
+
}).catch(() => {
|
|
732
|
+
const textarea = document.createElement('textarea');
|
|
733
|
+
textarea.value = url;
|
|
734
|
+
document.body.appendChild(textarea);
|
|
735
|
+
textarea.select();
|
|
736
|
+
document.execCommand('copy');
|
|
737
|
+
document.body.removeChild(textarea);
|
|
738
|
+
const tip = document.getElementById('copy-tip');
|
|
739
|
+
tip.style.display = 'block';
|
|
740
|
+
setTimeout(() => {
|
|
741
|
+
tip.style.display = 'none';
|
|
742
|
+
}, 2000);
|
|
743
|
+
});
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
// 键盘支持
|
|
747
|
+
document.addEventListener('keydown', function(e) {
|
|
748
|
+
if (e.key === 'ArrowRight' || e.key === 'ArrowDown') nextStep();
|
|
749
|
+
if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') prevStep();
|
|
750
|
+
});
|
|
751
|
+
</script>
|
|
752
|
+
</body>
|
|
753
|
+
</html>
|