From 5ba6eb0b692a1c16aadccf928a456f32d1473574 Mon Sep 17 00:00:00 2001 From: Samuel Maddock Date: Wed, 11 Dec 2024 23:42:41 -0500 Subject: [PATCH] feat: electron backwards compat --- .../spec/chrome-browserAction-spec.ts | 12 ++++++--- .../spec/crx-helpers.ts | 17 +++++++----- .../src/browser-action.ts | 11 +++++--- .../src/browser/index.ts | 27 +++++++++++-------- .../electron-chrome-extensions/src/preload.ts | 1 + .../src/renderer/index.ts | 11 +++++--- .../src/browser/index.ts | 12 ++++++++- packages/shell/browser/main.js | 15 +++++++---- 8 files changed, 73 insertions(+), 33 deletions(-) diff --git a/packages/electron-chrome-extensions/spec/chrome-browserAction-spec.ts b/packages/electron-chrome-extensions/spec/chrome-browserAction-spec.ts index 7e60c09e..6fb806d3 100644 --- a/packages/electron-chrome-extensions/spec/chrome-browserAction-spec.ts +++ b/packages/electron-chrome-extensions/spec/chrome-browserAction-spec.ts @@ -43,10 +43,14 @@ describe('chrome.browserAction', () => { it('supports cross-session communication', async () => { const otherSession = session.fromPartition(`persist:crx-${uuid()}`) - // TODO(mv3): remove any - ;(browser.session as any).getPreloadScripts().forEach((script) => { - ;(otherSession as any).registerPreloadScript(script) - }) + if ('registerPreloadScript' in otherSession) { + // TODO(mv3): remove any + ;(browser.session as any).getPreloadScripts().forEach((script: any) => { + ;(otherSession as any).registerPreloadScript(script) + }) + } else { + otherSession.setPreloads(browser.session.getPreloads()) + } const view = new BrowserView({ webPreferences: { session: otherSession, nodeIntegration: false, contextIsolation: true }, diff --git a/packages/electron-chrome-extensions/spec/crx-helpers.ts b/packages/electron-chrome-extensions/spec/crx-helpers.ts index 05e46c13..80f9c65e 100644 --- a/packages/electron-chrome-extensions/spec/crx-helpers.ts +++ b/packages/electron-chrome-extensions/spec/crx-helpers.ts @@ -14,12 +14,17 @@ export const createCrxSession = () => { } export const addCrxPreload = (session: Electron.Session) => { - // TODO(mv3): remove any - (session as any).registerPreloadScript({ - id: 'crx-test-preload', - type: 'frame', - filePath: path.join(__dirname, 'fixtures', 'crx-test-preload.js') - }) + const preloadPath = path.join(__dirname, 'fixtures', 'crx-test-preload.js') + if ('registerPreloadScript' in session) { + // TODO(mv3): remove any + ;(session as any).registerPreloadScript({ + id: 'crx-test-preload', + type: 'frame', + filePath: preloadPath, + }) + } else { + session.setPreloads([...session.getPreloads(), preloadPath]) + } } export const createCrxRemoteWindow = () => { diff --git a/packages/electron-chrome-extensions/src/browser-action.ts b/packages/electron-chrome-extensions/src/browser-action.ts index 935841a4..1ccd8ec2 100644 --- a/packages/electron-chrome-extensions/src/browser-action.ts +++ b/packages/electron-chrome-extensions/src/browser-action.ts @@ -405,9 +405,14 @@ export const injectBrowserAction = () => { contextBridge.exposeInMainWorld('browserAction', __browserAction__) // Must execute script in main world to modify custom component registry. - ;(contextBridge as any).executeInMainWorld({ - func: mainWorldScript, - }) + if ('executeInMainWorld' in contextBridge) { + ;(contextBridge as any).executeInMainWorld({ + func: mainWorldScript, + }) + } else { + // TODO(mv3): remove webFrame usage + webFrame.executeJavaScript(`(${mainWorldScript}());`) + } } else { // When contextIsolation is disabled, contextBridge will throw an error. // If that's the case, we're in the main world so we can just execute our diff --git a/packages/electron-chrome-extensions/src/browser/index.ts b/packages/electron-chrome-extensions/src/browser/index.ts index 8653c764..d4403a9e 100644 --- a/packages/electron-chrome-extensions/src/browser/index.ts +++ b/packages/electron-chrome-extensions/src/browser/index.ts @@ -104,18 +104,23 @@ export class ElectronChromeExtensions extends EventEmitter { private async prependPreload() { const { session } = this.ctx - // TODO(mv3): remove 'any' const preloadPath = path.join(this.modulePath, 'dist/preload.js') - ;(session as any).registerPreloadScript({ - id: 'crx-mv2-preload', - type: 'frame', - filePath: preloadPath, - }) - ;(session as any).registerPreloadScript({ - id: 'crx-mv3-preload', - type: 'service-worker', - filePath: preloadPath, - }) + + if ('registerPreloadScript' in session) { + // TODO(mv3): remove 'any' + ;(session as any).registerPreloadScript({ + id: 'crx-mv2-preload', + type: 'frame', + filePath: preloadPath, + }) + ;(session as any).registerPreloadScript({ + id: 'crx-mv3-preload', + type: 'service-worker', + filePath: preloadPath, + }) + } else { + session.setPreloads([...session.getPreloads(), preloadPath]) + } let preloadExists = false try { diff --git a/packages/electron-chrome-extensions/src/preload.ts b/packages/electron-chrome-extensions/src/preload.ts index be8d5497..c80d6013 100644 --- a/packages/electron-chrome-extensions/src/preload.ts +++ b/packages/electron-chrome-extensions/src/preload.ts @@ -1,6 +1,7 @@ import { injectExtensionAPIs } from './renderer' // Only load within extension page context +// TODO(mv3): remove any if ((process as any).type === 'service-worker' || location.href.startsWith('chrome-extension://')) { injectExtensionAPIs() } diff --git a/packages/electron-chrome-extensions/src/renderer/index.ts b/packages/electron-chrome-extensions/src/renderer/index.ts index d406a86a..fdd3c399 100644 --- a/packages/electron-chrome-extensions/src/renderer/index.ts +++ b/packages/electron-chrome-extensions/src/renderer/index.ts @@ -545,9 +545,14 @@ export const injectExtensionAPIs = () => { contextBridge.exposeInMainWorld('electron', electronContext) // Mutate global 'chrome' object with additional APIs in the main world. - ;(contextBridge as any).executeInMainWorld({ - func: mainWorldScript, - }) + if ('executeInMainWorld' in contextBridge) { + ;(contextBridge as any).executeInMainWorld({ + func: mainWorldScript, + }) + } else { + // TODO(mv3): remove webFrame usage + webFrame.executeJavaScript(`(${mainWorldScript}());`) + } } catch (error) { console.error(`injectExtensionAPIs error (${location.href})`) console.error(error) diff --git a/packages/electron-chrome-web-store/src/browser/index.ts b/packages/electron-chrome-web-store/src/browser/index.ts index e31d2330..8db5be32 100644 --- a/packages/electron-chrome-web-store/src/browser/index.ts +++ b/packages/electron-chrome-web-store/src/browser/index.ts @@ -525,7 +525,17 @@ export function installChromeWebStore(opts: ElectronChromeWebStoreOptions = {}) // Add preload script to session const preloadPath = path.join(modulePath, 'dist/renderer/web-store-preload.js') - session.setPreloads([...session.getPreloads(), preloadPath]) + + if ('registerPreloadScript' in session) { + ;(session as any).registerPreloadScript({ + id: 'electron-chrome-web-store', + type: 'frame', + filePath: preloadPath, + }) + } else { + // TODO(mv3): remove + session.setPreloads([...session.getPreloads(), preloadPath]) + } addIpcListeners(webStoreState) diff --git a/packages/shell/browser/main.js b/packages/shell/browser/main.js index 14bc5ebe..173e6abb 100644 --- a/packages/shell/browser/main.js +++ b/packages/shell/browser/main.js @@ -126,11 +126,16 @@ class Browser { this.initSession() setupMenu(this) - this.session.registerPreloadScript({ - id: 'shell-preload', - type: 'frame', - filePath: PATHS.PRELOAD, - }) + if ('registerPreloadScript' in this.session) { + this.session.registerPreloadScript({ + id: 'shell-preload', + type: 'frame', + filePath: PATHS.PRELOAD, + }) + } else { + // TODO(mv3): remove + this.session.setPreloads([PATHS.PRELOAD]) + } this.extensions = new ElectronChromeExtensions({ license: 'internal-license-do-not-use',