diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index ee6ad94ba77a..4935adbc75ad 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -218,7 +218,8 @@ WebContents::WebContents(content::WebContents* web_contents) WebContents::WebContents(v8::Isolate* isolate, const mate::Dictionary& options) - : request_id_(0) { + : embedder_(nullptr), + request_id_(0) { // Whether it is a guest WebContents. bool is_guest = false; options.Get("isGuest", &is_guest); @@ -273,10 +274,10 @@ WebContents::WebContents(v8::Isolate* isolate, guest_delegate_->Initialize(this); NativeWindow* owner_window = nullptr; - WebContents* embedder = nullptr; - if (options.Get("embedder", &embedder) && embedder) { + if (options.Get("embedder", &embedder_) && embedder_) { // New WebContents's owner_window is the embedder's owner_window. - auto relay = NativeWindowRelay::FromWebContents(embedder->web_contents()); + auto relay = + NativeWindowRelay::FromWebContents(embedder_->web_contents()); if (relay) owner_window = relay->window.get(); } @@ -1116,6 +1117,12 @@ v8::Local WebContents::Session(v8::Isolate* isolate) { return v8::Local::New(isolate, session_); } +content::WebContents* WebContents::HostWebContents() { + if (!embedder_) + return nullptr; + return embedder_->web_contents(); +} + v8::Local WebContents::DevToolsWebContents(v8::Isolate* isolate) { if (devtools_web_contents_.IsEmpty()) return v8::Null(isolate); @@ -1199,6 +1206,7 @@ void WebContents::BuildPrototype(v8::Isolate* isolate, .SetMethod("addWorkSpace", &WebContents::AddWorkSpace) .SetMethod("removeWorkSpace", &WebContents::RemoveWorkSpace) .SetProperty("session", &WebContents::Session) + .SetProperty("hostWebContents", &WebContents::HostWebContents) .SetProperty("devToolsWebContents", &WebContents::DevToolsWebContents) .SetProperty("debugger", &WebContents::Debugger); } diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 63c4a0177716..b4f29090dbd3 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -147,6 +147,7 @@ class WebContents : public mate::TrackableObject, // Properties. v8::Local Session(v8::Isolate* isolate); + content::WebContents* HostWebContents(); v8::Local DevToolsWebContents(v8::Isolate* isolate); v8::Local Debugger(v8::Isolate* isolate); @@ -287,6 +288,9 @@ class WebContents : public mate::TrackableObject, scoped_ptr guest_delegate_; + // The host webcontents that may contain this webcontents. + WebContents* embedder_; + // The type of current WebContents. Type type_; diff --git a/atom/common/native_mate_converters/content_converter.cc b/atom/common/native_mate_converters/content_converter.cc index 699f101d0e4b..f5d81d085bc1 100644 --- a/atom/common/native_mate_converters/content_converter.cc +++ b/atom/common/native_mate_converters/content_converter.cc @@ -173,6 +173,8 @@ bool Converter::FromV8( // static v8::Local Converter::ToV8( v8::Isolate* isolate, content::WebContents* val) { + if (!val) + return v8::Null(isolate); return atom::api::WebContents::CreateFrom(isolate, val).ToV8(); } diff --git a/atom/renderer/lib/web-view/web-view.js b/atom/renderer/lib/web-view/web-view.js index 7e38bb33715a..44fc10421621 100644 --- a/atom/renderer/lib/web-view/web-view.js +++ b/atom/renderer/lib/web-view/web-view.js @@ -388,7 +388,7 @@ var registerWebViewElement = function() { 'downloadURL', 'inspectServiceWorker', 'print', - 'printToPDF' + 'printToPDF', ]; nonblockMethods = [ 'executeJavaScript', @@ -430,6 +430,12 @@ var registerWebViewElement = function() { proto[m] = createNonBlockHandler(m); } + // WebContents associated with this webview. + proto.getWebContents = function() { + var internal = v8Util.getHiddenValue(this, 'internal'); + return internal.webContents; + }; + // Deprecated. deprecate.rename(proto, 'getUrl', 'getURL'); window.WebView = webFrame.registerEmbedderCustomElement('webview', { diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index e0139a29fa6c..dde701d7f488 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -842,6 +842,10 @@ win.webContents.on('did-finish-load', function() { Returns the [session](session.md) object used by this webContents. +### `webContents.hostWebContents` + +Returns the `WebContents` that might own this `WebContents`. + ### `webContents.devToolsWebContents` Get the `WebContents` of DevTools for this `WebContents`. diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index b4f139d475ca..4a0697ad843d 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -438,6 +438,10 @@ Sends an input `event` to the page. See [webContents.sendInputEvent](web-contents.md##webcontentssendinputeventevent) for detailed description of `event` object. +### `.getWebContents()` + +Returns the [WebContents](web-contents.md) associated with this `webview`. + ## DOM events The following DOM events are available to the `webview` tag: diff --git a/spec/webview-spec.js b/spec/webview-spec.js index 54b544def0db..d73a177d0970 100644 --- a/spec/webview-spec.js +++ b/spec/webview-spec.js @@ -703,4 +703,17 @@ describe(' tag', function() { document.body.appendChild(webview); }); }); + + describe('.getWebContents', function() { + it('can return the webcontents associated', function(done) { + webview.addEventListener('did-finish-load', function() { + const webviewContents = webview.getWebContents(); + assert(webviewContents); + assert.equal(webviewContents.getURL(), 'about:blank'); + done(); + }); + webview.src = "about:blank"; + document.body.appendChild(webview); + }); + }); });