assistant/spike/embed/main.js

60 lines
2.9 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 技术验证:Electron 内嵌 WebContentsView + 远程调试端口,供 browser-use 通过 CDP 接管。
// 运行:npx electron spike/embed/main.js
const { app, BrowserWindow, WebContentsView, session, protocol, net } = require("electron");
const path = require("path");
const { pathToFileURL } = require("url");
// 界面页走自定义协议 app://ui/...:file:// 没有主机名,会被 browser-use 的安全看门狗当成非法标签页关掉
protocol.registerSchemesAsPrivileged([{ scheme: "app", privileges: { standard: true, secure: true, supportFetchAPI: true } }]);
const CDP_PORT = process.env.SPIKE_CDP_PORT || "9333";
app.commandLine.appendSwitch("remote-debugging-port", CDP_PORT);
app.commandLine.appendSwitch("remote-allow-origins", "*");
app.whenReady().then(() => {
protocol.handle("app", (request) => {
const url = new URL(request.url);
const rel = url.pathname === "/" ? "index.html" : url.pathname.replace(/^\/+/, "");
return net.fetch(pathToFileURL(path.join(__dirname, rel)).toString());
});
const win = new BrowserWindow({
width: 1280,
height: 820,
title: "embed-spike",
webPreferences: { contextIsolation: true, nodeIntegration: false },
});
win.loadURL("app://ui/index.html");
const part = session.fromPartition("persist:spike-view");
const view = new WebContentsView({
webPreferences: { session: part, contextIsolation: true, nodeIntegration: false, sandbox: true },
});
win.contentView.addChildView(view);
const layout = () => {
const [w, h] = win.getContentSize();
view.setBounds({ x: Math.round(w * 0.36), y: 56, width: Math.round(w * 0.64), height: h - 56 });
};
win.on("resize", layout);
layout();
view.webContents.loadURL("about:blank");
win.on("close", () => console.log("[win] close requested"));
win.on("closed", () => console.log("[win] closed"));
view.webContents.on("destroyed", () => console.log("[view] destroyed"));
win.webContents.on("did-navigate", (_e, url) => console.log("[ui] did-navigate", url));
view.webContents.on("did-navigate", (_e, url) => console.log("[view] did-navigate", url));
view.webContents.on("did-navigate-in-page", (_e, url) => console.log("[view] in-page", url));
view.webContents.setWindowOpenHandler(({ url }) => {
console.log("[view] window.open blocked", url);
return { action: "deny" };
});
app.on("browser-window-created", () => console.log("[app] browser-window-created; total", BrowserWindow.getAllWindows().length));
app.on("web-contents-created", (_e, wc) => console.log("[app] web-contents-created type", wc.getType()));
setInterval(() => {
console.log("[hb] windows", BrowserWindow.getAllWindows().length, "| view url", view.webContents.getURL(), "| title", view.webContents.getTitle());
}, 5000);
console.log("[spike] ready; CDP http://127.0.0.1:" + CDP_PORT + "/json");
});
app.on("window-all-closed", () => app.quit());