|
@@ -57,7 +57,30 @@ const createGuest = function (embedder, url, frameName, options) {
|
|
|
}
|
|
|
options.webPreferences.openerId = embedder.id
|
|
|
guest = new BrowserWindow(options)
|
|
|
- guest.loadURL(url)
|
|
|
+ if (!options.webContents || url !== 'about:blank') {
|
|
|
+ // We should not call `loadURL` if the window was constructed from an
|
|
|
+ // existing webContents(window.open in a sandboxed renderer) and if the url
|
|
|
+ // is not 'about:blank'.
|
|
|
+ //
|
|
|
+ // Navigating to the url when creating the window from an existing
|
|
|
+ // webContents would not be necessary(it will navigate there anyway), but
|
|
|
+ // apparently there's a bug that allows the child window to be scripted by
|
|
|
+ // the opener, even when the child window is from another origin.
|
|
|
+ //
|
|
|
+ // That's why the second condition(url !== "about:blank") is required: to
|
|
|
+ // force `OverrideSiteInstanceForNavigation` to be called and consequently
|
|
|
+ // spawn a new renderer if the new window is targeting a different origin.
|
|
|
+ //
|
|
|
+ // If the URL is "about:blank", then it is very likely that the opener just
|
|
|
+ // wants to synchronously script the popup, for example:
|
|
|
+ //
|
|
|
+ // let popup = window.open()
|
|
|
+ // popup.document.body.write('<h1>hello</h1>')
|
|
|
+ //
|
|
|
+ // The above code would not work if a navigation to "about:blank" is done
|
|
|
+ // here, since the window would be cleared of all changes in the next tick.
|
|
|
+ guest.loadURL(url)
|
|
|
+ }
|
|
|
|
|
|
// When |embedder| is destroyed we should also destroy attached guest, and if
|
|
|
// guest is closed by user then we should prevent |embedder| from double
|
|
@@ -72,8 +95,19 @@ const createGuest = function (embedder, url, frameName, options) {
|
|
|
embedder.send('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_CLOSED_' + guestId)
|
|
|
embedder.removeListener('render-view-deleted', closedByEmbedder)
|
|
|
}
|
|
|
- embedder.once('render-view-deleted', closedByEmbedder)
|
|
|
- guest.once('closed', closedByUser)
|
|
|
+ if (!options.webPreferences.sandbox) {
|
|
|
+ // These events should only be handled when the guest window is opened by a
|
|
|
+ // non-sandboxed renderer for two reasons:
|
|
|
+ //
|
|
|
+ // - `render-view-deleted` is emitted when the popup is closed by the user,
|
|
|
+ // and that will eventually result in NativeWindow::NotifyWindowClosed
|
|
|
+ // using a dangling pointer since `destroy()` would have been called by
|
|
|
+ // `closeByEmbedded`
|
|
|
+ // - No need to emit `ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_CLOSED_` since
|
|
|
+ // there's no renderer code listening to it.,
|
|
|
+ embedder.once('render-view-deleted', closedByEmbedder)
|
|
|
+ guest.once('closed', closedByUser)
|
|
|
+ }
|
|
|
|
|
|
if (frameName) {
|
|
|
frameToGuest[frameName] = guest
|