1. 程式人生 > 實用技巧 >electron中重寫js 內建函式 需要重新核心編譯

electron中重寫js 內建函式 需要重新核心編譯

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));
      }
    });
  });
})