diff --git a/lib/browser/api/browser-window.js b/lib/browser/api/browser-window.js index 8d5bc8444999..d27573659ba1 100644 --- a/lib/browser/api/browser-window.js +++ b/lib/browser/api/browser-window.js @@ -1,9 +1,8 @@ 'use strict' const electron = require('electron') -const {ipcMain, WebContentsView, TopLevelWindow} = electron +const {WebContentsView, TopLevelWindow} = electron const {BrowserWindow} = process.atomBinding('window') -const v8Util = process.atomBinding('v8_util') Object.setPrototypeOf(BrowserWindow.prototype, TopLevelWindow.prototype) @@ -17,67 +16,6 @@ BrowserWindow.prototype._init = function () { // Create WebContentsView. this.setContentView(new WebContentsView(this.webContents)) - // Make new windows requested by links behave like "window.open" - this.webContents.on('-new-window', (event, url, frameName, disposition, - additionalFeatures, postData, - referrer) => { - const options = { - show: true, - width: 800, - height: 600 - } - ipcMain.emit('ELECTRON_GUEST_WINDOW_MANAGER_INTERNAL_WINDOW_OPEN', - event, url, referrer, frameName, disposition, - options, additionalFeatures, postData) - }) - - this.webContents.on('-web-contents-created', (event, webContents, url, - frameName) => { - v8Util.setHiddenValue(webContents, 'url-framename', {url, frameName}) - }) - - // Create a new browser window for the native implementation of - // "window.open", used in sandbox and nativeWindowOpen mode - this.webContents.on('-add-new-contents', (event, webContents, disposition, - userGesture, left, top, width, - height) => { - let urlFrameName = v8Util.getHiddenValue(webContents, 'url-framename') - if ((disposition !== 'foreground-tab' && disposition !== 'new-window' && - disposition !== 'background-tab') || !urlFrameName) { - event.preventDefault() - return - } - - if (webContents.getLastWebPreferences().nodeIntegration === true) { - const message = - 'Enabling Node.js integration in child windows opened with the ' + - '"nativeWindowOpen" option will cause memory leaks, please turn off ' + - 'the "nodeIntegration" option.\\n' + - 'See https://github.com/electron/electron/pull/15076 for more.' - // console is only available after DOM is created. - const printWarning = () => this.webContents.executeJavaScript(`console.warn('${message}')`) - if (this.webContents.isDomReady()) { - printWarning() - } else { - this.webContents.once('dom-ready', printWarning) - } - } - - let {url, frameName} = urlFrameName - v8Util.deleteHiddenValue(webContents, 'url-framename') - const options = { - show: true, - x: left, - y: top, - width: width || 800, - height: height || 600, - webContents: webContents - } - const referrer = { url: '', policy: 'default' } - ipcMain.emit('ELECTRON_GUEST_WINDOW_MANAGER_INTERNAL_WINDOW_OPEN', - event, url, referrer, frameName, disposition, options) - }) - // window.resizeTo(...) // window.moveTo(...) this.webContents.on('move', (event, size) => { diff --git a/lib/browser/api/web-contents.js b/lib/browser/api/web-contents.js index 8f5bd037b14d..433fd3338222 100644 --- a/lib/browser/api/web-contents.js +++ b/lib/browser/api/web-contents.js @@ -5,6 +5,7 @@ const electron = require('electron') const path = require('path') const url = require('url') const {app, ipcMain, session, NavigationController, deprecate} = electron +const v8Util = process.atomBinding('v8_util') // session is not used here, the purpose is to make sure session is initalized // before the webContents module. @@ -313,6 +314,79 @@ WebContents.prototype._init = function () { this.reload() }) + // Handle window.open for BrowserWindow and BrowserView. + if (['browserView', 'window'].includes(this.getType())) { + // Make new windows requested by links behave like "window.open" + this.on('-new-window', (event, url, frameName, disposition, + additionalFeatures, postData, + referrer) => { + const options = { + show: true, + width: 800, + height: 600 + } + ipcMain.emit('ELECTRON_GUEST_WINDOW_MANAGER_INTERNAL_WINDOW_OPEN', + event, url, referrer, frameName, disposition, + options, additionalFeatures, postData) + }) + + this.on('-web-contents-created', (event, webContents, url, + frameName) => { + v8Util.setHiddenValue(webContents, 'url-framename', { + url, + frameName + }) + }) + + // Create a new browser window for the native implementation of + // "window.open", used in sandbox and nativeWindowOpen mode + this.on('-add-new-contents', (event, webContents, disposition, + userGesture, left, top, width, + height) => { + let urlFrameName = v8Util.getHiddenValue(webContents, 'url-framename') + if ((disposition !== 'foreground-tab' && disposition !== 'new-window' && + disposition !== 'background-tab') || !urlFrameName) { + event.preventDefault() + return + } + + if (webContents.getLastWebPreferences().nodeIntegration === true) { + const message = + 'Enabling Node.js integration in child windows opened with the ' + + '"nativeWindowOpen" option will cause memory leaks, please turn off ' + + 'the "nodeIntegration" option.\\n' + + 'See https://github.com/electron/electron/pull/15076 for more.' + // console is only available after DOM is created. + const printWarning = () => this.webContents.executeJavaScript(`console.warn('${message}')`) + if (this.webContents.isDomReady()) { + printWarning() + } else { + this.webContents.once('dom-ready', printWarning) + } + } + + let { + url, + frameName + } = urlFrameName + v8Util.deleteHiddenValue(webContents, 'url-framename') + const options = { + show: true, + x: left, + y: top, + width: width || 800, + height: height || 600, + webContents: webContents + } + const referrer = { + url: '', + policy: 'default' + } + ipcMain.emit('ELECTRON_GUEST_WINDOW_MANAGER_INTERNAL_WINDOW_OPEN', + event, url, referrer, frameName, disposition, options) + }) + } + app.emit('web-contents-created', {}, this) }