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);
|
||||
InitWithWebContents(web_contents);
|
||||
|
||||
// Save the preferences.
|
||||
// Save the preferences in C++.
|
||||
base::DictionaryValue web_preferences;
|
||||
mate::ConvertFromV8(isolate, options.GetHandle(), &web_preferences);
|
||||
new WebContentsPreferences(web_contents, &web_preferences);
|
||||
|
@ -887,6 +887,12 @@ bool WebContents::IsGuest() const {
|
|||
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(
|
||||
v8::Isolate* isolate) {
|
||||
if (template_.IsEmpty())
|
||||
|
@ -942,6 +948,7 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder(
|
|||
.SetMethod("setSize", &WebContents::SetSize)
|
||||
.SetMethod("setAllowTransparency", &WebContents::SetAllowTransparency)
|
||||
.SetMethod("isGuest", &WebContents::IsGuest)
|
||||
.SetMethod("getWebPreferences", &WebContents::GetWebPreferences)
|
||||
.SetMethod("hasServiceWorker", &WebContents::HasServiceWorker)
|
||||
.SetMethod("unregisterServiceWorker",
|
||||
&WebContents::UnregisterServiceWorker)
|
||||
|
@ -995,7 +1002,7 @@ mate::Handle<WebContents> WebContents::CreateFrom(
|
|||
// static
|
||||
mate::Handle<WebContents> WebContents::Create(
|
||||
v8::Isolate* isolate, const mate::Dictionary& options) {
|
||||
auto handle = mate::CreateHandle(isolate, new WebContents(isolate, options));
|
||||
auto handle = mate::CreateHandle(isolate, new WebContents(isolate, options));
|
||||
g_wrap_web_contents.Run(handle.ToV8());
|
||||
return handle;
|
||||
}
|
||||
|
|
|
@ -132,6 +132,9 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
|||
void SetAllowTransparency(bool allow);
|
||||
bool IsGuest() const;
|
||||
|
||||
// Returns the web preferences of current WebContents.
|
||||
v8::Local<v8::Value> GetWebPreferences(v8::Isolate* isolate);
|
||||
|
||||
protected:
|
||||
explicit WebContents(content::WebContents* web_contents);
|
||||
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());
|
||||
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.
|
||||
window_.reset(NativeWindow::Create(web_contents->managed_web_contents(),
|
||||
options));
|
||||
|
|
|
@ -4,6 +4,17 @@ BrowserWindow = require 'browser-window'
|
|||
|
||||
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|.
|
||||
createGuest = (embedder, url, frameName, options) ->
|
||||
guest = frameToGuest[frameName]
|
||||
|
@ -11,7 +22,7 @@ createGuest = (embedder, url, frameName, options) ->
|
|||
guest.loadUrl url
|
||||
return guest.id
|
||||
|
||||
guest = new BrowserWindow(options)
|
||||
guest = new BrowserWindow(mergeBrowserWindowOptions(embedder, options))
|
||||
guest.loadUrl url
|
||||
|
||||
# Remember the embedder, will be used by window.opener methods.
|
||||
|
|
|
@ -40,6 +40,9 @@ WebContentsPreferences::WebContentsPreferences(
|
|||
base::DictionaryValue* web_preferences) {
|
||||
web_preferences_.Swap(web_preferences);
|
||||
web_contents->SetUserData(UserDataKey(), this);
|
||||
|
||||
// The "isGuest" is not a preferences field.
|
||||
web_preferences_.Remove("isGuest", nullptr);
|
||||
}
|
||||
|
||||
WebContentsPreferences::~WebContentsPreferences() {
|
||||
|
|
|
@ -37,6 +37,9 @@ class WebContentsPreferences
|
|||
// $.extend(|web_preferences_|, |new_web_preferences|).
|
||||
void Merge(const base::DictionaryValue& new_web_preferences);
|
||||
|
||||
// Returns the web preferences.
|
||||
base::DictionaryValue* web_preferences() { return &web_preferences_; }
|
||||
|
||||
private:
|
||||
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
|
||||
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])`
|
||||
|
||||
* `url` String
|
||||
|
@ -16,6 +20,9 @@ you should create a `BrowserWindow` directly.
|
|||
|
||||
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)`
|
||||
|
||||
* `message` String
|
||||
|
|
|
@ -35,6 +35,8 @@ describe 'chromium feature', ->
|
|||
assert.notEqual navigator.language, ''
|
||||
|
||||
describe 'window.open', ->
|
||||
@timeout 10000
|
||||
|
||||
it 'returns a BrowserWindowProxy object', ->
|
||||
b = window.open 'about:blank', '', 'show=no'
|
||||
assert.equal b.closed, false
|
||||
|
@ -50,6 +52,16 @@ describe 'chromium feature', ->
|
|||
window.addEventListener 'message', listener
|
||||
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', ->
|
||||
@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