cdp-tunnel 3.0.2 → 3.0.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/package.json
CHANGED
|
@@ -181,17 +181,25 @@ class PortPoolManager {
|
|
|
181
181
|
return;
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
+
// 合成输入命令需要 ensureVisible(和 forward.js 的逻辑一致)
|
|
185
|
+
const SYNTHETIC_INPUT = ['Input.dispatchKeyEvent', 'Input.dispatchMouseEvent'];
|
|
186
|
+
|
|
184
187
|
// 消息处理:client → plugin(带 portIndex 标记)
|
|
185
|
-
ws.on('message', (data) => {
|
|
188
|
+
ws.on('message', async (data) => {
|
|
186
189
|
let msg;
|
|
187
190
|
try { msg = JSON.parse(data.toString()); } catch { return; }
|
|
188
191
|
|
|
189
192
|
if (msg.id !== undefined) {
|
|
193
|
+
// 合成输入命令:先 bringToFront + 等待,再发原命令
|
|
194
|
+
if (SYNTHETIC_INPUT.indexOf(msg.method) >= 0 && msg.sessionId) {
|
|
195
|
+
await this._ensureVisible(session, pluginWs, msg.sessionId);
|
|
196
|
+
}
|
|
197
|
+
|
|
190
198
|
// 命令:分配新 id,记录映射(含 method 名供响应后处理),转发给 plugin
|
|
191
199
|
const newId = `pool${session.portIndex}_${msg.id}`;
|
|
192
200
|
session.pendingRequests.set(newId, {
|
|
193
201
|
originalId: msg.id,
|
|
194
|
-
method: msg.method,
|
|
202
|
+
method: msg.method,
|
|
195
203
|
clientWs: ws
|
|
196
204
|
});
|
|
197
205
|
|
|
@@ -223,6 +231,10 @@ class PortPoolManager {
|
|
|
223
231
|
|
|
224
232
|
// 1. 响应消息:id 以 pool 开头
|
|
225
233
|
if (msg.id && typeof msg.id === 'string' && msg.id.startsWith('pool')) {
|
|
234
|
+
// 内部命令(ensureVisible 用的)响应直接丢弃
|
|
235
|
+
if (msg.id.includes('_internal')) {
|
|
236
|
+
return true;
|
|
237
|
+
}
|
|
226
238
|
const match = msg.id.match(/^pool(\d+)_(.+)$/);
|
|
227
239
|
if (!match) return false;
|
|
228
240
|
|
|
@@ -300,6 +312,54 @@ class PortPoolManager {
|
|
|
300
312
|
return isNaN(n) ? idStr : n;
|
|
301
313
|
}
|
|
302
314
|
|
|
315
|
+
/**
|
|
316
|
+
* 让 tab 变 visible:Page.bringToFront + 等待 + 恢复焦点。
|
|
317
|
+
* 内部命令用 _internal_ 前缀,handlePluginMessage 会丢弃它们的响应。
|
|
318
|
+
*/
|
|
319
|
+
async _ensureVisible(session, pluginWs, sessionId) {
|
|
320
|
+
const pfx = `pool${session.portIndex}_internal`;
|
|
321
|
+
|
|
322
|
+
// 1. 保存焦点
|
|
323
|
+
pluginWs.send(JSON.stringify({
|
|
324
|
+
id: `${pfx}_save_${Date.now()}`,
|
|
325
|
+
method: 'Runtime.evaluate',
|
|
326
|
+
params: { expression: '(function(){var el=document.activeElement;if(el&&el!==document.body&&el.focus){el.setAttribute("data-cdp-saved-focus","1");return 1}return 0})()', returnByValue: true },
|
|
327
|
+
sessionId, __portIndex: session.portIndex
|
|
328
|
+
}));
|
|
329
|
+
|
|
330
|
+
// 2. bringToFront
|
|
331
|
+
pluginWs.send(JSON.stringify({
|
|
332
|
+
id: `${pfx}_front_${Date.now()}`,
|
|
333
|
+
method: 'Page.bringToFront',
|
|
334
|
+
params: {},
|
|
335
|
+
sessionId, __portIndex: session.portIndex
|
|
336
|
+
}));
|
|
337
|
+
|
|
338
|
+
// 3. 等 visibilitychange + 双 rAF(renderer 完成切换)
|
|
339
|
+
pluginWs.send(JSON.stringify({
|
|
340
|
+
id: `${pfx}_vis_${Date.now()}`,
|
|
341
|
+
method: 'Runtime.evaluate',
|
|
342
|
+
params: {
|
|
343
|
+
expression: 'new Promise(function(r){function ok(){requestAnimationFrame(function(){requestAnimationFrame(function(){r(1)})})}if(document.visibilityState==="visible"){ok()}else{var d=function(){if(document.visibilityState==="visible"){document.removeEventListener("visibilitychange",d);ok()}};document.addEventListener("visibilitychange",d);setTimeout(function(){document.removeEventListener("visibilitychange",d);ok()},3000)}})',
|
|
344
|
+
awaitPromise: true
|
|
345
|
+
},
|
|
346
|
+
sessionId, __portIndex: session.portIndex
|
|
347
|
+
}));
|
|
348
|
+
|
|
349
|
+
// 给 bringToFront + visibility 等待时间(不等具体响应,内部命令响应被丢弃)
|
|
350
|
+
await new Promise(r => setTimeout(r, 300));
|
|
351
|
+
|
|
352
|
+
// 4. 恢复焦点
|
|
353
|
+
pluginWs.send(JSON.stringify({
|
|
354
|
+
id: `${pfx}_restore_${Date.now()}`,
|
|
355
|
+
method: 'Runtime.evaluate',
|
|
356
|
+
params: { expression: '(function(){var el=document.querySelector("[data-cdp-saved-focus]");if(el){el.removeAttribute("data-cdp-saved-focus");el.focus();return 1}return 0})()', returnByValue: true },
|
|
357
|
+
sessionId, __portIndex: session.portIndex
|
|
358
|
+
}));
|
|
359
|
+
|
|
360
|
+
await new Promise(r => setTimeout(r, 50));
|
|
361
|
+
}
|
|
362
|
+
|
|
303
363
|
_broadcastToPort(portIndex, msg) {
|
|
304
364
|
const session = this.portSessions[portIndex];
|
|
305
365
|
if (!session) return;
|