Use BuildPrototype to build prototype
authorCheng Zhao <zcbenz@gmail.com>
Thu, 3 Dec 2015 08:04:46 +0000 (16:04 +0800)
committerCheng Zhao <zcbenz@gmail.com>
Thu, 3 Dec 2015 08:04:46 +0000 (16:04 +0800)
This saves the step of manually keeping the global template object,
which is easy to forget then leak.

atom/browser/api/atom_api_cookies.cc
atom/browser/api/atom_api_cookies.h
atom/browser/api/atom_api_download_item.cc
atom/browser/api/atom_api_download_item.h
atom/browser/api/atom_api_session.cc
atom/browser/api/atom_api_session.h
atom/browser/api/atom_api_web_contents.cc
atom/browser/api/atom_api_web_contents.h
atom/browser/api/trackable_object.h
atom/common/api/atom_api_asar.cc

index a3b2c37..3b1bd49 100644 (file)
@@ -322,14 +322,6 @@ void Cookies::OnSetCookies(const CookiesCallback& 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() {
   return request_context_getter_->GetURLRequestContext()->cookie_store();
 }
@@ -341,6 +333,15 @@ mate::Handle<Cookies> Cookies::Create(
   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 atom
index 0c309b3..5afa1bd 100644 (file)
@@ -7,8 +7,8 @@
 
 #include <string>
 
+#include "atom/browser/api/trackable_object.h"
 #include "base/callback.h"
-#include "native_mate/wrappable.h"
 #include "native_mate/handle.h"
 #include "net/cookies/canonical_cookie.h"
 
@@ -33,7 +33,7 @@ namespace atom {
 
 namespace api {
 
-class Cookies : public mate::Wrappable {
+class Cookies : public mate::TrackableObject<Cookies> {
  public:
   // node.js style callback function(error, result)
   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,
                                       content::BrowserContext* browser_context);
 
+  // mate::TrackableObject:
+  static void BuildPrototype(v8::Isolate* isolate,
+                             v8::Local<v8::ObjectTemplate> prototype);
+
  protected:
   explicit Cookies(content::BrowserContext* browser_context);
   ~Cookies();
@@ -70,10 +74,6 @@ class Cookies : public mate::Wrappable {
   void OnSetCookies(const CookiesCallback& callback,
                     bool set_success);
 
-  // mate::Wrappable:
-  mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
-      v8::Isolate* isolate) override;
-
  private:
   // Must be called on IO thread.
   net::CookieStore* GetCookieStore();
index fe63d70..f186821 100644 (file)
@@ -135,9 +135,10 @@ void DownloadItem::Cancel() {
   download_item_->Cancel(true);
 }
 
-mate::ObjectTemplateBuilder DownloadItem::GetObjectTemplateBuilder(
-    v8::Isolate* isolate) {
-  return mate::ObjectTemplateBuilder(isolate)
+// static
+void DownloadItem::BuildPrototype(v8::Isolate* isolate,
+                                  v8::Local<v8::ObjectTemplate> prototype) {
+  mate::ObjectTemplateBuilder(isolate, prototype)
       .MakeDestroyable()
       .SetMethod("pause", &DownloadItem::Pause)
       .SetMethod("resume", &DownloadItem::Resume)
index 412b6ce..471913c 100644 (file)
@@ -17,7 +17,7 @@ namespace atom {
 
 namespace api {
 
-class DownloadItem : public mate::EventEmitter,
+class DownloadItem : public mate::TrackableObject<DownloadItem>,
                      public content::DownloadItem::Observer {
  public:
   class SavePathData : public base::SupportsUserData::Data {
@@ -32,6 +32,10 @@ class DownloadItem : public mate::EventEmitter,
                                            content::DownloadItem* item);
   static void* UserDataKey();
 
+  // mate::TrackableObject:
+  static void BuildPrototype(v8::Isolate* isolate,
+                             v8::Local<v8::ObjectTemplate> prototype);
+
  protected:
   explicit DownloadItem(content::DownloadItem* download_item);
   ~DownloadItem();
@@ -53,10 +57,6 @@ class DownloadItem : public mate::EventEmitter,
   void SetSavePath(const base::FilePath& path);
 
  private:
-  // mate::Wrappable:
-  mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
-      v8::Isolate* isolate) override;
-
   content::DownloadItem* download_item_;
 
   DISALLOW_COPY_AND_ASSIGN(DownloadItem);
index 495a4c4..f390738 100644 (file)
@@ -367,21 +367,6 @@ v8::Local<v8::Value> Session::Cookies(v8::Isolate* isolate) {
   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
 mate::Handle<Session> Session::CreateFrom(
     v8::Isolate* isolate, AtomBrowserContext* browser_context) {
@@ -402,6 +387,22 @@ mate::Handle<Session> Session::FromPartition(
                     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() {
   g_wrap_session.Reset();
 }
index 104a8e4..e800a99 100644 (file)
@@ -48,6 +48,10 @@ class Session: public mate::TrackableObject<Session>,
 
   AtomBrowserContext* browser_context() const { return browser_context_.get(); }
 
+  // mate::TrackableObject:
+  static void BuildPrototype(v8::Isolate* isolate,
+                             v8::Local<v8::ObjectTemplate> prototype);
+
  protected:
   explicit Session(AtomBrowserContext* browser_context);
   ~Session();
@@ -56,10 +60,6 @@ class Session: public mate::TrackableObject<Session>,
   void OnDownloadCreated(content::DownloadManager* manager,
                          content::DownloadItem* item) override;
 
-  // mate::Wrappable:
-  mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
-      v8::Isolate* isolate) override;
-
  private:
   void ResolveProxy(const GURL& url, ResolveProxyCallback callback);
   void ClearCache(const net::CompletionCallback& callback);
index 2f8353e..da28dcf 100644 (file)
@@ -194,8 +194,6 @@ namespace api {
 
 namespace {
 
-v8::Persistent<v8::ObjectTemplate> template_;
-
 // The wrapWebContents function which is implemented in JavaScript
 using WrapWebContentsCallback = base::Callback<void(v8::Local<v8::Value>)>;
 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_);
 }
 
-mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder(
-    v8::Isolate* isolate) {
-  if (template_.IsEmpty())
-    template_.Reset(isolate, mate::ObjectTemplateBuilder(isolate)
-        .MakeDestroyable()
-        .SetMethod("getId", &WebContents::GetID)
-        .SetMethod("equal", &WebContents::Equal)
-        .SetMethod("_loadURL", &WebContents::LoadURL)
-        .SetMethod("_getURL", &WebContents::GetURL)
-        .SetMethod("getTitle", &WebContents::GetTitle)
-        .SetMethod("isLoading", &WebContents::IsLoading)
-        .SetMethod("isWaitingForResponse", &WebContents::IsWaitingForResponse)
-        .SetMethod("_stop", &WebContents::Stop)
-        .SetMethod("_goBack", &WebContents::GoBack)
-        .SetMethod("_goForward", &WebContents::GoForward)
-        .SetMethod("_goToOffset", &WebContents::GoToOffset)
-        .SetMethod("isCrashed", &WebContents::IsCrashed)
-        .SetMethod("setUserAgent", &WebContents::SetUserAgent)
-        .SetMethod("getUserAgent", &WebContents::GetUserAgent)
-        .SetMethod("insertCSS", &WebContents::InsertCSS)
-        .SetMethod("savePage", &WebContents::SavePage)
-        .SetMethod("_executeJavaScript", &WebContents::ExecuteJavaScript)
-        .SetMethod("openDevTools", &WebContents::OpenDevTools)
-        .SetMethod("closeDevTools", &WebContents::CloseDevTools)
-        .SetMethod("isDevToolsOpened", &WebContents::IsDevToolsOpened)
-        .SetMethod("enableDeviceEmulation",
-                   &WebContents::EnableDeviceEmulation)
-        .SetMethod("disableDeviceEmulation",
-                   &WebContents::DisableDeviceEmulation)
-        .SetMethod("toggleDevTools", &WebContents::ToggleDevTools)
-        .SetMethod("inspectElement", &WebContents::InspectElement)
-        .SetMethod("setAudioMuted", &WebContents::SetAudioMuted)
-        .SetMethod("isAudioMuted", &WebContents::IsAudioMuted)
-        .SetMethod("undo", &WebContents::Undo)
-        .SetMethod("redo", &WebContents::Redo)
-        .SetMethod("cut", &WebContents::Cut)
-        .SetMethod("copy", &WebContents::Copy)
-        .SetMethod("paste", &WebContents::Paste)
-        .SetMethod("pasteAndMatchStyle", &WebContents::PasteAndMatchStyle)
-        .SetMethod("delete", &WebContents::Delete)
-        .SetMethod("selectAll", &WebContents::SelectAll)
-        .SetMethod("unselect", &WebContents::Unselect)
-        .SetMethod("replace", &WebContents::Replace)
-        .SetMethod("replaceMisspelling", &WebContents::ReplaceMisspelling)
-        .SetMethod("focus", &WebContents::Focus)
-        .SetMethod("tabTraverse", &WebContents::TabTraverse)
-        .SetMethod("_send", &WebContents::SendIPCMessage)
-        .SetMethod("sendInputEvent", &WebContents::SendInputEvent)
-        .SetMethod("beginFrameSubscription",
-                   &WebContents::BeginFrameSubscription)
-        .SetMethod("endFrameSubscription", &WebContents::EndFrameSubscription)
-        .SetMethod("setSize", &WebContents::SetSize)
-        .SetMethod("setAllowTransparency", &WebContents::SetAllowTransparency)
-        .SetMethod("isGuest", &WebContents::IsGuest)
-        .SetMethod("getWebPreferences", &WebContents::GetWebPreferences)
-        .SetMethod("getOwnerBrowserWindow", &WebContents::GetOwnerBrowserWindow)
-        .SetMethod("hasServiceWorker", &WebContents::HasServiceWorker)
-        .SetMethod("unregisterServiceWorker",
-                   &WebContents::UnregisterServiceWorker)
-        .SetMethod("inspectServiceWorker", &WebContents::InspectServiceWorker)
-        .SetMethod("print", &WebContents::Print)
-        .SetMethod("_printToPDF", &WebContents::PrintToPDF)
-        .SetMethod("addWorkSpace", &WebContents::AddWorkSpace)
-        .SetMethod("removeWorkSpace", &WebContents::RemoveWorkSpace)
-        .SetProperty("session", &WebContents::Session)
-        .SetProperty("devToolsWebContents", &WebContents::DevToolsWebContents)
-        .Build());
-
-  return mate::ObjectTemplateBuilder(
-      isolate, v8::Local<v8::ObjectTemplate>::New(isolate, template_));
+// static
+void WebContents::BuildPrototype(v8::Isolate* isolate,
+                                 v8::Local<v8::ObjectTemplate> prototype) {
+  mate::ObjectTemplateBuilder(isolate, prototype)
+      .MakeDestroyable()
+      .SetMethod("getId", &WebContents::GetID)
+      .SetMethod("equal", &WebContents::Equal)
+      .SetMethod("_loadURL", &WebContents::LoadURL)
+      .SetMethod("_getURL", &WebContents::GetURL)
+      .SetMethod("getTitle", &WebContents::GetTitle)
+      .SetMethod("isLoading", &WebContents::IsLoading)
+      .SetMethod("isWaitingForResponse", &WebContents::IsWaitingForResponse)
+      .SetMethod("_stop", &WebContents::Stop)
+      .SetMethod("_goBack", &WebContents::GoBack)
+      .SetMethod("_goForward", &WebContents::GoForward)
+      .SetMethod("_goToOffset", &WebContents::GoToOffset)
+      .SetMethod("isCrashed", &WebContents::IsCrashed)
+      .SetMethod("setUserAgent", &WebContents::SetUserAgent)
+      .SetMethod("getUserAgent", &WebContents::GetUserAgent)
+      .SetMethod("insertCSS", &WebContents::InsertCSS)
+      .SetMethod("savePage", &WebContents::SavePage)
+      .SetMethod("_executeJavaScript", &WebContents::ExecuteJavaScript)
+      .SetMethod("openDevTools", &WebContents::OpenDevTools)
+      .SetMethod("closeDevTools", &WebContents::CloseDevTools)
+      .SetMethod("isDevToolsOpened", &WebContents::IsDevToolsOpened)
+      .SetMethod("enableDeviceEmulation",
+                 &WebContents::EnableDeviceEmulation)
+      .SetMethod("disableDeviceEmulation",
+                 &WebContents::DisableDeviceEmulation)
+      .SetMethod("toggleDevTools", &WebContents::ToggleDevTools)
+      .SetMethod("inspectElement", &WebContents::InspectElement)
+      .SetMethod("setAudioMuted", &WebContents::SetAudioMuted)
+      .SetMethod("isAudioMuted", &WebContents::IsAudioMuted)
+      .SetMethod("undo", &WebContents::Undo)
+      .SetMethod("redo", &WebContents::Redo)
+      .SetMethod("cut", &WebContents::Cut)
+      .SetMethod("copy", &WebContents::Copy)
+      .SetMethod("paste", &WebContents::Paste)
+      .SetMethod("pasteAndMatchStyle", &WebContents::PasteAndMatchStyle)
+      .SetMethod("delete", &WebContents::Delete)
+      .SetMethod("selectAll", &WebContents::SelectAll)
+      .SetMethod("unselect", &WebContents::Unselect)
+      .SetMethod("replace", &WebContents::Replace)
+      .SetMethod("replaceMisspelling", &WebContents::ReplaceMisspelling)
+      .SetMethod("focus", &WebContents::Focus)
+      .SetMethod("tabTraverse", &WebContents::TabTraverse)
+      .SetMethod("_send", &WebContents::SendIPCMessage)
+      .SetMethod("sendInputEvent", &WebContents::SendInputEvent)
+      .SetMethod("beginFrameSubscription",
+                 &WebContents::BeginFrameSubscription)
+      .SetMethod("endFrameSubscription", &WebContents::EndFrameSubscription)
+      .SetMethod("setSize", &WebContents::SetSize)
+      .SetMethod("setAllowTransparency", &WebContents::SetAllowTransparency)
+      .SetMethod("isGuest", &WebContents::IsGuest)
+      .SetMethod("getWebPreferences", &WebContents::GetWebPreferences)
+      .SetMethod("getOwnerBrowserWindow", &WebContents::GetOwnerBrowserWindow)
+      .SetMethod("hasServiceWorker", &WebContents::HasServiceWorker)
+      .SetMethod("unregisterServiceWorker",
+                 &WebContents::UnregisterServiceWorker)
+      .SetMethod("inspectServiceWorker", &WebContents::InspectServiceWorker)
+      .SetMethod("print", &WebContents::Print)
+      .SetMethod("_printToPDF", &WebContents::PrintToPDF)
+      .SetMethod("addWorkSpace", &WebContents::AddWorkSpace)
+      .SetMethod("removeWorkSpace", &WebContents::RemoveWorkSpace)
+      .SetProperty("session", &WebContents::Session)
+      .SetProperty("devToolsWebContents", &WebContents::DevToolsWebContents);
 }
 
 AtomBrowserContext* WebContents::GetBrowserContext() const {
index 9462e92..637785a 100644 (file)
@@ -141,15 +141,15 @@ class WebContents : public mate::TrackableObject<WebContents>,
   v8::Local<v8::Value> Session(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:
   explicit WebContents(content::WebContents* web_contents);
   WebContents(v8::Isolate* isolate, const mate::Dictionary& options);
   ~WebContents();
 
-  // mate::Wrappable:
-  mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
-      v8::Isolate* isolate) override;
-
   // content::WebContentsDelegate:
   bool AddMessageToConsole(content::WebContents* source,
                            int32 level,
index 975bb13..562ab5b 100644 (file)
@@ -12,6 +12,7 @@
 #include "base/bind.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/weak_ptr.h"
+#include "native_mate/object_template_builder.h"
 
 namespace base {
 class SupportsUserData;
@@ -120,17 +121,34 @@ class TrackableObject : public TrackableObjectBase {
   }
 
  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.
   static void ReleaseAllWeakReferences() {
     weak_map_.reset();
   }
 
+  static v8::Persistent<v8::ObjectTemplate> template_;
   static scoped_ptr<atom::IDWeakMap> weak_map_;
 
   DISALLOW_COPY_AND_ASSIGN(TrackableObject);
 };
 
 template<typename T>
+v8::Persistent<v8::ObjectTemplate> TrackableObject<T>::template_;
+
+template<typename T>
 scoped_ptr<atom::IDWeakMap> TrackableObject<T>::weak_map_;
 
 }  // namespace mate
index 4ea7d8c..7aee71f 100644 (file)
@@ -18,6 +18,8 @@
 
 namespace {
 
+v8::Persistent<v8::ObjectTemplate> template_;
+
 class Archive : public mate::Wrappable {
  public:
   static v8::Local<v8::Value> Create(v8::Isolate* isolate,
@@ -101,15 +103,20 @@ class Archive : public mate::Wrappable {
 
   // mate::Wrappable:
   mate::ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate* isolate) {
-    return mate::ObjectTemplateBuilder(isolate)
-        .SetValue("path", archive_->path())
-        .SetMethod("getFileInfo", &Archive::GetFileInfo)
-        .SetMethod("stat", &Archive::Stat)
-        .SetMethod("readdir", &Archive::Readdir)
-        .SetMethod("realpath", &Archive::Realpath)
-        .SetMethod("copyFileOut", &Archive::CopyFileOut)
-        .SetMethod("getFd", &Archive::GetFD)
-        .SetMethod("destroy", &Archive::Destroy);
+    if (template_.IsEmpty())
+      template_.Reset(isolate, mate::ObjectTemplateBuilder(isolate)
+          .SetValue("path", archive_->path())
+          .SetMethod("getFileInfo", &Archive::GetFileInfo)
+          .SetMethod("stat", &Archive::Stat)
+          .SetMethod("readdir", &Archive::Readdir)
+          .SetMethod("realpath", &Archive::Realpath)
+          .SetMethod("copyFileOut", &Archive::CopyFileOut)
+          .SetMethod("getFd", &Archive::GetFD)
+          .SetMethod("destroy", &Archive::Destroy)
+          .Build());
+
+    return mate::ObjectTemplateBuilder(
+        isolate, v8::Local<v8::ObjectTemplate>::New(isolate, template_));
   }
 
  private: