diff --git a/patches/chromium/chore_add_electron_objects_to_wrappablepointertag.patch b/patches/chromium/chore_add_electron_objects_to_wrappablepointertag.patch index 525b2eb3c6..95b264c839 100644 --- a/patches/chromium/chore_add_electron_objects_to_wrappablepointertag.patch +++ b/patches/chromium/chore_add_electron_objects_to_wrappablepointertag.patch @@ -8,17 +8,18 @@ electron objects that extend gin::Wrappable and gets allocated on the cpp heap diff --git a/gin/public/wrappable_pointer_tags.h b/gin/public/wrappable_pointer_tags.h -index a507d1d837ab3ec2b2d3ae7978d9d410ab2ec2d1..5a69c5c7c5ed0e834e09ff3a2d0f0126ba4ccf99 100644 +index a507d1d837ab3ec2b2d3ae7978d9d410ab2ec2d1..2f4b90949972c3c4641bc9e489bd0c73c2f0a981 100644 --- a/gin/public/wrappable_pointer_tags.h +++ b/gin/public/wrappable_pointer_tags.h -@@ -72,7 +72,9 @@ enum WrappablePointerTag : uint16_t { +@@ -72,7 +72,10 @@ enum WrappablePointerTag : uint16_t { kTextInputControllerBindings, // content::TextInputControllerBindings kWebAXObjectProxy, // content::WebAXObjectProxy kWrappedExceptionHandler, // extensions::WrappedExceptionHandler - kLastPointerTag = kWrappedExceptionHandler, + kElectronApp, // electron::api::App + kElectronSession, // electron::api::Session -+ kLastPointerTag = kElectronSession, ++ kElectronEvent, // gin_helper::internal::Event ++ kLastPointerTag = kElectronEvent, }; static_assert(kLastPointerTag < diff --git a/shell/browser/api/electron_api_base_window.cc b/shell/browser/api/electron_api_base_window.cc index a6ebfb156b..b362c47a22 100644 --- a/shell/browser/api/electron_api_base_window.cc +++ b/shell/browser/api/electron_api_base_window.cc @@ -194,14 +194,15 @@ void BaseWindow::OnWindowQueryEndSession( v8::Isolate* isolate = JavascriptEnvironment::GetIsolate(); v8::HandleScope handle_scope(isolate); - gin_helper::Handle event = + gin_helper::internal::Event* event = gin_helper::internal::Event::New(isolate); - v8::Local event_object = event.ToV8().As(); + v8::Local event_object = + event->GetWrapper(isolate).ToLocalChecked(); gin::Dictionary dict(isolate, event_object); dict.Set("reasons", reasons); - EmitWithoutEvent("query-session-end", event); + EmitWithoutEvent("query-session-end", event_object); if (event->GetDefaultPrevented()) { *prevent_default = true; } @@ -211,14 +212,15 @@ void BaseWindow::OnWindowEndSession(const std::vector& reasons) { v8::Isolate* isolate = JavascriptEnvironment::GetIsolate(); v8::HandleScope handle_scope(isolate); - gin_helper::Handle event = + gin_helper::internal::Event* event = gin_helper::internal::Event::New(isolate); - v8::Local event_object = event.ToV8().As(); + v8::Local event_object = + event->GetWrapper(isolate).ToLocalChecked(); gin::Dictionary dict(isolate, event_object); dict.Set("reasons", reasons); - EmitWithoutEvent("session-end", event); + EmitWithoutEvent("session-end", event_object); } void BaseWindow::OnWindowBlur() { diff --git a/shell/browser/api/electron_api_web_contents.cc b/shell/browser/api/electron_api_web_contents.cc index e187828ff1..a0cba67673 100644 --- a/shell/browser/api/electron_api_web_contents.cc +++ b/shell/browser/api/electron_api_web_contents.cc @@ -1117,9 +1117,10 @@ void WebContents::OnDidAddMessageToConsole( v8::Isolate* isolate = JavascriptEnvironment::GetIsolate(); v8::HandleScope handle_scope(isolate); - gin_helper::Handle event = + gin_helper::internal::Event* event = gin_helper::internal::Event::New(isolate); - v8::Local event_object = event.ToV8().As(); + v8::Local event_object = + event->GetWrapper(isolate).ToLocalChecked(); gin_helper::Dictionary dict(isolate, event_object); dict.SetGetter("frame", source_frame); @@ -1131,7 +1132,7 @@ void WebContents::OnDidAddMessageToConsole( // TODO(samuelmaddock): Delete when deprecated arguments are fully removed. dict.Set("_level", static_cast(level)); - EmitWithoutEvent("-console-message", event); + EmitWithoutEvent("-console-message", event_object); } void WebContents::OnCreateWindow( @@ -1515,9 +1516,10 @@ void WebContents::RendererUnresponsive( base::RepeatingClosure hang_monitor_restarter) { v8::Isolate* isolate = JavascriptEnvironment::GetIsolate(); v8::HandleScope handle_scope(isolate); - gin_helper::Handle event = + gin_helper::internal::Event* event = gin_helper::internal::Event::New(isolate); - v8::Local event_object = event.ToV8().As(); + v8::Local event_object = + event->GetWrapper(isolate).ToLocalChecked(); gin::Dictionary dict(isolate, event_object); auto* web_contents_impl = static_cast(source); @@ -1531,7 +1533,7 @@ void WebContents::RendererUnresponsive( static_cast(render_widget_host); dict.Set("rendererInitialized", rwh_impl->renderer_initialized()); - EmitWithoutEvent("-unresponsive", event); + EmitWithoutEvent("-unresponsive", event_object); } void WebContents::RendererResponsive( @@ -1700,12 +1702,13 @@ content::JavaScriptDialogManager* WebContents::GetJavaScriptDialogManager( void WebContents::OnAudioStateChanged(bool audible) { v8::Isolate* isolate = JavascriptEnvironment::GetIsolate(); v8::HandleScope handle_scope(isolate); - gin_helper::Handle event = + gin_helper::internal::Event* event = gin_helper::internal::Event::New(isolate); - v8::Local event_object = event.ToV8().As(); + v8::Local event_object = + event->GetWrapper(isolate).ToLocalChecked(); gin::Dictionary dict(isolate, event_object); dict.Set("audible", audible); - EmitWithoutEvent("audio-state-changed", event); + EmitWithoutEvent("audio-state-changed", event_object); } void WebContents::BeforeUnloadFired(bool proceed) { @@ -1968,9 +1971,10 @@ bool WebContents::EmitNavigationEvent( v8::Isolate* isolate = JavascriptEnvironment::GetIsolate(); v8::HandleScope handle_scope(isolate); - gin_helper::Handle event = + gin_helper::internal::Event* event = gin_helper::internal::Event::New(isolate); - v8::Local event_object = event.ToV8().As(); + v8::Local event_object = + event->GetWrapper(isolate).ToLocalChecked(); gin_helper::Dictionary dict(isolate, event_object); dict.Set("url", url); @@ -1981,8 +1985,8 @@ bool WebContents::EmitNavigationEvent( dict.SetGetter("frame", frame_host); dict.SetGetter("initiator", initiator_frame_host); - EmitWithoutEvent(event_name, event, url, is_same_document, is_main_frame, - frame_process_id, frame_routing_id); + EmitWithoutEvent(event_name, event_object, url, is_same_document, + is_main_frame, frame_process_id, frame_routing_id); return event->GetDefaultPrevented(); } @@ -3632,16 +3636,17 @@ void WebContents::OnPaint(const gfx::Rect& dirty_rect, v8::Isolate* isolate = JavascriptEnvironment::GetIsolate(); v8::HandleScope handle_scope(isolate); - gin_helper::Handle event = + gin_helper::internal::Event* event = gin_helper::internal::Event::New(isolate); - v8::Local event_object = event.ToV8().As(); + v8::Local event_object = + event->GetWrapper(isolate).ToLocalChecked(); gin_helper::Dictionary dict(isolate, event_object); if (offscreen_use_shared_texture_) { dict.Set("texture", tex); } - EmitWithoutEvent("paint", event, dirty_rect, + EmitWithoutEvent("paint", event_object, dirty_rect, gfx::Image::CreateFrom1xBitmap(bitmap)); } diff --git a/shell/browser/api/ipc_dispatcher.h b/shell/browser/api/ipc_dispatcher.h index 1a53f79d9c..29cffe472e 100644 --- a/shell/browser/api/ipc_dispatcher.h +++ b/shell/browser/api/ipc_dispatcher.h @@ -18,6 +18,7 @@ #include "shell/common/gin_helper/handle.h" #include "shell/common/gin_helper/reply_channel.h" #include "shell/common/v8_util.h" +#include "v8/include/cppgc/macros.h" namespace electron { @@ -25,15 +26,17 @@ namespace electron { // See ipc-dispatch.ts for JS listeners. template class IpcDispatcher { + CPPGC_DISALLOW_NEW(); + public: - void Message(gin_helper::Handle& event, + void Message(v8::Local event, const std::string& channel, blink::CloneableMessage args) { TRACE_EVENT1("electron", "IpcDispatcher::Message", "channel", channel); emitter()->EmitWithoutEvent("-ipc-message", event, channel, args); } - void Invoke(gin_helper::Handle& event, + void Invoke(v8::Local event, const std::string& channel, blink::CloneableMessage arguments) { TRACE_EVENT1("electron", "IpcDispatcher::Invoke", "channel", channel); @@ -41,10 +44,9 @@ class IpcDispatcher { std::move(arguments)); } - void ReceivePostMessage( - gin_helper::Handle& event, - const std::string& channel, - blink::TransferableMessage message) { + void ReceivePostMessage(v8::Local event, + const std::string& channel, + blink::TransferableMessage message) { TRACE_EVENT1("electron", "IpcDispatcher::ReceivePostMessage", "channel", channel); v8::Isolate* isolate = JavascriptEnvironment::GetIsolate(); @@ -57,7 +59,7 @@ class IpcDispatcher { std::move(wrapped_ports)); } - void MessageSync(gin_helper::Handle& event, + void MessageSync(v8::Local event, const std::string& channel, blink::CloneableMessage arguments) { TRACE_EVENT1("electron", "IpcDispatcher::MessageSync", "channel", channel); @@ -65,7 +67,7 @@ class IpcDispatcher { std::move(arguments)); } - void MessageHost(gin_helper::Handle& event, + void MessageHost(v8::Local event, const std::string& channel, blink::CloneableMessage arguments) { TRACE_EVENT1("electron", "IpcDispatcher::MessageHost", "channel", channel); diff --git a/shell/browser/electron_api_ipc_handler_impl.cc b/shell/browser/electron_api_ipc_handler_impl.cc index 0080717485..8847f5fa48 100644 --- a/shell/browser/electron_api_ipc_handler_impl.cc +++ b/shell/browser/electron_api_ipc_handler_impl.cc @@ -48,10 +48,10 @@ void ElectronApiIPCHandlerImpl::Message(bool internal, if (session && session->Get()) { v8::Isolate* isolate = electron::JavascriptEnvironment::GetIsolate(); v8::HandleScope handle_scope(isolate); - auto event = MakeIPCEvent(isolate, session->Get(), internal); - if (event.IsEmpty()) - return; - session->Get()->Message(event, channel, std::move(arguments)); + auto* event = MakeIPCEvent(isolate, session->Get(), internal); + v8::Local event_object = + event->GetWrapper(isolate).ToLocalChecked(); + session->Get()->Message(event_object, channel, std::move(arguments)); } } void ElectronApiIPCHandlerImpl::Invoke(bool internal, @@ -62,11 +62,11 @@ void ElectronApiIPCHandlerImpl::Invoke(bool internal, if (session && session->Get()) { v8::Isolate* isolate = electron::JavascriptEnvironment::GetIsolate(); v8::HandleScope handle_scope(isolate); - auto event = + auto* event = MakeIPCEvent(isolate, session->Get(), internal, std::move(callback)); - if (event.IsEmpty()) - return; - session->Get()->Invoke(event, channel, std::move(arguments)); + v8::Local event_object = + event->GetWrapper(isolate).ToLocalChecked(); + session->Get()->Invoke(event_object, channel, std::move(arguments)); } } @@ -77,10 +77,11 @@ void ElectronApiIPCHandlerImpl::ReceivePostMessage( if (session && session->Get()) { v8::Isolate* isolate = electron::JavascriptEnvironment::GetIsolate(); v8::HandleScope handle_scope(isolate); - auto event = MakeIPCEvent(isolate, session->Get(), false); - if (event.IsEmpty()) - return; - session->Get()->ReceivePostMessage(event, channel, std::move(message)); + auto* event = MakeIPCEvent(isolate, session->Get(), false); + v8::Local event_object = + event->GetWrapper(isolate).ToLocalChecked(); + session->Get()->ReceivePostMessage(event_object, channel, + std::move(message)); } } @@ -92,11 +93,11 @@ void ElectronApiIPCHandlerImpl::MessageSync(bool internal, if (session && session->Get()) { v8::Isolate* isolate = electron::JavascriptEnvironment::GetIsolate(); v8::HandleScope handle_scope(isolate); - auto event = + auto* event = MakeIPCEvent(isolate, session->Get(), internal, std::move(callback)); - if (event.IsEmpty()) - return; - session->Get()->MessageSync(event, channel, std::move(arguments)); + v8::Local event_object = + event->GetWrapper(isolate).ToLocalChecked(); + session->Get()->MessageSync(event_object, channel, std::move(arguments)); } } @@ -106,10 +107,10 @@ void ElectronApiIPCHandlerImpl::MessageHost(const std::string& channel, if (session && session->Get()) { v8::Isolate* isolate = electron::JavascriptEnvironment::GetIsolate(); v8::HandleScope handle_scope(isolate); - auto event = MakeIPCEvent(isolate, session->Get(), false); - if (event.IsEmpty()) - return; - session->Get()->MessageHost(event, channel, std::move(arguments)); + auto* event = MakeIPCEvent(isolate, session->Get(), false); + v8::Local event_object = + event->GetWrapper(isolate).ToLocalChecked(); + session->Get()->MessageHost(event_object, channel, std::move(arguments)); } } @@ -123,8 +124,7 @@ gin::WeakCell* ElectronApiIPCHandlerImpl::GetSession() { : nullptr; } -gin_helper::Handle -ElectronApiIPCHandlerImpl::MakeIPCEvent( +gin_helper::internal::Event* ElectronApiIPCHandlerImpl::MakeIPCEvent( v8::Isolate* isolate, api::Session* session, bool internal, @@ -159,9 +159,11 @@ ElectronApiIPCHandlerImpl::MakeIPCEvent( } content::RenderFrameHost* frame = GetRenderFrameHost(); - gin_helper::Handle event = + gin_helper::internal::Event* event = gin_helper::internal::Event::New(isolate); - gin_helper::Dictionary dict(isolate, event.ToV8().As()); + v8::Local event_object = + event->GetWrapper(isolate).ToLocalChecked(); + gin_helper::Dictionary dict(isolate, event_object); dict.Set("type", "frame"); dict.Set("sender", web_contents()); if (internal) diff --git a/shell/browser/electron_api_ipc_handler_impl.h b/shell/browser/electron_api_ipc_handler_impl.h index ff73a6ea1f..57135ccc1c 100644 --- a/shell/browser/electron_api_ipc_handler_impl.h +++ b/shell/browser/electron_api_ipc_handler_impl.h @@ -72,7 +72,7 @@ class ElectronApiIPCHandlerImpl : public mojom::ElectronApiIPC, content::RenderFrameHost* GetRenderFrameHost(); gin::WeakCell* GetSession(); - gin_helper::Handle MakeIPCEvent( + gin_helper::internal::Event* MakeIPCEvent( v8::Isolate* isolate, api::Session* session, bool internal, diff --git a/shell/browser/electron_api_sw_ipc_handler_impl.cc b/shell/browser/electron_api_sw_ipc_handler_impl.cc index d8938f5863..23b3b9b551 100644 --- a/shell/browser/electron_api_sw_ipc_handler_impl.cc +++ b/shell/browser/electron_api_sw_ipc_handler_impl.cc @@ -75,10 +75,10 @@ void ElectronApiSWIPCHandlerImpl::Message(bool internal, if (session && session->Get()) { v8::Isolate* isolate = electron::JavascriptEnvironment::GetIsolate(); v8::HandleScope handle_scope(isolate); - auto event = MakeIPCEvent(isolate, session->Get(), internal); - if (event.IsEmpty()) - return; - session->Get()->Message(event, channel, std::move(arguments)); + auto* event = MakeIPCEvent(isolate, session->Get(), internal); + v8::Local event_object = + event->GetWrapper(isolate).ToLocalChecked(); + session->Get()->Message(event_object, channel, std::move(arguments)); } } @@ -90,11 +90,11 @@ void ElectronApiSWIPCHandlerImpl::Invoke(bool internal, if (session && session->Get()) { v8::Isolate* isolate = electron::JavascriptEnvironment::GetIsolate(); v8::HandleScope handle_scope(isolate); - auto event = + auto* event = MakeIPCEvent(isolate, session->Get(), internal, std::move(callback)); - if (event.IsEmpty()) - return; - session->Get()->Invoke(event, channel, std::move(arguments)); + v8::Local event_object = + event->GetWrapper(isolate).ToLocalChecked(); + session->Get()->Invoke(event_object, channel, std::move(arguments)); } } @@ -105,10 +105,11 @@ void ElectronApiSWIPCHandlerImpl::ReceivePostMessage( if (session && session->Get()) { v8::Isolate* isolate = electron::JavascriptEnvironment::GetIsolate(); v8::HandleScope handle_scope(isolate); - auto event = MakeIPCEvent(isolate, session->Get(), false); - if (event.IsEmpty()) - return; - session->Get()->ReceivePostMessage(event, channel, std::move(message)); + auto* event = MakeIPCEvent(isolate, session->Get(), false); + v8::Local event_object = + event->GetWrapper(isolate).ToLocalChecked(); + session->Get()->ReceivePostMessage(event_object, channel, + std::move(message)); } } @@ -120,11 +121,11 @@ void ElectronApiSWIPCHandlerImpl::MessageSync(bool internal, if (session && session->Get()) { v8::Isolate* isolate = electron::JavascriptEnvironment::GetIsolate(); v8::HandleScope handle_scope(isolate); - auto event = + auto* event = MakeIPCEvent(isolate, session->Get(), internal, std::move(callback)); - if (event.IsEmpty()) - return; - session->Get()->MessageSync(event, channel, std::move(arguments)); + v8::Local event_object = + event->GetWrapper(isolate).ToLocalChecked(); + session->Get()->MessageSync(event_object, channel, std::move(arguments)); } } @@ -144,8 +145,7 @@ gin::WeakCell* ElectronApiSWIPCHandlerImpl::GetSession() { return api::Session::FromBrowserContext(GetBrowserContext()); } -gin_helper::Handle -ElectronApiSWIPCHandlerImpl::MakeIPCEvent( +gin_helper::internal::Event* ElectronApiSWIPCHandlerImpl::MakeIPCEvent( v8::Isolate* isolate, api::Session* session, bool internal, @@ -159,9 +159,10 @@ ElectronApiSWIPCHandlerImpl::MakeIPCEvent( return {}; } - gin_helper::Handle event = + gin_helper::internal::Event* event = gin_helper::internal::Event::New(isolate); - v8::Local event_object = event.ToV8().As(); + v8::Local event_object = + event->GetWrapper(isolate).ToLocalChecked(); gin_helper::Dictionary dict(isolate, event_object); dict.Set("type", "service-worker"); diff --git a/shell/browser/electron_api_sw_ipc_handler_impl.h b/shell/browser/electron_api_sw_ipc_handler_impl.h index aceae5ccbb..031ebd311d 100644 --- a/shell/browser/electron_api_sw_ipc_handler_impl.h +++ b/shell/browser/electron_api_sw_ipc_handler_impl.h @@ -13,7 +13,6 @@ #include "electron/shell/common/api/api.mojom.h" #include "mojo/public/cpp/bindings/associated_receiver.h" #include "shell/common/gin_helper/event.h" -#include "shell/common/gin_helper/handle.h" namespace content { class RenderProcessHost; @@ -75,7 +74,7 @@ class ElectronApiSWIPCHandlerImpl : public mojom::ElectronApiIPC, ElectronBrowserContext* GetBrowserContext(); gin::WeakCell* GetSession(); - gin_helper::Handle MakeIPCEvent( + gin_helper::internal::Event* MakeIPCEvent( v8::Isolate* isolate, api::Session* session, bool internal, diff --git a/shell/browser/electron_crypto_module_delegate_nss.cc b/shell/browser/electron_crypto_module_delegate_nss.cc index fb08ab7c00..eaa0902dd5 100644 --- a/shell/browser/electron_crypto_module_delegate_nss.cc +++ b/shell/browser/electron_crypto_module_delegate_nss.cc @@ -48,9 +48,10 @@ void ElectronNSSCryptoModuleDelegate::RequestPasswordOnUIThread( v8::Isolate* isolate = electron::JavascriptEnvironment::GetIsolate(); v8::HandleScope handle_scope(isolate); - gin_helper::Handle event = + gin_helper::internal::Event* event = gin_helper::internal::Event::New(isolate); - v8::Local event_object = event.ToV8().As(); + v8::Local event_object = + event->GetWrapper(isolate).ToLocalChecked(); gin_helper::Dictionary dict(isolate, event_object); dict.Set("hostname", server_.host()); dict.Set("tokenName", token_name); diff --git a/shell/browser/event_emitter_mixin.h b/shell/browser/event_emitter_mixin.h index 38005202b3..7260f93407 100644 --- a/shell/browser/event_emitter_mixin.h +++ b/shell/browser/event_emitter_mixin.h @@ -32,8 +32,10 @@ class EventEmitterMixin { v8::Local wrapper; if (!static_cast(this)->GetWrapper(isolate).ToLocal(&wrapper)) return false; - gin_helper::Handle event = internal::Event::New(isolate); - gin_helper::EmitEvent(isolate, wrapper, name, event, + internal::Event* event = internal::Event::New(isolate); + v8::Local event_object = + event->GetWrapper(isolate).ToLocalChecked(); + gin_helper::EmitEvent(isolate, wrapper, name, event_object, std::forward(args)...); return event->GetDefaultPrevented(); } diff --git a/shell/common/gin_helper/event.cc b/shell/common/gin_helper/event.cc index 03bb2580d3..c125c5cbea 100644 --- a/shell/common/gin_helper/event.cc +++ b/shell/common/gin_helper/event.cc @@ -3,21 +3,24 @@ // found in the LICENSE file. #include "shell/common/gin_helper/event.h" -#include "gin/dictionary.h" + #include "gin/object_template_builder.h" -#include "shell/common/gin_helper/handle.h" +#include "v8/include/cppgc/allocation.h" +#include "v8/include/v8-cppgc.h" namespace gin_helper::internal { // static -gin_helper::Handle Event::New(v8::Isolate* isolate) { - return gin_helper::CreateHandle(isolate, new Event()); +Event* Event::New(v8::Isolate* isolate) { + auto* event = cppgc::MakeGarbageCollected( + isolate->GetCppHeap()->GetAllocationHandle()); + return event; } // static v8::Local Event::FillObjectTemplate( v8::Isolate* isolate, v8::Local templ) { - return gin::ObjectTemplateBuilder(isolate, "Event", templ) + return gin::ObjectTemplateBuilder(isolate, GetClassName(), templ) .SetMethod("preventDefault", &Event::PreventDefault) .SetProperty("defaultPrevented", &Event::GetDefaultPrevented) .Build(); @@ -27,10 +30,15 @@ Event::Event() = default; Event::~Event() = default; -gin::DeprecatedWrapperInfo Event::kWrapperInfo = {gin::kEmbedderNativeGin}; +gin::WrapperInfo Event::kWrapperInfo = {{gin::kEmbedderNativeGin}, + gin::kElectronEvent}; -const char* Event::GetTypeName() { - return GetClassName(); +const gin::WrapperInfo* Event::wrapper_info() const { + return &kWrapperInfo; +} + +const char* Event::GetHumanReadableName() const { + return "Electron / Event"; } } // namespace gin_helper::internal diff --git a/shell/common/gin_helper/event.h b/shell/common/gin_helper/event.h index 28dd2eaa12..3d74f5b94a 100644 --- a/shell/common/gin_helper/event.h +++ b/shell/common/gin_helper/event.h @@ -5,38 +5,27 @@ #ifndef ELECTRON_SHELL_COMMON_GIN_HELPER_EVENT_H_ #define ELECTRON_SHELL_COMMON_GIN_HELPER_EVENT_H_ +#include "gin/wrappable.h" #include "shell/common/gin_helper/constructible.h" -#include "shell/common/gin_helper/wrappable.h" - -namespace gin_helper { -template -class Handle; -} // namespace gin_helper - -namespace v8 { -class Isolate; -template -class Local; -class Object; -class ObjectTemplate; -} // namespace v8 namespace gin_helper::internal { -class Event final : public gin_helper::DeprecatedWrappable, +class Event final : public gin::Wrappable, public gin_helper::Constructible { public: // gin_helper::Constructible - static gin_helper::Handle New(v8::Isolate* isolate); + static Event* New(v8::Isolate* isolate); static v8::Local FillObjectTemplate( v8::Isolate* isolate, v8::Local prototype); static const char* GetClassName() { return "Event"; } - // gin_helper::Wrappable - static gin::DeprecatedWrapperInfo kWrapperInfo; - const char* GetTypeName() override; + // gin::Wrappable + static gin::WrapperInfo kWrapperInfo; + const gin::WrapperInfo* wrapper_info() const override; + const char* GetHumanReadableName() const override; + Event(); ~Event() override; void PreventDefault() { default_prevented_ = true; } @@ -44,8 +33,6 @@ class Event final : public gin_helper::DeprecatedWrappable, bool GetDefaultPrevented() { return default_prevented_; } private: - Event(); - bool default_prevented_ = false; }; diff --git a/shell/common/gin_helper/event_emitter.h b/shell/common/gin_helper/event_emitter.h index ff074d3a65..4b57cfb80a 100644 --- a/shell/common/gin_helper/event_emitter.h +++ b/shell/common/gin_helper/event_emitter.h @@ -31,10 +31,13 @@ class EventEmitter : public gin_helper::Wrappable { v8::Local wrapper = this->GetWrapper(); if (wrapper.IsEmpty()) return false; - gin_helper::Handle event = internal::Event::New(isolate); + internal::Event* event = internal::Event::New(isolate); + v8::Local event_object = + event->GetWrapper(isolate).ToLocalChecked(); // It's possible that |this| will be deleted by EmitEvent, so save anything // we need from |this| before calling EmitEvent. - EmitEvent(isolate, wrapper, name, event, std::forward(args)...); + EmitEvent(isolate, wrapper, name, event_object, + std::forward(args)...); return event->GetDefaultPrevented(); } diff --git a/shell/common/node_bindings.cc b/shell/common/node_bindings.cc index 52186599b4..e0c1f43e61 100644 --- a/shell/common/node_bindings.cc +++ b/shell/common/node_bindings.cc @@ -644,7 +644,8 @@ void NodeBindings::Initialize(v8::Isolate* const isolate, SetErrorMode(GetErrorMode() & ~SEM_NOGPFAULTERRORBOX); #endif - gin_helper::internal::Event::GetConstructor(isolate, context); + gin_helper::internal::Event::GetConstructor( + isolate, context, &gin_helper::internal::Event::kWrapperInfo); g_is_initialized = true; } diff --git a/spec/cpp-heap-spec.ts b/spec/cpp-heap-spec.ts index 1458819241..bc36fd8283 100644 --- a/spec/cpp-heap-spec.ts +++ b/spec/cpp-heap-spec.ts @@ -76,4 +76,30 @@ describe('cpp heap', () => { expect(result).to.equal(true); }); }); + + describe('internal event', () => { + it('should record as node in heap snapshot', async () => { + const { remotely } = await startRemoteControlApp(['--expose-internals']); + const result = await remotely(async (heap: string, snapshotHelper: string) => { + const { BrowserWindow } = require('electron'); + const { once } = require('node:events'); + const { recordState } = require(heap); + const { containsRetainingPath } = require(snapshotHelper); + + const w = new BrowserWindow({ + show: false + }); + await w.loadURL('about:blank'); + const state = recordState(); + const isClosed = once(w, 'closed'); + w.destroy(); + await isClosed; + const eventNativeStackReference = containsRetainingPath(state.snapshot, ['C++ native stack roots', 'Electron / Event']); + const noPersistentReference = !containsRetainingPath(state.snapshot, ['C++ Persistent roots', 'Electron / Event']); + return eventNativeStackReference && noPersistentReference; + }, path.join(__dirname, '../../third_party/electron_node/test/common/heap'), + path.join(__dirname, 'lib', 'heapsnapshot-helpers.js')); + expect(result).to.equal(true); + }); + }); });