refactor: expose ipcRendererInternal to the main world for window-setup using the content script world pattern (#17591)

This commit is contained in:
Milan Burda 2019-03-30 02:10:21 +01:00 committed by Samuel Attard
parent b8dbe4bc15
commit d597a0e8b0
4 changed files with 30 additions and 32 deletions

View file

@ -24,9 +24,9 @@ Object.setPrototypeOf(process, EventEmitter.prototype)
const isolatedWorldArgs = v8Util.getHiddenValue(isolatedWorld, 'isolated-world-args') const isolatedWorldArgs = v8Util.getHiddenValue(isolatedWorld, 'isolated-world-args')
if (isolatedWorldArgs) { if (isolatedWorldArgs) {
const { ipcRendererInternal, guestInstanceId, isHiddenPage, openerId, usesNativeWindowOpen } = isolatedWorldArgs const { guestInstanceId, isHiddenPage, openerId, usesNativeWindowOpen } = isolatedWorldArgs
const { windowSetup } = require('@electron/internal/renderer/window-setup') const { windowSetup } = require('@electron/internal/renderer/window-setup')
windowSetup(ipcRendererInternal, guestInstanceId, openerId, isHiddenPage, usesNativeWindowOpen) windowSetup(guestInstanceId, openerId, isHiddenPage, usesNativeWindowOpen)
} }
const extensionId = v8Util.getHiddenValue(isolatedWorld, `extension-${worldId}`) const extensionId = v8Util.getHiddenValue(isolatedWorld, `extension-${worldId}`)

View file

@ -2,9 +2,13 @@
/* global nodeProcess, isolatedWorld */ /* global nodeProcess, isolatedWorld */
const electronBinding = require('@electron/internal/common/atom-binding-setup').electronBindingSetup(nodeProcess.binding, 'renderer') process.electronBinding = require('@electron/internal/common/atom-binding-setup').electronBindingSetup(nodeProcess.binding, 'renderer')
const v8Util = electronBinding('v8_util') const v8Util = process.electronBinding('v8_util')
// The `lib/renderer/ipc-renderer-internal.js` module looks for the ipc object in the
// "ipc-internal" hidden value
v8Util.setHiddenValue(global, 'ipc-internal', v8Util.getHiddenValue(isolatedWorld, 'ipc-internal'))
const webViewImpl = v8Util.getHiddenValue(isolatedWorld, 'web-view-impl') const webViewImpl = v8Util.getHiddenValue(isolatedWorld, 'web-view-impl')
@ -17,7 +21,7 @@ if (webViewImpl) {
const isolatedWorldArgs = v8Util.getHiddenValue(isolatedWorld, 'isolated-world-args') const isolatedWorldArgs = v8Util.getHiddenValue(isolatedWorld, 'isolated-world-args')
if (isolatedWorldArgs) { if (isolatedWorldArgs) {
const { ipcRendererInternal, guestInstanceId, isHiddenPage, openerId, usesNativeWindowOpen } = isolatedWorldArgs const { guestInstanceId, isHiddenPage, openerId, usesNativeWindowOpen } = isolatedWorldArgs
const { windowSetup } = require('@electron/internal/renderer/window-setup') const { windowSetup } = require('@electron/internal/renderer/window-setup')
windowSetup(ipcRendererInternal, guestInstanceId, openerId, isHiddenPage, usesNativeWindowOpen) windowSetup(guestInstanceId, openerId, isHiddenPage, usesNativeWindowOpen)
} }

View file

@ -82,7 +82,7 @@ switch (window.location.protocol) {
default: { default: {
// Override default web functions. // Override default web functions.
const { windowSetup } = require('@electron/internal/renderer/window-setup') const { windowSetup } = require('@electron/internal/renderer/window-setup')
windowSetup(ipcRendererInternal, guestInstanceId, openerId, isHiddenPage, usesNativeWindowOpen) windowSetup(guestInstanceId, openerId, isHiddenPage, usesNativeWindowOpen)
// Inject content scripts. // Inject content scripts.
require('@electron/internal/renderer/content-scripts-injector')(process.getRenderProcessPreferences) require('@electron/internal/renderer/content-scripts-injector')(process.getRenderProcessPreferences)

View file

@ -1,6 +1,4 @@
// This file should have no requires since it is used by the isolated context import { ipcRendererInternal } from '@electron/internal/renderer/ipc-renderer-internal'
// preload bundle. Instead arguments should be passed in for everything it
// needs.
// This file implements the following APIs: // This file implements the following APIs:
// - window.history.back() // - window.history.back()
@ -37,10 +35,10 @@ const toString = (value: any) => {
const windowProxies: Record<number, BrowserWindowProxy> = {} const windowProxies: Record<number, BrowserWindowProxy> = {}
const getOrCreateProxy = (ipcRenderer: Electron.IpcRenderer, guestId: number) => { const getOrCreateProxy = (guestId: number) => {
let proxy = windowProxies[guestId] let proxy = windowProxies[guestId]
if (proxy == null) { if (proxy == null) {
proxy = new BrowserWindowProxy(ipcRenderer, guestId) proxy = new BrowserWindowProxy(guestId)
windowProxies[guestId] = proxy windowProxies[guestId] = proxy
} }
return proxy return proxy
@ -63,7 +61,6 @@ class LocationProxy {
@LocationProxy.ProxyProperty public protocol!: string; @LocationProxy.ProxyProperty public protocol!: string;
@LocationProxy.ProxyProperty public search!: URLSearchParams; @LocationProxy.ProxyProperty public search!: URLSearchParams;
private ipcRenderer: Electron.IpcRenderer;
private guestId: number; private guestId: number;
/** /**
@ -92,11 +89,10 @@ class LocationProxy {
}) })
} }
constructor (ipcRenderer: Electron.IpcRenderer, guestId: number) { constructor (guestId: number) {
// eslint will consider the constructor "useless" // eslint will consider the constructor "useless"
// unless we assign them in the body. It's fine, that's what // unless we assign them in the body. It's fine, that's what
// TS would do anyway. // TS would do anyway.
this.ipcRenderer = ipcRenderer
this.guestId = guestId this.guestId = guestId
this.getGuestURL = this.getGuestURL.bind(this) this.getGuestURL = this.getGuestURL.bind(this)
} }
@ -106,7 +102,7 @@ class LocationProxy {
} }
private getGuestURL (): URL | null { private getGuestURL (): URL | null {
const urlString = this.ipcRenderer.sendSync('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD_SYNC', this.guestId, 'getURL') const urlString = ipcRendererInternal.sendSync('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD_SYNC', this.guestId, 'getURL')
try { try {
return new URL(urlString) return new URL(urlString)
} catch (e) { } catch (e) {
@ -122,7 +118,6 @@ class BrowserWindowProxy {
private _location: LocationProxy private _location: LocationProxy
private guestId: number private guestId: number
private ipcRenderer: Electron.IpcRenderer
// TypeScript doesn't allow getters/accessors with different types, // TypeScript doesn't allow getters/accessors with different types,
// so for now, we'll have to make do with an "any" in the mix. // so for now, we'll have to make do with an "any" in the mix.
@ -132,47 +127,46 @@ class BrowserWindowProxy {
} }
public set location (url: string | any) { public set location (url: string | any) {
url = resolveURL(url) url = resolveURL(url)
this.ipcRenderer.sendSync('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD_SYNC', this.guestId, 'loadURL', url) ipcRendererInternal.sendSync('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD_SYNC', this.guestId, 'loadURL', url)
} }
constructor (ipcRenderer: Electron.IpcRenderer, guestId: number) { constructor (guestId: number) {
this.guestId = guestId this.guestId = guestId
this.ipcRenderer = ipcRenderer this._location = new LocationProxy(guestId)
this._location = new LocationProxy(ipcRenderer, guestId)
ipcRenderer.once(`ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_CLOSED_${guestId}`, () => { ipcRendererInternal.once(`ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_CLOSED_${guestId}`, () => {
removeProxy(guestId) removeProxy(guestId)
this.closed = true this.closed = true
}) })
} }
public close () { public close () {
this.ipcRenderer.send('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_CLOSE', this.guestId) ipcRendererInternal.send('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_CLOSE', this.guestId)
} }
public focus () { public focus () {
this.ipcRenderer.send('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_METHOD', this.guestId, 'focus') ipcRendererInternal.send('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_METHOD', this.guestId, 'focus')
} }
public blur () { public blur () {
this.ipcRenderer.send('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_METHOD', this.guestId, 'blur') ipcRendererInternal.send('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_METHOD', this.guestId, 'blur')
} }
public print () { public print () {
this.ipcRenderer.send('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', this.guestId, 'print') ipcRendererInternal.send('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', this.guestId, 'print')
} }
public postMessage (message: any, targetOrigin: any) { public postMessage (message: any, targetOrigin: any) {
this.ipcRenderer.send('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', this.guestId, message, toString(targetOrigin), window.location.origin) ipcRendererInternal.send('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', this.guestId, message, toString(targetOrigin), window.location.origin)
} }
public eval (...args: any[]) { public eval (...args: any[]) {
this.ipcRenderer.send('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', this.guestId, 'executeJavaScript', ...args) ipcRendererInternal.send('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', this.guestId, 'executeJavaScript', ...args)
} }
} }
export const windowSetup = ( export const windowSetup = (
ipcRendererInternal: Electron.IpcRendererInternal, guestInstanceId: number, openerId: number, isHiddenPage: boolean, usesNativeWindowOpen: boolean guestInstanceId: number, openerId: number, isHiddenPage: boolean, usesNativeWindowOpen: boolean
) => { ) => {
if (guestInstanceId == null) { if (guestInstanceId == null) {
// Override default window.close. // Override default window.close.
@ -189,14 +183,14 @@ export const windowSetup = (
} }
const guestId = ipcRendererInternal.sendSync('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_OPEN', url, toString(frameName), toString(features)) const guestId = ipcRendererInternal.sendSync('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_OPEN', url, toString(frameName), toString(features))
if (guestId != null) { if (guestId != null) {
return getOrCreateProxy(ipcRendererInternal, guestId) return getOrCreateProxy(guestId)
} else { } else {
return null return null
} }
} }
if (openerId != null) { if (openerId != null) {
window.opener = getOrCreateProxy(ipcRendererInternal, openerId) window.opener = getOrCreateProxy(openerId)
} }
} }
@ -219,7 +213,7 @@ export const windowSetup = (
event.data = message event.data = message
event.origin = sourceOrigin event.origin = sourceOrigin
event.source = getOrCreateProxy(ipcRendererInternal, sourceId) event.source = getOrCreateProxy(sourceId)
window.dispatchEvent(event as MessageEvent) window.dispatchEvent(event as MessageEvent)
}) })