Browse Source

chore: remove native_mate (Part 9) (#20645)

* refactor: remove a few uses of native_mate/gfx_converter.h

* refactor: deprecate mate::EventEmitter

* refactor: add gin_helper::EventEmitter

* refactor: convert a few classes to use gin_helper::EventEmitter

* refactor: get rid of native_mate_converters/gfx_converter.h

* fix: follow native_mate on reporting errors

* fix: gin is weak at guessing parameter types

* fix: incorrect full class name

* fix: gin::Handle does not accept null
Cheng Zhao 5 years ago
parent
commit
eb0e55c514
38 changed files with 532 additions and 326 deletions
  1. 5 3
      filenames.gni
  2. 14 0
      native_mate/native_mate/persistent_dictionary.h
  3. 1 1
      shell/browser/api/atom_api_app.h
  4. 2 5
      shell/browser/api/atom_api_auto_updater.cc
  5. 6 4
      shell/browser/api/atom_api_auto_updater.h
  6. 24 21
      shell/browser/api/atom_api_browser_view.cc
  7. 4 5
      shell/browser/api/atom_api_browser_view.h
  8. 11 11
      shell/browser/api/atom_api_desktop_capturer.cc
  9. 7 3
      shell/browser/api/atom_api_desktop_capturer.h
  10. 1 1
      shell/browser/api/atom_api_event.cc
  11. 20 24
      shell/browser/api/atom_api_in_app_purchase.cc
  12. 9 7
      shell/browser/api/atom_api_in_app_purchase.h
  13. 1 1
      shell/browser/api/atom_api_native_theme.h
  14. 1 1
      shell/browser/api/atom_api_net.h
  15. 7 6
      shell/browser/api/atom_api_screen.cc
  16. 3 2
      shell/browser/api/atom_api_screen.h
  17. 1 1
      shell/browser/api/atom_api_system_preferences.h
  18. 62 58
      shell/browser/api/atom_api_top_level_window.cc
  19. 27 24
      shell/browser/api/atom_api_top_level_window.h
  20. 32 24
      shell/browser/api/atom_api_tray.cc
  21. 19 14
      shell/browser/api/atom_api_tray.h
  22. 1 1
      shell/browser/api/atom_api_url_request_ns.h
  23. 23 11
      shell/browser/api/atom_api_web_contents.cc
  24. 1 1
      shell/browser/api/event_emitter_deprecated.cc
  25. 3 3
      shell/browser/api/event_emitter_deprecated.h
  26. 0 1
      shell/browser/api/frame_subscriber.cc
  27. 9 8
      shell/browser/api/trackable_object.h
  28. 8 0
      shell/common/gin_converters/std_converter.h
  29. 22 0
      shell/common/gin_helper/arguments.cc
  30. 17 0
      shell/common/gin_helper/arguments.h
  31. 67 0
      shell/common/gin_helper/event_emitter.cc
  32. 107 0
      shell/common/gin_helper/event_emitter.h
  33. 6 0
      shell/common/gin_helper/object_template_builder.cc
  34. 2 0
      shell/common/gin_helper/object_template_builder.h
  35. 0 78
      shell/common/native_mate_converters/gfx_converter.h
  36. 6 5
      shell/common/promise_util.h
  37. 0 1
      shell/renderer/api/atom_api_web_frame.cc
  38. 3 1
      spec-main/api-browser-window-spec.ts

+ 5 - 3
filenames.gni

@@ -112,8 +112,8 @@ filenames = {
     "shell/browser/api/atom_api_browser_window_views.cc",
     "shell/browser/api/event.cc",
     "shell/browser/api/event.h",
-    "shell/browser/api/event_emitter.cc",
-    "shell/browser/api/event_emitter.h",
+    "shell/browser/api/event_emitter_deprecated.cc",
+    "shell/browser/api/event_emitter_deprecated.h",
     "shell/browser/api/trackable_object.cc",
     "shell/browser/api/trackable_object.h",
     "shell/browser/api/frame_subscriber.cc",
@@ -485,6 +485,7 @@ filenames = {
     "shell/common/gin_converters/std_converter.h",
     "shell/common/gin_converters/blink_converter_gin_adapter.h",
     "shell/common/gin_converters/value_converter_gin_adapter.h",
+    "shell/common/gin_helper/arguments.cc",
     "shell/common/gin_helper/arguments.h",
     "shell/common/gin_helper/callback.cc",
     "shell/common/gin_helper/callback.h",
@@ -495,6 +496,8 @@ filenames = {
     "shell/common/gin_helper/error_thrower.h",
     "shell/common/gin_helper/event_emitter_caller.cc",
     "shell/common/gin_helper/event_emitter_caller.h",
+    "shell/common/gin_helper/event_emitter.cc",
+    "shell/common/gin_helper/event_emitter.h",
     "shell/common/gin_helper/function_template.cc",
     "shell/common/gin_helper/function_template.h",
     "shell/common/gin_helper/object_template_builder.cc",
@@ -520,7 +523,6 @@ filenames = {
     "shell/common/native_mate_converters/content_converter.h",
     "shell/common/native_mate_converters/file_dialog_converter.h",
     "shell/common/native_mate_converters/file_path_converter.h",
-    "shell/common/native_mate_converters/gfx_converter.h",
     "shell/common/native_mate_converters/gurl_converter.h",
     "shell/common/native_mate_converters/image_converter.h",
     "shell/common/native_mate_converters/native_window_converter.h",

+ 14 - 0
native_mate/native_mate/persistent_dictionary.h

@@ -34,4 +34,18 @@ struct Converter<PersistentDictionary> {
 
 }  // namespace mate
 
+namespace gin {
+
+// Keep compatibility with gin.
+template <>
+struct Converter<mate::PersistentDictionary> {
+  static bool FromV8(v8::Isolate* isolate,
+                     v8::Local<v8::Value> val,
+                     mate::PersistentDictionary* out) {
+    return mate::ConvertFromV8(isolate, val, out);
+  }
+};
+
+}  // namespace gin
+
 #endif  // NATIVE_MATE_NATIVE_MATE_PERSISTENT_DICTIONARY_H_

+ 1 - 1
shell/browser/api/atom_api_app.h

@@ -22,7 +22,7 @@
 #include "net/base/completion_once_callback.h"
 #include "net/base/completion_repeating_callback.h"
 #include "net/ssl/client_cert_identity.h"
-#include "shell/browser/api/event_emitter.h"
+#include "shell/browser/api/event_emitter_deprecated.h"
 #include "shell/browser/api/process_metric.h"
 #include "shell/browser/atom_browser_client.h"
 #include "shell/browser/browser.h"

+ 2 - 5
shell/browser/api/atom_api_auto_updater.cc

@@ -14,10 +14,7 @@
 #include "shell/common/gin_helper/object_template_builder.h"
 #include "shell/common/node_includes.h"
 
-// TODO(zcbenz): Remove this after removing mate::EventEmitter.
-#include "shell/common/native_mate_converters/callback_converter_deprecated.h"
-
-namespace mate {
+namespace gin {
 
 template <>
 struct Converter<base::Time> {
@@ -32,7 +29,7 @@ struct Converter<base::Time> {
   }
 };
 
-}  // namespace mate
+}  // namespace gin
 
 namespace electron {
 

+ 6 - 4
shell/browser/api/atom_api_auto_updater.h

@@ -8,17 +8,19 @@
 #include <string>
 
 #include "gin/handle.h"
-#include "shell/browser/api/event_emitter.h"
+#include "native_mate/wrappable.h"
 #include "shell/browser/auto_updater.h"
 #include "shell/browser/window_list_observer.h"
+#include "shell/common/gin_helper/event_emitter.h"
 
 namespace electron {
 
 namespace api {
 
-class AutoUpdater : public mate::EventEmitter<AutoUpdater>,
-                    public auto_updater::Delegate,
-                    public WindowListObserver {
+class AutoUpdater
+    : public gin_helper::EventEmitter<mate::Wrappable<AutoUpdater>>,
+      public auto_updater::Delegate,
+      public WindowListObserver {
  public:
   static gin::Handle<AutoUpdater> Create(v8::Isolate* isolate);
 

+ 24 - 21
shell/browser/api/atom_api_browser_view.cc

@@ -4,26 +4,26 @@
 
 #include "shell/browser/api/atom_api_browser_view.h"
 
-#include "native_mate/constructor.h"
 #include "native_mate/dictionary.h"
 #include "shell/browser/api/atom_api_web_contents.h"
 #include "shell/browser/browser.h"
 #include "shell/browser/native_browser_view.h"
 #include "shell/common/color_util.h"
-#include "shell/common/native_mate_converters/gfx_converter.h"
-#include "shell/common/native_mate_converters/value_converter.h"
+#include "shell/common/gin_converters/gfx_converter.h"
+#include "shell/common/gin_helper/dictionary.h"
+#include "shell/common/gin_helper/object_template_builder.h"
 #include "shell/common/node_includes.h"
 #include "shell/common/options_switches.h"
 #include "ui/gfx/geometry/rect.h"
 
-namespace mate {
+namespace gin {
 
 template <>
 struct Converter<electron::AutoResizeFlags> {
   static bool FromV8(v8::Isolate* isolate,
                      v8::Local<v8::Value> val,
                      electron::AutoResizeFlags* auto_resize_flags) {
-    mate::Dictionary params;
+    gin_helper::Dictionary params;
     if (!ConvertFromV8(isolate, val, &params)) {
       return false;
     }
@@ -51,20 +51,24 @@ struct Converter<electron::AutoResizeFlags> {
   }
 };
 
-}  // namespace mate
+}  // namespace gin
 
 namespace electron {
 
 namespace api {
 
 BrowserView::BrowserView(gin::Arguments* args,
-                         const mate::Dictionary& options) {
+                         const gin_helper::Dictionary& options) {
   v8::Isolate* isolate = args->isolate();
-  mate::Dictionary web_preferences = mate::Dictionary::CreateEmpty(isolate);
+  gin_helper::Dictionary web_preferences =
+      gin::Dictionary::CreateEmpty(isolate);
   options.Get(options::kWebPreferences, &web_preferences);
   web_preferences.Set("type", "browserView");
-  mate::Handle<class WebContents> web_contents =
-      WebContents::Create(isolate, web_preferences);
+  mate::Handle<class WebContents> web_contents = WebContents::Create(
+      isolate,
+      // TODO(zcbenz): No need to do convertion after converting constructor
+      // of WebContents to gin.
+      mate::Dictionary(isolate, web_preferences.GetHandle()));
 
   web_contents_.Reset(isolate, web_contents.ToV8());
   api_web_contents_ = web_contents.get();
@@ -97,7 +101,7 @@ mate::WrappableBase* BrowserView::New(gin_helper::ErrorThrower thrower,
     return nullptr;
   }
 
-  mate::Dictionary options = mate::Dictionary::CreateEmpty(args->isolate());
+  gin::Dictionary options = gin::Dictionary::CreateEmpty(args->isolate());
   args->GetNext(&options);
 
   return new BrowserView(args, options);
@@ -134,9 +138,9 @@ v8::Local<v8::Value> BrowserView::GetWebContents() {
 // static
 void BrowserView::BuildPrototype(v8::Isolate* isolate,
                                  v8::Local<v8::FunctionTemplate> prototype) {
-  prototype->SetClassName(mate::StringToV8(isolate, "BrowserView"));
+  prototype->SetClassName(gin::StringToV8(isolate, "BrowserView"));
   gin_helper::Destroyable::MakeDestroyable(isolate, prototype);
-  mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
+  gin_helper::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
       .SetMethod("setAutoResize", &BrowserView::SetAutoResize)
       .SetMethod("setBounds", &BrowserView::SetBounds)
       .SetMethod("getBounds", &BrowserView::GetBounds)
@@ -160,14 +164,13 @@ void Initialize(v8::Local<v8::Object> exports,
   v8::Isolate* isolate = context->GetIsolate();
   BrowserView::SetConstructor(isolate, base::BindRepeating(&BrowserView::New));
 
-  mate::Dictionary browser_view(isolate, BrowserView::GetConstructor(isolate)
-                                             ->GetFunction(context)
-                                             .ToLocalChecked());
-  browser_view.SetMethod("fromId",
-                         &mate::TrackableObject<BrowserView>::FromWeakMapID);
-  browser_view.SetMethod("getAllViews",
-                         &mate::TrackableObject<BrowserView>::GetAll);
-  mate::Dictionary dict(isolate, exports);
+  gin_helper::Dictionary browser_view(isolate,
+                                      BrowserView::GetConstructor(isolate)
+                                          ->GetFunction(context)
+                                          .ToLocalChecked());
+  browser_view.SetMethod("fromId", &BrowserView::FromWeakMapID);
+  browser_view.SetMethod("getAllViews", &BrowserView::GetAll);
+  gin_helper::Dictionary dict(isolate, exports);
   dict.Set("BrowserView", browser_view);
 }
 

+ 4 - 5
shell/browser/api/atom_api_browser_view.h

@@ -9,7 +9,7 @@
 #include <string>
 
 #include "content/public/browser/web_contents_observer.h"
-#include "native_mate/handle.h"
+#include "gin/handle.h"
 #include "shell/browser/api/trackable_object.h"
 #include "shell/browser/native_browser_view.h"
 #include "shell/common/gin_helper/error_thrower.h"
@@ -18,10 +18,9 @@ namespace gfx {
 class Rect;
 }
 
-namespace mate {
-class Arguments;
+namespace gin_helper {
 class Dictionary;
-}  // namespace mate
+}
 
 namespace electron {
 
@@ -46,7 +45,7 @@ class BrowserView : public mate::TrackableObject<BrowserView>,
   int32_t ID() const;
 
  protected:
-  BrowserView(gin::Arguments* args, const mate::Dictionary& options);
+  BrowserView(gin::Arguments* args, const gin_helper::Dictionary& options);
   ~BrowserView() override;
 
   // content::WebContentsObserver:

+ 11 - 11
shell/browser/api/atom_api_desktop_capturer.cc

@@ -14,9 +14,10 @@
 #include "chrome/browser/media/webrtc/desktop_media_list.h"
 #include "chrome/browser/media/webrtc/window_icon_util.h"
 #include "content/public/browser/desktop_capture.h"
-#include "native_mate/dictionary.h"
 #include "shell/common/api/atom_api_native_image.h"
-#include "shell/common/native_mate_converters/gfx_converter.h"
+#include "shell/common/gin_converters/gfx_converter.h"
+#include "shell/common/gin_helper/dictionary.h"
+#include "shell/common/gin_helper/object_template_builder.h"
 #include "shell/common/node_includes.h"
 #include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h"
 #include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h"
@@ -27,14 +28,14 @@
 #include "ui/display/win/display_info.h"
 #endif  // defined(OS_WIN)
 
-namespace mate {
+namespace gin {
 
 template <>
 struct Converter<electron::api::DesktopCapturer::Source> {
   static v8::Local<v8::Value> ToV8(
       v8::Isolate* isolate,
       const electron::api::DesktopCapturer::Source& source) {
-    mate::Dictionary dict(isolate, v8::Object::New(isolate));
+    gin_helper::Dictionary dict = gin::Dictionary::CreateEmpty(isolate);
     content::DesktopMediaID id = source.media_list_source.id;
     dict.Set("name", base::UTF16ToUTF8(source.media_list_source.name));
     dict.Set("id", id.ToString());
@@ -52,7 +53,7 @@ struct Converter<electron::api::DesktopCapturer::Source> {
   }
 };
 
-}  // namespace mate
+}  // namespace gin
 
 namespace electron {
 
@@ -181,16 +182,16 @@ void DesktopCapturer::UpdateSourcesList(DesktopMediaList* list) {
 }
 
 // static
-mate::Handle<DesktopCapturer> DesktopCapturer::Create(v8::Isolate* isolate) {
-  return mate::CreateHandle(isolate, new DesktopCapturer(isolate));
+gin::Handle<DesktopCapturer> DesktopCapturer::Create(v8::Isolate* isolate) {
+  return gin::CreateHandle(isolate, new DesktopCapturer(isolate));
 }
 
 // static
 void DesktopCapturer::BuildPrototype(
     v8::Isolate* isolate,
     v8::Local<v8::FunctionTemplate> prototype) {
-  prototype->SetClassName(mate::StringToV8(isolate, "DesktopCapturer"));
-  mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
+  prototype->SetClassName(gin::StringToV8(isolate, "DesktopCapturer"));
+  gin_helper::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
       .SetMethod("startHandling", &DesktopCapturer::StartHandling);
 }
 
@@ -204,8 +205,7 @@ void Initialize(v8::Local<v8::Object> exports,
                 v8::Local<v8::Value> unused,
                 v8::Local<v8::Context> context,
                 void* priv) {
-  v8::Isolate* isolate = context->GetIsolate();
-  mate::Dictionary dict(isolate, exports);
+  gin_helper::Dictionary dict(context->GetIsolate(), exports);
   dict.SetMethod("createDesktopCapturer",
                  &electron::api::DesktopCapturer::Create);
 }

+ 7 - 3
shell/browser/api/atom_api_desktop_capturer.h

@@ -11,14 +11,18 @@
 
 #include "chrome/browser/media/webrtc/desktop_media_list_observer.h"
 #include "chrome/browser/media/webrtc/native_desktop_media_list.h"
-#include "native_mate/handle.h"
+#include "gin/handle.h"
 #include "shell/browser/api/trackable_object.h"
+#include "shell/common/gin_helper/event_emitter.h"
 
 namespace electron {
 
 namespace api {
 
-class DesktopCapturer : public mate::TrackableObject<DesktopCapturer> {
+class DesktopCapturer
+    : public mate::TrackableObject<
+          DesktopCapturer,
+          gin_helper::EventEmitter<mate::Wrappable<DesktopCapturer>>> {
  public:
   struct Source {
     DesktopMediaList::Source media_list_source;
@@ -29,7 +33,7 @@ class DesktopCapturer : public mate::TrackableObject<DesktopCapturer> {
     bool fetch_icon = false;
   };
 
-  static mate::Handle<DesktopCapturer> Create(v8::Isolate* isolate);
+  static gin::Handle<DesktopCapturer> Create(v8::Isolate* isolate);
 
   static void BuildPrototype(v8::Isolate* isolate,
                              v8::Local<v8::FunctionTemplate> prototype);

+ 1 - 1
shell/browser/api/atom_api_event.cc

@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 #include "native_mate/dictionary.h"
-#include "shell/browser/api/event_emitter.h"
+#include "shell/browser/api/event_emitter_deprecated.h"
 #include "shell/common/node_includes.h"
 
 namespace {

+ 20 - 24
shell/browser/api/atom_api_in_app_purchase.cc

@@ -8,19 +8,18 @@
 #include <utility>
 #include <vector>
 
-#include "native_mate/dictionary.h"
 #include "shell/common/gin_helper/dictionary.h"
+#include "shell/common/gin_helper/object_template_builder.h"
 #include "shell/common/node_includes.h"
 
-namespace mate {
+namespace gin {
 
 template <>
 struct Converter<in_app_purchase::Payment> {
   static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
                                    const in_app_purchase::Payment& payment) {
-    mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
-    // TODO(zcbenz): Just call SetHidden when this file is converted to gin.
-    gin_helper::Dictionary(isolate, dict.GetHandle()).SetHidden("simple", true);
+    gin_helper::Dictionary dict = gin::Dictionary::CreateEmpty(isolate);
+    dict.SetHidden("simple", true);
     dict.Set("productIdentifier", payment.productIdentifier);
     dict.Set("quantity", payment.quantity);
     return dict.GetHandle();
@@ -31,9 +30,8 @@ template <>
 struct Converter<in_app_purchase::Transaction> {
   static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
                                    const in_app_purchase::Transaction& val) {
-    mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
-    // TODO(zcbenz): Just call SetHidden when this file is converted to gin.
-    gin_helper::Dictionary(isolate, dict.GetHandle()).SetHidden("simple", true);
+    gin_helper::Dictionary dict = gin::Dictionary::CreateEmpty(isolate);
+    dict.SetHidden("simple", true);
     dict.Set("transactionIdentifier", val.transactionIdentifier);
     dict.Set("transactionDate", val.transactionDate);
     dict.Set("originalTransactionIdentifier",
@@ -50,9 +48,8 @@ template <>
 struct Converter<in_app_purchase::Product> {
   static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
                                    const in_app_purchase::Product& val) {
-    mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
-    // TODO(zcbenz): Just call SetHidden when this file is converted to gin.
-    gin_helper::Dictionary(isolate, dict.GetHandle()).SetHidden("simple", true);
+    gin_helper::Dictionary dict = gin::Dictionary::CreateEmpty(isolate);
+    dict.SetHidden("simple", true);
     dict.Set("productIdentifier", val.productIdentifier);
     dict.Set("localizedDescription", val.localizedDescription);
     dict.Set("localizedTitle", val.localizedTitle);
@@ -70,7 +67,7 @@ struct Converter<in_app_purchase::Product> {
   }
 };
 
-}  // namespace mate
+}  // namespace gin
 
 namespace electron {
 
@@ -78,15 +75,15 @@ namespace api {
 
 #if defined(OS_MACOSX)
 // static
-mate::Handle<InAppPurchase> InAppPurchase::Create(v8::Isolate* isolate) {
-  return mate::CreateHandle(isolate, new InAppPurchase(isolate));
+gin::Handle<InAppPurchase> InAppPurchase::Create(v8::Isolate* isolate) {
+  return gin::CreateHandle(isolate, new InAppPurchase(isolate));
 }
 
 // static
 void InAppPurchase::BuildPrototype(v8::Isolate* isolate,
                                    v8::Local<v8::FunctionTemplate> prototype) {
-  prototype->SetClassName(mate::StringToV8(isolate, "InAppPurchase"));
-  mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
+  prototype->SetClassName(gin::StringToV8(isolate, "InAppPurchase"));
+  gin_helper::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
       .SetMethod("canMakePayments", &in_app_purchase::CanMakePayments)
       .SetMethod("getReceiptURL", &in_app_purchase::GetReceiptURL)
       .SetMethod("purchaseProduct", &InAppPurchase::PurchaseProduct)
@@ -105,7 +102,7 @@ InAppPurchase::~InAppPurchase() {}
 
 v8::Local<v8::Promise> InAppPurchase::PurchaseProduct(
     const std::string& product_id,
-    mate::Arguments* args) {
+    gin::Arguments* args) {
   v8::Isolate* isolate = args->isolate();
   electron::util::Promise<bool> promise(isolate);
   v8::Local<v8::Promise> handle = promise.GetHandle();
@@ -115,15 +112,14 @@ v8::Local<v8::Promise> InAppPurchase::PurchaseProduct(
 
   in_app_purchase::PurchaseProduct(
       product_id, quantity,
-      base::BindOnce(electron::util::Promise<bool>::ResolvePromise,
-                     std::move(promise)));
+      base::BindOnce(util::Promise<bool>::ResolvePromise, std::move(promise)));
 
   return handle;
 }
 
 v8::Local<v8::Promise> InAppPurchase::GetProducts(
     const std::vector<std::string>& productIDs,
-    mate::Arguments* args) {
+    gin::Arguments* args) {
   v8::Isolate* isolate = args->isolate();
   electron::util::Promise<std::vector<in_app_purchase::Product>> promise(
       isolate);
@@ -131,9 +127,9 @@ v8::Local<v8::Promise> InAppPurchase::GetProducts(
 
   in_app_purchase::GetProducts(
       productIDs,
-      base::BindOnce(electron::util::Promise<
-                         std::vector<in_app_purchase::Product>>::ResolvePromise,
-                     std::move(promise)));
+      base::BindOnce(
+          util::Promise<std::vector<in_app_purchase::Product>>::ResolvePromise,
+          std::move(promise)));
 
   return handle;
 }
@@ -158,7 +154,7 @@ void Initialize(v8::Local<v8::Object> exports,
                 void* priv) {
 #if defined(OS_MACOSX)
   v8::Isolate* isolate = context->GetIsolate();
-  mate::Dictionary dict(isolate, exports);
+  gin_helper::Dictionary dict(isolate, exports);
   dict.Set("inAppPurchase", InAppPurchase::Create(isolate));
   dict.Set("InAppPurchase", InAppPurchase::GetConstructor(isolate)
                                 ->GetFunction(context)

+ 9 - 7
shell/browser/api/atom_api_in_app_purchase.h

@@ -8,21 +8,23 @@
 #include <string>
 #include <vector>
 
-#include "native_mate/handle.h"
-#include "shell/browser/api/event_emitter.h"
+#include "gin/handle.h"
+#include "native_mate/wrappable.h"
 #include "shell/browser/mac/in_app_purchase.h"
 #include "shell/browser/mac/in_app_purchase_observer.h"
 #include "shell/browser/mac/in_app_purchase_product.h"
+#include "shell/common/gin_helper/event_emitter.h"
 #include "shell/common/promise_util.h"
 
 namespace electron {
 
 namespace api {
 
-class InAppPurchase : public mate::EventEmitter<InAppPurchase>,
-                      public in_app_purchase::TransactionObserver {
+class InAppPurchase
+    : public gin_helper::EventEmitter<mate::Wrappable<InAppPurchase>>,
+      public in_app_purchase::TransactionObserver {
  public:
-  static mate::Handle<InAppPurchase> Create(v8::Isolate* isolate);
+  static gin::Handle<InAppPurchase> Create(v8::Isolate* isolate);
 
   static void BuildPrototype(v8::Isolate* isolate,
                              v8::Local<v8::FunctionTemplate> prototype);
@@ -32,10 +34,10 @@ class InAppPurchase : public mate::EventEmitter<InAppPurchase>,
   ~InAppPurchase() override;
 
   v8::Local<v8::Promise> PurchaseProduct(const std::string& product_id,
-                                         mate::Arguments* args);
+                                         gin::Arguments* args);
 
   v8::Local<v8::Promise> GetProducts(const std::vector<std::string>& productIDs,
-                                     mate::Arguments* args);
+                                     gin::Arguments* args);
 
   // TransactionObserver:
   void OnTransactionsUpdated(

+ 1 - 1
shell/browser/api/atom_api_native_theme.h

@@ -5,7 +5,7 @@
 #ifndef SHELL_BROWSER_API_ATOM_API_NATIVE_THEME_H_
 #define SHELL_BROWSER_API_ATOM_API_NATIVE_THEME_H_
 
-#include "shell/browser/api/event_emitter.h"
+#include "shell/browser/api/event_emitter_deprecated.h"
 #include "ui/native_theme/native_theme.h"
 #include "ui/native_theme/native_theme_observer.h"
 

+ 1 - 1
shell/browser/api/atom_api_net.h

@@ -5,7 +5,7 @@
 #ifndef SHELL_BROWSER_API_ATOM_API_NET_H_
 #define SHELL_BROWSER_API_ATOM_API_NET_H_
 
-#include "shell/browser/api/event_emitter.h"
+#include "shell/browser/api/event_emitter_deprecated.h"
 
 namespace electron {
 

+ 7 - 6
shell/browser/api/atom_api_screen.cc

@@ -9,11 +9,12 @@
 
 #include "base/bind.h"
 #include "gin/dictionary.h"
+#include "gin/handle.h"
 #include "shell/browser/browser.h"
 #include "shell/common/gin_converters/callback_converter.h"
+#include "shell/common/gin_converters/gfx_converter.h"
+#include "shell/common/gin_converters/native_window_converter.h"
 #include "shell/common/gin_helper/object_template_builder.h"
-#include "shell/common/native_mate_converters/gfx_converter.h"
-#include "shell/common/native_mate_converters/native_window_converter.h"
 #include "shell/common/node_includes.h"
 #include "ui/display/display.h"
 #include "ui/display/screen.h"
@@ -147,16 +148,16 @@ v8::Local<v8::Value> Screen::Create(gin_helper::ErrorThrower error_thrower) {
     return v8::Null(error_thrower.isolate());
   }
 
-  return mate::CreateHandle(error_thrower.isolate(),
-                            new Screen(error_thrower.isolate(), screen))
+  return gin::CreateHandle(error_thrower.isolate(),
+                           new Screen(error_thrower.isolate(), screen))
       .ToV8();
 }
 
 // static
 void Screen::BuildPrototype(v8::Isolate* isolate,
                             v8::Local<v8::FunctionTemplate> prototype) {
-  prototype->SetClassName(mate::StringToV8(isolate, "Screen"));
-  mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
+  prototype->SetClassName(gin::StringToV8(isolate, "Screen"));
+  gin_helper::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
       .SetMethod("getCursorScreenPoint", &Screen::GetCursorScreenPoint)
       .SetMethod("getPrimaryDisplay", &Screen::GetPrimaryDisplay)
       .SetMethod("getAllDisplays", &Screen::GetAllDisplays)

+ 3 - 2
shell/browser/api/atom_api_screen.h

@@ -7,8 +7,9 @@
 
 #include <vector>
 
-#include "shell/browser/api/event_emitter.h"
+#include "native_mate/wrappable.h"
 #include "shell/common/gin_helper/error_thrower.h"
+#include "shell/common/gin_helper/event_emitter.h"
 #include "ui/display/display_observer.h"
 #include "ui/display/screen.h"
 
@@ -22,7 +23,7 @@ namespace electron {
 
 namespace api {
 
-class Screen : public mate::EventEmitter<Screen>,
+class Screen : public gin_helper::EventEmitter<mate::Wrappable<Screen>>,
                public display::DisplayObserver {
  public:
   static v8::Local<v8::Value> Create(gin_helper::ErrorThrower error_thrower);

+ 1 - 1
shell/browser/api/atom_api_system_preferences.h

@@ -11,7 +11,7 @@
 #include "base/callback.h"
 #include "base/values.h"
 #include "native_mate/handle.h"
-#include "shell/browser/api/event_emitter.h"
+#include "shell/browser/api/event_emitter_deprecated.h"
 #include "shell/common/gin_helper/error_thrower.h"
 #include "shell/common/promise_util.h"
 

+ 62 - 58
shell/browser/api/atom_api_top_level_window.cc

@@ -9,7 +9,6 @@
 
 #include "electron/buildflags/buildflags.h"
 #include "gin/dictionary.h"
-#include "native_mate/handle.h"
 #include "native_mate/persistent_dictionary.h"
 #include "shell/browser/api/atom_api_browser_view.h"
 #include "shell/browser/api/atom_api_menu.h"
@@ -17,13 +16,13 @@
 #include "shell/browser/api/atom_api_web_contents.h"
 #include "shell/common/color_util.h"
 #include "shell/common/gin_converters/callback_converter.h"
+#include "shell/common/gin_converters/file_path_converter.h"
+#include "shell/common/gin_converters/gfx_converter.h"
 #include "shell/common/gin_converters/image_converter.h"
-#include "shell/common/native_mate_converters/file_path_converter.h"
-#include "shell/common/native_mate_converters/gfx_converter.h"
-#include "shell/common/native_mate_converters/image_converter.h"
-#include "shell/common/native_mate_converters/native_window_converter.h"
-#include "shell/common/native_mate_converters/string16_converter.h"
-#include "shell/common/native_mate_converters/value_converter.h"
+#include "shell/common/gin_converters/native_window_converter.h"
+#include "shell/common/gin_converters/value_converter_gin_adapter.h"
+#include "shell/common/gin_helper/dictionary.h"
+#include "shell/common/gin_helper/object_template_builder.h"
 #include "shell/common/node_includes.h"
 #include "shell/common/options_switches.h"
 
@@ -36,11 +35,8 @@
 #include "ui/base/win/shell.h"
 #endif
 
-// TODO(zcbenz): Remove this after removing mate::ObjectTemplateBuilder.
-#include "shell/common/native_mate_converters/callback_converter_deprecated.h"
-
 #if defined(OS_WIN)
-namespace mate {
+namespace gin {
 
 template <>
 struct Converter<electron::TaskbarHost::ThumbarButton> {
@@ -57,7 +53,7 @@ struct Converter<electron::TaskbarHost::ThumbarButton> {
   }
 };
 
-}  // namespace mate
+}  // namespace gin
 #endif
 
 namespace electron {
@@ -87,11 +83,11 @@ TopLevelWindow::TopLevelWindow(v8::Isolate* isolate,
 
 #if BUILDFLAG(ENABLE_OSR)
   // Offscreen windows are always created frameless.
-  mate::Dictionary web_preferences;
+  gin_helper::Dictionary web_preferences;
   bool offscreen;
   if (options.Get(options::kWebPreferences, &web_preferences) &&
       web_preferences.Get(options::kOffscreen, &offscreen) && offscreen) {
-    const_cast<mate::Dictionary&>(options).Set(options::kFrame, false);
+    const_cast<gin_helper::Dictionary&>(options).Set(options::kFrame, false);
   }
 #endif
 
@@ -108,7 +104,7 @@ TopLevelWindow::TopLevelWindow(v8::Isolate* isolate,
 #endif
 }
 
-TopLevelWindow::TopLevelWindow(gin::Arguments* args,
+TopLevelWindow::TopLevelWindow(gin_helper::Arguments* args,
                                const mate::Dictionary& options)
     : TopLevelWindow(args->isolate(), options) {
   InitWithArgs(args);
@@ -128,13 +124,16 @@ TopLevelWindow::~TopLevelWindow() {
 void TopLevelWindow::InitWith(v8::Isolate* isolate,
                               v8::Local<v8::Object> wrapper) {
   AttachAsUserData(window_.get());
-  mate::TrackableObject<TopLevelWindow>::InitWith(isolate, wrapper);
+  mate::TrackableObject<
+      TopLevelWindow, gin_helper::EventEmitter<
+                          mate::Wrappable<TopLevelWindow>>>::InitWith(isolate,
+                                                                      wrapper);
 
   // We can only append this window to parent window's child windows after this
   // window's JS wrapper gets initialized.
   if (!parent_window_.IsEmpty()) {
     mate::Handle<TopLevelWindow> parent;
-    mate::ConvertFromV8(isolate, GetParentWindow(), &parent);
+    gin::ConvertFromV8(isolate, GetParentWindow(), &parent);
     DCHECK(!parent.IsEmpty());
     parent->child_windows_.Set(isolate, weak_map_id(), wrapper);
   }
@@ -381,7 +380,8 @@ bool TopLevelWindow::IsFullscreen() {
   return window_->IsFullscreen();
 }
 
-void TopLevelWindow::SetBounds(const gfx::Rect& bounds, mate::Arguments* args) {
+void TopLevelWindow::SetBounds(const gfx::Rect& bounds,
+                               gin_helper::Arguments* args) {
   bool animate = false;
   args->GetNext(&animate);
   window_->SetBounds(bounds, animate);
@@ -400,7 +400,7 @@ gfx::Rect TopLevelWindow::GetNormalBounds() {
 }
 
 void TopLevelWindow::SetContentBounds(const gfx::Rect& bounds,
-                                      mate::Arguments* args) {
+                                      gin_helper::Arguments* args) {
   bool animate = false;
   args->GetNext(&animate);
   window_->SetContentBounds(bounds, animate);
@@ -410,7 +410,9 @@ gfx::Rect TopLevelWindow::GetContentBounds() {
   return window_->GetContentBounds();
 }
 
-void TopLevelWindow::SetSize(int width, int height, mate::Arguments* args) {
+void TopLevelWindow::SetSize(int width,
+                             int height,
+                             gin_helper::Arguments* args) {
   bool animate = false;
   gfx::Size size = window_->GetMinimumSize();
   size.SetToMax(gfx::Size(width, height));
@@ -428,7 +430,7 @@ std::vector<int> TopLevelWindow::GetSize() {
 
 void TopLevelWindow::SetContentSize(int width,
                                     int height,
-                                    mate::Arguments* args) {
+                                    gin_helper::Arguments* args) {
   bool animate = false;
   args->GetNext(&animate);
   window_->SetContentSize(gfx::Size(width, height), animate);
@@ -466,7 +468,8 @@ std::vector<int> TopLevelWindow::GetMaximumSize() {
   return result;
 }
 
-void TopLevelWindow::SetSheetOffset(double offsetY, mate::Arguments* args) {
+void TopLevelWindow::SetSheetOffset(double offsetY,
+                                    gin_helper::Arguments* args) {
   double offsetX = 0.0;
   args->GetNext(&offsetX);
   window_->SetSheetOffset(offsetX, offsetY);
@@ -520,7 +523,7 @@ bool TopLevelWindow::IsClosable() {
   return window_->IsClosable();
 }
 
-void TopLevelWindow::SetAlwaysOnTop(bool top, mate::Arguments* args) {
+void TopLevelWindow::SetAlwaysOnTop(bool top, gin_helper::Arguments* args) {
   std::string level = "floating";
   int relative_level = 0;
   args->GetNext(&level);
@@ -539,7 +542,7 @@ void TopLevelWindow::Center() {
   window_->Center();
 }
 
-void TopLevelWindow::SetPosition(int x, int y, mate::Arguments* args) {
+void TopLevelWindow::SetPosition(int x, int y, gin_helper::Arguments* args) {
   bool animate = false;
   args->GetNext(&animate);
   window_->SetPosition(gfx::Point(x, y), animate);
@@ -553,7 +556,7 @@ std::vector<int> TopLevelWindow::GetPosition() {
   return result;
 }
 void TopLevelWindow::MoveAbove(const std::string& sourceId,
-                               mate::Arguments* args) {
+                               gin_helper::Arguments* args) {
 #if BUILDFLAG(ENABLE_DESKTOP_CAPTURER)
   if (!window_->MoveAbove(sourceId))
     args->ThrowError("Invalid media source id");
@@ -655,8 +658,9 @@ bool TopLevelWindow::IsDocumentEdited() {
   return window_->IsDocumentEdited();
 }
 
-void TopLevelWindow::SetIgnoreMouseEvents(bool ignore, mate::Arguments* args) {
-  mate::Dictionary options;
+void TopLevelWindow::SetIgnoreMouseEvents(bool ignore,
+                                          gin_helper::Arguments* args) {
+  gin_helper::Dictionary options;
   bool forward = false;
   args->GetNext(&options) && options.Get("forward", &forward);
   return window_->SetIgnoreMouseEvents(ignore, forward);
@@ -676,7 +680,7 @@ void TopLevelWindow::SetMenu(v8::Isolate* isolate, v8::Local<v8::Value> value) {
   v8::Local<v8::Object> object;
   if (value->IsObject() && value->ToObject(context).ToLocal(&object) &&
       gin::V8ToString(isolate, object->GetConstructorName()) == "Menu" &&
-      mate::ConvertFromV8(isolate, value, &menu) && !menu.IsEmpty()) {
+      gin::ConvertFromV8(isolate, value, &menu) && !menu.IsEmpty()) {
     menu_.Reset(isolate, menu.ToV8());
     window_->SetMenu(menu->model());
   } else if (value->IsNull()) {
@@ -684,7 +688,7 @@ void TopLevelWindow::SetMenu(v8::Isolate* isolate, v8::Local<v8::Value> value) {
     window_->SetMenu(nullptr);
   } else {
     isolate->ThrowException(
-        v8::Exception::TypeError(mate::StringToV8(isolate, "Invalid Menu")));
+        v8::Exception::TypeError(gin::StringToV8(isolate, "Invalid Menu")));
   }
 }
 
@@ -694,7 +698,7 @@ void TopLevelWindow::RemoveMenu() {
 }
 
 void TopLevelWindow::SetParentWindow(v8::Local<v8::Value> value,
-                                     mate::Arguments* args) {
+                                     gin_helper::Arguments* args) {
   if (IsModal()) {
     args->ThrowError("Can not be called for modal window");
     return;
@@ -723,7 +727,7 @@ void TopLevelWindow::SetBrowserView(v8::Local<v8::Value> value) {
 void TopLevelWindow::AddBrowserView(v8::Local<v8::Value> value) {
   mate::Handle<BrowserView> browser_view;
   if (value->IsObject() &&
-      mate::ConvertFromV8(isolate(), value, &browser_view)) {
+      gin::ConvertFromV8(isolate(), value, &browser_view)) {
     auto get_that_view = browser_views_.find(browser_view->weak_map_id());
     if (get_that_view == browser_views_.end()) {
       window_->AddBrowserView(browser_view->view());
@@ -736,7 +740,7 @@ void TopLevelWindow::AddBrowserView(v8::Local<v8::Value> value) {
 void TopLevelWindow::RemoveBrowserView(v8::Local<v8::Value> value) {
   mate::Handle<BrowserView> browser_view;
   if (value->IsObject() &&
-      mate::ConvertFromV8(isolate(), value, &browser_view)) {
+      gin::ConvertFromV8(isolate(), value, &browser_view)) {
     auto get_that_view = browser_views_.find(browser_view->weak_map_id());
     if (get_that_view != browser_views_.end()) {
       window_->RemoveBrowserView(browser_view->view());
@@ -760,8 +764,9 @@ v8::Local<v8::Value> TopLevelWindow::GetNativeWindowHandle() {
   return ToBuffer(isolate(), &handle, sizeof(handle));
 }
 
-void TopLevelWindow::SetProgressBar(double progress, mate::Arguments* args) {
-  mate::Dictionary options;
+void TopLevelWindow::SetProgressBar(double progress,
+                                    gin_helper::Arguments* args) {
+  gin_helper::Dictionary options;
   std::string mode;
   args->GetNext(&options) && options.Get("mode", &mode);
 
@@ -784,8 +789,8 @@ void TopLevelWindow::SetOverlayIcon(const gfx::Image& overlay,
 }
 
 void TopLevelWindow::SetVisibleOnAllWorkspaces(bool visible,
-                                               mate::Arguments* args) {
-  mate::Dictionary options;
+                                               gin_helper::Arguments* args) {
+  gin_helper::Dictionary options;
   bool visibleOnFullScreen = false;
   args->GetNext(&options) &&
       options.Get("visibleOnFullScreen", &visibleOnFullScreen);
@@ -841,13 +846,13 @@ void TopLevelWindow::ToggleTabBar() {
 }
 
 void TopLevelWindow::AddTabbedWindow(NativeWindow* window,
-                                     mate::Arguments* args) {
+                                     gin_helper::Arguments* args) {
   if (!window_->AddTabbedWindow(window))
     args->ThrowError("AddTabbedWindow cannot be called by a window on itself.");
 }
 
 void TopLevelWindow::SetWindowButtonVisibility(bool visible,
-                                               mate::Arguments* args) {
+                                               gin_helper::Arguments* args) {
   if (!window_->SetWindowButtonVisibility(visible)) {
     args->ThrowError("Not supported for this window");
   }
@@ -870,14 +875,14 @@ bool TopLevelWindow::IsMenuBarVisible() {
 }
 
 void TopLevelWindow::SetAspectRatio(double aspect_ratio,
-                                    mate::Arguments* args) {
+                                    gin_helper::Arguments* args) {
   gfx::Size extra_size;
   args->GetNext(&extra_size);
   window_->SetAspectRatio(aspect_ratio, extra_size);
 }
 
 void TopLevelWindow::PreviewFile(const std::string& path,
-                                 mate::Arguments* args) {
+                                 gin_helper::Arguments* args) {
   std::string display_name;
   if (!args->GetNext(&display_name))
     display_name = path;
@@ -911,7 +916,7 @@ std::vector<v8::Local<v8::Object>> TopLevelWindow::GetChildWindows() const {
 }
 
 v8::Local<v8::Value> TopLevelWindow::GetBrowserView(
-    mate::Arguments* args) const {
+    gin_helper::Arguments* args) const {
   if (browser_views_.size() == 0) {
     return v8::Null(isolate());
   } else if (browser_views_.size() == 1) {
@@ -939,7 +944,7 @@ bool TopLevelWindow::IsModal() const {
   return window_->is_modal();
 }
 
-bool TopLevelWindow::SetThumbarButtons(mate::Arguments* args) {
+bool TopLevelWindow::SetThumbarButtons(gin_helper::Arguments* args) {
 #if defined(OS_WIN)
   std::vector<TaskbarHost::ThumbarButton> buttons;
   if (!args->GetNext(&buttons)) {
@@ -998,7 +1003,7 @@ bool TopLevelWindow::SetThumbnailToolTip(const std::string& tooltip) {
       window_->GetAcceleratedWidget(), tooltip);
 }
 
-void TopLevelWindow::SetAppDetails(const mate::Dictionary& options) {
+void TopLevelWindow::SetAppDetails(const gin_helper::Dictionary& options) {
   base::string16 app_id;
   base::FilePath app_icon_path;
   int app_icon_index = 0;
@@ -1024,9 +1029,9 @@ int32_t TopLevelWindow::GetID() const {
 void TopLevelWindow::ResetBrowserViews() {
   for (auto& item : browser_views_) {
     mate::Handle<BrowserView> browser_view;
-    if (mate::ConvertFromV8(isolate(),
-                            v8::Local<v8::Value>::New(isolate(), item.second),
-                            &browser_view) &&
+    if (gin::ConvertFromV8(isolate(),
+                           v8::Local<v8::Value>::New(isolate(), item.second),
+                           &browser_view) &&
         !browser_view.IsEmpty()) {
       window_->RemoveBrowserView(browser_view->view());
       browser_view->web_contents()->SetOwnerWindow(nullptr);
@@ -1043,7 +1048,7 @@ void TopLevelWindow::RemoveFromParentChildWindows() {
     return;
 
   mate::Handle<TopLevelWindow> parent;
-  if (!mate::ConvertFromV8(isolate(), GetParentWindow(), &parent) ||
+  if (!gin::ConvertFromV8(isolate(), GetParentWindow(), &parent) ||
       parent.IsEmpty()) {
     return;
   }
@@ -1052,7 +1057,7 @@ void TopLevelWindow::RemoveFromParentChildWindows() {
 }
 
 // static
-mate::WrappableBase* TopLevelWindow::New(gin::Arguments* args) {
+mate::WrappableBase* TopLevelWindow::New(gin_helper::Arguments* args) {
   mate::Dictionary options = mate::Dictionary::CreateEmpty(args->isolate());
   args->GetNext(&options);
 
@@ -1062,9 +1067,9 @@ mate::WrappableBase* TopLevelWindow::New(gin::Arguments* args) {
 // static
 void TopLevelWindow::BuildPrototype(v8::Isolate* isolate,
                                     v8::Local<v8::FunctionTemplate> prototype) {
-  prototype->SetClassName(mate::StringToV8(isolate, "TopLevelWindow"));
+  prototype->SetClassName(gin::StringToV8(isolate, "TopLevelWindow"));
   gin_helper::Destroyable::MakeDestroyable(isolate, prototype);
-  mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
+  gin_helper::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
       .SetMethod("setContentView", &TopLevelWindow::SetContentView)
       .SetMethod("close", &TopLevelWindow::Close)
       .SetMethod("focus", &TopLevelWindow::Focus)
@@ -1240,15 +1245,14 @@ void Initialize(v8::Local<v8::Object> exports,
   TopLevelWindow::SetConstructor(isolate,
                                  base::BindRepeating(&TopLevelWindow::New));
 
-  mate::Dictionary constructor(isolate, TopLevelWindow::GetConstructor(isolate)
-                                            ->GetFunction(context)
-                                            .ToLocalChecked());
-  constructor.SetMethod("fromId",
-                        &mate::TrackableObject<TopLevelWindow>::FromWeakMapID);
-  constructor.SetMethod("getAllWindows",
-                        &mate::TrackableObject<TopLevelWindow>::GetAll);
+  gin_helper::Dictionary constructor(isolate,
+                                     TopLevelWindow::GetConstructor(isolate)
+                                         ->GetFunction(context)
+                                         .ToLocalChecked());
+  constructor.SetMethod("fromId", &TopLevelWindow::FromWeakMapID);
+  constructor.SetMethod("getAllWindows", &TopLevelWindow::GetAll);
 
-  mate::Dictionary dict(isolate, exports);
+  gin_helper::Dictionary dict(isolate, exports);
   dict.Set("TopLevelWindow", constructor);
 }
 

+ 27 - 24
shell/browser/api/atom_api_top_level_window.h

@@ -13,11 +13,11 @@
 #include "base/task/post_task.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
-#include "native_mate/handle.h"
 #include "shell/browser/api/trackable_object.h"
 #include "shell/browser/native_window.h"
 #include "shell/browser/native_window_observer.h"
 #include "shell/common/api/atom_api_native_image.h"
+#include "shell/common/gin_helper/event_emitter.h"
 
 namespace electron {
 
@@ -25,10 +25,13 @@ namespace api {
 
 class View;
 
-class TopLevelWindow : public mate::TrackableObject<TopLevelWindow>,
-                       public NativeWindowObserver {
+class TopLevelWindow
+    : public mate::TrackableObject<
+          TopLevelWindow,
+          gin_helper::EventEmitter<mate::Wrappable<TopLevelWindow>>>,
+      public NativeWindowObserver {
  public:
-  static mate::WrappableBase* New(gin::Arguments* args);
+  static mate::WrappableBase* New(gin_helper::Arguments* args);
 
   static void BuildPrototype(v8::Isolate* isolate,
                              v8::Local<v8::FunctionTemplate> prototype);
@@ -43,7 +46,7 @@ class TopLevelWindow : public mate::TrackableObject<TopLevelWindow>,
   // Common constructor.
   TopLevelWindow(v8::Isolate* isolate, const mate::Dictionary& options);
   // Creating independent TopLevelWindow instance.
-  TopLevelWindow(gin::Arguments* args, const mate::Dictionary& options);
+  TopLevelWindow(gin_helper::Arguments* args, const mate::Dictionary& options);
   ~TopLevelWindow() override;
 
   // TrackableObject:
@@ -107,13 +110,13 @@ class TopLevelWindow : public mate::TrackableObject<TopLevelWindow>,
   bool IsMinimized();
   void SetFullScreen(bool fullscreen);
   bool IsFullscreen();
-  void SetBounds(const gfx::Rect& bounds, mate::Arguments* args);
+  void SetBounds(const gfx::Rect& bounds, gin_helper::Arguments* args);
   gfx::Rect GetBounds();
-  void SetSize(int width, int height, mate::Arguments* args);
+  void SetSize(int width, int height, gin_helper::Arguments* args);
   std::vector<int> GetSize();
-  void SetContentSize(int width, int height, mate::Arguments* args);
+  void SetContentSize(int width, int height, gin_helper::Arguments* args);
   std::vector<int> GetContentSize();
-  void SetContentBounds(const gfx::Rect& bounds, mate::Arguments* args);
+  void SetContentBounds(const gfx::Rect& bounds, gin_helper::Arguments* args);
   gfx::Rect GetContentBounds();
   bool IsNormal();
   gfx::Rect GetNormalBounds();
@@ -121,11 +124,11 @@ class TopLevelWindow : public mate::TrackableObject<TopLevelWindow>,
   std::vector<int> GetMinimumSize();
   void SetMaximumSize(int width, int height);
   std::vector<int> GetMaximumSize();
-  void SetSheetOffset(double offsetY, mate::Arguments* args);
+  void SetSheetOffset(double offsetY, gin_helper::Arguments* args);
   void SetResizable(bool resizable);
   bool IsResizable();
   void SetMovable(bool movable);
-  void MoveAbove(const std::string& sourceId, mate::Arguments* args);
+  void MoveAbove(const std::string& sourceId, gin_helper::Arguments* args);
   void MoveTop();
   bool IsMovable();
   void SetMinimizable(bool minimizable);
@@ -136,10 +139,10 @@ class TopLevelWindow : public mate::TrackableObject<TopLevelWindow>,
   bool IsFullScreenable();
   void SetClosable(bool closable);
   bool IsClosable();
-  void SetAlwaysOnTop(bool top, mate::Arguments* args);
+  void SetAlwaysOnTop(bool top, gin_helper::Arguments* args);
   bool IsAlwaysOnTop();
   void Center();
-  void SetPosition(int x, int y, mate::Arguments* args);
+  void SetPosition(int x, int y, gin_helper::Arguments* args);
   std::vector<int> GetPosition();
   void SetTitle(const std::string& title);
   std::string GetTitle();
@@ -163,12 +166,12 @@ class TopLevelWindow : public mate::TrackableObject<TopLevelWindow>,
   std::string GetRepresentedFilename();
   void SetDocumentEdited(bool edited);
   bool IsDocumentEdited();
-  void SetIgnoreMouseEvents(bool ignore, mate::Arguments* args);
+  void SetIgnoreMouseEvents(bool ignore, gin_helper::Arguments* args);
   void SetContentProtection(bool enable);
   void SetFocusable(bool focusable);
   void SetMenu(v8::Isolate* isolate, v8::Local<v8::Value> menu);
   void RemoveMenu();
-  void SetParentWindow(v8::Local<v8::Value> value, mate::Arguments* args);
+  void SetParentWindow(v8::Local<v8::Value> value, gin_helper::Arguments* args);
   virtual void SetBrowserView(v8::Local<v8::Value> value);
   virtual void AddBrowserView(v8::Local<v8::Value> value);
   virtual void RemoveBrowserView(v8::Local<v8::Value> value);
@@ -176,10 +179,10 @@ class TopLevelWindow : public mate::TrackableObject<TopLevelWindow>,
   virtual void ResetBrowserViews();
   std::string GetMediaSourceId() const;
   v8::Local<v8::Value> GetNativeWindowHandle();
-  void SetProgressBar(double progress, mate::Arguments* args);
+  void SetProgressBar(double progress, gin_helper::Arguments* args);
   void SetOverlayIcon(const gfx::Image& overlay,
                       const std::string& description);
-  void SetVisibleOnAllWorkspaces(bool visible, mate::Arguments* args);
+  void SetVisibleOnAllWorkspaces(bool visible, gin_helper::Arguments* args);
   bool IsVisibleOnAllWorkspaces();
   void SetAutoHideCursor(bool auto_hide);
   virtual void SetVibrancy(v8::Isolate* isolate, v8::Local<v8::Value> value);
@@ -191,14 +194,14 @@ class TopLevelWindow : public mate::TrackableObject<TopLevelWindow>,
   void MergeAllWindows();
   void MoveTabToNewWindow();
   void ToggleTabBar();
-  void AddTabbedWindow(NativeWindow* window, mate::Arguments* args);
-  void SetWindowButtonVisibility(bool visible, mate::Arguments* args);
+  void AddTabbedWindow(NativeWindow* window, gin_helper::Arguments* args);
+  void SetWindowButtonVisibility(bool visible, gin_helper::Arguments* args);
   void SetAutoHideMenuBar(bool auto_hide);
   bool IsMenuBarAutoHide();
   void SetMenuBarVisibility(bool visible);
   bool IsMenuBarVisible();
-  void SetAspectRatio(double aspect_ratio, mate::Arguments* args);
-  void PreviewFile(const std::string& path, mate::Arguments* args);
+  void SetAspectRatio(double aspect_ratio, gin_helper::Arguments* args);
+  void PreviewFile(const std::string& path, gin_helper::Arguments* args);
   void CloseFilePreview();
   void SetGTKDarkThemeEnabled(bool use_dark_theme);
 
@@ -206,11 +209,11 @@ class TopLevelWindow : public mate::TrackableObject<TopLevelWindow>,
   v8::Local<v8::Value> GetContentView() const;
   v8::Local<v8::Value> GetParentWindow() const;
   std::vector<v8::Local<v8::Object>> GetChildWindows() const;
-  v8::Local<v8::Value> GetBrowserView(mate::Arguments* args) const;
+  v8::Local<v8::Value> GetBrowserView(gin_helper::Arguments* args) const;
   bool IsModal() const;
 
   // Extra APIs added in JS.
-  bool SetThumbarButtons(mate::Arguments* args);
+  bool SetThumbarButtons(gin_helper::Arguments* args);
 #if defined(TOOLKIT_VIEWS)
   void SetIcon(mate::Handle<NativeImage> icon);
 #endif
@@ -224,7 +227,7 @@ class TopLevelWindow : public mate::TrackableObject<TopLevelWindow>,
   void UnhookAllWindowMessages();
   bool SetThumbnailClip(const gfx::Rect& region);
   bool SetThumbnailToolTip(const std::string& tooltip);
-  void SetAppDetails(const mate::Dictionary& options);
+  void SetAppDetails(const gin_helper::Dictionary& options);
 #endif
   int32_t GetID() const;
 

+ 32 - 24
shell/browser/api/atom_api_tray.cc

@@ -7,18 +7,17 @@
 #include <string>
 
 #include "base/threading/thread_task_runner_handle.h"
-#include "native_mate/constructor.h"
-#include "native_mate/dictionary.h"
 #include "shell/browser/api/atom_api_menu.h"
 #include "shell/browser/browser.h"
 #include "shell/common/api/atom_api_native_image.h"
-#include "shell/common/native_mate_converters/gfx_converter.h"
-#include "shell/common/native_mate_converters/image_converter.h"
-#include "shell/common/native_mate_converters/string16_converter.h"
+#include "shell/common/gin_converters/gfx_converter.h"
+#include "shell/common/gin_converters/image_converter.h"
+#include "shell/common/gin_helper/dictionary.h"
+#include "shell/common/gin_helper/object_template_builder.h"
 #include "shell/common/node_includes.h"
 #include "ui/gfx/image/image.h"
 
-namespace mate {
+namespace gin {
 
 template <>
 struct Converter<electron::TrayIcon::IconType> {
@@ -49,13 +48,13 @@ struct Converter<electron::TrayIcon::IconType> {
   }
 };
 
-}  // namespace mate
+}  // namespace gin
 
 namespace electron {
 
 namespace api {
 
-Tray::Tray(mate::Handle<NativeImage> image, gin::Arguments* args)
+Tray::Tray(gin::Handle<NativeImage> image, gin_helper::Arguments* args)
     : tray_icon_(TrayIcon::Create()) {
   SetImage(args->isolate(), image);
   tray_icon_->AddObserver(this);
@@ -67,8 +66,8 @@ Tray::~Tray() = default;
 
 // static
 mate::WrappableBase* Tray::New(gin_helper::ErrorThrower thrower,
-                               mate::Handle<NativeImage> image,
-                               gin::Arguments* args) {
+                               gin::Handle<NativeImage> image,
+                               gin_helper::Arguments* args) {
   if (!Browser::Get()->is_ready()) {
     thrower.ThrowError("Cannot create Tray before app is ready");
     return nullptr;
@@ -138,7 +137,7 @@ void Tray::OnDragEnded() {
   Emit("drag-end");
 }
 
-void Tray::SetImage(v8::Isolate* isolate, mate::Handle<NativeImage> image) {
+void Tray::SetImage(v8::Isolate* isolate, gin::Handle<NativeImage> image) {
 #if defined(OS_WIN)
   tray_icon_->SetImage(image->GetHICON(GetSystemMetrics(SM_CXSMICON)));
 #else
@@ -147,7 +146,7 @@ void Tray::SetImage(v8::Isolate* isolate, mate::Handle<NativeImage> image) {
 }
 
 void Tray::SetPressedImage(v8::Isolate* isolate,
-                           mate::Handle<NativeImage> image) {
+                           gin::Handle<NativeImage> image) {
 #if defined(OS_WIN)
   tray_icon_->SetPressedImage(image->GetHICON(GetSystemMetrics(SM_CXSMICON)));
 #else
@@ -187,17 +186,17 @@ bool Tray::GetIgnoreDoubleClickEvents() {
 #endif
 }
 
-void Tray::DisplayBalloon(mate::Arguments* args,
-                          const mate::Dictionary& options) {
+void Tray::DisplayBalloon(gin_helper::ErrorThrower thrower,
+                          const gin_helper::Dictionary& options) {
   TrayIcon::BalloonOptions balloon_options;
 
   if (!options.Get("title", &balloon_options.title) ||
       !options.Get("content", &balloon_options.content)) {
-    args->ThrowError("'title' and 'content' must be defined");
+    thrower.ThrowError("'title' and 'content' must be defined");
     return;
   }
 
-  mate::Handle<NativeImage> icon;
+  gin::Handle<NativeImage> icon;
   options.Get("icon", &icon);
   options.Get("iconType", &balloon_options.icon_type);
   options.Get("largeIcon", &balloon_options.large_icon);
@@ -224,17 +223,26 @@ void Tray::Focus() {
   tray_icon_->Focus();
 }
 
-void Tray::PopUpContextMenu(mate::Arguments* args) {
-  mate::Handle<Menu> menu;
+void Tray::PopUpContextMenu(gin_helper::Arguments* args) {
+  gin::Handle<Menu> menu;
   args->GetNext(&menu);
   gfx::Point pos;
   args->GetNext(&pos);
   tray_icon_->PopUpContextMenu(pos, menu.IsEmpty() ? nullptr : menu->model());
 }
 
-void Tray::SetContextMenu(v8::Isolate* isolate, mate::Handle<Menu> menu) {
-  menu_.Reset(isolate, menu.ToV8());
-  tray_icon_->SetContextMenu(menu.IsEmpty() ? nullptr : menu->model());
+void Tray::SetContextMenu(gin_helper::ErrorThrower thrower,
+                          v8::Local<v8::Value> arg) {
+  gin::Handle<Menu> menu;
+  if (arg->IsNull()) {
+    menu_.Reset();
+    tray_icon_->SetContextMenu(nullptr);
+  } else if (gin::ConvertFromV8(thrower.isolate(), arg, &menu)) {
+    menu_.Reset(thrower.isolate(), menu.ToV8());
+    tray_icon_->SetContextMenu(menu->model());
+  } else {
+    thrower.ThrowTypeError("Must pass Menu or null");
+  }
 }
 
 gfx::Rect Tray::GetBounds() {
@@ -244,9 +252,9 @@ gfx::Rect Tray::GetBounds() {
 // static
 void Tray::BuildPrototype(v8::Isolate* isolate,
                           v8::Local<v8::FunctionTemplate> prototype) {
-  prototype->SetClassName(mate::StringToV8(isolate, "Tray"));
+  prototype->SetClassName(gin::StringToV8(isolate, "Tray"));
   gin_helper::Destroyable::MakeDestroyable(isolate, prototype);
-  mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
+  gin_helper::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
       .SetMethod("setImage", &Tray::SetImage)
       .SetMethod("setPressedImage", &Tray::SetPressedImage)
       .SetMethod("setToolTip", &Tray::SetToolTip)
@@ -279,7 +287,7 @@ void Initialize(v8::Local<v8::Object> exports,
   v8::Isolate* isolate = context->GetIsolate();
   Tray::SetConstructor(isolate, base::BindRepeating(&Tray::New));
 
-  mate::Dictionary dict(isolate, exports);
+  gin_helper::Dictionary dict(isolate, exports);
   dict.Set(
       "Tray",
       Tray::GetConstructor(isolate)->GetFunction(context).ToLocalChecked());

+ 19 - 14
shell/browser/api/atom_api_tray.h

@@ -9,20 +9,20 @@
 #include <string>
 #include <vector>
 
-#include "native_mate/handle.h"
+#include "gin/handle.h"
 #include "shell/browser/api/trackable_object.h"
 #include "shell/browser/ui/tray_icon.h"
 #include "shell/browser/ui/tray_icon_observer.h"
 #include "shell/common/gin_helper/error_thrower.h"
+#include "shell/common/gin_helper/event_emitter.h"
 
 namespace gfx {
 class Image;
 }
 
-namespace mate {
-class Arguments;
+namespace gin_helper {
 class Dictionary;
-}  // namespace mate
+}
 
 namespace electron {
 
@@ -33,17 +33,20 @@ namespace api {
 class Menu;
 class NativeImage;
 
-class Tray : public mate::TrackableObject<Tray>, public TrayIconObserver {
+class Tray : public mate::TrackableObject<
+                 Tray,
+                 gin_helper::EventEmitter<mate::Wrappable<Tray>>>,
+             public TrayIconObserver {
  public:
   static mate::WrappableBase* New(gin_helper::ErrorThrower thrower,
-                                  mate::Handle<NativeImage> image,
-                                  gin::Arguments* args);
+                                  gin::Handle<NativeImage> image,
+                                  gin_helper::Arguments* args);
 
   static void BuildPrototype(v8::Isolate* isolate,
                              v8::Local<v8::FunctionTemplate> prototype);
 
  protected:
-  Tray(mate::Handle<NativeImage> image, gin::Arguments* args);
+  Tray(gin::Handle<NativeImage> image, gin_helper::Arguments* args);
   ~Tray() override;
 
   // TrayIconObserver:
@@ -65,22 +68,24 @@ class Tray : public mate::TrackableObject<Tray>, public TrayIconObserver {
   void OnMouseExited(const gfx::Point& location, int modifiers) override;
   void OnMouseMoved(const gfx::Point& location, int modifiers) override;
 
-  void SetImage(v8::Isolate* isolate, mate::Handle<NativeImage> image);
-  void SetPressedImage(v8::Isolate* isolate, mate::Handle<NativeImage> image);
+  void SetImage(v8::Isolate* isolate, gin::Handle<NativeImage> image);
+  void SetPressedImage(v8::Isolate* isolate, gin::Handle<NativeImage> image);
   void SetToolTip(const std::string& tool_tip);
   void SetTitle(const std::string& title);
   std::string GetTitle();
   void SetIgnoreDoubleClickEvents(bool ignore);
   bool GetIgnoreDoubleClickEvents();
-  void DisplayBalloon(mate::Arguments* args, const mate::Dictionary& options);
+  void DisplayBalloon(gin_helper::ErrorThrower thrower,
+                      const gin_helper::Dictionary& options);
   void RemoveBalloon();
   void Focus();
-  void PopUpContextMenu(mate::Arguments* args);
-  void SetContextMenu(v8::Isolate* isolate, mate::Handle<Menu> menu);
+  void PopUpContextMenu(gin_helper::Arguments* args);
+  void SetContextMenu(gin_helper::ErrorThrower thrower,
+                      v8::Local<v8::Value> arg);
   gfx::Rect GetBounds();
 
  private:
-  v8::Global<v8::Object> menu_;
+  v8::Global<v8::Value> menu_;
   std::unique_ptr<TrayIcon> tray_icon_;
 
   DISALLOW_COPY_AND_ASSIGN(Tray);

+ 1 - 1
shell/browser/api/atom_api_url_request_ns.h

@@ -17,7 +17,7 @@
 #include "services/network/public/cpp/simple_url_loader.h"
 #include "services/network/public/cpp/simple_url_loader_stream_consumer.h"
 #include "services/network/public/mojom/data_pipe_getter.mojom.h"
-#include "shell/browser/api/event_emitter.h"
+#include "shell/browser/api/event_emitter_deprecated.h"
 
 namespace electron {
 

+ 23 - 11
shell/browser/api/atom_api_web_contents.cc

@@ -72,12 +72,13 @@
 #include "shell/browser/web_view_guest_delegate.h"
 #include "shell/common/api/atom_api_native_image.h"
 #include "shell/common/color_util.h"
+#include "shell/common/gin_converters/callback_converter.h"
+#include "shell/common/gin_converters/gfx_converter.h"
 #include "shell/common/gin_helper/dictionary.h"
 #include "shell/common/mouse_util.h"
 #include "shell/common/native_mate_converters/blink_converter.h"
 #include "shell/common/native_mate_converters/content_converter.h"
 #include "shell/common/native_mate_converters/file_path_converter.h"
-#include "shell/common/native_mate_converters/gfx_converter.h"
 #include "shell/common/native_mate_converters/gurl_converter.h"
 #include "shell/common/native_mate_converters/image_converter.h"
 #include "shell/common/native_mate_converters/net_converter.h"
@@ -671,7 +672,8 @@ void WebContents::BeforeUnloadFired(content::WebContents* tab,
 
 void WebContents::SetContentsBounds(content::WebContents* source,
                                     const gfx::Rect& pos) {
-  Emit("move", pos);
+  // TODO(zcbenz): Use implicit convertion after removing mate::EventEmitter.
+  Emit("move", gin::ConvertToV8(isolate(), pos));
 }
 
 void WebContents::CloseContents(content::WebContents* source) {
@@ -801,13 +803,13 @@ void WebContents::FindReply(content::WebContents* web_contents,
 
   v8::Locker locker(isolate());
   v8::HandleScope handle_scope(isolate());
-  mate::Dictionary result = mate::Dictionary::CreateEmpty(isolate());
+  gin_helper::Dictionary result = gin::Dictionary::CreateEmpty(isolate());
   result.Set("requestId", request_id);
   result.Set("matches", number_of_matches);
   result.Set("selectionArea", selection_rect);
   result.Set("activeMatchOrdinal", active_match_ordinal);
   result.Set("finalUpdate", final_update);  // Deprecate after 2.0
-  Emit("found-in-page", result);
+  Emit("found-in-page", result.GetHandle());
 }
 
 bool WebContents::CheckMediaAccessPermission(
@@ -2128,7 +2130,11 @@ void WebContents::SendInputEvent(v8::Isolate* isolate,
       v8::Exception::Error(mate::StringToV8(isolate, "Invalid event object")));
 }
 
-void WebContents::BeginFrameSubscription(mate::Arguments* args) {
+void WebContents::BeginFrameSubscription(mate::Arguments* mate_args) {
+  // TODO(zcbenz): Remove this after converting WebContents to gin.
+  gin::Arguments gin_args(mate_args->info());
+  gin_helper::Arguments* args = static_cast<gin_helper::Arguments*>(&gin_args);
+
   bool only_dirty = false;
   FrameSubscriber::FrameCaptureCallback callback;
 
@@ -2182,7 +2188,11 @@ void WebContents::StartDrag(const mate::Dictionary& item,
   }
 }
 
-v8::Local<v8::Promise> WebContents::CapturePage(mate::Arguments* args) {
+v8::Local<v8::Promise> WebContents::CapturePage(mate::Arguments* mate_args) {
+  // TODO(zcbenz): Remove this after converting WebContents to gin.
+  gin::Arguments gin_args(mate_args->info());
+  gin::Arguments* args = &gin_args;
+
   gfx::Rect rect;
   util::Promise<gfx::Image> promise(isolate());
   v8::Local<v8::Promise> handle = promise.GetHandle();
@@ -2223,8 +2233,11 @@ void WebContents::OnCursorChange(const content::WebCursor& cursor) {
     Emit("cursor-changed", CursorTypeToString(info),
          gfx::Image::CreateFrom1xBitmap(info.custom_image),
          info.image_scale_factor,
-         gfx::Size(info.custom_image.width(), info.custom_image.height()),
-         info.hotspot);
+         // TODO(zcbenz): Use implicit convertion after removing
+         // mate::EventEmitter.
+         gin::ConvertToV8(isolate(), gfx::Size(info.custom_image.width(),
+                                               info.custom_image.height())),
+         gin::ConvertToV8(isolate(), info.hotspot));
   } else {
     Emit("cursor-changed", CursorTypeToString(info));
   }
@@ -2672,9 +2685,8 @@ void Initialize(v8::Local<v8::Object> exports,
                               ->GetFunction(context)
                               .ToLocalChecked());
   dict.SetMethod("create", &WebContents::Create);
-  dict.SetMethod("fromId", &mate::TrackableObject<WebContents>::FromWeakMapID);
-  dict.SetMethod("getAllWebContents",
-                 &mate::TrackableObject<WebContents>::GetAll);
+  dict.SetMethod("fromId", &WebContents::FromWeakMapID);
+  dict.SetMethod("getAllWebContents", &WebContents::GetAll);
 }
 
 }  // namespace

+ 1 - 1
shell/browser/api/event_emitter.cc → shell/browser/api/event_emitter_deprecated.cc

@@ -2,7 +2,7 @@
 // Use of this source code is governed by the MIT license that can be
 // found in the LICENSE file.
 
-#include "shell/browser/api/event_emitter.h"
+#include "shell/browser/api/event_emitter_deprecated.h"
 
 #include <utility>
 

+ 3 - 3
shell/browser/api/event_emitter.h → shell/browser/api/event_emitter_deprecated.h

@@ -2,8 +2,8 @@
 // Use of this source code is governed by the MIT license that can be
 // found in the LICENSE file.
 
-#ifndef SHELL_BROWSER_API_EVENT_EMITTER_H_
-#define SHELL_BROWSER_API_EVENT_EMITTER_H_
+#ifndef SHELL_BROWSER_API_EVENT_EMITTER_DEPRECATED_H_
+#define SHELL_BROWSER_API_EVENT_EMITTER_DEPRECATED_H_
 
 #include <utility>
 #include <vector>
@@ -126,4 +126,4 @@ class EventEmitter : public Wrappable<T> {
 
 }  // namespace mate
 
-#endif  // SHELL_BROWSER_API_EVENT_EMITTER_H_
+#endif  // SHELL_BROWSER_API_EVENT_EMITTER_DEPRECATED_H_

+ 0 - 1
shell/browser/api/frame_subscriber.cc

@@ -10,7 +10,6 @@
 #include "content/public/browser/render_widget_host.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "media/capture/mojom/video_capture_types.mojom.h"
-#include "shell/common/native_mate_converters/gfx_converter.h"
 #include "ui/gfx/geometry/size_conversions.h"
 #include "ui/gfx/image/image.h"
 #include "ui/gfx/skbitmap_operations.h"

+ 9 - 8
shell/browser/api/trackable_object.h

@@ -10,7 +10,7 @@
 #include "base/bind.h"
 #include "base/memory/weak_ptr.h"
 #include "native_mate/object_template_builder_deprecated.h"
-#include "shell/browser/api/event_emitter.h"
+#include "shell/browser/api/event_emitter_deprecated.h"
 #include "shell/common/key_weak_map.h"
 
 namespace base {
@@ -51,9 +51,10 @@ class TrackableObjectBase {
 
 // All instances of TrackableObject will be kept in a weak map and can be got
 // from its ID.
-template <typename T>
-class TrackableObject : public TrackableObjectBase,
-                        public mate::EventEmitter<T> {
+//
+// TODO(zcbenz): Remove "typename B" after removing native_mate.
+template <typename T, typename B = mate::EventEmitter<T>>
+class TrackableObject : public TrackableObjectBase, public B {
  public:
   // Mark the JS object as destroyed.
   void MarkDestroyed() {
@@ -126,11 +127,11 @@ class TrackableObject : public TrackableObjectBase,
   DISALLOW_COPY_AND_ASSIGN(TrackableObject);
 };
 
-template <typename T>
-int32_t TrackableObject<T>::next_id_ = 0;
+template <typename T, typename B>
+int32_t TrackableObject<T, B>::next_id_ = 0;
 
-template <typename T>
-electron::KeyWeakMap<int32_t>* TrackableObject<T>::weak_map_ = nullptr;
+template <typename T, typename B>
+electron::KeyWeakMap<int32_t>* TrackableObject<T, B>::weak_map_ = nullptr;
 
 }  // namespace mate
 

+ 8 - 0
shell/common/gin_converters/std_converter.h

@@ -39,6 +39,14 @@ struct Converter<const char*> {
   }
 };
 
+template <>
+struct Converter<char[]> {
+  static v8::Local<v8::Value> ToV8(v8::Isolate* isolate, const char* val) {
+    return v8::String::NewFromUtf8(isolate, val, v8::NewStringType::kNormal)
+        .ToLocalChecked();
+  }
+};
+
 template <size_t n>
 struct Converter<char[n]> {
   static v8::Local<v8::Value> ToV8(v8::Isolate* isolate, const char* val) {

+ 22 - 0
shell/common/gin_helper/arguments.cc

@@ -0,0 +1,22 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE.chromium file.
+
+#include "shell/common/gin_helper/arguments.h"
+
+namespace gin_helper {
+
+void Arguments::ThrowError() const {
+  // Gin advances |next_| counter when conversion fails while we do not, so we
+  // have to manually advance the counter here to make gin report error with the
+  // correct index.
+  const_cast<Arguments*>(this)->Skip();
+  gin::Arguments::ThrowError();
+}
+
+void Arguments::ThrowError(base::StringPiece message) const {
+  isolate()->ThrowException(
+      v8::Exception::Error(gin::StringToV8(isolate(), message)));
+}
+
+}  // namespace gin_helper

+ 17 - 0
shell/common/gin_helper/arguments.h

@@ -5,6 +5,8 @@
 #ifndef SHELL_COMMON_GIN_HELPER_ARGUMENTS_H_
 #define SHELL_COMMON_GIN_HELPER_ARGUMENTS_H_
 
+#include "gin/arguments.h"
+
 namespace gin_helper {
 
 // Provides additional APIs to the gin::Arguments class.
@@ -25,6 +27,21 @@ class Arguments : public gin::Arguments {
     return true;
   }
 
+  // Gin always returns true when converting V8 value to boolean, we do not want
+  // this behavior when parsing parameters.
+  bool GetNext(bool* out) {
+    v8::Local<v8::Value> val = PeekNext();
+    if (val.IsEmpty() || !val->IsBoolean())
+      return false;
+    *out = val->BooleanValue(isolate());
+    Skip();
+    return true;
+  }
+
+  // Throw error with custom error message.
+  void ThrowError() const;
+  void ThrowError(base::StringPiece message) const;
+
  private:
   // MUST NOT ADD ANY DATA MEMBER.
 };

+ 67 - 0
shell/common/gin_helper/event_emitter.cc

@@ -0,0 +1,67 @@
+// Copyright (c) 2019 GitHub, Inc.
+// Use of this source code is governed by the MIT license that can be
+// found in the LICENSE file.
+
+#include "shell/common/gin_helper/event_emitter.h"
+
+#include "shell/common/gin_helper/dictionary.h"
+#include "shell/common/gin_helper/object_template_builder.h"
+#include "ui/events/event_constants.h"
+
+namespace gin_helper {
+
+namespace internal {
+
+namespace {
+
+v8::Persistent<v8::ObjectTemplate> event_template;
+
+void PreventDefault(gin_helper::Arguments* args) {
+  Dictionary self;
+  if (args->GetHolder(&self))
+    self.Set("defaultPrevented", true);
+}
+
+}  // namespace
+
+v8::Local<v8::Object> CreateEventObject(v8::Isolate* isolate) {
+  if (event_template.IsEmpty()) {
+    event_template.Reset(
+        isolate,
+        ObjectTemplateBuilder(isolate, v8::ObjectTemplate::New(isolate))
+            .SetMethod("preventDefault", &PreventDefault)
+            .Build());
+  }
+
+  return v8::Local<v8::ObjectTemplate>::New(isolate, event_template)
+      ->NewInstance(isolate->GetCurrentContext())
+      .ToLocalChecked();
+}
+
+v8::Local<v8::Object> CreateCustomEvent(v8::Isolate* isolate,
+                                        v8::Local<v8::Object> object,
+                                        v8::Local<v8::Object> custom_event) {
+  v8::Local<v8::Object> event = CreateEventObject(isolate);
+  event->SetPrototype(custom_event->CreationContext(), custom_event).IsJust();
+  Dictionary(isolate, event).Set("sender", object);
+  return event;
+}
+
+v8::Local<v8::Object> CreateEventFromFlags(v8::Isolate* isolate, int flags) {
+  const int mouse_button_flags =
+      (ui::EF_RIGHT_MOUSE_BUTTON | ui::EF_LEFT_MOUSE_BUTTON |
+       ui::EF_MIDDLE_MOUSE_BUTTON | ui::EF_BACK_MOUSE_BUTTON |
+       ui::EF_FORWARD_MOUSE_BUTTON);
+  const int is_mouse_click = static_cast<bool>(flags & mouse_button_flags);
+  Dictionary obj = gin::Dictionary::CreateEmpty(isolate);
+  obj.Set("shiftKey", static_cast<bool>(flags & ui::EF_SHIFT_DOWN));
+  obj.Set("ctrlKey", static_cast<bool>(flags & ui::EF_CONTROL_DOWN));
+  obj.Set("altKey", static_cast<bool>(flags & ui::EF_ALT_DOWN));
+  obj.Set("metaKey", static_cast<bool>(flags & ui::EF_COMMAND_DOWN));
+  obj.Set("triggeredByAccelerator", !is_mouse_click);
+  return obj.GetHandle();
+}
+
+}  // namespace internal
+
+}  // namespace gin_helper

+ 107 - 0
shell/common/gin_helper/event_emitter.h

@@ -0,0 +1,107 @@
+// Copyright (c) 2019 GitHub, Inc.
+// Use of this source code is governed by the MIT license that can be
+// found in the LICENSE file.
+
+#ifndef SHELL_COMMON_GIN_HELPER_EVENT_EMITTER_H_
+#define SHELL_COMMON_GIN_HELPER_EVENT_EMITTER_H_
+
+#include <utility>
+#include <vector>
+
+#include "base/optional.h"
+#include "electron/shell/common/api/api.mojom.h"
+#include "shell/common/gin_helper/event_emitter_caller.h"
+
+namespace gin_helper {
+
+namespace internal {
+
+v8::Local<v8::Object> CreateEventObject(v8::Isolate* isolate);
+v8::Local<v8::Object> CreateCustomEvent(v8::Isolate* isolate,
+                                        v8::Local<v8::Object> object,
+                                        v8::Local<v8::Object> event);
+v8::Local<v8::Object> CreateEventFromFlags(v8::Isolate* isolate, int flags);
+
+}  // namespace internal
+
+// Provide helperers to emit event in JavaScript.
+//
+// TODO(zcbenz): Inherit from Wrappable directly after removing native_mate.
+template <typename Base>
+class EventEmitter : public Base {
+ public:
+  typedef std::vector<v8::Local<v8::Value>> ValueArray;
+
+  // Make the convinient methods visible:
+  // https://isocpp.org/wiki/faq/templates#nondependent-name-lookup-members
+  v8::Isolate* isolate() const { return Base::isolate(); }
+  v8::Local<v8::Object> GetWrapper() const { return Base::GetWrapper(); }
+  v8::MaybeLocal<v8::Object> GetWrapper(v8::Isolate* isolate) const {
+    return Base::GetWrapper(isolate);
+  }
+
+  // this.emit(name, event, args...);
+  template <typename... Args>
+  bool EmitCustomEvent(base::StringPiece name,
+                       v8::Local<v8::Object> event,
+                       Args&&... args) {
+    return EmitWithEvent(
+        name, internal::CreateCustomEvent(isolate(), GetWrapper(), event),
+        std::forward<Args>(args)...);
+  }
+
+  // this.emit(name, new Event(flags), args...);
+  template <typename... Args>
+  bool EmitWithFlags(base::StringPiece name, int flags, Args&&... args) {
+    return EmitCustomEvent(name,
+                           internal::CreateEventFromFlags(isolate(), flags),
+                           std::forward<Args>(args)...);
+  }
+
+  // this.emit(name, new Event(), args...);
+  template <typename... Args>
+  bool Emit(base::StringPiece name, Args&&... args) {
+    v8::Locker locker(isolate());
+    v8::HandleScope handle_scope(isolate());
+    v8::Local<v8::Object> wrapper = GetWrapper();
+    if (wrapper.IsEmpty()) {
+      return false;
+    }
+    v8::Local<v8::Object> event = internal::CreateEventObject(isolate());
+    event
+        ->Set(isolate()->GetCurrentContext(),
+              gin::StringToV8(isolate(), "sender"), wrapper)
+        .IsJust();
+    return EmitWithEvent(name, event, std::forward<Args>(args)...);
+  }
+
+ protected:
+  EventEmitter() {}
+
+ private:
+  // this.emit(name, event, args...);
+  template <typename... Args>
+  bool EmitWithEvent(base::StringPiece name,
+                     v8::Local<v8::Object> event,
+                     Args&&... args) {
+    // It's possible that |this| will be deleted by EmitEvent, so save anything
+    // we need from |this| before calling EmitEvent.
+    auto* isolate = this->isolate();
+    v8::Locker locker(isolate);
+    v8::HandleScope handle_scope(isolate);
+    auto context = isolate->GetCurrentContext();
+    EmitEvent(isolate, GetWrapper(), name, event, std::forward<Args>(args)...);
+    v8::Local<v8::Value> defaultPrevented;
+    if (event->Get(context, gin::StringToV8(isolate, "defaultPrevented"))
+            .ToLocal(&defaultPrevented)) {
+      return defaultPrevented->BooleanValue(isolate);
+    }
+    return false;
+  }
+
+  DISALLOW_COPY_AND_ASSIGN(EventEmitter);
+};
+
+}  // namespace gin_helper
+
+#endif  // SHELL_COMMON_GIN_HELPER_EVENT_EMITTER_H_

+ 6 - 0
shell/common/gin_helper/object_template_builder.cc

@@ -29,4 +29,10 @@ ObjectTemplateBuilder& ObjectTemplateBuilder::SetPropertyImpl(
   return *this;
 }
 
+v8::Local<v8::ObjectTemplate> ObjectTemplateBuilder::Build() {
+  v8::Local<v8::ObjectTemplate> result = template_;
+  template_.Clear();
+  return result;
+}
+
 }  // namespace gin_helper

+ 2 - 0
shell/common/gin_helper/object_template_builder.h

@@ -56,6 +56,8 @@ class ObjectTemplateBuilder {
                            CallbackTraits<U>::CreateTemplate(isolate_, setter));
   }
 
+  v8::Local<v8::ObjectTemplate> Build();
+
  private:
   ObjectTemplateBuilder& SetImpl(const base::StringPiece& name,
                                  v8::Local<v8::Data> val);

+ 0 - 78
shell/common/native_mate_converters/gfx_converter.h

@@ -1,78 +0,0 @@
-// Copyright (c) 2014 GitHub, Inc.
-// Use of this source code is governed by the MIT license that can be
-// found in the LICENSE file.
-
-#ifndef SHELL_COMMON_NATIVE_MATE_CONVERTERS_GFX_CONVERTER_H_
-#define SHELL_COMMON_NATIVE_MATE_CONVERTERS_GFX_CONVERTER_H_
-
-#include "native_mate/converter.h"
-#include "shell/common/gin_converters/gfx_converter.h"
-
-namespace mate {
-
-template <>
-struct Converter<gfx::Point> {
-  static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
-                                   const gfx::Point& val) {
-    return gin::ConvertToV8(isolate, val);
-  }
-  static bool FromV8(v8::Isolate* isolate,
-                     v8::Local<v8::Value> val,
-                     gfx::Point* out) {
-    return gin::ConvertFromV8(isolate, val, out);
-  }
-};
-
-template <>
-struct Converter<gfx::PointF> {
-  static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
-                                   const gfx::PointF& val) {
-    return gin::ConvertToV8(isolate, val);
-  }
-  static bool FromV8(v8::Isolate* isolate,
-                     v8::Local<v8::Value> val,
-                     gfx::PointF* out) {
-    return gin::ConvertFromV8(isolate, val, out);
-  }
-};
-
-template <>
-struct Converter<gfx::Size> {
-  static v8::Local<v8::Value> ToV8(v8::Isolate* isolate, const gfx::Size& val) {
-    return gin::ConvertToV8(isolate, val);
-  }
-  static bool FromV8(v8::Isolate* isolate,
-                     v8::Local<v8::Value> val,
-                     gfx::Size* out) {
-    return gin::ConvertFromV8(isolate, val, out);
-  }
-};
-
-template <>
-struct Converter<gfx::Rect> {
-  static v8::Local<v8::Value> ToV8(v8::Isolate* isolate, const gfx::Rect& val) {
-    return gin::ConvertToV8(isolate, val);
-  }
-  static bool FromV8(v8::Isolate* isolate,
-                     v8::Local<v8::Value> val,
-                     gfx::Rect* out) {
-    return gin::ConvertFromV8(isolate, val, out);
-  }
-};
-
-template <>
-struct Converter<display::Display> {
-  static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
-                                   const display::Display& val) {
-    return gin::ConvertToV8(isolate, val);
-  }
-  static bool FromV8(v8::Isolate* isolate,
-                     v8::Local<v8::Value> val,
-                     display::Display* out) {
-    return gin::ConvertFromV8(isolate, val, out);
-  }
-};
-
-}  // namespace mate
-
-#endif  // SHELL_COMMON_NATIVE_MATE_CONVERTERS_GFX_CONVERTER_H_

+ 6 - 5
shell/common/promise_util.h

@@ -55,12 +55,13 @@ class Promise {
 
   static void ResolvePromise(Promise<RT> promise, RT result) {
     if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
-      base::PostTask(FROM_HERE, {content::BrowserThread::UI},
-                     base::BindOnce([](Promise<RT> promise,
-                                       RT result) { promise.Resolve(result); },
-                                    std::move(promise), std::move(result)));
+      base::PostTask(
+          FROM_HERE, {content::BrowserThread::UI},
+          base::BindOnce([](Promise<RT> promise,
+                            RT result) { promise.ResolveWithGin(result); },
+                         std::move(promise), std::move(result)));
     } else {
-      promise.Resolve(result);
+      promise.ResolveWithGin(result);
     }
   }
 

+ 0 - 1
shell/renderer/api/atom_api_web_frame.cc

@@ -16,7 +16,6 @@
 #include "services/service_manager/public/cpp/interface_provider.h"
 #include "shell/common/api/api.mojom.h"
 #include "shell/common/native_mate_converters/blink_converter.h"
-#include "shell/common/native_mate_converters/gfx_converter.h"
 #include "shell/common/native_mate_converters/string16_converter.h"
 #include "shell/common/node_includes.h"
 #include "shell/common/promise_util.h"

+ 3 - 1
spec-main/api-browser-window-spec.ts

@@ -2737,7 +2737,9 @@ describe('BrowserWindow module', () => {
       const w = new BrowserWindow({show: false})
       expect(() => {
         w.webContents.beginFrameSubscription(true, true as any)
-      }).to.throw('Error processing argument at index 1, conversion failure from true')
+        // TODO(zcbenz): gin is weak at guessing parameter types, we should
+        // upstream native_mate's implementation to gin.
+      }).to.throw('Error processing argument at index 1, conversion failure from ')
     })
   })