diff --git a/atom/browser/api/atom_api_web_contents_view.cc b/atom/browser/api/atom_api_web_contents_view.cc index 2b9443ba2a41..a96f4a9c8d6c 100644 --- a/atom/browser/api/atom_api_web_contents_view.cc +++ b/atom/browser/api/atom_api_web_contents_view.cc @@ -6,6 +6,7 @@ #include "atom/browser/api/atom_api_web_contents.h" #include "brightray/browser/inspectable_web_contents_view.h" +#include "content/public/browser/web_contents_user_data.h" #include "native_mate/dictionary.h" #if defined(OS_MACOSX) @@ -14,6 +15,27 @@ #include "atom/common/node_includes.h" +namespace { + +// Used to indicate whether a WebContents already has a view. +class WebContentsViewRelay + : public content::WebContentsUserData { + public: + ~WebContentsViewRelay() override {} + + private: + explicit WebContentsViewRelay(content::WebContents* contents) {} + friend class content::WebContentsUserData; + + atom::api::WebContentsView* view_ = nullptr; + + DISALLOW_COPY_AND_ASSIGN(WebContentsViewRelay); +}; + +} // namespace + +DEFINE_WEB_CONTENTS_USER_DATA_KEY(WebContentsViewRelay); + namespace atom { namespace api { @@ -36,6 +58,7 @@ WebContentsView::WebContentsView(v8::Isolate* isolate, // On other platforms the View is managed by InspectableWebContents. set_delete_view(false); #endif + WebContentsViewRelay::CreateForWebContents(web_contents->web_contents()); api_web_contents_->AddObserver(this); } @@ -52,12 +75,23 @@ void WebContentsView::OnCloseContents() { mate::WrappableBase* WebContentsView::New( mate::Arguments* args, mate::Handle web_contents) { + // Currently we only support InspectableWebContents, e.g. the WebContents + // created by users directly. To support devToolsWebContents we need to create + // a wrapper view. if (!web_contents->managed_web_contents()) { const char* error = "The WebContents must be created by user"; args->isolate()->ThrowException( v8::Exception::Error(mate::StringToV8(args->isolate(), error))); return nullptr; } + // Check if the WebContents has already been added to a view. + if (WebContentsViewRelay::FromWebContents(web_contents->web_contents())) { + const char* error = "The WebContents has already been added to a View"; + args->isolate()->ThrowException( + v8::Exception::Error(mate::StringToV8(args->isolate(), error))); + return nullptr; + } + // Constructor call. auto* view = new WebContentsView(args->isolate(), web_contents, web_contents->managed_web_contents()); view->InitWith(args->isolate(), args->GetThis());