mirror of
https://github.com/electron/electron.git
synced 2026-04-10 03:01:51 -04:00
Compare commits
15 Commits
v42.0.0-al
...
cherry-pic
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7e3d9430d6 | ||
|
|
e1e3ecee75 | ||
|
|
d1b34d76a8 | ||
|
|
d456259da4 | ||
|
|
e21a1b8cd1 | ||
|
|
7f8e35c8c8 | ||
|
|
2da7d8dadb | ||
|
|
d2e0d19985 | ||
|
|
d074963b30 | ||
|
|
ef7f35e15c | ||
|
|
5559ffa184 | ||
|
|
4ede07538d | ||
|
|
b310e26059 | ||
|
|
ad4dc5045f | ||
|
|
a45f5dbcba |
3
.github/actions/build-electron/action.yml
vendored
3
.github/actions/build-electron/action.yml
vendored
@@ -128,6 +128,9 @@ runs:
|
||||
fi
|
||||
sed $SEDOPTION '/.*builtins-pgo/d' out/Default/mksnapshot_args
|
||||
sed $SEDOPTION '/--turbo-profiling-input/d' out/Default/mksnapshot_args
|
||||
sed $SEDOPTION '/--reorder-builtins/d' out/Default/mksnapshot_args
|
||||
sed $SEDOPTION '/--warn-about-builtin-profile-data/d' out/Default/mksnapshot_args
|
||||
sed $SEDOPTION '/--abort-on-bad-builtin-profile-data/d' out/Default/mksnapshot_args
|
||||
|
||||
if [ "${{ inputs.target-platform }}" = "win" ]; then
|
||||
cd out/Default
|
||||
|
||||
@@ -24,7 +24,7 @@ runs:
|
||||
# The cache will always exist here as a result of the checkout job
|
||||
# Either it was uploaded to Azure in the checkout job for this commit
|
||||
# or it was uploaded in the checkout job for a previous commit.
|
||||
uses: nick-fields/retry@7152eba30c6575329ac0576536151aca5a72780e # v3.0.0
|
||||
uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0
|
||||
with:
|
||||
timeout_minutes: 30
|
||||
max_attempts: 3
|
||||
@@ -101,7 +101,7 @@ runs:
|
||||
|
||||
- name: Move Src Cache (Windows)
|
||||
if: ${{ inputs.target-platform == 'win' }}
|
||||
uses: nick-fields/retry@7152eba30c6575329ac0576536151aca5a72780e # v3.0.0
|
||||
uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0
|
||||
with:
|
||||
timeout_minutes: 30
|
||||
max_attempts: 3
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -42,6 +42,7 @@ spec/.hash
|
||||
|
||||
# Generated native addon files
|
||||
/spec/fixtures/native-addon/echo/build/
|
||||
/spec/fixtures/native-addon/dialog-helper/build/
|
||||
|
||||
# If someone runs tsc this is where stuff will end up
|
||||
ts-gen
|
||||
|
||||
4
DEPS
4
DEPS
@@ -2,9 +2,9 @@ gclient_gn_args_from = 'src'
|
||||
|
||||
vars = {
|
||||
'chromium_version':
|
||||
'148.0.7741.0',
|
||||
'148.0.7751.0',
|
||||
'node_version':
|
||||
'v24.14.0',
|
||||
'v24.14.1',
|
||||
'nan_version':
|
||||
'675cefebca42410733da8a454c8d9391fcebfbc2',
|
||||
'squirrel.mac_version':
|
||||
|
||||
@@ -51,9 +51,6 @@ is_cfi = false
|
||||
use_qt5 = false
|
||||
use_qt6 = false
|
||||
|
||||
# Disables the builtins PGO for V8
|
||||
v8_builtins_profiling_log_file = ""
|
||||
|
||||
# https://chromium.googlesource.com/chromium/src/+/main/docs/dangling_ptr.md
|
||||
# TODO(vertedinde): hunt down dangling pointers on Linux
|
||||
enable_dangling_raw_ptr_checks = false
|
||||
|
||||
@@ -86,12 +86,12 @@ app.whenReady().then(() => {
|
||||
* `body` string (optional) - The body text of the notification, which will be displayed below the title or subtitle.
|
||||
* `silent` boolean (optional) - Whether or not to suppress the OS notification noise when showing the notification.
|
||||
* `icon` (string | [NativeImage](native-image.md)) (optional) - An icon to use in the notification. If a string is passed, it must be a valid path to a local icon file.
|
||||
* `hasReply` boolean (optional) _macOS_ - Whether or not to add an inline reply option to the notification.
|
||||
* `hasReply` boolean (optional) _macOS_ _Windows_ - Whether or not to add an inline reply option to the notification.
|
||||
* `timeoutType` string (optional) _Linux_ _Windows_ - The timeout duration of the notification. Can be 'default' or 'never'.
|
||||
* `replyPlaceholder` string (optional) _macOS_ - The placeholder to write in the inline reply input field.
|
||||
* `replyPlaceholder` string (optional) _macOS_ _Windows_ - The placeholder to write in the inline reply input field.
|
||||
* `sound` string (optional) _macOS_ - The name of the sound file to play when the notification is shown.
|
||||
* `urgency` string (optional) _Linux_ _Windows_ - The urgency level of the notification. Can be 'normal', 'critical', or 'low'.
|
||||
* `actions` [NotificationAction[]](structures/notification-action.md) (optional) _macOS_ - Actions to add to the notification. Please read the available actions and limitations in the `NotificationAction` documentation.
|
||||
* `actions` [NotificationAction[]](structures/notification-action.md) (optional) _macOS_ _Windows_ - Actions to add to the notification. Please read the available actions and limitations in the `NotificationAction` documentation.
|
||||
* `closeButtonText` string (optional) _macOS_ - A custom title for the close button of an alert. An empty string will cause the default localized text to be used.
|
||||
* `toastXml` string (optional) _Windows_ - A custom description of the Notification on Windows superseding all properties above. Provides full customization of design and behavior of the notification.
|
||||
|
||||
|
||||
@@ -56,6 +56,15 @@ app.whenReady().then(() => {
|
||||
})
|
||||
```
|
||||
|
||||
## Protocol names
|
||||
|
||||
[RFC 3986](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) defines what a valid
|
||||
protocol name is:
|
||||
|
||||
> Scheme names consist of a sequence of characters beginning with a letter and followed
|
||||
> by any combination of letters, digits, plus ("+"), period ("."), or hyphen ("-").
|
||||
> Although schemes are case-insensitive, the canonical form is lowercase […].
|
||||
|
||||
## Methods
|
||||
|
||||
The `protocol` module has the following methods:
|
||||
|
||||
@@ -147,3 +147,4 @@ fix_pass_trigger_for_global_shortcuts_on_wayland.patch
|
||||
feat_plumb_node_integration_in_worker_through_workersettings.patch
|
||||
fix_restore_sdk_inputs_cross-toolchain_deps_for_macos.patch
|
||||
fix_fire_menu_popup_start_for_dynamically_created_aria_menus.patch
|
||||
cherry-pick-d8b01057f740.patch
|
||||
|
||||
@@ -23,10 +23,10 @@ index 8077ed85e45e56d6cccb691223216c1f6a94b5ee..dd4cee346f16df703d414bf206bbe6c9
|
||||
int32_t world_id) {}
|
||||
virtual void DidClearWindowObject() {}
|
||||
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
|
||||
index 42a0a7e5be01fe346cc2ad83d3395425a41e1699..40d1f104794795dba6cd59518819e98a4cdbfc44 100644
|
||||
index 280091edd7aa92c3cbc9e4b442cba91cb5bd2aa4..92272d5177cc47839169066b860577194cbc5d47 100644
|
||||
--- a/content/renderer/render_frame_impl.cc
|
||||
+++ b/content/renderer/render_frame_impl.cc
|
||||
@@ -4769,6 +4769,12 @@ void RenderFrameImpl::DidCreateScriptContext(v8::Local<v8::Context> context,
|
||||
@@ -4744,6 +4744,12 @@ void RenderFrameImpl::DidCreateScriptContext(v8::Local<v8::Context> context,
|
||||
observer.DidCreateScriptContext(context, world_id);
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ index 42a0a7e5be01fe346cc2ad83d3395425a41e1699..40d1f104794795dba6cd59518819e98a
|
||||
int world_id) {
|
||||
for (auto& observer : observers_)
|
||||
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
|
||||
index c803bf1d93bb9aabf0f9098c4d58aa7528d18d79..ced097d57cec93b3d3062a6d7d9f7d037a355e6c 100644
|
||||
index 8bdb45a481f16096fa0509570872745531495eb3..0062c466fbe4c625669d3a334fc9b9d8c49837f2 100644
|
||||
--- a/content/renderer/render_frame_impl.h
|
||||
+++ b/content/renderer/render_frame_impl.h
|
||||
@@ -606,6 +606,8 @@ class CONTENT_EXPORT RenderFrameImpl
|
||||
|
||||
@@ -8,10 +8,10 @@ was removed as part of the Raw Clipboard API scrubbing.
|
||||
https://bugs.chromium.org/p/chromium/issues/detail?id=1217643
|
||||
|
||||
diff --git a/ui/base/clipboard/scoped_clipboard_writer.cc b/ui/base/clipboard/scoped_clipboard_writer.cc
|
||||
index 503225a84c1fe3835e97d8cc521f661339de105e..9949bd699ccca7fef8750816663fd66701b08d69 100644
|
||||
index 12695bb8f3d2cc3f498e5c6e37e4729d9586962f..6bd7b6f2908d3c8316191e3106e50b2137068a0f 100644
|
||||
--- a/ui/base/clipboard/scoped_clipboard_writer.cc
|
||||
+++ b/ui/base/clipboard/scoped_clipboard_writer.cc
|
||||
@@ -240,6 +240,16 @@ void ScopedClipboardWriter::WriteData(std::u16string_view format,
|
||||
@@ -239,6 +239,16 @@ void ScopedClipboardWriter::WriteData(std::u16string_view format,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ index 503225a84c1fe3835e97d8cc521f661339de105e..9949bd699ccca7fef8750816663fd667
|
||||
objects_.clear();
|
||||
raw_objects_.clear();
|
||||
diff --git a/ui/base/clipboard/scoped_clipboard_writer.h b/ui/base/clipboard/scoped_clipboard_writer.h
|
||||
index 8c2be540757856a3e704764fe56003205b24812f..e31fbc01f68c0e92284a72298cac878d7247e7fb 100644
|
||||
index 7d7d015f9725ef39b7d5e82b83ac5195e2cfe309..83565b6d73cbe30e3c24913468862173cfd3a83e 100644
|
||||
--- a/ui/base/clipboard/scoped_clipboard_writer.h
|
||||
+++ b/ui/base/clipboard/scoped_clipboard_writer.h
|
||||
@@ -91,6 +91,10 @@ class COMPONENT_EXPORT(UI_BASE_CLIPBOARD) ScopedClipboardWriter {
|
||||
|
||||
@@ -10,7 +10,7 @@ usage of BrowserList and Browser as we subclass related methods and use our
|
||||
WindowList.
|
||||
|
||||
diff --git a/chrome/browser/ui/webui/accessibility/accessibility_ui.cc b/chrome/browser/ui/webui/accessibility/accessibility_ui.cc
|
||||
index 9b22efa07e43b60a8bd8bb6288792846709fae87..cf60a541720ffbcdaa5163d727a7761dcb30f131 100644
|
||||
index 1322a7c5f9b3baca837488de2e5323ee5c49800c..cb1895f2be25d210f7508433a352bc1e93369f4a 100644
|
||||
--- a/chrome/browser/ui/webui/accessibility/accessibility_ui.cc
|
||||
+++ b/chrome/browser/ui/webui/accessibility/accessibility_ui.cc
|
||||
@@ -48,6 +48,7 @@
|
||||
@@ -64,7 +64,7 @@ index 9b22efa07e43b60a8bd8bb6288792846709fae87..cf60a541720ffbcdaa5163d727a7761d
|
||||
data.Set(kBrowsersField, std::move(browser_list));
|
||||
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
@@ -847,7 +848,8 @@ void AccessibilityUIMessageHandler::SetGlobalString(
|
||||
@@ -870,7 +871,8 @@ void AccessibilityUIMessageHandler::HandleSetGlobalString(
|
||||
const std::string value = CheckJSValue(data.FindString(kValueField));
|
||||
|
||||
if (string_name == kApiTypeField) {
|
||||
@@ -74,7 +74,7 @@ index 9b22efa07e43b60a8bd8bb6288792846709fae87..cf60a541720ffbcdaa5163d727a7761d
|
||||
pref->SetString(prefs::kShownAccessibilityApiType, value);
|
||||
}
|
||||
}
|
||||
@@ -901,7 +903,8 @@ void AccessibilityUIMessageHandler::RequestWebContentsTree(
|
||||
@@ -924,7 +926,8 @@ void AccessibilityUIMessageHandler::HandleRequestWebContentsTree(
|
||||
AXPropertyFilter::ALLOW_EMPTY);
|
||||
AddPropertyFilters(property_filters, deny, AXPropertyFilter::DENY);
|
||||
|
||||
@@ -84,7 +84,7 @@ index 9b22efa07e43b60a8bd8bb6288792846709fae87..cf60a541720ffbcdaa5163d727a7761d
|
||||
ui::AXApiType::Type api_type =
|
||||
ui::AXApiType::From(pref->GetString(prefs::kShownAccessibilityApiType));
|
||||
std::string accessibility_contents =
|
||||
@@ -921,7 +924,7 @@ void AccessibilityUIMessageHandler::RequestNativeUITree(
|
||||
@@ -944,7 +947,7 @@ void AccessibilityUIMessageHandler::HandleRequestNativeUITree(
|
||||
|
||||
AllowJavascript();
|
||||
|
||||
@@ -93,7 +93,7 @@ index 9b22efa07e43b60a8bd8bb6288792846709fae87..cf60a541720ffbcdaa5163d727a7761d
|
||||
std::vector<AXPropertyFilter> property_filters;
|
||||
AddPropertyFilters(property_filters, allow, AXPropertyFilter::ALLOW);
|
||||
AddPropertyFilters(property_filters, allow_empty,
|
||||
@@ -948,7 +951,7 @@ void AccessibilityUIMessageHandler::RequestNativeUITree(
|
||||
@@ -971,7 +974,7 @@ void AccessibilityUIMessageHandler::HandleRequestNativeUITree(
|
||||
if (found) {
|
||||
return;
|
||||
}
|
||||
@@ -102,7 +102,7 @@ index 9b22efa07e43b60a8bd8bb6288792846709fae87..cf60a541720ffbcdaa5163d727a7761d
|
||||
// No browser with the specified |session_id| was found.
|
||||
base::DictValue result;
|
||||
result.Set(kSessionIdField, session_id);
|
||||
@@ -991,11 +994,13 @@ void AccessibilityUIMessageHandler::StopRecording(
|
||||
@@ -1014,11 +1017,13 @@ void AccessibilityUIMessageHandler::StopRecording(
|
||||
}
|
||||
|
||||
ui::AXApiType::Type AccessibilityUIMessageHandler::GetRecordingApiType() {
|
||||
@@ -119,7 +119,7 @@ index 9b22efa07e43b60a8bd8bb6288792846709fae87..cf60a541720ffbcdaa5163d727a7761d
|
||||
// Check to see if it is in the supported types list.
|
||||
if (std::find(supported_types.begin(), supported_types.end(), api_type) ==
|
||||
supported_types.end()) {
|
||||
@@ -1065,10 +1070,13 @@ void AccessibilityUIMessageHandler::RequestAccessibilityEvents(
|
||||
@@ -1088,10 +1093,13 @@ void AccessibilityUIMessageHandler::HandleRequestAccessibilityEvents(
|
||||
// static
|
||||
void AccessibilityUIMessageHandler::RegisterProfilePrefs(
|
||||
user_prefs::PrefRegistrySyncable* registry) {
|
||||
@@ -134,7 +134,7 @@ index 9b22efa07e43b60a8bd8bb6288792846709fae87..cf60a541720ffbcdaa5163d727a7761d
|
||||
|
||||
void AccessibilityUIMessageHandler::OnVisibilityChanged(
|
||||
diff --git a/chrome/browser/ui/webui/accessibility/accessibility_ui.h b/chrome/browser/ui/webui/accessibility/accessibility_ui.h
|
||||
index 67f7e34271994ff66da2a3c3b90c2f02797c2d14..8f786bc00dc4a7cc775ca3ff3fca4da680272682 100644
|
||||
index 184a10239d7072572a043f2b4e29bcdb5344f3ec..77d3ca336eaa28b7c476861c8d4a43e45804ac7a 100644
|
||||
--- a/chrome/browser/ui/webui/accessibility/accessibility_ui.h
|
||||
+++ b/chrome/browser/ui/webui/accessibility/accessibility_ui.h
|
||||
@@ -28,6 +28,8 @@ namespace content {
|
||||
@@ -146,12 +146,12 @@ index 67f7e34271994ff66da2a3c3b90c2f02797c2d14..8f786bc00dc4a7cc775ca3ff3fca4da6
|
||||
namespace user_prefs {
|
||||
class PrefRegistrySyncable;
|
||||
} // namespace user_prefs
|
||||
@@ -79,6 +81,8 @@ class AccessibilityUIMessageHandler : public content::WebUIMessageHandler,
|
||||
@@ -81,6 +83,8 @@ class AccessibilityUIMessageHandler : public content::WebUIMessageHandler,
|
||||
static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
|
||||
|
||||
private:
|
||||
+ friend class ElectronAccessibilityUIMessageHandler;
|
||||
+
|
||||
void ToggleAccessibilityForWebContents(const base::ListValue& args);
|
||||
void SetGlobalFlag(const base::ListValue& args);
|
||||
void SetGlobalString(const base::ListValue& args);
|
||||
void HandleInitialize(const base::ListValue& args);
|
||||
void HandleToggleAccessibilityForWebContents(const base::ListValue& args);
|
||||
void HandleSetGlobalFlag(const base::ListValue& args);
|
||||
|
||||
@@ -6,7 +6,7 @@ Subject: allow disabling blink scheduler throttling per RenderView
|
||||
This allows us to disable throttling for hidden windows.
|
||||
|
||||
diff --git a/content/browser/renderer_host/navigation_controller_impl_unittest.cc b/content/browser/renderer_host/navigation_controller_impl_unittest.cc
|
||||
index c33775220e161d38e41efe8fea897815737341f8..e9636b69a8eb748aaa493466c3190ec602e16449 100644
|
||||
index 29d5b174e122cbd140554687548106ead8f8e8d9..da74da96c3fe35a0f3838f04bca08846f7b41abe 100644
|
||||
--- a/content/browser/renderer_host/navigation_controller_impl_unittest.cc
|
||||
+++ b/content/browser/renderer_host/navigation_controller_impl_unittest.cc
|
||||
@@ -168,6 +168,12 @@ class MockPageBroadcast : public blink::mojom::PageBroadcast {
|
||||
|
||||
@@ -49,7 +49,7 @@ index 901b727ed898cdd840df5ff7e2380fbee5d7fde2..1caacaeed9ddf1162cfa393fe4a7c86a
|
||||
// its owning reference back to our owning LocalFrame.
|
||||
client_->Detached(type);
|
||||
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc
|
||||
index 8d1aa4435bb815b2e8d4b2e14f60e7e11a29ae7d..34603bffa39cf2aaedfd7c3152464c524995f6f0 100644
|
||||
index b31df93f2210e7030be73b4ee87463bd6318eb7c..daf04130625fda5b6779126e9a63d9f4854a8555 100644
|
||||
--- a/third_party/blink/renderer/core/frame/local_frame.cc
|
||||
+++ b/third_party/blink/renderer/core/frame/local_frame.cc
|
||||
@@ -758,10 +758,6 @@ bool LocalFrame::DetachImpl(FrameDetachType type) {
|
||||
|
||||
@@ -11,7 +11,7 @@ if we ever align our .pak file generation with Chrome we can remove this
|
||||
patch.
|
||||
|
||||
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn
|
||||
index 74aadd24a27d31291bb42d452ff247bbf6dad14a..a0d74156745c0d22a332b2547c59b98d1ae8a7c5 100644
|
||||
index e30ea563d0d74d6dfb198b19edf9ef1c086d10f8..ee0cfd7476700622f445f287dd23f42d48553797 100644
|
||||
--- a/chrome/BUILD.gn
|
||||
+++ b/chrome/BUILD.gn
|
||||
@@ -201,11 +201,16 @@ if (!is_android && !is_mac) {
|
||||
@@ -33,10 +33,10 @@ index 74aadd24a27d31291bb42d452ff247bbf6dad14a..a0d74156745c0d22a332b2547c59b98d
|
||||
"//base",
|
||||
"//build:branding_buildflags",
|
||||
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
|
||||
index f195e70c33b1a88e44f8ad51be6573d609d91b7f..a9195e0149385e7ffc95eb809bc30256683861d7 100644
|
||||
index 26181ca1d4df95d67e625c8043c148579b5acc7c..ac1d5d4f3618057335fff5fe11418f7b84786775 100644
|
||||
--- a/chrome/browser/BUILD.gn
|
||||
+++ b/chrome/browser/BUILD.gn
|
||||
@@ -4532,7 +4532,7 @@ static_library("browser") {
|
||||
@@ -4507,7 +4507,7 @@ static_library("browser") {
|
||||
]
|
||||
}
|
||||
|
||||
@@ -46,10 +46,10 @@ index f195e70c33b1a88e44f8ad51be6573d609d91b7f..a9195e0149385e7ffc95eb809bc30256
|
||||
# than here in :chrome_dll.
|
||||
deps += [ "//chrome:packed_resources_integrity_header" ]
|
||||
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
|
||||
index cf7e31b7b1b8eab0e82a669902dc37020f74195a..dfeb9048a85ab2076259c01687d30c2c7f36d8b0 100644
|
||||
index e627fc93f01fcf5598aa594f18cf6efa03c96268..2723bbe8b197d611f5224505e13adf375c19392f 100644
|
||||
--- a/chrome/test/BUILD.gn
|
||||
+++ b/chrome/test/BUILD.gn
|
||||
@@ -7770,9 +7770,12 @@ test("unit_tests") {
|
||||
@@ -7733,9 +7733,12 @@ test("unit_tests") {
|
||||
"//chrome/notification_helper",
|
||||
]
|
||||
|
||||
@@ -63,7 +63,7 @@ index cf7e31b7b1b8eab0e82a669902dc37020f74195a..dfeb9048a85ab2076259c01687d30c2c
|
||||
"//chrome//services/util_win:unit_tests",
|
||||
"//chrome/app:chrome_dll_resources",
|
||||
"//chrome/app:win_unit_tests",
|
||||
@@ -8771,6 +8774,10 @@ test("unit_tests") {
|
||||
@@ -8734,6 +8737,10 @@ test("unit_tests") {
|
||||
"../browser/performance_manager/policies/background_tab_loading_policy_unittest.cc",
|
||||
]
|
||||
|
||||
@@ -74,7 +74,7 @@ index cf7e31b7b1b8eab0e82a669902dc37020f74195a..dfeb9048a85ab2076259c01687d30c2c
|
||||
sources += [
|
||||
# The importer code is not used on Android.
|
||||
"../common/importer/firefox_importer_utils_unittest.cc",
|
||||
@@ -8828,7 +8835,6 @@ test("unit_tests") {
|
||||
@@ -8791,7 +8798,6 @@ test("unit_tests") {
|
||||
# TODO(crbug.com/417513088): Maybe merge with the non-android `deps` declaration above?
|
||||
deps += [
|
||||
"../browser/screen_ai:screen_ai_install_state",
|
||||
|
||||
@@ -9,10 +9,10 @@ potentially prevent a window from being created.
|
||||
TODO(loc): this patch is currently broken.
|
||||
|
||||
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
index 4e7b516f145312e353f112499b2792b27207d84b..222cf1b2bbc98aa5e271426478a774f8a48e693d 100644
|
||||
index 44493867e40e08f2136c5d3fe116a1e8d313e091..4530ef9ccef717342bc71e37f7a6005b8184b645 100644
|
||||
--- a/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
@@ -10125,6 +10125,7 @@ void RenderFrameHostImpl::CreateNewWindow(
|
||||
@@ -10126,6 +10126,7 @@ void RenderFrameHostImpl::CreateNewWindow(
|
||||
last_committed_origin_, params->window_container_type,
|
||||
params->target_url, params->referrer.To<Referrer>(),
|
||||
params->frame_name, params->disposition, *params->features,
|
||||
@@ -21,10 +21,10 @@ index 4e7b516f145312e353f112499b2792b27207d84b..222cf1b2bbc98aa5e271426478a774f8
|
||||
&no_javascript_access);
|
||||
|
||||
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
|
||||
index b0f3579f18f3b6dd5a9b328324348770319ccf67..1567ac2a65d222080430a47dce97b6d387ebe49d 100644
|
||||
index 96d5fbb522045a9d1c1d22ab2b625801206dd9a6..daab93ed099913477d94c7790325a0aea2f3c75f 100644
|
||||
--- a/content/browser/web_contents/web_contents_impl.cc
|
||||
+++ b/content/browser/web_contents/web_contents_impl.cc
|
||||
@@ -5385,6 +5385,10 @@ FrameTree* WebContentsImpl::CreateNewWindow(
|
||||
@@ -5487,6 +5487,10 @@ FrameTree* WebContentsImpl::CreateNewWindow(
|
||||
create_params.initially_hidden = renderer_started_hidden;
|
||||
create_params.initial_popup_url = params.target_url;
|
||||
|
||||
@@ -35,7 +35,7 @@ index b0f3579f18f3b6dd5a9b328324348770319ccf67..1567ac2a65d222080430a47dce97b6d3
|
||||
// Even though all codepaths leading here are in response to a renderer
|
||||
// trying to open a new window, if the new window ends up in a different
|
||||
// browsing instance, then the RenderViewHost, RenderWidgetHost,
|
||||
@@ -5439,6 +5443,12 @@ FrameTree* WebContentsImpl::CreateNewWindow(
|
||||
@@ -5541,6 +5545,12 @@ FrameTree* WebContentsImpl::CreateNewWindow(
|
||||
// Sets the newly created WebContents WindowOpenDisposition.
|
||||
new_contents_impl->original_window_open_disposition_ = params.disposition;
|
||||
|
||||
@@ -48,7 +48,7 @@ index b0f3579f18f3b6dd5a9b328324348770319ccf67..1567ac2a65d222080430a47dce97b6d3
|
||||
// If the new frame has a name, make sure any SiteInstances that can find
|
||||
// this named frame have proxies for it. Must be called after
|
||||
// SetSessionStorageNamespace, since this calls CreateRenderView, which uses
|
||||
@@ -5480,12 +5490,6 @@ FrameTree* WebContentsImpl::CreateNewWindow(
|
||||
@@ -5582,12 +5592,6 @@ FrameTree* WebContentsImpl::CreateNewWindow(
|
||||
AddWebContentsDestructionObserver(new_contents_impl);
|
||||
}
|
||||
|
||||
@@ -62,10 +62,10 @@ index b0f3579f18f3b6dd5a9b328324348770319ccf67..1567ac2a65d222080430a47dce97b6d3
|
||||
new_contents_impl, opener, params.target_url,
|
||||
params.referrer.To<Referrer>(), params.disposition,
|
||||
diff --git a/content/common/frame.mojom b/content/common/frame.mojom
|
||||
index 19dbb921c9644522588ff74d0a1925f826736957..4e7b36729741a79cfdf04f89a8ec615d3148b294 100644
|
||||
index 444fa7009d0db33470cac9ab9cfdc23ceacec942..ab9aeb852e5ea89583284386d9a78a3e3e17a310 100644
|
||||
--- a/content/common/frame.mojom
|
||||
+++ b/content/common/frame.mojom
|
||||
@@ -658,6 +658,10 @@ struct CreateNewWindowParams {
|
||||
@@ -617,6 +617,10 @@ struct CreateNewWindowParams {
|
||||
pending_associated_remote<blink.mojom.Widget> widget;
|
||||
pending_associated_receiver<blink.mojom.FrameWidgetHost> frame_widget_host;
|
||||
pending_associated_remote<blink.mojom.FrameWidget> frame_widget;
|
||||
@@ -77,10 +77,10 @@ index 19dbb921c9644522588ff74d0a1925f826736957..4e7b36729741a79cfdf04f89a8ec615d
|
||||
|
||||
// Operation result when the renderer asks the browser to create a new window.
|
||||
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc
|
||||
index d2dccc29b0e13ab5c87b4c6803e79dc781e52ea2..be6639ef1a7eebb147afee483a35898d1ea5d95f 100644
|
||||
index 0ecf7b395a1f270397c25a116d28a4d9cb05fa84..bc437d5f7d14d2d5df13595f78e0fc145285bdbc 100644
|
||||
--- a/content/public/browser/content_browser_client.cc
|
||||
+++ b/content/public/browser/content_browser_client.cc
|
||||
@@ -877,6 +877,8 @@ bool ContentBrowserClient::CanCreateWindow(
|
||||
@@ -882,6 +882,8 @@ bool ContentBrowserClient::CanCreateWindow(
|
||||
const std::string& frame_name,
|
||||
WindowOpenDisposition disposition,
|
||||
const blink::mojom::WindowFeatures& features,
|
||||
@@ -90,7 +90,7 @@ index d2dccc29b0e13ab5c87b4c6803e79dc781e52ea2..be6639ef1a7eebb147afee483a35898d
|
||||
bool opener_suppressed,
|
||||
bool* no_javascript_access) {
|
||||
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
|
||||
index 3b6c42b2c4cd5d9e5753af25b27925ff0d933568..e6f51d39b4f2f6b162814996921958ca1252e1d7 100644
|
||||
index 486b5f0e6c0969df5373666c257c36dcdc19f96b..11eece7441d775490c4149e607b1812e917a1b00 100644
|
||||
--- a/content/public/browser/content_browser_client.h
|
||||
+++ b/content/public/browser/content_browser_client.h
|
||||
@@ -205,6 +205,7 @@ class NetworkService;
|
||||
@@ -101,7 +101,7 @@ index 3b6c42b2c4cd5d9e5753af25b27925ff0d933568..e6f51d39b4f2f6b162814996921958ca
|
||||
} // namespace network
|
||||
|
||||
namespace sandbox {
|
||||
@@ -1468,6 +1469,8 @@ class CONTENT_EXPORT ContentBrowserClient {
|
||||
@@ -1471,6 +1472,8 @@ class CONTENT_EXPORT ContentBrowserClient {
|
||||
const std::string& frame_name,
|
||||
WindowOpenDisposition disposition,
|
||||
const blink::mojom::WindowFeatures& features,
|
||||
@@ -170,10 +170,10 @@ index 0650197909d484b8a0f48ab61b22471c71bce0e8..29c380d7845aab1a7b3417e0d3940ea0
|
||||
// typically happens when popups are created.
|
||||
virtual void WebContentsCreated(WebContents* source_contents,
|
||||
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
|
||||
index 6ee766c52202804adc532b1585224b4e35239f9a..42a0a7e5be01fe346cc2ad83d3395425a41e1699 100644
|
||||
index aaa66a747228097e971587f14b453f4ea4f49f7c..280091edd7aa92c3cbc9e4b442cba91cb5bd2aa4 100644
|
||||
--- a/content/renderer/render_frame_impl.cc
|
||||
+++ b/content/renderer/render_frame_impl.cc
|
||||
@@ -6879,6 +6879,10 @@ WebView* RenderFrameImpl::CreateNewWindow(
|
||||
@@ -6854,6 +6854,10 @@ WebView* RenderFrameImpl::CreateNewWindow(
|
||||
params->started_by_ad =
|
||||
GetWebFrame()->IsAdFrame() || GetWebFrame()->IsAdScriptInStack();
|
||||
|
||||
@@ -224,10 +224,10 @@ index d92bab531c12c62a5321a23f4a0cb89691668127..2060e04795ba8e7a923fd0fe3485b8c5
|
||||
|
||||
} // namespace blink
|
||||
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.cc b/third_party/blink/renderer/core/frame/local_dom_window.cc
|
||||
index 715ca6e188c7e821478fcbaa4496efd25a673c61..e58465eb936b2a8b3479201ec24580501f7fc2f3 100644
|
||||
index 87856b74d5e0a323b8527d783316d1aab1cf9b1e..9f0d95954ed3d7c7e3ac4825f31ee55255e0c46f 100644
|
||||
--- a/third_party/blink/renderer/core/frame/local_dom_window.cc
|
||||
+++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
|
||||
@@ -2341,6 +2341,8 @@ DOMWindow* LocalDOMWindow::open(v8::Isolate* isolate,
|
||||
@@ -2366,6 +2366,8 @@ DOMWindow* LocalDOMWindow::open(v8::Isolate* isolate,
|
||||
WebWindowFeatures window_features =
|
||||
GetWindowFeaturesFromString(features, entered_window);
|
||||
|
||||
|
||||
73
patches/chromium/cherry-pick-d8b01057f740.patch
Normal file
73
patches/chromium/cherry-pick-d8b01057f740.patch
Normal file
@@ -0,0 +1,73 @@
|
||||
From d8b01057f740d3bb0ec880b34372da63147c2521 Mon Sep 17 00:00:00 2001
|
||||
From: Steinar H. Gunderson <sesse@chromium.org>
|
||||
Date: Fri, 20 Mar 2026 07:22:02 -0700
|
||||
Subject: [PATCH] Fix another use-after-free with lazy style attributes.
|
||||
|
||||
This is a similar problem as regular attribute checks, just for
|
||||
the special case of input type="" (which is a similar but separate
|
||||
path).
|
||||
|
||||
Style perftest and Speedometer3 are neutral.
|
||||
|
||||
Fixed: 493952652
|
||||
Change-Id: I264503545c345325e6d21afa0726f524bb9394b8
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7686835
|
||||
Reviewed-by: Anders Hartvoll Ruud <andruud@chromium.org>
|
||||
Commit-Queue: Steinar H Gunderson <sesse@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1602570}
|
||||
---
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/css/element_rule_collector.cc b/third_party/blink/renderer/core/css/element_rule_collector.cc
|
||||
index 901a258..64198a33 100644
|
||||
--- a/third_party/blink/renderer/core/css/element_rule_collector.cc
|
||||
+++ b/third_party/blink/renderer/core/css/element_rule_collector.cc
|
||||
@@ -957,11 +957,14 @@
|
||||
if (const AtomicString& input_type =
|
||||
element.getAttribute(html_names::kTypeAttr);
|
||||
!input_type.IsNull()) {
|
||||
+ // Do not use input_type in the loop; the reference
|
||||
+ // may be dangling if CollectMatchingRulesForList()
|
||||
+ // adds lazy attributes.
|
||||
+ AtomicString input_type_lower = input_type.ToAsciiLower();
|
||||
for (const auto bundle : match_request.RuleSetsWithInputRules()) {
|
||||
if (CollectMatchingRulesForList<stop_at_first_match>(
|
||||
- bundle.rule_set->InputRules(input_type.ToAsciiLower()),
|
||||
- match_request, bundle.rule_set, bundle.style_sheet_index,
|
||||
- checker, context) &&
|
||||
+ bundle.rule_set->InputRules(input_type_lower), match_request,
|
||||
+ bundle.rule_set, bundle.style_sheet_index, checker, context) &&
|
||||
stop_at_first_match) {
|
||||
return true;
|
||||
}
|
||||
diff --git a/third_party/blink/web_tests/external/wpt/css/css-values/crashtests/chrome-bug-493952652.html b/third_party/blink/web_tests/external/wpt/css/css-values/crashtests/chrome-bug-493952652.html
|
||||
new file mode 100644
|
||||
index 0000000..a9c96ec5
|
||||
--- /dev/null
|
||||
+++ b/third_party/blink/web_tests/external/wpt/css/css-values/crashtests/chrome-bug-493952652.html
|
||||
@@ -0,0 +1,26 @@
|
||||
+<!DOCTYPE html>
|
||||
+<head>
|
||||
+ <link rel="help" href="https://crbug.com/493952652">
|
||||
+ <style>
|
||||
+ /*
|
||||
+ Evaluation of [style] will add a new attribute to the element,
|
||||
+ as lazy style gets synchronized. However, the bucketing will be
|
||||
+ on input type, so we do not synchronize the attributes _before_
|
||||
+ iteration.
|
||||
+ */
|
||||
+ input[style][type="text"] {}
|
||||
+ </style>
|
||||
+ <style>
|
||||
+ /*
|
||||
+ For the second stylesheet, when checking the type="" value string,
|
||||
+ we must not use a reference into the old attributes.
|
||||
+ */
|
||||
+ input[style][type="text"] {}
|
||||
+ </style>
|
||||
+</head>
|
||||
+<body>
|
||||
+ <input id="target" type="text"></input>
|
||||
+ <script>
|
||||
+ document.getElementById('target').style.color = 'red';
|
||||
+ </script>
|
||||
+</body>
|
||||
@@ -34,10 +34,10 @@ index dd4cee346f16df703d414bf206bbe6c9f4b1f796..5565f5a9259bd7da0722080bf01b3415
|
||||
virtual void DidClearWindowObject() {}
|
||||
virtual void DidChangeScrollOffset() {}
|
||||
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
|
||||
index 40d1f104794795dba6cd59518819e98a4cdbfc44..8352f70c6c11af2890a03a2fae1729d27fc8da1f 100644
|
||||
index 92272d5177cc47839169066b860577194cbc5d47..776e097dda38e920430ea49b15069dd908c6268e 100644
|
||||
--- a/content/renderer/render_frame_impl.cc
|
||||
+++ b/content/renderer/render_frame_impl.cc
|
||||
@@ -4775,10 +4775,11 @@ void RenderFrameImpl::DidInstallConditionalFeatures(
|
||||
@@ -4750,10 +4750,11 @@ void RenderFrameImpl::DidInstallConditionalFeatures(
|
||||
observer.DidInstallConditionalFeatures(context, world_id);
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ index 40d1f104794795dba6cd59518819e98a4cdbfc44..8352f70c6c11af2890a03a2fae1729d2
|
||||
|
||||
void RenderFrameImpl::DidChangeScrollOffset() {
|
||||
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
|
||||
index ced097d57cec93b3d3062a6d7d9f7d037a355e6c..c08b9323175e5ec62203fa74d93a307aa35f3616 100644
|
||||
index 0062c466fbe4c625669d3a334fc9b9d8c49837f2..e4939464a5bc4908fe83799c1920b8f294b4de84 100644
|
||||
--- a/content/renderer/render_frame_impl.h
|
||||
+++ b/content/renderer/render_frame_impl.h
|
||||
@@ -608,7 +608,8 @@ class CONTENT_EXPORT RenderFrameImpl
|
||||
|
||||
@@ -14,10 +14,10 @@ track down the source of this problem & figure out if we can fix it
|
||||
by changing something in Electron.
|
||||
|
||||
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
|
||||
index b3215ec81f8d750cfaa9b66a4880c6a90a6e183d..2d993b4265f6be26da1f0bc98520eec3fe393645 100644
|
||||
index 6838e858c78b1c12d352860186ee2a75bbed2ad8..e770df76c913bfb126d8e9ecd2eb8548b9bfb2f9 100644
|
||||
--- a/content/browser/web_contents/web_contents_impl.cc
|
||||
+++ b/content/browser/web_contents/web_contents_impl.cc
|
||||
@@ -5356,7 +5356,7 @@ FrameTree* WebContentsImpl::CreateNewWindow(
|
||||
@@ -5458,7 +5458,7 @@ FrameTree* WebContentsImpl::CreateNewWindow(
|
||||
: IsGuest();
|
||||
// While some guest types do not have a guest SiteInstance, the ones that
|
||||
// don't all override WebContents creation above.
|
||||
|
||||
@@ -80,10 +80,10 @@ index 39fa45f0a0f9076bd7ac0be6f455dd540a276512..3d0381d463eed73470b28085830f2a23
|
||||
content::WebContents* source,
|
||||
const content::OpenURLParams& params,
|
||||
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc
|
||||
index 8899a3216052582e35c5c046e1e0baee48052452..461cb574dc1083fae0bc96e53ed94ba117f7691d 100644
|
||||
index e7fe85a1eae545b1bdcfd81d23ec607a42f3941a..d33125fb7e76b15d68d3c88be319f5ca93f82163 100644
|
||||
--- a/chrome/browser/ui/browser.cc
|
||||
+++ b/chrome/browser/ui/browser.cc
|
||||
@@ -2288,7 +2288,8 @@ bool Browser::IsWebContentsCreationOverridden(
|
||||
@@ -2292,7 +2292,8 @@ bool Browser::IsWebContentsCreationOverridden(
|
||||
content::mojom::WindowContainerType window_container_type,
|
||||
const GURL& opener_url,
|
||||
const std::string& frame_name,
|
||||
@@ -93,7 +93,7 @@ index 8899a3216052582e35c5c046e1e0baee48052452..461cb574dc1083fae0bc96e53ed94ba1
|
||||
if (HasActorTaskPreventingNewWebContents(profile(), opener)) {
|
||||
// If an ExecutionEngine is acting on the opener, prevent it from creating a
|
||||
// new WebContents. We'll instead force the navigation to happen in the same
|
||||
@@ -2301,7 +2302,7 @@ bool Browser::IsWebContentsCreationOverridden(
|
||||
@@ -2305,7 +2306,7 @@ bool Browser::IsWebContentsCreationOverridden(
|
||||
return (window_container_type ==
|
||||
content::mojom::WindowContainerType::BACKGROUND &&
|
||||
ShouldCreateBackgroundContents(source_site_instance, opener_url,
|
||||
@@ -103,10 +103,10 @@ index 8899a3216052582e35c5c046e1e0baee48052452..461cb574dc1083fae0bc96e53ed94ba1
|
||||
|
||||
WebContents* Browser::CreateCustomWebContents(
|
||||
diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h
|
||||
index e92caadbec713996d7eb0af9e59ed4a3f14ea148..fe904aaa2ee0f94d3ff34174bac82464dfded91a 100644
|
||||
index b78f6ff36aaf1f541fedb8e2cb652f69227c506e..a8c426b0c1099822e9f2396981bf347d9318c451 100644
|
||||
--- a/chrome/browser/ui/browser.h
|
||||
+++ b/chrome/browser/ui/browser.h
|
||||
@@ -916,8 +916,7 @@ class Browser : public TabStripModelObserver,
|
||||
@@ -917,8 +917,7 @@ class Browser : public TabStripModelObserver,
|
||||
content::SiteInstance* source_site_instance,
|
||||
content::mojom::WindowContainerType window_container_type,
|
||||
const GURL& opener_url,
|
||||
@@ -223,10 +223,10 @@ index b969f1d97b7e3396119b579cfbe61e19ff7d2dd4..b8d6169652da28266a514938b45b39c5
|
||||
content::WebContents* AddNewContents(
|
||||
content::WebContents* source,
|
||||
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
|
||||
index f605f46115cda0f8f06e5274a26e3b997ca4c62e..16c4c2f73643314a9b8287e13a6472dff2671652 100644
|
||||
index 2dfacb13990561632441ccc9d0ae3006693b67e2..bef008a5233d7e941d88d5353ce8940df5a17b84 100644
|
||||
--- a/content/browser/web_contents/web_contents_impl.cc
|
||||
+++ b/content/browser/web_contents/web_contents_impl.cc
|
||||
@@ -5320,8 +5320,7 @@ FrameTree* WebContentsImpl::CreateNewWindow(
|
||||
@@ -5422,8 +5422,7 @@ FrameTree* WebContentsImpl::CreateNewWindow(
|
||||
if (delegate_ &&
|
||||
delegate_->IsWebContentsCreationOverridden(
|
||||
opener, source_site_instance, params.window_container_type,
|
||||
|
||||
@@ -8,10 +8,10 @@ Allow registering custom protocols to handle service worker main script fetching
|
||||
Refs https://bugs.chromium.org/p/chromium/issues/detail?id=996511
|
||||
|
||||
diff --git a/content/browser/service_worker/service_worker_context_wrapper.cc b/content/browser/service_worker/service_worker_context_wrapper.cc
|
||||
index fdfa916eac0b6dd3f0fd09f284245f0ceb1b176e..26400bf6d5e0f48d649a31a27e33c8bc812990a6 100644
|
||||
index 701ce5df52e77f9277b5d548b82eef3120435bf2..0974935ea7a72ade31270c10abfee1be92a3dcb9 100644
|
||||
--- a/content/browser/service_worker/service_worker_context_wrapper.cc
|
||||
+++ b/content/browser/service_worker/service_worker_context_wrapper.cc
|
||||
@@ -1958,6 +1958,25 @@ ServiceWorkerContextWrapper::GetLoaderFactoryForBrowserInitiatedRequest(
|
||||
@@ -1954,6 +1954,25 @@ ServiceWorkerContextWrapper::GetLoaderFactoryForBrowserInitiatedRequest(
|
||||
loader_factory_bundle_info =
|
||||
context()->loader_factory_bundle_for_update_check()->Clone();
|
||||
|
||||
|
||||
@@ -33,10 +33,10 @@ index 0ab8187b0db8ae6db46d81738f653a2bc4c566f6..de3d55e85c22317f7f9375eb94d0d5d4
|
||||
|
||||
} // namespace net
|
||||
diff --git a/services/network/network_context.cc b/services/network/network_context.cc
|
||||
index 1fcf11cf90206270c6b0131b687ae668a8a12f83..af072c92721215d3306c165fb571710c91933829 100644
|
||||
index 9b7b17abed8d2220065e7b6130c77196f88dc825..b9aa61748c31d0e25a5d4ebc2f319a65ca1b30c0 100644
|
||||
--- a/services/network/network_context.cc
|
||||
+++ b/services/network/network_context.cc
|
||||
@@ -1923,6 +1923,13 @@ void NetworkContext::SetNetworkConditions(
|
||||
@@ -1931,6 +1931,13 @@ void NetworkContext::SetNetworkConditions(
|
||||
std::move(network_conditions));
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ index 1fcf11cf90206270c6b0131b687ae668a8a12f83..af072c92721215d3306c165fb571710c
|
||||
// This may only be called on NetworkContexts created with the constructor
|
||||
// that calls MakeURLRequestContext().
|
||||
diff --git a/services/network/network_context.h b/services/network/network_context.h
|
||||
index bb00a6ba93c522b484dc525ba204f1bd537e6285..26e6a215dd4be92f939e18b0b4a8339eb30cde33 100644
|
||||
index d76159ac97c9c51fc73692e8f76f868259152d00..e6b8c8c5102cfab32126b49483be11866a44a68b 100644
|
||||
--- a/services/network/network_context.h
|
||||
+++ b/services/network/network_context.h
|
||||
@@ -322,6 +322,7 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext
|
||||
@@ -63,10 +63,10 @@ index bb00a6ba93c522b484dc525ba204f1bd537e6285..26e6a215dd4be92f939e18b0b4a8339e
|
||||
void SetEnableReferrers(bool enable_referrers) override;
|
||||
#if BUILDFLAG(IS_CT_SUPPORTED)
|
||||
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom
|
||||
index 099e103c8e17ff640270744903585d4c76cdd6a7..c8b56dcc8cd2d202c895f4aadcae4f6767a248d5 100644
|
||||
index 63d410dd356594a5928ed2f84b05b403bf3367f0..ca47c9cb58d5d69faade9f85d1e63683d79cb5e3 100644
|
||||
--- a/services/network/public/mojom/network_context.mojom
|
||||
+++ b/services/network/public/mojom/network_context.mojom
|
||||
@@ -1294,6 +1294,9 @@ interface NetworkContext {
|
||||
@@ -1291,6 +1291,9 @@ interface NetworkContext {
|
||||
SetNetworkConditions(mojo_base.mojom.UnguessableToken throttling_profile_id,
|
||||
array<MatchedNetworkConditions> conditions);
|
||||
|
||||
@@ -77,7 +77,7 @@ index 099e103c8e17ff640270744903585d4c76cdd6a7..c8b56dcc8cd2d202c895f4aadcae4f67
|
||||
SetAcceptLanguage(string new_accept_language);
|
||||
|
||||
diff --git a/services/network/test/test_network_context.h b/services/network/test/test_network_context.h
|
||||
index 9d9e1f63fa138e3393c0395334049d10e8d1329f..1a8ac7dfefe1dde40b8a1dd63f7b2a7a3abe00ec 100644
|
||||
index bc26f449109b3be84490fbb3569e36aa4aca8c4b..d273faec6c235cb7d29f0f7fb90affdca7240e51 100644
|
||||
--- a/services/network/test/test_network_context.h
|
||||
+++ b/services/network/test/test_network_context.h
|
||||
@@ -156,6 +156,7 @@ class TestNetworkContext : public mojom::NetworkContext {
|
||||
|
||||
@@ -315,7 +315,7 @@ index 38aa41a82acdf42fb05d3315c4df408796437873..0c6cbbc920c65a6e671839eb8022fbc9
|
||||
|
||||
// Although ScreenCaptureKit is available in 12.3 there were some bugs that
|
||||
diff --git a/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc b/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc
|
||||
index 9887b022744234f11322806982962390d79031ac..631022789ffb51b45b120520977bea7239f28636 100644
|
||||
index be22921bec3f112eb3d92c6a696aee2c3ed3a097..6d71bac3ac7b1318cd741efa50a5f40bd92b17fa 100644
|
||||
--- a/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc
|
||||
+++ b/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc
|
||||
@@ -321,8 +321,16 @@ void InProcessVideoCaptureDeviceLauncher::LaunchDeviceAsync(
|
||||
|
||||
@@ -91,7 +91,7 @@ index 2afe18e9e4a5404ed184aeedc1c02a313853f463..7c3b0c2da6ded539764ce59bc43f49e9
|
||||
return a.EmptyCells() == b.EmptyCells();
|
||||
case CSSPropertyID::kFill:
|
||||
diff --git a/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc
|
||||
index 6bcd20f64680f2f78984d686a7e2b7027f8fb111..8184630b3238f739aad68568b099d7d9416bc107 100644
|
||||
index 7407d5592f54dfbdb6c8099c9fd96d4f8921aaf8..71fe4155378b22e1bad523794882fa47a7b504ac 100644
|
||||
--- a/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc
|
||||
+++ b/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc
|
||||
@@ -13263,5 +13263,36 @@ const CSSValue* InternalEmptyLineHeight::ParseSingleValue(
|
||||
@@ -132,10 +132,10 @@ index 6bcd20f64680f2f78984d686a7e2b7027f8fb111..8184630b3238f739aad68568b099d7d9
|
||||
} // namespace css_longhand
|
||||
} // namespace blink
|
||||
diff --git a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
|
||||
index 7e435bbd4a8ac83eee4be981dcff5c504261ce73..f560c4070d19396d0e9219bcd5682395c8495a8c 100644
|
||||
index c7b826dd29b9a4c5a06a3bd352e3c481219f8d40..3ca28dd12cc1a20c7acba53f7e7180f8f28ed0ba 100644
|
||||
--- a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
|
||||
+++ b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
|
||||
@@ -4192,6 +4192,15 @@ PositionTryFallback StyleBuilderConverter::ConvertSinglePositionTryFallback(
|
||||
@@ -4196,6 +4196,15 @@ PositionTryFallback StyleBuilderConverter::ConvertSinglePositionTryFallback(
|
||||
return PositionTryFallback(scoped_name, tactic_list);
|
||||
}
|
||||
|
||||
@@ -203,10 +203,10 @@ index 19cda703154dab9397827ab6ea66c2ca446c644d..dd5943c511886f4e39b2e7f10e67e60f
|
||||
return result;
|
||||
}
|
||||
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn
|
||||
index 784ce295c0bca0a7bd096585c0f6ff603f688abc..aeb07b03395d0ea4fd2ca229aed1da4ec80dd969 100644
|
||||
index 33c91f31f548d54bcf3937e87ac391098bfd1905..4afbee0c16769a2ddbb115efa60951d7d062a62f 100644
|
||||
--- a/third_party/blink/renderer/platform/BUILD.gn
|
||||
+++ b/third_party/blink/renderer/platform/BUILD.gn
|
||||
@@ -1673,6 +1673,8 @@ component("platform") {
|
||||
@@ -1676,6 +1676,8 @@ component("platform") {
|
||||
"widget/widget_base.h",
|
||||
"widget/widget_base_client.h",
|
||||
"windows_keyboard_codes.h",
|
||||
@@ -314,7 +314,7 @@ index 18f283e625101318ee14b50e6e765dfd1c9a1a44..44a3a55974c9e4b9e715574075f25661
|
||||
|
||||
auto DrawAsSinglePath = [&]() {
|
||||
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
|
||||
index b95006c3b2c040a21f65f93c5fc95dbde92b8e55..571ebaf1390970aa0759506e0731e74c20782efb 100644
|
||||
index a4c41a7d2356e0e7be404380f3e7c59847b46230..e4b395b5ce2b2e5d161b75f9b51b810e3f362983 100644
|
||||
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
|
||||
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
|
||||
@@ -214,6 +214,10 @@
|
||||
|
||||
@@ -112,10 +112,10 @@ index 0d3aa45778e02c4a5bcdea6e8b0f5ab722e86aa3..fbe4f3d2931cdd9893a3c96667015d40
|
||||
string mime_type;
|
||||
|
||||
diff --git a/services/network/url_loader.cc b/services/network/url_loader.cc
|
||||
index ed2de2a74f757f8dbb03d24934468933bc6923ed..a985ad9c86b4cf55abd52d62275e56788dd46a3d 100644
|
||||
index 4f74407b7bdfdcba2cf4b76d9cb9ef317e243285..3010f32a6189251c448f31be8bab7ce8e6d058e5 100644
|
||||
--- a/services/network/url_loader.cc
|
||||
+++ b/services/network/url_loader.cc
|
||||
@@ -373,6 +373,9 @@ URLLoader::URLLoader(
|
||||
@@ -372,6 +372,9 @@ URLLoader::URLLoader(
|
||||
mojo::SimpleWatcher::ArmingPolicy::MANUAL,
|
||||
TaskRunner(request.priority)),
|
||||
per_factory_orb_state_(context.GetMutableOrbState()),
|
||||
@@ -125,7 +125,7 @@ index ed2de2a74f757f8dbb03d24934468933bc6923ed..a985ad9c86b4cf55abd52d62275e5678
|
||||
devtools_request_id_(request.devtools_request_id),
|
||||
options_(PopulateOptions(options,
|
||||
factory_params_->is_orb_enabled,
|
||||
@@ -570,7 +573,7 @@ void URLLoader::SetUpUrlRequestCallbacks(
|
||||
@@ -569,7 +572,7 @@ void URLLoader::SetUpUrlRequestCallbacks(
|
||||
&URLLoader::IsSharedDictionaryReadAllowed, base::Unretained(this)));
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ index ed2de2a74f757f8dbb03d24934468933bc6923ed..a985ad9c86b4cf55abd52d62275e5678
|
||||
url_request_->SetResponseHeadersCallback(base::BindRepeating(
|
||||
&URLLoader::SetRawResponseHeaders, base::Unretained(this)));
|
||||
}
|
||||
@@ -1176,6 +1179,19 @@ void URLLoader::OnResponseStarted(net::URLRequest* url_request, int net_error) {
|
||||
@@ -1175,6 +1178,19 @@ void URLLoader::OnResponseStarted(net::URLRequest* url_request, int net_error) {
|
||||
}
|
||||
|
||||
response_ = BuildResponseHead();
|
||||
|
||||
@@ -139,10 +139,10 @@ index 96678f5de2a0b67cd338012fb84b9ea7ff904084..afc4c3030d15eeb7a270ca6d3cc29e64
|
||||
|
||||
// Register the CGWindowID (used to identify this window for video capture)
|
||||
diff --git a/ui/views/widget/widget.cc b/ui/views/widget/widget.cc
|
||||
index e62f180fd782f29c25cf47a4e6be0cce46c99b17..b65d050fee7a607658efa6914c35186d9452f26f 100644
|
||||
index e02d00c5928f02791f71f348048bda50a7800eac..e73037b52ef2f81738ed7eeb5cb6f3b199b23249 100644
|
||||
--- a/ui/views/widget/widget.cc
|
||||
+++ b/ui/views/widget/widget.cc
|
||||
@@ -223,6 +223,18 @@ ui::ZOrderLevel Widget::InitParams::EffectiveZOrderLevel() const {
|
||||
@@ -224,6 +224,18 @@ ui::ZOrderLevel Widget::InitParams::EffectiveZOrderLevel() const {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,7 +161,7 @@ index e62f180fd782f29c25cf47a4e6be0cce46c99b17..b65d050fee7a607658efa6914c35186d
|
||||
void Widget::InitParams::SetParent(Widget* parent_widget) {
|
||||
SetParent(parent_widget->GetNativeView());
|
||||
}
|
||||
@@ -470,6 +482,7 @@ void Widget::Init(InitParams params) {
|
||||
@@ -471,6 +483,7 @@ void Widget::Init(InitParams params) {
|
||||
|
||||
params.child |= (params.type == InitParams::TYPE_CONTROL);
|
||||
is_top_level_ = !params.child;
|
||||
|
||||
@@ -28,10 +28,10 @@ The patch should be removed in favor of either:
|
||||
Upstream bug https://bugs.chromium.org/p/chromium/issues/detail?id=1081397.
|
||||
|
||||
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc
|
||||
index f1c701adc36a69ccd0940a5dc7f2033cfd30ef6c..48236f4a9defef53625ad4b8ebaaaabffd535c75 100644
|
||||
index 09a1c29bbae86da44b3433eaf78551e72b485245..b9501ec28078c3a95004fdfd9c7ac410e36f7d57 100644
|
||||
--- a/content/browser/renderer_host/navigation_request.cc
|
||||
+++ b/content/browser/renderer_host/navigation_request.cc
|
||||
@@ -11785,6 +11785,11 @@ url::Origin NavigationRequest::GetOriginForURLLoaderFactoryUnchecked() {
|
||||
@@ -11817,6 +11817,11 @@ url::Origin NavigationRequest::GetOriginForURLLoaderFactoryUnchecked() {
|
||||
target_rph_id);
|
||||
}
|
||||
|
||||
|
||||
@@ -87,10 +87,10 @@ index a4768b51dae6817c9e9a467e9b16e827e0bfebda..83c42b5062aa8193fe2f56e407abe67d
|
||||
// The view with active text input state, i.e., a focused <input> element.
|
||||
// It will be nullptr if no such view exists. Note that the active view
|
||||
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
|
||||
index 76def190aabe280bb8e0971dc5c72643bbce8f53..b3215ec81f8d750cfaa9b66a4880c6a90a6e183d 100644
|
||||
index 4fb9fcdc24376c81fe6092a484eb72a55e1ea45a..6838e858c78b1c12d352860186ee2a75bbed2ad8 100644
|
||||
--- a/content/browser/web_contents/web_contents_impl.cc
|
||||
+++ b/content/browser/web_contents/web_contents_impl.cc
|
||||
@@ -10284,7 +10284,7 @@ void WebContentsImpl::OnFocusedElementChangedInFrame(
|
||||
@@ -10415,7 +10415,7 @@ void WebContentsImpl::OnFocusedElementChangedInFrame(
|
||||
"WebContentsImpl::OnFocusedElementChangedInFrame",
|
||||
"render_frame_host", frame);
|
||||
RenderWidgetHostViewBase* root_view =
|
||||
|
||||
@@ -59,7 +59,7 @@ index cba373664bec3a32abad6fe0396bd67b53b7e67f..a54f1b3351efd2d8f324436f7f35cd43
|
||||
|
||||
#endif // THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_SCRIPT_EXECUTION_CALLBACK_H_
|
||||
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc
|
||||
index 34603bffa39cf2aaedfd7c3152464c524995f6f0..df2bf77d922cd5fed2d29b99bc35f28988d6d14f 100644
|
||||
index daf04130625fda5b6779126e9a63d9f4854a8555..c5bd0e7930e17541f9fbae5994933c80fbe91f54 100644
|
||||
--- a/third_party/blink/renderer/core/frame/local_frame.cc
|
||||
+++ b/third_party/blink/renderer/core/frame/local_frame.cc
|
||||
@@ -3197,6 +3197,7 @@ void LocalFrame::RequestExecuteScript(
|
||||
@@ -92,10 +92,10 @@ index 0f119c1170f3379754b03ff38358ed6f191fb578..64024aaa3630bacbaf13b7491ff4ed54
|
||||
mojom::blink::WantResultOption,
|
||||
mojom::blink::PromiseResultOption);
|
||||
diff --git a/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc b/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc
|
||||
index 56d681d3eea661fb0a5b1a135b4d4ea09e9e4577..7bcae985c6c918782f2795746f3ea01fcdcb1bff 100644
|
||||
index aa2666a03b9f0b4585f6025b45e1a1a914508843..3d88ea81f4d524979e42bbc6f5a2b1c0a4d15e26 100644
|
||||
--- a/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc
|
||||
+++ b/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc
|
||||
@@ -987,6 +987,7 @@ void LocalFrameMojoHandler::JavaScriptExecuteRequestInIsolatedWorld(
|
||||
@@ -988,6 +988,7 @@ void LocalFrameMojoHandler::JavaScriptExecuteRequestInIsolatedWorld(
|
||||
std::move(callback).Run(value ? std::move(*value) : base::Value());
|
||||
},
|
||||
std::move(callback)),
|
||||
@@ -223,7 +223,7 @@ index 6e87cd9a855bd3f1145f864367f34d966088ce6c..6b0448254eec33896686544ebc2a9bf6
|
||||
mojom::blink::WantResultOption::kWantResult, wait_for_promise);
|
||||
}
|
||||
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
|
||||
index 6ce6c0af328f722d02228feae910b129e0f41a74..d4a11cc2cd9be3a97058ec800ff23bc2ce33b12b 100644
|
||||
index d2b005438958f685e2187d8853926a94211427ad..e3446c84a068a954dfaa809580e8945f359f9e3c 100644
|
||||
--- a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
|
||||
+++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
|
||||
@@ -1128,14 +1128,15 @@ void WebLocalFrameImpl::RequestExecuteScript(
|
||||
|
||||
@@ -6,10 +6,10 @@ Subject: frame_host_manager.patch
|
||||
Allows embedder to intercept site instances created by chromium.
|
||||
|
||||
diff --git a/content/browser/renderer_host/render_frame_host_manager.cc b/content/browser/renderer_host/render_frame_host_manager.cc
|
||||
index a5165a08f161844898281c18d3963f8abffd58a8..c4d995aec772a6818c747adceb9fc63fe8d272e2 100644
|
||||
index c6a3a45f875c010a9f9cda637fb91d74427aeec6..15ec1a4c8796378effd9e1530851eb6d7fa4dfa1 100644
|
||||
--- a/content/browser/renderer_host/render_frame_host_manager.cc
|
||||
+++ b/content/browser/renderer_host/render_frame_host_manager.cc
|
||||
@@ -4925,6 +4925,9 @@ RenderFrameHostManager::GetSiteInstanceForNavigationRequest(
|
||||
@@ -4864,6 +4864,9 @@ RenderFrameHostManager::GetSiteInstanceForNavigationRequest(
|
||||
request->ResetStateForSiteInstanceChange();
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ index a5165a08f161844898281c18d3963f8abffd58a8..c4d995aec772a6818c747adceb9fc63f
|
||||
}
|
||||
|
||||
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
|
||||
index e6f51d39b4f2f6b162814996921958ca1252e1d7..1f496db16389734a30f1c07903ff6225aeb1f1b4 100644
|
||||
index 11eece7441d775490c4149e607b1812e917a1b00..978a5688a5be1ee05888264250c3356ba1ad707b 100644
|
||||
--- a/content/public/browser/content_browser_client.h
|
||||
+++ b/content/public/browser/content_browser_client.h
|
||||
@@ -350,6 +350,11 @@ class CONTENT_EXPORT ContentBrowserClient {
|
||||
|
||||
@@ -6,10 +6,10 @@ Subject: gritsettings_resource_ids.patch
|
||||
Add electron resources file to the list of resource ids generation.
|
||||
|
||||
diff --git a/tools/gritsettings/resource_ids.spec b/tools/gritsettings/resource_ids.spec
|
||||
index bc4d99704dcdb1f2d688fb6d847304ac7a45d3a8..5087a431bb9bd1fba7779f01c738c9d19cbfb63c 100644
|
||||
index a71d0f633287f6832a933447b9edb71aafece4ba..0d92a115b539f5449205fddaa34ef27e5d364592 100644
|
||||
--- a/tools/gritsettings/resource_ids.spec
|
||||
+++ b/tools/gritsettings/resource_ids.spec
|
||||
@@ -1661,6 +1661,11 @@
|
||||
@@ -1665,6 +1665,11 @@
|
||||
"includes": [12000],
|
||||
},
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ system font by checking if it's kCTFontPriorityAttribute is set to
|
||||
system priority.
|
||||
|
||||
diff --git a/base/BUILD.gn b/base/BUILD.gn
|
||||
index 17b0a948c762996026885cbb63d66cbd0ab94981..a1a18ffa59d45518cb171efb08cf24d1648de425 100644
|
||||
index aacecd4fbfa237ed17e8264abd37cce969dfa331..17af90379af2b07c7f7645adc2955df22afb32dc 100644
|
||||
--- a/base/BUILD.gn
|
||||
+++ b/base/BUILD.gn
|
||||
@@ -1085,6 +1085,7 @@ component("base") {
|
||||
@@ -974,7 +974,7 @@ index 664e12c07204feeb5be16581fe51e8adc4b898dd..38159d146cdf71f84611d58e2983418a
|
||||
return kAttributes;
|
||||
}
|
||||
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
|
||||
index 29104a461b7a3e04dc86baab0521288f974750a8..ea54cab0a72e931299871968afab7701e21547e4 100644
|
||||
index 6fb162e7f477fabde5a83de7bf68b87f1708f274..c276641783fc8a88f09fe7e0e6c48a937b69fead 100644
|
||||
--- a/content/browser/BUILD.gn
|
||||
+++ b/content/browser/BUILD.gn
|
||||
@@ -363,6 +363,7 @@ source_set("browser") {
|
||||
@@ -1189,7 +1189,7 @@ index a1068589ad844518038ee7bc15a3de9bc5cba525..1ff781c49f086ec8015c7d3c44567dbe
|
||||
|
||||
} // namespace content
|
||||
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
|
||||
index 3235936853681da70e93a31d51a7f6a91be698b0..a3c78319d97fe84621c29d778e354a6384f8583f 100644
|
||||
index 457752f9e929414b6d5afd1fa58b3916939157af..3227168bb01fa03c24f2496fd3848699ed3f8c8e 100644
|
||||
--- a/content/test/BUILD.gn
|
||||
+++ b/content/test/BUILD.gn
|
||||
@@ -701,6 +701,7 @@ static_library("test_support") {
|
||||
@@ -1378,7 +1378,7 @@ index 3a079b0fc34031d062045510fe0e2444792ff942..1be75833d46aaa124e5467904f68e46c
|
||||
} // namespace
|
||||
#endif
|
||||
diff --git a/net/dns/BUILD.gn b/net/dns/BUILD.gn
|
||||
index 012632a440f5078a71cbb327b04990654f282141..8e47b039b63fe74d3de441b8d21e7a9c4ec974f5 100644
|
||||
index 5be47a39edb9c5f3b05a13d10732b772d30cc2d7..a455b220b1e16770888bb02daeb88bfc4fa86fbd 100644
|
||||
--- a/net/dns/BUILD.gn
|
||||
+++ b/net/dns/BUILD.gn
|
||||
@@ -223,6 +223,8 @@ source_set("dns") {
|
||||
@@ -1789,7 +1789,7 @@ index eb81a70e4d5d5cd3e6ae9b45f8cd1c795ea76c51..9921ccb10d3455600eddd85f77f10228
|
||||
|
||||
} // namespace sandbox
|
||||
diff --git a/third_party/blink/renderer/core/BUILD.gn b/third_party/blink/renderer/core/BUILD.gn
|
||||
index 9b399ad326a19af7fd5e717bf8940ec562338f6d..96cc912489ab4423e0592d9c90c3d38f57131087 100644
|
||||
index 7b4ad32dfe88c07b8b82fbd58e7eb2da98cc86d7..b769dd1db63d6cf2f52d7b241237aa9601042b93 100644
|
||||
--- a/third_party/blink/renderer/core/BUILD.gn
|
||||
+++ b/third_party/blink/renderer/core/BUILD.gn
|
||||
@@ -444,6 +444,7 @@ component("core") {
|
||||
@@ -2359,10 +2359,10 @@ index bbe355cf69f160866188216cc274d75bd35603db..06ee100d7ea2e892dbf3c0b1adc96c50
|
||||
// enough.
|
||||
return PlatformFontMac::SystemFontType::kGeneral;
|
||||
diff --git a/ui/views/BUILD.gn b/ui/views/BUILD.gn
|
||||
index 5c0cad2640d84193e396ac1faff7d61230ab388c..edaf2a169d67cfa7903c56989801b1563ecf7af3 100644
|
||||
index 82c365a68444028440a3147193c49047ea1737d3..d338b652ebbe84891c5a5678ed5295fc907d0974 100644
|
||||
--- a/ui/views/BUILD.gn
|
||||
+++ b/ui/views/BUILD.gn
|
||||
@@ -732,6 +732,8 @@ component("views") {
|
||||
@@ -734,6 +734,8 @@ component("views") {
|
||||
"IOSurface.framework",
|
||||
"QuartzCore.framework",
|
||||
]
|
||||
@@ -2371,7 +2371,7 @@ index 5c0cad2640d84193e396ac1faff7d61230ab388c..edaf2a169d67cfa7903c56989801b156
|
||||
}
|
||||
|
||||
if (is_win) {
|
||||
@@ -1161,6 +1163,8 @@ source_set("test_support") {
|
||||
@@ -1163,6 +1165,8 @@ source_set("test_support") {
|
||||
"//ui/base/mojom:ui_base_types",
|
||||
]
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ This adds a callback from the network service that's used to implement
|
||||
session.setCertificateVerifyCallback.
|
||||
|
||||
diff --git a/services/network/network_context.cc b/services/network/network_context.cc
|
||||
index 55832bf73e134f21948821fbe13dd0642661e8d3..1fcf11cf90206270c6b0131b687ae668a8a12f83 100644
|
||||
index 504a8d0cd8bbc7b5e597e784d26d9fd905ba43da..9b7b17abed8d2220065e7b6130c77196f88dc825 100644
|
||||
--- a/services/network/network_context.cc
|
||||
+++ b/services/network/network_context.cc
|
||||
@@ -171,6 +171,11 @@
|
||||
@@ -134,7 +134,7 @@ index 55832bf73e134f21948821fbe13dd0642661e8d3..1fcf11cf90206270c6b0131b687ae668
|
||||
constexpr uint32_t NetworkContext::kMaxOutstandingRequestsPerProcess;
|
||||
|
||||
NetworkContext::NetworkContextHttpAuthPreferences::
|
||||
@@ -1036,6 +1146,13 @@ void NetworkContext::SetClient(
|
||||
@@ -1044,6 +1154,13 @@ void NetworkContext::SetClient(
|
||||
client_.Bind(std::move(client));
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ index 55832bf73e134f21948821fbe13dd0642661e8d3..1fcf11cf90206270c6b0131b687ae668
|
||||
void NetworkContext::CreateURLLoaderFactory(
|
||||
mojo::PendingReceiver<mojom::URLLoaderFactory> receiver,
|
||||
mojom::URLLoaderFactoryParamsPtr params) {
|
||||
@@ -2723,6 +2840,10 @@ URLRequestContextOwner NetworkContext::MakeURLRequestContext(
|
||||
@@ -2733,6 +2850,10 @@ URLRequestContextOwner NetworkContext::MakeURLRequestContext(
|
||||
cert_verifier = std::make_unique<net::CachingCertVerifier>(
|
||||
std::make_unique<net::CoalescingCertVerifier>(
|
||||
std::move(cert_verifier)));
|
||||
@@ -160,7 +160,7 @@ index 55832bf73e134f21948821fbe13dd0642661e8d3..1fcf11cf90206270c6b0131b687ae668
|
||||
|
||||
builder.SetCertVerifier(IgnoreErrorsCertVerifier::MaybeWrapCertVerifier(
|
||||
diff --git a/services/network/network_context.h b/services/network/network_context.h
|
||||
index f4bc2b75bc833dc7a47e1fa178f5542824843b36..bb00a6ba93c522b484dc525ba204f1bd537e6285 100644
|
||||
index 3e95a8a8c8c8e4d43cc461ce1c13589cc881b09e..d76159ac97c9c51fc73692e8f76f868259152d00 100644
|
||||
--- a/services/network/network_context.h
|
||||
+++ b/services/network/network_context.h
|
||||
@@ -119,6 +119,7 @@ class SimpleUrlPatternMatcher;
|
||||
@@ -180,7 +180,7 @@ index f4bc2b75bc833dc7a47e1fa178f5542824843b36..bb00a6ba93c522b484dc525ba204f1bd
|
||||
void ResetURLLoaderFactories() override;
|
||||
void GetViaObliviousHttp(
|
||||
mojom::ObliviousHttpRequestPtr request,
|
||||
@@ -970,6 +973,8 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext
|
||||
@@ -971,6 +974,8 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext
|
||||
std::vector<base::OnceClosure> dismount_closures_;
|
||||
#endif // BUILDFLAG(IS_DIRECTORY_TRANSFER_REQUIRED)
|
||||
|
||||
@@ -190,10 +190,10 @@ index f4bc2b75bc833dc7a47e1fa178f5542824843b36..bb00a6ba93c522b484dc525ba204f1bd
|
||||
std::unique_ptr<HostResolver> internal_host_resolver_;
|
||||
std::set<std::unique_ptr<HostResolver>, base::UniquePtrComparator>
|
||||
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom
|
||||
index 116ecc87549d02fa20ef9fd8068b3410590a2879..099e103c8e17ff640270744903585d4c76cdd6a7 100644
|
||||
index 47134ad9365ce50035d5a305418e36a41fc917c9..63d410dd356594a5928ed2f84b05b403bf3367f0 100644
|
||||
--- a/services/network/public/mojom/network_context.mojom
|
||||
+++ b/services/network/public/mojom/network_context.mojom
|
||||
@@ -324,6 +324,17 @@ struct SocketBrokerRemotes {
|
||||
@@ -325,6 +325,17 @@ struct SocketBrokerRemotes {
|
||||
pending_remote<SocketBroker> server;
|
||||
};
|
||||
|
||||
@@ -211,7 +211,7 @@ index 116ecc87549d02fa20ef9fd8068b3410590a2879..099e103c8e17ff640270744903585d4c
|
||||
// Parameters for constructing a network context.
|
||||
struct NetworkContextParams {
|
||||
// The user agent string.
|
||||
@@ -980,6 +991,9 @@ interface NetworkContext {
|
||||
@@ -977,6 +988,9 @@ interface NetworkContext {
|
||||
// Sets a client for this network context.
|
||||
SetClient(pending_remote<NetworkContextClient> client);
|
||||
|
||||
@@ -222,7 +222,7 @@ index 116ecc87549d02fa20ef9fd8068b3410590a2879..099e103c8e17ff640270744903585d4c
|
||||
CreateURLLoaderFactory(
|
||||
pending_receiver<URLLoaderFactory> url_loader_factory,
|
||||
diff --git a/services/network/test/test_network_context.h b/services/network/test/test_network_context.h
|
||||
index 817b69f7b36f996a5f3f068649a997fdf67afd1b..9d9e1f63fa138e3393c0395334049d10e8d1329f 100644
|
||||
index beb1c3dba14fcc504886f100b1568768231a4f2d..bc26f449109b3be84490fbb3569e36aa4aca8c4b 100644
|
||||
--- a/services/network/test/test_network_context.h
|
||||
+++ b/services/network/test/test_network_context.h
|
||||
@@ -63,6 +63,8 @@ class TestNetworkContext : public mojom::NetworkContext {
|
||||
|
||||
@@ -133,7 +133,7 @@ index 9bf238e64af483294ae3c3f18a4e9aed49a8658d..b9b2a4c8c387b8e8b4eb1f02fc0f891c
|
||||
const GURL& document_url,
|
||||
const WeakDocumentPtr& weak_document_ptr,
|
||||
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
|
||||
index c160b8ad92ad648dd7657fc3b94d2cc6c72c3824..23ddb2009a6118aad1f9629c7cd7a6d566b3bcc6 100644
|
||||
index 50bf9100cd0dacd5c1a1c7293683101efcf7f1b2..40c41c074c75ec04badee292310d13d393e42fdd 100644
|
||||
--- a/content/browser/renderer_host/render_process_host_impl.cc
|
||||
+++ b/content/browser/renderer_host/render_process_host_impl.cc
|
||||
@@ -2375,7 +2375,7 @@ void RenderProcessHostImpl::CreateNotificationService(
|
||||
|
||||
@@ -36,10 +36,10 @@ index 6f31a20329a7bc7cafb6384c3b8ec9ed7a11e64e..3bf92efa5c0ad0212096e61383b53095
|
||||
Microsoft::WRL::ComPtr<ID3D11Texture2D> d3d11_texture;
|
||||
|
||||
diff --git a/media/video/renderable_mappable_shared_image_video_frame_pool.cc b/media/video/renderable_mappable_shared_image_video_frame_pool.cc
|
||||
index 36ed797edc58a6cf094a0b720bf949b3f6379890..36a4a080da38cddad645d42e5c53c840e211105e 100644
|
||||
index 6b1abdebe1fb0043f535e731d0bd14a6d3e3c083..cde2239a516133fedb46dc4bd06b791a1a4d12aa 100644
|
||||
--- a/media/video/renderable_mappable_shared_image_video_frame_pool.cc
|
||||
+++ b/media/video/renderable_mappable_shared_image_video_frame_pool.cc
|
||||
@@ -211,6 +211,24 @@ bool FrameResources::Initialize(VideoPixelFormat format,
|
||||
@@ -212,6 +212,24 @@ bool FrameResources::Initialize(VideoPixelFormat format,
|
||||
const gfx::Size coded_size =
|
||||
GetCodedSizeForVideoPixelFormat(format, visible_size_);
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ index f91857eb0b6ad385721b8224100de26dfdd7dd8d..45e8766fcb8d46d8edc3bf8d21d3f826
|
||||
: PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3;
|
||||
}
|
||||
diff --git a/chrome/browser/printing/print_view_manager_base.cc b/chrome/browser/printing/print_view_manager_base.cc
|
||||
index aa79c324af2cec50019bca3bccff5d420fb30ffd..eb76ee91743236d05c3a70a54d5345a705b5d994 100644
|
||||
index aa79c324af2cec50019bca3bccff5d420fb30ffd..455095a2cd63eabe4f267747070b443f0c49c1e8 100644
|
||||
--- a/chrome/browser/printing/print_view_manager_base.cc
|
||||
+++ b/chrome/browser/printing/print_view_manager_base.cc
|
||||
@@ -80,6 +80,20 @@ namespace printing {
|
||||
@@ -326,14 +326,23 @@ index aa79c324af2cec50019bca3bccff5d420fb30ffd..eb76ee91743236d05c3a70a54d5345a7
|
||||
ReleasePrinterQuery();
|
||||
}
|
||||
|
||||
@@ -851,15 +886,24 @@ void PrintViewManagerBase::RemoveTestObserver(TestObserver& observer) {
|
||||
@@ -851,15 +886,33 @@ void PrintViewManagerBase::RemoveTestObserver(TestObserver& observer) {
|
||||
test_observers_.RemoveObserver(&observer);
|
||||
}
|
||||
|
||||
+void PrintViewManagerBase::ShowInvalidPrinterSettingsError() {
|
||||
+ if (!callback_.is_null()) {
|
||||
+ printing_status_ = PrintStatus::kInvalid;
|
||||
+ TerminatePrintJob(true);
|
||||
+ if (print_job_) {
|
||||
+ TerminatePrintJob(true);
|
||||
+ } else {
|
||||
+ // No print job was created, so TerminatePrintJob would bail out
|
||||
+ // without ever calling ReleasePrintJob (where the callback is
|
||||
+ // invoked). Fire the callback directly to avoid leaking it until
|
||||
+ // WebContents destruction.
|
||||
+ std::move(callback_).Run(false,
|
||||
+ PrintReasonFromPrintStatus(printing_status_));
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
@@ -351,7 +360,7 @@ index aa79c324af2cec50019bca3bccff5d420fb30ffd..eb76ee91743236d05c3a70a54d5345a7
|
||||
}
|
||||
|
||||
void PrintViewManagerBase::RenderFrameDeleted(
|
||||
@@ -901,13 +945,14 @@ void PrintViewManagerBase::SystemDialogCancelled() {
|
||||
@@ -901,13 +954,14 @@ void PrintViewManagerBase::SystemDialogCancelled() {
|
||||
// System dialog was cancelled. Clean up the print job and notify the
|
||||
// BackgroundPrintingManager.
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
@@ -367,7 +376,7 @@ index aa79c324af2cec50019bca3bccff5d420fb30ffd..eb76ee91743236d05c3a70a54d5345a7
|
||||
}
|
||||
|
||||
void PrintViewManagerBase::OnDocDone(int job_id, PrintedDocument* document) {
|
||||
@@ -921,18 +966,26 @@ void PrintViewManagerBase::OnJobDone() {
|
||||
@@ -921,18 +975,26 @@ void PrintViewManagerBase::OnJobDone() {
|
||||
// Printing is done, we don't need it anymore.
|
||||
// print_job_->is_job_pending() may still be true, depending on the order
|
||||
// of object registration.
|
||||
@@ -396,7 +405,7 @@ index aa79c324af2cec50019bca3bccff5d420fb30ffd..eb76ee91743236d05c3a70a54d5345a7
|
||||
TerminatePrintJob(true);
|
||||
}
|
||||
|
||||
@@ -942,7 +995,7 @@ bool PrintViewManagerBase::RenderAllMissingPagesNow() {
|
||||
@@ -942,7 +1004,7 @@ bool PrintViewManagerBase::RenderAllMissingPagesNow() {
|
||||
|
||||
// Is the document already complete?
|
||||
if (print_job_->document() && print_job_->document()->IsComplete()) {
|
||||
@@ -405,7 +414,7 @@ index aa79c324af2cec50019bca3bccff5d420fb30ffd..eb76ee91743236d05c3a70a54d5345a7
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -995,7 +1048,10 @@ bool PrintViewManagerBase::SetupNewPrintJob(
|
||||
@@ -995,7 +1057,10 @@ bool PrintViewManagerBase::SetupNewPrintJob(
|
||||
|
||||
// Disconnect the current `print_job_`.
|
||||
auto weak_this = weak_ptr_factory_.GetWeakPtr();
|
||||
@@ -417,7 +426,7 @@ index aa79c324af2cec50019bca3bccff5d420fb30ffd..eb76ee91743236d05c3a70a54d5345a7
|
||||
if (!weak_this)
|
||||
return false;
|
||||
|
||||
@@ -1015,7 +1071,7 @@ bool PrintViewManagerBase::SetupNewPrintJob(
|
||||
@@ -1015,7 +1080,7 @@ bool PrintViewManagerBase::SetupNewPrintJob(
|
||||
#endif
|
||||
print_job_->AddObserver(*this);
|
||||
|
||||
@@ -426,7 +435,7 @@ index aa79c324af2cec50019bca3bccff5d420fb30ffd..eb76ee91743236d05c3a70a54d5345a7
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1073,7 +1129,7 @@ void PrintViewManagerBase::ReleasePrintJob() {
|
||||
@@ -1073,7 +1138,7 @@ void PrintViewManagerBase::ReleasePrintJob() {
|
||||
// Ensure that any residual registration of printing client is released.
|
||||
// This might be necessary in some abnormal cases, such as the associated
|
||||
// render process having terminated.
|
||||
@@ -435,7 +444,7 @@ index aa79c324af2cec50019bca3bccff5d420fb30ffd..eb76ee91743236d05c3a70a54d5345a7
|
||||
if (!analyzing_content_) {
|
||||
UnregisterSystemPrintClient();
|
||||
}
|
||||
@@ -1083,6 +1139,11 @@ void PrintViewManagerBase::ReleasePrintJob() {
|
||||
@@ -1083,6 +1148,11 @@ void PrintViewManagerBase::ReleasePrintJob() {
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -447,7 +456,7 @@ index aa79c324af2cec50019bca3bccff5d420fb30ffd..eb76ee91743236d05c3a70a54d5345a7
|
||||
if (!print_job_)
|
||||
return;
|
||||
|
||||
@@ -1090,7 +1151,7 @@ void PrintViewManagerBase::ReleasePrintJob() {
|
||||
@@ -1090,7 +1160,7 @@ void PrintViewManagerBase::ReleasePrintJob() {
|
||||
// printing_rfh_ should only ever point to a RenderFrameHost with a live
|
||||
// RenderFrame.
|
||||
DCHECK(rfh->IsRenderFrameLive());
|
||||
@@ -456,7 +465,7 @@ index aa79c324af2cec50019bca3bccff5d420fb30ffd..eb76ee91743236d05c3a70a54d5345a7
|
||||
}
|
||||
|
||||
print_job_->RemoveObserver(*this);
|
||||
@@ -1132,7 +1193,7 @@ bool PrintViewManagerBase::RunInnerMessageLoop() {
|
||||
@@ -1132,7 +1202,7 @@ bool PrintViewManagerBase::RunInnerMessageLoop() {
|
||||
}
|
||||
|
||||
bool PrintViewManagerBase::OpportunisticallyCreatePrintJob(int cookie) {
|
||||
@@ -465,7 +474,7 @@ index aa79c324af2cec50019bca3bccff5d420fb30ffd..eb76ee91743236d05c3a70a54d5345a7
|
||||
return true;
|
||||
|
||||
if (!cookie) {
|
||||
@@ -1155,7 +1216,7 @@ bool PrintViewManagerBase::OpportunisticallyCreatePrintJob(int cookie) {
|
||||
@@ -1155,7 +1225,7 @@ bool PrintViewManagerBase::OpportunisticallyCreatePrintJob(int cookie) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -474,7 +483,7 @@ index aa79c324af2cec50019bca3bccff5d420fb30ffd..eb76ee91743236d05c3a70a54d5345a7
|
||||
// Don't start printing if enterprise checks are being performed to check if
|
||||
// printing is allowed, or if content analysis is going to take place right
|
||||
// before starting `print_job_`.
|
||||
@@ -1286,6 +1347,8 @@ void PrintViewManagerBase::CompleteScriptedPrint(
|
||||
@@ -1286,6 +1356,8 @@ void PrintViewManagerBase::CompleteScriptedPrint(
|
||||
auto callback_wrapper = base::BindOnce(
|
||||
&PrintViewManagerBase::ScriptedPrintReply, weak_ptr_factory_.GetWeakPtr(),
|
||||
std::move(callback), render_process_host->GetDeprecatedID());
|
||||
@@ -483,7 +492,7 @@ index aa79c324af2cec50019bca3bccff5d420fb30ffd..eb76ee91743236d05c3a70a54d5345a7
|
||||
std::unique_ptr<PrinterQuery> printer_query =
|
||||
queue()->PopPrinterQuery(params->cookie);
|
||||
if (!printer_query)
|
||||
@@ -1296,10 +1359,10 @@ void PrintViewManagerBase::CompleteScriptedPrint(
|
||||
@@ -1296,10 +1368,10 @@ void PrintViewManagerBase::CompleteScriptedPrint(
|
||||
params->expected_pages_count, params->has_selection, params->margin_type,
|
||||
params->is_scripted, !render_process_host->IsPdf(),
|
||||
base::BindOnce(&OnDidScriptedPrint, queue_, std::move(printer_query),
|
||||
|
||||
@@ -44,10 +44,10 @@ index 5e7d992ba2144d32f8eb1c6fa5233c68954318e1..4ff55ddc2286fff096a7e2bcdfb87d87
|
||||
|
||||
void RenderWidgetHostImpl::ShowContextMenuAtPoint(
|
||||
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
|
||||
index 1567ac2a65d222080430a47dce97b6d387ebe49d..f605f46115cda0f8f06e5274a26e3b997ca4c62e 100644
|
||||
index daab93ed099913477d94c7790325a0aea2f3c75f..2dfacb13990561632441ccc9d0ae3006693b67e2 100644
|
||||
--- a/content/browser/web_contents/web_contents_impl.cc
|
||||
+++ b/content/browser/web_contents/web_contents_impl.cc
|
||||
@@ -6212,6 +6212,11 @@ TextInputManager* WebContentsImpl::GetTextInputManager() {
|
||||
@@ -6320,6 +6320,11 @@ TextInputManager* WebContentsImpl::GetTextInputManager() {
|
||||
return text_input_manager_.get();
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ index 1567ac2a65d222080430a47dce97b6d387ebe49d..f605f46115cda0f8f06e5274a26e3b99
|
||||
RenderWidgetHostImpl* render_widget_host) {
|
||||
return render_widget_host == GetPrimaryMainFrame()->GetRenderWidgetHost();
|
||||
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
|
||||
index c1fdb7e3d899dbdd4413361040158395a6d4eb98..ce46eaa39b053850e2692c906a9e991052cd7195 100644
|
||||
index c353ef73e003f50f4a047dd4dcce5b6673ca4942..56690cd6d4603f91e1a5ce06d93a66b5381560cd 100644
|
||||
--- a/content/browser/web_contents/web_contents_impl.h
|
||||
+++ b/content/browser/web_contents/web_contents_impl.h
|
||||
@@ -1204,6 +1204,7 @@ class CONTENT_EXPORT WebContentsImpl
|
||||
|
||||
@@ -8,7 +8,7 @@ it in Electron and prevent drift from Chrome's blocklist. We should look for a w
|
||||
to upstream this change to Chrome.
|
||||
|
||||
diff --git a/chrome/browser/file_system_access/chrome_file_system_access_permission_context.cc b/chrome/browser/file_system_access/chrome_file_system_access_permission_context.cc
|
||||
index e45b723af85446b5c7537d49e70f34b2a67bab97..ac44b6723085c7a94a5d8736e24ea4ea22ac206a 100644
|
||||
index 4e769e8be28ffd18788d8786fe7341e5d5b0697c..2f447d1a3e7ab50458159bcb717220bb60f6f6ea 100644
|
||||
--- a/chrome/browser/file_system_access/chrome_file_system_access_permission_context.cc
|
||||
+++ b/chrome/browser/file_system_access/chrome_file_system_access_permission_context.cc
|
||||
@@ -83,11 +83,13 @@
|
||||
@@ -25,7 +25,7 @@ index e45b723af85446b5c7537d49e70f34b2a67bab97..ac44b6723085c7a94a5d8736e24ea4ea
|
||||
#include "components/tabs/public/tab_interface.h"
|
||||
#if BUILDFLAG(ENABLE_PLATFORM_APPS)
|
||||
#include "extensions/browser/extension_registry.h" // nogncheck
|
||||
@@ -287,190 +289,10 @@ bool MaybeIsLocalUNCPath(const base::FilePath& path) {
|
||||
@@ -286,190 +288,10 @@ bool MaybeIsLocalUNCPath(const base::FilePath& path) {
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -220,7 +220,7 @@ index e45b723af85446b5c7537d49e70f34b2a67bab97..ac44b6723085c7a94a5d8736e24ea4ea
|
||||
|
||||
// Checks if `path` should be blocked by the `rules`.
|
||||
// The BlockType of the nearest ancestor of a path to check is what
|
||||
@@ -1405,16 +1227,6 @@ struct ChromeFileSystemAccessPermissionContext::OriginState {
|
||||
@@ -1404,16 +1226,6 @@ struct ChromeFileSystemAccessPermissionContext::OriginState {
|
||||
std::unique_ptr<base::RetainingOneShotTimer> cleanup_timer;
|
||||
};
|
||||
|
||||
@@ -237,7 +237,7 @@ index e45b723af85446b5c7537d49e70f34b2a67bab97..ac44b6723085c7a94a5d8736e24ea4ea
|
||||
ChromeFileSystemAccessPermissionContext::
|
||||
ChromeFileSystemAccessPermissionContext(content::BrowserContext* context,
|
||||
const base::Clock* clock)
|
||||
@@ -1433,7 +1245,7 @@ ChromeFileSystemAccessPermissionContext::
|
||||
@@ -1432,7 +1244,7 @@ ChromeFileSystemAccessPermissionContext::
|
||||
#if BUILDFLAG(IS_ANDROID)
|
||||
one_time_permissions_tracker_.Observe(
|
||||
OneTimePermissionsTrackerFactory::GetForBrowserContext(context));
|
||||
@@ -246,7 +246,7 @@ index e45b723af85446b5c7537d49e70f34b2a67bab97..ac44b6723085c7a94a5d8736e24ea4ea
|
||||
auto* provider = web_app::WebAppProvider::GetForWebApps(
|
||||
Profile::FromBrowserContext(profile_));
|
||||
if (provider) {
|
||||
@@ -2813,7 +2625,7 @@ void ChromeFileSystemAccessPermissionContext::OnShutdown() {
|
||||
@@ -2812,7 +2624,7 @@ void ChromeFileSystemAccessPermissionContext::OnShutdown() {
|
||||
one_time_permissions_tracker_.Reset();
|
||||
}
|
||||
|
||||
@@ -255,7 +255,7 @@ index e45b723af85446b5c7537d49e70f34b2a67bab97..ac44b6723085c7a94a5d8736e24ea4ea
|
||||
void ChromeFileSystemAccessPermissionContext::OnWebAppInstalled(
|
||||
const webapps::AppId& app_id) {
|
||||
if (!base::FeatureList::IsEnabled(
|
||||
@@ -3171,11 +2983,7 @@ bool ChromeFileSystemAccessPermissionContext::
|
||||
@@ -3170,11 +2982,7 @@ bool ChromeFileSystemAccessPermissionContext::
|
||||
HandleType handle_type,
|
||||
UserAction user_action,
|
||||
GrantType grant_type) {
|
||||
@@ -268,7 +268,7 @@ index e45b723af85446b5c7537d49e70f34b2a67bab97..ac44b6723085c7a94a5d8736e24ea4ea
|
||||
if (!base::FeatureList::IsEnabled(
|
||||
features::kFileSystemAccessPersistentPermissions)) {
|
||||
return false;
|
||||
@@ -3226,6 +3034,7 @@ bool ChromeFileSystemAccessPermissionContext::
|
||||
@@ -3225,6 +3033,7 @@ bool ChromeFileSystemAccessPermissionContext::
|
||||
|
||||
return false;
|
||||
#endif // BUILDFLAG(IS_ANDROID)
|
||||
|
||||
@@ -15,10 +15,10 @@ This CL removes these filters so the unresponsive event can still be
|
||||
accessed from our JS event. The filtering is moved into Electron's code.
|
||||
|
||||
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
|
||||
index 2d993b4265f6be26da1f0bc98520eec3fe393645..a526b1071029a33983060e3f379e3030ac723403 100644
|
||||
index e770df76c913bfb126d8e9ecd2eb8548b9bfb2f9..e8578f1c2c63fa83c7b8ba413a55121c4479aa3e 100644
|
||||
--- a/content/browser/web_contents/web_contents_impl.cc
|
||||
+++ b/content/browser/web_contents/web_contents_impl.cc
|
||||
@@ -10446,25 +10446,13 @@ void WebContentsImpl::RendererUnresponsive(
|
||||
@@ -10567,25 +10567,13 @@ void WebContentsImpl::RendererUnresponsive(
|
||||
base::RepeatingClosure hang_monitor_restarter) {
|
||||
OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::RendererUnresponsive",
|
||||
"render_widget_host", render_widget_host);
|
||||
|
||||
@@ -52,7 +52,7 @@ Some alternatives to this patch:
|
||||
None of these options seems like a substantial maintainability win over this patch to me (@nornagon).
|
||||
|
||||
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn
|
||||
index d8f51269f5edb6fa698bc40abb3900a551f2ab0d..74aadd24a27d31291bb42d452ff247bbf6dad14a 100644
|
||||
index f74c98ab47e2917781a689856b4d05d9ea175de2..e30ea563d0d74d6dfb198b19edf9ef1c086d10f8 100644
|
||||
--- a/chrome/BUILD.gn
|
||||
+++ b/chrome/BUILD.gn
|
||||
@@ -1550,7 +1550,7 @@ if (is_chrome_branded && !is_android) {
|
||||
|
||||
@@ -245,10 +245,10 @@ index 1ef2c9052262eccdbc40030746a858b7f30ac469..c7101b0d71826b05f61bfe0e74429d92
|
||||
}
|
||||
|
||||
diff --git a/content/common/features.cc b/content/common/features.cc
|
||||
index a66e20e2f49f02c314a863b6877608b81c1f6ec4..0ddfd42a86aa09ef01c7d0a5ab1c075cf40527dc 100644
|
||||
index 60450dda6cdc81dae8d288df7c03a13c86beed0e..efce8544ae5b7d5b904d99b242af4a04144bb548 100644
|
||||
--- a/content/common/features.cc
|
||||
+++ b/content/common/features.cc
|
||||
@@ -370,6 +370,14 @@ BASE_FEATURE(kInterestGroupUpdateIfOlderThan, base::FEATURE_ENABLED_BY_DEFAULT);
|
||||
@@ -393,6 +393,14 @@ BASE_FEATURE(kInterestGroupUpdateIfOlderThan, base::FEATURE_ENABLED_BY_DEFAULT);
|
||||
BASE_FEATURE(kIOSurfaceCapturer, base::FEATURE_ENABLED_BY_DEFAULT);
|
||||
#endif
|
||||
|
||||
@@ -264,10 +264,10 @@ index a66e20e2f49f02c314a863b6877608b81c1f6ec4..0ddfd42a86aa09ef01c7d0a5ab1c075c
|
||||
BASE_FEATURE(kKeepChildProcessAfterIPCReset, base::FEATURE_DISABLED_BY_DEFAULT);
|
||||
|
||||
diff --git a/content/common/features.h b/content/common/features.h
|
||||
index 85097d0c88411409c91a2a64cbc19133b703de57..4dd265220050c3bd723e0ef62cc8cc9ab8dcd442 100644
|
||||
index f26e5c9f95dd3cfd81bee53507d181c08df3a044..b6efabd4fd0ebfdbea904bc19918aec9a6ba0ff0 100644
|
||||
--- a/content/common/features.h
|
||||
+++ b/content/common/features.h
|
||||
@@ -143,6 +143,9 @@ CONTENT_EXPORT BASE_DECLARE_FEATURE(kInterestGroupUpdateIfOlderThan);
|
||||
@@ -149,6 +149,9 @@ CONTENT_EXPORT BASE_DECLARE_FEATURE(kInterestGroupUpdateIfOlderThan);
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
CONTENT_EXPORT BASE_DECLARE_FEATURE(kIOSurfaceCapturer);
|
||||
#endif
|
||||
|
||||
@@ -54,10 +54,10 @@ index e3fa1bdc048a59dd64dae19b2372119335686643..b5ceb81ecc4d0274a411267e975ea413
|
||||
if (mouse_event_callback.Run(mouse_event)) {
|
||||
return;
|
||||
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
|
||||
index a526b1071029a33983060e3f379e3030ac723403..28a98260183ad24529ef5848ffcb117e9e1a6e3b 100644
|
||||
index e8578f1c2c63fa83c7b8ba413a55121c4479aa3e..cc1294bc66b38bae4960fecb0380ad6cacd39df3 100644
|
||||
--- a/content/browser/web_contents/web_contents_impl.cc
|
||||
+++ b/content/browser/web_contents/web_contents_impl.cc
|
||||
@@ -4486,6 +4486,12 @@ void WebContentsImpl::RenderWidgetWasResized(
|
||||
@@ -4582,6 +4582,12 @@ void WebContentsImpl::RenderWidgetWasResized(
|
||||
width_changed);
|
||||
}
|
||||
|
||||
@@ -71,10 +71,10 @@ index a526b1071029a33983060e3f379e3030ac723403..28a98260183ad24529ef5848ffcb117e
|
||||
const gfx::PointF& client_pt) {
|
||||
if (delegate_) {
|
||||
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
|
||||
index ce46eaa39b053850e2692c906a9e991052cd7195..953deca8142154ffd0a27c11e9beb42270107a8c 100644
|
||||
index 56690cd6d4603f91e1a5ce06d93a66b5381560cd..ef40925c6aa3875f34af3027937d1f856b4cbff5 100644
|
||||
--- a/content/browser/web_contents/web_contents_impl.h
|
||||
+++ b/content/browser/web_contents/web_contents_impl.h
|
||||
@@ -1134,6 +1134,7 @@ class CONTENT_EXPORT WebContentsImpl
|
||||
@@ -1132,6 +1132,7 @@ class CONTENT_EXPORT WebContentsImpl
|
||||
|
||||
double GetPendingZoomLevel(RenderWidgetHostImpl* rwh) override;
|
||||
|
||||
|
||||
@@ -10,10 +10,10 @@ on Windows. We should refactor our code so that this patch isn't
|
||||
necessary.
|
||||
|
||||
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
|
||||
index 8dcd23b01d299057ce13c1a4d9016c1f3a4331b6..804b4e3a3c63c6302f92f9ba6738966957eb42c8 100644
|
||||
index f11731797c7063b837e3d9396b84d02881754894..9f90a2b1c9849aa37f711cab9fb0006ba3e3dd12 100644
|
||||
--- a/testing/variations/fieldtrial_testing_config.json
|
||||
+++ b/testing/variations/fieldtrial_testing_config.json
|
||||
@@ -21965,6 +21965,21 @@
|
||||
@@ -22324,6 +22324,21 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
@@ -36,10 +36,10 @@ index 8dcd23b01d299057ce13c1a4d9016c1f3a4331b6..804b4e3a3c63c6302f92f9ba67389669
|
||||
{
|
||||
"platforms": [
|
||||
diff --git a/ui/views/views_features.cc b/ui/views/views_features.cc
|
||||
index d033e4924e4646665840db11e988d430523cd65a..2c89de182d1bff0904762b88f6e16eec5839469d 100644
|
||||
index c74cf661f64e60ad6740e011f372e53426ce0c4d..77ce34e4f47a54f7ecabbd6e6d4d19555af248ff 100644
|
||||
--- a/ui/views/views_features.cc
|
||||
+++ b/ui/views/views_features.cc
|
||||
@@ -34,6 +34,14 @@ BASE_FEATURE(kEnableClickjackingProtection, base::FEATURE_DISABLED_BY_DEFAULT);
|
||||
@@ -34,6 +34,14 @@ BASE_FEATURE(kEnableInputProtection, base::FEATURE_DISABLED_BY_DEFAULT);
|
||||
// crbug.com/370856871.
|
||||
BASE_FEATURE(kEnableTouchDragCursorSync, base::FEATURE_ENABLED_BY_DEFAULT);
|
||||
|
||||
@@ -55,12 +55,12 @@ index d033e4924e4646665840db11e988d430523cd65a..2c89de182d1bff0904762b88f6e16eec
|
||||
// to kKeyboardAccessibleTooltip in //ui/base/ui_base_features.cc.
|
||||
BASE_FEATURE(kKeyboardAccessibleTooltipInViews,
|
||||
diff --git a/ui/views/views_features.h b/ui/views/views_features.h
|
||||
index 78d8585e83bb12acb9e95867dfb586299c511277..838b40eb0aa31e12d6527f39a673f71af7ffa851 100644
|
||||
index 092e51509d4adccb8adbe2481909068e3e6836aa..5093a4c08bf6675ed1e5cb944c1bcb8251bdb033 100644
|
||||
--- a/ui/views/views_features.h
|
||||
+++ b/ui/views/views_features.h
|
||||
@@ -16,6 +16,7 @@ VIEWS_EXPORT BASE_DECLARE_FEATURE(kAnnounceTextAdditionalAttributes);
|
||||
VIEWS_EXPORT BASE_DECLARE_FEATURE(kApplyInitialUrlToWebContents);
|
||||
VIEWS_EXPORT BASE_DECLARE_FEATURE(kEnableClickjackingProtection);
|
||||
VIEWS_EXPORT BASE_DECLARE_FEATURE(kEnableInputProtection);
|
||||
VIEWS_EXPORT BASE_DECLARE_FEATURE(kEnableTouchDragCursorSync);
|
||||
+VIEWS_EXPORT BASE_DECLARE_FEATURE(kEnableTransparentHwndEnlargement);
|
||||
VIEWS_EXPORT BASE_DECLARE_FEATURE(kKeyboardAccessibleTooltipInViews);
|
||||
|
||||
@@ -6,7 +6,7 @@ Subject: scroll_bounce_flag.patch
|
||||
Patch to make scrollBounce option work.
|
||||
|
||||
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
|
||||
index 6dfee417bf6fbf94fd47aa4e9e9717378eabdfc9..623f2de73b5ae1c2129b8deb74faecb5a03423d2 100644
|
||||
index 98ffa5d66e413682f01b3a86a90d7889d73b999e..bbcef0b179405d44200aadcf01a6595f7f2bafa2 100644
|
||||
--- a/content/renderer/render_thread_impl.cc
|
||||
+++ b/content/renderer/render_thread_impl.cc
|
||||
@@ -1127,11 +1127,11 @@ bool RenderThreadImpl::IsLcdTextEnabled() {
|
||||
|
||||
@@ -22,7 +22,7 @@ However, the patch would need to be reviewed by the security team, as it
|
||||
does touch a security-sensitive class.
|
||||
|
||||
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
|
||||
index 23ddb2009a6118aad1f9629c7cd7a6d566b3bcc6..27c80d6dfca4c422be531bf5376bb23844e731a6 100644
|
||||
index 40c41c074c75ec04badee292310d13d393e42fdd..b45fb6cd8881315e2696eb1de4697c6077efb024 100644
|
||||
--- a/content/browser/renderer_host/render_process_host_impl.cc
|
||||
+++ b/content/browser/renderer_host/render_process_host_impl.cc
|
||||
@@ -1955,6 +1955,10 @@ bool RenderProcessHostImpl::Init() {
|
||||
|
||||
@@ -9,10 +9,10 @@ is needed for OSR.
|
||||
Originally landed in https://github.com/electron/libchromiumcontent/pull/226.
|
||||
|
||||
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
|
||||
index 16c4c2f73643314a9b8287e13a6472dff2671652..859643e7796440bf1966007c598effffba7e47c9 100644
|
||||
index bef008a5233d7e941d88d5353ce8940df5a17b84..1cc1fa8f02bd84a8c30de178fcb0a91da772bbcb 100644
|
||||
--- a/content/browser/web_contents/web_contents_impl.cc
|
||||
+++ b/content/browser/web_contents/web_contents_impl.cc
|
||||
@@ -4203,6 +4203,13 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params,
|
||||
@@ -4299,6 +4299,13 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params,
|
||||
params.main_frame_name, GetOpener(), primary_main_frame_policy,
|
||||
base::UnguessableToken::Create());
|
||||
|
||||
@@ -26,7 +26,7 @@ index 16c4c2f73643314a9b8287e13a6472dff2671652..859643e7796440bf1966007c598effff
|
||||
std::unique_ptr<WebContentsViewDelegate> delegate =
|
||||
GetContentClient()->browser()->GetWebContentsViewDelegate(this);
|
||||
|
||||
@@ -4213,6 +4220,7 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params,
|
||||
@@ -4309,6 +4316,7 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params,
|
||||
view_ = CreateWebContentsView(this, std::move(delegate),
|
||||
&render_view_host_delegate_view_);
|
||||
}
|
||||
@@ -35,7 +35,7 @@ index 16c4c2f73643314a9b8287e13a6472dff2671652..859643e7796440bf1966007c598effff
|
||||
CHECK(view_.get());
|
||||
|
||||
diff --git a/content/public/browser/web_contents.h b/content/public/browser/web_contents.h
|
||||
index a02a9134feae75d4fe95f2d8163983bdec447b2b..055302c00a625f4570c57243be3bd0ae02a73347 100644
|
||||
index 89902fe3d1fec3e0af044ab1737353f07ca6362d..b5982fd7f17a48c92ed2beb4e31a28f73714a66e 100644
|
||||
--- a/content/public/browser/web_contents.h
|
||||
+++ b/content/public/browser/web_contents.h
|
||||
@@ -130,11 +130,14 @@ class PrerenderHandle;
|
||||
|
||||
@@ -15,10 +15,10 @@ Note that we also need to manually update embedder's
|
||||
`api::WebContents::IsFullscreenForTabOrPending` value.
|
||||
|
||||
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
index 222cf1b2bbc98aa5e271426478a774f8a48e693d..865df1914009165ef0b0ea0e812e9e53535551bb 100644
|
||||
index 4530ef9ccef717342bc71e37f7a6005b8184b645..2a44f82dabfbb9d56846d44d52153056942c3925 100644
|
||||
--- a/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
@@ -9190,6 +9190,17 @@ void RenderFrameHostImpl::EnterFullscreen(
|
||||
@@ -9191,6 +9191,17 @@ void RenderFrameHostImpl::EnterFullscreen(
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,10 +37,10 @@ index 222cf1b2bbc98aa5e271426478a774f8a48e693d..865df1914009165ef0b0ea0e812e9e53
|
||||
if (had_fullscreen_token && !GetView()->HasFocus()) {
|
||||
GetView()->Focus();
|
||||
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
|
||||
index 859643e7796440bf1966007c598effffba7e47c9..76def190aabe280bb8e0971dc5c72643bbce8f53 100644
|
||||
index 1cc1fa8f02bd84a8c30de178fcb0a91da772bbcb..4fb9fcdc24376c81fe6092a484eb72a55e1ea45a 100644
|
||||
--- a/content/browser/web_contents/web_contents_impl.cc
|
||||
+++ b/content/browser/web_contents/web_contents_impl.cc
|
||||
@@ -4503,21 +4503,25 @@ KeyboardEventProcessingResult WebContentsImpl::PreHandleKeyboardEvent(
|
||||
@@ -4599,21 +4599,25 @@ KeyboardEventProcessingResult WebContentsImpl::PreHandleKeyboardEvent(
|
||||
const input::NativeWebKeyboardEvent& event) {
|
||||
OPTIONAL_TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("content.verbose"),
|
||||
"WebContentsImpl::PreHandleKeyboardEvent");
|
||||
@@ -80,7 +80,7 @@ index 859643e7796440bf1966007c598effffba7e47c9..76def190aabe280bb8e0971dc5c72643
|
||||
}
|
||||
|
||||
bool WebContentsImpl::HandleMouseEvent(const blink::WebMouseEvent& event) {
|
||||
@@ -4690,7 +4694,7 @@ void WebContentsImpl::EnterFullscreenMode(
|
||||
@@ -4792,7 +4796,7 @@ void WebContentsImpl::EnterFullscreenMode(
|
||||
OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::EnterFullscreenMode");
|
||||
DCHECK(CanEnterFullscreenMode(requesting_frame));
|
||||
DCHECK(requesting_frame->IsActive());
|
||||
|
||||
@@ -26,10 +26,10 @@ index 1f6c015c361b3146db760643e3670a110634d75b..d4d9c10d3420a5ff998aeb593ea6a255
|
||||
// An empty URL is returned if the URL is not overriden.
|
||||
virtual GURL OverrideFlashEmbedWithHTML(const GURL& url);
|
||||
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc
|
||||
index 78f0ab75486f90ad9bda568cd28c20ec0c48f298..5e2fff57b0a4e08d4263546a8914575501fc9082 100644
|
||||
index b21e367edf3e7bba172f3d63f5e3a18e53342ab4..d6cfc578d52fab79635fea73138262431abc3a63 100644
|
||||
--- a/content/renderer/renderer_blink_platform_impl.cc
|
||||
+++ b/content/renderer/renderer_blink_platform_impl.cc
|
||||
@@ -922,6 +922,12 @@ void RendererBlinkPlatformImpl::WillStopWorkerThread() {
|
||||
@@ -928,6 +928,12 @@ void RendererBlinkPlatformImpl::WillStopWorkerThread() {
|
||||
WorkerThreadRegistry::Instance()->WillStopCurrentWorkerThread();
|
||||
}
|
||||
|
||||
@@ -43,10 +43,10 @@ index 78f0ab75486f90ad9bda568cd28c20ec0c48f298..5e2fff57b0a4e08d4263546a89145755
|
||||
const v8::Local<v8::Context>& worker) {
|
||||
GetContentClient()->renderer()->DidInitializeWorkerContextOnWorkerThread(
|
||||
diff --git a/content/renderer/renderer_blink_platform_impl.h b/content/renderer/renderer_blink_platform_impl.h
|
||||
index 4535d0bf0328301f6ed1a602f6ff97a0243f7685..e191b4ef4185a6cb745c50e949ce6281719e0265 100644
|
||||
index 9664dd32d8945ca5303825377c8e345573d83a26..96898a41c3efe31e9043b092d37d7c4b42709bcc 100644
|
||||
--- a/content/renderer/renderer_blink_platform_impl.h
|
||||
+++ b/content/renderer/renderer_blink_platform_impl.h
|
||||
@@ -209,6 +209,7 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
|
||||
@@ -212,6 +212,7 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
|
||||
void DidStartWorkerThread() override;
|
||||
void WillStopWorkerThread() override;
|
||||
void WorkerContextCreated(const v8::Local<v8::Context>& worker) override;
|
||||
@@ -55,10 +55,10 @@ index 4535d0bf0328301f6ed1a602f6ff97a0243f7685..e191b4ef4185a6cb745c50e949ce6281
|
||||
const blink::WebSecurityOrigin& script_origin) override;
|
||||
blink::ProtocolHandlerSecurityLevel GetProtocolHandlerSecurityLevel(
|
||||
diff --git a/third_party/blink/public/platform/platform.h b/third_party/blink/public/platform/platform.h
|
||||
index a26e45d64229f692efb4a218c653afc212788d1f..4c797975567026268ea107f42e47f6411c5b7311 100644
|
||||
index bb80991d521edbb22bb08e50805dd8c131cf75a4..495f557bd1a727c95749b05ac7945292b372f371 100644
|
||||
--- a/third_party/blink/public/platform/platform.h
|
||||
+++ b/third_party/blink/public/platform/platform.h
|
||||
@@ -685,6 +685,7 @@ class BLINK_PLATFORM_EXPORT Platform {
|
||||
@@ -695,6 +695,7 @@ class BLINK_PLATFORM_EXPORT Platform {
|
||||
virtual void DidStartWorkerThread() {}
|
||||
virtual void WillStopWorkerThread() {}
|
||||
virtual void WorkerContextCreated(const v8::Local<v8::Context>& worker) {}
|
||||
|
||||
@@ -35,10 +35,10 @@ index d4d9c10d3420a5ff998aeb593ea6a25556d1215e..d64fef6bfc37264dcdc1bbea22eb5c4e
|
||||
// from the worker thread.
|
||||
virtual void WillDestroyWorkerContextOnWorkerThread(
|
||||
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc
|
||||
index 5e2fff57b0a4e08d4263546a8914575501fc9082..bfc88be930331b75be718fe3f7017f7ec477b086 100644
|
||||
index d6cfc578d52fab79635fea73138262431abc3a63..37b2b2820a817f79e8e43f49d84bbb1675a5dc9f 100644
|
||||
--- a/content/renderer/renderer_blink_platform_impl.cc
|
||||
+++ b/content/renderer/renderer_blink_platform_impl.cc
|
||||
@@ -934,6 +934,12 @@ void RendererBlinkPlatformImpl::WorkerContextCreated(
|
||||
@@ -940,6 +940,12 @@ void RendererBlinkPlatformImpl::WorkerContextCreated(
|
||||
worker);
|
||||
}
|
||||
|
||||
@@ -52,10 +52,10 @@ index 5e2fff57b0a4e08d4263546a8914575501fc9082..bfc88be930331b75be718fe3f7017f7e
|
||||
const blink::WebSecurityOrigin& script_origin) {
|
||||
return GetContentClient()->renderer()->AllowScriptExtensionForServiceWorker(
|
||||
diff --git a/content/renderer/renderer_blink_platform_impl.h b/content/renderer/renderer_blink_platform_impl.h
|
||||
index e191b4ef4185a6cb745c50e949ce6281719e0265..826134f19df305cb79598739174bc09808ea472e 100644
|
||||
index 96898a41c3efe31e9043b092d37d7c4b42709bcc..f6fbc3f4893b1894f4170a4b595ec8e72146b5bc 100644
|
||||
--- a/content/renderer/renderer_blink_platform_impl.h
|
||||
+++ b/content/renderer/renderer_blink_platform_impl.h
|
||||
@@ -209,6 +209,8 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
|
||||
@@ -212,6 +212,8 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
|
||||
void DidStartWorkerThread() override;
|
||||
void WillStopWorkerThread() override;
|
||||
void WorkerContextCreated(const v8::Local<v8::Context>& worker) override;
|
||||
@@ -65,10 +65,10 @@ index e191b4ef4185a6cb745c50e949ce6281719e0265..826134f19df305cb79598739174bc098
|
||||
bool AllowScriptExtensionForServiceWorker(
|
||||
const blink::WebSecurityOrigin& script_origin) override;
|
||||
diff --git a/third_party/blink/public/platform/platform.h b/third_party/blink/public/platform/platform.h
|
||||
index 4c797975567026268ea107f42e47f6411c5b7311..ae463faa3d16ab2697a4c20f3b038755205188f7 100644
|
||||
index 495f557bd1a727c95749b05ac7945292b372f371..6588d1fabf1c05950f0cd2768fbbef9fe48a036a 100644
|
||||
--- a/third_party/blink/public/platform/platform.h
|
||||
+++ b/third_party/blink/public/platform/platform.h
|
||||
@@ -685,6 +685,8 @@ class BLINK_PLATFORM_EXPORT Platform {
|
||||
@@ -695,6 +695,8 @@ class BLINK_PLATFORM_EXPORT Platform {
|
||||
virtual void DidStartWorkerThread() {}
|
||||
virtual void WillStopWorkerThread() {}
|
||||
virtual void WorkerContextCreated(const v8::Local<v8::Context>& worker) {}
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
chore_expose_ui_to_allow_electron_to_set_dock_side.patch
|
||||
fix_prefer_browser_runtime_over_node_in_hostruntime_detection.patch
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shelley Vohr <shelley.vohr@gmail.com>
|
||||
Date: Thu, 12 Mar 2026 17:03:29 +0100
|
||||
Subject: fix: prefer browser runtime over node in HostRuntime detection
|
||||
|
||||
In Electron, the `process` global is available in renderer processes,
|
||||
including the DevTools renderer. This causes the IS_NODE check to pass,
|
||||
leading DevTools to attempt importing the Node.js platform runtime
|
||||
(which uses `node:worker_threads`). However, DevTools Web Workers
|
||||
running under the `devtools://` protocol don't have access to Node.js
|
||||
built-in modules, resulting in a failed dynamic import.
|
||||
|
||||
Fix by checking IS_BROWSER first, since DevTools always runs in a
|
||||
browser-like environment. The Node.js runtime is only needed when
|
||||
DevTools runs under pure Node.js (e.g., CLI tooling or testing).
|
||||
|
||||
diff --git a/front_end/core/platform/HostRuntime.ts b/front_end/core/platform/HostRuntime.ts
|
||||
index 91adba7c966a9c4c0e5315d2cfee07f8f622b731..16822b8d4ea74a4ffd6870e5e95948d75918f5d2 100644
|
||||
--- a/front_end/core/platform/HostRuntime.ts
|
||||
+++ b/front_end/core/platform/HostRuntime.ts
|
||||
@@ -14,12 +14,12 @@ export const IS_BROWSER =
|
||||
typeof window !== 'undefined' || (typeof self !== 'undefined' && typeof self.postMessage === 'function');
|
||||
|
||||
export const HOST_RUNTIME = await (async(): Promise<Api.HostRuntime.HostRuntime> => {
|
||||
- if (IS_NODE) {
|
||||
- return (await import('./node/node.js')).HostRuntime.HOST_RUNTIME;
|
||||
- }
|
||||
if (IS_BROWSER) {
|
||||
return (await import('./browser/browser.js')).HostRuntime.HOST_RUNTIME;
|
||||
}
|
||||
+ if (IS_NODE) {
|
||||
+ return (await import('./node/node.js')).HostRuntime.HOST_RUNTIME;
|
||||
+ }
|
||||
|
||||
throw new Error('Unknown runtime!');
|
||||
})();
|
||||
@@ -533,10 +533,10 @@ index 55a0c986c5b6989ee9ce277bb6a9778abb2ad2ee..809d88f21e5572807e38132d40ee7587
|
||||
READONLY_PROPERTY(target, "exitCodes", exit_codes);
|
||||
|
||||
diff --git a/src/node_file.cc b/src/node_file.cc
|
||||
index ba6ffc2b6565dea500bc8dd4818c8fcb7648694a..e834325a763f7ea8f53210145b5edd134d6b67e6 100644
|
||||
index 96aac2d86695732bf6805f2ad2168a62241b5045..547455bb5011677719a8de1f98cb447561bce6aa 100644
|
||||
--- a/src/node_file.cc
|
||||
+++ b/src/node_file.cc
|
||||
@@ -3843,7 +3843,7 @@ void BindingData::Deserialize(Local<Context> context,
|
||||
@@ -3850,7 +3850,7 @@ void BindingData::Deserialize(Local<Context> context,
|
||||
int index,
|
||||
InternalFieldInfoBase* info) {
|
||||
DCHECK_IS_SNAPSHOT_SLOT(index);
|
||||
@@ -686,7 +686,7 @@ index d33ee3c26c111e53edf27e6368ca8f64ff30a349..f1c53c44f201b295888e7932c5e3e2b1
|
||||
|
||||
Environment* env = Environment::GetCurrent(isolate);
|
||||
diff --git a/src/node_url.cc b/src/node_url.cc
|
||||
index 9d1e8ec05161570db11f7b662395509774668d78..9b91f83d879ea02fd3d61913c8dfd35b3bf1ac31 100644
|
||||
index 9b676a0156ab8ef47f62627be953c23d4fcbf4f4..6294cd03667980e2ad23cae9e7961262369efb62 100644
|
||||
--- a/src/node_url.cc
|
||||
+++ b/src/node_url.cc
|
||||
@@ -70,7 +70,7 @@ void BindingData::Deserialize(Local<Context> context,
|
||||
|
||||
@@ -7,7 +7,7 @@ Subject: build: ensure native module compilation fails if not using a new
|
||||
This should not be upstreamed, it is a quality-of-life patch for downstream module builders.
|
||||
|
||||
diff --git a/common.gypi b/common.gypi
|
||||
index b3b5c23e471ece7584d209b3ae4197c46011d50e..bdcea65ad3e0315c85b1818e695d8b63093aed34 100644
|
||||
index d9eb9527e3cbb3b101274ab19e6d6ace42f0e022..a1243ad39b8fcf564285ace0b51b1482bd85071b 100644
|
||||
--- a/common.gypi
|
||||
+++ b/common.gypi
|
||||
@@ -89,6 +89,8 @@
|
||||
|
||||
@@ -11,7 +11,7 @@ node-gyp will use the result of `process.config` that reflects the environment
|
||||
in which the binary got built.
|
||||
|
||||
diff --git a/common.gypi b/common.gypi
|
||||
index bdcea65ad3e0315c85b1818e695d8b63093aed34..0653735a0b154e326e5df7049a7beb395f0015c8 100644
|
||||
index a1243ad39b8fcf564285ace0b51b1482bd85071b..60ac7a50718fd8239fd96b811cdccd1c73b2d606 100644
|
||||
--- a/common.gypi
|
||||
+++ b/common.gypi
|
||||
@@ -128,6 +128,7 @@
|
||||
|
||||
@@ -10,7 +10,7 @@ M151, and so we should allow for building until then.
|
||||
This patch can be removed at the M151 branch point.
|
||||
|
||||
diff --git a/common.gypi b/common.gypi
|
||||
index 0653735a0b154e326e5df7049a7beb395f0015c8..006f52ed18d955da0d9a06e881e86e6e724095ac 100644
|
||||
index 60ac7a50718fd8239fd96b811cdccd1c73b2d606..709eb83801eeed81f79c4305a86d1a19710298c2 100644
|
||||
--- a/common.gypi
|
||||
+++ b/common.gypi
|
||||
@@ -677,7 +677,7 @@
|
||||
|
||||
@@ -7,7 +7,7 @@ common.gypi is a file that's included in the node header bundle, despite
|
||||
the fact that we do not build node with gyp.
|
||||
|
||||
diff --git a/common.gypi b/common.gypi
|
||||
index c5a7dc9cacf8b983984e7c7de9e63d26e418cc8d..b3b5c23e471ece7584d209b3ae4197c46011d50e 100644
|
||||
index 283c60eab356a5befc15027cd186ea0416914ee6..d9eb9527e3cbb3b101274ab19e6d6ace42f0e022 100644
|
||||
--- a/common.gypi
|
||||
+++ b/common.gypi
|
||||
@@ -91,6 +91,23 @@
|
||||
|
||||
@@ -53,10 +53,10 @@ index 81799fc159cf20344aac64cd7129240deb9a4fe8..12b476ff97603718186dd25b1f435d37
|
||||
const maybeMain = resolvedOption <= legacyMainResolveExtensionsIndexes.kResolvedByMainIndexNode ?
|
||||
packageConfig.main || './' : '';
|
||||
diff --git a/src/node_file.cc b/src/node_file.cc
|
||||
index 58476306172433db98a3e3a1ab31d13bf42014f1..ba6ffc2b6565dea500bc8dd4818c8fcb7648694a 100644
|
||||
index c69b4eb461cab79906833152d02f76f81149ad7e..96aac2d86695732bf6805f2ad2168a62241b5045 100644
|
||||
--- a/src/node_file.cc
|
||||
+++ b/src/node_file.cc
|
||||
@@ -3592,13 +3592,25 @@ static void CpSyncCopyDir(const FunctionCallbackInfo<Value>& args) {
|
||||
@@ -3599,13 +3599,25 @@ static void CpSyncCopyDir(const FunctionCallbackInfo<Value>& args) {
|
||||
}
|
||||
|
||||
BindingData::FilePathIsFileReturnType BindingData::FilePathIsFile(
|
||||
@@ -83,7 +83,7 @@ index 58476306172433db98a3e3a1ab31d13bf42014f1..ba6ffc2b6565dea500bc8dd4818c8fcb
|
||||
uv_fs_t req;
|
||||
|
||||
int rc = uv_fs_stat(env->event_loop(), &req, file_path.c_str(), nullptr);
|
||||
@@ -3656,6 +3668,11 @@ void BindingData::LegacyMainResolve(const FunctionCallbackInfo<Value>& args) {
|
||||
@@ -3663,6 +3675,11 @@ void BindingData::LegacyMainResolve(const FunctionCallbackInfo<Value>& args) {
|
||||
std::optional<std::string> initial_file_path;
|
||||
std::string file_path;
|
||||
|
||||
@@ -95,7 +95,7 @@ index 58476306172433db98a3e3a1ab31d13bf42014f1..ba6ffc2b6565dea500bc8dd4818c8fcb
|
||||
if (args.Length() >= 2 && args[1]->IsString()) {
|
||||
auto package_config_main = Utf8Value(isolate, args[1]).ToString();
|
||||
|
||||
@@ -3676,7 +3693,7 @@ void BindingData::LegacyMainResolve(const FunctionCallbackInfo<Value>& args) {
|
||||
@@ -3683,7 +3700,7 @@ void BindingData::LegacyMainResolve(const FunctionCallbackInfo<Value>& args) {
|
||||
BufferValue buff_file_path(isolate, local_file_path);
|
||||
ToNamespacedPath(env, &buff_file_path);
|
||||
|
||||
@@ -104,7 +104,7 @@ index 58476306172433db98a3e3a1ab31d13bf42014f1..ba6ffc2b6565dea500bc8dd4818c8fcb
|
||||
case BindingData::FilePathIsFileReturnType::kIsFile:
|
||||
return args.GetReturnValue().Set(i);
|
||||
case BindingData::FilePathIsFileReturnType::kIsNotFile:
|
||||
@@ -3713,7 +3730,7 @@ void BindingData::LegacyMainResolve(const FunctionCallbackInfo<Value>& args) {
|
||||
@@ -3720,7 +3737,7 @@ void BindingData::LegacyMainResolve(const FunctionCallbackInfo<Value>& args) {
|
||||
BufferValue buff_file_path(isolate, local_file_path);
|
||||
ToNamespacedPath(env, &buff_file_path);
|
||||
|
||||
|
||||
@@ -7,10 +7,10 @@ libc++ added [[nodiscard]] to std::filesystem::copy_options operator|=
|
||||
which causes build failures with -Werror.
|
||||
|
||||
diff --git a/src/node_file.cc b/src/node_file.cc
|
||||
index e834325a763f7ea8f53210145b5edd134d6b67e6..5197202255bcd9345ac19c7fb6106f49c2800770 100644
|
||||
index 547455bb5011677719a8de1f98cb447561bce6aa..385db5fd6fe5db6bb7ff17e98309b6cd605a82d3 100644
|
||||
--- a/src/node_file.cc
|
||||
+++ b/src/node_file.cc
|
||||
@@ -3453,11 +3453,11 @@ static void CpSyncCopyDir(const FunctionCallbackInfo<Value>& args) {
|
||||
@@ -3460,11 +3460,11 @@ static void CpSyncCopyDir(const FunctionCallbackInfo<Value>& args) {
|
||||
|
||||
auto file_copy_opts = std::filesystem::copy_options::recursive;
|
||||
if (force) {
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
chore_allow_customizing_microtask_policy_per_context.patch
|
||||
build_warn_instead_of_abort_on_builtin_pgo_profile_mismatch.patch
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Sam Attard <sattard@anthropic.com>
|
||||
Date: Sun, 22 Mar 2026 10:51:26 +0000
|
||||
Subject: build: warn instead of abort on builtin PGO profile mismatch
|
||||
|
||||
Electron sets v8_enable_javascript_promise_hooks = true to support
|
||||
Node.js async_hooks (see node/src/env.cc SetPromiseHooks usage:
|
||||
https://github.com/nodejs/node/blob/abff716eaccd0c4f4949d1315cb057a45979649d/src/env.cc#L223-L236).
|
||||
This flag adds conditional branches to builtins-microtask-queue-gen.cc
|
||||
and promise-misc.tq, changing the control-flow graph hash of several
|
||||
Promise/async builtins. This invalidates V8's pre-generated PGO profile
|
||||
for those builtins (built with Chrome defaults where the flag is off).
|
||||
|
||||
Rather than disabling builtins PGO entirely, warn and skip mismatched
|
||||
builtins so all other builtins still benefit from PGO.
|
||||
|
||||
diff --git a/BUILD.gn b/BUILD.gn
|
||||
index 4b7de10c45c1c6530b2105eb10be204128821042..01893af66b8a9c9cc39a25e9287c32c5dc37537e 100644
|
||||
--- a/BUILD.gn
|
||||
+++ b/BUILD.gn
|
||||
@@ -2803,9 +2803,11 @@ template("run_mksnapshot") {
|
||||
"--turbo-profiling-input",
|
||||
rebase_path(v8_builtins_profiling_log_file, root_build_dir),
|
||||
|
||||
- # Replace this with --warn-about-builtin-profile-data to see the full
|
||||
- # list of builtins with incompatible profiles.
|
||||
- "--abort-on-bad-builtin-profile-data",
|
||||
+ # Electron: Use warn instead of abort so that builtins whose control
|
||||
+ # flow is changed by Electron's build flags (e.g. RunMicrotasks via
|
||||
+ # v8_enable_javascript_promise_hooks) are skipped rather than failing
|
||||
+ # the build. All other builtins still receive PGO.
|
||||
+ "--warn-about-builtin-profile-data",
|
||||
]
|
||||
|
||||
if (!v8_enable_builtins_profiling && v8_enable_builtins_reordering) {
|
||||
@@ -11,7 +11,7 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const ELECTRON_DIR = resolve(__dirname, '..');
|
||||
|
||||
const DEPS_REGEX = /chromium_version':\n +'(.+?)',/m;
|
||||
const CL_REGEX = /https:\/\/chromium-review\.googlesource\.com\/c\/(?:chromium\/src|v8\/v8)\/\+\/(\d+)(#\S+)?/g;
|
||||
const CL_REGEX = /https:\/\/chromium-review\.googlesource\.com\/c\/(chromium\/src|devtools\/devtools-frontend|v8\/v8)\/\+\/(\d+)(#\S+)?/g;
|
||||
const ROLLER_BRANCH_PATTERN = /^roller\/chromium\/(.+)$/;
|
||||
|
||||
function getCurrentBranch () {
|
||||
@@ -177,8 +177,9 @@ async function main () {
|
||||
|
||||
const cls = [...commit.message.matchAll(CL_REGEX)].map((match) => ({
|
||||
url: match[0],
|
||||
clNumber: match[1],
|
||||
fragment: match[2] ?? null
|
||||
fullRepo: match[1],
|
||||
clNumber: match[2],
|
||||
fragment: match[3] ?? null
|
||||
}));
|
||||
|
||||
if (cls.length === 0) {
|
||||
@@ -207,9 +208,7 @@ async function main () {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Determine repo from URL
|
||||
const isV8 = cl.url.startsWith('https://chromium-review.googlesource.com/c/v8/v8/');
|
||||
const repo = isV8 ? 'v8' : 'chromium';
|
||||
const repo = cl.fullRepo.split('/')[0];
|
||||
|
||||
// Fetch Gerrit details to get commit SHA
|
||||
const gerritDetails = await getGerritPatchDetails(cl.url);
|
||||
@@ -243,9 +242,9 @@ async function main () {
|
||||
continue;
|
||||
}
|
||||
|
||||
// For V8 CLs, we need to find the corresponding Chromium commit
|
||||
// For non-Chromium CLs, we need to find the corresponding Chromium commit
|
||||
let chromiumVersion = clEarliestVersion;
|
||||
if (isV8 && dashDetails.relations) {
|
||||
if (repo !== 'chromium' && dashDetails.relations) {
|
||||
const chromiumRelation = dashDetails.relations.find(
|
||||
(rel) => rel.from_commit === gerritDetails.commitSha
|
||||
);
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "base/apple/scoped_nsautorelease_pool.h"
|
||||
#include "base/at_exit.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/compiler_specific.h"
|
||||
#include "base/i18n/icu_util.h"
|
||||
#include "base/notreached.h"
|
||||
#include "content/public/app/content_main.h"
|
||||
@@ -33,7 +34,10 @@ int ElectronMain(int argc, char* argv[]) {
|
||||
delegate.OverrideFrameworkBundlePath();
|
||||
delegate.SetUpBundleOverrides();
|
||||
|
||||
return content::ContentMain(content::ContentMainParams{&delegate});
|
||||
content::ContentMainParams params{&delegate};
|
||||
params.argc = argc;
|
||||
params.argv = UNSAFE_BUFFERS(const_cast<const char**>(argv));
|
||||
return content::ContentMain(std::move(params));
|
||||
}
|
||||
|
||||
int ElectronInitializeICUandStartNode(int argc, char* argv[]) {
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "base/at_exit.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/compiler_specific.h"
|
||||
#include "base/i18n/icu_util.h"
|
||||
#include "base/strings/cstring_view.h"
|
||||
#include "content/public/app/content_main.h"
|
||||
@@ -29,6 +30,9 @@ namespace {
|
||||
int main(int argc, char* argv[]) {
|
||||
FixStdioStreams();
|
||||
|
||||
// Chromium expects the original argv in its original memory location
|
||||
// to update /proc/<pid>/cmdline.
|
||||
const char** original_argv = UNSAFE_BUFFERS(const_cast<const char**>(argv));
|
||||
argv = uv_setup_args(argc, argv);
|
||||
base::CommandLine::Init(argc, argv);
|
||||
electron::ElectronCommandLine::Init(argc, argv);
|
||||
@@ -40,5 +44,8 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
|
||||
electron::ElectronMainDelegate delegate;
|
||||
return content::ContentMain(content::ContentMainParams{&delegate});
|
||||
content::ContentMainParams params{&delegate};
|
||||
params.argc = argc;
|
||||
params.argv = original_argv;
|
||||
return content::ContentMain(std::move(params));
|
||||
}
|
||||
|
||||
@@ -151,7 +151,10 @@ void OnTraceBufferUsageAvailable(
|
||||
gin_helper::Promise<gin_helper::Dictionary> promise,
|
||||
float percent_full,
|
||||
size_t approximate_count) {
|
||||
auto dict = gin_helper::Dictionary::CreateEmpty(promise.isolate());
|
||||
v8::Isolate* isolate = promise.isolate();
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
|
||||
auto dict = gin_helper::Dictionary::CreateEmpty(isolate);
|
||||
dict.Set("percentage", percent_full);
|
||||
dict.Set("value", approximate_count);
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ v8::Local<v8::Value> ServiceWorkerRunningInfoToDict(
|
||||
return gin::DataObjectBuilder(isolate)
|
||||
.Set("scriptUrl", info.script_url.spec())
|
||||
.Set("scope", info.scope.spec())
|
||||
.Set("renderProcessId", info.render_process_id)
|
||||
.Set("renderProcessId", info.render_process_id.GetUnsafeValue())
|
||||
.Build();
|
||||
}
|
||||
|
||||
|
||||
@@ -1469,9 +1469,8 @@ void ElectronBrowserClient::RegisterAssociatedInterfaceBindersForServiceWorker(
|
||||
base::BindRepeating(&extensions::RendererStartupHelper::BindForRenderer,
|
||||
service_worker_version_info.process_id));
|
||||
associated_registry.AddInterface<extensions::mojom::ServiceWorkerHost>(
|
||||
base::BindRepeating(
|
||||
&extensions::ServiceWorkerHost::BindReceiver,
|
||||
service_worker_version_info.process_id.GetUnsafeValue()));
|
||||
base::BindRepeating(&extensions::ServiceWorkerHost::BindReceiver,
|
||||
service_worker_version_info.process_id));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -72,7 +72,8 @@ std::wstring NotificationPresenterWin::SaveIconToFilesystem(
|
||||
|
||||
std::string filename;
|
||||
if (origin.is_valid()) {
|
||||
filename = base::SHA1HashString(origin.spec()) + ".png";
|
||||
const auto hash = base::SHA1HashString(origin.spec());
|
||||
filename = base::HexEncode(hash) + ".png";
|
||||
} else {
|
||||
const int64_t now_usec = base::Time::Now().since_origin().InMicroseconds();
|
||||
filename = base::NumberToString(now_usec) + ".png";
|
||||
|
||||
@@ -133,6 +133,21 @@ std::wstring GetExecutablePath() {
|
||||
return std::wstring(path, len);
|
||||
}
|
||||
|
||||
// Installers sometimes put the running app in a versioned subfolder and ship a
|
||||
// stub with the same filename one directory up. Point the Start Menu shortcut
|
||||
// at the stub when it exists so toast activation and updates keep a stable
|
||||
// launch path.
|
||||
std::wstring GetShortcutTargetPath(const std::wstring& exe_path) {
|
||||
if (exe_path.empty())
|
||||
return L"";
|
||||
base::FilePath exe_fp(exe_path);
|
||||
base::FilePath stub_candidate =
|
||||
exe_fp.DirName().DirName().Append(exe_fp.BaseName());
|
||||
if (base::PathExists(stub_candidate))
|
||||
return stub_candidate.value();
|
||||
return exe_path;
|
||||
}
|
||||
|
||||
void EnsureCLSIDRegistry() {
|
||||
std::wstring exe = GetExecutablePath();
|
||||
if (exe.empty())
|
||||
@@ -153,7 +168,10 @@ void EnsureCLSIDRegistry() {
|
||||
server_key.WriteValue(nullptr, exe.c_str());
|
||||
}
|
||||
|
||||
bool ExistingShortcutValid(const base::FilePath& lnk_path, PCWSTR aumid) {
|
||||
bool ExistingShortcutValid(const base::FilePath& lnk_path,
|
||||
PCWSTR aumid,
|
||||
const std::wstring& expected_target_path,
|
||||
const std::wstring& expected_working_dir) {
|
||||
if (!base::PathExists(lnk_path))
|
||||
return false;
|
||||
Microsoft::WRL::ComPtr<IShellLink> existing;
|
||||
@@ -165,6 +183,31 @@ bool ExistingShortcutValid(const base::FilePath& lnk_path, PCWSTR aumid) {
|
||||
FAILED(pf->Load(lnk_path.value().c_str(), STGM_READ))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// After an auto-update the .lnk may still have the correct AUMID/CLSID but
|
||||
// point at an old install path; treat that as invalid so we rewrite it.
|
||||
wchar_t target_path[MAX_PATH];
|
||||
if (FAILED(existing->GetPath(target_path, MAX_PATH, nullptr, SLGP_RAWPATH)))
|
||||
return false;
|
||||
if (base::FilePath::CompareIgnoreCase(
|
||||
base::FilePath(expected_target_path).value(),
|
||||
base::FilePath(target_path).value()) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
wchar_t work_dir[MAX_PATH];
|
||||
work_dir[0] = L'\0';
|
||||
if (FAILED(existing->GetWorkingDirectory(work_dir, MAX_PATH)))
|
||||
return false;
|
||||
base::FilePath expected_cwd =
|
||||
base::FilePath(expected_working_dir).NormalizePathSeparators();
|
||||
base::FilePath actual_cwd =
|
||||
base::FilePath(work_dir).NormalizePathSeparators();
|
||||
if (base::FilePath::CompareIgnoreCase(expected_cwd.value(),
|
||||
actual_cwd.value()) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Microsoft::WRL::ComPtr<IPropertyStore> store;
|
||||
if (FAILED(existing.As(&store)))
|
||||
return false;
|
||||
@@ -194,6 +237,7 @@ void EnsureShortcut() {
|
||||
std::wstring exe = GetExecutablePath();
|
||||
if (exe.empty())
|
||||
return;
|
||||
std::wstring shortcut_target = GetShortcutTargetPath(exe);
|
||||
|
||||
PWSTR programs_path = nullptr;
|
||||
if (FAILED(
|
||||
@@ -232,18 +276,20 @@ void EnsureShortcut() {
|
||||
}
|
||||
}
|
||||
|
||||
if (ExistingShortcutValid(lnk_path, aumid))
|
||||
const std::wstring expected_working_dir =
|
||||
base::FilePath(exe).DirName().value();
|
||||
if (ExistingShortcutValid(lnk_path, aumid, shortcut_target,
|
||||
expected_working_dir))
|
||||
return;
|
||||
|
||||
Microsoft::WRL::ComPtr<IShellLink> shell_link;
|
||||
if (FAILED(CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER,
|
||||
IID_PPV_ARGS(&shell_link))))
|
||||
return;
|
||||
shell_link->SetPath(exe.c_str());
|
||||
shell_link->SetPath(shortcut_target.c_str());
|
||||
shell_link->SetArguments(L"");
|
||||
shell_link->SetDescription(product_name.c_str());
|
||||
shell_link->SetWorkingDirectory(
|
||||
base::FilePath(exe).DirName().value().c_str());
|
||||
shell_link->SetWorkingDirectory(expected_working_dir.c_str());
|
||||
|
||||
Microsoft::WRL::ComPtr<IPropertyStore> prop_store;
|
||||
if (SUCCEEDED(shell_link.As(&prop_store))) {
|
||||
|
||||
@@ -478,7 +478,6 @@ NSArray* ConvertSharingItemToNS(const SharingItem& item) {
|
||||
|
||||
if (![represented
|
||||
isKindOfClass:[WeakPtrToElectronMenuModelAsNSObject class]]) {
|
||||
NSLog(@"representedObject is not a WeakPtrToElectronMenuModelAsNSObject");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -473,23 +473,27 @@ void ElectronAccessibilityUIMessageHandler::RequestNativeUITree(
|
||||
void ElectronAccessibilityUIMessageHandler::RegisterMessages() {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
|
||||
web_ui()->RegisterMessageCallback(
|
||||
"initialize",
|
||||
base::BindRepeating(&AccessibilityUIMessageHandler::HandleInitialize,
|
||||
base::Unretained(this)));
|
||||
web_ui()->RegisterMessageCallback(
|
||||
"toggleAccessibility",
|
||||
base::BindRepeating(
|
||||
&AccessibilityUIMessageHandler::ToggleAccessibilityForWebContents,
|
||||
base::Unretained(this)));
|
||||
base::BindRepeating(&AccessibilityUIMessageHandler::
|
||||
HandleToggleAccessibilityForWebContents,
|
||||
base::Unretained(this)));
|
||||
web_ui()->RegisterMessageCallback(
|
||||
"setGlobalFlag",
|
||||
base::BindRepeating(&AccessibilityUIMessageHandler::SetGlobalFlag,
|
||||
base::BindRepeating(&AccessibilityUIMessageHandler::HandleSetGlobalFlag,
|
||||
base::Unretained(this)));
|
||||
web_ui()->RegisterMessageCallback(
|
||||
"setGlobalString",
|
||||
base::BindRepeating(&AccessibilityUIMessageHandler::SetGlobalString,
|
||||
base::BindRepeating(&AccessibilityUIMessageHandler::HandleSetGlobalString,
|
||||
base::Unretained(this)));
|
||||
web_ui()->RegisterMessageCallback(
|
||||
"requestWebContentsTree",
|
||||
base::BindRepeating(
|
||||
&AccessibilityUIMessageHandler::RequestWebContentsTree,
|
||||
&AccessibilityUIMessageHandler::HandleRequestWebContentsTree,
|
||||
base::Unretained(this)));
|
||||
web_ui()->RegisterMessageCallback(
|
||||
"requestNativeUITree",
|
||||
@@ -499,13 +503,14 @@ void ElectronAccessibilityUIMessageHandler::RegisterMessages() {
|
||||
#if defined(USE_AURA)
|
||||
web_ui()->RegisterMessageCallback(
|
||||
"requestWidgetsTree",
|
||||
base::BindRepeating(&AccessibilityUIMessageHandler::RequestWidgetsTree,
|
||||
base::Unretained(this)));
|
||||
base::BindRepeating(
|
||||
&AccessibilityUIMessageHandler::HandleRequestWidgetsTree,
|
||||
base::Unretained(this)));
|
||||
#endif
|
||||
web_ui()->RegisterMessageCallback(
|
||||
"requestAccessibilityEvents",
|
||||
base::BindRepeating(
|
||||
&AccessibilityUIMessageHandler::RequestAccessibilityEvents,
|
||||
&AccessibilityUIMessageHandler::HandleRequestAccessibilityEvents,
|
||||
base::Unretained(this)));
|
||||
|
||||
auto* web_contents = web_ui()->GetWebContents();
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "shell/common/process_util.h"
|
||||
#include "third_party/skia/include/core/SkBitmap.h"
|
||||
#include "ui/base/clipboard/clipboard_format_type.h"
|
||||
#include "ui/base/clipboard/clipboard_url_info.h"
|
||||
#include "ui/base/clipboard/file_info.h"
|
||||
#include "ui/base/clipboard/scoped_clipboard_writer.h"
|
||||
#include "ui/gfx/codec/png_codec.h"
|
||||
@@ -210,7 +211,8 @@ void Clipboard::Write(const gin_helper::Dictionary& data,
|
||||
writer.WriteText(text);
|
||||
|
||||
if (data.Get("bookmark", &bookmark))
|
||||
writer.WriteBookmark(bookmark, base::UTF16ToUTF8(text));
|
||||
writer.WriteURL(
|
||||
ui::ClipboardUrlInfo{.url = GURL(text), .title = bookmark});
|
||||
}
|
||||
|
||||
if (data.Get("rtf", &text)) {
|
||||
@@ -333,13 +335,13 @@ v8::Local<v8::Value> Clipboard::ReadBookmark(v8::Isolate* const isolate) {
|
||||
ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
|
||||
|
||||
base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed);
|
||||
clipboard->ReadBookmark(
|
||||
clipboard->ReadURL(
|
||||
/* data_dst = */ std::nullopt,
|
||||
base::BindOnce(
|
||||
[](std::u16string* out_title, GURL* out_url, base::OnceClosure quit,
|
||||
std::u16string title, GURL url) {
|
||||
*out_title = std::move(title);
|
||||
*out_url = std::move(url);
|
||||
ui::ClipboardUrlInfo url_info) {
|
||||
*out_title = std::move(url_info.title);
|
||||
*out_url = std::move(url_info.url);
|
||||
std::move(quit).Run();
|
||||
},
|
||||
&title, &url, run_loop.QuitClosure()));
|
||||
@@ -354,7 +356,7 @@ void Clipboard::WriteBookmark(const std::u16string& title,
|
||||
const std::string& url,
|
||||
gin::Arguments* const args) {
|
||||
ui::ScopedClipboardWriter writer(GetClipboardBuffer(args));
|
||||
writer.WriteBookmark(title, url);
|
||||
writer.WriteURL(ui::ClipboardUrlInfo{.url = GURL(url), .title = title});
|
||||
}
|
||||
|
||||
gfx::Image Clipboard::ReadImage(gin::Arguments* const args) {
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#ifndef ELECTRON_SHELL_COMMON_GIN_CONVERTERS_FILE_PATH_CONVERTER_H_
|
||||
#define ELECTRON_SHELL_COMMON_GIN_CONVERTERS_FILE_PATH_CONVERTER_H_
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
#include "gin/converter.h"
|
||||
#include "shell/common/gin_converters/std_converter.h"
|
||||
@@ -30,6 +32,11 @@ struct Converter<base::FilePath> {
|
||||
|
||||
base::FilePath::StringType path;
|
||||
if (Converter<base::FilePath::StringType>::FromV8(isolate, val, &path)) {
|
||||
bool has_control_chars = std::any_of(
|
||||
path.begin(), path.end(),
|
||||
[](base::FilePath::CharType c) { return c >= 0 && c < 0x20; });
|
||||
if (has_control_chars)
|
||||
return false;
|
||||
*out = base::FilePath(path);
|
||||
return true;
|
||||
} else {
|
||||
|
||||
@@ -608,6 +608,9 @@ bool Converter<scoped_refptr<network::ResourceRequestBody>>::FromV8(
|
||||
const std::string* file = dict.FindString("filePath");
|
||||
if (!file)
|
||||
return false;
|
||||
if (std::any_of(file->begin(), file->end(),
|
||||
[](char c) { return c >= 0 && c < 0x20; }))
|
||||
return false;
|
||||
double modification_time =
|
||||
dict.FindDouble("modificationTime").value_or(0.0);
|
||||
int offset = dict.FindInt("offset").value_or(0);
|
||||
|
||||
@@ -132,6 +132,36 @@ ifdescribe(!(['arm', 'arm64'].includes(process.arch)) || (process.platform !== '
|
||||
});
|
||||
});
|
||||
|
||||
describe('getTraceBufferUsage', function () {
|
||||
this.timeout(10e3);
|
||||
|
||||
it('does not crash and returns valid usage data', async () => {
|
||||
await app.whenReady();
|
||||
await contentTracing.startRecording({
|
||||
categoryFilter: '*',
|
||||
traceOptions: 'record-until-full'
|
||||
});
|
||||
|
||||
// Yield to the event loop so the JS HandleScope from this tick is gone.
|
||||
// When the Mojo response arrives it fires OnTraceBufferUsageAvailable
|
||||
// as a plain Chromium task — if that callback lacks its own HandleScope
|
||||
// the process will crash with "Cannot create a handle without a HandleScope".
|
||||
const result = await contentTracing.getTraceBufferUsage();
|
||||
|
||||
expect(result).to.have.property('percentage').that.is.a('number');
|
||||
expect(result).to.have.property('value').that.is.a('number');
|
||||
|
||||
await contentTracing.stopRecording();
|
||||
});
|
||||
|
||||
it('returns zero usage when no trace is active', async () => {
|
||||
await app.whenReady();
|
||||
const result = await contentTracing.getTraceBufferUsage();
|
||||
expect(result).to.have.property('percentage').that.is.a('number');
|
||||
expect(result.percentage).to.equal(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('captured events', () => {
|
||||
it('include V8 samples from the main process', async function () {
|
||||
this.timeout(60000);
|
||||
|
||||
@@ -2,9 +2,10 @@ import { dialog, BaseWindow, BrowserWindow } from 'electron/main';
|
||||
|
||||
import { expect } from 'chai';
|
||||
|
||||
import * as path from 'node:path';
|
||||
import { setTimeout } from 'node:timers/promises';
|
||||
|
||||
import { ifit } from './lib/spec-helpers';
|
||||
import { ifdescribe, ifit } from './lib/spec-helpers';
|
||||
import { closeAllWindows } from './lib/window-helpers';
|
||||
|
||||
describe('dialog module', () => {
|
||||
@@ -243,4 +244,785 @@ describe('dialog module', () => {
|
||||
}).to.throw(/message must be a string/);
|
||||
});
|
||||
});
|
||||
|
||||
ifdescribe(process.platform === 'darwin' && !process.env.ELECTRON_SKIP_NATIVE_MODULE_TESTS)('end-to-end dialog interaction (macOS)', () => {
|
||||
let dialogHelper: any;
|
||||
|
||||
before(() => {
|
||||
dialogHelper = require('@electron-ci/dialog-helper');
|
||||
});
|
||||
|
||||
afterEach(closeAllWindows);
|
||||
|
||||
// Poll for a sheet to appear on the given window.
|
||||
async function waitForSheet (w: BrowserWindow): Promise<void> {
|
||||
const handle = w.getNativeWindowHandle();
|
||||
for (let i = 0; i < 50; i++) {
|
||||
const info = dialogHelper.getDialogInfo(handle);
|
||||
if (info.type !== 'none') return;
|
||||
await setTimeout(100);
|
||||
}
|
||||
throw new Error('Timed out waiting for dialog sheet to appear');
|
||||
}
|
||||
|
||||
describe('showMessageBox', () => {
|
||||
it('shows the correct message and buttons', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showMessageBox(w, {
|
||||
message: 'Test message',
|
||||
buttons: ['OK', 'Cancel']
|
||||
});
|
||||
|
||||
await waitForSheet(w);
|
||||
const handle = w.getNativeWindowHandle();
|
||||
const info = dialogHelper.getDialogInfo(handle);
|
||||
|
||||
expect(info.type).to.equal('message-box');
|
||||
expect(info.message).to.equal('Test message');
|
||||
|
||||
const buttons = JSON.parse(info.buttons);
|
||||
expect(buttons).to.include('OK');
|
||||
expect(buttons).to.include('Cancel');
|
||||
|
||||
dialogHelper.clickMessageBoxButton(handle, 0);
|
||||
await p;
|
||||
});
|
||||
|
||||
it('shows detail text', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showMessageBox(w, {
|
||||
message: 'Main message',
|
||||
detail: 'Extra detail text',
|
||||
buttons: ['OK']
|
||||
});
|
||||
|
||||
await waitForSheet(w);
|
||||
const handle = w.getNativeWindowHandle();
|
||||
const info = dialogHelper.getDialogInfo(handle);
|
||||
|
||||
expect(info.message).to.equal('Main message');
|
||||
expect(info.detail).to.equal('Extra detail text');
|
||||
|
||||
dialogHelper.clickMessageBoxButton(handle, 0);
|
||||
await p;
|
||||
});
|
||||
|
||||
it('returns the correct response when a specific button is clicked', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showMessageBox(w, {
|
||||
message: 'Choose a button',
|
||||
buttons: ['First', 'Second', 'Third']
|
||||
});
|
||||
|
||||
await waitForSheet(w);
|
||||
const handle = w.getNativeWindowHandle();
|
||||
dialogHelper.clickMessageBoxButton(handle, 1);
|
||||
|
||||
const result = await p;
|
||||
expect(result.response).to.equal(1);
|
||||
});
|
||||
|
||||
it('returns the correct response when the last button is clicked', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showMessageBox(w, {
|
||||
message: 'Choose a button',
|
||||
buttons: ['Yes', 'No', 'Maybe']
|
||||
});
|
||||
|
||||
await waitForSheet(w);
|
||||
const handle = w.getNativeWindowHandle();
|
||||
dialogHelper.clickMessageBoxButton(handle, 2);
|
||||
|
||||
const result = await p;
|
||||
expect(result.response).to.equal(2);
|
||||
});
|
||||
|
||||
it('shows a single button when no buttons are specified', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showMessageBox(w, {
|
||||
message: 'No buttons specified'
|
||||
});
|
||||
|
||||
await waitForSheet(w);
|
||||
const handle = w.getNativeWindowHandle();
|
||||
const info = dialogHelper.getDialogInfo(handle);
|
||||
|
||||
expect(info.type).to.equal('message-box');
|
||||
// macOS adds a default "OK" button when none are specified.
|
||||
const buttons = JSON.parse(info.buttons);
|
||||
expect(buttons).to.have.lengthOf(1);
|
||||
|
||||
dialogHelper.clickMessageBoxButton(handle, 0);
|
||||
const result = await p;
|
||||
expect(result.response).to.equal(0);
|
||||
});
|
||||
|
||||
it('renders checkbox with the correct label and initial state', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showMessageBox(w, {
|
||||
message: 'Checkbox test',
|
||||
buttons: ['OK'],
|
||||
checkboxLabel: 'Do not show again',
|
||||
checkboxChecked: false
|
||||
});
|
||||
|
||||
await waitForSheet(w);
|
||||
const handle = w.getNativeWindowHandle();
|
||||
const info = dialogHelper.getDialogInfo(handle);
|
||||
|
||||
expect(info.checkboxLabel).to.equal('Do not show again');
|
||||
expect(info.checkboxChecked).to.be.false();
|
||||
|
||||
dialogHelper.clickMessageBoxButton(handle, 0);
|
||||
const result = await p;
|
||||
expect(result.checkboxChecked).to.be.false();
|
||||
});
|
||||
|
||||
it('returns checkboxChecked as true when checkbox is initially checked', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showMessageBox(w, {
|
||||
message: 'Pre-checked checkbox',
|
||||
buttons: ['OK'],
|
||||
checkboxLabel: 'Remember my choice',
|
||||
checkboxChecked: true
|
||||
});
|
||||
|
||||
await waitForSheet(w);
|
||||
const handle = w.getNativeWindowHandle();
|
||||
const info = dialogHelper.getDialogInfo(handle);
|
||||
|
||||
expect(info.checkboxLabel).to.equal('Remember my choice');
|
||||
expect(info.checkboxChecked).to.be.true();
|
||||
|
||||
dialogHelper.clickMessageBoxButton(handle, 0);
|
||||
const result = await p;
|
||||
expect(result.checkboxChecked).to.be.true();
|
||||
});
|
||||
|
||||
it('can toggle checkbox and returns updated state', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showMessageBox(w, {
|
||||
message: 'Toggle test',
|
||||
buttons: ['OK'],
|
||||
checkboxLabel: 'Toggle me',
|
||||
checkboxChecked: false
|
||||
});
|
||||
|
||||
await waitForSheet(w);
|
||||
const handle = w.getNativeWindowHandle();
|
||||
|
||||
// Verify initially unchecked.
|
||||
let info = dialogHelper.getDialogInfo(handle);
|
||||
expect(info.checkboxChecked).to.be.false();
|
||||
|
||||
// Click the checkbox to check it.
|
||||
dialogHelper.clickCheckbox(handle);
|
||||
info = dialogHelper.getDialogInfo(handle);
|
||||
expect(info.checkboxChecked).to.be.true();
|
||||
|
||||
dialogHelper.clickMessageBoxButton(handle, 0);
|
||||
const result = await p;
|
||||
expect(result.checkboxChecked).to.be.true();
|
||||
});
|
||||
|
||||
it('strips access keys on macOS with normalizeAccessKeys', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showMessageBox(w, {
|
||||
message: 'Access key test',
|
||||
buttons: ['&Save', '&Cancel'],
|
||||
normalizeAccessKeys: true
|
||||
});
|
||||
|
||||
await waitForSheet(w);
|
||||
const handle = w.getNativeWindowHandle();
|
||||
const info = dialogHelper.getDialogInfo(handle);
|
||||
|
||||
// On macOS, ampersands are stripped by normalizeAccessKeys.
|
||||
const buttons = JSON.parse(info.buttons);
|
||||
expect(buttons).to.include('Save');
|
||||
expect(buttons).to.include('Cancel');
|
||||
expect(buttons).not.to.include('&Save');
|
||||
expect(buttons).not.to.include('&Cancel');
|
||||
|
||||
dialogHelper.clickMessageBoxButton(handle, 0);
|
||||
await p;
|
||||
});
|
||||
|
||||
it('respects defaultId by making it the default button', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showMessageBox(w, {
|
||||
message: 'Default button test',
|
||||
buttons: ['One', 'Two', 'Three'],
|
||||
defaultId: 2
|
||||
});
|
||||
|
||||
await waitForSheet(w);
|
||||
const handle = w.getNativeWindowHandle();
|
||||
|
||||
const info = dialogHelper.getDialogInfo(handle);
|
||||
const buttons = JSON.parse(info.buttons);
|
||||
expect(buttons).to.deep.equal(['One', 'Two', 'Three']);
|
||||
|
||||
dialogHelper.clickMessageBoxButton(handle, 2);
|
||||
const result = await p;
|
||||
expect(result.response).to.equal(2);
|
||||
});
|
||||
|
||||
it('respects cancelId and returns it when cancelled via signal', async () => {
|
||||
const controller = new AbortController();
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showMessageBox(w, {
|
||||
message: 'Cancel ID test',
|
||||
buttons: ['OK', 'Dismiss', 'Abort'],
|
||||
cancelId: 2,
|
||||
signal: controller.signal
|
||||
});
|
||||
|
||||
await waitForSheet(w);
|
||||
controller.abort();
|
||||
|
||||
const result = await p;
|
||||
expect(result.response).to.equal(2);
|
||||
});
|
||||
|
||||
it('works with all message box types', async () => {
|
||||
const types: Array<'none' | 'info' | 'warning' | 'error' | 'question'> =
|
||||
['none', 'info', 'warning', 'error', 'question'];
|
||||
|
||||
for (const type of types) {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showMessageBox(w, {
|
||||
message: `Type: ${type}`,
|
||||
type,
|
||||
buttons: ['OK']
|
||||
});
|
||||
|
||||
await waitForSheet(w);
|
||||
const handle = w.getNativeWindowHandle();
|
||||
const info = dialogHelper.getDialogInfo(handle);
|
||||
|
||||
expect(info.type).to.equal('message-box');
|
||||
expect(info.message).to.equal(`Type: ${type}`);
|
||||
|
||||
dialogHelper.clickMessageBoxButton(handle, 0);
|
||||
await p;
|
||||
w.destroy();
|
||||
// Allow the event loop to settle between iterations to avoid
|
||||
// Chromium DCHECK failures from rapid window lifecycle churn.
|
||||
await setTimeout(100);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('showOpenDialog', () => {
|
||||
it('can cancel an open dialog', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showOpenDialog(w, {
|
||||
title: 'Test Open',
|
||||
properties: ['openFile']
|
||||
});
|
||||
|
||||
await waitForSheet(w);
|
||||
const handle = w.getNativeWindowHandle();
|
||||
const info = dialogHelper.getDialogInfo(handle);
|
||||
expect(info.type).to.equal('open-dialog');
|
||||
|
||||
dialogHelper.cancelFileDialog(handle);
|
||||
|
||||
const result = await p;
|
||||
expect(result.canceled).to.be.true();
|
||||
expect(result.filePaths).to.have.lengthOf(0);
|
||||
});
|
||||
|
||||
it('sets a custom button label', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showOpenDialog(w, {
|
||||
buttonLabel: 'Select This',
|
||||
properties: ['openFile']
|
||||
});
|
||||
|
||||
await waitForSheet(w);
|
||||
const handle = w.getNativeWindowHandle();
|
||||
const info = dialogHelper.getDialogInfo(handle);
|
||||
expect(info.prompt).to.equal('Select This');
|
||||
|
||||
dialogHelper.cancelFileDialog(handle);
|
||||
await p;
|
||||
});
|
||||
|
||||
it('sets a message on the dialog', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showOpenDialog(w, {
|
||||
message: 'Choose a file to import',
|
||||
properties: ['openFile']
|
||||
});
|
||||
|
||||
await waitForSheet(w);
|
||||
const handle = w.getNativeWindowHandle();
|
||||
const info = dialogHelper.getDialogInfo(handle);
|
||||
expect(info.panelMessage).to.equal('Choose a file to import');
|
||||
|
||||
dialogHelper.cancelFileDialog(handle);
|
||||
await p;
|
||||
});
|
||||
|
||||
it('defaults to openFile with canChooseFiles enabled', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showOpenDialog(w, {
|
||||
properties: ['openFile']
|
||||
});
|
||||
|
||||
await waitForSheet(w);
|
||||
const handle = w.getNativeWindowHandle();
|
||||
const info = dialogHelper.getDialogInfo(handle);
|
||||
expect(info.canChooseFiles).to.be.true();
|
||||
expect(info.canChooseDirectories).to.be.false();
|
||||
expect(info.allowsMultipleSelection).to.be.false();
|
||||
|
||||
dialogHelper.cancelFileDialog(handle);
|
||||
await p;
|
||||
});
|
||||
|
||||
it('enables directory selection with openDirectory', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showOpenDialog(w, {
|
||||
properties: ['openDirectory']
|
||||
});
|
||||
|
||||
await waitForSheet(w);
|
||||
const handle = w.getNativeWindowHandle();
|
||||
const info = dialogHelper.getDialogInfo(handle);
|
||||
expect(info.canChooseDirectories).to.be.true();
|
||||
// openFile is not set, so canChooseFiles should be false
|
||||
expect(info.canChooseFiles).to.be.false();
|
||||
|
||||
dialogHelper.cancelFileDialog(handle);
|
||||
await p;
|
||||
});
|
||||
|
||||
it('enables both file and directory selection together', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showOpenDialog(w, {
|
||||
properties: ['openFile', 'openDirectory']
|
||||
});
|
||||
|
||||
await waitForSheet(w);
|
||||
const handle = w.getNativeWindowHandle();
|
||||
const info = dialogHelper.getDialogInfo(handle);
|
||||
expect(info.canChooseFiles).to.be.true();
|
||||
expect(info.canChooseDirectories).to.be.true();
|
||||
|
||||
dialogHelper.cancelFileDialog(handle);
|
||||
await p;
|
||||
});
|
||||
|
||||
it('enables multiple selection with multiSelections', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showOpenDialog(w, {
|
||||
properties: ['openFile', 'multiSelections']
|
||||
});
|
||||
|
||||
await waitForSheet(w);
|
||||
const handle = w.getNativeWindowHandle();
|
||||
const info = dialogHelper.getDialogInfo(handle);
|
||||
expect(info.allowsMultipleSelection).to.be.true();
|
||||
|
||||
dialogHelper.cancelFileDialog(handle);
|
||||
await p;
|
||||
});
|
||||
|
||||
it('shows hidden files with showHiddenFiles', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showOpenDialog(w, {
|
||||
properties: ['openFile', 'showHiddenFiles']
|
||||
});
|
||||
|
||||
await waitForSheet(w);
|
||||
const handle = w.getNativeWindowHandle();
|
||||
const info = dialogHelper.getDialogInfo(handle);
|
||||
expect(info.showsHiddenFiles).to.be.true();
|
||||
|
||||
dialogHelper.cancelFileDialog(handle);
|
||||
await p;
|
||||
});
|
||||
|
||||
it('does not show hidden files by default', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showOpenDialog(w, {
|
||||
properties: ['openFile']
|
||||
});
|
||||
|
||||
await waitForSheet(w);
|
||||
const handle = w.getNativeWindowHandle();
|
||||
const info = dialogHelper.getDialogInfo(handle);
|
||||
expect(info.showsHiddenFiles).to.be.false();
|
||||
|
||||
dialogHelper.cancelFileDialog(handle);
|
||||
await p;
|
||||
});
|
||||
|
||||
it('disables alias resolution with noResolveAliases', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showOpenDialog(w, {
|
||||
properties: ['openFile', 'noResolveAliases']
|
||||
});
|
||||
|
||||
await waitForSheet(w);
|
||||
const handle = w.getNativeWindowHandle();
|
||||
const info = dialogHelper.getDialogInfo(handle);
|
||||
expect(info.resolvesAliases).to.be.false();
|
||||
|
||||
dialogHelper.cancelFileDialog(handle);
|
||||
await p;
|
||||
});
|
||||
|
||||
it('resolves aliases by default', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showOpenDialog(w, {
|
||||
properties: ['openFile']
|
||||
});
|
||||
|
||||
await waitForSheet(w);
|
||||
const handle = w.getNativeWindowHandle();
|
||||
const info = dialogHelper.getDialogInfo(handle);
|
||||
expect(info.resolvesAliases).to.be.true();
|
||||
|
||||
dialogHelper.cancelFileDialog(handle);
|
||||
await p;
|
||||
});
|
||||
|
||||
it('treats packages as directories with treatPackageAsDirectory', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showOpenDialog(w, {
|
||||
properties: ['openFile', 'treatPackageAsDirectory']
|
||||
});
|
||||
|
||||
await waitForSheet(w);
|
||||
const handle = w.getNativeWindowHandle();
|
||||
const info = dialogHelper.getDialogInfo(handle);
|
||||
expect(info.treatsPackagesAsDirectories).to.be.true();
|
||||
|
||||
dialogHelper.cancelFileDialog(handle);
|
||||
await p;
|
||||
});
|
||||
|
||||
it('enables directory creation with createDirectory', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showOpenDialog(w, {
|
||||
properties: ['openFile', 'createDirectory']
|
||||
});
|
||||
|
||||
await waitForSheet(w);
|
||||
const handle = w.getNativeWindowHandle();
|
||||
const info = dialogHelper.getDialogInfo(handle);
|
||||
expect(info.canCreateDirectories).to.be.true();
|
||||
|
||||
dialogHelper.cancelFileDialog(handle);
|
||||
await p;
|
||||
});
|
||||
|
||||
it('sets the default path directory', async () => {
|
||||
const defaultDir = path.join(__dirname, 'fixtures');
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showOpenDialog(w, {
|
||||
defaultPath: defaultDir,
|
||||
properties: ['openFile']
|
||||
});
|
||||
|
||||
await waitForSheet(w);
|
||||
const handle = w.getNativeWindowHandle();
|
||||
const info = dialogHelper.getDialogInfo(handle);
|
||||
expect(info.directory).to.equal(defaultDir);
|
||||
|
||||
dialogHelper.cancelFileDialog(handle);
|
||||
await p;
|
||||
});
|
||||
|
||||
it('applies multiple properties simultaneously', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showOpenDialog(w, {
|
||||
title: 'Multi-Property Test',
|
||||
buttonLabel: 'Pick',
|
||||
message: 'Select items',
|
||||
properties: [
|
||||
'openFile',
|
||||
'openDirectory',
|
||||
'multiSelections',
|
||||
'showHiddenFiles',
|
||||
'createDirectory',
|
||||
'treatPackageAsDirectory',
|
||||
'noResolveAliases'
|
||||
]
|
||||
});
|
||||
|
||||
await waitForSheet(w);
|
||||
const handle = w.getNativeWindowHandle();
|
||||
const info = dialogHelper.getDialogInfo(handle);
|
||||
|
||||
expect(info.type).to.equal('open-dialog');
|
||||
expect(info.prompt).to.equal('Pick');
|
||||
expect(info.panelMessage).to.equal('Select items');
|
||||
expect(info.canChooseFiles).to.be.true();
|
||||
expect(info.canChooseDirectories).to.be.true();
|
||||
expect(info.allowsMultipleSelection).to.be.true();
|
||||
expect(info.showsHiddenFiles).to.be.true();
|
||||
expect(info.canCreateDirectories).to.be.true();
|
||||
expect(info.treatsPackagesAsDirectories).to.be.true();
|
||||
expect(info.resolvesAliases).to.be.false();
|
||||
|
||||
dialogHelper.cancelFileDialog(handle);
|
||||
await p;
|
||||
});
|
||||
|
||||
it('can accept an open dialog and return a file path', async () => {
|
||||
const targetDir = path.join(__dirname, 'fixtures');
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showOpenDialog(w, {
|
||||
defaultPath: targetDir,
|
||||
properties: ['openDirectory']
|
||||
});
|
||||
|
||||
await waitForSheet(w);
|
||||
const handle = w.getNativeWindowHandle();
|
||||
|
||||
dialogHelper.acceptFileDialog(handle);
|
||||
|
||||
const result = await p;
|
||||
expect(result.canceled).to.be.false();
|
||||
expect(result.filePaths).to.have.lengthOf(1);
|
||||
expect(result.filePaths[0]).to.equal(targetDir);
|
||||
});
|
||||
});
|
||||
|
||||
describe('showSaveDialog', () => {
|
||||
it('can cancel a save dialog', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showSaveDialog(w, {
|
||||
title: 'Test Save'
|
||||
});
|
||||
|
||||
await waitForSheet(w);
|
||||
const handle = w.getNativeWindowHandle();
|
||||
const info = dialogHelper.getDialogInfo(handle);
|
||||
expect(info.type).to.equal('save-dialog');
|
||||
|
||||
dialogHelper.cancelFileDialog(handle);
|
||||
|
||||
const result = await p;
|
||||
expect(result.canceled).to.be.true();
|
||||
expect(result.filePath).to.equal('');
|
||||
});
|
||||
|
||||
it('can accept a save dialog with a filename', async () => {
|
||||
const defaultDir = path.join(__dirname, 'fixtures');
|
||||
const filename = 'test-save-output.txt';
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showSaveDialog(w, {
|
||||
title: 'Test Save',
|
||||
defaultPath: path.join(defaultDir, filename)
|
||||
});
|
||||
|
||||
await waitForSheet(w);
|
||||
const handle = w.getNativeWindowHandle();
|
||||
|
||||
dialogHelper.acceptFileDialog(handle);
|
||||
|
||||
const result = await p;
|
||||
expect(result.canceled).to.be.false();
|
||||
expect(result.filePath).to.equal(path.join(defaultDir, filename));
|
||||
});
|
||||
|
||||
it('sets a custom button label', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showSaveDialog(w, {
|
||||
buttonLabel: 'Export'
|
||||
});
|
||||
|
||||
await waitForSheet(w);
|
||||
const handle = w.getNativeWindowHandle();
|
||||
const info = dialogHelper.getDialogInfo(handle);
|
||||
expect(info.prompt).to.equal('Export');
|
||||
|
||||
dialogHelper.cancelFileDialog(handle);
|
||||
await p;
|
||||
});
|
||||
|
||||
it('sets a message on the dialog', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showSaveDialog(w, {
|
||||
message: 'Choose where to save'
|
||||
});
|
||||
|
||||
await waitForSheet(w);
|
||||
const handle = w.getNativeWindowHandle();
|
||||
const info = dialogHelper.getDialogInfo(handle);
|
||||
expect(info.panelMessage).to.equal('Choose where to save');
|
||||
|
||||
dialogHelper.cancelFileDialog(handle);
|
||||
await p;
|
||||
});
|
||||
|
||||
it('sets a custom name field label', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showSaveDialog(w, {
|
||||
nameFieldLabel: 'Export As:'
|
||||
});
|
||||
|
||||
await waitForSheet(w);
|
||||
const handle = w.getNativeWindowHandle();
|
||||
const info = dialogHelper.getDialogInfo(handle);
|
||||
expect(info.nameFieldLabel).to.equal('Export As:');
|
||||
|
||||
dialogHelper.cancelFileDialog(handle);
|
||||
await p;
|
||||
});
|
||||
|
||||
it('sets the default filename from defaultPath', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showSaveDialog(w, {
|
||||
defaultPath: path.join(__dirname, 'fixtures', 'my-document.txt')
|
||||
});
|
||||
|
||||
await waitForSheet(w);
|
||||
const handle = w.getNativeWindowHandle();
|
||||
const info = dialogHelper.getDialogInfo(handle);
|
||||
expect(info.nameFieldValue).to.equal('my-document.txt');
|
||||
|
||||
dialogHelper.cancelFileDialog(handle);
|
||||
await p;
|
||||
});
|
||||
|
||||
it('sets the default directory from defaultPath', async () => {
|
||||
const defaultDir = path.join(__dirname, 'fixtures');
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showSaveDialog(w, {
|
||||
defaultPath: path.join(defaultDir, 'some-file.txt')
|
||||
});
|
||||
|
||||
await waitForSheet(w);
|
||||
const handle = w.getNativeWindowHandle();
|
||||
const info = dialogHelper.getDialogInfo(handle);
|
||||
expect(info.directory).to.equal(defaultDir);
|
||||
|
||||
dialogHelper.cancelFileDialog(handle);
|
||||
await p;
|
||||
});
|
||||
|
||||
it('hides the tag field when showsTagField is false', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showSaveDialog(w, {
|
||||
showsTagField: false
|
||||
});
|
||||
|
||||
await waitForSheet(w);
|
||||
const handle = w.getNativeWindowHandle();
|
||||
const info = dialogHelper.getDialogInfo(handle);
|
||||
expect(info.showsTagField).to.be.false();
|
||||
|
||||
dialogHelper.cancelFileDialog(handle);
|
||||
await p;
|
||||
});
|
||||
|
||||
it('shows the tag field by default', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showSaveDialog(w, {});
|
||||
|
||||
await waitForSheet(w);
|
||||
const handle = w.getNativeWindowHandle();
|
||||
const info = dialogHelper.getDialogInfo(handle);
|
||||
expect(info.showsTagField).to.be.true();
|
||||
|
||||
dialogHelper.cancelFileDialog(handle);
|
||||
await p;
|
||||
});
|
||||
|
||||
it('enables directory creation with createDirectory', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showSaveDialog(w, {
|
||||
properties: ['createDirectory']
|
||||
});
|
||||
|
||||
await waitForSheet(w);
|
||||
const handle = w.getNativeWindowHandle();
|
||||
const info = dialogHelper.getDialogInfo(handle);
|
||||
expect(info.canCreateDirectories).to.be.true();
|
||||
|
||||
dialogHelper.cancelFileDialog(handle);
|
||||
await p;
|
||||
});
|
||||
|
||||
it('shows hidden files with showHiddenFiles', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showSaveDialog(w, {
|
||||
properties: ['showHiddenFiles']
|
||||
});
|
||||
|
||||
await waitForSheet(w);
|
||||
const handle = w.getNativeWindowHandle();
|
||||
const info = dialogHelper.getDialogInfo(handle);
|
||||
expect(info.showsHiddenFiles).to.be.true();
|
||||
|
||||
dialogHelper.cancelFileDialog(handle);
|
||||
await p;
|
||||
});
|
||||
|
||||
it('does not show hidden files by default', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showSaveDialog(w, {});
|
||||
|
||||
await waitForSheet(w);
|
||||
const handle = w.getNativeWindowHandle();
|
||||
const info = dialogHelper.getDialogInfo(handle);
|
||||
expect(info.showsHiddenFiles).to.be.false();
|
||||
|
||||
dialogHelper.cancelFileDialog(handle);
|
||||
await p;
|
||||
});
|
||||
|
||||
it('treats packages as directories with treatPackageAsDirectory', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showSaveDialog(w, {
|
||||
properties: ['treatPackageAsDirectory']
|
||||
});
|
||||
|
||||
await waitForSheet(w);
|
||||
const handle = w.getNativeWindowHandle();
|
||||
const info = dialogHelper.getDialogInfo(handle);
|
||||
expect(info.treatsPackagesAsDirectories).to.be.true();
|
||||
|
||||
dialogHelper.cancelFileDialog(handle);
|
||||
await p;
|
||||
});
|
||||
|
||||
it('applies multiple options simultaneously', async () => {
|
||||
const defaultDir = path.join(__dirname, 'fixtures');
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const p = dialog.showSaveDialog(w, {
|
||||
buttonLabel: 'Save Now',
|
||||
message: 'Pick a location',
|
||||
nameFieldLabel: 'File Name:',
|
||||
defaultPath: path.join(defaultDir, 'output.txt'),
|
||||
showsTagField: false,
|
||||
properties: ['showHiddenFiles', 'createDirectory']
|
||||
});
|
||||
|
||||
await waitForSheet(w);
|
||||
const handle = w.getNativeWindowHandle();
|
||||
const info = dialogHelper.getDialogInfo(handle);
|
||||
|
||||
expect(info.type).to.equal('save-dialog');
|
||||
expect(info.prompt).to.equal('Save Now');
|
||||
expect(info.panelMessage).to.equal('Pick a location');
|
||||
expect(info.nameFieldLabel).to.equal('File Name:');
|
||||
expect(info.nameFieldValue).to.equal('output.txt');
|
||||
expect(info.directory).to.equal(defaultDir);
|
||||
expect(info.showsTagField).to.be.false();
|
||||
expect(info.showsHiddenFiles).to.be.true();
|
||||
expect(info.canCreateDirectories).to.be.true();
|
||||
|
||||
dialogHelper.cancelFileDialog(handle);
|
||||
await p;
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
7
spec/fixtures/native-addon/dialog-helper/.gitignore
vendored
Normal file
7
spec/fixtures/native-addon/dialog-helper/.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/node_modules
|
||||
/build
|
||||
*.swp
|
||||
*.log
|
||||
*~
|
||||
.node-version
|
||||
package-lock.json
|
||||
23
spec/fixtures/native-addon/dialog-helper/binding.gyp
vendored
Normal file
23
spec/fixtures/native-addon/dialog-helper/binding.gyp
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'dialog_helper',
|
||||
'conditions': [
|
||||
['OS=="mac"', {
|
||||
'sources': [
|
||||
'src/main.cc',
|
||||
'src/dialog_helper_mac.mm',
|
||||
],
|
||||
'libraries': [
|
||||
'$(SDKROOT)/System/Library/Frameworks/AppKit.framework',
|
||||
],
|
||||
'xcode_settings': {
|
||||
'OTHER_CFLAGS': ['-fobjc-arc'],
|
||||
},
|
||||
}, {
|
||||
'type': 'none',
|
||||
}],
|
||||
],
|
||||
}
|
||||
]
|
||||
}
|
||||
2
spec/fixtures/native-addon/dialog-helper/lib/index.js
vendored
Normal file
2
spec/fixtures/native-addon/dialog-helper/lib/index.js
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
const binding = require('../build/Release/dialog_helper.node');
|
||||
module.exports = binding;
|
||||
10
spec/fixtures/native-addon/dialog-helper/package.json
vendored
Normal file
10
spec/fixtures/native-addon/dialog-helper/package.json
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "@electron-ci/dialog-helper",
|
||||
"version": "0.0.1",
|
||||
"main": "./lib/index.js",
|
||||
"private": true,
|
||||
"licenses": "MIT",
|
||||
"scripts": {
|
||||
"install": "node-gyp configure && node-gyp build"
|
||||
}
|
||||
}
|
||||
68
spec/fixtures/native-addon/dialog-helper/src/dialog_helper.h
vendored
Normal file
68
spec/fixtures/native-addon/dialog-helper/src/dialog_helper.h
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
#ifndef SRC_DIALOG_HELPER_H_
|
||||
#define SRC_DIALOG_HELPER_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
|
||||
namespace dialog_helper {
|
||||
|
||||
struct DialogInfo {
|
||||
// "message-box", "open-dialog", "save-dialog", or "none"
|
||||
std::string type;
|
||||
// Button titles for message boxes
|
||||
std::string buttons; // JSON array string, e.g. '["OK","Cancel"]'
|
||||
// Message text (NSAlert messageText or panel title)
|
||||
std::string message;
|
||||
// Detail / informative text (NSAlert informativeText)
|
||||
std::string detail;
|
||||
// Checkbox (suppression button) label, empty if none
|
||||
std::string checkbox_label;
|
||||
// Whether the checkbox is checked
|
||||
bool checkbox_checked = false;
|
||||
|
||||
// File dialog properties (open/save panels)
|
||||
std::string prompt; // Button label (NSSavePanel prompt)
|
||||
std::string panel_message; // Panel message text (NSSavePanel message)
|
||||
std::string directory; // Current directory URL path
|
||||
|
||||
// NSSavePanel-specific properties
|
||||
std::string name_field_label; // Label for the name field
|
||||
std::string name_field_value; // Current value of the name field
|
||||
bool shows_tag_field = true;
|
||||
|
||||
// NSOpenPanel-specific properties
|
||||
bool can_choose_files = false;
|
||||
bool can_choose_directories = false;
|
||||
bool allows_multiple_selection = false;
|
||||
|
||||
// Shared panel properties (open and save)
|
||||
bool shows_hidden_files = false;
|
||||
bool resolves_aliases = true;
|
||||
bool treats_packages_as_directories = false;
|
||||
bool can_create_directories = false;
|
||||
};
|
||||
|
||||
// Get information about the sheet dialog attached to the window identified
|
||||
// by the given native handle buffer (NSView* on macOS).
|
||||
DialogInfo GetDialogInfo(char* handle, size_t size);
|
||||
|
||||
// Click a button at the given index on an NSAlert sheet attached to the window.
|
||||
// Returns true if a message box was found and the button was clicked.
|
||||
bool ClickMessageBoxButton(char* handle, size_t size, int button_index);
|
||||
|
||||
// Toggle the checkbox (suppression button) on an NSAlert sheet.
|
||||
// Returns true if a checkbox was found and clicked.
|
||||
bool ClickCheckbox(char* handle, size_t size);
|
||||
|
||||
// Cancel the file dialog (NSOpenPanel/NSSavePanel) sheet attached to the window.
|
||||
// Returns true if a file dialog was found and cancelled.
|
||||
bool CancelFileDialog(char* handle, size_t size);
|
||||
|
||||
// Accept the file dialog sheet attached to the window.
|
||||
// For save dialogs, |filename| is set in the name field before accepting.
|
||||
// Returns true if a file dialog was found and accepted.
|
||||
bool AcceptFileDialog(char* handle, size_t size, const std::string& filename);
|
||||
|
||||
} // namespace dialog_helper
|
||||
|
||||
#endif // SRC_DIALOG_HELPER_H_
|
||||
320
spec/fixtures/native-addon/dialog-helper/src/dialog_helper_mac.mm
vendored
Normal file
320
spec/fixtures/native-addon/dialog-helper/src/dialog_helper_mac.mm
vendored
Normal file
@@ -0,0 +1,320 @@
|
||||
#include "dialog_helper.h"
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
namespace {
|
||||
|
||||
// Extract the NSWindow* from the native handle buffer.
|
||||
// The buffer contains an NSView* (the content view of the window).
|
||||
NSWindow* GetNSWindowFromHandle(char* handle, size_t size) {
|
||||
if (size != sizeof(void*))
|
||||
return nil;
|
||||
// Read the raw pointer from the buffer, then bridge to ARC.
|
||||
void* raw = *reinterpret_cast<void**>(handle);
|
||||
NSView* view = (__bridge NSView*)raw;
|
||||
if (!view || ![view isKindOfClass:[NSView class]])
|
||||
return nil;
|
||||
return [view window];
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace dialog_helper {
|
||||
|
||||
DialogInfo GetDialogInfo(char* handle, size_t size) {
|
||||
DialogInfo info;
|
||||
info.type = "none";
|
||||
|
||||
NSWindow* window = GetNSWindowFromHandle(handle, size);
|
||||
if (!window)
|
||||
return info;
|
||||
|
||||
NSWindow* sheet = [window attachedSheet];
|
||||
if (!sheet)
|
||||
return info;
|
||||
|
||||
// NSOpenPanel is a subclass of NSSavePanel, so check NSOpenPanel first.
|
||||
if ([sheet isKindOfClass:[NSOpenPanel class]]) {
|
||||
info.type = "open-dialog";
|
||||
NSOpenPanel* panel = (NSOpenPanel*)sheet;
|
||||
info.message = [[panel title] UTF8String] ?: "";
|
||||
info.prompt = [[panel prompt] UTF8String] ?: "";
|
||||
info.panel_message = [[panel message] UTF8String] ?: "";
|
||||
if ([panel directoryURL])
|
||||
info.directory = [[[panel directoryURL] path] UTF8String] ?: "";
|
||||
info.can_choose_files = [panel canChooseFiles];
|
||||
info.can_choose_directories = [panel canChooseDirectories];
|
||||
info.allows_multiple_selection = [panel allowsMultipleSelection];
|
||||
info.shows_hidden_files = [panel showsHiddenFiles];
|
||||
info.resolves_aliases = [panel resolvesAliases];
|
||||
info.treats_packages_as_directories = [panel treatsFilePackagesAsDirectories];
|
||||
info.can_create_directories = [panel canCreateDirectories];
|
||||
return info;
|
||||
}
|
||||
|
||||
if ([sheet isKindOfClass:[NSSavePanel class]]) {
|
||||
info.type = "save-dialog";
|
||||
NSSavePanel* panel = (NSSavePanel*)sheet;
|
||||
info.message = [[panel title] UTF8String] ?: "";
|
||||
info.prompt = [[panel prompt] UTF8String] ?: "";
|
||||
info.panel_message = [[panel message] UTF8String] ?: "";
|
||||
if ([panel directoryURL])
|
||||
info.directory = [[[panel directoryURL] path] UTF8String] ?: "";
|
||||
info.name_field_label = [[panel nameFieldLabel] UTF8String] ?: "";
|
||||
info.name_field_value = [[panel nameFieldStringValue] UTF8String] ?: "";
|
||||
info.shows_tag_field = [panel showsTagField];
|
||||
info.shows_hidden_files = [panel showsHiddenFiles];
|
||||
info.treats_packages_as_directories =
|
||||
[panel treatsFilePackagesAsDirectories];
|
||||
info.can_create_directories = [panel canCreateDirectories];
|
||||
return info;
|
||||
}
|
||||
|
||||
// For NSAlert, the sheet window is not an NSSavePanel.
|
||||
// Check if it contains typical NSAlert button structure.
|
||||
// NSAlert's window contains buttons as subviews in its content view.
|
||||
NSView* contentView = [sheet contentView];
|
||||
NSMutableArray<NSButton*>* buttons = [NSMutableArray array];
|
||||
|
||||
// Recursively find all NSButton instances in the view hierarchy.
|
||||
NSMutableArray<NSView*>* stack =
|
||||
[NSMutableArray arrayWithObject:contentView];
|
||||
while ([stack count] > 0) {
|
||||
NSView* current = [stack lastObject];
|
||||
[stack removeLastObject];
|
||||
if ([current isKindOfClass:[NSButton class]]) {
|
||||
NSButton* btn = (NSButton*)current;
|
||||
// Filter to push-type buttons (not checkboxes, radio buttons, etc.)
|
||||
if ([btn bezelStyle] == NSBezelStyleRounded ||
|
||||
[btn bezelStyle] == NSBezelStyleRegularSquare) {
|
||||
[buttons addObject:btn];
|
||||
}
|
||||
}
|
||||
for (NSView* subview in [current subviews]) {
|
||||
[stack addObject:subview];
|
||||
}
|
||||
}
|
||||
|
||||
if ([buttons count] > 0) {
|
||||
info.type = "message-box";
|
||||
|
||||
// Sort buttons by tag to maintain the order they were added.
|
||||
[buttons sortUsingComparator:^NSComparisonResult(NSButton* a, NSButton* b) {
|
||||
if ([a tag] < [b tag])
|
||||
return NSOrderedAscending;
|
||||
if ([a tag] > [b tag])
|
||||
return NSOrderedDescending;
|
||||
return NSOrderedSame;
|
||||
}];
|
||||
|
||||
std::string btn_json = "[";
|
||||
for (NSUInteger i = 0; i < [buttons count]; i++) {
|
||||
if (i > 0)
|
||||
btn_json += ",";
|
||||
btn_json += "\"";
|
||||
NSString* title = [[buttons objectAtIndex:i] title];
|
||||
btn_json += [title UTF8String] ?: "";
|
||||
btn_json += "\"";
|
||||
}
|
||||
btn_json += "]";
|
||||
info.buttons = btn_json;
|
||||
|
||||
// NSAlert's content view contains static NSTextFields for message and
|
||||
// detail text. The first non-editable text field with content is the
|
||||
// message; the second is the detail (informative text).
|
||||
int text_field_index = 0;
|
||||
// Walk all subviews (non-recursive — NSAlert places labels directly).
|
||||
for (NSView* subview in [contentView subviews]) {
|
||||
if ([subview isKindOfClass:[NSTextField class]]) {
|
||||
NSTextField* field = (NSTextField*)subview;
|
||||
if (![field isEditable] && [[field stringValue] length] > 0) {
|
||||
if (text_field_index == 0) {
|
||||
info.message = [[field stringValue] UTF8String];
|
||||
} else if (text_field_index == 1) {
|
||||
info.detail = [[field stringValue] UTF8String];
|
||||
}
|
||||
text_field_index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check for the suppression (checkbox) button.
|
||||
// NSAlert's suppression button is a non-bordered NSButton, unlike
|
||||
// push buttons which are bordered. This reliably identifies it
|
||||
// across macOS versions where the accessibility role may differ.
|
||||
NSMutableArray<NSView*>* cbStack =
|
||||
[NSMutableArray arrayWithObject:contentView];
|
||||
while ([cbStack count] > 0) {
|
||||
NSView* current = [cbStack lastObject];
|
||||
[cbStack removeLastObject];
|
||||
if ([current isKindOfClass:[NSButton class]]) {
|
||||
NSButton* btn = (NSButton*)current;
|
||||
if (![btn isBordered]) {
|
||||
NSString* title = [btn title];
|
||||
if (title && [title length] > 0) {
|
||||
info.checkbox_label = [title UTF8String];
|
||||
info.checkbox_checked =
|
||||
([btn state] == NSControlStateValueOn);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (NSView* sub in [current subviews]) {
|
||||
[cbStack addObject:sub];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
bool ClickMessageBoxButton(char* handle, size_t size, int button_index) {
|
||||
NSWindow* window = GetNSWindowFromHandle(handle, size);
|
||||
if (!window)
|
||||
return false;
|
||||
|
||||
NSWindow* sheet = [window attachedSheet];
|
||||
if (!sheet)
|
||||
return false;
|
||||
|
||||
// Find buttons in the sheet, sorted by tag.
|
||||
NSView* contentView = [sheet contentView];
|
||||
NSMutableArray<NSButton*>* buttons = [NSMutableArray array];
|
||||
|
||||
NSMutableArray<NSView*>* stack =
|
||||
[NSMutableArray arrayWithObject:contentView];
|
||||
while ([stack count] > 0) {
|
||||
NSView* current = [stack lastObject];
|
||||
[stack removeLastObject];
|
||||
if ([current isKindOfClass:[NSButton class]]) {
|
||||
NSButton* btn = (NSButton*)current;
|
||||
if ([btn bezelStyle] == NSBezelStyleRounded ||
|
||||
[btn bezelStyle] == NSBezelStyleRegularSquare) {
|
||||
[buttons addObject:btn];
|
||||
}
|
||||
}
|
||||
for (NSView* subview in [current subviews]) {
|
||||
[stack addObject:subview];
|
||||
}
|
||||
}
|
||||
|
||||
[buttons sortUsingComparator:^NSComparisonResult(NSButton* a, NSButton* b) {
|
||||
if ([a tag] < [b tag])
|
||||
return NSOrderedAscending;
|
||||
if ([a tag] > [b tag])
|
||||
return NSOrderedDescending;
|
||||
return NSOrderedSame;
|
||||
}];
|
||||
|
||||
if (button_index < 0 || button_index >= (int)[buttons count])
|
||||
return false;
|
||||
|
||||
NSButton* target = [buttons objectAtIndex:button_index];
|
||||
[target performClick:nil];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ClickCheckbox(char* handle, size_t size) {
|
||||
NSWindow* window = GetNSWindowFromHandle(handle, size);
|
||||
if (!window)
|
||||
return false;
|
||||
|
||||
NSWindow* sheet = [window attachedSheet];
|
||||
if (!sheet)
|
||||
return false;
|
||||
|
||||
// Find the suppression/checkbox button — it is a non-bordered NSButton,
|
||||
// unlike the push buttons which are bordered.
|
||||
NSView* contentView = [sheet contentView];
|
||||
NSMutableArray<NSView*>* stack =
|
||||
[NSMutableArray arrayWithObject:contentView];
|
||||
while ([stack count] > 0) {
|
||||
NSView* current = [stack lastObject];
|
||||
[stack removeLastObject];
|
||||
if ([current isKindOfClass:[NSButton class]]) {
|
||||
NSButton* btn = (NSButton*)current;
|
||||
if (![btn isBordered] && [[btn title] length] > 0) {
|
||||
[btn performClick:nil];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (NSView* subview in [current subviews]) {
|
||||
[stack addObject:subview];
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CancelFileDialog(char* handle, size_t size) {
|
||||
NSWindow* window = GetNSWindowFromHandle(handle, size);
|
||||
if (!window)
|
||||
return false;
|
||||
|
||||
NSWindow* sheet = [window attachedSheet];
|
||||
if (!sheet)
|
||||
return false;
|
||||
|
||||
// sheet is the NSSavePanel/NSOpenPanel window itself when presented as a
|
||||
// sheet. We need to find the actual panel object. On macOS, when an
|
||||
// NSSavePanel is run as a sheet, [window attachedSheet] returns the panel's
|
||||
// window. The panel can be retrieved because NSSavePanel IS the window.
|
||||
if ([sheet isKindOfClass:[NSSavePanel class]]) {
|
||||
NSSavePanel* panel = (NSSavePanel*)sheet;
|
||||
[panel cancel:nil];
|
||||
return true;
|
||||
}
|
||||
|
||||
// If it's not a recognized panel type, try ending the sheet directly.
|
||||
[NSApp endSheet:sheet returnCode:NSModalResponseCancel];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AcceptFileDialog(char* handle, size_t size, const std::string& filename) {
|
||||
NSWindow* window = GetNSWindowFromHandle(handle, size);
|
||||
if (!window)
|
||||
return false;
|
||||
|
||||
NSWindow* sheet = [window attachedSheet];
|
||||
if (!sheet)
|
||||
return false;
|
||||
|
||||
if (![sheet isKindOfClass:[NSSavePanel class]])
|
||||
return false;
|
||||
|
||||
NSSavePanel* panel = (NSSavePanel*)sheet;
|
||||
|
||||
// Set the filename if provided (for save dialogs).
|
||||
if (!filename.empty()) {
|
||||
NSString* name = [NSString stringWithUTF8String:filename.c_str()];
|
||||
[panel setNameFieldStringValue:name];
|
||||
// Resign first responder to commit the name field edit. Without this,
|
||||
// the panel may still use the previous value (e.g. "Untitled") when
|
||||
// the accept button is clicked immediately after.
|
||||
[sheet makeFirstResponder:nil];
|
||||
}
|
||||
|
||||
NSView* contentView = [sheet contentView];
|
||||
|
||||
// Search for the default button (key equivalent "\r") in the view hierarchy.
|
||||
NSMutableArray<NSView*>* stack =
|
||||
[NSMutableArray arrayWithObject:contentView];
|
||||
while ([stack count] > 0) {
|
||||
NSView* current = [stack lastObject];
|
||||
[stack removeLastObject];
|
||||
if ([current isKindOfClass:[NSButton class]]) {
|
||||
NSButton* btn = (NSButton*)current;
|
||||
if ([[btn keyEquivalent] isEqualToString:@"\r"]) {
|
||||
[btn performClick:nil];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (NSView* subview in [current subviews]) {
|
||||
[stack addObject:subview];
|
||||
}
|
||||
}
|
||||
|
||||
[NSApp endSheet:sheet returnCode:NSModalResponseOK];
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace dialog_helper
|
||||
231
spec/fixtures/native-addon/dialog-helper/src/main.cc
vendored
Normal file
231
spec/fixtures/native-addon/dialog-helper/src/main.cc
vendored
Normal file
@@ -0,0 +1,231 @@
|
||||
#include <js_native_api.h>
|
||||
#include <node_api.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "dialog_helper.h"
|
||||
|
||||
namespace {
|
||||
|
||||
// Helper: extract (char* data, size_t length) from the first Buffer argument.
|
||||
bool GetHandleArg(napi_env env, napi_callback_info info, size_t expected_argc,
|
||||
napi_value* args, char** data, size_t* length) {
|
||||
size_t argc = expected_argc;
|
||||
napi_status status = napi_get_cb_info(env, info, &argc, args, NULL, NULL);
|
||||
if (status != napi_ok || argc < 1)
|
||||
return false;
|
||||
|
||||
bool is_buffer;
|
||||
status = napi_is_buffer(env, args[0], &is_buffer);
|
||||
if (status != napi_ok || !is_buffer) {
|
||||
napi_throw_error(env, NULL, "First argument must be a Buffer (native window handle)");
|
||||
return false;
|
||||
}
|
||||
|
||||
status = napi_get_buffer_info(env, args[0], (void**)data, length);
|
||||
return status == napi_ok;
|
||||
}
|
||||
|
||||
napi_value GetDialogInfo(napi_env env, napi_callback_info info) {
|
||||
napi_value args[1];
|
||||
char* data;
|
||||
size_t length;
|
||||
if (!GetHandleArg(env, info, 1, args, &data, &length))
|
||||
return NULL;
|
||||
|
||||
dialog_helper::DialogInfo di = dialog_helper::GetDialogInfo(data, length);
|
||||
|
||||
napi_value result;
|
||||
napi_create_object(env, &result);
|
||||
|
||||
// Message box properties
|
||||
napi_value type_val;
|
||||
napi_create_string_utf8(env, di.type.c_str(), di.type.size(), &type_val);
|
||||
napi_set_named_property(env, result, "type", type_val);
|
||||
|
||||
napi_value buttons_val;
|
||||
napi_create_string_utf8(env, di.buttons.c_str(), di.buttons.size(), &buttons_val);
|
||||
napi_set_named_property(env, result, "buttons", buttons_val);
|
||||
|
||||
napi_value message_val;
|
||||
napi_create_string_utf8(env, di.message.c_str(), di.message.size(), &message_val);
|
||||
napi_set_named_property(env, result, "message", message_val);
|
||||
|
||||
napi_value detail_val;
|
||||
napi_create_string_utf8(env, di.detail.c_str(), di.detail.size(), &detail_val);
|
||||
napi_set_named_property(env, result, "detail", detail_val);
|
||||
|
||||
napi_value checkbox_label_val;
|
||||
napi_create_string_utf8(env, di.checkbox_label.c_str(),
|
||||
di.checkbox_label.size(), &checkbox_label_val);
|
||||
napi_set_named_property(env, result, "checkboxLabel", checkbox_label_val);
|
||||
|
||||
napi_value checkbox_checked_val;
|
||||
napi_get_boolean(env, di.checkbox_checked, &checkbox_checked_val);
|
||||
napi_set_named_property(env, result, "checkboxChecked", checkbox_checked_val);
|
||||
|
||||
// File dialog properties
|
||||
napi_value prompt_val;
|
||||
napi_create_string_utf8(env, di.prompt.c_str(), di.prompt.size(), &prompt_val);
|
||||
napi_set_named_property(env, result, "prompt", prompt_val);
|
||||
|
||||
napi_value panel_message_val;
|
||||
napi_create_string_utf8(env, di.panel_message.c_str(),
|
||||
di.panel_message.size(), &panel_message_val);
|
||||
napi_set_named_property(env, result, "panelMessage", panel_message_val);
|
||||
|
||||
napi_value directory_val;
|
||||
napi_create_string_utf8(env, di.directory.c_str(), di.directory.size(),
|
||||
&directory_val);
|
||||
napi_set_named_property(env, result, "directory", directory_val);
|
||||
|
||||
// NSSavePanel-specific string/boolean properties
|
||||
napi_value name_field_label_val;
|
||||
napi_create_string_utf8(env, di.name_field_label.c_str(),
|
||||
di.name_field_label.size(), &name_field_label_val);
|
||||
napi_set_named_property(env, result, "nameFieldLabel", name_field_label_val);
|
||||
|
||||
napi_value name_field_value_val;
|
||||
napi_create_string_utf8(env, di.name_field_value.c_str(),
|
||||
di.name_field_value.size(), &name_field_value_val);
|
||||
napi_set_named_property(env, result, "nameFieldValue", name_field_value_val);
|
||||
|
||||
napi_value shows_tag_field_val;
|
||||
napi_get_boolean(env, di.shows_tag_field, &shows_tag_field_val);
|
||||
napi_set_named_property(env, result, "showsTagField", shows_tag_field_val);
|
||||
|
||||
// NSOpenPanel-specific properties
|
||||
napi_value can_choose_files_val;
|
||||
napi_get_boolean(env, di.can_choose_files, &can_choose_files_val);
|
||||
napi_set_named_property(env, result, "canChooseFiles", can_choose_files_val);
|
||||
|
||||
napi_value can_choose_dirs_val;
|
||||
napi_get_boolean(env, di.can_choose_directories, &can_choose_dirs_val);
|
||||
napi_set_named_property(env, result, "canChooseDirectories",
|
||||
can_choose_dirs_val);
|
||||
|
||||
napi_value allows_multi_val;
|
||||
napi_get_boolean(env, di.allows_multiple_selection, &allows_multi_val);
|
||||
napi_set_named_property(env, result, "allowsMultipleSelection",
|
||||
allows_multi_val);
|
||||
|
||||
// Shared panel properties (open and save)
|
||||
napi_value shows_hidden_val;
|
||||
napi_get_boolean(env, di.shows_hidden_files, &shows_hidden_val);
|
||||
napi_set_named_property(env, result, "showsHiddenFiles", shows_hidden_val);
|
||||
|
||||
napi_value resolves_aliases_val;
|
||||
napi_get_boolean(env, di.resolves_aliases, &resolves_aliases_val);
|
||||
napi_set_named_property(env, result, "resolvesAliases", resolves_aliases_val);
|
||||
|
||||
napi_value treats_packages_val;
|
||||
napi_get_boolean(env, di.treats_packages_as_directories, &treats_packages_val);
|
||||
napi_set_named_property(env, result, "treatsPackagesAsDirectories",
|
||||
treats_packages_val);
|
||||
|
||||
napi_value can_create_dirs_val;
|
||||
napi_get_boolean(env, di.can_create_directories, &can_create_dirs_val);
|
||||
napi_set_named_property(env, result, "canCreateDirectories",
|
||||
can_create_dirs_val);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
napi_value ClickMessageBoxButton(napi_env env, napi_callback_info info) {
|
||||
napi_value args[2];
|
||||
char* data;
|
||||
size_t length;
|
||||
if (!GetHandleArg(env, info, 2, args, &data, &length))
|
||||
return NULL;
|
||||
|
||||
int32_t button_index;
|
||||
napi_status status = napi_get_value_int32(env, args[1], &button_index);
|
||||
if (status != napi_ok) {
|
||||
napi_throw_error(env, NULL, "Second argument must be a number (button index)");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool ok = dialog_helper::ClickMessageBoxButton(data, length, button_index);
|
||||
|
||||
napi_value result;
|
||||
napi_get_boolean(env, ok, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
napi_value ClickCheckbox(napi_env env, napi_callback_info info) {
|
||||
napi_value args[1];
|
||||
char* data;
|
||||
size_t length;
|
||||
if (!GetHandleArg(env, info, 1, args, &data, &length))
|
||||
return NULL;
|
||||
|
||||
bool ok = dialog_helper::ClickCheckbox(data, length);
|
||||
|
||||
napi_value result;
|
||||
napi_get_boolean(env, ok, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
napi_value CancelFileDialog(napi_env env, napi_callback_info info) {
|
||||
napi_value args[1];
|
||||
char* data;
|
||||
size_t length;
|
||||
if (!GetHandleArg(env, info, 1, args, &data, &length))
|
||||
return NULL;
|
||||
|
||||
bool ok = dialog_helper::CancelFileDialog(data, length);
|
||||
|
||||
napi_value result;
|
||||
napi_get_boolean(env, ok, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
napi_value AcceptFileDialog(napi_env env, napi_callback_info info) {
|
||||
napi_value args[2];
|
||||
char* data;
|
||||
size_t length;
|
||||
if (!GetHandleArg(env, info, 2, args, &data, &length))
|
||||
return NULL;
|
||||
|
||||
std::string filename;
|
||||
// Second argument (filename) is optional.
|
||||
napi_valuetype vtype;
|
||||
napi_typeof(env, args[1], &vtype);
|
||||
if (vtype == napi_string) {
|
||||
size_t str_len;
|
||||
napi_get_value_string_utf8(env, args[1], NULL, 0, &str_len);
|
||||
filename.resize(str_len);
|
||||
napi_get_value_string_utf8(env, args[1], &filename[0], str_len + 1,
|
||||
&str_len);
|
||||
}
|
||||
|
||||
bool ok = dialog_helper::AcceptFileDialog(data, length, filename);
|
||||
|
||||
napi_value result;
|
||||
napi_get_boolean(env, ok, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
napi_value Init(napi_env env, napi_value exports) {
|
||||
napi_property_descriptor descriptors[] = {
|
||||
{"getDialogInfo", NULL, GetDialogInfo, NULL, NULL, NULL,
|
||||
napi_enumerable, NULL},
|
||||
{"clickMessageBoxButton", NULL, ClickMessageBoxButton, NULL, NULL, NULL,
|
||||
napi_enumerable, NULL},
|
||||
{"clickCheckbox", NULL, ClickCheckbox, NULL, NULL, NULL,
|
||||
napi_enumerable, NULL},
|
||||
{"cancelFileDialog", NULL, CancelFileDialog, NULL, NULL, NULL,
|
||||
napi_enumerable, NULL},
|
||||
{"acceptFileDialog", NULL, AcceptFileDialog, NULL, NULL, NULL,
|
||||
napi_enumerable, NULL},
|
||||
};
|
||||
|
||||
napi_define_properties(env, exports,
|
||||
sizeof(descriptors) / sizeof(*descriptors),
|
||||
descriptors);
|
||||
return exports;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)
|
||||
@@ -7,6 +7,7 @@
|
||||
"node-gyp-install": "node-gyp install"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@electron-ci/dialog-helper": "*",
|
||||
"@electron-ci/echo": "*",
|
||||
"@electron-ci/external-ab": "*",
|
||||
"@electron-ci/is-valid-window": "*",
|
||||
|
||||
@@ -616,6 +616,12 @@ __metadata:
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@electron-ci/dialog-helper@npm:*, @electron-ci/dialog-helper@workspace:spec/fixtures/native-addon/dialog-helper":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@electron-ci/dialog-helper@workspace:spec/fixtures/native-addon/dialog-helper"
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@electron-ci/echo@npm:*, @electron-ci/echo@workspace:spec/fixtures/native-addon/echo":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@electron-ci/echo@workspace:spec/fixtures/native-addon/echo"
|
||||
@@ -4741,6 +4747,7 @@ __metadata:
|
||||
version: 0.0.0-use.local
|
||||
resolution: "electron-test-main@workspace:spec"
|
||||
dependencies:
|
||||
"@electron-ci/dialog-helper": "npm:*"
|
||||
"@electron-ci/echo": "npm:*"
|
||||
"@electron-ci/external-ab": "npm:*"
|
||||
"@electron-ci/is-valid-window": "npm:*"
|
||||
|
||||
Reference in New Issue
Block a user