Skip to content

Latest commit

 

History

History
127 lines (106 loc) · 5.79 KB

File metadata and controls

127 lines (106 loc) · 5.79 KB

Opening windows from the renderer

There are several ways to control how windows are created from trusted or untrusted content within a renderer. Windows can be created from the renderer in two ways:

  • clicking on links or submitting forms adorned with target=_blank
  • JavaScript calling window.open()

For same-site content, the new window is created within the same process, enabling the parent to access the child window directly. This can be very useful for app sub-windows that act as preference panels, or similar, as the parent can render to the sub-window directly, as if it were a div in the parent. This is the same behavior as in the browser.

Process-level webPreferences such as sandbox and nodeIntegration are baked into a renderer process when it launches, so a child window whose sandbox state differs from the opener's process cannot share it. In that case the child is created in a process of its own with no opener relationship: window.open() returns null in the opener and window.opener is null in the child. Child windows default to sandboxed, so a window.open() from an unsandboxed opener (for example one with nodeIntegration: true) is isolated like this by default. To keep such a child in the opener's process, explicitly set sandbox: false in the webPreferences returned from webContents.setWindowOpenHandler.

Electron pairs this native DOM Window with a BrowserWindow under the hood. You can take advantage of all the customization available when creating a BrowserWindow in the main process by using webContents.setWindowOpenHandler() for renderer-created windows.

BrowserWindow constructor options are set by, in increasing precedence order: parsed options from the features string from window.open(), security-related webPreferences inherited from the parent, and options given by webContents.setWindowOpenHandler. Note that webContents.setWindowOpenHandler has final say and full privilege because it is invoked in the main process.

window.open(url[, frameName][, features])

  • url string
  • frameName string (optional)
  • features string (optional)

Returns Window | null

features is a comma-separated key-value list, following the standard format of the browser. For convenience, Electron will parse a subset of presentational BrowserWindowConstructorOptions out of this list (such as width, height, x, y, show, frame, title, backgroundColor). Because the renderer is untrusted, options that cause the main process to access the filesystem or that are otherwise privileged (such as icon) are ignored. For full control and better ergonomics, use webContents.setWindowOpenHandler to customize the BrowserWindow creation from the main process.

A subset of WebPreferences can be set directly, unnested, from the features string: zoomFactor, nodeIntegration, javascript, contextIsolation, and webviewTag.

For example:

window.open('https://github.com', '_blank', 'top=500,left=200,frame=false,nodeIntegration=no')

Notes:

  • Node integration will always be disabled in the opened window if it is disabled on the parent window.
  • Context isolation will always be enabled in the opened window if it is enabled on the parent window.
  • JavaScript will always be disabled in the opened window if it is disabled on the parent window.
  • Features that are not handled by Chromium and not in Electron's allowlist of presentational BrowserWindowConstructorOptions are ignored. The raw features string is still available to the main process via setWindowOpenHandler.
  • frameName follows the specification of target located in the native documentation.
  • When opening about:blank, the child window's WebPreferences will be copied from the parent window, and there is no way to override it because Chromium skips browser side navigation in this case.

To customize or cancel the creation of the window, you can optionally set an override handler with webContents.setWindowOpenHandler() from the main process. Returning { action: 'deny' } cancels the window. Returning { action: 'allow', overrideBrowserWindowOptions: { ... } } will allow opening the window and setting the BrowserWindowConstructorOptions to be used when creating the window. Note that this is more powerful than passing options through the feature string, as the renderer has more limited privileges in deciding security preferences than the main process.

In addition to passing in action and overrideBrowserWindowOptions, outlivesOpener can be passed like: { action: 'allow', outlivesOpener: true, overrideBrowserWindowOptions: { ... } }. If set to true, the newly created window will not close when the opener window closes. The default value is false.

Native Window example

// main.js
const mainWindow = new BrowserWindow()

// In this example, only windows with the `about:blank` url will be created.
// All other urls will be blocked.
mainWindow.webContents.setWindowOpenHandler(({ url }) => {
  if (url === 'about:blank') {
    return {
      action: 'allow',
      overrideBrowserWindowOptions: {
        frame: false,
        fullscreenable: false,
        backgroundColor: 'black',
        webPreferences: {
          preload: 'my-child-window-preload-script.js'
        }
      }
    }
  }
  return { action: 'deny' }
})
// renderer process (mainWindow)
const childWindow = window.open('', 'modal')
childWindow.document.write('<h1>Hello</h1>')