8000 fix: handle window.open events in BrowserView by Anrock · Pull Request #12686 · electron/electron · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

fix: handle window.open events in BrowserView #12686

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Nov 27, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion atom/browser/native_window_mac.mm
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,8 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) {
}

NativeWindowMac::~NativeWindowMac() {
[NSEvent removeMonitor:wheel_event_monitor_];
if (wheel_event_monitor_)
[NSEvent removeMonitor:wheel_event_monitor_];
}

void NativeWindowMac::SetContentView(views::View* view) {
Expand Down Expand Up @@ -517,6 +518,13 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) {
}

void NativeWindowMac::CloseImmediately() {
// Remove event monitor before destroying window, otherwise the monitor may
// call its callback after window has been destroyed.
if (wheel_event_monitor_) {
[NSEvent removeMonitor:wheel_event_monitor_];
wheel_event_monitor_ = nil;
}

// Retain the child window before closing it. If the last reference to the
// NSWindow goes away inside -[NSWindow close], then bad stuff can happen.
// See e.g. http://crbug.com/616701.
Expand Down
38 changes: 0 additions & 38 deletions lib/browser/api/browser-window.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
const electron = require('electron')
const { WebContentsView, TopLevelWindow } = electron
const { BrowserWindow } = process.atomBinding('window')
const ipcMain = require('@electron/internal/browser/ipc-main-internal')

Object.setPrototypeOf(BrowserWindow.prototype, TopLevelWindow.prototype)

Expand All @@ -26,43 +25,6 @@ BrowserWindow.prototype._init = function () {
nativeSetBounds.call(this, bounds, ...opts)
}

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

// 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, url, frameName) => {
if ((disposition !== 'foreground-tab' && disposition !== 'new-window' &&
disposition !== 'background-tab')) {
event.preventDefault()
return
}

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) => {
Expand Down
40 changes: 40 additions & 0 deletions lib/browser/api/web-contents.js
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,46 @@ 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
}
ipcMainInternal.emit('ELECTRON_GUEST_WINDOW_MANAGER_INTERNAL_WINDOW_OPEN',
event, url, referrer, frameName, disposition,
options, additionalFeatures, postData)
})

// 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, url, frameName) => {
if ((disposition !== 'foreground-tab' && disposition !== 'new-window' &&
disposition !== 'background-tab')) {
event.preventDefault()
return
}

const options = {
show: true,
x: left,
y: top,
width: width || 800,
height: height || 600,
webContents
}
const referrer = { url: '', policy: 'default' }
ipcMainInternal.emit('ELECTRON_GUEST_WINDOW_MANAGER_INTERNAL_WINDOW_OPEN',
event, url, referrer, frameName, disposition, options)
})
}

app.emit('web-contents-created', {}, this)
}

Expand Down
20 changes: 19 additions & 1 deletion spec/api-browser-view-spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use strict'

const assert = require('assert')
const chai = require('chai')
const ChildProcess = require('child_process')
const dirtyChai = require('dirty-chai')
Expand All @@ -14,6 +15,8 @@ const { expect } = chai
chai.use(dirtyChai)

describe('BrowserView module', () => {
const fixtures = path.resolve(__dirname, 'fixtures')

let w = null
let view = null

Expand Down Expand Up @@ -178,11 +181,26 @@ describe('BrowserView module', () => {

describe('new BrowserView()', () => {
it('does not crash on exit', async () => {
const appPath = path.join(__dirname, 'fixtures', 'api', 'leak-exit-browserview.js')
const appPath = path.join(fixtures, 'api', 'leak-exit-browserview.js')
const electronPath = remote.getGlobal('process').execPath
const appProcess = ChildProcess.spawn(electronPath, [appPath])
const [code] = await emittedOnce(appProcess, 'close')
expect(code).to.equal(0)
})
})

describe('window.open()', () => {
it('works in BrowserView', (done) => {
view = new BrowserView()
w.setBrowserView(view)
view.webContents.once('new-window', (e, url, frameName, disposition, options, additionalFeatures) => {
e.preventDefault()
assert.strictEqual(url, 'http://host/')
assert.strictEqual(frameName, 'host')
assert.strictEqual(additionalFeatures[0], 'this-is-not-a-standard-feature')
done()
})
view.webContents.loadFile(path.join(fixtures, 'pages', 'window-open.html'))
})
})
})
0