diff --git a/filenames.auto.gni b/filenames.auto.gni index e5030b2019e..cb3a8d44235 100644 --- a/filenames.auto.gni +++ b/filenames.auto.gni @@ -238,7 +238,6 @@ auto_filenames = { "lib/browser/remote/objects-registry.ts", "lib/browser/remote/server.ts", "lib/browser/rpc-server.ts", - "lib/browser/utils.ts", "lib/common/api/clipboard.ts", "lib/common/api/deprecate.ts", "lib/common/api/module-list.ts", diff --git a/lib/browser/api/screen.ts b/lib/browser/api/screen.ts index b2122762871..1d5e11729e7 100644 --- a/lib/browser/api/screen.ts +++ b/lib/browser/api/screen.ts @@ -1,10 +1,20 @@ -'use strict'; +const { createScreen } = process._linkedBinding('electron_common_screen'); -import { createLazyInstance } from '@electron/internal/browser/utils'; -const { EventEmitter } = require('events'); -const { Screen, createScreen } = process._linkedBinding('electron_common_screen'); +let _screen: Electron.Screen; -// Screen is an EventEmitter. -Object.setPrototypeOf(Screen.prototype, EventEmitter.prototype); - -module.exports = createLazyInstance(createScreen, Screen, true); +// We can't call createScreen until after app.on('ready'), but this module +// exposes an instance created by createScreen. In order to avoid +// side-effecting and calling createScreen upon import of this module, instead +// we export a proxy which lazily calls createScreen on first access. +export default new Proxy({}, { + get: (target, prop) => { + if (_screen === undefined) { + _screen = createScreen(); + } + const v = (_screen as any)[prop]; + if (typeof v === 'function') { + return v.bind(_screen); + } + return v; + } +}); diff --git a/lib/browser/utils.ts b/lib/browser/utils.ts deleted file mode 100644 index fd2b35d58af..00000000000 --- a/lib/browser/utils.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { EventEmitter } from 'events'; - -/** -* Creates a lazy instance of modules that can't be required before the -* app 'ready' event by returning a proxy object to mitigate side effects -* on 'require' -* -* @param {Function} creator - Function that creates a new module instance -* @param {Object} holder - the object holding the module prototype -* @param {Boolean} isEventEmitter - whether or not the module is an EventEmitter -* @returns {Object} - a proxy object for the -*/ - -export function createLazyInstance ( - creator: Function, - holder: Object, - isEventEmitter: Boolean -) { - let lazyModule: Object; - const module: any = {}; - for (const method in (holder as any).prototype) { // eslint-disable-line guard-for-in - module[method] = (...args: any) => { - // create new instance of module at runtime if none exists - if (!lazyModule) { - lazyModule = creator(); - if (isEventEmitter) EventEmitter.call(lazyModule as any); - } - - // check for properties on the prototype chain that aren't functions - if (typeof (lazyModule as any)[method] !== 'function') { - return (lazyModule as any)[method]; - } - - return (lazyModule as any)[method](...args); - }; - } - return module; -} diff --git a/shell/browser/api/electron_api_screen.cc b/shell/browser/api/electron_api_screen.cc index 773653c6b9e..13c9a39786b 100644 --- a/shell/browser/api/electron_api_screen.cc +++ b/shell/browser/api/electron_api_screen.cc @@ -29,6 +29,8 @@ namespace electron { namespace api { +gin::WrapperInfo Screen::kWrapperInfo = {gin::kEmbedderNativeGin}; + namespace { // Find an item in container according to its ID. @@ -72,7 +74,6 @@ void DelayEmitWithMetrics(Screen* screen, Screen::Screen(v8::Isolate* isolate, display::Screen* screen) : screen_(screen) { screen_->AddObserver(this); - Init(isolate); } Screen::~Screen() { @@ -154,11 +155,10 @@ v8::Local Screen::Create(gin_helper::ErrorThrower error_thrower) { .ToV8(); } -// static -void Screen::BuildPrototype(v8::Isolate* isolate, - v8::Local prototype) { - prototype->SetClassName(gin::StringToV8(isolate, "Screen")); - gin_helper::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate()) +gin::ObjectTemplateBuilder Screen::GetObjectTemplateBuilder( + v8::Isolate* isolate) { + return gin_helper::EventEmitterMixin::GetObjectTemplateBuilder( + isolate) .SetMethod("getCursorScreenPoint", &Screen::GetCursorScreenPoint) .SetMethod("getPrimaryDisplay", &Screen::GetPrimaryDisplay) .SetMethod("getAllDisplays", &Screen::GetAllDisplays) @@ -172,6 +172,10 @@ void Screen::BuildPrototype(v8::Isolate* isolate, .SetMethod("getDisplayMatching", &Screen::GetDisplayMatching); } +const char* Screen::GetTypeName() { + return "Screen"; +} + } // namespace api } // namespace electron @@ -187,9 +191,6 @@ void Initialize(v8::Local exports, v8::Isolate* isolate = context->GetIsolate(); gin_helper::Dictionary dict(isolate, exports); dict.SetMethod("createScreen", base::BindRepeating(&Screen::Create)); - dict.Set( - "Screen", - Screen::GetConstructor(isolate)->GetFunction(context).ToLocalChecked()); } } // namespace diff --git a/shell/browser/api/electron_api_screen.h b/shell/browser/api/electron_api_screen.h index 56700c1c667..94400e10019 100644 --- a/shell/browser/api/electron_api_screen.h +++ b/shell/browser/api/electron_api_screen.h @@ -7,8 +7,9 @@ #include +#include "gin/wrappable.h" +#include "shell/browser/event_emitter_mixin.h" #include "shell/common/gin_helper/error_thrower.h" -#include "shell/common/gin_helper/event_emitter.h" #include "ui/display/display_observer.h" #include "ui/display/screen.h" @@ -22,13 +23,16 @@ namespace electron { namespace api { -class Screen : public gin_helper::EventEmitter, +class Screen : public gin::Wrappable, + public gin_helper::EventEmitterMixin, public display::DisplayObserver { public: static v8::Local Create(gin_helper::ErrorThrower error_thrower); - static void BuildPrototype(v8::Isolate* isolate, - v8::Local prototype); + static gin::WrapperInfo kWrapperInfo; + gin::ObjectTemplateBuilder GetObjectTemplateBuilder( + v8::Isolate* isolate) override; + const char* GetTypeName() override; protected: Screen(v8::Isolate* isolate, display::Screen* screen);