Browse Source

fix: set prototype names on `gin::Constructible` classes (#39035)

* fix: set prototype names on gin::Constructible classes

Co-authored-by: Shelley Vohr <[email protected]>

* test: add tests

Co-authored-by: Shelley Vohr <[email protected]>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <[email protected]>
trop[bot] 1 year ago
parent
commit
9281a34f8b

+ 5 - 1
shell/browser/api/electron_api_browser_view.cc

@@ -201,7 +201,7 @@ v8::Local<v8::Value> BrowserView::GetWebContents(v8::Isolate* isolate) {
 // static
 void BrowserView::FillObjectTemplate(v8::Isolate* isolate,
                                      v8::Local<v8::ObjectTemplate> templ) {
-  gin::ObjectTemplateBuilder(isolate, "BrowserView", templ)
+  gin::ObjectTemplateBuilder(isolate, GetClassName(), templ)
       .SetMethod("setAutoResize", &BrowserView::SetAutoResize)
       .SetMethod("setBounds", &BrowserView::SetBounds)
       .SetMethod("getBounds", &BrowserView::GetBounds)
@@ -210,6 +210,10 @@ void BrowserView::FillObjectTemplate(v8::Isolate* isolate,
       .Build();
 }
 
+const char* BrowserView::GetTypeName() {
+  return GetClassName();
+}
+
 }  // namespace electron::api
 
 namespace {

+ 2 - 0
shell/browser/api/electron_api_browser_view.h

@@ -45,9 +45,11 @@ class BrowserView : public gin::Wrappable<BrowserView>,
   static gin::Handle<BrowserView> New(gin_helper::ErrorThrower thrower,
                                       gin::Arguments* args);
   static void FillObjectTemplate(v8::Isolate*, v8::Local<v8::ObjectTemplate>);
+  static const char* GetClassName() { return "BrowserView"; }
 
   // gin::Wrappable
   static gin::WrapperInfo kWrapperInfo;
+  const char* GetTypeName() override;
 
   WebContents* web_contents() const { return api_web_contents_; }
   NativeBrowserView* view() const { return view_.get(); }

+ 4 - 0
shell/browser/api/electron_api_menu.cc

@@ -298,6 +298,10 @@ void Menu::FillObjectTemplate(v8::Isolate* isolate,
       .Build();
 }
 
+const char* Menu::GetTypeName() {
+  return GetClassName();
+}
+
 }  // namespace electron::api
 
 namespace {

+ 2 - 0
shell/browser/api/electron_api_menu.h

@@ -28,9 +28,11 @@ class Menu : public gin::Wrappable<Menu>,
   // gin_helper::Constructible
   static gin::Handle<Menu> New(gin::Arguments* args);
   static void FillObjectTemplate(v8::Isolate*, v8::Local<v8::ObjectTemplate>);
+  static const char* GetClassName() { return "Menu"; }
 
   // gin::Wrappable
   static gin::WrapperInfo kWrapperInfo;
+  const char* GetTypeName() override;
 
 #if BUILDFLAG(IS_MAC)
   // Set the global menubar.

+ 5 - 1
shell/browser/api/electron_api_notification.cc

@@ -255,7 +255,7 @@ bool Notification::IsSupported() {
 
 void Notification::FillObjectTemplate(v8::Isolate* isolate,
                                       v8::Local<v8::ObjectTemplate> templ) {
-  gin::ObjectTemplateBuilder(isolate, "Notification", templ)
+  gin::ObjectTemplateBuilder(isolate, GetClassName(), templ)
       .SetMethod("show", &Notification::Show)
       .SetMethod("close", &Notification::Close)
       .SetProperty("title", &Notification::GetTitle, &Notification::SetTitle)
@@ -281,6 +281,10 @@ void Notification::FillObjectTemplate(v8::Isolate* isolate,
       .Build();
 }
 
+const char* Notification::GetTypeName() {
+  return GetClassName();
+}
+
 }  // namespace electron::api
 
 namespace {

+ 2 - 0
shell/browser/api/electron_api_notification.h

@@ -39,6 +39,7 @@ class Notification : public gin::Wrappable<Notification>,
   static gin::Handle<Notification> New(gin_helper::ErrorThrower thrower,
                                        gin::Arguments* args);
   static void FillObjectTemplate(v8::Isolate*, v8::Local<v8::ObjectTemplate>);
+  static const char* GetClassName() { return "Notification"; }
 
   // NotificationDelegate:
   void NotificationAction(int index) override;
@@ -51,6 +52,7 @@ class Notification : public gin::Wrappable<Notification>,
 
   // gin::Wrappable
   static gin::WrapperInfo kWrapperInfo;
+  const char* GetTypeName() override;
 
   // disable copy
   Notification(const Notification&) = delete;

+ 2 - 2
shell/browser/api/electron_api_protocol.cc

@@ -283,7 +283,7 @@ gin::Handle<Protocol> Protocol::New(gin_helper::ErrorThrower thrower) {
 v8::Local<v8::ObjectTemplate> Protocol::FillObjectTemplate(
     v8::Isolate* isolate,
     v8::Local<v8::ObjectTemplate> tmpl) {
-  return gin::ObjectTemplateBuilder(isolate, "Protocol", tmpl)
+  return gin::ObjectTemplateBuilder(isolate, GetClassName(), tmpl)
       .SetMethod("registerStringProtocol",
                  &Protocol::RegisterProtocolFor<ProtocolType::kString>)
       .SetMethod("registerBufferProtocol",
@@ -317,7 +317,7 @@ v8::Local<v8::ObjectTemplate> Protocol::FillObjectTemplate(
 }
 
 const char* Protocol::GetTypeName() {
-  return "Protocol";
+  return GetClassName();
 }
 
 }  // namespace electron::api

+ 5 - 3
shell/browser/api/electron_api_protocol.h

@@ -44,13 +44,15 @@ class Protocol : public gin::Wrappable<Protocol>,
   static gin::Handle<Protocol> Create(v8::Isolate* isolate,
                                       ElectronBrowserContext* browser_context);
 
+  // gin_helper::Constructible
   static gin::Handle<Protocol> New(gin_helper::ErrorThrower thrower);
-
-  // gin::Wrappable
-  static gin::WrapperInfo kWrapperInfo;
   static v8::Local<v8::ObjectTemplate> FillObjectTemplate(
       v8::Isolate* isolate,
       v8::Local<v8::ObjectTemplate> tmpl);
+  static const char* GetClassName() { return "Protocol"; }
+
+  // gin::Wrappable
+  static gin::WrapperInfo kWrapperInfo;
   const char* GetTypeName() override;
 
  private:

+ 2 - 2
shell/browser/api/electron_api_session.cc

@@ -1300,7 +1300,7 @@ gin::Handle<Session> Session::New() {
 
 void Session::FillObjectTemplate(v8::Isolate* isolate,
                                  v8::Local<v8::ObjectTemplate> templ) {
-  gin::ObjectTemplateBuilder(isolate, "Session", templ)
+  gin::ObjectTemplateBuilder(isolate, GetClassName(), templ)
       .SetMethod("resolveHost", &Session::ResolveHost)
       .SetMethod("resolveProxy", &Session::ResolveProxy)
       .SetMethod("getCacheSize", &Session::GetCacheSize)
@@ -1378,7 +1378,7 @@ void Session::FillObjectTemplate(v8::Isolate* isolate,
 }
 
 const char* Session::GetTypeName() {
-  return "Session";
+  return GetClassName();
 }
 
 }  // namespace electron::api

+ 1 - 0
shell/browser/api/electron_api_session.h

@@ -94,6 +94,7 @@ class Session : public gin::Wrappable<Session>,
   // gin::Wrappable
   static gin::WrapperInfo kWrapperInfo;
   static void FillObjectTemplate(v8::Isolate*, v8::Local<v8::ObjectTemplate>);
+  static const char* GetClassName() { return "Session"; }
   const char* GetTypeName() override;
 
   // Methods.

+ 5 - 1
shell/browser/api/electron_api_tray.cc

@@ -396,7 +396,7 @@ bool Tray::CheckAlive() {
 // static
 void Tray::FillObjectTemplate(v8::Isolate* isolate,
                               v8::Local<v8::ObjectTemplate> templ) {
-  gin::ObjectTemplateBuilder(isolate, "Tray", templ)
+  gin::ObjectTemplateBuilder(isolate, GetClassName(), templ)
       .SetMethod("destroy", &Tray::Destroy)
       .SetMethod("isDestroyed", &Tray::IsDestroyed)
       .SetMethod("setImage", &Tray::SetImage)
@@ -418,6 +418,10 @@ void Tray::FillObjectTemplate(v8::Isolate* isolate,
       .Build();
 }
 
+const char* Tray::GetTypeName() {
+  return GetClassName();
+}
+
 }  // namespace electron::api
 
 namespace {

+ 3 - 0
shell/browser/api/electron_api_tray.h

@@ -45,10 +45,13 @@ class Tray : public gin::Wrappable<Tray>,
                                v8::Local<v8::Value> image,
                                absl::optional<UUID> guid,
                                gin::Arguments* args);
+
   static void FillObjectTemplate(v8::Isolate*, v8::Local<v8::ObjectTemplate>);
+  static const char* GetClassName() { return "Tray"; }
 
   // gin::Wrappable
   static gin::WrapperInfo kWrapperInfo;
+  const char* GetTypeName() override;
 
   // disable copy
   Tray(const Tray&) = delete;

+ 2 - 2
shell/browser/api/electron_api_web_contents.cc

@@ -4227,7 +4227,7 @@ void WebContents::FillObjectTemplate(v8::Isolate* isolate,
                                      v8::Local<v8::ObjectTemplate> templ) {
   gin::InvokerOptions options;
   options.holder_is_first_argument = true;
-  options.holder_type = "WebContents";
+  options.holder_type = GetClassName();
   templ->Set(
       gin::StringToSymbol(isolate, "isDestroyed"),
       gin::CreateFunctionTemplate(
@@ -4369,7 +4369,7 @@ void WebContents::FillObjectTemplate(v8::Isolate* isolate,
 }
 
 const char* WebContents::GetTypeName() {
-  return "WebContents";
+  return GetClassName();
 }
 
 ElectronBrowserContext* WebContents::GetBrowserContext() const {

+ 4 - 1
shell/browser/api/electron_api_web_contents.h

@@ -148,9 +148,12 @@ class WebContents : public ExclusiveAccessContext,
       v8::Isolate* isolate,
       const gin_helper::Dictionary& web_preferences);
 
+  // gin_helper::Constructible
+  static void FillObjectTemplate(v8::Isolate*, v8::Local<v8::ObjectTemplate>);
+  static const char* GetClassName() { return "WebContents"; }
+
   // gin::Wrappable
   static gin::WrapperInfo kWrapperInfo;
-  static void FillObjectTemplate(v8::Isolate*, v8::Local<v8::ObjectTemplate>);
   const char* GetTypeName() override;
 
   void Destroy();

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

@@ -409,7 +409,7 @@ void WebFrameMain::FillObjectTemplate(v8::Isolate* isolate,
 }
 
 const char* WebFrameMain::GetTypeName() {
-  return "WebFrameMain";
+  return GetClassName();
 }
 
 }  // namespace electron::api

+ 4 - 1
shell/browser/api/electron_api_web_frame_main.h

@@ -51,9 +51,12 @@ class WebFrameMain : public gin::Wrappable<WebFrameMain>,
   static WebFrameMain* FromRenderFrameHost(
       content::RenderFrameHost* render_frame_host);
 
+  // gin_helper::Constructible
+  static void FillObjectTemplate(v8::Isolate*, v8::Local<v8::ObjectTemplate>);
+  static const char* GetClassName() { return "WebFrameMain"; }
+
   // gin::Wrappable
   static gin::WrapperInfo kWrapperInfo;
-  static void FillObjectTemplate(v8::Isolate*, v8::Local<v8::ObjectTemplate>);
   const char* GetTypeName() override;
 
   content::RenderFrameHost* render_frame_host() const { return render_frame_; }

+ 1 - 0
shell/common/gin_helper/constructible.h

@@ -55,6 +55,7 @@ class Constructible {
       }
       constructor->InstanceTemplate()->SetInternalFieldCount(
           gin::kNumberOfInternalFields);
+      constructor->SetClassName(gin::StringToV8(isolate, T::GetClassName()));
       T::FillObjectTemplate(isolate, constructor->PrototypeTemplate());
       data->SetObjectTemplate(wrapper_info, constructor->InstanceTemplate());
       data->SetFunctionTemplate(wrapper_info, constructor);

+ 1 - 0
shell/common/gin_helper/event.h

@@ -27,6 +27,7 @@ class Event : public gin::Wrappable<Event>,
   static v8::Local<v8::ObjectTemplate> FillObjectTemplate(
       v8::Isolate* isolate,
       v8::Local<v8::ObjectTemplate> prototype);
+  static const char* GetClassName() { return "Event"; }
 
   // gin::Wrappable
   static gin::WrapperInfo kWrapperInfo;

+ 4 - 0
spec/api-browser-view-spec.ts

@@ -40,6 +40,10 @@ describe('BrowserView module', () => {
     expect(webContents.getAllWebContents()).to.have.length(0);
   });
 
+  it('sets the correct class name on the prototype', () => {
+    expect(BrowserView.prototype.constructor.name).to.equal('BrowserView');
+  });
+
   it('can be created with an existing webContents', async () => {
     const wc = (webContents as typeof ElectronInternal.WebContents).create({ sandbox: true });
     await wc.loadURL('about:blank');

+ 4 - 0
spec/api-browser-window-spec.ts

@@ -48,6 +48,10 @@ const isBeforeUnload = (event: Event, level: number, message: string) => {
 };
 
 describe('BrowserWindow module', () => {
+  it('sets the correct class name on the prototype', () => {
+    expect(BrowserWindow.prototype.constructor.name).to.equal('BrowserWindow');
+  });
+
   describe('BrowserWindow constructor', () => {
     it('allows passing void 0 as the webContents', async () => {
       expect(() => {

+ 4 - 0
spec/api-menu-spec.ts

@@ -11,6 +11,10 @@ import { setTimeout } from 'timers/promises';
 const fixturesPath = path.resolve(__dirname, 'fixtures');
 
 describe('Menu module', function () {
+  it('sets the correct class name on the prototype', () => {
+    expect(Menu.prototype.constructor.name).to.equal('Menu');
+  });
+
   describe('Menu.buildFromTemplate', () => {
     it('should be able to attach extra fields', () => {
       const menu = Menu.buildFromTemplate([

+ 4 - 0
spec/api-notification-spec.ts

@@ -4,6 +4,10 @@ import { once } from 'events';
 import { ifit } from './lib/spec-helpers';
 
 describe('Notification module', () => {
+  it('sets the correct class name on the prototype', () => {
+    expect(Notification.prototype.constructor.name).to.equal('Notification');
+  });
+
   it('is supported', () => {
     expect(Notification.isSupported()).to.be.a('boolean');
   });

+ 4 - 0
spec/api-tray-spec.ts

@@ -15,6 +15,10 @@ describe('tray module', () => {
   });
 
   describe('new Tray', () => {
+    it('sets the correct class name on the prototype', () => {
+      expect(Tray.prototype.constructor.name).to.equal('Tray');
+    });
+
     it('throws a descriptive error for a missing file', () => {
       const badPath = path.resolve('I', 'Do', 'Not', 'Exist');
       expect(() => {