Use BuildPrototype to build prototype

This saves the step of manually keeping the global template object,
which is easy to forget then leak.
This commit is contained in:
Cheng Zhao 2015-12-03 16:04:46 +08:00
parent 6795bd1d96
commit a15f9fab5b
10 changed files with 148 additions and 126 deletions

View file

@ -322,14 +322,6 @@ void Cookies::OnSetCookies(const CookiesCallback& callback,
callback)); callback));
} }
mate::ObjectTemplateBuilder Cookies::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
return mate::ObjectTemplateBuilder(isolate)
.SetMethod("get", &Cookies::Get)
.SetMethod("remove", &Cookies::Remove)
.SetMethod("set", &Cookies::Set);
}
net::CookieStore* Cookies::GetCookieStore() { net::CookieStore* Cookies::GetCookieStore() {
return request_context_getter_->GetURLRequestContext()->cookie_store(); return request_context_getter_->GetURLRequestContext()->cookie_store();
} }
@ -341,6 +333,15 @@ mate::Handle<Cookies> Cookies::Create(
return mate::CreateHandle(isolate, new Cookies(browser_context)); return mate::CreateHandle(isolate, new Cookies(browser_context));
} }
// static
void Cookies::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::ObjectTemplate> prototype) {
mate::ObjectTemplateBuilder(isolate, prototype)
.SetMethod("get", &Cookies::Get)
.SetMethod("remove", &Cookies::Remove)
.SetMethod("set", &Cookies::Set);
}
} // namespace api } // namespace api
} // namespace atom } // namespace atom

View file

@ -7,8 +7,8 @@
#include <string> #include <string>
#include "atom/browser/api/trackable_object.h"
#include "base/callback.h" #include "base/callback.h"
#include "native_mate/wrappable.h"
#include "native_mate/handle.h" #include "native_mate/handle.h"
#include "net/cookies/canonical_cookie.h" #include "net/cookies/canonical_cookie.h"
@ -33,7 +33,7 @@ namespace atom {
namespace api { namespace api {
class Cookies : public mate::Wrappable { class Cookies : public mate::TrackableObject<Cookies> {
public: public:
// node.js style callback function(error, result) // node.js style callback function(error, result)
typedef base::Callback<void(v8::Local<v8::Value>, v8::Local<v8::Value>)> typedef base::Callback<void(v8::Local<v8::Value>, v8::Local<v8::Value>)>
@ -42,6 +42,10 @@ class Cookies : public mate::Wrappable {
static mate::Handle<Cookies> Create(v8::Isolate* isolate, static mate::Handle<Cookies> Create(v8::Isolate* isolate,
content::BrowserContext* browser_context); content::BrowserContext* browser_context);
// mate::TrackableObject:
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::ObjectTemplate> prototype);
protected: protected:
explicit Cookies(content::BrowserContext* browser_context); explicit Cookies(content::BrowserContext* browser_context);
~Cookies(); ~Cookies();
@ -70,10 +74,6 @@ class Cookies : public mate::Wrappable {
void OnSetCookies(const CookiesCallback& callback, void OnSetCookies(const CookiesCallback& callback,
bool set_success); bool set_success);
// mate::Wrappable:
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) override;
private: private:
// Must be called on IO thread. // Must be called on IO thread.
net::CookieStore* GetCookieStore(); net::CookieStore* GetCookieStore();

View file

@ -135,9 +135,10 @@ void DownloadItem::Cancel() {
download_item_->Cancel(true); download_item_->Cancel(true);
} }
mate::ObjectTemplateBuilder DownloadItem::GetObjectTemplateBuilder( // static
v8::Isolate* isolate) { void DownloadItem::BuildPrototype(v8::Isolate* isolate,
return mate::ObjectTemplateBuilder(isolate) v8::Local<v8::ObjectTemplate> prototype) {
mate::ObjectTemplateBuilder(isolate, prototype)
.MakeDestroyable() .MakeDestroyable()
.SetMethod("pause", &DownloadItem::Pause) .SetMethod("pause", &DownloadItem::Pause)
.SetMethod("resume", &DownloadItem::Resume) .SetMethod("resume", &DownloadItem::Resume)

View file

@ -17,7 +17,7 @@ namespace atom {
namespace api { namespace api {
class DownloadItem : public mate::EventEmitter, class DownloadItem : public mate::TrackableObject<DownloadItem>,
public content::DownloadItem::Observer { public content::DownloadItem::Observer {
public: public:
class SavePathData : public base::SupportsUserData::Data { class SavePathData : public base::SupportsUserData::Data {
@ -32,6 +32,10 @@ class DownloadItem : public mate::EventEmitter,
content::DownloadItem* item); content::DownloadItem* item);
static void* UserDataKey(); static void* UserDataKey();
// mate::TrackableObject:
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::ObjectTemplate> prototype);
protected: protected:
explicit DownloadItem(content::DownloadItem* download_item); explicit DownloadItem(content::DownloadItem* download_item);
~DownloadItem(); ~DownloadItem();
@ -53,10 +57,6 @@ class DownloadItem : public mate::EventEmitter,
void SetSavePath(const base::FilePath& path); void SetSavePath(const base::FilePath& path);
private: private:
// mate::Wrappable:
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) override;
content::DownloadItem* download_item_; content::DownloadItem* download_item_;
DISALLOW_COPY_AND_ASSIGN(DownloadItem); DISALLOW_COPY_AND_ASSIGN(DownloadItem);

View file

@ -367,21 +367,6 @@ v8::Local<v8::Value> Session::Cookies(v8::Isolate* isolate) {
return v8::Local<v8::Value>::New(isolate, cookies_); return v8::Local<v8::Value>::New(isolate, cookies_);
} }
mate::ObjectTemplateBuilder Session::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
return mate::ObjectTemplateBuilder(isolate)
.MakeDestroyable()
.SetMethod("resolveProxy", &Session::ResolveProxy)
.SetMethod("clearCache", &Session::ClearCache)
.SetMethod("clearStorageData", &Session::ClearStorageData)
.SetMethod("setProxy", &Session::SetProxy)
.SetMethod("setDownloadPath", &Session::SetDownloadPath)
.SetMethod("enableNetworkEmulation", &Session::EnableNetworkEmulation)
.SetMethod("disableNetworkEmulation", &Session::DisableNetworkEmulation)
.SetMethod("setCertificateVerifyProc", &Session::SetCertVerifyProc)
.SetProperty("cookies", &Session::Cookies);
}
// static // static
mate::Handle<Session> Session::CreateFrom( mate::Handle<Session> Session::CreateFrom(
v8::Isolate* isolate, AtomBrowserContext* browser_context) { v8::Isolate* isolate, AtomBrowserContext* browser_context) {
@ -402,6 +387,22 @@ mate::Handle<Session> Session::FromPartition(
static_cast<AtomBrowserContext*>(browser_context.get())); static_cast<AtomBrowserContext*>(browser_context.get()));
} }
// static
void Session::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::ObjectTemplate> prototype) {
mate::ObjectTemplateBuilder(isolate, prototype)
.MakeDestroyable()
.SetMethod("resolveProxy", &Session::ResolveProxy)
.SetMethod("clearCache", &Session::ClearCache)
.SetMethod("clearStorageData", &Session::ClearStorageData)
.SetMethod("setProxy", &Session::SetProxy)
.SetMethod("setDownloadPath", &Session::SetDownloadPath)
.SetMethod("enableNetworkEmulation", &Session::EnableNetworkEmulation)
.SetMethod("disableNetworkEmulation", &Session::DisableNetworkEmulation)
.SetMethod("setCertificateVerifyProc", &Session::SetCertVerifyProc)
.SetProperty("cookies", &Session::Cookies);
}
void ClearWrapSession() { void ClearWrapSession() {
g_wrap_session.Reset(); g_wrap_session.Reset();
} }

View file

@ -48,6 +48,10 @@ class Session: public mate::TrackableObject<Session>,
AtomBrowserContext* browser_context() const { return browser_context_.get(); } AtomBrowserContext* browser_context() const { return browser_context_.get(); }
// mate::TrackableObject:
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::ObjectTemplate> prototype);
protected: protected:
explicit Session(AtomBrowserContext* browser_context); explicit Session(AtomBrowserContext* browser_context);
~Session(); ~Session();
@ -56,10 +60,6 @@ class Session: public mate::TrackableObject<Session>,
void OnDownloadCreated(content::DownloadManager* manager, void OnDownloadCreated(content::DownloadManager* manager,
content::DownloadItem* item) override; content::DownloadItem* item) override;
// mate::Wrappable:
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) override;
private: private:
void ResolveProxy(const GURL& url, ResolveProxyCallback callback); void ResolveProxy(const GURL& url, ResolveProxyCallback callback);
void ClearCache(const net::CompletionCallback& callback); void ClearCache(const net::CompletionCallback& callback);

View file

@ -194,8 +194,6 @@ namespace api {
namespace { namespace {
v8::Persistent<v8::ObjectTemplate> template_;
// The wrapWebContents function which is implemented in JavaScript // The wrapWebContents function which is implemented in JavaScript
using WrapWebContentsCallback = base::Callback<void(v8::Local<v8::Value>)>; using WrapWebContentsCallback = base::Callback<void(v8::Local<v8::Value>)>;
WrapWebContentsCallback g_wrap_web_contents; WrapWebContentsCallback g_wrap_web_contents;
@ -982,76 +980,72 @@ v8::Local<v8::Value> WebContents::DevToolsWebContents(v8::Isolate* isolate) {
return v8::Local<v8::Value>::New(isolate, devtools_web_contents_); return v8::Local<v8::Value>::New(isolate, devtools_web_contents_);
} }
mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder( // static
v8::Isolate* isolate) { void WebContents::BuildPrototype(v8::Isolate* isolate,
if (template_.IsEmpty()) v8::Local<v8::ObjectTemplate> prototype) {
template_.Reset(isolate, mate::ObjectTemplateBuilder(isolate) mate::ObjectTemplateBuilder(isolate, prototype)
.MakeDestroyable() .MakeDestroyable()
.SetMethod("getId", &WebContents::GetID) .SetMethod("getId", &WebContents::GetID)
.SetMethod("equal", &WebContents::Equal) .SetMethod("equal", &WebContents::Equal)
.SetMethod("_loadURL", &WebContents::LoadURL) .SetMethod("_loadURL", &WebContents::LoadURL)
.SetMethod("_getURL", &WebContents::GetURL) .SetMethod("_getURL", &WebContents::GetURL)
.SetMethod("getTitle", &WebContents::GetTitle) .SetMethod("getTitle", &WebContents::GetTitle)
.SetMethod("isLoading", &WebContents::IsLoading) .SetMethod("isLoading", &WebContents::IsLoading)
.SetMethod("isWaitingForResponse", &WebContents::IsWaitingForResponse) .SetMethod("isWaitingForResponse", &WebContents::IsWaitingForResponse)
.SetMethod("_stop", &WebContents::Stop) .SetMethod("_stop", &WebContents::Stop)
.SetMethod("_goBack", &WebContents::GoBack) .SetMethod("_goBack", &WebContents::GoBack)
.SetMethod("_goForward", &WebContents::GoForward) .SetMethod("_goForward", &WebContents::GoForward)
.SetMethod("_goToOffset", &WebContents::GoToOffset) .SetMethod("_goToOffset", &WebContents::GoToOffset)
.SetMethod("isCrashed", &WebContents::IsCrashed) .SetMethod("isCrashed", &WebContents::IsCrashed)
.SetMethod("setUserAgent", &WebContents::SetUserAgent) .SetMethod("setUserAgent", &WebContents::SetUserAgent)
.SetMethod("getUserAgent", &WebContents::GetUserAgent) .SetMethod("getUserAgent", &WebContents::GetUserAgent)
.SetMethod("insertCSS", &WebContents::InsertCSS) .SetMethod("insertCSS", &WebContents::InsertCSS)
.SetMethod("savePage", &WebContents::SavePage) .SetMethod("savePage", &WebContents::SavePage)
.SetMethod("_executeJavaScript", &WebContents::ExecuteJavaScript) .SetMethod("_executeJavaScript", &WebContents::ExecuteJavaScript)
.SetMethod("openDevTools", &WebContents::OpenDevTools) .SetMethod("openDevTools", &WebContents::OpenDevTools)
.SetMethod("closeDevTools", &WebContents::CloseDevTools) .SetMethod("closeDevTools", &WebContents::CloseDevTools)
.SetMethod("isDevToolsOpened", &WebContents::IsDevToolsOpened) .SetMethod("isDevToolsOpened", &WebContents::IsDevToolsOpened)
.SetMethod("enableDeviceEmulation", .SetMethod("enableDeviceEmulation",
&WebContents::EnableDeviceEmulation) &WebContents::EnableDeviceEmulation)
.SetMethod("disableDeviceEmulation", .SetMethod("disableDeviceEmulation",
&WebContents::DisableDeviceEmulation) &WebContents::DisableDeviceEmulation)
.SetMethod("toggleDevTools", &WebContents::ToggleDevTools) .SetMethod("toggleDevTools", &WebContents::ToggleDevTools)
.SetMethod("inspectElement", &WebContents::InspectElement) .SetMethod("inspectElement", &WebContents::InspectElement)
.SetMethod("setAudioMuted", &WebContents::SetAudioMuted) .SetMethod("setAudioMuted", &WebContents::SetAudioMuted)
.SetMethod("isAudioMuted", &WebContents::IsAudioMuted) .SetMethod("isAudioMuted", &WebContents::IsAudioMuted)
.SetMethod("undo", &WebContents::Undo) .SetMethod("undo", &WebContents::Undo)
.SetMethod("redo", &WebContents::Redo) .SetMethod("redo", &WebContents::Redo)
.SetMethod("cut", &WebContents::Cut) .SetMethod("cut", &WebContents::Cut)
.SetMethod("copy", &WebContents::Copy) .SetMethod("copy", &WebContents::Copy)
.SetMethod("paste", &WebContents::Paste) .SetMethod("paste", &WebContents::Paste)
.SetMethod("pasteAndMatchStyle", &WebContents::PasteAndMatchStyle) .SetMethod("pasteAndMatchStyle", &WebContents::PasteAndMatchStyle)
.SetMethod("delete", &WebContents::Delete) .SetMethod("delete", &WebContents::Delete)
.SetMethod("selectAll", &WebContents::SelectAll) .SetMethod("selectAll", &WebContents::SelectAll)
.SetMethod("unselect", &WebContents::Unselect) .SetMethod("unselect", &WebContents::Unselect)
.SetMethod("replace", &WebContents::Replace) .SetMethod("replace", &WebContents::Replace)
.SetMethod("replaceMisspelling", &WebContents::ReplaceMisspelling) .SetMethod("replaceMisspelling", &WebContents::ReplaceMisspelling)
.SetMethod("focus", &WebContents::Focus) .SetMethod("focus", &WebContents::Focus)
.SetMethod("tabTraverse", &WebContents::TabTraverse) .SetMethod("tabTraverse", &WebContents::TabTraverse)
.SetMethod("_send", &WebContents::SendIPCMessage) .SetMethod("_send", &WebContents::SendIPCMessage)
.SetMethod("sendInputEvent", &WebContents::SendInputEvent) .SetMethod("sendInputEvent", &WebContents::SendInputEvent)
.SetMethod("beginFrameSubscription", .SetMethod("beginFrameSubscription",
&WebContents::BeginFrameSubscription) &WebContents::BeginFrameSubscription)
.SetMethod("endFrameSubscription", &WebContents::EndFrameSubscription) .SetMethod("endFrameSubscription", &WebContents::EndFrameSubscription)
.SetMethod("setSize", &WebContents::SetSize) .SetMethod("setSize", &WebContents::SetSize)
.SetMethod("setAllowTransparency", &WebContents::SetAllowTransparency) .SetMethod("setAllowTransparency", &WebContents::SetAllowTransparency)
.SetMethod("isGuest", &WebContents::IsGuest) .SetMethod("isGuest", &WebContents::IsGuest)
.SetMethod("getWebPreferences", &WebContents::GetWebPreferences) .SetMethod("getWebPreferences", &WebContents::GetWebPreferences)
.SetMethod("getOwnerBrowserWindow", &WebContents::GetOwnerBrowserWindow) .SetMethod("getOwnerBrowserWindow", &WebContents::GetOwnerBrowserWindow)
.SetMethod("hasServiceWorker", &WebContents::HasServiceWorker) .SetMethod("hasServiceWorker", &WebContents::HasServiceWorker)
.SetMethod("unregisterServiceWorker", .SetMethod("unregisterServiceWorker",
&WebContents::UnregisterServiceWorker) &WebContents::UnregisterServiceWorker)
.SetMethod("inspectServiceWorker", &WebContents::InspectServiceWorker) .SetMethod("inspectServiceWorker", &WebContents::InspectServiceWorker)
.SetMethod("print", &WebContents::Print) .SetMethod("print", &WebContents::Print)
.SetMethod("_printToPDF", &WebContents::PrintToPDF) .SetMethod("_printToPDF", &WebContents::PrintToPDF)
.SetMethod("addWorkSpace", &WebContents::AddWorkSpace) .SetMethod("addWorkSpace", &WebContents::AddWorkSpace)
.SetMethod("removeWorkSpace", &WebContents::RemoveWorkSpace) .SetMethod("removeWorkSpace", &WebContents::RemoveWorkSpace)
.SetProperty("session", &WebContents::Session) .SetProperty("session", &WebContents::Session)
.SetProperty("devToolsWebContents", &WebContents::DevToolsWebContents) .SetProperty("devToolsWebContents", &WebContents::DevToolsWebContents);
.Build());
return mate::ObjectTemplateBuilder(
isolate, v8::Local<v8::ObjectTemplate>::New(isolate, template_));
} }
AtomBrowserContext* WebContents::GetBrowserContext() const { AtomBrowserContext* WebContents::GetBrowserContext() const {

View file

@ -141,15 +141,15 @@ class WebContents : public mate::TrackableObject<WebContents>,
v8::Local<v8::Value> Session(v8::Isolate* isolate); v8::Local<v8::Value> Session(v8::Isolate* isolate);
v8::Local<v8::Value> DevToolsWebContents(v8::Isolate* isolate); v8::Local<v8::Value> DevToolsWebContents(v8::Isolate* isolate);
// mate::TrackableObject:
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::ObjectTemplate> prototype);
protected: protected:
explicit WebContents(content::WebContents* web_contents); explicit WebContents(content::WebContents* web_contents);
WebContents(v8::Isolate* isolate, const mate::Dictionary& options); WebContents(v8::Isolate* isolate, const mate::Dictionary& options);
~WebContents(); ~WebContents();
// mate::Wrappable:
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) override;
// content::WebContentsDelegate: // content::WebContentsDelegate:
bool AddMessageToConsole(content::WebContents* source, bool AddMessageToConsole(content::WebContents* source,
int32 level, int32 level,

View file

@ -12,6 +12,7 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "native_mate/object_template_builder.h"
namespace base { namespace base {
class SupportsUserData; class SupportsUserData;
@ -120,16 +121,33 @@ class TrackableObject : public TrackableObjectBase {
} }
private: private:
// mate::Wrappable:
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) override {
if (template_.IsEmpty()) {
auto templ = v8::ObjectTemplate::New(isolate);
T::BuildPrototype(isolate, templ);
template_.Reset(isolate, templ);
}
return ObjectTemplateBuilder(
isolate, v8::Local<v8::ObjectTemplate>::New(isolate, template_));
}
// Releases all weak references in weak map, called when app is terminating. // Releases all weak references in weak map, called when app is terminating.
static void ReleaseAllWeakReferences() { static void ReleaseAllWeakReferences() {
weak_map_.reset(); weak_map_.reset();
} }
static v8::Persistent<v8::ObjectTemplate> template_;
static scoped_ptr<atom::IDWeakMap> weak_map_; static scoped_ptr<atom::IDWeakMap> weak_map_;
DISALLOW_COPY_AND_ASSIGN(TrackableObject); DISALLOW_COPY_AND_ASSIGN(TrackableObject);
}; };
template<typename T>
v8::Persistent<v8::ObjectTemplate> TrackableObject<T>::template_;
template<typename T> template<typename T>
scoped_ptr<atom::IDWeakMap> TrackableObject<T>::weak_map_; scoped_ptr<atom::IDWeakMap> TrackableObject<T>::weak_map_;

View file

@ -18,6 +18,8 @@
namespace { namespace {
v8::Persistent<v8::ObjectTemplate> template_;
class Archive : public mate::Wrappable { class Archive : public mate::Wrappable {
public: public:
static v8::Local<v8::Value> Create(v8::Isolate* isolate, static v8::Local<v8::Value> Create(v8::Isolate* isolate,
@ -101,15 +103,20 @@ class Archive : public mate::Wrappable {
// mate::Wrappable: // mate::Wrappable:
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate* isolate) { mate::ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate* isolate) {
return mate::ObjectTemplateBuilder(isolate) if (template_.IsEmpty())
.SetValue("path", archive_->path()) template_.Reset(isolate, mate::ObjectTemplateBuilder(isolate)
.SetMethod("getFileInfo", &Archive::GetFileInfo) .SetValue("path", archive_->path())
.SetMethod("stat", &Archive::Stat) .SetMethod("getFileInfo", &Archive::GetFileInfo)
.SetMethod("readdir", &Archive::Readdir) .SetMethod("stat", &Archive::Stat)
.SetMethod("realpath", &Archive::Realpath) .SetMethod("readdir", &Archive::Readdir)
.SetMethod("copyFileOut", &Archive::CopyFileOut) .SetMethod("realpath", &Archive::Realpath)
.SetMethod("getFd", &Archive::GetFD) .SetMethod("copyFileOut", &Archive::CopyFileOut)
.SetMethod("destroy", &Archive::Destroy); .SetMethod("getFd", &Archive::GetFD)
.SetMethod("destroy", &Archive::Destroy)
.Build());
return mate::ObjectTemplateBuilder(
isolate, v8::Local<v8::ObjectTemplate>::New(isolate, template_));
} }
private: private: