diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index 323a80cc8a25..c3869c07fea7 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -525,6 +525,7 @@ void App::OnLogin(LoginHandler* login_handler, void App::OnCreateWindow(const GURL& target_url, const std::string& frame_name, WindowOpenDisposition disposition, + const std::vector& features, int render_process_id, int render_frame_id) { v8::Locker locker(isolate()); @@ -535,7 +536,10 @@ void App::OnCreateWindow(const GURL& target_url, content::WebContents::FromRenderFrameHost(rfh); if (web_contents) { auto api_web_contents = WebContents::CreateFrom(isolate(), web_contents); - api_web_contents->OnCreateWindow(target_url, frame_name, disposition); + api_web_contents->OnCreateWindow(target_url, + frame_name, + disposition, + features); } } diff --git a/atom/browser/api/atom_api_app.h b/atom/browser/api/atom_api_app.h index c2afb15232ec..b11c68077560 100644 --- a/atom/browser/api/atom_api_app.h +++ b/atom/browser/api/atom_api_app.h @@ -6,6 +6,7 @@ #define ATOM_BROWSER_API_ATOM_API_APP_H_ #include +#include #include "atom/browser/api/event_emitter.h" #include "atom/browser/atom_browser_client.h" @@ -50,6 +51,7 @@ class App : public AtomBrowserClient::Delegate, void OnCreateWindow(const GURL& target_url, const std::string& frame_name, WindowOpenDisposition disposition, + const std::vector& features, int render_process_id, int render_frame_id); diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 8b84b74f59d4..6e4a5131a9b0 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -416,11 +416,12 @@ bool WebContents::AddMessageToConsole(content::WebContents* source, void WebContents::OnCreateWindow(const GURL& target_url, const std::string& frame_name, - WindowOpenDisposition disposition) { + WindowOpenDisposition disposition, + const std::vector& features) { if (type_ == BROWSER_WINDOW || type_ == OFF_SCREEN) - Emit("-new-window", target_url, frame_name, disposition); + Emit("-new-window", target_url, frame_name, disposition, features); else - Emit("new-window", target_url, frame_name, disposition); + Emit("new-window", target_url, frame_name, disposition, features); } void WebContents::WebContentsCreated(content::WebContents* source_contents, diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index d0dceb1a98f0..c7b92f54727d 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -178,7 +178,8 @@ class WebContents : public mate::TrackableObject, // Create window with the given disposition. void OnCreateWindow(const GURL& target_url, const std::string& frame_name, - WindowOpenDisposition disposition); + WindowOpenDisposition disposition, + const std::vector& features); // Returns the web preferences of current WebContents. v8::Local GetWebPreferences(v8::Isolate* isolate); diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index 4ab09523dcb5..685d2700d79a 100644 --- a/atom/browser/atom_browser_client.cc +++ b/atom/browser/atom_browser_client.cc @@ -318,6 +318,7 @@ bool AtomBrowserClient::CanCreateWindow( const content::Referrer& referrer, WindowOpenDisposition disposition, const blink::WebWindowFeatures& features, + const std::vector& additional_features, bool user_gesture, bool opener_suppressed, content::ResourceContext* context, @@ -339,6 +340,7 @@ bool AtomBrowserClient::CanCreateWindow( target_url, frame_name, disposition, + additional_features, render_process_id, opener_render_frame_id)); } diff --git a/atom/browser/atom_browser_client.h b/atom/browser/atom_browser_client.h index b6e928ce8e69..37ed898be9ce 100644 --- a/atom/browser/atom_browser_client.h +++ b/atom/browser/atom_browser_client.h @@ -88,6 +88,7 @@ class AtomBrowserClient : public brightray::BrowserClient, const content::Referrer& referrer, WindowOpenDisposition disposition, const blink::WebWindowFeatures& features, + const std::vector& additional_features, bool user_gesture, bool opener_suppressed, content::ResourceContext* context, diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 2a9664f747c1..ec1003f2d894 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -147,6 +147,8 @@ Returns: `new-window`, `save-to-disk` and `other`. * `options` Object - The options which will be used for creating the new `BrowserWindow`. +* `additionalFeatures` Array - The non-standard features (features not handled + by Chromium or Electron) given to `window.open()`. Emitted when the page requests to open a new window for a `url`. It could be requested by `window.open` or an external link like ``. diff --git a/docs/api/window-open.md b/docs/api/window-open.md index 0ecb9f60598e..cbe3aed23029 100644 --- a/docs/api/window-open.md +++ b/docs/api/window-open.md @@ -25,8 +25,12 @@ Returns `BrowserWindowProxy` - Creates a new window and returns an instance of ` The `features` string follows the format of standard browser, but each feature has to be a field of `BrowserWindow`'s options. -**Note:** Node integration will always be disabled in the opened `window` if it -is disabled on the parent window. +**Notes:** +* Node integration will always be disabled in the opened `window` if it is + disabled on the parent window. +* Non-standard features (that are not handled by Chromium or Electron) given in + `features` will be passed to any registered `webContent`'s `new-window` event + handler in the `additionalFeatures` argument. ### `window.opener.postMessage(message, targetOrigin)` diff --git a/lib/browser/api/browser-window.js b/lib/browser/api/browser-window.js index 920d2404432e..237d655b8a66 100644 --- a/lib/browser/api/browser-window.js +++ b/lib/browser/api/browser-window.js @@ -18,13 +18,13 @@ BrowserWindow.prototype._init = function () { } // Make new windows requested by links behave like "window.open" - this.webContents.on('-new-window', (event, url, frameName, disposition) => { + this.webContents.on('-new-window', (event, url, frameName, disposition, additionalFeatures) => { const options = { show: true, width: 800, height: 600 } - ipcMain.emit('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_OPEN', event, url, frameName, disposition, options) + ipcMain.emit('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_OPEN', event, url, frameName, disposition, options, additionalFeatures) }) this.webContents.on('-web-contents-created', (event, webContents, url, diff --git a/lib/browser/guest-window-manager.js b/lib/browser/guest-window-manager.js index f20f1bbb0ab9..92a807ae8196 100644 --- a/lib/browser/guest-window-manager.js +++ b/lib/browser/guest-window-manager.js @@ -135,9 +135,9 @@ const getGuestWindow = function (guestId) { } // Routed window.open messages. -ipcMain.on('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_OPEN', function (event, url, frameName, disposition, options) { +ipcMain.on('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_OPEN', function (event, url, frameName, disposition, options, additionalFeatures) { options = mergeBrowserWindowOptions(event.sender, options) - event.sender.emit('new-window', event, url, frameName, disposition, options) + event.sender.emit('new-window', event, url, frameName, disposition, options, additionalFeatures) if ((event.sender.isGuest() && !event.sender.allowPopups) || event.defaultPrevented) { event.returnValue = null } else { diff --git a/lib/renderer/override.js b/lib/renderer/override.js index 29cf9f5acaec..9358a06a09d6 100644 --- a/lib/renderer/override.js +++ b/lib/renderer/override.js @@ -88,7 +88,7 @@ if (process.guestInstanceId == null) { // Make the browser window or guest view emit "new-window" event. window.open = function (url, frameName, features) { - var feature, guestId, i, j, len, len1, name, options, ref1, ref2, value + var feature, guestId, i, j, len, len1, name, options, ref1, ref2, value, additionalFeatures if (frameName == null) { frameName = '' } @@ -101,6 +101,9 @@ window.open = function (url, frameName, features) { const webPreferences = ['zoomFactor', 'nodeIntegration', 'preload'] const disposition = 'new-window' + // Used to store additional features + additionalFeatures = [] + // Make sure to get rid of excessive whitespace in the property name ref1 = features.split(/,\s*/) for (i = 0, len = ref1.length; i < len; i++) { @@ -109,13 +112,17 @@ window.open = function (url, frameName, features) { name = ref2[0] value = ref2[1] value = value === 'yes' || value === '1' ? true : value === 'no' || value === '0' ? false : value - if (webPreferences.includes(name)) { - if (options.webPreferences == null) { - options.webPreferences = {} - } - options.webPreferences[name] = value + if (value === undefined) { + additionalFeatures.push(feature) } else { - options[name] = value + if (webPreferences.includes(name)) { + if (options.webPreferences == null) { + options.webPreferences = {} + } + options.webPreferences[name] = value + } else { + options[name] = value + } } } if (options.left) { @@ -150,7 +157,7 @@ window.open = function (url, frameName, features) { options[name] = parseInt(options[name], 10) } } - guestId = ipcRenderer.sendSync('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_OPEN', url, frameName, disposition, options) + guestId = ipcRenderer.sendSync('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_OPEN', url, frameName, disposition, options, additionalFeatures) if (guestId) { return BrowserWindowProxy.getOrCreate(guestId) } else { diff --git a/script/lib/config.py b/script/lib/config.py index 344f7606a3a4..0dd486b370b8 100644 --- a/script/lib/config.py +++ b/script/lib/config.py @@ -9,7 +9,7 @@ import sys BASE_URL = os.getenv('LIBCHROMIUMCONTENT_MIRROR') or \ 'https://s3.amazonaws.com/github-janky-artifacts/libchromiumcontent' LIBCHROMIUMCONTENT_COMMIT = os.getenv('LIBCHROMIUMCONTENT_COMMIT') or \ - '63b939087a4a8170a82c8caf0f6e9cfcf234472b' + '292bc81e83686ae5e7125163290928bf9b839560' PLATFORM = { 'cygwin': 'win32',