diff --git a/atom.gyp b/atom.gyp index 12d1bb1eb1..86cb4e1ced 100644 --- a/atom.gyp +++ b/atom.gyp @@ -181,8 +181,6 @@ 'atom/browser/ui/win/notify_icon.h', 'atom/browser/ui/x/x_window_utils.cc', 'atom/browser/ui/x/x_window_utils.h', - 'atom/browser/web_view/web_view_guest.cc', - 'atom/browser/web_view/web_view_guest.h', 'atom/browser/web_view/web_view_manager.cc', 'atom/browser/web_view/web_view_manager.h', 'atom/browser/window_list.cc', diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 62f4bacd2f..678483779b 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -44,6 +44,7 @@ WebContents::WebContents(const mate::Dictionary& options) params.guest_delegate = this; storage_.reset(content::WebContents::Create(params)); + storage_->SetDelegate(this); Observe(storage_.get()); } @@ -94,6 +95,9 @@ bool WebContents::OnMessageReceived(const IPC::Message& message) { return handled; } +void WebContents::RenderViewReady() { +} + void WebContents::WebContentsDestroyed() { // The RenderViewDeleted was not called when the WebContents is destroyed. RenderViewDeleted(web_contents()->GetRenderViewHost()); @@ -105,6 +109,12 @@ void WebContents::WillAttach(content::WebContents* embedder_web_contents, LOG(ERROR) << "WillAttach"; } +content::WebContents* WebContents::CreateNewGuestWindow( + const content::WebContents::CreateParams& create_params) { + LOG(ERROR) << "CreateNewGuestWindow"; + return nullptr; +} + void WebContents::DidAttach() { LOG(ERROR) << "DidAttach"; } @@ -137,6 +147,7 @@ void WebContents::RegisterDestructionCallback( } void WebContents::Destroy() { + LOG(ERROR) << "Destroy"; if (storage_) { if (!destruction_callback_.is_null()) destruction_callback_.Run(); diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 7734fee18a..433d67deb2 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -7,6 +7,7 @@ #include "atom/browser/api/event_emitter.h" #include "content/public/browser/browser_plugin_guest_delegate.h" +#include "content/public/browser/web_contents_delegate.h" #include "content/public/browser/web_contents_observer.h" #include "native_mate/handle.h" @@ -20,6 +21,7 @@ namespace api { class WebContents : public mate::EventEmitter, public content::BrowserPluginGuestDelegate, + public content::WebContentsDelegate, public content::WebContentsObserver { public: // Create from an existing WebContents. @@ -54,6 +56,10 @@ class WebContents : public mate::EventEmitter, bool SendIPCMessage(const base::string16& channel, const base::ListValue& args); + content::WebContents* web_contents() const { + return content::WebContentsObserver::web_contents(); + } + protected: explicit WebContents(content::WebContents* web_contents); explicit WebContents(const mate::Dictionary& options); @@ -61,35 +67,38 @@ class WebContents : public mate::EventEmitter, // mate::Wrappable: virtual mate::ObjectTemplateBuilder GetObjectTemplateBuilder( - v8::Isolate* isolate) OVERRIDE; + v8::Isolate* isolate) override; // content::WebContentsObserver: - virtual void RenderViewDeleted(content::RenderViewHost*) OVERRIDE; - virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE; + virtual void RenderViewDeleted(content::RenderViewHost*) override; + virtual void RenderProcessGone(base::TerminationStatus status) override; virtual void DidFinishLoad(content::RenderFrameHost* render_frame_host, - const GURL& validated_url) OVERRIDE; + const GURL& validated_url) override; virtual void DidStartLoading( - content::RenderViewHost* render_view_host) OVERRIDE; + content::RenderViewHost* render_view_host) override; virtual void DidStopLoading( - content::RenderViewHost* render_view_host) OVERRIDE; - virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; - virtual void WebContentsDestroyed() OVERRIDE; + content::RenderViewHost* render_view_host) override; + virtual bool OnMessageReceived(const IPC::Message& message) override; + virtual void RenderViewReady() override; + virtual void WebContentsDestroyed() override; // content::BrowserPluginGuestDelegate: virtual void WillAttach(content::WebContents* embedder_web_contents, - const base::DictionaryValue& extra_params) final; - virtual void DidAttach() final; - virtual int GetGuestInstanceID() const final; + const base::DictionaryValue& extra_params) override; + virtual content::WebContents* CreateNewGuestWindow( + const content::WebContents::CreateParams& create_params) override; + virtual void DidAttach() override; + virtual int GetGuestInstanceID() const override; virtual void ElementSizeChanged(const gfx::Size& old_size, - const gfx::Size& new_size) final; + const gfx::Size& new_size) override; virtual void GuestSizeChanged(const gfx::Size& old_size, - const gfx::Size& new_size) final; + const gfx::Size& new_size) override; virtual void RequestPointerLockPermission( bool user_gesture, bool last_unlocked_by_target, - const base::Callback& callback) final; + const base::Callback& callback) override; virtual void RegisterDestructionCallback( - const DestructionCallback& callback) final; + const DestructionCallback& callback) override; private: // Called when received a message from renderer. diff --git a/atom/browser/atom_browser_context.h b/atom/browser/atom_browser_context.h index 71a023cea5..4ed5e1c3bb 100644 --- a/atom/browser/atom_browser_context.h +++ b/atom/browser/atom_browser_context.h @@ -22,9 +22,6 @@ class AtomBrowserContext : public brightray::BrowserContext { // Returns the browser context singleton. static AtomBrowserContext* Get(); - AtomURLRequestJobFactory* job_factory() const { return job_factory_; } - - protected: // brightray::URLRequestContextGetter::Delegate: virtual net::URLRequestJobFactory* CreateURLRequestJobFactory( content::ProtocolHandlerMap* handlers, @@ -33,6 +30,8 @@ class AtomBrowserContext : public brightray::BrowserContext { // content::BrowserContext: virtual content::BrowserPluginGuestManager* GetGuestManager() override; + AtomURLRequestJobFactory* job_factory() const { return job_factory_; } + private: // A fake BrowserProcess object that used to feed the source code from chrome. scoped_ptr fake_browser_process_; diff --git a/atom/browser/default_app/default_app.js b/atom/browser/default_app/default_app.js index ee5e5733e1..269821d2a3 100644 --- a/atom/browser/default_app/default_app.js +++ b/atom/browser/default_app/default_app.js @@ -18,6 +18,9 @@ app.on('ready', function() { resizable: false, 'auto-hide-menu-bar': true, 'use-content-size': true, + 'web-preferences': { + 'plugins': true, + }, }); mainWindow.loadUrl('file://' + __dirname + '/index.html'); mainWindow.focus(); diff --git a/atom/browser/lib/guest-view-manager.coffee b/atom/browser/lib/guest-view-manager.coffee index b462f11042..c57c0382fa 100644 --- a/atom/browser/lib/guest-view-manager.coffee +++ b/atom/browser/lib/guest-view-manager.coffee @@ -1,5 +1,6 @@ ipc = require 'ipc' webContents = require 'web-contents' +webViewManager = null # Doesn't exist in early initialization. nextInstanceId = 0 guestInstances = {} @@ -10,17 +11,24 @@ getNextInstanceId = (webContents) -> # Create a new guest instance. createGuest = (embedder, params) -> + webViewManager ?= process.atomBinding 'web_view_manager' + id = getNextInstanceId embedder - guestInstances[id] = webContents.create isGuest: true, guestInstanceId: id + guestInstances[id] = webContents.create + isGuest: true + guestInstanceId: id + storagePartitionId: params.storagePartitionId + webViewManager.addGuest id, embedder, guestInstances[id] id # Destroy an existing guest instance. destroyGuest = (id) -> + webViewManager.removeGuest id guestInstances[id].destroy() delete guestInstances[id] ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_CREATE_GUEST', (event, type, params, requestId) -> - event.sender.send "ATOM_SHELL_RESPONSE_#{requestId}", createGuest(event.sender) + event.sender.send "ATOM_SHELL_RESPONSE_#{requestId}", createGuest(event.sender, params) ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_DESTROY_GUEST', (event, guestInstanceId) -> destroyGuest guestInstanceId diff --git a/atom/browser/web_view/web_view_guest.cc b/atom/browser/web_view/web_view_guest.cc deleted file mode 100644 index 37c14f7269..0000000000 --- a/atom/browser/web_view/web_view_guest.cc +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) 2014 GitHub, Inc. All rights reserved. -// Use of this source code is governed by the MIT license that can be -// found in the LICENSE file. - -#include "atom/browser/web_view/web_view_guest.h" - -namespace atom { - - - -} // namespace atom diff --git a/atom/browser/web_view/web_view_guest.h b/atom/browser/web_view/web_view_guest.h deleted file mode 100644 index 9696eca595..0000000000 --- a/atom/browser/web_view/web_view_guest.h +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) 2014 GitHub, Inc. All rights reserved. -// Use of this source code is governed by the MIT license that can be -// found in the LICENSE file. - -#ifndef ATOM_BROWSER_WEB_VIEW_WEB_VIEW_GUEST_H_ -#define ATOM_BROWSER_WEB_VIEW_WEB_VIEW_GUEST_H_ - -namespace atom { - -// A WebViewGuest provides the browser-side implementation of the API -// and manages the dispatch of extension events. WebViewGuest is -// created on attachment. That is, when a guest WebContents is associated with -// a particular embedder WebContents. This happens on either initial navigation -// or through the use of the New Window API, when a new window is attached to -// a particular . - -} // namespace atom - -#endif // ATOM_BROWSER_WEB_VIEW_WEB_VIEW_GUEST_H_ diff --git a/atom/browser/web_view/web_view_manager.cc b/atom/browser/web_view/web_view_manager.cc index 48e1b1fdf5..3b639c9adc 100644 --- a/atom/browser/web_view/web_view_manager.cc +++ b/atom/browser/web_view/web_view_manager.cc @@ -4,7 +4,30 @@ #include "atom/browser/web_view/web_view_manager.h" -#include "base/logging.h" +#include "atom/browser/api/atom_api_web_contents.h" +#include "atom/browser/atom_browser_context.h" +#include "base/bind.h" +#include "base/stl_util.h" +#include "native_mate/dictionary.h" +#include "native_mate/object_template_builder.h" + +#include "atom/common/node_includes.h" + +namespace mate { + +template<> +struct Converter { + static bool FromV8(v8::Isolate* isolate, v8::Handle val, + content::WebContents** out) { + atom::api::WebContents* contents; + if (!Converter::FromV8(isolate, val, &contents)) + return false; + *out = contents->web_contents(); + return true; + } +}; + +} // namespace mate namespace atom { @@ -14,18 +37,53 @@ WebViewManager::WebViewManager(content::BrowserContext* context) { WebViewManager::~WebViewManager() { } +void WebViewManager::AddGuest(int guest_instance_id, + content::WebContents* embedder, + content::WebContents* web_contents) { + web_contents_map_[guest_instance_id] = {web_contents, embedder}; +} + +void WebViewManager::RemoveGuest(int guest_instance_id) { + web_contents_map_.erase(guest_instance_id); +} + void WebViewManager::MaybeGetGuestByInstanceIDOrKill( int guest_instance_id, int embedder_render_process_id, const GuestByInstanceIDCallback& callback) { - LOG(ERROR) << "MaybeGetGuestByInstanceIDOrKill"; - callback.Run(nullptr); + if (ContainsKey(web_contents_map_, guest_instance_id)) + callback.Run(web_contents_map_[guest_instance_id].web_contents); + else + callback.Run(nullptr); } bool WebViewManager::ForEachGuest(content::WebContents* embedder_web_contents, const GuestCallback& callback) { - LOG(ERROR) << "ForEachGuest"; + for (auto& item : web_contents_map_) + if (item.second.embedder == embedder_web_contents && + callback.Run(item.second.web_contents)) + return true; return false; } } // namespace atom + +namespace { + +void Initialize(v8::Handle exports, v8::Handle unused, + v8::Handle context, void* priv) { + using atom::WebViewManager; + auto manager = static_cast( + atom::AtomBrowserContext::Get()->GetGuestManager()); + mate::Dictionary dict(context->GetIsolate(), exports); + dict.SetMethod("addGuest", + base::Bind(&WebViewManager::AddGuest, + base::Unretained(manager))); + dict.SetMethod("removeGuest", + base::Bind(&WebViewManager::RemoveGuest, + base::Unretained(manager))); +} + +} // namespace + +NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_web_view_manager, Initialize) diff --git a/atom/browser/web_view/web_view_manager.h b/atom/browser/web_view/web_view_manager.h index 25bc9bd396..dd72f8ac52 100644 --- a/atom/browser/web_view/web_view_manager.h +++ b/atom/browser/web_view/web_view_manager.h @@ -5,6 +5,8 @@ #ifndef ATOM_BROWSER_WEB_VIEW_WEB_VIEW_MANAGER_H_ #define ATOM_BROWSER_WEB_VIEW_WEB_VIEW_MANAGER_H_ +#include + #include "content/public/browser/browser_plugin_guest_manager.h" namespace content { @@ -18,6 +20,12 @@ class WebViewManager : public content::BrowserPluginGuestManager { explicit WebViewManager(content::BrowserContext* context); virtual ~WebViewManager(); + void AddGuest(int guest_instance_id, + content::WebContents* embedder, + content::WebContents* web_contents); + void RemoveGuest(int guest_instance_id); + + protected: // content::BrowserPluginGuestManager: virtual void MaybeGetGuestByInstanceIDOrKill( int guest_instance_id, @@ -27,6 +35,12 @@ class WebViewManager : public content::BrowserPluginGuestManager { const GuestCallback& callback) override; private: + struct WebContentsWithEmbedder { + content::WebContents* web_contents; // Weak ref. + content::WebContents* embedder; + }; + std::map web_contents_map_; + DISALLOW_COPY_AND_ASSIGN(WebViewManager); };