diff --git a/filenames.auto.gni b/filenames.auto.gni index 5d899c4bda72d..6bc1b2ae5b50f 100644 --- a/filenames.auto.gni +++ b/filenames.auto.gni @@ -166,6 +166,7 @@ auto_filenames = { "lib/renderer/web-view/web-view-element.ts", "lib/renderer/web-view/web-view-impl.ts", "lib/renderer/web-view/web-view-init.ts", + "lib/renderer/window-setup.ts", "lib/sandboxed_renderer/api/exports/electron.js", "lib/sandboxed_renderer/api/module-list.js", "lib/sandboxed_renderer/init.js", diff --git a/lib/browser/guest-window-manager.js b/lib/browser/guest-window-manager.js index 52e5439dbfd99..423ec357012e8 100644 --- a/lib/browser/guest-window-manager.js +++ b/lib/browser/guest-window-manager.js @@ -75,8 +75,10 @@ const mergeBrowserWindowOptions = function (embedder, options) { } } - // Sets correct openerId here to give correct options to 'new-window' event handler - options.webPreferences.openerId = embedder.id + if (!webPreferences.nativeWindowOpen) { + // Sets correct openerId here to give correct options to 'new-window' event handler + options.webPreferences.openerId = embedder.id + } return options } diff --git a/lib/browser/rpc-server.js b/lib/browser/rpc-server.js index 4fb062d974a77..2c06bf4f0ba45 100644 --- a/lib/browser/rpc-server.js +++ b/lib/browser/rpc-server.js @@ -529,12 +529,15 @@ ipcMainUtils.handle('ELECTRON_GET_CONTENT_SCRIPTS', () => getContentScripts()) ipcMainUtils.handle('ELECTRON_BROWSER_SANDBOX_LOAD', async function (event) { const preloadPaths = event.sender._getPreloadPaths() + const webPreferences = event.sender.getLastWebPreferences() || {} return { contentScripts: getContentScripts(), preloadScripts: await Promise.all(preloadPaths.map(path => getPreloadScript(path))), isRemoteModuleEnabled: isRemoteModuleEnabled(event.sender), isWebViewTagEnabled: guestViewManager.isWebViewTagEnabled(event.sender), + guestInstanceId: webPreferences.guestInstanceId, + openerId: webPreferences.openerId, process: { arch: process.arch, platform: process.platform, diff --git a/lib/renderer/window-setup.ts b/lib/renderer/window-setup.ts index 49b6a8ba59999..a98bc4248cd98 100644 --- a/lib/renderer/window-setup.ts +++ b/lib/renderer/window-setup.ts @@ -177,7 +177,7 @@ class BrowserWindowProxy { export const windowSetup = ( guestInstanceId: number, openerId: number, isHiddenPage: boolean, usesNativeWindowOpen: boolean ) => { - if (guestInstanceId == null) { + if (!process.sandboxed && guestInstanceId == null) { // Override default window.close. window.close = function () { ipcRendererInternal.sendSync('ELECTRON_BROWSER_WINDOW_CLOSE') @@ -197,10 +197,10 @@ export const windowSetup = ( return null } } + } - if (openerId != null) { - window.opener = getOrCreateProxy(openerId) - } + if (openerId != null) { + window.opener = getOrCreateProxy(openerId) } // But we do not support prompt(). @@ -208,42 +208,46 @@ export const windowSetup = ( throw new Error('prompt() is and will not be supported.') } - ipcRendererInternal.on('ELECTRON_GUEST_WINDOW_POSTMESSAGE', function ( - _event, sourceId: number, message: any, sourceOrigin: string - ) { - // Manually dispatch event instead of using postMessage because we also need to - // set event.source. - // - // Why any? We can't construct a MessageEvent and we can't - // use `as MessageEvent` because you're not supposed to override - // data, origin, and source - const event: any = document.createEvent('Event') - event.initEvent('message', false, false) - - event.data = message - event.origin = sourceOrigin - event.source = getOrCreateProxy(sourceId) - - window.dispatchEvent(event as MessageEvent) - }) - - window.history.back = function () { - ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_BACK') + if (!usesNativeWindowOpen || openerId != null) { + ipcRendererInternal.on('ELECTRON_GUEST_WINDOW_POSTMESSAGE', function ( + _event, sourceId: number, message: any, sourceOrigin: string + ) { + // Manually dispatch event instead of using postMessage because we also need to + // set event.source. + // + // Why any? We can't construct a MessageEvent and we can't + // use `as MessageEvent` because you're not supposed to override + // data, origin, and source + const event: any = document.createEvent('Event') + event.initEvent('message', false, false) + + event.data = message + event.origin = sourceOrigin + event.source = getOrCreateProxy(sourceId) + + window.dispatchEvent(event as MessageEvent) + }) } - window.history.forward = function () { - ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_FORWARD') - } + if (!process.sandboxed) { + window.history.back = function () { + ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_BACK') + } - window.history.go = function (offset: number) { - ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_TO_OFFSET', +offset) - } + window.history.forward = function () { + ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_FORWARD') + } - Object.defineProperty(window.history, 'length', { - get: function () { - return ipcRendererInternal.sendSync('ELECTRON_NAVIGATION_CONTROLLER_LENGTH') + window.history.go = function (offset: number) { + ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_TO_OFFSET', +offset) } - }) + + Object.defineProperty(window.history, 'length', { + get: function () { + return ipcRendererInternal.sendSync('ELECTRON_NAVIGATION_CONTROLLER_LENGTH') + } + }) + } if (guestInstanceId != null) { // Webview `document.visibilityState` tracks window visibility (and ignores diff --git a/lib/sandboxed_renderer/init.js b/lib/sandboxed_renderer/init.js index 6573d48b52eff..5247841224087 100644 --- a/lib/sandboxed_renderer/init.js +++ b/lib/sandboxed_renderer/init.js @@ -30,7 +30,13 @@ const { ipcRendererInternal } = require('@electron/internal/renderer/ipc-rendere const ipcRendererUtils = require('@electron/internal/renderer/ipc-renderer-internal-utils') const { - contentScripts, preloadScripts, isRemoteModuleEnabled, isWebViewTagEnabled, process: processProps + contentScripts, + preloadScripts, + isRemoteModuleEnabled, + isWebViewTagEnabled, + guestInstanceId, + openerId, + process: processProps } = ipcRendererUtils.invokeSync('ELECTRON_BROWSER_SANDBOX_LOAD') process.isRemoteModuleEnabled = isRemoteModuleEnabled @@ -109,6 +115,11 @@ function preloadRequire (module) { const { hasSwitch } = process.electronBinding('command_line') const contextIsolation = hasSwitch('context-isolation') +const isHiddenPage = hasSwitch('hidden-page') +const usesNativeWindowOpen = true + +// The arguments to be passed to isolated world. +const isolatedWorldArgs = { ipcRendererInternal, guestInstanceId, isHiddenPage, openerId, usesNativeWindowOpen } switch (window.location.protocol) { case 'devtools:': { @@ -125,19 +136,26 @@ switch (window.location.protocol) { break } default: { + // Override default web functions. + const { windowSetup } = require('@electron/internal/renderer/window-setup') + windowSetup(guestInstanceId, openerId, isHiddenPage, usesNativeWindowOpen) + // Inject content scripts. require('@electron/internal/renderer/content-scripts-injector')(contentScripts) } } -const guestInstanceId = binding.guestInstanceId && parseInt(binding.guestInstanceId) - // Load webview tag implementation. if (process.isMainFrame) { const { webViewInit } = require('@electron/internal/renderer/web-view/web-view-init') webViewInit(contextIsolation, isWebViewTagEnabled, guestInstanceId) } +// Pass the arguments to isolatedWorld. +if (contextIsolation) { + v8Util.setHiddenValue(global, 'isolated-world-args', isolatedWorldArgs) +} + const errorUtils = require('@electron/internal/common/error-utils') // Wrap the script into a function executed in global scope. It won't have diff --git a/shell/renderer/atom_sandboxed_renderer_client.cc b/shell/renderer/atom_sandboxed_renderer_client.cc index 12e0dc4e28974..85adc30e87f9c 100644 --- a/shell/renderer/atom_sandboxed_renderer_client.cc +++ b/shell/renderer/atom_sandboxed_renderer_client.cc @@ -144,12 +144,6 @@ void AtomSandboxedRendererClient::InitializeBindings( process.SetReadOnly("sandboxed", true); process.SetReadOnly("type", "renderer"); process.SetReadOnly("isMainFrame", is_main_frame); - - // Pass in CLI flags needed to setup the renderer - base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); - if (command_line->HasSwitch(switches::kGuestInstanceID)) - b.Set(options::kGuestInstanceID, - command_line->GetSwitchValueASCII(switches::kGuestInstanceID)); } void AtomSandboxedRendererClient::RenderFrameCreated(