mirror of
https://github.com/electron/electron.git
synced 2026-02-26 03:01:17 -05:00
Compare commits
1 Commits
nikwen/ext
...
refactor/a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
14fbf5086f |
@@ -1556,19 +1556,6 @@ Enables full sandbox mode on the app. This means that all renderers will be laun
|
|||||||
|
|
||||||
This method can only be called before app is ready.
|
This method can only be called before app is ready.
|
||||||
|
|
||||||
### `app.enableExtensionsOnAllProtocols()`
|
|
||||||
|
|
||||||
Enables Chrome extensions on all protocols.
|
|
||||||
|
|
||||||
By default, Chrome extensions are enabled only for a select number of protocols
|
|
||||||
such as `http`, `https`, and `file`. Calling this function will enable Chrome extensions
|
|
||||||
on all protocols, including [custom protocols](protocol.md).
|
|
||||||
|
|
||||||
This can have security implications. For most apps, it is recommended to enable
|
|
||||||
this during development only and keep it disabled in production builds.
|
|
||||||
|
|
||||||
This method can only be called before app is ready.
|
|
||||||
|
|
||||||
### `app.isInApplicationsFolder()` _macOS_
|
### `app.isInApplicationsFolder()` _macOS_
|
||||||
|
|
||||||
Returns `boolean` - Whether the application is currently running from the
|
Returns `boolean` - Whether the application is currently running from the
|
||||||
|
|||||||
@@ -144,4 +144,3 @@ fix_linux_tray_id.patch
|
|||||||
expose_gtk_ui_platform_field.patch
|
expose_gtk_ui_platform_field.patch
|
||||||
patch_osr_control_screen_info.patch
|
patch_osr_control_screen_info.patch
|
||||||
refactor_allow_customizing_config_in_freedesktopsecretkeyprovider.patch
|
refactor_allow_customizing_config_in_freedesktopsecretkeyprovider.patch
|
||||||
feat_allow_enabling_extensions_on_all_protocols.patch
|
|
||||||
|
|||||||
@@ -1,84 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Niklas Wenzel <dev@nikwen.de>
|
|
||||||
Date: Wed, 25 Feb 2026 16:24:03 +0100
|
|
||||||
Subject: feat: allow enabling extensions on all protocols
|
|
||||||
|
|
||||||
This allows us to use Chrome extensions on custom protocols.
|
|
||||||
|
|
||||||
The patch can't really be upstreamed, unfortunately, because there are
|
|
||||||
other URLPattern functions that we don't patch that Chrome needs.
|
|
||||||
|
|
||||||
Patching those properly would require replacing the bitmap logic in
|
|
||||||
URLPattern with a more flexible solution. This would be a larger effort
|
|
||||||
and Chromium might reject it for performance reasons.
|
|
||||||
|
|
||||||
See: https://source.chromium.org/chromium/chromium/src/+/main:extensions/common/url_pattern.h;l=53-74;drc=50dbcddad2f8e36ddfcec21d4551f389df425c37
|
|
||||||
|
|
||||||
This patch makes it work in the context of Electron.
|
|
||||||
|
|
||||||
diff --git a/extensions/common/url_pattern.cc b/extensions/common/url_pattern.cc
|
|
||||||
index 4054af728030306c5473f9a47e580595596768a0..38c3f5976a122e6e4b7e8512ef977242fa395d8d 100644
|
|
||||||
--- a/extensions/common/url_pattern.cc
|
|
||||||
+++ b/extensions/common/url_pattern.cc
|
|
||||||
@@ -133,6 +133,13 @@ std::string_view CanonicalizeHostForMatching(std::string_view host_piece) {
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
+bool URLPattern::enable_extensions_on_all_protocols_ = false;
|
|
||||||
+
|
|
||||||
+// static
|
|
||||||
+void URLPattern::EnableExtensionsOnAllProtocols() {
|
|
||||||
+ enable_extensions_on_all_protocols_ = true;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
// static
|
|
||||||
bool URLPattern::IsValidSchemeForExtensions(std::string_view scheme) {
|
|
||||||
for (auto* valid_scheme : kValidSchemes) {
|
|
||||||
@@ -140,11 +147,14 @@ bool URLPattern::IsValidSchemeForExtensions(std::string_view scheme) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
- return false;
|
|
||||||
+ return enable_extensions_on_all_protocols_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
int URLPattern::GetValidSchemeMaskForExtensions() {
|
|
||||||
+ if (enable_extensions_on_all_protocols_) {
|
|
||||||
+ return SCHEME_ALL;
|
|
||||||
+ }
|
|
||||||
int result = 0;
|
|
||||||
for (int valid_scheme_mask : kValidSchemeMasks) {
|
|
||||||
result |= valid_scheme_mask;
|
|
||||||
@@ -401,7 +411,7 @@ bool URLPattern::IsValidScheme(std::string_view scheme) const {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- return false;
|
|
||||||
+ return enable_extensions_on_all_protocols_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void URLPattern::SetPath(std::string_view path) {
|
|
||||||
diff --git a/extensions/common/url_pattern.h b/extensions/common/url_pattern.h
|
|
||||||
index 4d09251b0160644d86682ad3db7c41b50f360e6f..78978b82e37e080add6680300d09503acdb663db 100644
|
|
||||||
--- a/extensions/common/url_pattern.h
|
|
||||||
+++ b/extensions/common/url_pattern.h
|
|
||||||
@@ -96,6 +96,8 @@ class URLPattern {
|
|
||||||
// Returns the mask for all schemes considered valid for extensions.
|
|
||||||
static int GetValidSchemeMaskForExtensions();
|
|
||||||
|
|
||||||
+ static void EnableExtensionsOnAllProtocols();
|
|
||||||
+
|
|
||||||
explicit URLPattern(int valid_schemes);
|
|
||||||
|
|
||||||
// Convenience to construct a URLPattern from a string. If the string is not
|
|
||||||
@@ -251,6 +253,9 @@ class URLPattern {
|
|
||||||
// Get an error string for a ParseResult.
|
|
||||||
static const char* GetParseResultString(URLPattern::ParseResult parse_result);
|
|
||||||
|
|
||||||
+ protected:
|
|
||||||
+ static bool enable_extensions_on_all_protocols_;
|
|
||||||
+
|
|
||||||
private:
|
|
||||||
// Returns true if any of the `schemes` items matches our scheme.
|
|
||||||
bool MatchesAnyScheme(const std::vector<std::string>& schemes) const;
|
|
||||||
@@ -1,2 +1 @@
|
|||||||
chore_expose_ui_to_allow_electron_to_set_dock_side.patch
|
chore_expose_ui_to_allow_electron_to_set_dock_side.patch
|
||||||
feat_allow_enabling_extension_panels_on_all_protocols.patch
|
|
||||||
|
|||||||
@@ -1,41 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Niklas Wenzel <dev@nikwen.de>
|
|
||||||
Date: Wed, 25 Feb 2026 16:23:07 +0100
|
|
||||||
Subject: feat: allow enabling extension panels on all protocols
|
|
||||||
|
|
||||||
This allows us to show Chrome extension panels on pages served over
|
|
||||||
custom protocols.
|
|
||||||
|
|
||||||
diff --git a/front_end/core/root/Runtime.ts b/front_end/core/root/Runtime.ts
|
|
||||||
index 19824217973f002a52478c7fa63a3faa217b0c63..6406fff61691fab0d2a8cc5344aaee743937c84e 100644
|
|
||||||
--- a/front_end/core/root/Runtime.ts
|
|
||||||
+++ b/front_end/core/root/Runtime.ts
|
|
||||||
@@ -639,6 +639,7 @@ export type HostConfig = Platform.TypeScriptUtilities.RecursivePartial<{
|
|
||||||
* or guest mode, rather than a "normal" profile.
|
|
||||||
*/
|
|
||||||
isOffTheRecord: boolean,
|
|
||||||
+ devToolsExtensionsOnAllProtocols: boolean,
|
|
||||||
devToolsEnableOriginBoundCookies: HostConfigEnableOriginBoundCookies,
|
|
||||||
devToolsAnimationStylesInStylesTab: HostConfigAnimationStylesInStylesTab,
|
|
||||||
thirdPartyCookieControls: HostConfigThirdPartyCookieControls,
|
|
||||||
diff --git a/front_end/panels/common/ExtensionServer.ts b/front_end/panels/common/ExtensionServer.ts
|
|
||||||
index 0a5ec620b135b128013d6ddbb5299f9a5813f122..1a6118b4fa1607a634720b5579a50d1b4478b60a 100644
|
|
||||||
--- a/front_end/panels/common/ExtensionServer.ts
|
|
||||||
+++ b/front_end/panels/common/ExtensionServer.ts
|
|
||||||
@@ -12,6 +12,7 @@ import * as Host from '../../core/host/host.js';
|
|
||||||
import * as i18n from '../../core/i18n/i18n.js';
|
|
||||||
import * as Platform from '../../core/platform/platform.js';
|
|
||||||
import * as _ProtocolClient from '../../core/protocol_client/protocol_client.js'; // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
||||||
+import * as Root from '../../core/root/root.js';
|
|
||||||
import * as SDK from '../../core/sdk/sdk.js';
|
|
||||||
import type * as Protocol from '../../generated/protocol.js';
|
|
||||||
import * as Bindings from '../../models/bindings/bindings.js';
|
|
||||||
@@ -1607,7 +1608,7 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (!kPermittedSchemes.includes(parsedURL.protocol)) {
|
|
||||||
+ if (!Root.Runtime.hostConfig.devToolsExtensionsOnAllProtocols && !kPermittedSchemes.includes(parsedURL.protocol)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -86,10 +86,6 @@
|
|||||||
#include "v8/include/cppgc/allocation.h"
|
#include "v8/include/cppgc/allocation.h"
|
||||||
#include "v8/include/v8-traced-handle.h"
|
#include "v8/include/v8-traced-handle.h"
|
||||||
|
|
||||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
|
||||||
#include "extensions/common/url_pattern.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BUILDFLAG(IS_WIN)
|
#if BUILDFLAG(IS_WIN)
|
||||||
#include "base/strings/utf_string_conversions.h"
|
#include "base/strings/utf_string_conversions.h"
|
||||||
#include "shell/browser/notifications/win/windows_toast_activator.h"
|
#include "shell/browser/notifications/win/windows_toast_activator.h"
|
||||||
@@ -1550,28 +1546,6 @@ void App::EnableSandbox(gin_helper::ErrorThrower thrower) {
|
|||||||
command_line->AppendSwitch(switches::kEnableSandbox);
|
command_line->AppendSwitch(switches::kEnableSandbox);
|
||||||
}
|
}
|
||||||
|
|
||||||
void App::EnableExtensionsOnAllProtocols(gin_helper::ErrorThrower thrower) {
|
|
||||||
if (Browser::Get()->is_ready()) {
|
|
||||||
thrower.ThrowError(
|
|
||||||
"app.enableExtensionsOnAllProtocols() can only be called "
|
|
||||||
"before app is ready");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
|
||||||
enable_extensions_on_all_protocols_ = true;
|
|
||||||
URLPattern::EnableExtensionsOnAllProtocols();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
bool App::AreExtensionsEnabledOnAllProtocols() const {
|
|
||||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
|
||||||
return enable_extensions_on_all_protocols_;
|
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
v8::Local<v8::Promise> App::SetProxy(gin::Arguments* args) {
|
v8::Local<v8::Promise> App::SetProxy(gin::Arguments* args) {
|
||||||
v8::Isolate* isolate = args->isolate();
|
v8::Isolate* isolate = args->isolate();
|
||||||
gin_helper::Promise<void> promise(isolate);
|
gin_helper::Promise<void> promise(isolate);
|
||||||
@@ -1975,8 +1949,6 @@ gin::ObjectTemplateBuilder App::GetObjectTemplateBuilder(v8::Isolate* isolate) {
|
|||||||
&App::IsHardwareAccelerationEnabled)
|
&App::IsHardwareAccelerationEnabled)
|
||||||
.SetMethod("disableDomainBlockingFor3DAPIs",
|
.SetMethod("disableDomainBlockingFor3DAPIs",
|
||||||
&App::DisableDomainBlockingFor3DAPIs)
|
&App::DisableDomainBlockingFor3DAPIs)
|
||||||
.SetMethod("enableExtensionsOnAllProtocols",
|
|
||||||
&App::EnableExtensionsOnAllProtocols)
|
|
||||||
.SetMethod("getFileIcon", &App::GetFileIcon)
|
.SetMethod("getFileIcon", &App::GetFileIcon)
|
||||||
.SetMethod("getAppMetrics", &App::GetAppMetrics)
|
.SetMethod("getAppMetrics", &App::GetAppMetrics)
|
||||||
.SetMethod("getGPUFeatureStatus", &App::GetGPUFeatureStatus)
|
.SetMethod("getGPUFeatureStatus", &App::GetGPUFeatureStatus)
|
||||||
|
|||||||
@@ -89,8 +89,6 @@ class App final : public gin::Wrappable<App>,
|
|||||||
|
|
||||||
static bool IsPackaged();
|
static bool IsPackaged();
|
||||||
|
|
||||||
bool AreExtensionsEnabledOnAllProtocols() const;
|
|
||||||
|
|
||||||
App();
|
App();
|
||||||
~App() override;
|
~App() override;
|
||||||
|
|
||||||
@@ -238,7 +236,6 @@ class App final : public gin::Wrappable<App>,
|
|||||||
v8::Local<v8::Promise> GetGPUInfo(v8::Isolate* isolate,
|
v8::Local<v8::Promise> GetGPUInfo(v8::Isolate* isolate,
|
||||||
const std::string& info_type);
|
const std::string& info_type);
|
||||||
void EnableSandbox(gin_helper::ErrorThrower thrower);
|
void EnableSandbox(gin_helper::ErrorThrower thrower);
|
||||||
void EnableExtensionsOnAllProtocols(gin_helper::ErrorThrower thrower);
|
|
||||||
void SetUserAgentFallback(const std::string& user_agent);
|
void SetUserAgentFallback(const std::string& user_agent);
|
||||||
std::string GetUserAgentFallback();
|
std::string GetUserAgentFallback();
|
||||||
v8::Local<v8::Promise> SetProxy(gin::Arguments* args);
|
v8::Local<v8::Promise> SetProxy(gin::Arguments* args);
|
||||||
@@ -296,10 +293,6 @@ class App final : public gin::Wrappable<App>,
|
|||||||
bool disable_domain_blocking_for_3DAPIs_ = false;
|
bool disable_domain_blocking_for_3DAPIs_ = false;
|
||||||
bool watch_singleton_socket_on_ready_ = false;
|
bool watch_singleton_socket_on_ready_ = false;
|
||||||
|
|
||||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
|
||||||
bool enable_extensions_on_all_protocols_ = false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
std::unique_ptr<content::ScopedAccessibilityMode> scoped_accessibility_mode_;
|
std::unique_ptr<content::ScopedAccessibilityMode> scoped_accessibility_mode_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "base/environment.h"
|
#include "base/environment.h"
|
||||||
#include "base/functional/bind.h"
|
#include "base/functional/bind.h"
|
||||||
#include "base/logging.h"
|
#include "base/logging.h"
|
||||||
|
#include "base/strings/string_number_conversions.h"
|
||||||
#include "base/strings/utf_string_conversions.h"
|
#include "base/strings/utf_string_conversions.h"
|
||||||
#include "base/task/single_thread_task_runner.h"
|
#include "base/task/single_thread_task_runner.h"
|
||||||
#include "content/public/browser/browser_task_traits.h"
|
#include "content/public/browser/browser_task_traits.h"
|
||||||
@@ -279,7 +280,8 @@ void OnDeploymentCompleted(std::unique_ptr<DeploymentCallbackData> data,
|
|||||||
HRESULT error_code;
|
HRESULT error_code;
|
||||||
hr = async_info->get_ErrorCode(&error_code);
|
hr = async_info->get_ErrorCode(&error_code);
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
error += " (" + std::to_string(static_cast<int>(error_code)) + ")";
|
error +=
|
||||||
|
" (" + base::NumberToString(static_cast<int>(error_code)) + ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -798,10 +800,10 @@ v8::Local<v8::Value> GetPackageInfo() {
|
|||||||
ABI::Windows::ApplicationModel::PackageVersion pkg_version;
|
ABI::Windows::ApplicationModel::PackageVersion pkg_version;
|
||||||
hr = package_id->get_Version(&pkg_version);
|
hr = package_id->get_Version(&pkg_version);
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
std::string version = std::to_string(pkg_version.Major) + "." +
|
std::string version = base::NumberToString(pkg_version.Major) + "." +
|
||||||
std::to_string(pkg_version.Minor) + "." +
|
base::NumberToString(pkg_version.Minor) + "." +
|
||||||
std::to_string(pkg_version.Build) + "." +
|
base::NumberToString(pkg_version.Build) + "." +
|
||||||
std::to_string(pkg_version.Revision);
|
base::NumberToString(pkg_version.Revision);
|
||||||
result.Set("version", version);
|
result.Set("version", version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#include "base/json/json_reader.h"
|
#include "base/json/json_reader.h"
|
||||||
#include "base/no_destructor.h"
|
#include "base/no_destructor.h"
|
||||||
#include "base/strings/strcat.h"
|
#include "base/strings/strcat.h"
|
||||||
|
#include "base/strings/string_number_conversions.h"
|
||||||
#include "base/strings/utf_string_conversions.h"
|
#include "base/strings/utf_string_conversions.h"
|
||||||
#include "base/task/current_thread.h"
|
#include "base/task/current_thread.h"
|
||||||
#include "base/threading/scoped_blocking_call.h"
|
#include "base/threading/scoped_blocking_call.h"
|
||||||
@@ -2659,7 +2660,7 @@ void WebContents::RestoreHistory(
|
|||||||
thrower.ThrowError(
|
thrower.ThrowError(
|
||||||
"Failed to restore navigation history: Invalid navigation entry at "
|
"Failed to restore navigation history: Invalid navigation entry at "
|
||||||
"index " +
|
"index " +
|
||||||
std::to_string(index) + ".");
|
base::NumberToString(index) + ".");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -617,12 +617,6 @@ void ElectronBrowserClient::AppendExtraCommandLineSwitches(
|
|||||||
command_line->AppendSwitch(switches::kServiceWorkerPreload);
|
command_line->AppendSwitch(switches::kServiceWorkerPreload);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
|
||||||
if (api::App::Get()->AreExtensionsEnabledOnAllProtocols()) {
|
|
||||||
command_line->AppendSwitch(switches::kEnableExtensionsOnAllProtocols);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,6 @@
|
|||||||
#include "services/network/public/cpp/simple_url_loader_stream_consumer.h"
|
#include "services/network/public/cpp/simple_url_loader_stream_consumer.h"
|
||||||
#include "services/network/public/cpp/wrapper_shared_url_loader_factory.h"
|
#include "services/network/public/cpp/wrapper_shared_url_loader_factory.h"
|
||||||
#include "services/network/public/mojom/url_response_head.mojom.h"
|
#include "services/network/public/mojom/url_response_head.mojom.h"
|
||||||
#include "shell/browser/api/electron_api_app.h"
|
|
||||||
#include "shell/browser/api/electron_api_web_contents.h"
|
#include "shell/browser/api/electron_api_web_contents.h"
|
||||||
#include "shell/browser/native_window_views.h"
|
#include "shell/browser/native_window_views.h"
|
||||||
#include "shell/browser/net/asar/asar_url_loader_factory.h"
|
#include "shell/browser/net/asar/asar_url_loader_factory.h"
|
||||||
@@ -866,8 +865,6 @@ void InspectableWebContents::GetSyncInformation(DispatchCallback callback) {
|
|||||||
|
|
||||||
void InspectableWebContents::GetHostConfig(DispatchCallback callback) {
|
void InspectableWebContents::GetHostConfig(DispatchCallback callback) {
|
||||||
base::DictValue response_dict;
|
base::DictValue response_dict;
|
||||||
response_dict.Set("devToolsExtensionsOnAllProtocols",
|
|
||||||
api::App::Get()->AreExtensionsEnabledOnAllProtocols());
|
|
||||||
base::Value response = base::Value(std::move(response_dict));
|
base::Value response = base::Value(std::move(response_dict));
|
||||||
std::move(callback).Run(&response);
|
std::move(callback).Run(&response);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
#include "base/environment.h"
|
#include "base/environment.h"
|
||||||
#include "base/path_service.h"
|
#include "base/path_service.h"
|
||||||
#include "base/run_loop.h"
|
#include "base/run_loop.h"
|
||||||
|
#include "base/strings/string_number_conversions.h"
|
||||||
#include "base/strings/string_split.h"
|
#include "base/strings/string_split.h"
|
||||||
#include "base/strings/utf_string_conversions.h"
|
#include "base/strings/utf_string_conversions.h"
|
||||||
#include "base/task/single_thread_task_runner.h"
|
#include "base/task/single_thread_task_runner.h"
|
||||||
@@ -192,7 +193,7 @@ void V8OOMErrorCallback(const char* location, const v8::OOMDetails& details) {
|
|||||||
|
|
||||||
#if !IS_MAS_BUILD()
|
#if !IS_MAS_BUILD()
|
||||||
electron::crash_keys::SetCrashKey("electron.v8-oom.is_heap_oom",
|
electron::crash_keys::SetCrashKey("electron.v8-oom.is_heap_oom",
|
||||||
std::to_string(details.is_heap_oom));
|
base::NumberToString(details.is_heap_oom));
|
||||||
if (location) {
|
if (location) {
|
||||||
electron::crash_keys::SetCrashKey("electron.v8-oom.location", location);
|
electron::crash_keys::SetCrashKey("electron.v8-oom.location", location);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
|
||||||
#include "base/strings/cstring_view.h"
|
#include "base/strings/cstring_view.h"
|
||||||
#include "electron/buildflags/buildflags.h"
|
|
||||||
|
|
||||||
namespace electron {
|
namespace electron {
|
||||||
|
|
||||||
@@ -271,12 +270,6 @@ inline constexpr base::cstring_view kStreamingSchemes = "streaming-schemes";
|
|||||||
// Register schemes as supporting V8 code cache.
|
// Register schemes as supporting V8 code cache.
|
||||||
inline constexpr base::cstring_view kCodeCacheSchemes = "code-cache-schemes";
|
inline constexpr base::cstring_view kCodeCacheSchemes = "code-cache-schemes";
|
||||||
|
|
||||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
|
||||||
// Enable Chrome extensions on all protocols.
|
|
||||||
inline constexpr base::cstring_view kEnableExtensionsOnAllProtocols =
|
|
||||||
"enable-extensions-on-all-protocols";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// The browser process app model ID
|
// The browser process app model ID
|
||||||
inline constexpr base::cstring_view kAppUserModelId = "app-user-model-id";
|
inline constexpr base::cstring_view kAppUserModelId = "app-user-model-id";
|
||||||
|
|
||||||
|
|||||||
@@ -162,11 +162,6 @@ RendererClientBase::RendererClientBase() {
|
|||||||
ParseSchemesCLISwitch(command_line, switches::kSecureSchemes);
|
ParseSchemesCLISwitch(command_line, switches::kSecureSchemes);
|
||||||
for (const std::string& scheme : secure_schemes_list)
|
for (const std::string& scheme : secure_schemes_list)
|
||||||
url::AddSecureScheme(scheme.data());
|
url::AddSecureScheme(scheme.data());
|
||||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
|
||||||
// Parse --enable-extensions-on-all-protocols
|
|
||||||
if (command_line->HasSwitch(switches::kEnableExtensionsOnAllProtocols))
|
|
||||||
URLPattern::EnableExtensionsOnAllProtocols();
|
|
||||||
#endif
|
|
||||||
// We rely on the unique process host id which is notified to the
|
// We rely on the unique process host id which is notified to the
|
||||||
// renderer process via command line switch from the content layer,
|
// renderer process via command line switch from the content layer,
|
||||||
// if this switch is removed from the content layer for some reason,
|
// if this switch is removed from the content layer for some reason,
|
||||||
|
|||||||
@@ -1765,15 +1765,6 @@ describe('app module', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('enableExtensionsOnAllProtocols() API', () => {
|
|
||||||
// Proper tests are in extensions-spec.ts
|
|
||||||
it('throws when called after app is ready', () => {
|
|
||||||
expect(() => {
|
|
||||||
app.enableExtensionsOnAllProtocols();
|
|
||||||
}).to.throw(/before app is ready/);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('disableDomainBlockingFor3DAPIs() API', () => {
|
describe('disableDomainBlockingFor3DAPIs() API', () => {
|
||||||
it('throws when called after app is ready', () => {
|
it('throws when called after app is ready', () => {
|
||||||
expect(() => {
|
expect(() => {
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import { app, session, webFrameMain, BrowserWindow, ipcMain, WebContents, Extens
|
|||||||
import { expect } from 'chai';
|
import { expect } from 'chai';
|
||||||
import * as WebSocket from 'ws';
|
import * as WebSocket from 'ws';
|
||||||
|
|
||||||
import { spawn } from 'node:child_process';
|
|
||||||
import { once } from 'node:events';
|
import { once } from 'node:events';
|
||||||
import * as fs from 'node:fs/promises';
|
import * as fs from 'node:fs/promises';
|
||||||
import * as http from 'node:http';
|
import * as http from 'node:http';
|
||||||
@@ -1339,26 +1338,4 @@ describe('chrome extensions', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('custom protocol', () => {
|
|
||||||
async function runFixture (name: string) {
|
|
||||||
const appProcess = spawn(process.execPath, [(path.join(fixtures, 'extensions', name, 'main.js'))]);
|
|
||||||
|
|
||||||
let output = '';
|
|
||||||
appProcess.stdout.on('data', (data) => { output += data; });
|
|
||||||
await once(appProcess.stdout, 'end');
|
|
||||||
|
|
||||||
return output.trim();
|
|
||||||
};
|
|
||||||
|
|
||||||
it('loads DevTools extensions on custom protocols with app.enableExtensionsOnAllProtocols() and runs content and background scripts', async () => {
|
|
||||||
const output = await runFixture('custom-protocol');
|
|
||||||
expect(output).to.equal('Title: MESSAGE RECEIVED');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('loads DevTools panels on custom protocols with app.enableExtensionsOnAllProtocols()', async () => {
|
|
||||||
const output = await runFixture('custom-protocol-panel');
|
|
||||||
expect(output).to.equal('ELECTRON TEST PANEL created');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<script src="devtools.js"></script>
|
|
||||||
</head>
|
|
||||||
</html>
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
/* global chrome */
|
|
||||||
chrome.devtools.panels.create('ELECTRON TEST PANEL', '', 'panel.html');
|
|
||||||
|
|
||||||
console.log('ELECTRON TEST PANEL created');
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "custom-protocol-panel",
|
|
||||||
"version": "1.0",
|
|
||||||
"devtools_page": "devtools.html",
|
|
||||||
"manifest_version": 3
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<body>
|
|
||||||
DevTools panel
|
|
||||||
</body>
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
const { app, BrowserWindow, protocol, session } = require('electron/main');
|
|
||||||
|
|
||||||
const { once } = require('node:events');
|
|
||||||
const path = require('node:path');
|
|
||||||
|
|
||||||
const html = '<html><body><h1>EMPTY PAGE</h1></body></html>';
|
|
||||||
const scheme = 'custom';
|
|
||||||
|
|
||||||
protocol.registerSchemesAsPrivileged([
|
|
||||||
{
|
|
||||||
scheme,
|
|
||||||
privileges: {
|
|
||||||
standard: true,
|
|
||||||
secure: true,
|
|
||||||
allowServiceWorkers: true,
|
|
||||||
supportFetchAPI: true,
|
|
||||||
bypassCSP: false,
|
|
||||||
corsEnabled: true,
|
|
||||||
stream: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
|
|
||||||
app.enableExtensionsOnAllProtocols();
|
|
||||||
|
|
||||||
app.whenReady().then(async () => {
|
|
||||||
const ses = session.defaultSession;
|
|
||||||
|
|
||||||
ses.protocol.handle(scheme, () => new Response(html, {
|
|
||||||
headers: { 'Content-Type': 'text/html' }
|
|
||||||
}));
|
|
||||||
|
|
||||||
await ses.extensions.loadExtension(path.join(__dirname, 'extension'));
|
|
||||||
|
|
||||||
const win = new BrowserWindow();
|
|
||||||
|
|
||||||
win.webContents.openDevTools();
|
|
||||||
await once(win.webContents, 'devtools-opened');
|
|
||||||
|
|
||||||
win.devToolsWebContents.on('console-message', ({ message }) => {
|
|
||||||
if (message === 'ELECTRON TEST PANEL created') {
|
|
||||||
console.log(message);
|
|
||||||
app.quit();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
await win.loadURL(`${scheme}://app/`);
|
|
||||||
});
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
/* global chrome */
|
|
||||||
chrome.runtime.onMessage.addListener((_message, sender, reply) => {
|
|
||||||
reply({
|
|
||||||
text: 'MESSAGE RECEIVED',
|
|
||||||
senderTabId: sender.tab && sender.tab.id
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
/* global chrome */
|
|
||||||
chrome.runtime.sendMessage({ text: 'hello from content script' }, (response) => {
|
|
||||||
if (!response || !response.text) return;
|
|
||||||
document.title = response.text;
|
|
||||||
});
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "custom-protocol",
|
|
||||||
"version": "1.0",
|
|
||||||
"background": {
|
|
||||||
"service_worker": "background.js"
|
|
||||||
},
|
|
||||||
"content_scripts": [
|
|
||||||
{
|
|
||||||
"matches": ["<all_urls>"],
|
|
||||||
"js": ["content_script.js"],
|
|
||||||
"run_at": "document_start"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"manifest_version": 3
|
|
||||||
}
|
|
||||||
42
spec/fixtures/extensions/custom-protocol/main.js
vendored
42
spec/fixtures/extensions/custom-protocol/main.js
vendored
@@ -1,42 +0,0 @@
|
|||||||
const { app, BrowserWindow, protocol, session } = require('electron/main');
|
|
||||||
|
|
||||||
const path = require('node:path');
|
|
||||||
|
|
||||||
const html = '<html><body><h1>EMPTY PAGE</h1></body></html>';
|
|
||||||
const scheme = 'example';
|
|
||||||
|
|
||||||
protocol.registerSchemesAsPrivileged([
|
|
||||||
{
|
|
||||||
scheme,
|
|
||||||
privileges: {
|
|
||||||
standard: true,
|
|
||||||
secure: true,
|
|
||||||
allowServiceWorkers: true,
|
|
||||||
supportFetchAPI: true,
|
|
||||||
bypassCSP: false,
|
|
||||||
corsEnabled: true,
|
|
||||||
stream: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
|
|
||||||
app.enableExtensionsOnAllProtocols();
|
|
||||||
|
|
||||||
app.whenReady().then(async () => {
|
|
||||||
const ses = session.defaultSession;
|
|
||||||
|
|
||||||
ses.protocol.handle(scheme, () => new Response(html, {
|
|
||||||
headers: { 'Content-Type': 'text/html' }
|
|
||||||
}));
|
|
||||||
|
|
||||||
await ses.extensions.loadExtension(path.join(__dirname, 'extension'));
|
|
||||||
|
|
||||||
const win = new BrowserWindow();
|
|
||||||
|
|
||||||
win.on('page-title-updated', (_event, title) => {
|
|
||||||
console.log(`Title: ${title}`);
|
|
||||||
app.quit();
|
|
||||||
});
|
|
||||||
|
|
||||||
await win.loadURL(`${scheme}://app/`);
|
|
||||||
});
|
|
||||||
Reference in New Issue
Block a user