fix: move open handling to web-contents.js (#16637)

This commit is contained in:
trop[bot] 2019-01-30 19:48:54 -08:00 committed by Shelley Vohr
parent d89d8f51b9
commit f40f9b06f8
2 changed files with 75 additions and 63 deletions

View file

@ -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) => {

View file

@ -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)
}