Merge pull request #2869 from atom/inherit-window-open
Inherit parent window's options in window.open
This commit is contained in:
commit
d0d71efb0b
9 changed files with 61 additions and 3 deletions
|
@ -228,7 +228,7 @@ WebContents::WebContents(v8::Isolate* isolate,
|
||||||
AttachAsUserData(web_contents);
|
AttachAsUserData(web_contents);
|
||||||
InitWithWebContents(web_contents);
|
InitWithWebContents(web_contents);
|
||||||
|
|
||||||
// Save the preferences.
|
// Save the preferences in C++.
|
||||||
base::DictionaryValue web_preferences;
|
base::DictionaryValue web_preferences;
|
||||||
mate::ConvertFromV8(isolate, options.GetHandle(), &web_preferences);
|
mate::ConvertFromV8(isolate, options.GetHandle(), &web_preferences);
|
||||||
new WebContentsPreferences(web_contents, &web_preferences);
|
new WebContentsPreferences(web_contents, &web_preferences);
|
||||||
|
@ -887,6 +887,12 @@ bool WebContents::IsGuest() const {
|
||||||
return type_ == WEB_VIEW;
|
return type_ == WEB_VIEW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
v8::Local<v8::Value> WebContents::GetWebPreferences(v8::Isolate* isolate) {
|
||||||
|
WebContentsPreferences* web_preferences =
|
||||||
|
WebContentsPreferences::FromWebContents(web_contents());
|
||||||
|
return mate::ConvertToV8(isolate, *web_preferences->web_preferences());
|
||||||
|
}
|
||||||
|
|
||||||
mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder(
|
mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder(
|
||||||
v8::Isolate* isolate) {
|
v8::Isolate* isolate) {
|
||||||
if (template_.IsEmpty())
|
if (template_.IsEmpty())
|
||||||
|
@ -942,6 +948,7 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder(
|
||||||
.SetMethod("setSize", &WebContents::SetSize)
|
.SetMethod("setSize", &WebContents::SetSize)
|
||||||
.SetMethod("setAllowTransparency", &WebContents::SetAllowTransparency)
|
.SetMethod("setAllowTransparency", &WebContents::SetAllowTransparency)
|
||||||
.SetMethod("isGuest", &WebContents::IsGuest)
|
.SetMethod("isGuest", &WebContents::IsGuest)
|
||||||
|
.SetMethod("getWebPreferences", &WebContents::GetWebPreferences)
|
||||||
.SetMethod("hasServiceWorker", &WebContents::HasServiceWorker)
|
.SetMethod("hasServiceWorker", &WebContents::HasServiceWorker)
|
||||||
.SetMethod("unregisterServiceWorker",
|
.SetMethod("unregisterServiceWorker",
|
||||||
&WebContents::UnregisterServiceWorker)
|
&WebContents::UnregisterServiceWorker)
|
||||||
|
|
|
@ -132,6 +132,9 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||||
void SetAllowTransparency(bool allow);
|
void SetAllowTransparency(bool allow);
|
||||||
bool IsGuest() const;
|
bool IsGuest() const;
|
||||||
|
|
||||||
|
// Returns the web preferences of current WebContents.
|
||||||
|
v8::Local<v8::Value> GetWebPreferences(v8::Isolate* isolate);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit WebContents(content::WebContents* web_contents);
|
explicit WebContents(content::WebContents* web_contents);
|
||||||
WebContents(v8::Isolate* isolate, const mate::Dictionary& options);
|
WebContents(v8::Isolate* isolate, const mate::Dictionary& options);
|
||||||
|
|
|
@ -82,6 +82,10 @@ Window::Window(v8::Isolate* isolate, const mate::Dictionary& options) {
|
||||||
web_contents_.Reset(isolate, web_contents.ToV8());
|
web_contents_.Reset(isolate, web_contents.ToV8());
|
||||||
api_web_contents_ = web_contents.get();
|
api_web_contents_ = web_contents.get();
|
||||||
|
|
||||||
|
// Keep a copy of the options for later use.
|
||||||
|
mate::Dictionary(isolate, web_contents->GetWrapper(isolate)).Set(
|
||||||
|
"browserWindowOptions", options);
|
||||||
|
|
||||||
// Creates BrowserWindow.
|
// Creates BrowserWindow.
|
||||||
window_.reset(NativeWindow::Create(web_contents->managed_web_contents(),
|
window_.reset(NativeWindow::Create(web_contents->managed_web_contents(),
|
||||||
options));
|
options));
|
||||||
|
|
|
@ -4,6 +4,17 @@ BrowserWindow = require 'browser-window'
|
||||||
|
|
||||||
frameToGuest = {}
|
frameToGuest = {}
|
||||||
|
|
||||||
|
# Merge |options| with the |embedder|'s window's options.
|
||||||
|
mergeBrowserWindowOptions = (embedder, options) ->
|
||||||
|
if embedder.browserWindowOptions?
|
||||||
|
# Inherit the original options if it is a BrowserWindow.
|
||||||
|
options.__proto__ = embedder.browserWindowOptions
|
||||||
|
else
|
||||||
|
# Or only inherit web-preferences if it is a webview.
|
||||||
|
options['web-preferences'] ?= {}
|
||||||
|
options['web-preferences'].__proto__ = embedder.getWebPreferences()
|
||||||
|
options
|
||||||
|
|
||||||
# Create a new guest created by |embedder| with |options|.
|
# Create a new guest created by |embedder| with |options|.
|
||||||
createGuest = (embedder, url, frameName, options) ->
|
createGuest = (embedder, url, frameName, options) ->
|
||||||
guest = frameToGuest[frameName]
|
guest = frameToGuest[frameName]
|
||||||
|
@ -11,7 +22,7 @@ createGuest = (embedder, url, frameName, options) ->
|
||||||
guest.loadUrl url
|
guest.loadUrl url
|
||||||
return guest.id
|
return guest.id
|
||||||
|
|
||||||
guest = new BrowserWindow(options)
|
guest = new BrowserWindow(mergeBrowserWindowOptions(embedder, options))
|
||||||
guest.loadUrl url
|
guest.loadUrl url
|
||||||
|
|
||||||
# Remember the embedder, will be used by window.opener methods.
|
# Remember the embedder, will be used by window.opener methods.
|
||||||
|
|
|
@ -40,6 +40,9 @@ WebContentsPreferences::WebContentsPreferences(
|
||||||
base::DictionaryValue* web_preferences) {
|
base::DictionaryValue* web_preferences) {
|
||||||
web_preferences_.Swap(web_preferences);
|
web_preferences_.Swap(web_preferences);
|
||||||
web_contents->SetUserData(UserDataKey(), this);
|
web_contents->SetUserData(UserDataKey(), this);
|
||||||
|
|
||||||
|
// The "isGuest" is not a preferences field.
|
||||||
|
web_preferences_.Remove("isGuest", nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
WebContentsPreferences::~WebContentsPreferences() {
|
WebContentsPreferences::~WebContentsPreferences() {
|
||||||
|
|
|
@ -37,6 +37,9 @@ class WebContentsPreferences
|
||||||
// $.extend(|web_preferences_|, |new_web_preferences|).
|
// $.extend(|web_preferences_|, |new_web_preferences|).
|
||||||
void Merge(const base::DictionaryValue& new_web_preferences);
|
void Merge(const base::DictionaryValue& new_web_preferences);
|
||||||
|
|
||||||
|
// Returns the web preferences.
|
||||||
|
base::DictionaryValue* web_preferences() { return &web_preferences_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class content::WebContentsUserData<WebContentsPreferences>;
|
friend class content::WebContentsUserData<WebContentsPreferences>;
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,10 @@ The proxy has limited standard functionality implemented to be
|
||||||
compatible with traditional web pages. For full control of the new window
|
compatible with traditional web pages. For full control of the new window
|
||||||
you should create a `BrowserWindow` directly.
|
you should create a `BrowserWindow` directly.
|
||||||
|
|
||||||
|
The newly created `BrowserWindow` will inherit parent window's options by
|
||||||
|
default, to override inherited options you can set them in the `features`
|
||||||
|
string.
|
||||||
|
|
||||||
### `window.open(url[, frameName][, features])`
|
### `window.open(url[, frameName][, features])`
|
||||||
|
|
||||||
* `url` String
|
* `url` String
|
||||||
|
@ -16,6 +20,9 @@ you should create a `BrowserWindow` directly.
|
||||||
|
|
||||||
Creates a new window and returns an instance of `BrowserWindowProxy` class.
|
Creates a new window and returns an instance of `BrowserWindowProxy` class.
|
||||||
|
|
||||||
|
The `features` string follows the format of standard browser, but each feature
|
||||||
|
has to be a field of `BrowserWindow`'s options.
|
||||||
|
|
||||||
### `window.opener.postMessage(message, targetOrigin)`
|
### `window.opener.postMessage(message, targetOrigin)`
|
||||||
|
|
||||||
* `message` String
|
* `message` String
|
||||||
|
|
|
@ -35,6 +35,8 @@ describe 'chromium feature', ->
|
||||||
assert.notEqual navigator.language, ''
|
assert.notEqual navigator.language, ''
|
||||||
|
|
||||||
describe 'window.open', ->
|
describe 'window.open', ->
|
||||||
|
@timeout 10000
|
||||||
|
|
||||||
it 'returns a BrowserWindowProxy object', ->
|
it 'returns a BrowserWindowProxy object', ->
|
||||||
b = window.open 'about:blank', '', 'show=no'
|
b = window.open 'about:blank', '', 'show=no'
|
||||||
assert.equal b.closed, false
|
assert.equal b.closed, false
|
||||||
|
@ -50,6 +52,16 @@ describe 'chromium feature', ->
|
||||||
window.addEventListener 'message', listener
|
window.addEventListener 'message', listener
|
||||||
b = window.open "file://#{fixtures}/pages/window-opener-node.html", '', 'node-integration=no,show=no'
|
b = window.open "file://#{fixtures}/pages/window-opener-node.html", '', 'node-integration=no,show=no'
|
||||||
|
|
||||||
|
it 'inherit options of parent window', (done) ->
|
||||||
|
listener = (event) ->
|
||||||
|
window.removeEventListener 'message', listener
|
||||||
|
b.close()
|
||||||
|
size = remote.getCurrentWindow().getSize()
|
||||||
|
assert.equal event.data, "size: #{size.width} #{size.height}"
|
||||||
|
done()
|
||||||
|
window.addEventListener 'message', listener
|
||||||
|
b = window.open "file://#{fixtures}/pages/window-open-size.html", '', 'show=no'
|
||||||
|
|
||||||
describe 'window.opener', ->
|
describe 'window.opener', ->
|
||||||
@timeout 10000
|
@timeout 10000
|
||||||
|
|
||||||
|
|
8
spec/fixtures/pages/window-open-size.html
vendored
Normal file
8
spec/fixtures/pages/window-open-size.html
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<script type="text/javascript" charset="utf-8">
|
||||||
|
var size = require('remote').getCurrentWindow().getSize();
|
||||||
|
window.opener.postMessage('size: ' + size.width + ' ' + size.height, '*')
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in a new issue