api: Add webContent.create() to create detached WebContents

This commit is contained in:
Cheng Zhao 2014-10-23 14:04:13 +08:00
parent c72d769ff0
commit d34cff2eef
5 changed files with 78 additions and 9 deletions

View file

@ -4,6 +4,7 @@
#include "atom/browser/api/atom_api_web_contents.h"
#include "atom/browser/atom_browser_context.h"
#include "atom/common/api/api_messages.h"
#include "atom/common/native_mate_converters/gurl_converter.h"
#include "atom/common/native_mate_converters/string16_converter.h"
@ -13,8 +14,11 @@
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "native_mate/dictionary.h"
#include "native_mate/object_template_builder.h"
#include "atom/common/node_includes.h"
namespace atom {
namespace api {
@ -26,8 +30,20 @@ v8::Persistent<v8::ObjectTemplate> template_;
} // namespace
WebContents::WebContents(content::WebContents* web_contents)
: content::WebContentsObserver(web_contents),
web_contents_(web_contents) {
: content::WebContentsObserver(web_contents) {
}
WebContents::WebContents(const mate::Dictionary& options) {
content::WebContents::CreateParams params(AtomBrowserContext::Get());
bool is_guest;
if (options.Get("isGuest", &is_guest) && is_guest)
params.guest_delegate = this;
storage_.reset(content::WebContents::Create(params));
Observe(storage_.get());
}
WebContents::~WebContents() {
}
void WebContents::RenderViewDeleted(content::RenderViewHost* render_view_host) {
@ -75,10 +91,17 @@ bool WebContents::OnMessageReceived(const IPC::Message& message) {
void WebContents::WebContentsDestroyed() {
// The RenderViewDeleted was not called when the WebContents is destroyed.
RenderViewDeleted(web_contents_->GetRenderViewHost());
RenderViewDeleted(web_contents()->GetRenderViewHost());
Emit("destroyed");
}
void WebContents::Destroy() {
if (storage_) {
Observe(nullptr);
storage_.reset();
}
}
bool WebContents::IsAlive() const {
return web_contents() != NULL;
}
@ -174,6 +197,7 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
if (template_.IsEmpty())
template_.Reset(isolate, mate::ObjectTemplateBuilder(isolate)
.SetMethod("destroy", &WebContents::Destroy)
.SetMethod("isAlive", &WebContents::IsAlive)
.SetMethod("loadUrl", &WebContents::LoadURL)
.SetMethod("getUrl", &WebContents::GetURL)
@ -215,11 +239,31 @@ void WebContents::OnRendererMessageSync(const base::string16& channel,
}
// static
mate::Handle<WebContents> WebContents::Create(
mate::Handle<WebContents> WebContents::CreateFrom(
v8::Isolate* isolate, content::WebContents* web_contents) {
return mate::CreateHandle(isolate, new WebContents(web_contents));
}
// static
mate::Handle<WebContents> WebContents::Create(
v8::Isolate* isolate, const mate::Dictionary& options) {
return mate::CreateHandle(isolate, new WebContents(options));
}
} // namespace api
} // namespace atom
namespace {
void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
v8::Handle<v8::Context> context, void* priv) {
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary dict(isolate, exports);
dict.SetMethod("create", &atom::api::WebContents::Create);
}
} // namespace
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_web_contents, Initialize)

View file

@ -6,19 +6,31 @@
#define ATOM_BROWSER_API_ATOM_API_WEB_CONTENTS_H_
#include "atom/browser/api/event_emitter.h"
#include "content/public/browser/browser_plugin_guest_delegate.h"
#include "content/public/browser/web_contents_observer.h"
#include "native_mate/handle.h"
namespace mate {
class Dictionary;
}
namespace atom {
namespace api {
class WebContents : public mate::EventEmitter,
public content::BrowserPluginGuestDelegate,
public content::WebContentsObserver {
public:
static mate::Handle<WebContents> Create(v8::Isolate* isolate,
content::WebContents* web_contents);
// Create from an existing WebContents.
static mate::Handle<WebContents> CreateFrom(
v8::Isolate* isolate, content::WebContents* web_contents);
// Create a new WebContents.
static mate::Handle<WebContents> Create(
v8::Isolate* isolate, const mate::Dictionary& options);
void Destroy();
bool IsAlive() const;
void LoadURL(const GURL& url);
GURL GetURL() const;
@ -44,6 +56,8 @@ class WebContents : public mate::EventEmitter,
protected:
explicit WebContents(content::WebContents* web_contents);
explicit WebContents(const mate::Dictionary& options);
~WebContents();
// mate::Wrappable implementations:
virtual mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
@ -71,7 +85,8 @@ class WebContents : public mate::EventEmitter,
const base::ListValue& args,
IPC::Message* message);
content::WebContents* web_contents_; // Weak.
// Stores the WebContents that managed by this class.
scoped_ptr<content::WebContents> storage_;
DISALLOW_COPY_AND_ASSIGN(WebContents);
};

View file

@ -375,12 +375,12 @@ void Window::SetProgressBar(double progress) {
}
mate::Handle<WebContents> Window::GetWebContents(v8::Isolate* isolate) const {
return WebContents::Create(isolate, window_->GetWebContents());
return WebContents::CreateFrom(isolate, window_->GetWebContents());
}
mate::Handle<WebContents> Window::GetDevToolsWebContents(
v8::Isolate* isolate) const {
return WebContents::Create(isolate, window_->GetDevToolsWebContents());
return WebContents::CreateFrom(isolate, window_->GetDevToolsWebContents());
}
// static

View file

@ -1,4 +1,5 @@
EventEmitter = require('events').EventEmitter
binding = process.atomBinding 'web_contents'
ipc = require 'ipc'
module.exports.wrap = (webContents) ->
@ -40,3 +41,11 @@ module.exports.wrap = (webContents) ->
ipc.emit channel, event, args...
webContents
module.exports.create = (options={}) ->
webContents = @wrap binding.create(options)
# Ensure the webContents is destroyed on exit.
process.on 'exit', -> webContents.destroy()
webContents

View file

@ -68,6 +68,7 @@ REFERENCE_MODULE(atom_browser_power_monitor);
REFERENCE_MODULE(atom_browser_protocol);
REFERENCE_MODULE(atom_browser_global_shortcut);
REFERENCE_MODULE(atom_browser_tray);
REFERENCE_MODULE(atom_browser_web_contents);
REFERENCE_MODULE(atom_browser_window);
REFERENCE_MODULE(atom_common_asar);
REFERENCE_MODULE(atom_common_clipboard);