refactor: simplify events (#37099)
This commit is contained in:
parent
8b3e498436
commit
71944f2c3b
32 changed files with 290 additions and 409 deletions
|
@ -1,28 +0,0 @@
|
|||
// Copyright (c) 2018 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/api/event.h"
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/gin_helper/event_emitter.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
|
||||
namespace {
|
||||
|
||||
v8::Local<v8::Object> CreateWithSender(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> sender) {
|
||||
return gin_helper::internal::CreateCustomEvent(isolate, sender);
|
||||
}
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context,
|
||||
void* priv) {
|
||||
gin_helper::Dictionary dict(context->GetIsolate(), exports);
|
||||
dict.SetMethod("createWithSender", &CreateWithSender);
|
||||
dict.SetMethod("createEmpty", &gin_helper::Event::Create);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_LINKED_BINDING_CONTEXT_AWARE(electron_browser_event, Initialize)
|
|
@ -1178,8 +1178,7 @@ gin::Handle<Session> Session::CreateFrom(
|
|||
// to use partition strings, instead of using the Session object directly.
|
||||
handle->Pin(isolate);
|
||||
|
||||
App::Get()->EmitCustomEvent("session-created",
|
||||
handle.ToV8().As<v8::Object>());
|
||||
App::Get()->EmitWithoutEvent("session-created", handle);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
|
|
@ -97,19 +97,19 @@ void Tray::OnClicked(const gfx::Rect& bounds,
|
|||
int modifiers) {
|
||||
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
|
||||
v8::HandleScope scope(isolate);
|
||||
EmitCustomEvent("click", CreateEventFromFlags(modifiers), bounds, location);
|
||||
EmitWithoutEvent("click", CreateEventFromFlags(modifiers), bounds, location);
|
||||
}
|
||||
|
||||
void Tray::OnDoubleClicked(const gfx::Rect& bounds, int modifiers) {
|
||||
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
|
||||
v8::HandleScope scope(isolate);
|
||||
EmitCustomEvent("double-click", CreateEventFromFlags(modifiers), bounds);
|
||||
EmitWithoutEvent("double-click", CreateEventFromFlags(modifiers), bounds);
|
||||
}
|
||||
|
||||
void Tray::OnRightClicked(const gfx::Rect& bounds, int modifiers) {
|
||||
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
|
||||
v8::HandleScope scope(isolate);
|
||||
EmitCustomEvent("right-click", CreateEventFromFlags(modifiers), bounds);
|
||||
EmitWithoutEvent("right-click", CreateEventFromFlags(modifiers), bounds);
|
||||
}
|
||||
|
||||
void Tray::OnBalloonShow() {
|
||||
|
@ -139,31 +139,31 @@ void Tray::OnDropText(const std::string& text) {
|
|||
void Tray::OnMouseEntered(const gfx::Point& location, int modifiers) {
|
||||
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
|
||||
v8::HandleScope scope(isolate);
|
||||
EmitCustomEvent("mouse-enter", CreateEventFromFlags(modifiers), location);
|
||||
EmitWithoutEvent("mouse-enter", CreateEventFromFlags(modifiers), location);
|
||||
}
|
||||
|
||||
void Tray::OnMouseExited(const gfx::Point& location, int modifiers) {
|
||||
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
|
||||
v8::HandleScope scope(isolate);
|
||||
EmitCustomEvent("mouse-leave", CreateEventFromFlags(modifiers), location);
|
||||
EmitWithoutEvent("mouse-leave", CreateEventFromFlags(modifiers), location);
|
||||
}
|
||||
|
||||
void Tray::OnMouseMoved(const gfx::Point& location, int modifiers) {
|
||||
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
|
||||
v8::HandleScope scope(isolate);
|
||||
EmitCustomEvent("mouse-move", CreateEventFromFlags(modifiers), location);
|
||||
EmitWithoutEvent("mouse-move", CreateEventFromFlags(modifiers), location);
|
||||
}
|
||||
|
||||
void Tray::OnMouseUp(const gfx::Point& location, int modifiers) {
|
||||
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
|
||||
v8::HandleScope scope(isolate);
|
||||
EmitCustomEvent("mouse-up", CreateEventFromFlags(modifiers), location);
|
||||
EmitWithoutEvent("mouse-up", CreateEventFromFlags(modifiers), location);
|
||||
}
|
||||
|
||||
void Tray::OnMouseDown(const gfx::Point& location, int modifiers) {
|
||||
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
|
||||
v8::HandleScope scope(isolate);
|
||||
EmitCustomEvent("mouse-down", CreateEventFromFlags(modifiers), location);
|
||||
EmitWithoutEvent("mouse-down", CreateEventFromFlags(modifiers), location);
|
||||
}
|
||||
|
||||
void Tray::OnDragEntered() {
|
||||
|
|
|
@ -203,13 +203,13 @@ void UtilityProcessWrapper::OnServiceProcessLaunched(
|
|||
pid_ = process.Pid();
|
||||
GetAllUtilityProcessWrappers().AddWithID(this, pid_);
|
||||
if (stdout_read_fd_ != -1) {
|
||||
EmitWithoutCustomEvent("stdout", stdout_read_fd_);
|
||||
EmitWithoutEvent("stdout", stdout_read_fd_);
|
||||
}
|
||||
if (stderr_read_fd_ != -1) {
|
||||
EmitWithoutCustomEvent("stderr", stderr_read_fd_);
|
||||
EmitWithoutEvent("stderr", stderr_read_fd_);
|
||||
}
|
||||
// Emit 'spawn' event
|
||||
EmitWithoutCustomEvent("spawn");
|
||||
EmitWithoutEvent("spawn");
|
||||
}
|
||||
|
||||
void UtilityProcessWrapper::OnServiceProcessDisconnected(
|
||||
|
@ -219,7 +219,7 @@ void UtilityProcessWrapper::OnServiceProcessDisconnected(
|
|||
GetAllUtilityProcessWrappers().Remove(pid_);
|
||||
CloseConnectorPort();
|
||||
// Emit 'exit' event
|
||||
EmitWithoutCustomEvent("exit", error_code);
|
||||
EmitWithoutEvent("exit", error_code);
|
||||
Unpin();
|
||||
}
|
||||
|
||||
|
@ -238,7 +238,7 @@ void UtilityProcessWrapper::Shutdown(int exit_code) {
|
|||
node_service_remote_.reset();
|
||||
CloseConnectorPort();
|
||||
// Emit 'exit' event
|
||||
EmitWithoutCustomEvent("exit", exit_code);
|
||||
EmitWithoutEvent("exit", exit_code);
|
||||
Unpin();
|
||||
}
|
||||
|
||||
|
@ -311,7 +311,7 @@ bool UtilityProcessWrapper::Accept(mojo::Message* mojo_message) {
|
|||
v8::HandleScope handle_scope(isolate);
|
||||
v8::Local<v8::Value> message_value =
|
||||
electron::DeserializeV8Value(isolate, message);
|
||||
EmitWithoutCustomEvent("message", message_value);
|
||||
EmitWithoutEvent("message", message_value);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1812,6 +1812,81 @@ void WebContents::OnFirstNonEmptyLayout(
|
|||
}
|
||||
}
|
||||
|
||||
// This object wraps the InvokeCallback so that if it gets GC'd by V8, we can
|
||||
// still call the callback and send an error. Not doing so causes a Mojo DCHECK,
|
||||
// since Mojo requires callbacks to be called before they are destroyed.
|
||||
class ReplyChannel : public gin::Wrappable<ReplyChannel> {
|
||||
public:
|
||||
using InvokeCallback = electron::mojom::ElectronApiIPC::InvokeCallback;
|
||||
static gin::Handle<ReplyChannel> Create(v8::Isolate* isolate,
|
||||
InvokeCallback callback) {
|
||||
return gin::CreateHandle(isolate, new ReplyChannel(std::move(callback)));
|
||||
}
|
||||
|
||||
// gin::Wrappable
|
||||
static gin::WrapperInfo kWrapperInfo;
|
||||
gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) override {
|
||||
return gin::Wrappable<ReplyChannel>::GetObjectTemplateBuilder(isolate)
|
||||
.SetMethod("sendReply", &ReplyChannel::SendReply);
|
||||
}
|
||||
const char* GetTypeName() override { return "ReplyChannel"; }
|
||||
|
||||
private:
|
||||
explicit ReplyChannel(InvokeCallback callback)
|
||||
: callback_(std::move(callback)) {}
|
||||
~ReplyChannel() override {
|
||||
if (callback_) {
|
||||
v8::Isolate* isolate = electron::JavascriptEnvironment::GetIsolate();
|
||||
// If there's no current context, it means we're shutting down, so we
|
||||
// don't need to send an event.
|
||||
if (!isolate->GetCurrentContext().IsEmpty()) {
|
||||
v8::HandleScope scope(isolate);
|
||||
auto message = gin::DataObjectBuilder(isolate)
|
||||
.Set("error", "reply was never sent")
|
||||
.Build();
|
||||
SendReply(isolate, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool SendReply(v8::Isolate* isolate, v8::Local<v8::Value> arg) {
|
||||
if (!callback_)
|
||||
return false;
|
||||
blink::CloneableMessage message;
|
||||
if (!gin::ConvertFromV8(isolate, arg, &message)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::move(callback_).Run(std::move(message));
|
||||
return true;
|
||||
}
|
||||
|
||||
InvokeCallback callback_;
|
||||
};
|
||||
|
||||
gin::WrapperInfo ReplyChannel::kWrapperInfo = {gin::kEmbedderNativeGin};
|
||||
|
||||
gin::Handle<gin_helper::internal::Event> WebContents::MakeEventWithSender(
|
||||
v8::Isolate* isolate,
|
||||
content::RenderFrameHost* frame,
|
||||
electron::mojom::ElectronApiIPC::InvokeCallback callback) {
|
||||
v8::Local<v8::Object> wrapper;
|
||||
if (!GetWrapper(isolate).ToLocal(&wrapper))
|
||||
return gin::Handle<gin_helper::internal::Event>();
|
||||
gin::Handle<gin_helper::internal::Event> event =
|
||||
gin_helper::internal::Event::New(isolate);
|
||||
gin_helper::Dictionary dict(isolate, event.ToV8().As<v8::Object>());
|
||||
if (callback)
|
||||
dict.Set("_replyChannel",
|
||||
ReplyChannel::Create(isolate, std::move(callback)));
|
||||
if (frame) {
|
||||
dict.Set("frameId", frame->GetRoutingID());
|
||||
dict.Set("processId", frame->GetProcess()->GetID());
|
||||
}
|
||||
return event;
|
||||
}
|
||||
|
||||
void WebContents::ReceivePostMessage(
|
||||
const std::string& channel,
|
||||
blink::TransferableMessage message,
|
||||
|
|
|
@ -352,20 +352,26 @@ class WebContents : public ExclusiveAccessContext,
|
|||
// this.emit(name, new Event(sender, message), args...);
|
||||
template <typename... Args>
|
||||
bool EmitWithSender(base::StringPiece name,
|
||||
content::RenderFrameHost* sender,
|
||||
content::RenderFrameHost* frame,
|
||||
electron::mojom::ElectronApiIPC::InvokeCallback callback,
|
||||
Args&&... args) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
v8::Local<v8::Object> wrapper;
|
||||
if (!GetWrapper(isolate).ToLocal(&wrapper))
|
||||
|
||||
gin::Handle<gin_helper::internal::Event> event =
|
||||
MakeEventWithSender(isolate, frame, std::move(callback));
|
||||
if (event.IsEmpty())
|
||||
return false;
|
||||
v8::Local<v8::Object> event = gin_helper::internal::CreateNativeEvent(
|
||||
isolate, wrapper, sender, std::move(callback));
|
||||
return EmitCustomEvent(name, event, std::forward<Args>(args)...);
|
||||
EmitWithoutEvent(name, event, std::forward<Args>(args)...);
|
||||
return event->GetDefaultPrevented();
|
||||
}
|
||||
|
||||
gin::Handle<gin_helper::internal::Event> MakeEventWithSender(
|
||||
v8::Isolate* isolate,
|
||||
content::RenderFrameHost* frame,
|
||||
electron::mojom::ElectronApiIPC::InvokeCallback callback);
|
||||
|
||||
WebContents* embedder() { return embedder_; }
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
|
|
|
@ -1,77 +0,0 @@
|
|||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/api/event.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "gin/data_object_builder.h"
|
||||
#include "gin/object_template_builder.h"
|
||||
#include "shell/browser/javascript_environment.h"
|
||||
#include "shell/common/gin_converters/blink_converter.h"
|
||||
#include "shell/common/gin_converters/std_converter.h"
|
||||
|
||||
namespace gin_helper {
|
||||
|
||||
gin::WrapperInfo Event::kWrapperInfo = {gin::kEmbedderNativeGin};
|
||||
|
||||
Event::Event() = default;
|
||||
|
||||
Event::~Event() {
|
||||
if (callback_) {
|
||||
v8::Isolate* isolate = electron::JavascriptEnvironment::GetIsolate();
|
||||
// If there's no current context, it means we're shutting down, so we don't
|
||||
// need to send an event.
|
||||
if (!isolate->GetCurrentContext().IsEmpty()) {
|
||||
v8::HandleScope scope(isolate);
|
||||
auto message = gin::DataObjectBuilder(isolate)
|
||||
.Set("error", "reply was never sent")
|
||||
.Build();
|
||||
SendReply(isolate, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Event::SetCallback(InvokeCallback callback) {
|
||||
DCHECK(!callback_);
|
||||
callback_ = std::move(callback);
|
||||
}
|
||||
|
||||
void Event::PreventDefault(v8::Isolate* isolate) {
|
||||
v8::Local<v8::Object> self = GetWrapper(isolate).ToLocalChecked();
|
||||
self->Set(isolate->GetCurrentContext(),
|
||||
gin::StringToV8(isolate, "defaultPrevented"), v8::True(isolate))
|
||||
.Check();
|
||||
}
|
||||
|
||||
bool Event::SendReply(v8::Isolate* isolate, v8::Local<v8::Value> result) {
|
||||
if (!callback_)
|
||||
return false;
|
||||
|
||||
blink::CloneableMessage message;
|
||||
if (!gin::ConvertFromV8(isolate, result, &message)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::move(callback_).Run(std::move(message));
|
||||
return true;
|
||||
}
|
||||
|
||||
gin::ObjectTemplateBuilder Event::GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) {
|
||||
return gin::Wrappable<Event>::GetObjectTemplateBuilder(isolate)
|
||||
.SetMethod("preventDefault", &Event::PreventDefault)
|
||||
.SetMethod("sendReply", &Event::SendReply);
|
||||
}
|
||||
|
||||
const char* Event::GetTypeName() {
|
||||
return "Event";
|
||||
}
|
||||
|
||||
// static
|
||||
gin::Handle<Event> Event::Create(v8::Isolate* isolate) {
|
||||
return gin::CreateHandle(isolate, new Event());
|
||||
}
|
||||
|
||||
} // namespace gin_helper
|
|
@ -1,52 +0,0 @@
|
|||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ELECTRON_SHELL_BROWSER_API_EVENT_H_
|
||||
#define ELECTRON_SHELL_BROWSER_API_EVENT_H_
|
||||
|
||||
#include "electron/shell/common/api/api.mojom.h"
|
||||
#include "gin/handle.h"
|
||||
#include "gin/wrappable.h"
|
||||
|
||||
namespace gin_helper {
|
||||
|
||||
class Event : public gin::Wrappable<Event> {
|
||||
public:
|
||||
using InvokeCallback = electron::mojom::ElectronApiIPC::InvokeCallback;
|
||||
|
||||
static gin::WrapperInfo kWrapperInfo;
|
||||
|
||||
static gin::Handle<Event> Create(v8::Isolate* isolate);
|
||||
|
||||
// Pass the callback to be invoked.
|
||||
void SetCallback(InvokeCallback callback);
|
||||
|
||||
// event.PreventDefault().
|
||||
void PreventDefault(v8::Isolate* isolate);
|
||||
|
||||
// event.sendReply(value), used for replying to synchronous messages and
|
||||
// `invoke` calls.
|
||||
bool SendReply(v8::Isolate* isolate, v8::Local<v8::Value> result);
|
||||
|
||||
// disable copy
|
||||
Event(const Event&) = delete;
|
||||
Event& operator=(const Event&) = delete;
|
||||
|
||||
protected:
|
||||
Event();
|
||||
~Event() override;
|
||||
|
||||
// gin::Wrappable:
|
||||
gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) override;
|
||||
const char* GetTypeName() override;
|
||||
|
||||
private:
|
||||
// Replier for the synchronous messages.
|
||||
InvokeCallback callback_;
|
||||
};
|
||||
|
||||
} // namespace gin_helper
|
||||
|
||||
#endif // ELECTRON_SHELL_BROWSER_API_EVENT_H_
|
|
@ -1,41 +0,0 @@
|
|||
// Copyright (c) 2019 Slack Technologies, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/event_emitter_mixin.h"
|
||||
|
||||
#include "gin/public/wrapper_info.h"
|
||||
#include "shell/browser/api/electron_api_event_emitter.h"
|
||||
|
||||
namespace gin_helper::internal {
|
||||
|
||||
gin::WrapperInfo kWrapperInfo = {gin::kEmbedderNativeGin};
|
||||
|
||||
v8::Local<v8::FunctionTemplate> GetEventEmitterTemplate(v8::Isolate* isolate) {
|
||||
gin::PerIsolateData* data = gin::PerIsolateData::From(isolate);
|
||||
v8::Local<v8::FunctionTemplate> tmpl =
|
||||
data->GetFunctionTemplate(&kWrapperInfo);
|
||||
|
||||
if (tmpl.IsEmpty()) {
|
||||
tmpl = v8::FunctionTemplate::New(isolate);
|
||||
v8::Local<v8::Context> context = isolate->GetCurrentContext();
|
||||
v8::Local<v8::Function> func = tmpl->GetFunction(context).ToLocalChecked();
|
||||
|
||||
v8::Local<v8::Object> eventemitter_prototype =
|
||||
electron::GetEventEmitterPrototype(isolate);
|
||||
|
||||
v8::Local<v8::Value> func_prototype;
|
||||
CHECK(func->Get(context, gin::StringToSymbol(isolate, "prototype"))
|
||||
.ToLocal(&func_prototype));
|
||||
|
||||
CHECK(func_prototype.As<v8::Object>()
|
||||
->SetPrototype(context, eventemitter_prototype)
|
||||
.ToChecked());
|
||||
|
||||
data->SetFunctionTemplate(&kWrapperInfo, tmpl);
|
||||
}
|
||||
|
||||
return tmpl;
|
||||
}
|
||||
|
||||
} // namespace gin_helper::internal
|
|
@ -7,16 +7,14 @@
|
|||
|
||||
#include <utility>
|
||||
|
||||
#include "gin/handle.h"
|
||||
#include "gin/object_template_builder.h"
|
||||
#include "shell/browser/javascript_environment.h"
|
||||
#include "shell/common/gin_helper/event.h"
|
||||
#include "shell/common/gin_helper/event_emitter.h"
|
||||
|
||||
namespace gin_helper {
|
||||
|
||||
namespace internal {
|
||||
v8::Local<v8::FunctionTemplate> GetEventEmitterTemplate(v8::Isolate* isolate);
|
||||
} // namespace internal
|
||||
|
||||
template <typename T>
|
||||
class EventEmitterMixin {
|
||||
public:
|
||||
|
@ -33,14 +31,15 @@ class EventEmitterMixin {
|
|||
v8::Local<v8::Object> wrapper;
|
||||
if (!static_cast<T*>(this)->GetWrapper(isolate).ToLocal(&wrapper))
|
||||
return false;
|
||||
v8::Local<v8::Object> event = internal::CreateCustomEvent(isolate, wrapper);
|
||||
return EmitWithEvent(isolate, wrapper, name, event,
|
||||
std::forward<Args>(args)...);
|
||||
gin::Handle<internal::Event> event = internal::Event::New(isolate);
|
||||
gin_helper::EmitEvent(isolate, wrapper, name, event,
|
||||
std::forward<Args>(args)...);
|
||||
return event->GetDefaultPrevented();
|
||||
}
|
||||
|
||||
// this.emit(name, args...);
|
||||
template <typename... Args>
|
||||
void EmitWithoutCustomEvent(base::StringPiece name, Args&&... args) {
|
||||
void EmitWithoutEvent(base::StringPiece name, Args&&... args) {
|
||||
v8::Isolate* isolate = electron::JavascriptEnvironment::GetIsolate();
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
v8::Local<v8::Object> wrapper;
|
||||
|
@ -49,20 +48,6 @@ class EventEmitterMixin {
|
|||
gin_helper::EmitEvent(isolate, wrapper, name, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
// this.emit(name, event, args...);
|
||||
template <typename... Args>
|
||||
bool EmitCustomEvent(base::StringPiece name,
|
||||
v8::Local<v8::Object> custom_event,
|
||||
Args&&... args) {
|
||||
v8::Isolate* isolate = electron::JavascriptEnvironment::GetIsolate();
|
||||
v8::HandleScope scope(isolate);
|
||||
v8::Local<v8::Object> wrapper;
|
||||
if (!static_cast<T*>(this)->GetWrapper(isolate).ToLocal(&wrapper))
|
||||
return false;
|
||||
return EmitWithEvent(isolate, wrapper, name, custom_event,
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
protected:
|
||||
EventEmitterMixin() = default;
|
||||
|
||||
|
@ -82,25 +67,6 @@ class EventEmitterMixin {
|
|||
static_cast<T*>(this)->GetTypeName(),
|
||||
constructor->InstanceTemplate());
|
||||
}
|
||||
|
||||
private:
|
||||
// this.emit(name, event, args...);
|
||||
template <typename... Args>
|
||||
static bool EmitWithEvent(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> wrapper,
|
||||
base::StringPiece name,
|
||||
v8::Local<v8::Object> event,
|
||||
Args&&... args) {
|
||||
auto context = isolate->GetCurrentContext();
|
||||
gin_helper::EmitEvent(isolate, wrapper, name, event,
|
||||
std::forward<Args>(args)...);
|
||||
v8::Local<v8::Value> defaultPrevented;
|
||||
if (event->Get(context, gin::StringToV8(isolate, "defaultPrevented"))
|
||||
.ToLocal(&defaultPrevented)) {
|
||||
return defaultPrevented->BooleanValue(isolate);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace gin_helper
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue