зеркало из https://github.com/electron/electron.git
chore: remove native_mate (Part 2) (#20106)
* add notice to files being removed * add gin version of function_template.h * rename callback.h to avoid confliction * add gin version of callback_converter * add gin converter for OnceCallback * remove callback_converter_gin_adapter.h * remove gin_util.h and gin_utils.h * fix lint warning * add helper for setting methods
This commit is contained in:
Родитель
504cdb13f0
Коммит
81ae154714
|
@ -437,7 +437,6 @@ filenames = {
|
|||
"shell/common/api/event_emitter_caller.cc",
|
||||
"shell/common/api/event_emitter_caller.h",
|
||||
"shell/common/api/features.cc",
|
||||
"shell/common/api/gin_utils.h",
|
||||
"shell/common/api/locker.cc",
|
||||
"shell/common/api/locker.h",
|
||||
"shell/common/api/object_life_monitor.cc",
|
||||
|
@ -475,7 +474,7 @@ filenames = {
|
|||
"shell/common/crash_reporter/linux/crash_dump_handler.h",
|
||||
"shell/common/crash_reporter/win/crash_service_main.cc",
|
||||
"shell/common/crash_reporter/win/crash_service_main.h",
|
||||
"shell/common/gin_converters/callback_converter_gin_adapter.h",
|
||||
"shell/common/gin_converters/callback_converter.h",
|
||||
"shell/common/gin_converters/file_dialog_converter.cc",
|
||||
"shell/common/gin_converters/file_dialog_converter.h",
|
||||
"shell/common/gin_converters/file_path_converter.h",
|
||||
|
@ -489,9 +488,13 @@ filenames = {
|
|||
"shell/common/gin_converters/net_converter.h",
|
||||
"shell/common/gin_converters/std_converter.h",
|
||||
"shell/common/gin_converters/value_converter_gin_adapter.h",
|
||||
"shell/common/gin_helper/callback.cc",
|
||||
"shell/common/gin_helper/callback.h",
|
||||
"shell/common/gin_helper/destroyable.cc",
|
||||
"shell/common/gin_helper/destroyable.h",
|
||||
"shell/common/gin_util.h",
|
||||
"shell/common/gin_helper/dictionary.h",
|
||||
"shell/common/gin_helper/function_template.cc",
|
||||
"shell/common/gin_helper/function_template.h",
|
||||
"shell/common/heap_snapshot.cc",
|
||||
"shell/common/heap_snapshot.h",
|
||||
"shell/common/key_weak_map.h",
|
||||
|
@ -509,8 +512,8 @@ filenames = {
|
|||
"shell/common/native_mate_converters/accelerator_converter.h",
|
||||
"shell/common/native_mate_converters/blink_converter.cc",
|
||||
"shell/common/native_mate_converters/blink_converter.h",
|
||||
"shell/common/native_mate_converters/callback.cc",
|
||||
"shell/common/native_mate_converters/callback.h",
|
||||
"shell/common/native_mate_converters/callback_converter_deprecated.cc",
|
||||
"shell/common/native_mate_converters/callback_converter_deprecated.h",
|
||||
"shell/common/native_mate_converters/content_converter.cc",
|
||||
"shell/common/native_mate_converters/content_converter.h",
|
||||
"shell/common/native_mate_converters/file_dialog_converter.h",
|
||||
|
|
|
@ -12,6 +12,10 @@
|
|||
#include "base/optional.h"
|
||||
#include "native_mate/converter.h"
|
||||
|
||||
// =============================== NOTICE ===============================
|
||||
// Do not add code here, native_mate is being removed. Any new code
|
||||
// should use gin instead.
|
||||
|
||||
namespace mate {
|
||||
|
||||
// Arguments is a wrapper around v8::FunctionCallbackInfo that integrates
|
||||
|
|
|
@ -13,6 +13,10 @@
|
|||
#include "native_mate/wrappable_base.h"
|
||||
#include "v8/include/v8.h"
|
||||
|
||||
// =============================== NOTICE ===============================
|
||||
// Do not add code here, native_mate is being removed. Any new code
|
||||
// should use gin instead.
|
||||
|
||||
namespace mate {
|
||||
|
||||
enum CreateFunctionTemplateFlags {
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
#include "shell/browser/relauncher.h"
|
||||
#include "shell/common/application_info.h"
|
||||
#include "shell/common/atom_command_line.h"
|
||||
#include "shell/common/native_mate_converters/callback.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"
|
||||
#include "shell/common/native_mate_converters/image_converter.h"
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#include "shell/browser/browser.h"
|
||||
#include "shell/browser/browser_observer.h"
|
||||
#include "shell/common/error_util.h"
|
||||
#include "shell/common/native_mate_converters/callback.h"
|
||||
#include "shell/common/native_mate_converters/callback_converter_deprecated.h"
|
||||
#include "shell/common/promise_util.h"
|
||||
|
||||
#if defined(USE_NSS_CERTS)
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include "shell/browser/native_window.h"
|
||||
#include "shell/browser/window_list.h"
|
||||
#include "shell/common/api/event_emitter_caller.h"
|
||||
#include "shell/common/native_mate_converters/callback.h"
|
||||
#include "shell/common/native_mate_converters/callback_converter_deprecated.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
|
||||
namespace mate {
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include "shell/browser/window_list.h"
|
||||
#include "shell/common/api/constructor.h"
|
||||
#include "shell/common/color_util.h"
|
||||
#include "shell/common/native_mate_converters/callback.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"
|
||||
#include "shell/common/options_switches.h"
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include "base/threading/thread_restrictions.h"
|
||||
#include "content/public/browser/tracing_controller.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "shell/common/native_mate_converters/callback.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/value_converter.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "net/cookies/cookie_util.h"
|
||||
#include "shell/browser/atom_browser_context.h"
|
||||
#include "shell/browser/cookie_change_notifier.h"
|
||||
#include "shell/common/native_mate_converters/callback.h"
|
||||
#include "shell/common/native_mate_converters/callback_converter_deprecated.h"
|
||||
#include "shell/common/native_mate_converters/gurl_converter.h"
|
||||
#include "shell/common/native_mate_converters/value_converter.h"
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#include "content/public/browser/devtools_agent_host.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "shell/common/native_mate_converters/callback.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"
|
||||
|
||||
|
|
|
@ -6,15 +6,15 @@
|
|||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "gin/dictionary.h"
|
||||
#include "shell/browser/ui/certificate_trust.h"
|
||||
#include "shell/browser/ui/file_dialog.h"
|
||||
#include "shell/browser/ui/message_box.h"
|
||||
#include "shell/common/api/gin_utils.h"
|
||||
#include "shell/common/gin_converters/callback_converter.h"
|
||||
#include "shell/common/gin_converters/file_dialog_converter.h"
|
||||
#include "shell/common/gin_converters/message_box_converter.h"
|
||||
#include "shell/common/gin_converters/native_window_converter.h"
|
||||
#include "shell/common/gin_converters/net_converter.h"
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
#include "shell/common/promise_util.h"
|
||||
|
||||
|
@ -87,33 +87,17 @@ void Initialize(v8::Local<v8::Object> exports,
|
|||
v8::Local<v8::Context> context,
|
||||
void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
gin::Dictionary dict(isolate, exports);
|
||||
dict.Set("showMessageBoxSync",
|
||||
gin::ConvertCallbackToV8Leaked(
|
||||
isolate, base::BindRepeating(&ShowMessageBoxSync)));
|
||||
dict.Set("showMessageBox",
|
||||
gin::ConvertCallbackToV8Leaked(
|
||||
isolate, base::BindRepeating(&ShowMessageBox)));
|
||||
dict.Set("showErrorBox",
|
||||
gin::ConvertCallbackToV8Leaked(
|
||||
isolate, base::BindRepeating(&electron::ShowErrorBox)));
|
||||
dict.Set("showOpenDialogSync",
|
||||
gin::ConvertCallbackToV8Leaked(
|
||||
isolate, base::BindRepeating(&ShowOpenDialogSync)));
|
||||
dict.Set("showOpenDialog",
|
||||
gin::ConvertCallbackToV8Leaked(
|
||||
isolate, base::BindRepeating(&ShowOpenDialog)));
|
||||
dict.Set("showSaveDialogSync",
|
||||
gin::ConvertCallbackToV8Leaked(
|
||||
isolate, base::BindRepeating(&ShowSaveDialogSync)));
|
||||
dict.Set("showSaveDialog",
|
||||
gin::ConvertCallbackToV8Leaked(
|
||||
isolate, base::BindRepeating(&ShowSaveDialog)));
|
||||
gin_helper::Dictionary dict(isolate, exports);
|
||||
dict.SetMethod("showMessageBoxSync", &ShowMessageBoxSync);
|
||||
dict.SetMethod("showMessageBox", &ShowMessageBox);
|
||||
dict.SetMethod("showErrorBox", &electron::ShowErrorBox);
|
||||
dict.SetMethod("showOpenDialogSync", &ShowOpenDialogSync);
|
||||
dict.SetMethod("showOpenDialog", &ShowOpenDialog);
|
||||
dict.SetMethod("showSaveDialogSync", &ShowSaveDialogSync);
|
||||
dict.SetMethod("showSaveDialog", &ShowSaveDialog);
|
||||
#if defined(OS_MACOSX) || defined(OS_WIN)
|
||||
dict.Set("showCertificateTrustDialog",
|
||||
gin::ConvertCallbackToV8Leaked(
|
||||
isolate,
|
||||
base::BindRepeating(&certificate_trust::ShowCertificateTrust)));
|
||||
dict.SetMethod("showCertificateTrustDialog",
|
||||
&certificate_trust::ShowCertificateTrust);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include "native_mate/dictionary.h"
|
||||
#include "net/base/filename_util.h"
|
||||
#include "shell/browser/atom_browser_main_parts.h"
|
||||
#include "shell/common/native_mate_converters/callback.h"
|
||||
#include "shell/common/native_mate_converters/callback_converter_deprecated.h"
|
||||
#include "shell/common/native_mate_converters/file_dialog_converter.h"
|
||||
#include "shell/common/native_mate_converters/file_path_converter.h"
|
||||
#include "shell/common/native_mate_converters/gurl_converter.h"
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include "native_mate/dictionary.h"
|
||||
#include "shell/browser/api/atom_api_system_preferences.h"
|
||||
#include "shell/common/native_mate_converters/accelerator_converter.h"
|
||||
#include "shell/common/native_mate_converters/callback.h"
|
||||
#include "shell/common/native_mate_converters/callback_converter_deprecated.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include <vector>
|
||||
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "shell/common/native_mate_converters/callback.h"
|
||||
#include "shell/common/native_mate_converters/callback_converter_deprecated.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
|
||||
namespace mate {
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include "native_mate/object_template_builder.h"
|
||||
#include "shell/browser/native_window.h"
|
||||
#include "shell/common/native_mate_converters/accelerator_converter.h"
|
||||
#include "shell/common/native_mate_converters/callback.h"
|
||||
#include "shell/common/native_mate_converters/callback_converter_deprecated.h"
|
||||
#include "shell/common/native_mate_converters/image_converter.h"
|
||||
#include "shell/common/native_mate_converters/string16_converter.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include "native_mate/handle.h"
|
||||
#include "shell/browser/atom_browser_context.h"
|
||||
#include "shell/browser/net/system_network_context_manager.h"
|
||||
#include "shell/common/native_mate_converters/callback.h"
|
||||
#include "shell/common/native_mate_converters/callback_converter_deprecated.h"
|
||||
#include "shell/common/native_mate_converters/file_path_converter.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#include "base/power_monitor/power_monitor_device_source.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "shell/browser/browser.h"
|
||||
#include "shell/common/native_mate_converters/callback.h"
|
||||
#include "shell/common/native_mate_converters/callback_converter_deprecated.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
|
||||
namespace mate {
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
#include "shell/browser/media/media_device_id_salt.h"
|
||||
#include "shell/browser/net/cert_verifier_client.h"
|
||||
#include "shell/browser/session_preferences.h"
|
||||
#include "shell/common/native_mate_converters/callback.h"
|
||||
#include "shell/common/native_mate_converters/callback_converter_deprecated.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/gurl_converter.h"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include "shell/browser/api/atom_api_system_preferences.h"
|
||||
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "shell/common/native_mate_converters/callback.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"
|
||||
#include "ui/gfx/animation/animation.h"
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include "shell/browser/api/atom_api_view.h"
|
||||
#include "shell/browser/api/atom_api_web_contents.h"
|
||||
#include "shell/common/color_util.h"
|
||||
#include "shell/common/native_mate_converters/callback.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/gfx_converter.h"
|
||||
#include "shell/common/native_mate_converters/image_converter.h"
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include "shell/browser/api/atom_api_session.h"
|
||||
#include "shell/browser/api/atom_api_web_contents.h"
|
||||
#include "shell/browser/atom_browser_context.h"
|
||||
#include "shell/common/gin_converters/callback_converter_gin_adapter.h"
|
||||
#include "shell/common/gin_converters/callback_converter.h"
|
||||
#include "shell/common/gin_converters/gurl_converter.h"
|
||||
#include "shell/common/gin_converters/net_converter.h"
|
||||
#include "shell/common/gin_converters/std_converter.h"
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include "shell/browser/native_window.h"
|
||||
#include "shell/browser/ui/file_dialog.h"
|
||||
#include "shell/browser/web_contents_preferences.h"
|
||||
#include "shell/common/native_mate_converters/callback.h"
|
||||
#include "shell/common/native_mate_converters/callback_converter_deprecated.h"
|
||||
#include "shell/common/options_switches.h"
|
||||
|
||||
namespace electron {
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#include "mojo/public/cpp/system/string_data_source.h"
|
||||
#include "shell/common/api/event_emitter_caller.h"
|
||||
#include "shell/common/native_mate_converters/callback.h"
|
||||
#include "shell/common/native_mate_converters/callback_converter_deprecated.h"
|
||||
|
||||
#include "shell/common/node_includes.h"
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include "native_mate/object_template_builder.h"
|
||||
#include "native_mate/wrappable.h"
|
||||
#include "shell/common/asar/archive.h"
|
||||
#include "shell/common/native_mate_converters/callback.h"
|
||||
#include "shell/common/native_mate_converters/callback_converter_deprecated.h"
|
||||
#include "shell/common/native_mate_converters/file_path_converter.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
#include "third_party/electron_node/src/node_native_module_env.h"
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
|
||||
#include "base/bind.h"
|
||||
#include "gin/data_object_builder.h"
|
||||
#include "gin/dictionary.h"
|
||||
#include "shell/common/crash_reporter/crash_reporter.h"
|
||||
#include "shell/common/gin_util.h"
|
||||
#include "shell/common/gin_converters/callback_converter.h"
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/native_mate_converters/file_path_converter.h"
|
||||
#include "shell/common/native_mate_converters/map_converter.h"
|
||||
|
||||
|
@ -41,23 +41,26 @@ void Initialize(v8::Local<v8::Object> exports,
|
|||
v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context,
|
||||
void* priv) {
|
||||
using gin_util::SetMethod;
|
||||
auto reporter = base::Unretained(CrashReporter::GetInstance());
|
||||
SetMethod(exports, "start",
|
||||
base::BindRepeating(&CrashReporter::Start, reporter));
|
||||
SetMethod(exports, "addExtraParameter",
|
||||
base::BindRepeating(&CrashReporter::AddExtraParameter, reporter));
|
||||
SetMethod(
|
||||
exports, "removeExtraParameter",
|
||||
gin_helper::Dictionary dict(context->GetIsolate(), exports);
|
||||
dict.SetMethod("start", base::BindRepeating(&CrashReporter::Start, reporter));
|
||||
dict.SetMethod(
|
||||
"addExtraParameter",
|
||||
base::BindRepeating(&CrashReporter::AddExtraParameter, reporter));
|
||||
dict.SetMethod(
|
||||
"removeExtraParameter",
|
||||
base::BindRepeating(&CrashReporter::RemoveExtraParameter, reporter));
|
||||
SetMethod(exports, "getParameters",
|
||||
base::BindRepeating(&CrashReporter::GetParameters, reporter));
|
||||
SetMethod(exports, "getUploadedReports",
|
||||
base::BindRepeating(&CrashReporter::GetUploadedReports, reporter));
|
||||
SetMethod(exports, "setUploadToServer",
|
||||
base::BindRepeating(&CrashReporter::SetUploadToServer, reporter));
|
||||
SetMethod(exports, "getUploadToServer",
|
||||
base::BindRepeating(&CrashReporter::GetUploadToServer, reporter));
|
||||
dict.SetMethod("getParameters",
|
||||
base::BindRepeating(&CrashReporter::GetParameters, reporter));
|
||||
dict.SetMethod(
|
||||
"getUploadedReports",
|
||||
base::BindRepeating(&CrashReporter::GetUploadedReports, reporter));
|
||||
dict.SetMethod(
|
||||
"setUploadToServer",
|
||||
base::BindRepeating(&CrashReporter::SetUploadToServer, reporter));
|
||||
dict.SetMethod(
|
||||
"getUploadToServer",
|
||||
base::BindRepeating(&CrashReporter::GetUploadToServer, reporter));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include <string>
|
||||
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "shell/common/native_mate_converters/callback.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"
|
||||
#include "shell/common/native_mate_converters/string16_converter.h"
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
// 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_API_GIN_UTILS_H_
|
||||
#define SHELL_COMMON_API_GIN_UTILS_H_
|
||||
|
||||
#include "gin/function_template.h"
|
||||
|
||||
namespace gin {
|
||||
|
||||
// NOTE: V8 caches FunctionTemplates. Therefore it is user's responsibility
|
||||
// to ensure this function is called for one type only ONCE in the program's
|
||||
// whole lifetime, otherwise we would have memory leak.
|
||||
template <typename Sig>
|
||||
v8::Local<v8::Function> ConvertCallbackToV8Leaked(
|
||||
v8::Isolate* isolate,
|
||||
const base::RepeatingCallback<Sig>& callback) {
|
||||
// LOG(WARNING) << "Leaky conversion from callback to V8 triggered.";
|
||||
return gin::CreateFunctionTemplate(isolate, callback)
|
||||
->GetFunction(isolate->GetCurrentContext())
|
||||
.ToLocalChecked();
|
||||
}
|
||||
|
||||
} // namespace gin
|
||||
|
||||
#endif // SHELL_COMMON_API_GIN_UTILS_H_
|
|
@ -7,7 +7,7 @@
|
|||
#include "base/callback.h"
|
||||
#include "native_mate/converter.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "shell/common/native_mate_converters/callback.h"
|
||||
#include "shell/common/native_mate_converters/callback_converter_deprecated.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
// 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_CONVERTERS_CALLBACK_CONVERTER_H_
|
||||
#define SHELL_COMMON_GIN_CONVERTERS_CALLBACK_CONVERTER_H_
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "base/callback_helpers.h"
|
||||
#include "shell/common/gin_helper/callback.h"
|
||||
|
||||
namespace gin {
|
||||
|
||||
template <typename Sig>
|
||||
struct Converter<base::RepeatingCallback<Sig>> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const base::RepeatingCallback<Sig>& val) {
|
||||
// We don't use CreateFunctionTemplate here because it creates a new
|
||||
// FunctionTemplate everytime, which is cached by V8 and causes leaks.
|
||||
auto translater =
|
||||
base::Bind(&gin_helper::NativeFunctionInvoker<Sig>::Go, val);
|
||||
// To avoid memory leak, we ensure that the callback can only be called
|
||||
// for once.
|
||||
return gin_helper::CreateFunctionFromTranslater(isolate, translater, true);
|
||||
}
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
base::RepeatingCallback<Sig>* out) {
|
||||
if (!val->IsFunction())
|
||||
return false;
|
||||
|
||||
*out = base::BindRepeating(&gin_helper::V8FunctionInvoker<Sig>::Go, isolate,
|
||||
gin_helper::SafeV8Function(isolate, val));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Sig>
|
||||
struct Converter<base::OnceCallback<Sig>> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
base::OnceCallback<Sig> in) {
|
||||
return gin::ConvertToV8(isolate,
|
||||
base::AdaptCallbackForRepeating(std::move(in)));
|
||||
}
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
base::OnceCallback<Sig>* out) {
|
||||
if (!val->IsFunction())
|
||||
return false;
|
||||
*out = base::BindOnce(&gin_helper::V8FunctionInvoker<Sig>::Go, isolate,
|
||||
gin_helper::SafeV8Function(isolate, val));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace gin
|
||||
|
||||
#endif // SHELL_COMMON_GIN_CONVERTERS_CALLBACK_CONVERTER_H_
|
|
@ -1,44 +0,0 @@
|
|||
// 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_CONVERTERS_CALLBACK_CONVERTER_GIN_ADAPTER_H_
|
||||
#define SHELL_COMMON_GIN_CONVERTERS_CALLBACK_CONVERTER_GIN_ADAPTER_H_
|
||||
|
||||
#include "gin/converter.h"
|
||||
#include "shell/common/native_mate_converters/once_callback.h"
|
||||
|
||||
// TODO(zcbenz): Move the implementations from native_mate_converters to here.
|
||||
|
||||
namespace gin {
|
||||
|
||||
template <typename Sig>
|
||||
struct Converter<base::RepeatingCallback<Sig>> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const base::RepeatingCallback<Sig>& in) {
|
||||
return mate::ConvertToV8(isolate, in);
|
||||
}
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
base::RepeatingCallback<Sig>* out) {
|
||||
return mate::ConvertFromV8(isolate, val, out);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Sig>
|
||||
struct Converter<base::OnceCallback<Sig>> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
base::OnceCallback<Sig> in) {
|
||||
return mate::ConvertToV8(isolate, in);
|
||||
}
|
||||
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
base::OnceCallback<Sig>* out) {
|
||||
return mate::ConvertFromV8(isolate, val, out);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace gin
|
||||
|
||||
#endif // SHELL_COMMON_GIN_CONVERTERS_CALLBACK_CONVERTER_GIN_ADAPTER_H_
|
|
@ -1,18 +1,13 @@
|
|||
// Copyright (c) 2015 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2019 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/common/native_mate_converters/callback.h"
|
||||
#include "base/stl_util.h"
|
||||
#include "shell/common/gin_helper/callback.h"
|
||||
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "gin/dictionary.h"
|
||||
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace mate {
|
||||
|
||||
namespace internal {
|
||||
namespace gin_helper {
|
||||
|
||||
namespace {
|
||||
|
||||
|
@ -41,7 +36,7 @@ v8::Persistent<v8::FunctionTemplate> g_call_translater;
|
|||
|
||||
void CallTranslater(v8::Local<v8::External> external,
|
||||
v8::Local<v8::Object> state,
|
||||
mate::Arguments* args) {
|
||||
gin::Arguments* args) {
|
||||
// Whether the callback should only be called for once.
|
||||
v8::Isolate* isolate = args->isolate();
|
||||
auto context = isolate->GetCurrentContext();
|
||||
|
@ -52,7 +47,7 @@ void CallTranslater(v8::Local<v8::External> external,
|
|||
if (one_time) {
|
||||
auto called_symbol = mate::StringToSymbol(isolate, "called");
|
||||
if (state->Has(context, called_symbol).ToChecked()) {
|
||||
args->ThrowError("callback can only be called for once");
|
||||
args->ThrowTypeError("callback can only be called for once");
|
||||
return;
|
||||
} else {
|
||||
state->Set(context, called_symbol, v8::Boolean::New(isolate, true))
|
||||
|
@ -74,9 +69,10 @@ void CallTranslater(v8::Local<v8::External> external,
|
|||
struct DeleteOnUIThread {
|
||||
template <typename T>
|
||||
static void Destruct(const T* x) {
|
||||
if (Locker::IsBrowserProcess() &&
|
||||
!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
|
||||
BrowserThread::DeleteSoon(BrowserThread::UI, FROM_HERE, x);
|
||||
if (mate::Locker::IsBrowserProcess() &&
|
||||
!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
|
||||
content::BrowserThread::DeleteSoon(content::BrowserThread::UI, FROM_HERE,
|
||||
x);
|
||||
} else {
|
||||
delete x;
|
||||
}
|
||||
|
@ -124,21 +120,21 @@ v8::Local<v8::Value> CreateFunctionFromTranslater(v8::Isolate* isolate,
|
|||
bool one_time) {
|
||||
// The FunctionTemplate is cached.
|
||||
if (g_call_translater.IsEmpty())
|
||||
g_call_translater.Reset(isolate,
|
||||
mate::CreateFunctionTemplate(
|
||||
isolate, base::BindRepeating(&CallTranslater)));
|
||||
g_call_translater.Reset(
|
||||
isolate,
|
||||
CreateFunctionTemplate(isolate, base::BindRepeating(&CallTranslater)));
|
||||
|
||||
v8::Local<v8::FunctionTemplate> call_translater =
|
||||
v8::Local<v8::FunctionTemplate>::New(isolate, g_call_translater);
|
||||
auto* holder = new TranslaterHolder(isolate);
|
||||
holder->translater = translater;
|
||||
Dictionary state = mate::Dictionary::CreateEmpty(isolate);
|
||||
gin::Dictionary state = gin::Dictionary::CreateEmpty(isolate);
|
||||
if (one_time)
|
||||
state.Set("oneTime", true);
|
||||
auto context = isolate->GetCurrentContext();
|
||||
return BindFunctionWith(
|
||||
isolate, context, call_translater->GetFunction(context).ToLocalChecked(),
|
||||
holder->handle.Get(isolate), state.GetHandle());
|
||||
holder->handle.Get(isolate), gin::ConvertToV8(isolate, state));
|
||||
}
|
||||
|
||||
// func.bind(func, arg1).
|
||||
|
@ -158,6 +154,4 @@ v8::Local<v8::Value> BindFunctionWith(v8::Isolate* isolate,
|
|||
.ToLocalChecked();
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} // namespace mate
|
||||
} // namespace gin_helper
|
|
@ -0,0 +1,163 @@
|
|||
// Copyright (c) 2019 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_COMMON_GIN_HELPER_CALLBACK_H_
|
||||
#define SHELL_COMMON_GIN_HELPER_CALLBACK_H_
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "shell/common/api/locker.h"
|
||||
#include "shell/common/gin_helper/function_template.h"
|
||||
|
||||
// Implements safe convertions between JS functions and base::Callback.
|
||||
|
||||
namespace gin {
|
||||
|
||||
// Make it possible to convert move-only types.
|
||||
template <typename T>
|
||||
v8::Local<v8::Value> ConvertToV8(v8::Isolate* isolate, T&& input) {
|
||||
return Converter<typename std::remove_reference<T>::type>::ToV8(
|
||||
isolate, std::move(input));
|
||||
}
|
||||
|
||||
} // namespace gin
|
||||
|
||||
namespace gin_helper {
|
||||
|
||||
template <typename T>
|
||||
class RefCountedGlobal;
|
||||
|
||||
// Manages the V8 function with RAII.
|
||||
class SafeV8Function {
|
||||
public:
|
||||
SafeV8Function(v8::Isolate* isolate, v8::Local<v8::Value> value);
|
||||
SafeV8Function(const SafeV8Function& other);
|
||||
~SafeV8Function();
|
||||
|
||||
bool IsAlive() const;
|
||||
v8::Local<v8::Function> NewHandle(v8::Isolate* isolate) const;
|
||||
|
||||
private:
|
||||
scoped_refptr<RefCountedGlobal<v8::Function>> v8_function_;
|
||||
};
|
||||
|
||||
// Helper to invoke a V8 function with C++ parameters.
|
||||
template <typename Sig>
|
||||
struct V8FunctionInvoker {};
|
||||
|
||||
template <typename... ArgTypes>
|
||||
struct V8FunctionInvoker<v8::Local<v8::Value>(ArgTypes...)> {
|
||||
static v8::Local<v8::Value> Go(v8::Isolate* isolate,
|
||||
const SafeV8Function& function,
|
||||
ArgTypes... raw) {
|
||||
mate::Locker locker(isolate);
|
||||
v8::EscapableHandleScope handle_scope(isolate);
|
||||
if (!function.IsAlive())
|
||||
return v8::Null(isolate);
|
||||
v8::MicrotasksScope script_scope(isolate,
|
||||
v8::MicrotasksScope::kRunMicrotasks);
|
||||
v8::Local<v8::Function> holder = function.NewHandle(isolate);
|
||||
v8::Local<v8::Context> context = holder->CreationContext();
|
||||
v8::Context::Scope context_scope(context);
|
||||
std::vector<v8::Local<v8::Value>> args{
|
||||
gin::ConvertToV8(isolate, std::forward<ArgTypes>(raw))...};
|
||||
v8::MaybeLocal<v8::Value> ret = holder->Call(
|
||||
context, holder, args.size(), args.empty() ? nullptr : &args.front());
|
||||
if (ret.IsEmpty())
|
||||
return v8::Undefined(isolate);
|
||||
else
|
||||
return handle_scope.Escape(ret.ToLocalChecked());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename... ArgTypes>
|
||||
struct V8FunctionInvoker<void(ArgTypes...)> {
|
||||
static void Go(v8::Isolate* isolate,
|
||||
const SafeV8Function& function,
|
||||
ArgTypes... raw) {
|
||||
mate::Locker locker(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
if (!function.IsAlive())
|
||||
return;
|
||||
v8::MicrotasksScope script_scope(isolate,
|
||||
v8::MicrotasksScope::kRunMicrotasks);
|
||||
v8::Local<v8::Function> holder = function.NewHandle(isolate);
|
||||
v8::Local<v8::Context> context = holder->CreationContext();
|
||||
v8::Context::Scope context_scope(context);
|
||||
std::vector<v8::Local<v8::Value>> args{
|
||||
gin::ConvertToV8(isolate, std::forward<ArgTypes>(raw))...};
|
||||
holder
|
||||
->Call(context, holder, args.size(),
|
||||
args.empty() ? nullptr : &args.front())
|
||||
.IsEmpty();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ReturnType, typename... ArgTypes>
|
||||
struct V8FunctionInvoker<ReturnType(ArgTypes...)> {
|
||||
static ReturnType Go(v8::Isolate* isolate,
|
||||
const SafeV8Function& function,
|
||||
ArgTypes... raw) {
|
||||
mate::Locker locker(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
ReturnType ret = ReturnType();
|
||||
if (!function.IsAlive())
|
||||
return ret;
|
||||
v8::MicrotasksScope script_scope(isolate,
|
||||
v8::MicrotasksScope::kRunMicrotasks);
|
||||
v8::Local<v8::Function> holder = function.NewHandle(isolate);
|
||||
v8::Local<v8::Context> context = holder->CreationContext();
|
||||
v8::Context::Scope context_scope(context);
|
||||
std::vector<v8::Local<v8::Value>> args{
|
||||
gin::ConvertToV8(isolate, std::forward<ArgTypes>(raw))...};
|
||||
v8::Local<v8::Value> result;
|
||||
auto maybe_result = holder->Call(context, holder, args.size(),
|
||||
args.empty() ? nullptr : &args.front());
|
||||
if (maybe_result.ToLocal(&result))
|
||||
gin::Converter<ReturnType>::FromV8(isolate, result, &ret);
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
// Helper to pass a C++ funtion to JavaScript.
|
||||
using Translater = base::Callback<void(gin::Arguments* args)>;
|
||||
v8::Local<v8::Value> CreateFunctionFromTranslater(v8::Isolate* isolate,
|
||||
const Translater& translater,
|
||||
bool one_time);
|
||||
v8::Local<v8::Value> BindFunctionWith(v8::Isolate* isolate,
|
||||
v8::Local<v8::Context> context,
|
||||
v8::Local<v8::Function> func,
|
||||
v8::Local<v8::Value> arg1,
|
||||
v8::Local<v8::Value> arg2);
|
||||
|
||||
// Calls callback with Arguments.
|
||||
template <typename Sig>
|
||||
struct NativeFunctionInvoker {};
|
||||
|
||||
template <typename ReturnType, typename... ArgTypes>
|
||||
struct NativeFunctionInvoker<ReturnType(ArgTypes...)> {
|
||||
static void Go(base::Callback<ReturnType(ArgTypes...)> val,
|
||||
gin::Arguments* args) {
|
||||
using Indices = typename IndicesGenerator<sizeof...(ArgTypes)>::type;
|
||||
Invoker<Indices, ArgTypes...> invoker(args, 0);
|
||||
if (invoker.IsOK())
|
||||
invoker.DispatchToCallback(val);
|
||||
}
|
||||
};
|
||||
|
||||
// Convert a callback to V8 without the call number limitation, this can easily
|
||||
// cause memory leaks so use it with caution.
|
||||
template <typename Sig>
|
||||
v8::Local<v8::Value> CallbackToV8Leaked(
|
||||
v8::Isolate* isolate,
|
||||
const base::RepeatingCallback<Sig>& val) {
|
||||
Translater translater = base::Bind(&NativeFunctionInvoker<Sig>::Go, val);
|
||||
return CreateFunctionFromTranslater(isolate, translater, false);
|
||||
}
|
||||
|
||||
} // namespace gin_helper
|
||||
|
||||
#endif // SHELL_COMMON_GIN_HELPER_CALLBACK_H_
|
|
@ -0,0 +1,84 @@
|
|||
// 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_DICTIONARY_H_
|
||||
#define SHELL_COMMON_GIN_HELPER_DICTIONARY_H_
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "gin/dictionary.h"
|
||||
#include "shell/common/gin_helper/function_template.h"
|
||||
|
||||
namespace gin_helper {
|
||||
|
||||
// Base template - used only for non-member function pointers. Other types
|
||||
// either go to one of the below specializations, or go here and fail to compile
|
||||
// because of base::Bind().
|
||||
template <typename T, typename Enable = void>
|
||||
struct CallbackTraits {
|
||||
static v8::Local<v8::FunctionTemplate> CreateTemplate(v8::Isolate* isolate,
|
||||
T callback) {
|
||||
return CreateFunctionTemplate(isolate, base::BindRepeating(callback));
|
||||
}
|
||||
};
|
||||
|
||||
// Specialization for base::Callback.
|
||||
template <typename T>
|
||||
struct CallbackTraits<base::Callback<T>> {
|
||||
static v8::Local<v8::FunctionTemplate> CreateTemplate(
|
||||
v8::Isolate* isolate,
|
||||
const base::RepeatingCallback<T>& callback) {
|
||||
return CreateFunctionTemplate(isolate, callback);
|
||||
}
|
||||
};
|
||||
|
||||
// Specialization for member function pointers. We need to handle this case
|
||||
// specially because the first parameter for callbacks to MFP should typically
|
||||
// come from the the JavaScript "this" object the function was called on, not
|
||||
// from the first normal parameter.
|
||||
template <typename T>
|
||||
struct CallbackTraits<
|
||||
T,
|
||||
typename std::enable_if<std::is_member_function_pointer<T>::value>::type> {
|
||||
static v8::Local<v8::FunctionTemplate> CreateTemplate(v8::Isolate* isolate,
|
||||
T callback) {
|
||||
int flags = HolderIsFirstArgument;
|
||||
return CreateFunctionTemplate(isolate, base::BindRepeating(callback),
|
||||
flags);
|
||||
}
|
||||
};
|
||||
|
||||
// Adds a few more extends methods to gin::Dictionary.
|
||||
//
|
||||
// Note that as the destructor of gin::Dictionary is not virtual, and we want to
|
||||
// convert between 2 types, we must not add any member.
|
||||
class Dictionary : public gin::Dictionary {
|
||||
public:
|
||||
Dictionary(v8::Isolate* isolate, v8::Local<v8::Object> object)
|
||||
: gin::Dictionary(isolate, object) {}
|
||||
|
||||
template <typename T>
|
||||
bool SetMethod(base::StringPiece key, const T& callback) {
|
||||
auto context = isolate()->GetCurrentContext();
|
||||
auto templ = CallbackTraits<T>::CreateTemplate(isolate(), callback);
|
||||
return GetHandle()
|
||||
->Set(context, gin::StringToV8(isolate(), key),
|
||||
templ->GetFunction(context).ToLocalChecked())
|
||||
.ToChecked();
|
||||
}
|
||||
|
||||
v8::Local<v8::Object> GetHandle() const {
|
||||
return gin::ConvertToV8(isolate(),
|
||||
*static_cast<const gin::Dictionary*>(this))
|
||||
.As<v8::Object>();
|
||||
}
|
||||
|
||||
private:
|
||||
// DO NOT ADD ANY DATA MEMBER.
|
||||
};
|
||||
|
||||
} // namespace gin_helper
|
||||
|
||||
#endif // SHELL_COMMON_GIN_HELPER_DICTIONARY_H_
|
|
@ -0,0 +1,36 @@
|
|||
// 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/function_template.h"
|
||||
|
||||
namespace gin_helper {
|
||||
|
||||
CallbackHolderBase::CallbackHolderBase(v8::Isolate* isolate)
|
||||
: v8_ref_(isolate, v8::External::New(isolate, this)) {
|
||||
v8_ref_.SetWeak(this, &CallbackHolderBase::FirstWeakCallback,
|
||||
v8::WeakCallbackType::kParameter);
|
||||
}
|
||||
|
||||
CallbackHolderBase::~CallbackHolderBase() {
|
||||
DCHECK(v8_ref_.IsEmpty());
|
||||
}
|
||||
|
||||
v8::Local<v8::External> CallbackHolderBase::GetHandle(v8::Isolate* isolate) {
|
||||
return v8::Local<v8::External>::New(isolate, v8_ref_);
|
||||
}
|
||||
|
||||
// static
|
||||
void CallbackHolderBase::FirstWeakCallback(
|
||||
const v8::WeakCallbackInfo<CallbackHolderBase>& data) {
|
||||
data.GetParameter()->v8_ref_.Reset();
|
||||
data.SetSecondPassCallback(SecondWeakCallback);
|
||||
}
|
||||
|
||||
// static
|
||||
void CallbackHolderBase::SecondWeakCallback(
|
||||
const v8::WeakCallbackInfo<CallbackHolderBase>& data) {
|
||||
delete data.GetParameter();
|
||||
}
|
||||
|
||||
} // namespace gin_helper
|
|
@ -0,0 +1,263 @@
|
|||
// 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.
|
||||
|
||||
#ifndef SHELL_COMMON_GIN_HELPER_FUNCTION_TEMPLATE_H_
|
||||
#define SHELL_COMMON_GIN_HELPER_FUNCTION_TEMPLATE_H_
|
||||
|
||||
#include "base/callback.h"
|
||||
#include "gin/arguments.h"
|
||||
#include "shell/common/error_util.h"
|
||||
#include "shell/common/gin_helper/destroyable.h"
|
||||
|
||||
// This file is forked from gin/function_template.h with 2 differences:
|
||||
// 1. Support for additional types of arguments.
|
||||
// 2. Support for warning using destroyed objects.
|
||||
//
|
||||
// TODO(zcbenz): We should seek to remove this file after removing native_mate.
|
||||
|
||||
namespace gin_helper {
|
||||
|
||||
enum CreateFunctionTemplateFlags {
|
||||
HolderIsFirstArgument = 1 << 0,
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct CallbackParamTraits {
|
||||
typedef T LocalType;
|
||||
};
|
||||
template <typename T>
|
||||
struct CallbackParamTraits<const T&> {
|
||||
typedef T LocalType;
|
||||
};
|
||||
template <typename T>
|
||||
struct CallbackParamTraits<const T*> {
|
||||
typedef T* LocalType;
|
||||
};
|
||||
|
||||
// CallbackHolder and CallbackHolderBase are used to pass a base::Callback from
|
||||
// CreateFunctionTemplate through v8 (via v8::FunctionTemplate) to
|
||||
// DispatchToCallback, where it is invoked.
|
||||
|
||||
// This simple base class is used so that we can share a single object template
|
||||
// among every CallbackHolder instance.
|
||||
class CallbackHolderBase {
|
||||
public:
|
||||
v8::Local<v8::External> GetHandle(v8::Isolate* isolate);
|
||||
|
||||
protected:
|
||||
explicit CallbackHolderBase(v8::Isolate* isolate);
|
||||
virtual ~CallbackHolderBase();
|
||||
|
||||
private:
|
||||
static void FirstWeakCallback(
|
||||
const v8::WeakCallbackInfo<CallbackHolderBase>& data);
|
||||
static void SecondWeakCallback(
|
||||
const v8::WeakCallbackInfo<CallbackHolderBase>& data);
|
||||
|
||||
v8::Global<v8::External> v8_ref_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CallbackHolderBase);
|
||||
};
|
||||
|
||||
template <typename Sig>
|
||||
class CallbackHolder : public CallbackHolderBase {
|
||||
public:
|
||||
CallbackHolder(v8::Isolate* isolate,
|
||||
const base::Callback<Sig>& callback,
|
||||
int flags)
|
||||
: CallbackHolderBase(isolate), callback(callback), flags(flags) {}
|
||||
base::Callback<Sig> callback;
|
||||
int flags = 0;
|
||||
|
||||
private:
|
||||
virtual ~CallbackHolder() = default;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CallbackHolder);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
bool GetNextArgument(gin::Arguments* args,
|
||||
int create_flags,
|
||||
bool is_first,
|
||||
T* result) {
|
||||
if (is_first && (create_flags & HolderIsFirstArgument) != 0) {
|
||||
return args->GetHolder(result);
|
||||
} else {
|
||||
return args->GetNext(result);
|
||||
}
|
||||
}
|
||||
|
||||
// For advanced use cases, we allow callers to request the unparsed Arguments
|
||||
// object and poke around in it directly.
|
||||
inline bool GetNextArgument(gin::Arguments* args,
|
||||
int create_flags,
|
||||
bool is_first,
|
||||
gin::Arguments** result) {
|
||||
*result = args;
|
||||
return true;
|
||||
}
|
||||
|
||||
// It's common for clients to just need the isolate, so we make that easy.
|
||||
inline bool GetNextArgument(gin::Arguments* args,
|
||||
int create_flags,
|
||||
bool is_first,
|
||||
v8::Isolate** result) {
|
||||
*result = args->isolate();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Allow clients to pass a util::Error to throw errors if they
|
||||
// don't need the full gin::Arguments
|
||||
inline bool GetNextArgument(gin::Arguments* args,
|
||||
int create_flags,
|
||||
bool is_first,
|
||||
electron::util::ErrorThrower* result) {
|
||||
*result = electron::util::ErrorThrower(args->isolate());
|
||||
return true;
|
||||
}
|
||||
|
||||
// Classes for generating and storing an argument pack of integer indices
|
||||
// (based on well-known "indices trick", see: http://goo.gl/bKKojn):
|
||||
template <size_t... indices>
|
||||
struct IndicesHolder {};
|
||||
|
||||
template <size_t requested_index, size_t... indices>
|
||||
struct IndicesGenerator {
|
||||
using type = typename IndicesGenerator<requested_index - 1,
|
||||
requested_index - 1,
|
||||
indices...>::type;
|
||||
};
|
||||
template <size_t... indices>
|
||||
struct IndicesGenerator<0, indices...> {
|
||||
using type = IndicesHolder<indices...>;
|
||||
};
|
||||
|
||||
// Class template for extracting and storing single argument for callback
|
||||
// at position |index|.
|
||||
template <size_t index, typename ArgType>
|
||||
struct ArgumentHolder {
|
||||
using ArgLocalType = typename CallbackParamTraits<ArgType>::LocalType;
|
||||
|
||||
ArgLocalType value;
|
||||
bool ok = false;
|
||||
|
||||
ArgumentHolder(gin::Arguments* args, int create_flags) {
|
||||
v8::Local<v8::Object> holder;
|
||||
if (index == 0 && (create_flags & HolderIsFirstArgument) &&
|
||||
args->GetHolder(&holder) &&
|
||||
gin_helper::Destroyable::IsDestroyed(holder)) {
|
||||
args->ThrowTypeError("Object has been destroyed");
|
||||
return;
|
||||
}
|
||||
ok = GetNextArgument(args, create_flags, index == 0, &value);
|
||||
if (!ok) {
|
||||
// Ideally we would include the expected c++ type in the error
|
||||
// message which we can access via typeid(ArgType).name()
|
||||
// however we compile with no-rtti, which disables typeid.
|
||||
args->ThrowError();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Class template for converting arguments from JavaScript to C++ and running
|
||||
// the callback with them.
|
||||
template <typename IndicesType, typename... ArgTypes>
|
||||
class Invoker {};
|
||||
|
||||
template <size_t... indices, typename... ArgTypes>
|
||||
class Invoker<IndicesHolder<indices...>, ArgTypes...>
|
||||
: public ArgumentHolder<indices, ArgTypes>... {
|
||||
public:
|
||||
// Invoker<> inherits from ArgumentHolder<> for each argument.
|
||||
// C++ has always been strict about the class initialization order,
|
||||
// so it is guaranteed ArgumentHolders will be initialized (and thus, will
|
||||
// extract arguments from Arguments) in the right order.
|
||||
Invoker(gin::Arguments* args, int create_flags)
|
||||
: ArgumentHolder<indices, ArgTypes>(args, create_flags)..., args_(args) {
|
||||
// GCC thinks that create_flags is going unused, even though the
|
||||
// expansion above clearly makes use of it. Per jyasskin@, casting
|
||||
// to void is the commonly accepted way to convince the compiler
|
||||
// that you're actually using a parameter/varible.
|
||||
(void)create_flags;
|
||||
}
|
||||
|
||||
bool IsOK() { return And(ArgumentHolder<indices, ArgTypes>::ok...); }
|
||||
|
||||
template <typename ReturnType>
|
||||
void DispatchToCallback(base::Callback<ReturnType(ArgTypes...)> callback) {
|
||||
v8::MicrotasksScope script_scope(args_->isolate(),
|
||||
v8::MicrotasksScope::kRunMicrotasks);
|
||||
args_->Return(callback.Run(ArgumentHolder<indices, ArgTypes>::value...));
|
||||
}
|
||||
|
||||
// In C++, you can declare the function foo(void), but you can't pass a void
|
||||
// expression to foo. As a result, we must specialize the case of Callbacks
|
||||
// that have the void return type.
|
||||
void DispatchToCallback(base::Callback<void(ArgTypes...)> callback) {
|
||||
v8::MicrotasksScope script_scope(args_->isolate(),
|
||||
v8::MicrotasksScope::kRunMicrotasks);
|
||||
callback.Run(ArgumentHolder<indices, ArgTypes>::value...);
|
||||
}
|
||||
|
||||
private:
|
||||
static bool And() { return true; }
|
||||
template <typename... T>
|
||||
static bool And(bool arg1, T... args) {
|
||||
return arg1 && And(args...);
|
||||
}
|
||||
|
||||
gin::Arguments* args_;
|
||||
};
|
||||
|
||||
// DispatchToCallback converts all the JavaScript arguments to C++ types and
|
||||
// invokes the base::Callback.
|
||||
template <typename Sig>
|
||||
struct Dispatcher {};
|
||||
|
||||
template <typename ReturnType, typename... ArgTypes>
|
||||
struct Dispatcher<ReturnType(ArgTypes...)> {
|
||||
static void DispatchToCallback(
|
||||
const v8::FunctionCallbackInfo<v8::Value>& info) {
|
||||
gin::Arguments args(info);
|
||||
v8::Local<v8::External> v8_holder;
|
||||
args.GetData(&v8_holder);
|
||||
CallbackHolderBase* holder_base =
|
||||
reinterpret_cast<CallbackHolderBase*>(v8_holder->Value());
|
||||
|
||||
typedef CallbackHolder<ReturnType(ArgTypes...)> HolderT;
|
||||
HolderT* holder = static_cast<HolderT*>(holder_base);
|
||||
|
||||
using Indices = typename IndicesGenerator<sizeof...(ArgTypes)>::type;
|
||||
Invoker<Indices, ArgTypes...> invoker(&args, holder->flags);
|
||||
if (invoker.IsOK())
|
||||
invoker.DispatchToCallback(holder->callback);
|
||||
}
|
||||
};
|
||||
|
||||
// CreateFunctionTemplate creates a v8::FunctionTemplate that will create
|
||||
// JavaScript functions that execute a provided C++ function or base::Callback.
|
||||
// JavaScript arguments are automatically converted via gin::Converter, as is
|
||||
// the return value of the C++ function, if any.
|
||||
//
|
||||
// NOTE: V8 caches FunctionTemplates for a lifetime of a web page for its own
|
||||
// internal reasons, thus it is generally a good idea to cache the template
|
||||
// returned by this function. Otherwise, repeated method invocations from JS
|
||||
// will create substantial memory leaks. See http://crbug.com/463487.
|
||||
template <typename Sig>
|
||||
v8::Local<v8::FunctionTemplate> CreateFunctionTemplate(
|
||||
v8::Isolate* isolate,
|
||||
const base::Callback<Sig> callback,
|
||||
int callback_flags = 0) {
|
||||
typedef CallbackHolder<Sig> HolderT;
|
||||
HolderT* holder = new HolderT(isolate, callback, callback_flags);
|
||||
|
||||
return v8::FunctionTemplate::New(isolate,
|
||||
&Dispatcher<Sig>::DispatchToCallback,
|
||||
gin::ConvertToV8<v8::Local<v8::External>>(
|
||||
isolate, holder->GetHandle(isolate)));
|
||||
}
|
||||
|
||||
} // namespace gin_helper
|
||||
|
||||
#endif // SHELL_COMMON_GIN_HELPER_FUNCTION_TEMPLATE_H_
|
|
@ -1,29 +0,0 @@
|
|||
// Copyright (c) 2018 Slack Technologies, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_COMMON_GIN_UTIL_H_
|
||||
#define SHELL_COMMON_GIN_UTIL_H_
|
||||
|
||||
#include "gin/converter.h"
|
||||
#include "gin/function_template.h"
|
||||
|
||||
namespace gin_util {
|
||||
|
||||
template <typename T>
|
||||
bool SetMethod(v8::Local<v8::Object> recv,
|
||||
base::StringPiece key,
|
||||
const T& callback) {
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
auto context = isolate->GetCurrentContext();
|
||||
return recv
|
||||
->Set(context, gin::StringToV8(isolate, key),
|
||||
gin::CreateFunctionTemplate(isolate, callback)
|
||||
->GetFunction(context)
|
||||
.ToLocalChecked())
|
||||
.ToChecked();
|
||||
}
|
||||
|
||||
} // namespace gin_util
|
||||
|
||||
#endif // SHELL_COMMON_GIN_UTIL_H_
|
|
@ -0,0 +1,163 @@
|
|||
// Copyright (c) 2015 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/common/native_mate_converters/callback_converter_deprecated.h"
|
||||
#include "base/stl_util.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace mate {
|
||||
|
||||
namespace internal {
|
||||
|
||||
namespace {
|
||||
|
||||
struct TranslaterHolder {
|
||||
explicit TranslaterHolder(v8::Isolate* isolate)
|
||||
: handle(isolate, v8::External::New(isolate, this)) {
|
||||
handle.SetWeak(this, &GC, v8::WeakCallbackType::kFinalizer);
|
||||
}
|
||||
~TranslaterHolder() {
|
||||
if (!handle.IsEmpty()) {
|
||||
handle.ClearWeak();
|
||||
handle.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
static void GC(const v8::WeakCallbackInfo<TranslaterHolder>& data) {
|
||||
delete data.GetParameter();
|
||||
}
|
||||
|
||||
v8::Global<v8::External> handle;
|
||||
Translater translater;
|
||||
};
|
||||
|
||||
// Cached JavaScript version of |CallTranslater|.
|
||||
v8::Persistent<v8::FunctionTemplate> g_call_translater;
|
||||
|
||||
void CallTranslater(v8::Local<v8::External> external,
|
||||
v8::Local<v8::Object> state,
|
||||
mate::Arguments* args) {
|
||||
// Whether the callback should only be called for once.
|
||||
v8::Isolate* isolate = args->isolate();
|
||||
auto context = isolate->GetCurrentContext();
|
||||
bool one_time =
|
||||
state->Has(context, mate::StringToSymbol(isolate, "oneTime")).ToChecked();
|
||||
|
||||
// Check if the callback has already been called.
|
||||
if (one_time) {
|
||||
auto called_symbol = mate::StringToSymbol(isolate, "called");
|
||||
if (state->Has(context, called_symbol).ToChecked()) {
|
||||
args->ThrowError("callback can only be called for once");
|
||||
return;
|
||||
} else {
|
||||
state->Set(context, called_symbol, v8::Boolean::New(isolate, true))
|
||||
.ToChecked();
|
||||
}
|
||||
}
|
||||
|
||||
TranslaterHolder* holder = static_cast<TranslaterHolder*>(external->Value());
|
||||
holder->translater.Run(args);
|
||||
|
||||
// Free immediately for one-time callback.
|
||||
if (one_time)
|
||||
delete holder;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// Destroy the class on UI thread when possible.
|
||||
struct DeleteOnUIThread {
|
||||
template <typename T>
|
||||
static void Destruct(const T* x) {
|
||||
if (Locker::IsBrowserProcess() &&
|
||||
!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
|
||||
BrowserThread::DeleteSoon(BrowserThread::UI, FROM_HERE, x);
|
||||
} else {
|
||||
delete x;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Like v8::Global, but ref-counted.
|
||||
template <typename T>
|
||||
class RefCountedGlobal
|
||||
: public base::RefCountedThreadSafe<RefCountedGlobal<T>, DeleteOnUIThread> {
|
||||
public:
|
||||
RefCountedGlobal(v8::Isolate* isolate, v8::Local<v8::Value> value)
|
||||
: handle_(isolate, v8::Local<T>::Cast(value)) {}
|
||||
|
||||
bool IsAlive() const { return !handle_.IsEmpty(); }
|
||||
|
||||
v8::Local<T> NewHandle(v8::Isolate* isolate) const {
|
||||
return v8::Local<T>::New(isolate, handle_);
|
||||
}
|
||||
|
||||
private:
|
||||
v8::Global<T> handle_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(RefCountedGlobal);
|
||||
};
|
||||
|
||||
SafeV8Function::SafeV8Function(v8::Isolate* isolate, v8::Local<v8::Value> value)
|
||||
: v8_function_(new RefCountedGlobal<v8::Function>(isolate, value)) {}
|
||||
|
||||
SafeV8Function::SafeV8Function(const SafeV8Function& other)
|
||||
: v8_function_(other.v8_function_) {}
|
||||
|
||||
SafeV8Function::~SafeV8Function() {}
|
||||
|
||||
bool SafeV8Function::IsAlive() const {
|
||||
return v8_function_.get() && v8_function_->IsAlive();
|
||||
}
|
||||
|
||||
v8::Local<v8::Function> SafeV8Function::NewHandle(v8::Isolate* isolate) const {
|
||||
return v8_function_->NewHandle(isolate);
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> CreateFunctionFromTranslater(v8::Isolate* isolate,
|
||||
const Translater& translater,
|
||||
bool one_time) {
|
||||
// The FunctionTemplate is cached.
|
||||
if (g_call_translater.IsEmpty())
|
||||
g_call_translater.Reset(isolate,
|
||||
mate::CreateFunctionTemplate(
|
||||
isolate, base::BindRepeating(&CallTranslater)));
|
||||
|
||||
v8::Local<v8::FunctionTemplate> call_translater =
|
||||
v8::Local<v8::FunctionTemplate>::New(isolate, g_call_translater);
|
||||
auto* holder = new TranslaterHolder(isolate);
|
||||
holder->translater = translater;
|
||||
Dictionary state = mate::Dictionary::CreateEmpty(isolate);
|
||||
if (one_time)
|
||||
state.Set("oneTime", true);
|
||||
auto context = isolate->GetCurrentContext();
|
||||
return BindFunctionWith(
|
||||
isolate, context, call_translater->GetFunction(context).ToLocalChecked(),
|
||||
holder->handle.Get(isolate), state.GetHandle());
|
||||
}
|
||||
|
||||
// func.bind(func, arg1).
|
||||
// NB(zcbenz): Using C++11 version crashes VS.
|
||||
v8::Local<v8::Value> BindFunctionWith(v8::Isolate* isolate,
|
||||
v8::Local<v8::Context> context,
|
||||
v8::Local<v8::Function> func,
|
||||
v8::Local<v8::Value> arg1,
|
||||
v8::Local<v8::Value> arg2) {
|
||||
v8::MaybeLocal<v8::Value> bind =
|
||||
func->Get(context, mate::StringToV8(isolate, "bind"));
|
||||
CHECK(!bind.IsEmpty());
|
||||
v8::Local<v8::Function> bind_func =
|
||||
v8::Local<v8::Function>::Cast(bind.ToLocalChecked());
|
||||
v8::Local<v8::Value> converted[] = {func, arg1, arg2};
|
||||
return bind_func->Call(context, func, base::size(converted), converted)
|
||||
.ToLocalChecked();
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} // namespace mate
|
|
@ -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_COMMON_NATIVE_MATE_CONVERTERS_CALLBACK_H_
|
||||
#define SHELL_COMMON_NATIVE_MATE_CONVERTERS_CALLBACK_H_
|
||||
#ifndef SHELL_COMMON_NATIVE_MATE_CONVERTERS_CALLBACK_CONVERTER_DEPRECATED_H_
|
||||
#define SHELL_COMMON_NATIVE_MATE_CONVERTERS_CALLBACK_CONVERTER_DEPRECATED_H_
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
@ -16,6 +16,10 @@
|
|||
#include "native_mate/scoped_persistent.h"
|
||||
#include "shell/common/api/locker.h"
|
||||
|
||||
// =============================== NOTICE ===============================
|
||||
// Do not add code here, native_mate is being removed. Any new code
|
||||
// should use gin instead.
|
||||
|
||||
namespace mate {
|
||||
|
||||
namespace internal {
|
||||
|
@ -178,4 +182,4 @@ v8::Local<v8::Value> CallbackToV8(v8::Isolate* isolate,
|
|||
|
||||
} // namespace mate
|
||||
|
||||
#endif // SHELL_COMMON_NATIVE_MATE_CONVERTERS_CALLBACK_H_
|
||||
#endif // SHELL_COMMON_NATIVE_MATE_CONVERTERS_CALLBACK_CONVERTER_DEPRECATED_H_
|
|
@ -13,7 +13,7 @@
|
|||
#include "shell/browser/api/atom_api_web_contents.h"
|
||||
#include "shell/browser/web_contents_permission_helper.h"
|
||||
#include "shell/common/native_mate_converters/blink_converter.h"
|
||||
#include "shell/common/native_mate_converters/callback.h"
|
||||
#include "shell/common/native_mate_converters/callback_converter_deprecated.h"
|
||||
#include "shell/common/native_mate_converters/gurl_converter.h"
|
||||
#include "shell/common/native_mate_converters/string16_converter.h"
|
||||
#include "shell/common/native_mate_converters/ui_base_types_converter.h"
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
#include <utility>
|
||||
|
||||
#include "shell/common/native_mate_converters/callback.h"
|
||||
#include "shell/common/native_mate_converters/callback_converter_deprecated.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#include "content/public/browser/browser_thread.h"
|
||||
#include "native_mate/converter.h"
|
||||
#include "shell/common/api/locker.h"
|
||||
#include "shell/common/native_mate_converters/callback.h"
|
||||
#include "shell/common/native_mate_converters/callback_converter_deprecated.h"
|
||||
#include "shell/common/native_mate_converters/once_callback.h"
|
||||
|
||||
namespace electron {
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include "shell/common/api/api.mojom.h"
|
||||
#include "shell/common/api/event_emitter_caller.h"
|
||||
#include "shell/common/native_mate_converters/blink_converter.h"
|
||||
#include "shell/common/native_mate_converters/callback.h"
|
||||
#include "shell/common/native_mate_converters/callback_converter_deprecated.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"
|
||||
|
|
Загрузка…
Ссылка в новой задаче