electron中重寫js 內建函式 需要重新核心編譯
阿新 • • 發佈:2020-08-07
electron用typescript實現了函式。比如重寫了 windows.history.back go等js 內建函式。不走blink的js binding。
D:\dev\electron7\src\electron\lib\renderer\window-setup.ts
window.open
if (!usesNativeWindowOpen) { // TODO(MarshallOfSound): Make compatible with ctx isolation without hole-punch // Make the browser window or guest view emit "new-window" event.(window as any).open = function (url?: string, frameName?: string, features?: string) { if (url != null && url !== '') { url = resolveURL(url, location.href); } const guestId = ipcRendererInternal.sendSync('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_OPEN', url, toString(frameName), toString(features));if (guestId != null) { return getOrCreateProxy(guestId); } else { return null; } }; if (shouldUseContextBridge) internalContextBridge.overrideGlobalValueWithDynamicPropsFromIsolatedWorld(['open'], window.open); }
history
window.history.forward = function () { ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_FORWARD'); }; if (shouldUseContextBridge) internalContextBridge.overrideGlobalValueFromIsolatedWorld(['history', 'forward'], window.history.forward); window.history.go = function (offset: number) { ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_TO_OFFSET', +offset); }; if (shouldUseContextBridge) internalContextBridge.overrideGlobalValueFromIsolatedWorld(['history', 'go'], window.history.go); const getHistoryLength = () => ipcRendererInternal.sendSync('ELECTRON_NAVIGATION_CONTROLLER_LENGTH'); Object.defineProperty(window.history, 'length', { get: getHistoryLength, set () {} });
window.open的測試程式碼。其中呼叫了內部ipc,用js找到了ipcRenderer通道。
w.webContents.executeJavaScript
D:\dev\electron7\src\electron\spec-main\chromium-spec.ts
describe('window.open', () => { it('denies custom open when nativeWindowOpen: true', async () => { const w = new BrowserWindow({ show: false, webPreferences: { contextIsolation: false, nodeIntegration: true, nativeWindowOpen: true } }); w.loadURL('about:blank'); const previousListeners = process.listeners('uncaughtException'); process.removeAllListeners('uncaughtException'); try { const uncaughtException = new Promise<Error>(resolve => { process.once('uncaughtException', resolve); }); expect(await w.webContents.executeJavaScript(`(${function () { const ipc = process.electronBinding('ipc').ipc; return ipc.sendSync(true, 'ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_OPEN', ['', '', ''])[0]; }})()`)).to.be.null('null'); const exception = await uncaughtException; expect(exception.message).to.match(/denied: expected native window\.open/); } finally { previousListeners.forEach(l => process.on('uncaughtException', l)); } }); }); })