diff --git a/lib/browser/api/app.ts b/lib/browser/api/app.ts index db25a34b7d84..17d3cc00422f 100644 --- a/lib/browser/api/app.ts +++ b/lib/browser/api/app.ts @@ -2,40 +2,35 @@ import * as fs from 'fs'; import * as path from 'path'; import { deprecate, Menu } from 'electron/main'; -import { EventEmitter } from 'events'; const bindings = process._linkedBinding('electron_browser_app'); const commandLine = process._linkedBinding('electron_common_command_line'); -const { app, App } = bindings; +const { app } = bindings; // Only one app object permitted. export default app; let dockMenu: Electron.Menu | null = null; -// App is an EventEmitter. -Object.setPrototypeOf(App.prototype, EventEmitter.prototype); -EventEmitter.call(app as any); - // Properties. const nativeASGetter = app.isAccessibilitySupportEnabled; const nativeASSetter = app.setAccessibilitySupportEnabled; -Object.defineProperty(App.prototype, 'accessibilitySupportEnabled', { +Object.defineProperty(app, 'accessibilitySupportEnabled', { get: () => nativeASGetter.call(app), set: (enabled) => nativeASSetter.call(app, enabled) }); const nativeBCGetter = app.getBadgeCount; const nativeBCSetter = app.setBadgeCount; -Object.defineProperty(App.prototype, 'badgeCount', { +Object.defineProperty(app, 'badgeCount', { get: () => nativeBCGetter.call(app), set: (count) => nativeBCSetter.call(app, count) }); const nativeNGetter = app.getName; const nativeNSetter = app.setName; -Object.defineProperty(App.prototype, 'name', { +Object.defineProperty(app, 'name', { get: () => nativeNGetter.call(app), set: (name) => nativeNSetter.call(app, name) }); @@ -60,7 +55,7 @@ Object.defineProperty(app, 'applicationMenu', { } }); -App.prototype.isPackaged = (() => { +(app as any).isPackaged = (() => { const execFile = path.basename(process.execPath).toLowerCase(); if (process.platform === 'win32') { return execFile !== 'electron.exe'; @@ -137,4 +132,4 @@ for (const name of events) { // Deprecate allowRendererProcessReuse but only if they set it to false, no need to log if // they are setting it to true -deprecate.removeProperty(app, 'allowRendererProcessReuse', [false]); +deprecate.removeProperty({ __proto__: app } as any, 'allowRendererProcessReuse', [false]); diff --git a/shell/browser/api/electron_api_app.cc b/shell/browser/api/electron_api_app.cc index eced5ade15d9..a39b41d4f329 100644 --- a/shell/browser/api/electron_api_app.cc +++ b/shell/browser/api/electron_api_app.cc @@ -382,6 +382,8 @@ namespace electron { namespace api { +gin::WrapperInfo App::kWrapperInfo = {gin::kEmbedderNativeGin}; + namespace { IconLoader::IconSize GetIconSizeByString(const std::string& size) { @@ -466,7 +468,7 @@ void OnClientCertificateSelected( v8::Isolate* isolate, std::shared_ptr delegate, std::shared_ptr identities, - gin_helper::Arguments* args) { + gin::Arguments* args) { if (args->Length() == 2) { delegate->ContinueWithCertificate(nullptr, nullptr); return; @@ -481,7 +483,8 @@ void OnClientCertificateSelected( gin_helper::Dictionary cert_data; if (!gin::ConvertFromV8(isolate, val, &cert_data)) { - args->ThrowError("Must pass valid certificate object."); + gin_helper::ErrorThrower(isolate).ThrowError( + "Must pass valid certificate object."); return; } @@ -548,7 +551,7 @@ void OnIconDataAvailable(gin_helper::Promise promise, } // namespace -App::App(v8::Isolate* isolate) { +App::App() { static_cast(ElectronBrowserClient::Get()) ->set_delegate(this); Browser::Get()->AddObserver(this); @@ -558,7 +561,6 @@ App::App(v8::Isolate* isolate) { content::PROCESS_TYPE_BROWSER, base::GetCurrentProcessHandle(), base::ProcessMetrics::CreateCurrentProcessMetrics()); app_metrics_[pid] = std::move(process_metric); - Init(isolate); } App::~App() { @@ -707,8 +709,9 @@ bool App::CanCreateWindow( bool user_gesture, bool opener_suppressed, bool* no_javascript_access) { - v8::Locker locker(isolate()); - v8::HandleScope handle_scope(isolate()); + v8::Isolate* isolate = JavascriptEnvironment::GetIsolate(); + v8::Locker locker(isolate); + v8::HandleScope handle_scope(isolate); content::WebContents* web_contents = content::WebContents::FromRenderFrameHost(opener); if (web_contents) { @@ -732,11 +735,12 @@ void App::AllowCertificateError( bool strict_enforcement, base::OnceCallback callback) { auto adapted_callback = base::AdaptCallbackForRepeating(std::move(callback)); - v8::Locker locker(isolate()); - v8::HandleScope handle_scope(isolate()); + v8::Isolate* isolate = JavascriptEnvironment::GetIsolate(); + v8::Locker locker(isolate); + v8::HandleScope handle_scope(isolate); bool prevent_default = Emit("certificate-error", - WebContents::FromOrCreate(isolate(), web_contents), request_url, + WebContents::FromOrCreate(isolate, web_contents), request_url, net::ErrorToString(cert_error), ssl_info.cert, adapted_callback); // Deny the certificate by default. @@ -761,11 +765,12 @@ base::OnceClosure App::SelectClientCertificate( auto shared_identities = std::make_shared(std::move(identities)); + v8::Isolate* isolate = JavascriptEnvironment::GetIsolate(); bool prevent_default = Emit("select-client-certificate", - WebContents::FromOrCreate(isolate(), web_contents), + WebContents::FromOrCreate(isolate, web_contents), cert_request_info->host_and_port.ToString(), std::move(client_certs), - base::BindOnce(&OnClientCertificateSelected, isolate(), + base::BindOnce(&OnClientCertificateSelected, isolate, shared_delegate, shared_identities)); // Default to first certificate from the platform store. @@ -816,8 +821,9 @@ void App::BrowserChildProcessKilled( void App::BrowserChildProcessCrashedOrKilled( const content::ChildProcessData& data, const content::ChildProcessTerminationInfo& info) { - v8::HandleScope handle_scope(isolate()); - auto details = gin_helper::Dictionary::CreateEmpty(isolate()); + v8::Isolate* isolate = JavascriptEnvironment::GetIsolate(); + v8::HandleScope handle_scope(isolate); + auto details = gin_helper::Dictionary::CreateEmpty(isolate); details.Set("type", content::GetProcessTypeNameInEnglish(data.process_type)); details.Set("reason", info.status); details.Set("exitCode", info.exit_code); @@ -1049,7 +1055,7 @@ void App::ReleaseSingleInstanceLock() { } } -bool App::Relaunch(gin_helper::Arguments* js_args) { +bool App::Relaunch(gin::Arguments* js_args) { // Parse parameters. bool override_argv = false; base::FilePath exec_path; @@ -1135,8 +1141,7 @@ void App::SetAccessibilitySupportEnabled(gin_helper::ErrorThrower thrower, Browser::Get()->OnAccessibilitySupportChanged(); } -Browser::LoginItemSettings App::GetLoginItemSettings( - gin_helper::Arguments* args) { +Browser::LoginItemSettings App::GetLoginItemSettings(gin::Arguments* args) { Browser::LoginItemSettings options; args->GetNext(&options); return Browser::Get()->GetLoginItemSettings(options); @@ -1190,19 +1195,21 @@ v8::Local App::GetJumpListSettings() { LOG(ERROR) << "Failed to begin Jump List transaction."; } - gin_helper::Dictionary dict = gin::Dictionary::CreateEmpty(isolate()); + v8::Isolate* isolate = JavascriptEnvironment::GetIsolate(); + gin_helper::Dictionary dict = gin::Dictionary::CreateEmpty(isolate); dict.Set("minItems", min_items); - dict.Set("removedItems", gin::ConvertToV8(isolate(), removed_items)); + dict.Set("removedItems", gin::ConvertToV8(isolate, removed_items)); return dict.GetHandle(); } JumpListResult App::SetJumpList(v8::Local val, - gin_helper::Arguments* args) { + gin::Arguments* args) { std::vector categories; bool delete_jump_list = val->IsNull(); if (!delete_jump_list && !gin::ConvertFromV8(args->isolate(), val, &categories)) { - args->ThrowError("Argument must be null or an array of categories"); + gin_helper::ErrorThrower(args->isolate()) + .ThrowError("Argument must be null or an array of categories"); return JumpListResult::ARGUMENT_ERROR; } @@ -1234,8 +1241,9 @@ JumpListResult App::SetJumpList(v8::Local val, #endif // defined(OS_WIN) v8::Local App::GetFileIcon(const base::FilePath& path, - gin_helper::Arguments* args) { - gin_helper::Promise promise(isolate()); + gin::Arguments* args) { + v8::Isolate* isolate = JavascriptEnvironment::GetIsolate(); + gin_helper::Promise promise(isolate); v8::Local handle = promise.GetHandle(); base::FilePath normalized_path = path.NormalizePathSeparators(); @@ -1427,7 +1435,7 @@ bool App::IsInApplicationsFolder() { return ElectronBundleMover::IsCurrentAppInApplicationsFolder(); } -int DockBounce(gin_helper::Arguments* args) { +int DockBounce(gin::Arguments* args) { int request_id = -1; std::string type = "informational"; args->GetNext(&type); @@ -1478,7 +1486,7 @@ v8::Local App::GetDockAPI(v8::Isolate* isolate) { // static App* App::Get() { - static base::NoDestructor app(v8::Isolate::GetCurrent()); + static base::NoDestructor app; return app.get(); } @@ -1487,12 +1495,9 @@ gin::Handle App::Create(v8::Isolate* isolate) { return gin::CreateHandle(isolate, Get()); } -// static -void App::BuildPrototype(v8::Isolate* isolate, - v8::Local prototype) { - prototype->SetClassName(gin::StringToV8(isolate, "App")); +gin::ObjectTemplateBuilder App::GetObjectTemplateBuilder(v8::Isolate* isolate) { auto browser = base::Unretained(Browser::Get()); - gin_helper::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate()) + return gin_helper::EventEmitterMixin::GetObjectTemplateBuilder(isolate) .SetMethod("quit", base::BindRepeating(&Browser::Quit, browser)) .SetMethod("exit", base::BindRepeating(&Browser::Exit, browser)) .SetMethod("focus", base::BindRepeating(&Browser::Focus, browser)) @@ -1622,6 +1627,10 @@ void App::BuildPrototype(v8::Isolate* isolate, &App::SetBrowserClientCanUseCustomSiteInstance); } +const char* App::GetTypeName() { + return "App"; +} + } // namespace api } // namespace electron @@ -1634,9 +1643,6 @@ void Initialize(v8::Local exports, void* priv) { v8::Isolate* isolate = context->GetIsolate(); gin_helper::Dictionary dict(isolate, exports); - dict.Set("App", electron::api::App::GetConstructor(isolate) - ->GetFunction(context) - .ToLocalChecked()); dict.Set("app", electron::api::App::Create(isolate)); } diff --git a/shell/browser/api/electron_api_app.h b/shell/browser/api/electron_api_app.h index 43672d1a3896..7d48e8ca60f8 100644 --- a/shell/browser/api/electron_api_app.h +++ b/shell/browser/api/electron_api_app.h @@ -25,9 +25,9 @@ #include "shell/browser/browser.h" #include "shell/browser/browser_observer.h" #include "shell/browser/electron_browser_client.h" +#include "shell/browser/event_emitter_mixin.h" #include "shell/common/gin_helper/dictionary.h" #include "shell/common/gin_helper/error_thrower.h" -#include "shell/common/gin_helper/event_emitter.h" #include "shell/common/gin_helper/promise.h" #if defined(USE_NSS_CERTS) @@ -47,7 +47,8 @@ enum class JumpListResult : int; namespace api { class App : public ElectronBrowserClient::Delegate, - public gin_helper::EventEmitter, + public gin::Wrappable, + public gin_helper::EventEmitterMixin, public BrowserObserver, public content::GpuDataManagerObserver, public content::BrowserChildProcessObserver { @@ -58,8 +59,11 @@ class App : public ElectronBrowserClient::Delegate, static gin::Handle Create(v8::Isolate* isolate); static App* Get(); - static void BuildPrototype(v8::Isolate* isolate, - v8::Local prototype); + // gin::Wrappable + static gin::WrapperInfo kWrapperInfo; + gin::ObjectTemplateBuilder GetObjectTemplateBuilder( + v8::Isolate* isolate) override; + const char* GetTypeName() override; #if defined(USE_NSS_CERTS) void OnCertificateManagerModelCreated( @@ -72,7 +76,7 @@ class App : public ElectronBrowserClient::Delegate, void RenderProcessReady(content::RenderProcessHost* host); void RenderProcessDisconnected(base::ProcessId host_pid); - explicit App(v8::Isolate* isolate); + App(); private: ~App() override; @@ -185,20 +189,20 @@ class App : public ElectronBrowserClient::Delegate, bool HasSingleInstanceLock() const; bool RequestSingleInstanceLock(); void ReleaseSingleInstanceLock(); - bool Relaunch(gin_helper::Arguments* args); + bool Relaunch(gin::Arguments* args); void DisableHardwareAcceleration(gin_helper::ErrorThrower thrower); void DisableDomainBlockingFor3DAPIs(gin_helper::ErrorThrower thrower); bool IsAccessibilitySupportEnabled(); void SetAccessibilitySupportEnabled(gin_helper::ErrorThrower thrower, bool enabled); - Browser::LoginItemSettings GetLoginItemSettings(gin_helper::Arguments* args); + Browser::LoginItemSettings GetLoginItemSettings(gin::Arguments* args); #if defined(USE_NSS_CERTS) void ImportCertificate(gin_helper::ErrorThrower thrower, base::Value options, net::CompletionOnceCallback callback); #endif v8::Local GetFileIcon(const base::FilePath& path, - gin_helper::Arguments* args); + gin::Arguments* args); std::vector GetAppMetrics(v8::Isolate* isolate); v8::Local GetGPUFeatureStatus(v8::Isolate* isolate); @@ -221,7 +225,7 @@ class App : public ElectronBrowserClient::Delegate, #if defined(MAS_BUILD) base::RepeatingCallback StartAccessingSecurityScopedResource( - gin_helper::Arguments* args); + gin::Arguments* args); #endif #if defined(OS_WIN) @@ -229,8 +233,7 @@ class App : public ElectronBrowserClient::Delegate, v8::Local GetJumpListSettings(); // Set or remove a custom Jump List for the application. - JumpListResult SetJumpList(v8::Local val, - gin_helper::Arguments* args); + JumpListResult SetJumpList(v8::Local val, gin::Arguments* args); #endif // defined(OS_WIN) std::unique_ptr process_singleton_; diff --git a/shell/browser/api/electron_api_app_mas.mm b/shell/browser/api/electron_api_app_mas.mm index e3951ba792eb..a23a4f503d34 100644 --- a/shell/browser/api/electron_api_app_mas.mm +++ b/shell/browser/api/electron_api_app_mas.mm @@ -22,7 +22,7 @@ void OnStopAccessingSecurityScopedResource(NSURL* bookmarkUrl) { // Get base64 encoded NSData, create a bookmark for it and start accessing it. base::RepeatingCallback App::StartAccessingSecurityScopedResource( - gin_helper::Arguments* args) { + gin::Arguments* args) { std::string data; args->GetNext(&data); NSString* base64str = base::SysUTF8ToNSString(data); @@ -42,11 +42,13 @@ base::RepeatingCallback App::StartAccessingSecurityScopedResource( if (error != nil) { NSString* err = [NSString stringWithFormat:@"NSError: %@ %@", error, [error userInfo]]; - args->ThrowError(base::SysNSStringToUTF8(err)); + gin_helper::ErrorThrower(args->isolate()) + .ThrowError(base::SysNSStringToUTF8(err)); } if (isStale) { - args->ThrowError("bookmarkDataIsStale - try recreating the bookmark"); + gin_helper::ErrorThrower(args->isolate()) + .ThrowError("bookmarkDataIsStale - try recreating the bookmark"); } if (error == nil && isStale == false) { diff --git a/shell/browser/browser.cc b/shell/browser/browser.cc index 7ae88312874c..6340f56b52de 100644 --- a/shell/browser/browser.cc +++ b/shell/browser/browser.cc @@ -72,7 +72,7 @@ void Browser::Quit() { electron::WindowList::CloseAllWindows(); } -void Browser::Exit(gin_helper::Arguments* args) { +void Browser::Exit(gin::Arguments* args) { int code = 0; args->GetNext(&code); diff --git a/shell/browser/browser.h b/shell/browser/browser.h index 3a1499295f03..9228700a4ac1 100644 --- a/shell/browser/browser.h +++ b/shell/browser/browser.h @@ -57,13 +57,13 @@ class Browser : public WindowListObserver { void Quit(); // Exit the application immediately and set exit code. - void Exit(gin_helper::Arguments* args); + void Exit(gin::Arguments* args); // Cleanup everything and shutdown the application gracefully. void Shutdown(); // Focus the application. - void Focus(gin_helper::Arguments* args); + void Focus(gin::Arguments* args); // Returns the version of the executable (or bundle). std::string GetVersion() const; @@ -88,15 +88,15 @@ class Browser : public WindowListObserver { // Remove the default protocol handler registry key bool RemoveAsDefaultProtocolClient(const std::string& protocol, - gin_helper::Arguments* args); + gin::Arguments* args); // Set as default handler for a protocol. bool SetAsDefaultProtocolClient(const std::string& protocol, - gin_helper::Arguments* args); + gin::Arguments* args); // Query the current state of default handler for a protocol. bool IsDefaultProtocolClient(const std::string& protocol, - gin_helper::Arguments* args); + gin::Arguments* args); base::string16 GetApplicationNameForProtocol(const GURL& url); @@ -140,7 +140,7 @@ class Browser : public WindowListObserver { // Creates an activity and sets it as the one currently in use. void SetUserActivity(const std::string& type, base::DictionaryValue user_info, - gin_helper::Arguments* args); + gin::Arguments* args); // Returns the type name of the current user activity. std::string GetCurrentActivityType(); diff --git a/shell/browser/browser_linux.cc b/shell/browser/browser_linux.cc index c6029854e395..863f5ddab3c1 100644 --- a/shell/browser/browser_linux.cc +++ b/shell/browser/browser_linux.cc @@ -84,7 +84,7 @@ bool SetDefaultWebClient(const std::string& protocol) { return ran_ok && exit_code == EXIT_SUCCESS; } -void Browser::Focus(gin_helper::Arguments* args) { +void Browser::Focus(gin::Arguments* args) { // Focus on the first visible window. for (auto* const window : WindowList::GetWindows()) { if (window->IsVisible()) { @@ -101,12 +101,12 @@ void Browser::ClearRecentDocuments() {} void Browser::SetAppUserModelID(const base::string16& name) {} bool Browser::SetAsDefaultProtocolClient(const std::string& protocol, - gin_helper::Arguments* args) { + gin::Arguments* args) { return SetDefaultWebClient(protocol); } bool Browser::IsDefaultProtocolClient(const std::string& protocol, - gin_helper::Arguments* args) { + gin::Arguments* args) { std::unique_ptr env(base::Environment::Create()); if (protocol.empty()) @@ -128,7 +128,7 @@ bool Browser::IsDefaultProtocolClient(const std::string& protocol, // Todo implement bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol, - gin_helper::Arguments* args) { + gin::Arguments* args) { return false; } diff --git a/shell/browser/browser_mac.mm b/shell/browser/browser_mac.mm index e0608bb2aca4..346fd0e659d9 100644 --- a/shell/browser/browser_mac.mm +++ b/shell/browser/browser_mac.mm @@ -95,7 +95,7 @@ void Browser::SetShutdownHandler(base::Callback handler) { [[AtomApplication sharedApplication] setShutdownHandler:std::move(handler)]; } -void Browser::Focus(gin_helper::Arguments* args) { +void Browser::Focus(gin::Arguments* args) { gin_helper::Dictionary opts; bool steal_focus = false; @@ -134,7 +134,7 @@ void Browser::ClearRecentDocuments() { } bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol, - gin_helper::Arguments* args) { + gin::Arguments* args) { NSString* identifier = [base::mac::MainBundle() bundleIdentifier]; if (!identifier) return false; @@ -169,7 +169,7 @@ bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol, } bool Browser::SetAsDefaultProtocolClient(const std::string& protocol, - gin_helper::Arguments* args) { + gin::Arguments* args) { if (protocol.empty()) return false; @@ -184,7 +184,7 @@ bool Browser::SetAsDefaultProtocolClient(const std::string& protocol, } bool Browser::IsDefaultProtocolClient(const std::string& protocol, - gin_helper::Arguments* args) { + gin::Arguments* args) { if (protocol.empty()) return false; @@ -226,7 +226,7 @@ bool Browser::SetBadgeCount(int count) { void Browser::SetUserActivity(const std::string& type, base::DictionaryValue user_info, - gin_helper::Arguments* args) { + gin::Arguments* args) { std::string url_string; args->GetNext(&url_string); diff --git a/shell/browser/browser_win.cc b/shell/browser/browser_win.cc index 717ec16b01ca..d790dbde9ef1 100644 --- a/shell/browser/browser_win.cc +++ b/shell/browser/browser_win.cc @@ -4,11 +4,14 @@ #include "shell/browser/browser.h" -#include // windows.h must be included first +// must come before other includes. fixes bad #defines from . +#include "base/win/shlwapi.h" // NOLINT(build/include_order) -#include -#include -#include +#include // NOLINT(build/include_order) + +#include // NOLINT(build/include_order) +#include // NOLINT(build/include_order) +#include // NOLINT(build/include_order) #include "base/base_paths.h" #include "base/file_version_info.h" @@ -61,7 +64,7 @@ bool GetProcessExecPath(base::string16* exe) { return true; } -bool GetProtocolLaunchPath(gin_helper::Arguments* args, base::string16* exe) { +bool GetProtocolLaunchPath(gin::Arguments* args, base::string16* exe) { if (!args->GetNext(exe) && !GetProcessExecPath(exe)) { return false; } @@ -196,7 +199,7 @@ Browser::UserTask::UserTask() = default; Browser::UserTask::UserTask(const UserTask&) = default; Browser::UserTask::~UserTask() = default; -void Browser::Focus(gin_helper::Arguments* args) { +void Browser::Focus(gin::Arguments* args) { // On Windows we just focus on the first window found for this process. DWORD pid = GetCurrentProcessId(); EnumWindows(&WindowsEnumerationHandler, reinterpret_cast(&pid)); @@ -338,7 +341,7 @@ bool Browser::SetUserTasks(const std::vector& tasks) { } bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol, - gin_helper::Arguments* args) { + gin::Arguments* args) { if (protocol.empty()) return false; @@ -400,7 +403,7 @@ bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol, } bool Browser::SetAsDefaultProtocolClient(const std::string& protocol, - gin_helper::Arguments* args) { + gin::Arguments* args) { // HKEY_CLASSES_ROOT // $PROTOCOL // (Default) = "URL:$NAME" @@ -444,7 +447,7 @@ bool Browser::SetAsDefaultProtocolClient(const std::string& protocol, } bool Browser::IsDefaultProtocolClient(const std::string& protocol, - gin_helper::Arguments* args) { + gin::Arguments* args) { if (protocol.empty()) return false;