元素拾取跟随前台标签页: 点搜索等开新标签页后附着目标自动切换
- pickElement 轮询前经 /json/list 检查前台标签页, 变化时 activateTab 切换附着并重新注册/注入拾取脚本 - 结束时对所有已附着标签页清理拾取残留, 并移除全部 addScriptToEvaluateOnNewDocument 注入
This commit is contained in:
1 parent
5250bf1e35
commit
91d998b2ea
1 file changed
+28
-9
@@ -1165,16 +1165,32 @@ export class BrowserSession implements BrowserLike {
|
|||||||
}
|
}
|
||||||
const inject = () =>
|
const inject = () =>
|
||||||
this.evaluate(`(() => { try { delete window.__rpaPickResult; ${PICKER_BOOTSTRAP_SOURCE} } catch {} })()`);
|
this.evaluate(`(() => { try { delete window.__rpaPickResult; ${PICKER_BOOTSTRAP_SOURCE} } catch {} })()`);
|
||||||
|
const injectionIds: string[] = [];
|
||||||
|
const registerInjection = async () => {
|
||||||
|
const registered = await this.cdp<{ identifier?: string }>("Page.addScriptToEvaluateOnNewDocument", {
|
||||||
|
source: PICKER_BOOTSTRAP_SOURCE
|
||||||
|
}).catch(() => null);
|
||||||
|
if (registered?.identifier) injectionIds.push(registered.identifier);
|
||||||
|
};
|
||||||
|
// 跟随前台标签页:搜索/点按钮常开新标签页,附着目标切过去并重新注入,拾取不中断
|
||||||
|
const followForegroundTab = async () => {
|
||||||
|
if (this.win || !this.httpBase) return;
|
||||||
|
const pages = await listPageTargets(this.httpBase).catch(() => []);
|
||||||
|
const page = pages[0];
|
||||||
|
if (!page || page.id === this.activeTargetId) return;
|
||||||
|
await this.activateTab(page.id);
|
||||||
|
await this.cdp("Page.enable").catch(() => {});
|
||||||
|
await registerInjection();
|
||||||
|
await inject();
|
||||||
|
};
|
||||||
await this.cdp("Page.enable").catch(() => {});
|
await this.cdp("Page.enable").catch(() => {});
|
||||||
const registered = await this.cdp<{ identifier?: string }>("Page.addScriptToEvaluateOnNewDocument", {
|
await registerInjection();
|
||||||
source: PICKER_BOOTSTRAP_SOURCE
|
|
||||||
}).catch(() => null);
|
|
||||||
const injectionId = registered?.identifier;
|
|
||||||
try {
|
try {
|
||||||
await inject();
|
await inject();
|
||||||
const deadline = Date.now() + Math.max(5000, timeoutMs);
|
const deadline = Date.now() + Math.max(5000, timeoutMs);
|
||||||
while (Date.now() < deadline) {
|
while (Date.now() < deadline) {
|
||||||
await new Promise((resolve) => setTimeout(resolve, 400));
|
await new Promise((resolve) => setTimeout(resolve, 400));
|
||||||
|
await followForegroundTab().catch(() => {});
|
||||||
const state = await this.evaluate<{ result: { ok: boolean; value?: ElementPickResult; reason?: string } | null; active: boolean }>(
|
const state = await this.evaluate<{ result: { ok: boolean; value?: ElementPickResult; reason?: string } | null; active: boolean }>(
|
||||||
"({ result: window.__rpaPickResult ?? null, active: window.__rpaPickerActive?.active === true })"
|
"({ result: window.__rpaPickResult ?? null, active: window.__rpaPickerActive?.active === true })"
|
||||||
).catch(() => null);
|
).catch(() => null);
|
||||||
@@ -1187,11 +1203,14 @@ export class BrowserSession implements BrowserLike {
|
|||||||
}
|
}
|
||||||
throw new RuntimeError("timeout", "拾取超时,请重新点击拾取");
|
throw new RuntimeError("timeout", "拾取超时,请重新点击拾取");
|
||||||
} finally {
|
} finally {
|
||||||
await this.evaluate(
|
const cleanupExpr =
|
||||||
"(() => { try { window.__rpaElementPicker?.cancelHard?.(); window.__rpaPickerActive = undefined; delete window.__rpaPickResult; } catch {} })()"
|
"(() => { try { window.__rpaElementPicker?.cancelHard?.(); window.__rpaPickerActive = undefined; delete window.__rpaPickResult; } catch {} })()";
|
||||||
).catch(() => {});
|
await this.evaluate(cleanupExpr).catch(() => {});
|
||||||
if (injectionId) {
|
for (const tabTransport of this.tabTransports.values()) {
|
||||||
await this.cdp("Page.removeScriptToEvaluateOnNewDocument", { identifier: injectionId }).catch(() => {});
|
await tabTransport.send("Runtime.evaluate", { expression: cleanupExpr }).catch(() => {});
|
||||||
|
}
|
||||||
|
for (const identifier of injectionIds) {
|
||||||
|
await this.cdp("Page.removeScriptToEvaluateOnNewDocument", { identifier }).catch(() => {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user