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

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

* test: add tests
This commit is contained in:
Shelley Vohr 2023-07-10 11:49:20 +02:00 коммит произвёл GitHub
Родитель 56b5c00312
Коммит c7bdd907d7
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
23 изменённых файлов: 71 добавлений и 15 удалений

Просмотреть файл

@ -198,7 +198,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)
@ -207,6 +207,10 @@ void BrowserView::FillObjectTemplate(v8::Isolate* isolate,
.Build();
}
const char* BrowserView::GetTypeName() {
return GetClassName();
}
} // namespace electron::api
namespace {

Просмотреть файл

@ -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(); }

Просмотреть файл

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

Просмотреть файл

@ -29,9 +29,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.

Просмотреть файл

@ -256,7 +256,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)
@ -282,6 +282,10 @@ void Notification::FillObjectTemplate(v8::Isolate* isolate,
.Build();
}
const char* Notification::GetTypeName() {
return GetClassName();
}
} // namespace electron::api
namespace {

Просмотреть файл

@ -40,6 +40,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;
@ -52,6 +53,7 @@ class Notification : public gin::Wrappable<Notification>,
// gin::Wrappable
static gin::WrapperInfo kWrapperInfo;
const char* GetTypeName() override;
// disable copy
Notification(const Notification&) = delete;

Просмотреть файл

@ -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

Просмотреть файл

@ -45,13 +45,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:

Просмотреть файл

@ -1301,7 +1301,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)
@ -1379,7 +1379,7 @@ void Session::FillObjectTemplate(v8::Isolate* isolate,
}
const char* Session::GetTypeName() {
return "Session";
return GetClassName();
}
} // namespace electron::api

Просмотреть файл

@ -95,6 +95,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.

Просмотреть файл

@ -386,7 +386,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)
@ -408,6 +408,10 @@ void Tray::FillObjectTemplate(v8::Isolate* isolate,
.Build();
}
const char* Tray::GetTypeName() {
return GetClassName();
}
} // namespace electron::api
namespace {

Просмотреть файл

@ -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;

Просмотреть файл

@ -4161,7 +4161,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(
@ -4301,7 +4301,7 @@ void WebContents::FillObjectTemplate(v8::Isolate* isolate,
}
const char* WebContents::GetTypeName() {
return "WebContents";
return GetClassName();
}
ElectronBrowserContext* WebContents::GetBrowserContext() const {

Просмотреть файл

@ -147,9 +147,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();

Просмотреть файл

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

Просмотреть файл

@ -52,9 +52,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_; }

Просмотреть файл

@ -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);

Просмотреть файл

@ -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;

Просмотреть файл

@ -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');

Просмотреть файл

@ -47,6 +47,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(() => {

Просмотреть файл

@ -11,6 +11,10 @@ import { setTimeout } from 'node: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,6 +4,10 @@ import { once } from 'node: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');
});

Просмотреть файл

@ -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(() => {