Browse Source

chore: remove native_mate (Part 4) (#20146)

* avoid patching gin::Dictionary by using our wrapper

* remove SetHidden from mate::Dictionary
Cheng Zhao 5 years ago
parent
commit
49bd74ff0e

+ 0 - 26
native_mate/native_mate/dictionary.h

@@ -55,19 +55,6 @@ class Dictionary {
     return ConvertFromV8(isolate_, val, out);
   }
 
-  template <typename T>
-  bool GetHidden(base::StringPiece key, T* out) const {
-    v8::Local<v8::Context> context = isolate_->GetCurrentContext();
-    v8::Local<v8::Private> privateKey =
-        v8::Private::ForApi(isolate_, StringToV8(isolate_, key));
-    v8::Local<v8::Value> value;
-    v8::Maybe<bool> result = GetHandle()->HasPrivate(context, privateKey);
-    if (internal::IsTrue(result) &&
-        GetHandle()->GetPrivate(context, privateKey).ToLocal(&value))
-      return ConvertFromV8(isolate_, value, out);
-    return false;
-  }
-
   template <typename T>
   bool Set(base::StringPiece key, const T& val) {
     v8::Local<v8::Value> v8_value;
@@ -78,19 +65,6 @@ class Dictionary {
     return !result.IsNothing() && result.FromJust();
   }
 
-  template <typename T>
-  bool SetHidden(base::StringPiece key, T val) {
-    v8::Local<v8::Value> v8_value;
-    if (!TryConvertToV8(isolate_, val, &v8_value))
-      return false;
-    v8::Local<v8::Context> context = isolate_->GetCurrentContext();
-    v8::Local<v8::Private> privateKey =
-        v8::Private::ForApi(isolate_, StringToV8(isolate_, key));
-    v8::Maybe<bool> result =
-        GetHandle()->SetPrivate(context, privateKey, v8_value);
-    return !result.IsNothing() && result.FromJust();
-  }
-
   template <typename T>
   bool SetReadOnly(base::StringPiece key, T val) {
     v8::Local<v8::Value> v8_value;

+ 3 - 3
native_mate/native_mate/object_template_builder.h

@@ -21,7 +21,7 @@ template <typename T, typename Enable = void>
 struct CallbackTraits {
   static v8::Local<v8::FunctionTemplate> CreateTemplate(v8::Isolate* isolate,
                                                         T callback) {
-    return CreateFunctionTemplate(isolate, base::Bind(callback));
+    return mate::CreateFunctionTemplate(isolate, base::Bind(callback));
   }
 };
 
@@ -31,7 +31,7 @@ struct CallbackTraits<base::Callback<T>> {
   static v8::Local<v8::FunctionTemplate> CreateTemplate(
       v8::Isolate* isolate,
       const base::Callback<T>& callback) {
-    return CreateFunctionTemplate(isolate, callback);
+    return mate::CreateFunctionTemplate(isolate, callback);
   }
 };
 
@@ -46,7 +46,7 @@ struct CallbackTraits<
   static v8::Local<v8::FunctionTemplate> CreateTemplate(v8::Isolate* isolate,
                                                         T callback) {
     int flags = HolderIsFirstArgument;
-    return CreateFunctionTemplate(isolate, base::Bind(callback), flags);
+    return mate::CreateFunctionTemplate(isolate, base::Bind(callback), flags);
   }
 };
 

+ 0 - 1
patches/chromium/.patches

@@ -17,7 +17,6 @@ web_contents.patch
 webview_cross_drag.patch
 disable_user_gesture_requirement_for_beforeunload_dialogs.patch
 gin_enable_disable_v8_platform.patch
-gin_dictionary_default_constructor.patch
 blink-worker-enable-csp-in-file-scheme.patch
 disable-redraw-lock.patch
 v8_context_snapshot_generator.patch

+ 0 - 37
patches/chromium/gin_dictionary_default_constructor.patch

@@ -1,37 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Cheng Zhao <[email protected]>
-Date: Thu, 4 Oct 2018 14:57:02 -0700
-Subject: gin_dictionary_default_constructor.patch
-
-Add default constructor for gin::Dictionary.
-
-This is required for automatically converting arguments for functions that
-take gin::Dictionary as parameter.
-
-diff --git a/gin/dictionary.cc b/gin/dictionary.cc
-index 95e00072700c..7643347890a5 100644
---- a/gin/dictionary.cc
-+++ b/gin/dictionary.cc
-@@ -6,6 +6,10 @@
- 
- namespace gin {
- 
-+Dictionary::Dictionary()
-+    : isolate_(nullptr) {
-+}
-+
- Dictionary::Dictionary(v8::Isolate* isolate)
-     : isolate_(isolate) {
- }
-diff --git a/gin/dictionary.h b/gin/dictionary.h
-index 2645d328b4c1..43b227dd7e48 100644
---- a/gin/dictionary.h
-+++ b/gin/dictionary.h
-@@ -24,6 +24,7 @@ namespace gin {
- //
- class GIN_EXPORT Dictionary {
-  public:
-+  Dictionary();
-   explicit Dictionary(v8::Isolate* isolate);
-   Dictionary(v8::Isolate* isolate, v8::Local<v8::Object> object);
-   Dictionary(const Dictionary& other);

+ 9 - 3
shell/browser/api/atom_api_app.cc

@@ -43,6 +43,7 @@
 #include "shell/browser/relauncher.h"
 #include "shell/common/application_info.h"
 #include "shell/common/atom_command_line.h"
+#include "shell/common/gin_helper/dictionary.h"
 #include "shell/common/native_mate_converters/callback_converter_deprecated.h"
 #include "shell/common/native_mate_converters/file_path_converter.h"
 #include "shell/common/native_mate_converters/gurl_converter.h"
@@ -1207,8 +1208,11 @@ std::vector<mate::Dictionary> App::GetAppMetrics(v8::Isolate* isolate) {
     mate::Dictionary pid_dict = mate::Dictionary::CreateEmpty(isolate);
     mate::Dictionary cpu_dict = mate::Dictionary::CreateEmpty(isolate);
 
-    pid_dict.SetHidden("simple", true);
-    cpu_dict.SetHidden("simple", true);
+    // TODO(zcbenz): Just call SetHidden when this file is converted to gin.
+    gin_helper::Dictionary(isolate, pid_dict.GetHandle())
+        .SetHidden("simple", true);
+    gin_helper::Dictionary(isolate, cpu_dict.GetHandle())
+        .SetHidden("simple", true);
 
     cpu_dict.Set(
         "percentCPUUsage",
@@ -1236,7 +1240,9 @@ std::vector<mate::Dictionary> App::GetAppMetrics(v8::Isolate* isolate) {
     auto memory_info = process_metric.second->GetMemoryInfo();
 
     mate::Dictionary memory_dict = mate::Dictionary::CreateEmpty(isolate);
-    memory_dict.SetHidden("simple", true);
+    // TODO(zcbenz): Just call SetHidden when this file is converted to gin.
+    gin_helper::Dictionary(isolate, memory_dict.GetHandle())
+        .SetHidden("simple", true);
     memory_dict.Set("workingSetSize",
                     static_cast<double>(memory_info.working_set_size >> 10));
     memory_dict.Set(

+ 8 - 7
shell/browser/api/atom_api_dialog.cc

@@ -25,11 +25,12 @@ int ShowMessageBoxSync(const electron::MessageBoxSettings& settings) {
   return electron::ShowMessageBoxSync(settings);
 }
 
-void ResolvePromiseObject(electron::util::Promise<gin::Dictionary> promise,
-                          int result,
-                          bool checkbox_checked) {
+void ResolvePromiseObject(
+    electron::util::Promise<gin_helper::Dictionary> promise,
+    int result,
+    bool checkbox_checked) {
   v8::Isolate* isolate = promise.isolate();
-  gin::Dictionary dict = gin::Dictionary::CreateEmpty(isolate);
+  gin_helper::Dictionary dict = gin::Dictionary::CreateEmpty(isolate);
 
   dict.Set("response", result);
   dict.Set("checkboxChecked", checkbox_checked);
@@ -41,7 +42,7 @@ v8::Local<v8::Promise> ShowMessageBox(
     const electron::MessageBoxSettings& settings,
     gin::Arguments* args) {
   v8::Isolate* isolate = args->isolate();
-  electron::util::Promise<gin::Dictionary> promise(isolate);
+  electron::util::Promise<gin_helper::Dictionary> promise(isolate);
   v8::Local<v8::Promise> handle = promise.GetHandle();
 
   electron::ShowMessageBox(
@@ -60,7 +61,7 @@ void ShowOpenDialogSync(const file_dialog::DialogSettings& settings,
 v8::Local<v8::Promise> ShowOpenDialog(
     const file_dialog::DialogSettings& settings,
     gin::Arguments* args) {
-  electron::util::Promise<gin::Dictionary> promise(args->isolate());
+  electron::util::Promise<gin_helper::Dictionary> promise(args->isolate());
   v8::Local<v8::Promise> handle = promise.GetHandle();
   file_dialog::ShowOpenDialog(settings, std::move(promise));
   return handle;
@@ -76,7 +77,7 @@ void ShowSaveDialogSync(const file_dialog::DialogSettings& settings,
 v8::Local<v8::Promise> ShowSaveDialog(
     const file_dialog::DialogSettings& settings,
     gin::Arguments* args) {
-  electron::util::Promise<gin::Dictionary> promise(args->isolate());
+  electron::util::Promise<gin_helper::Dictionary> promise(args->isolate());
   v8::Local<v8::Promise> handle = promise.GetHandle();
 
   file_dialog::ShowSaveDialog(settings, std::move(promise));

+ 7 - 3
shell/browser/api/atom_api_in_app_purchase.cc

@@ -9,6 +9,7 @@
 #include <vector>
 
 #include "native_mate/dictionary.h"
+#include "shell/common/gin_helper/dictionary.h"
 #include "shell/common/node_includes.h"
 
 namespace mate {
@@ -18,7 +19,8 @@ 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);
-    dict.SetHidden("simple", true);
+    // TODO(zcbenz): Just call SetHidden when this file is converted to gin.
+    gin_helper::Dictionary(isolate, dict.GetHandle()).SetHidden("simple", true);
     dict.Set("productIdentifier", payment.productIdentifier);
     dict.Set("quantity", payment.quantity);
     return dict.GetHandle();
@@ -30,7 +32,8 @@ 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);
-    dict.SetHidden("simple", true);
+    // TODO(zcbenz): Just call SetHidden when this file is converted to gin.
+    gin_helper::Dictionary(isolate, dict.GetHandle()).SetHidden("simple", true);
     dict.Set("transactionIdentifier", val.transactionIdentifier);
     dict.Set("transactionDate", val.transactionDate);
     dict.Set("originalTransactionIdentifier",
@@ -48,7 +51,8 @@ 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);
-    dict.SetHidden("simple", true);
+    // TODO(zcbenz): Just call SetHidden when this file is converted to gin.
+    gin_helper::Dictionary(isolate, dict.GetHandle()).SetHidden("simple", true);
     dict.Set("productIdentifier", val.productIdentifier);
     dict.Set("localizedDescription", val.localizedDescription);
     dict.Set("localizedTitle", val.localizedTitle);

+ 2 - 1
shell/browser/api/atom_api_system_preferences.cc

@@ -5,6 +5,7 @@
 #include "shell/browser/api/atom_api_system_preferences.h"
 
 #include "native_mate/dictionary.h"
+#include "shell/common/gin_helper/dictionary.h"
 #include "shell/common/native_mate_converters/callback_converter_deprecated.h"
 #include "shell/common/native_mate_converters/value_converter.h"
 #include "shell/common/node_includes.h"
@@ -45,7 +46,7 @@ bool SystemPreferences::IsHighContrastColorScheme() {
 
 v8::Local<v8::Value> SystemPreferences::GetAnimationSettings(
     v8::Isolate* isolate) {
-  mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
+  gin_helper::Dictionary dict = gin::Dictionary::CreateEmpty(isolate);
   dict.SetHidden("simple", true);
   dict.Set("shouldRenderRichAnimation",
            gfx::Animation::ShouldRenderRichAnimation());

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

@@ -47,7 +47,7 @@ struct Converter<electron::TaskbarHost::ThumbarButton> {
   static bool FromV8(v8::Isolate* isolate,
                      v8::Handle<v8::Value> val,
                      electron::TaskbarHost::ThumbarButton* out) {
-    gin::Dictionary dict;
+    gin::Dictionary dict(isolate);
     if (!gin::ConvertFromV8(isolate, val, &dict))
       return false;
     dict.Get("click", &(out->clicked_callback));

+ 2 - 3
shell/browser/atom_download_manager_delegate.cc

@@ -17,7 +17,6 @@
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/download_item_utils.h"
 #include "content/public/browser/download_manager.h"
-#include "gin/dictionary.h"
 #include "net/base/filename_util.h"
 #include "shell/browser/api/atom_api_download_item.h"
 #include "shell/browser/atom_browser_context.h"
@@ -124,7 +123,7 @@ void AtomDownloadManagerDelegate::OnDownloadPathGenerated(
     settings.force_detached = offscreen;
 
     v8::Isolate* isolate = v8::Isolate::GetCurrent();
-    electron::util::Promise<gin::Dictionary> dialog_promise(isolate);
+    electron::util::Promise<gin_helper::Dictionary> dialog_promise(isolate);
     auto dialog_callback =
         base::BindOnce(&AtomDownloadManagerDelegate::OnDownloadSaveDialogDone,
                        base::Unretained(this), download_id, callback);
@@ -141,7 +140,7 @@ void AtomDownloadManagerDelegate::OnDownloadPathGenerated(
 void AtomDownloadManagerDelegate::OnDownloadSaveDialogDone(
     uint32_t download_id,
     const content::DownloadTargetCallback& download_callback,
-    gin::Dictionary result) {
+    gin_helper::Dictionary result) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   auto* item = download_manager_->GetDownload(download_id);

+ 2 - 1
shell/browser/atom_download_manager_delegate.h

@@ -10,6 +10,7 @@
 #include "base/memory/weak_ptr.h"
 #include "content/public/browser/download_manager_delegate.h"
 #include "shell/browser/ui/file_dialog.h"
+#include "shell/common/gin_helper/dictionary.h"
 
 namespace content {
 class DownloadManager;
@@ -48,7 +49,7 @@ class AtomDownloadManagerDelegate : public content::DownloadManagerDelegate {
   void OnDownloadSaveDialogDone(
       uint32_t download_id,
       const content::DownloadTargetCallback& download_callback,
-      gin::Dictionary result);
+      gin_helper::Dictionary result);
 
   content::DownloadManager* download_manager_;
   base::WeakPtrFactory<AtomDownloadManagerDelegate> weak_ptr_factory_;

+ 1 - 1
shell/browser/ui/cocoa/atom_bundle_mover.mm

@@ -38,7 +38,7 @@ namespace electron {
 bool AtomBundleMover::ShouldContinueMove(gin_helper::ErrorThrower thrower,
                                          BundlerMoverConflictType type,
                                          gin::Arguments* args) {
-  gin::Dictionary options;
+  gin::Dictionary options(args->isolate());
   bool hasOptions = args->GetNext(&options);
   base::OnceCallback<v8::Local<v8::Value>(BundlerMoverConflictType)>
       conflict_cb;

+ 3 - 3
shell/browser/ui/file_dialog.h

@@ -10,7 +10,7 @@
 #include <vector>
 
 #include "base/files/file_path.h"
-#include "gin/dictionary.h"
+#include "shell/common/gin_helper/dictionary.h"
 #include "shell/common/promise_util.h"
 
 namespace electron {
@@ -65,12 +65,12 @@ bool ShowOpenDialogSync(const DialogSettings& settings,
                         std::vector<base::FilePath>* paths);
 
 void ShowOpenDialog(const DialogSettings& settings,
-                    electron::util::Promise<gin::Dictionary> promise);
+                    electron::util::Promise<gin_helper::Dictionary> promise);
 
 bool ShowSaveDialogSync(const DialogSettings& settings, base::FilePath* path);
 
 void ShowSaveDialog(const DialogSettings& settings,
-                    electron::util::Promise<gin::Dictionary> promise);
+                    electron::util::Promise<gin_helper::Dictionary> promise);
 
 }  // namespace file_dialog
 

+ 16 - 12
shell/browser/ui/file_dialog_gtk.cc

@@ -138,15 +138,17 @@ class FileChooserDialog {
     gtk_window_present_with_time(GTK_WINDOW(dialog_), time);
   }
 
-  void RunSaveAsynchronous(electron::util::Promise<gin::Dictionary> promise) {
-    save_promise_.reset(
-        new electron::util::Promise<gin::Dictionary>(std::move(promise)));
+  void RunSaveAsynchronous(
+      electron::util::Promise<gin_helper::Dictionary> promise) {
+    save_promise_.reset(new electron::util::Promise<gin_helper::Dictionary>(
+        std::move(promise)));
     RunAsynchronous();
   }
 
-  void RunOpenAsynchronous(electron::util::Promise<gin::Dictionary> promise) {
-    open_promise_.reset(
-        new electron::util::Promise<gin::Dictionary>(std::move(promise)));
+  void RunOpenAsynchronous(
+      electron::util::Promise<gin_helper::Dictionary> promise) {
+    open_promise_.reset(new electron::util::Promise<gin_helper::Dictionary>(
+        std::move(promise)));
     RunAsynchronous();
   }
 
@@ -187,8 +189,10 @@ class FileChooserDialog {
   GtkWidget* preview_;
 
   Filters filters_;
-  std::unique_ptr<electron::util::Promise<gin::Dictionary>> save_promise_;
-  std::unique_ptr<electron::util::Promise<gin::Dictionary>> open_promise_;
+  std::unique_ptr<electron::util::Promise<gin_helper::Dictionary>>
+      save_promise_;
+  std::unique_ptr<electron::util::Promise<gin_helper::Dictionary>>
+      open_promise_;
 
   // Callback for when we update the preview for the selection.
   CHROMEG_CALLBACK_0(FileChooserDialog, void, OnUpdatePreview, GtkWidget*);
@@ -199,7 +203,7 @@ class FileChooserDialog {
 void FileChooserDialog::OnFileDialogResponse(GtkWidget* widget, int response) {
   gtk_widget_hide(dialog_);
   if (save_promise_) {
-    gin::Dictionary dict =
+    gin_helper::Dictionary dict =
         gin::Dictionary::CreateEmpty(save_promise_->isolate());
     if (response == GTK_RESPONSE_ACCEPT) {
       dict.Set("canceled", false);
@@ -210,7 +214,7 @@ void FileChooserDialog::OnFileDialogResponse(GtkWidget* widget, int response) {
     }
     save_promise_->ResolveWithGin(dict);
   } else if (open_promise_) {
-    gin::Dictionary dict =
+    gin_helper::Dictionary dict =
         gin::Dictionary::CreateEmpty(open_promise_->isolate());
     if (response == GTK_RESPONSE_ACCEPT) {
       dict.Set("canceled", false);
@@ -295,7 +299,7 @@ bool ShowOpenDialogSync(const DialogSettings& settings,
 }
 
 void ShowOpenDialog(const DialogSettings& settings,
-                    electron::util::Promise<gin::Dictionary> promise) {
+                    electron::util::Promise<gin_helper::Dictionary> promise) {
   GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_OPEN;
   if (settings.properties & OPEN_DIALOG_OPEN_DIRECTORY)
     action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER;
@@ -318,7 +322,7 @@ bool ShowSaveDialogSync(const DialogSettings& settings, base::FilePath* path) {
 }
 
 void ShowSaveDialog(const DialogSettings& settings,
-                    electron::util::Promise<gin::Dictionary> promise) {
+                    electron::util::Promise<gin_helper::Dictionary> promise) {
   FileChooserDialog* save_dialog =
       new FileChooserDialog(GTK_FILE_CHOOSER_ACTION_SAVE, settings);
   save_dialog->RunSaveAsynchronous(std::move(promise));

+ 18 - 14
shell/browser/ui/file_dialog_mac.mm

@@ -298,11 +298,12 @@ bool ShowOpenDialogSync(const DialogSettings& settings,
   return true;
 }
 
-void OpenDialogCompletion(int chosen,
-                          NSOpenPanel* dialog,
-                          bool security_scoped_bookmarks,
-                          electron::util::Promise<gin::Dictionary> promise) {
-  gin::Dictionary dict = gin::Dictionary::CreateEmpty(promise.isolate());
+void OpenDialogCompletion(
+    int chosen,
+    NSOpenPanel* dialog,
+    bool security_scoped_bookmarks,
+    electron::util::Promise<gin_helper::Dictionary> promise) {
+  gin_helper::Dictionary dict = gin::Dictionary::CreateEmpty(promise.isolate());
   if (chosen == NSFileHandlingPanelCancelButton) {
     dict.Set("canceled", true);
     dict.Set("filePaths", std::vector<base::FilePath>());
@@ -330,7 +331,7 @@ void OpenDialogCompletion(int chosen,
 }
 
 void ShowOpenDialog(const DialogSettings& settings,
-                    electron::util::Promise<gin::Dictionary> promise) {
+                    electron::util::Promise<gin_helper::Dictionary> promise) {
   NSOpenPanel* dialog = [NSOpenPanel openPanel];
 
   SetupDialog(dialog, settings);
@@ -340,7 +341,8 @@ void ShowOpenDialog(const DialogSettings& settings,
   // and pass it to the completion handler.
   bool security_scoped_bookmarks = settings.security_scoped_bookmarks;
 
-  __block electron::util::Promise<gin::Dictionary> p = std::move(promise);
+  __block electron::util::Promise<gin_helper::Dictionary> p =
+      std::move(promise);
 
   if (!settings.parent_window || !settings.parent_window->GetNativeWindow() ||
       settings.force_detached) {
@@ -375,11 +377,12 @@ bool ShowSaveDialogSync(const DialogSettings& settings, base::FilePath* path) {
   return true;
 }
 
-void SaveDialogCompletion(int chosen,
-                          NSSavePanel* dialog,
-                          bool security_scoped_bookmarks,
-                          electron::util::Promise<gin::Dictionary> promise) {
-  gin::Dictionary dict = gin::Dictionary::CreateEmpty(promise.isolate());
+void SaveDialogCompletion(
+    int chosen,
+    NSSavePanel* dialog,
+    bool security_scoped_bookmarks,
+    electron::util::Promise<gin_helper::Dictionary> promise) {
+  gin_helper::Dictionary dict = gin::Dictionary::CreateEmpty(promise.isolate());
   if (chosen == NSFileHandlingPanelCancelButton) {
     dict.Set("canceled", true);
     dict.Set("filePath", base::FilePath());
@@ -402,7 +405,7 @@ void SaveDialogCompletion(int chosen,
 }
 
 void ShowSaveDialog(const DialogSettings& settings,
-                    electron::util::Promise<gin::Dictionary> promise) {
+                    electron::util::Promise<gin_helper::Dictionary> promise) {
   NSSavePanel* dialog = [NSSavePanel savePanel];
 
   SetupDialog(dialog, settings);
@@ -413,7 +416,8 @@ void ShowSaveDialog(const DialogSettings& settings,
   // and pass it to the completion handler.
   bool security_scoped_bookmarks = settings.security_scoped_bookmarks;
 
-  __block electron::util::Promise<gin::Dictionary> p = std::move(promise);
+  __block electron::util::Promise<gin_helper::Dictionary> p =
+      std::move(promise);
 
   if (!settings.parent_window || !settings.parent_window->GetNativeWindow() ||
       settings.force_detached) {

+ 11 - 10
shell/browser/ui/file_dialog_win.cc

@@ -82,10 +82,10 @@ bool CreateDialogThread(RunState* run_state) {
   return true;
 }
 
-void OnDialogOpened(electron::util::Promise<gin::Dictionary> promise,
+void OnDialogOpened(electron::util::Promise<gin_helper::Dictionary> promise,
                     bool canceled,
                     std::vector<base::FilePath> paths) {
-  gin::Dictionary dict = gin::Dictionary::CreateEmpty(promise.isolate());
+  gin_helper::Dictionary dict = gin::Dictionary::CreateEmpty(promise.isolate());
   dict.Set("canceled", canceled);
   dict.Set("filePaths", paths);
   promise.ResolveWithGin(dict);
@@ -94,7 +94,7 @@ void OnDialogOpened(electron::util::Promise<gin::Dictionary> promise,
 void RunOpenDialogInNewThread(
     const RunState& run_state,
     const DialogSettings& settings,
-    electron::util::Promise<gin::Dictionary> promise) {
+    electron::util::Promise<gin_helper::Dictionary> promise) {
   std::vector<base::FilePath> paths;
   bool result = ShowOpenDialogSync(settings, &paths);
   run_state.ui_task_runner->PostTask(
@@ -103,10 +103,10 @@ void RunOpenDialogInNewThread(
   run_state.ui_task_runner->DeleteSoon(FROM_HERE, run_state.dialog_thread);
 }
 
-void OnSaveDialogDone(electron::util::Promise<gin::Dictionary> promise,
+void OnSaveDialogDone(electron::util::Promise<gin_helper::Dictionary> promise,
                       bool canceled,
                       const base::FilePath path) {
-  gin::Dictionary dict = gin::Dictionary::CreateEmpty(promise.isolate());
+  gin_helper::Dictionary dict = gin::Dictionary::CreateEmpty(promise.isolate());
   dict.Set("canceled", canceled);
   dict.Set("filePath", path);
   promise.ResolveWithGin(dict);
@@ -115,7 +115,7 @@ void OnSaveDialogDone(electron::util::Promise<gin::Dictionary> promise,
 void RunSaveDialogInNewThread(
     const RunState& run_state,
     const DialogSettings& settings,
-    electron::util::Promise<gin::Dictionary> promise) {
+    electron::util::Promise<gin_helper::Dictionary> promise) {
   base::FilePath path;
   bool result = ShowSaveDialogSync(settings, &path);
   run_state.ui_task_runner->PostTask(
@@ -277,8 +277,8 @@ bool ShowOpenDialogSync(const DialogSettings& settings,
 }
 
 void ShowOpenDialog(const DialogSettings& settings,
-                    electron::util::Promise<gin::Dictionary> promise) {
-  gin::Dictionary dict = gin::Dictionary::CreateEmpty(promise.isolate());
+                    electron::util::Promise<gin_helper::Dictionary> promise) {
+  gin_helper::Dictionary dict = gin::Dictionary::CreateEmpty(promise.isolate());
   RunState run_state;
   if (!CreateDialogThread(&run_state)) {
     dict.Set("canceled", true);
@@ -327,10 +327,11 @@ bool ShowSaveDialogSync(const DialogSettings& settings, base::FilePath* path) {
 }
 
 void ShowSaveDialog(const DialogSettings& settings,
-                    electron::util::Promise<gin::Dictionary> promise) {
+                    electron::util::Promise<gin_helper::Dictionary> promise) {
   RunState run_state;
   if (!CreateDialogThread(&run_state)) {
-    gin::Dictionary dict = gin::Dictionary::CreateEmpty(promise.isolate());
+    gin_helper::Dictionary dict =
+        gin::Dictionary::CreateEmpty(promise.isolate());
     dict.Set("canceled", true);
     dict.Set("filePath", base::FilePath());
     promise.ResolveWithGin(dict);

+ 5 - 4
shell/browser/web_dialog_helper.cc

@@ -28,6 +28,7 @@
 #include "shell/browser/ui/file_dialog.h"
 #include "shell/common/gin_converters/callback_converter.h"
 #include "shell/common/gin_converters/file_path_converter.h"
+#include "shell/common/gin_helper/dictionary.h"
 #include "ui/shell_dialogs/selected_file_info.h"
 
 using blink::mojom::FileChooserFileInfo;
@@ -55,7 +56,7 @@ class FileSelectHelper : public base::RefCounted<FileSelectHelper>,
 
   void ShowOpenDialog(const file_dialog::DialogSettings& settings) {
     v8::Isolate* isolate = v8::Isolate::GetCurrent();
-    electron::util::Promise<gin::Dictionary> promise(isolate);
+    electron::util::Promise<gin_helper::Dictionary> promise(isolate);
 
     auto callback = base::BindOnce(&FileSelectHelper::OnOpenDialogDone, this);
     ignore_result(promise.Then(std::move(callback)));
@@ -65,7 +66,7 @@ class FileSelectHelper : public base::RefCounted<FileSelectHelper>,
 
   void ShowSaveDialog(const file_dialog::DialogSettings& settings) {
     v8::Isolate* isolate = v8::Isolate::GetCurrent();
-    electron::util::Promise<gin::Dictionary> promise(isolate);
+    electron::util::Promise<gin_helper::Dictionary> promise(isolate);
 
     auto callback = base::BindOnce(&FileSelectHelper::OnSaveDialogDone, this);
     ignore_result(promise.Then(std::move(callback)));
@@ -116,7 +117,7 @@ class FileSelectHelper : public base::RefCounted<FileSelectHelper>,
     AddRef();
   }
 
-  void OnOpenDialogDone(gin::Dictionary result) {
+  void OnOpenDialogDone(gin_helper::Dictionary result) {
     std::vector<FileChooserFileInfoPtr> file_info;
     bool canceled = true;
     result.Get("canceled", &canceled);
@@ -158,7 +159,7 @@ class FileSelectHelper : public base::RefCounted<FileSelectHelper>,
     }
   }
 
-  void OnSaveDialogDone(gin::Dictionary result) {
+  void OnSaveDialogDone(gin_helper::Dictionary result) {
     std::vector<FileChooserFileInfoPtr> file_info;
     bool canceled = true;
     result.Get("canceled", &canceled);

+ 6 - 5
shell/common/api/electron_bindings.cc

@@ -24,6 +24,7 @@
 #include "shell/browser/browser.h"
 #include "shell/common/api/locker.h"
 #include "shell/common/application_info.h"
+#include "shell/common/gin_helper/dictionary.h"
 #include "shell/common/heap_snapshot.h"
 #include "shell/common/native_mate_converters/file_path_converter.h"
 #include "shell/common/native_mate_converters/string16_converter.h"
@@ -162,7 +163,7 @@ v8::Local<v8::Value> ElectronBindings::GetHeapStatistics(v8::Isolate* isolate) {
   v8::HeapStatistics v8_heap_stats;
   isolate->GetHeapStatistics(&v8_heap_stats);
 
-  mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
+  gin_helper::Dictionary dict = gin::Dictionary::CreateEmpty(isolate);
   dict.SetHidden("simple", true);
   dict.Set("totalHeapSize",
            static_cast<double>(v8_heap_stats.total_heap_size() >> 10));
@@ -207,7 +208,7 @@ v8::Local<v8::Value> ElectronBindings::GetSystemMemoryInfo(
     return v8::Undefined(isolate);
   }
 
-  mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
+  gin_helper::Dictionary dict = gin::Dictionary::CreateEmpty(isolate);
   dict.SetHidden("simple", true);
   dict.Set("total", mem_info.total);
 
@@ -256,7 +257,7 @@ v8::Local<v8::Value> ElectronBindings::GetBlinkMemoryInfo(
   auto allocated = blink::ProcessHeap::TotalAllocatedObjectSize();
   auto total = blink::ProcessHeap::TotalAllocatedSpace();
 
-  mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
+  gin_helper::Dictionary dict = gin::Dictionary::CreateEmpty(isolate);
   dict.SetHidden("simple", true);
   dict.Set("allocated", static_cast<double>(allocated >> 10));
   dict.Set("total", static_cast<double>(total >> 10));
@@ -308,7 +309,7 @@ void ElectronBindings::DidReceiveMemoryDump(
 v8::Local<v8::Value> ElectronBindings::GetCPUUsage(
     base::ProcessMetrics* metrics,
     v8::Isolate* isolate) {
-  mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
+  gin_helper::Dictionary dict = gin::Dictionary::CreateEmpty(isolate);
   dict.SetHidden("simple", true);
   int processor_count = base::SysInfo::NumberOfProcessors();
   dict.Set("percentCPUUsage",
@@ -329,7 +330,7 @@ v8::Local<v8::Value> ElectronBindings::GetCPUUsage(
 v8::Local<v8::Value> ElectronBindings::GetIOCounters(v8::Isolate* isolate) {
   auto metrics = base::ProcessMetrics::CreateCurrentProcessMetrics();
   base::IoCounters io_counters;
-  mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
+  gin_helper::Dictionary dict = gin::Dictionary::CreateEmpty(isolate);
   dict.SetHidden("simple", true);
 
   if (metrics->GetIOCounters(&io_counters)) {

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

@@ -30,6 +30,23 @@ struct Converter<unsigned long> {  // NOLINT(runtime/int)
 };
 #endif
 
+template <>
+struct Converter<const 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<const char[n]> {
+  static v8::Local<v8::Value> ToV8(v8::Isolate* isolate, const char* val) {
+    return v8::String::NewFromUtf8(isolate, val, v8::NewStringType::kNormal,
+                                   n - 1)
+        .ToLocalChecked();
+  }
+};
+
 template <>
 struct Converter<v8::Local<v8::Array>> {
   static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,

+ 53 - 0
shell/common/gin_helper/dictionary.h

@@ -56,9 +56,41 @@ struct CallbackTraits<
 // convert between 2 types, we must not add any member.
 class Dictionary : public gin::Dictionary {
  public:
+  Dictionary() : gin::Dictionary(nullptr) {}
   Dictionary(v8::Isolate* isolate, v8::Local<v8::Object> object)
       : gin::Dictionary(isolate, object) {}
 
+  // Allow implicitly converting from gin::Dictionary, as it is absolutely
+  // safe in this case.
+  Dictionary(const gin::Dictionary& dict)  // NOLINT(runtime/explicit)
+      : gin::Dictionary(dict) {}
+
+  template <typename T>
+  bool GetHidden(base::StringPiece key, T* out) const {
+    v8::Local<v8::Context> context = isolate()->GetCurrentContext();
+    v8::Local<v8::Private> privateKey =
+        v8::Private::ForApi(isolate(), gin::StringToV8(isolate(), key));
+    v8::Local<v8::Value> value;
+    v8::Maybe<bool> result = GetHandle()->HasPrivate(context, privateKey);
+    if (result.IsJust() && result.FromJust() &&
+        GetHandle()->GetPrivate(context, privateKey).ToLocal(&value))
+      return gin::ConvertFromV8(isolate(), value, out);
+    return false;
+  }
+
+  template <typename T>
+  bool SetHidden(base::StringPiece key, T val) {
+    v8::Local<v8::Value> v8_value;
+    if (!gin::TryConvertToV8(isolate(), val, &v8_value))
+      return false;
+    v8::Local<v8::Context> context = isolate()->GetCurrentContext();
+    v8::Local<v8::Private> privateKey =
+        v8::Private::ForApi(isolate(), gin::StringToV8(isolate(), key));
+    v8::Maybe<bool> result =
+        GetHandle()->SetPrivate(context, privateKey, v8_value);
+    return !result.IsNothing() && result.FromJust();
+  }
+
   template <typename T>
   bool SetMethod(base::StringPiece key, const T& callback) {
     auto context = isolate()->GetCurrentContext();
@@ -98,4 +130,25 @@ class Dictionary : public gin::Dictionary {
 
 }  // namespace gin_helper
 
+namespace gin {
+
+template <>
+struct Converter<gin_helper::Dictionary> {
+  static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
+                                   gin_helper::Dictionary val) {
+    return val.GetHandle();
+  }
+  static bool FromV8(v8::Isolate* isolate,
+                     v8::Local<v8::Value> val,
+                     gin_helper::Dictionary* out) {
+    gin::Dictionary gdict(isolate);
+    if (!ConvertFromV8(isolate, val, &gdict))
+      return false;
+    *out = gin_helper::Dictionary(gdict);
+    return true;
+  }
+};
+
+}  // namespace gin
+
 #endif  // SHELL_COMMON_GIN_HELPER_DICTIONARY_H_

+ 15 - 13
shell/common/native_mate_converters/gfx_converter.cc

@@ -5,6 +5,7 @@
 #include "shell/common/native_mate_converters/gfx_converter.h"
 
 #include "native_mate/dictionary.h"
+#include "shell/common/gin_helper/dictionary.h"
 #include "ui/display/display.h"
 #include "ui/display/screen.h"
 #include "ui/gfx/geometry/point.h"
@@ -15,7 +16,7 @@ namespace mate {
 
 v8::Local<v8::Value> Converter<gfx::Point>::ToV8(v8::Isolate* isolate,
                                                  const gfx::Point& val) {
-  mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
+  gin_helper::Dictionary dict = gin::Dictionary::CreateEmpty(isolate);
   dict.SetHidden("simple", true);
   dict.Set("x", val.x());
   dict.Set("y", val.y());
@@ -25,8 +26,8 @@ v8::Local<v8::Value> Converter<gfx::Point>::ToV8(v8::Isolate* isolate,
 bool Converter<gfx::Point>::FromV8(v8::Isolate* isolate,
                                    v8::Local<v8::Value> val,
                                    gfx::Point* out) {
-  mate::Dictionary dict;
-  if (!ConvertFromV8(isolate, val, &dict))
+  gin::Dictionary dict(isolate);
+  if (!gin::ConvertFromV8(isolate, val, &dict))
     return false;
   double x, y;
   if (!dict.Get("x", &x) || !dict.Get("y", &y))
@@ -38,7 +39,7 @@ bool Converter<gfx::Point>::FromV8(v8::Isolate* isolate,
 
 v8::Local<v8::Value> Converter<gfx::PointF>::ToV8(v8::Isolate* isolate,
                                                   const gfx::PointF& val) {
-  mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
+  gin_helper::Dictionary dict = gin::Dictionary::CreateEmpty(isolate);
   dict.SetHidden("simple", true);
   dict.Set("x", val.x());
   dict.Set("y", val.y());
@@ -48,8 +49,8 @@ v8::Local<v8::Value> Converter<gfx::PointF>::ToV8(v8::Isolate* isolate,
 bool Converter<gfx::PointF>::FromV8(v8::Isolate* isolate,
                                     v8::Local<v8::Value> val,
                                     gfx::PointF* out) {
-  mate::Dictionary dict;
-  if (!ConvertFromV8(isolate, val, &dict))
+  gin::Dictionary dict(isolate);
+  if (!gin::ConvertFromV8(isolate, val, &dict))
     return false;
   float x, y;
   if (!dict.Get("x", &x) || !dict.Get("y", &y))
@@ -60,7 +61,7 @@ bool Converter<gfx::PointF>::FromV8(v8::Isolate* isolate,
 
 v8::Local<v8::Value> Converter<gfx::Size>::ToV8(v8::Isolate* isolate,
                                                 const gfx::Size& val) {
-  mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
+  gin_helper::Dictionary dict = gin::Dictionary::CreateEmpty(isolate);
   dict.SetHidden("simple", true);
   dict.Set("width", val.width());
   dict.Set("height", val.height());
@@ -70,8 +71,8 @@ v8::Local<v8::Value> Converter<gfx::Size>::ToV8(v8::Isolate* isolate,
 bool Converter<gfx::Size>::FromV8(v8::Isolate* isolate,
                                   v8::Local<v8::Value> val,
                                   gfx::Size* out) {
-  mate::Dictionary dict;
-  if (!ConvertFromV8(isolate, val, &dict))
+  gin::Dictionary dict(isolate);
+  if (!gin::ConvertFromV8(isolate, val, &dict))
     return false;
   int width, height;
   if (!dict.Get("width", &width) || !dict.Get("height", &height))
@@ -82,7 +83,7 @@ bool Converter<gfx::Size>::FromV8(v8::Isolate* isolate,
 
 v8::Local<v8::Value> Converter<gfx::Rect>::ToV8(v8::Isolate* isolate,
                                                 const gfx::Rect& val) {
-  mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
+  gin_helper::Dictionary dict = gin::Dictionary::CreateEmpty(isolate);
   dict.SetHidden("simple", true);
   dict.Set("x", val.x());
   dict.Set("y", val.y());
@@ -94,8 +95,8 @@ v8::Local<v8::Value> Converter<gfx::Rect>::ToV8(v8::Isolate* isolate,
 bool Converter<gfx::Rect>::FromV8(v8::Isolate* isolate,
                                   v8::Local<v8::Value> val,
                                   gfx::Rect* out) {
-  mate::Dictionary dict;
-  if (!ConvertFromV8(isolate, val, &dict))
+  gin::Dictionary dict(isolate);
+  if (!gin::ConvertFromV8(isolate, val, &dict))
     return false;
   int x, y, width, height;
   if (!dict.Get("x", &x) || !dict.Get("y", &y) || !dict.Get("width", &width) ||
@@ -140,7 +141,8 @@ v8::Local<v8::Value> Converter<display::Display>::ToV8(
     v8::Isolate* isolate,
     const display::Display& val) {
   mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
-  dict.SetHidden("simple", true);
+  // TODO(zcbenz): Just call SetHidden when this file is converted to gin.
+  gin_helper::Dictionary(isolate, dict.GetHandle()).SetHidden("simple", true);
   dict.Set("id", val.id());
   dict.Set("bounds", val.bounds());
   dict.Set("workArea", val.work_area());

+ 4 - 6
shell/common/native_mate_converters/v8_value_converter.cc

@@ -10,10 +10,8 @@
 #include <utility>
 #include <vector>
 
-#include "base/logging.h"
 #include "base/values.h"
-#include "native_mate/dictionary.h"
-
+#include "shell/common/gin_helper/dictionary.h"
 #include "shell/common/node_bindings.h"
 #include "shell/common/node_includes.h"
 
@@ -224,7 +222,7 @@ v8::Local<v8::Value> V8ValueConverter::ToV8Array(
 v8::Local<v8::Value> V8ValueConverter::ToV8Object(
     v8::Isolate* isolate,
     const base::DictionaryValue* val) const {
-  mate::Dictionary result = mate::Dictionary::CreateEmpty(isolate);
+  gin_helper::Dictionary result = gin::Dictionary::CreateEmpty(isolate);
   result.SetHidden("simple", true);
 
   for (base::DictionaryValue::Iterator iter(*val); !iter.IsAtEnd();
@@ -262,7 +260,7 @@ v8::Local<v8::Value> V8ValueConverter::ToArrayBuffer(
   // From this point, if something goes wrong(can't find Buffer class for
   // example) we'll simply return a Uint8Array based on the created ArrayBuffer.
   // This can happen if no preload script was specified to the renderer.
-  mate::Dictionary global(isolate, context->Global());
+  gin_helper::Dictionary global(isolate, context->Global());
   v8::Local<v8::Value> buffer_value;
 
   // Get the Buffer class stored as a hidden value in the global object. We'll
@@ -272,7 +270,7 @@ v8::Local<v8::Value> V8ValueConverter::ToArrayBuffer(
     return v8::Uint8Array::New(array_buffer, 0, length);
   }
 
-  mate::Dictionary buffer_class(
+  gin::Dictionary buffer_class(
       isolate,
       buffer_value->ToObject(isolate->GetCurrentContext()).ToLocalChecked());
   v8::Local<v8::Value> from_value;

+ 2 - 1
shell/renderer/atom_sandboxed_renderer_client.cc

@@ -15,6 +15,7 @@
 #include "native_mate/dictionary.h"
 #include "shell/common/api/electron_bindings.h"
 #include "shell/common/application_info.h"
+#include "shell/common/gin_helper/dictionary.h"
 #include "shell/common/native_mate_converters/string16_converter.h"
 #include "shell/common/native_mate_converters/value_converter.h"
 #include "shell/common/node_bindings.h"
@@ -45,7 +46,7 @@ bool IsDevToolsExtension(content::RenderFrame* render_frame) {
 
 v8::Local<v8::Object> GetModuleCache(v8::Isolate* isolate) {
   auto context = isolate->GetCurrentContext();
-  mate::Dictionary global(isolate, context->Global());
+  gin_helper::Dictionary global(isolate, context->Global());
   v8::Local<v8::Value> cache;
 
   if (!global.GetHidden(kModuleCacheKey, &cache)) {

+ 5 - 7
shell/renderer/renderer_client_base.cc

@@ -19,9 +19,9 @@
 #include "content/public/renderer/render_thread.h"
 #include "content/public/renderer/render_view.h"
 #include "electron/buildflags/buildflags.h"
-#include "native_mate/dictionary.h"
 #include "printing/buildflags/buildflags.h"
 #include "shell/common/color_util.h"
+#include "shell/common/gin_helper/dictionary.h"
 #include "shell/common/native_mate_converters/value_converter.h"
 #include "shell/common/options_switches.h"
 #include "shell/renderer/atom_autofill_agent.h"
@@ -114,7 +114,7 @@ void RendererClientBase::DidCreateScriptContext(
   // global.setHidden("contextId", `${processHostId}-${++next_context_id_}`)
   auto context_id = base::StringPrintf(
       "%s-%" PRId64, renderer_client_id_.c_str(), ++next_context_id_);
-  mate::Dictionary global(context->GetIsolate(), context->Global());
+  gin_helper::Dictionary global(context->GetIsolate(), context->Global());
   global.SetHidden("contextId", context_id);
 
   auto* command_line = base::CommandLine::ForCurrentProcess();
@@ -125,9 +125,7 @@ void RendererClientBase::DidCreateScriptContext(
 
 void RendererClientBase::AddRenderBindings(
     v8::Isolate* isolate,
-    v8::Local<v8::Object> binding_object) {
-  mate::Dictionary dict(isolate, binding_object);
-}
+    v8::Local<v8::Object> binding_object) {}
 
 void RendererClientBase::RenderThreadStarted() {
   auto* command_line = base::CommandLine::ForCurrentProcess();
@@ -380,14 +378,14 @@ bool RendererClientBase::IsWebViewFrame(
   if (render_frame->IsMainFrame())
     return false;
 
-  mate::Dictionary window_dict(
+  gin::Dictionary window_dict(
       isolate, GetContext(render_frame->GetWebFrame(), isolate)->Global());
 
   v8::Local<v8::Object> frame_element;
   if (!window_dict.Get("frameElement", &frame_element))
     return false;
 
-  mate::Dictionary frame_element_dict(isolate, frame_element);
+  gin_helper::Dictionary frame_element_dict(isolate, frame_element);
 
   v8::Local<v8::Object> internal;
   if (!frame_element_dict.GetHidden("internal", &internal))