Compare commits

..

1 Commits

Author SHA1 Message Date
Shelley Vohr
3bcb262d02 fix: update DBus signal signature for XDG GlobalShortcuts portal 2026-02-18 12:48:44 +01:00
36 changed files with 444 additions and 1106 deletions

View File

@@ -98,7 +98,7 @@ runs:
# Upload build stats to Datadog
if ($env:DD_API_KEY) {
try {
npx node electron\script\build-stats.mjs out\Default\siso.exe.INFO --upload-stats ; $LASTEXITCODE = 0
npx node electron\script\build-stats.mjs out\Default\siso.exe.INFO --upload-stats
} catch {
Write-Host "Build stats upload failed, continuing..."
}

View File

@@ -9,6 +9,5 @@
"embedded_asar_integrity_validation": "0",
"only_load_app_from_asar": "0",
"load_browser_process_specific_v8_snapshot": "0",
"grant_file_protocol_extra_privileges": "1",
"wasm_trap_handlers": "1"
"grant_file_protocol_extra_privileges": "1"
}

View File

@@ -250,9 +250,7 @@ Returns:
Emitted when the user clicks the native macOS new tab button. The new
tab button is only visible if the current `BrowserWindow` has a
`tabbingIdentifier`.
You must create a window in this handler in order for macOS tabbing to work as expected.
`tabbingIdentifier`
### Event: 'browser-window-blur'

View File

@@ -351,11 +351,7 @@ Emitted when the window has closed a sheet.
#### Event: 'new-window-for-tab' _macOS_
Emitted when the user clicks the native macOS new tab button. The new
tab button is only visible if the current `BrowserWindow` has a
`tabbingIdentifier`.
You must create a window in this handler in order for macOS tabbing to work as expected.
Emitted when the native new tab button is clicked.
#### Event: 'system-context-menu' _Windows_ _Linux_

View File

@@ -435,11 +435,7 @@ Emitted when the window has closed a sheet.
#### Event: 'new-window-for-tab' _macOS_
Emitted when the user clicks the native macOS new tab button. The new
tab button is only visible if the current `BrowserWindow` has a
`tabbingIdentifier`.
You must create a window in this handler in order for macOS tabbing to work as expected.
Emitted when the native new tab button is clicked.
#### Event: 'system-context-menu' _Windows_ _Linux_

View File

@@ -15,14 +15,6 @@ Currently, ASAR integrity checking is supported on:
* macOS as of `electron>=16.0.0`
* Windows as of `electron>=30.0.0`
> [!NOTE]
> ASAR integrity is fully supported in Mac App Store (MAS) builds and is recommended
> as a best practice. While MAS-installed applications have their `Resources/` folder
> protected by the system (owned by root), ASAR integrity still provides an additional
> layer of security. It is especially important if you use Electron's MAS build but
> distribute your app through channels other than the Mac App Store (such as direct
> download), since those installations won't have the system-level read-only protections.
In order to enable ASAR integrity checking, you also need to ensure that your `app.asar` file
was generated by a version of the `@electron/asar` npm package that supports ASAR integrity.

View File

@@ -137,33 +137,6 @@ The extra privileges granted to the `file://` protocol by this fuse are incomple
* `file://` protocol pages have universal access granted to child frames also running on `file://`
protocols regardless of sandbox settings
### `wasmTrapHandlers`
**Default:** Enabled
**@electron/fuses:** `FuseV1Options.WasmTrapHandlers`
The `wasmTrapHandlers` fuse controls whether V8 will use signal handlers to trap Out of Bounds memory
access from WebAssembly. The feature works by surrounding the WebAssembly memory with large guard regions
and then installing a signal handler that traps attempt to access memory in the guard region. The feature
is only supported on the following 64-bit systems.
Linux. MacOS, Windows - x86_64
Linux, MacOS - aarch64
| Guard Pages | WASM heap | Guard Pages |
|-----8GB-----| |-----8GB-----|
When the fuse is disabled V8 will use explicit bound checks in the generated WebAssembly code to ensure
memory safety. However, this method has some downsides
* The compiler generates extra nodes for each memory reference, leading to longer compile times due to the
additional processing time needed for these nodes.
* In turn, these extra nodes lead to lots of extra code being generated, making WebAssembly modules bigger
than they ideally should be.
* This extra code, particularly the compare and branch before every memory reference,
incurs a significant runtime cost.
## How do I flip fuses?
### The easy way

View File

@@ -56,7 +56,7 @@
"ts-node": "6.2.0",
"typescript": "^5.8.3",
"url": "^0.11.4",
"webpack": "^5.104.1",
"webpack": "^5.95.0",
"webpack-cli": "^6.0.1",
"wrapper-webpack-plugin": "^2.2.0",
"yaml": "^2.8.1"
@@ -65,7 +65,7 @@
"scripts": {
"asar": "asar",
"generate-version-json": "node script/generate-version-json.js",
"lint": "node ./script/lint.js && npm run lint:docs && npm run lint:chromium-roller",
"lint": "node ./script/lint.js && npm run lint:docs",
"lint:js": "node ./script/lint.js --js",
"lint:clang-format": "python3 script/run-clang-format.py -r -c shell/ || (echo \"\\nCode not formatted correctly.\" && exit 1)",
"lint:clang-tidy": "ts-node ./script/run-clang-tidy.ts",
@@ -80,7 +80,6 @@
"lint:ts-check-js-in-markdown": "lint-roller-markdown-ts-check --root docs \"**/*.md\" --ignore \"breaking-changes.md\"",
"lint:js-in-markdown": "lint-roller-markdown-standard --root docs \"**/*.md\"",
"lint:api-history": "lint-roller-markdown-api-history --root \"./docs/api/\" --schema \"./docs/api-history.schema.json\" --breaking-changes-file \"./docs/breaking-changes.md\" --check-placement --check-strings \"*.md\"",
"lint:chromium-roller": "node ./script/lint-roller-chromium-changes.mjs",
"create-api-json": "node script/create-api-json.mjs",
"create-typescript-definitions": "npm run create-api-json && electron-typescript-definitions --api=electron-api.json && node spec/ts-smoke/runner.js",
"gn-typescript-definitions": "npm run create-typescript-definitions && node script/cp.mjs electron.d.ts",
@@ -104,9 +103,6 @@
"electron"
],
"lint-staged": {
"*": [
"npm run lint:chromium-roller"
],
"*.{js,ts}": [
"node script/lint.js --js --fix --only --"
],

View File

@@ -144,3 +144,4 @@ fix_linux_tray_id.patch
expose_gtk_ui_platform_field.patch
patch_osr_control_screen_info.patch
refactor_allow_customizing_config_in_freedesktopsecretkeyprovider.patch
fix_update_dbus_signal_signature_for_xdg_globalshortcuts_portal.patch

View File

@@ -23,10 +23,10 @@ additional headless changes from breaking macOS window behavior.
https://chromium-review.googlesource.com/c/chromium/src/+/7487666
diff --git a/components/remote_cocoa/app_shim/native_widget_mac_nswindow.mm b/components/remote_cocoa/app_shim/native_widget_mac_nswindow.mm
index 94bd32ce1ddd3f8b4315cd06be59d7550b591891..ad005e0a19a7763da089fccc659d93c8815dc860 100644
index 2a195724de141fd4f0f06c03314e6096a0d0ed3f..2532ae21d9244b2ec9747ef7d9916668dcad145c 100644
--- a/components/remote_cocoa/app_shim/native_widget_mac_nswindow.mm
+++ b/components/remote_cocoa/app_shim/native_widget_mac_nswindow.mm
@@ -231,6 +231,7 @@ @implementation NativeWidgetMacNSWindow {
@@ -218,6 +218,7 @@ @implementation NativeWidgetMacNSWindow {
BOOL _isEnforcingNeverMadeVisible;
BOOL _activationIndependence;
BOOL _isTooltip;
@@ -34,7 +34,7 @@ index 94bd32ce1ddd3f8b4315cd06be59d7550b591891..ad005e0a19a7763da089fccc659d93c8
BOOL _isShufflingForOrdering;
BOOL _miniaturizationInProgress;
std::unique_ptr<NativeWidgetMacNSWindowHeadlessInfo> _headless_info;
@@ -238,6 +239,7 @@ @implementation NativeWidgetMacNSWindow {
@@ -225,6 +226,7 @@ @implementation NativeWidgetMacNSWindow {
@synthesize bridgedNativeWidgetId = _bridgedNativeWidgetId;
@synthesize bridge = _bridge;
@synthesize isTooltip = _isTooltip;
@@ -42,7 +42,7 @@ index 94bd32ce1ddd3f8b4315cd06be59d7550b591891..ad005e0a19a7763da089fccc659d93c8
@synthesize isShufflingForOrdering = _isShufflingForOrdering;
@synthesize preventKeyWindow = _preventKeyWindow;
@synthesize childWindowAddedHandler = _childWindowAddedHandler;
@@ -259,23 +261,6 @@ - (instancetype)initWithContentRect:(NSRect)contentRect
@@ -246,23 +248,6 @@ - (instancetype)initWithContentRect:(NSRect)contentRect
return self;
}

View File

@@ -0,0 +1,58 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shelley Vohr <shelley.vohr@gmail.com>
Date: Mon, 16 Feb 2026 22:33:57 +0100
Subject: fix: update DBus signal signature for XDG GlobalShortcuts portal
Refs https://chromium-review.googlesource.com/c/chromium/src/+/7143562
The Activated signal from the XDG GlobalShortcuts portal has signature "osta{sv}",
but ConnectToSignal was declared with "ost". The strict ReadMessage parser
fails on the extra trailing options vardict. Fix by updating the signature
to match the spec.
This should be upstreamed.
diff --git a/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener_linux.cc b/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener_linux.cc
index b66e3ef53c7be56dce6e8c73792ef18a8ccf9f11..a5bb1271231bb092c5e35fcf0cc99f0a18164147 100644
--- a/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener_linux.cc
+++ b/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener_linux.cc
@@ -80,7 +80,7 @@ void GlobalAcceleratorListenerLinux::OnServiceStarted(uint32_t version) {
global_shortcuts_proxy_ = bus_->GetObjectProxy(
kPortalServiceName, dbus::ObjectPath(kPortalObjectPath));
- dbus_utils::ConnectToSignal<"ost">(
+ dbus_utils::ConnectToSignal<"osta{sv}">(
global_shortcuts_proxy_, kGlobalShortcutsInterface, kSignalActivated,
base::BindRepeating(&GlobalAcceleratorListenerLinux::OnActivatedSignal,
weak_ptr_factory_.GetWeakPtr()),
@@ -303,13 +303,14 @@ void GlobalAcceleratorListenerLinux::OnBindShortcuts(
}
void GlobalAcceleratorListenerLinux::OnActivatedSignal(
- dbus_utils::ConnectToSignalResultSig<"ost"> result) {
+ dbus_utils::ConnectToSignalResultSig<"osta{sv}"> result) {
if (!result.has_value()) {
LOG(ERROR) << "Failed to parse Activated signal.";
return;
}
- auto [session_handle, shortcut_id, timestamp] = std::move(result.value());
+ auto [session_handle, shortcut_id, timestamp, options] =
+ std::move(result.value());
// Only process the signal if it comes from our current session.
if (!session_proxy_ || session_proxy_->object_path() != session_handle) {
diff --git a/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener_linux.h b/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener_linux.h
index 458a39f8c9ac8c1882d62360e3c06e02e20cd9db..d6701805d79b9a3631afdeecc5ed139d02b64cb3 100644
--- a/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener_linux.h
+++ b/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener_linux.h
@@ -98,7 +98,8 @@ class GlobalAcceleratorListenerLinux : public GlobalAcceleratorListener {
base::expected<dbus_xdg::Dictionary, dbus_xdg::ResponseError> results);
// Callbacks for DBus signals.
- void OnActivatedSignal(dbus_utils::ConnectToSignalResultSig<"ost"> result);
+ void OnActivatedSignal(
+ dbus_utils::ConnectToSignalResultSig<"osta{sv}"> result);
void OnSignalConnected(const std::string& interface_name,
const std::string& signal_name,

View File

@@ -640,7 +640,7 @@ index 48f47bf3eeb8464d1c3925f0f73f62c790cac2f0..b7b2b7c1b7e99927012ce1676cc753b2
// The NSWindow used by BridgedNativeWidget. Provides hooks into AppKit that
// can only be accomplished by overriding methods.
diff --git a/components/remote_cocoa/app_shim/native_widget_mac_nswindow.mm b/components/remote_cocoa/app_shim/native_widget_mac_nswindow.mm
index a5fc9193711a7cc2eee45171178c070321177ca2..94bd32ce1ddd3f8b4315cd06be59d7550b591891 100644
index a5fc9193711a7cc2eee45171178c070321177ca2..2a195724de141fd4f0f06c03314e6096a0d0ed3f 100644
--- a/components/remote_cocoa/app_shim/native_widget_mac_nswindow.mm
+++ b/components/remote_cocoa/app_shim/native_widget_mac_nswindow.mm
@@ -22,6 +22,7 @@
@@ -677,7 +677,7 @@ index a5fc9193711a7cc2eee45171178c070321177ca2..94bd32ce1ddd3f8b4315cd06be59d755
@end
struct NSEdgeAndCornerThicknesses {
@@ -159,13 +164,30 @@ - (void)cr_mouseDownOnFrameView:(NSEvent*)event;
@@ -159,13 +164,17 @@ - (void)cr_mouseDownOnFrameView:(NSEvent*)event;
@implementation NSView (CRFrameViewAdditions)
// If a mouseDown: falls through to the frame view, turn it into a window drag.
- (void)cr_mouseDownOnFrameView:(NSEvent*)event {
@@ -685,19 +685,6 @@ index a5fc9193711a7cc2eee45171178c070321177ca2..94bd32ce1ddd3f8b4315cd06be59d755
if ([self.window _resizeDirectionForMouseLocation:event.locationInWindow] !=
-1)
return;
+#else
+ // For MAS builds, approximate the resize direction check.
+ if (self.window.styleMask & NSWindowStyleMaskResizable) {
+ constexpr CGFloat kResizeThreshold = 5.0;
+ NSPoint location = event.locationInWindow;
+ NSRect frame = self.window.frame;
+ CGFloat width = NSWidth(frame);
+ CGFloat height = NSHeight(frame);
+ if (location.x < kResizeThreshold || location.x > width - kResizeThreshold ||
+ location.y < kResizeThreshold || location.y > height - kResizeThreshold) {
+ return;
+ }
+ }
+#endif
[self.window performWindowDragWithEvent:event];
}
@@ -708,7 +695,7 @@ index a5fc9193711a7cc2eee45171178c070321177ca2..94bd32ce1ddd3f8b4315cd06be59d755
@implementation NativeWidgetMacNSWindowTitledFrame
- (void)mouseDown:(NSEvent*)event {
if (self.window.isMovable)
@@ -193,6 +215,8 @@ - (BOOL)usesCustomDrawing {
@@ -193,6 +202,8 @@ - (BOOL)usesCustomDrawing {
}
@end
@@ -717,7 +704,7 @@ index a5fc9193711a7cc2eee45171178c070321177ca2..94bd32ce1ddd3f8b4315cd06be59d755
@implementation NativeWidgetMacNSWindow {
@private
CommandDispatcher* __strong _commandDispatcher;
@@ -268,6 +292,7 @@ - (BOOL)invokeOriginalIsVisibleForTesting {
@@ -268,6 +279,7 @@ - (BOOL)invokeOriginalIsVisibleForTesting {
// bubbles and the find bar, but these should not be movable.
// Instead, let's push this up to the parent window which should be
// the browser.
@@ -725,7 +712,7 @@ index a5fc9193711a7cc2eee45171178c070321177ca2..94bd32ce1ddd3f8b4315cd06be59d755
- (void)_zoomToScreenEdge:(NSUInteger)edge {
if (self.parentWindow) {
[self.parentWindow _zoomToScreenEdge:edge];
@@ -275,6 +300,7 @@ - (void)_zoomToScreenEdge:(NSUInteger)edge {
@@ -275,6 +287,7 @@ - (void)_zoomToScreenEdge:(NSUInteger)edge {
[super _zoomToScreenEdge:edge];
}
}
@@ -733,7 +720,7 @@ index a5fc9193711a7cc2eee45171178c070321177ca2..94bd32ce1ddd3f8b4315cd06be59d755
// This override helps diagnose lifetime issues in crash stacktraces by
// inserting a symbol on NativeWidgetMacNSWindow and should be kept even if it
@@ -407,6 +433,8 @@ - (NSAccessibilityRole)accessibilityRole {
@@ -407,6 +420,8 @@ - (NSAccessibilityRole)accessibilityRole {
// NSWindow overrides.
@@ -742,7 +729,7 @@ index a5fc9193711a7cc2eee45171178c070321177ca2..94bd32ce1ddd3f8b4315cd06be59d755
+ (Class)frameViewClassForStyleMask:(NSWindowStyleMask)windowStyle {
if (windowStyle & NSWindowStyleMaskTitled) {
if (Class customFrame = [NativeWidgetMacNSWindowTitledFrame class])
@@ -418,6 +446,8 @@ + (Class)frameViewClassForStyleMask:(NSWindowStyleMask)windowStyle {
@@ -418,6 +433,8 @@ + (Class)frameViewClassForStyleMask:(NSWindowStyleMask)windowStyle {
return [super frameViewClassForStyleMask:windowStyle];
}
@@ -751,7 +738,7 @@ index a5fc9193711a7cc2eee45171178c070321177ca2..94bd32ce1ddd3f8b4315cd06be59d755
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen*)screen {
if (self.isHeadless || self.parentWindow) {
// AppKit's default implementation moves child windows down to avoid
@@ -455,12 +485,14 @@ - (BOOL)_usesCustomDrawing {
@@ -455,12 +472,14 @@ - (BOOL)_usesCustomDrawing {
// if it were valid to set that style for windows, setting the window style
// recalculates and re-caches a bunch of stuff, so a surgical override is the
// cleanest approach.
@@ -766,7 +753,7 @@ index a5fc9193711a7cc2eee45171178c070321177ca2..94bd32ce1ddd3f8b4315cd06be59d755
+ (void)_getExteriorResizeEdgeThicknesses:
(NSEdgeAndCornerThicknesses*)outThicknesses
@@ -714,9 +746,11 @@ - (id)archiver:(NSKeyedArchiver*)archiver willEncodeObject:(id)object {
@@ -714,9 +733,11 @@ - (id)archiver:(NSKeyedArchiver*)archiver willEncodeObject:(id)object {
}
- (void)saveRestorableState {
@@ -778,7 +765,7 @@ index a5fc9193711a7cc2eee45171178c070321177ca2..94bd32ce1ddd3f8b4315cd06be59d755
// Certain conditions, such as in the Speedometer 3 benchmark, can trigger a
// rapid succession of calls to saveRestorableState. If there's no pending
@@ -783,6 +817,7 @@ - (void)reallySaveRestorableState {
@@ -783,6 +804,7 @@ - (void)reallySaveRestorableState {
// affects its restorable state changes.
- (void)invalidateRestorableState {
[super invalidateRestorableState];
@@ -786,7 +773,7 @@ index a5fc9193711a7cc2eee45171178c070321177ca2..94bd32ce1ddd3f8b4315cd06be59d755
if ([self _isConsideredOpenForPersistentState]) {
if (_willUpdateRestorableState)
return;
@@ -795,6 +830,7 @@ - (void)invalidateRestorableState {
@@ -795,6 +817,7 @@ - (void)invalidateRestorableState {
_willUpdateRestorableState = NO;
[NSObject cancelPreviousPerformRequestsWithTarget:self];
}
@@ -794,7 +781,7 @@ index a5fc9193711a7cc2eee45171178c070321177ca2..94bd32ce1ddd3f8b4315cd06be59d755
}
// On newer SDKs, _canMiniaturize respects NSWindowStyleMaskMiniaturizable in
@@ -971,6 +1007,7 @@ - (void)maybeRemoveTreeFromOrderingGroups {
@@ -971,6 +994,7 @@ - (void)maybeRemoveTreeFromOrderingGroups {
// Since _removeFromGroups: is not documented it could go away in newer
// versions of macOS. If the selector does not exist, DumpWithoutCrashing() so
// we hear about the change.
@@ -802,7 +789,7 @@ index a5fc9193711a7cc2eee45171178c070321177ca2..94bd32ce1ddd3f8b4315cd06be59d755
if (![NSWindow instancesRespondToSelector:@selector(_removeFromGroups:)]) {
base::debug::DumpWithoutCrashing();
return;
@@ -988,6 +1025,7 @@ - (void)maybeRemoveTreeFromOrderingGroups {
@@ -988,6 +1012,7 @@ - (void)maybeRemoveTreeFromOrderingGroups {
[currentWindow _removeFromGroups:child];
}
}

View File

@@ -142,29 +142,8 @@ async function findMatchingFiles (top, test) {
});
}
function compareVersions (v1, v2) {
const [split1, split2] = [v1.split('.'), v2.split('.')];
if (split1.length !== split2.length) {
throw new Error(
`Expected version strings to have same number of sections: ${split1} and ${split2}`
);
}
for (let i = 0; i < split1.length; i++) {
const p1 = parseInt(split1[i], 10);
const p2 = parseInt(split2[i], 10);
if (p1 > p2) return 1;
else if (p1 < p2) return -1;
// Continue checking the value if this portion is equal
}
return 0;
}
module.exports = {
chunkFilenames,
compareVersions,
findMatchingFiles,
getCurrentBranch,
getElectronExec,

View File

@@ -1,287 +0,0 @@
#!/usr/bin/env node
import { execSync } from 'node:child_process';
import * as fs from 'node:fs/promises';
import { dirname, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
import { compareVersions } from './lib/utils.js';
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 ROLLER_BRANCH_PATTERN = /^roller\/chromium\/(.+)$/;
function getCommitsSinceMergeBase (mergeBase) {
try {
const output = execSync(`git log --format=%H%n%B%n---COMMIT_END--- ${mergeBase}..HEAD`, {
cwd: ELECTRON_DIR,
encoding: 'utf8'
});
const commits = [];
const parts = output.split('---COMMIT_END---');
for (const part of parts) {
const trimmed = part.trim();
if (!trimmed) continue;
const lines = trimmed.split('\n');
const sha = lines[0];
const message = lines.slice(1).join('\n');
if (sha && message) {
commits.push({ sha, message });
}
}
return commits;
} catch {
return [];
}
}
async function fetchChromiumDashCommit (commitSha, repo) {
const url = `https://chromiumdash.appspot.com/fetch_commit?commit=${commitSha}&repo=${repo}`;
const response = await fetch(url);
if (!response.ok) {
return null;
}
try {
return await response.json();
} catch {
return null;
}
}
async function getGerritPatchDetails (clUrl) {
const parsedUrl = new URL(clUrl);
const match = /^\/c\/(.+?)\/\+\/(\d+)/.exec(parsedUrl.pathname);
if (!match) {
return null;
}
const [, repo, number] = match;
const changeId = `${repo}~${number}`;
const url = `https://chromium-review.googlesource.com/changes/${encodeURIComponent(changeId)}?o=CURRENT_REVISION`;
const response = await fetch(url);
if (!response.ok) {
return null;
}
try {
// Gerrit returns JSON with a magic prefix
const text = await response.text();
const jsonText = text.startsWith(")]}'") ? text.substring(4) : text;
const data = JSON.parse(jsonText);
// Get the current revision's commit SHA
const currentRevision = data.current_revision;
return {
commitSha: currentRevision,
project: data.project
};
} catch {
return null;
}
}
async function main () {
let currentBranch;
try {
currentBranch = execSync('git rev-parse --abbrev-ref HEAD', {
cwd: ELECTRON_DIR,
encoding: 'utf8'
}).trim();
} catch {
console.error('Could not determine current git branch');
process.exit(1);
}
// Check if we're on a roller/chromium/* branch
const branchMatch = ROLLER_BRANCH_PATTERN.exec(currentBranch);
if (!branchMatch) {
console.log(`Not on a roller/chromium/* branch (current: ${currentBranch}), skipping lint.`);
process.exit(0);
}
const targetBranch = branchMatch[1];
console.log(`Linting roller branch: ${currentBranch} (target: ${targetBranch})`);
// Get the merge base with the target branch
let mergeBase;
try {
mergeBase = execSync(`git merge-base ${currentBranch} origin/${targetBranch}`, {
cwd: ELECTRON_DIR,
encoding: 'utf8'
}).trim();
} catch {
console.error(`Could not determine merge base with origin/${targetBranch}`);
process.exit(1);
}
// Get version range
let baseVersion = null;
try {
const baseDepsContent = execSync(`git show ${mergeBase}:DEPS`, {
cwd: ELECTRON_DIR,
encoding: 'utf8'
});
baseVersion = DEPS_REGEX.exec(baseDepsContent)?.[1] ?? null;
} catch {
// baseVersion remains null
}
const depsContent = await fs.readFile(resolve(ELECTRON_DIR, 'DEPS'), 'utf8');
const newVersion = DEPS_REGEX.exec(depsContent)?.[1] ?? null;
if (!baseVersion || !newVersion) {
console.error('Could not determine Chromium version range');
console.error(` Base version: ${baseVersion ?? 'unknown'}`);
console.error(` New version: ${newVersion ?? 'unknown'}`);
process.exit(1);
}
console.log(`Chromium version range: ${baseVersion} -> ${newVersion}`);
// Get all commits since merge base
const commits = getCommitsSinceMergeBase(mergeBase);
console.log(`Found ${commits.length} commits to check`);
let hasErrors = false;
const checkedCLs = new Map(); // Cache CL check results
for (const commit of commits) {
const shortSha = commit.sha.substring(0, 7);
const firstLine = commit.message.split('\n')[0];
// Check for Skip-Lint trailer
const skipLintMatch = /^Skip-Lint:\s*(.+)$/m.exec(commit.message);
if (skipLintMatch) {
console.log(`\nSkipping commit ${shortSha}: ${firstLine}`);
console.log(` ⏭️ Reason: ${skipLintMatch[1]}`);
continue;
}
const cls = [...commit.message.matchAll(CL_REGEX)].map((match) => ({
url: match[0],
clNumber: match[1],
fragment: match[2] ?? null
}));
if (cls.length === 0) {
// No CLs in this commit, skip
continue;
}
console.log(`\nChecking commit ${shortSha}: ${firstLine}`);
for (const cl of cls) {
// Skip CLs annotated with #nolint
if (cl.fragment === '#nolint') {
console.log(` ⏭️ CL ${cl.clNumber}: skipped (#nolint)`);
continue;
}
// Check cache first (use URL as key to distinguish same CL number across repos)
if (checkedCLs.has(cl.url)) {
const cached = checkedCLs.get(cl.url);
if (cached.valid) {
console.log(` ✅ CL ${cl.clNumber}: (already validated)`);
} else {
console.error(` ❌ CL ${cl.clNumber}: ${cached.error}`);
hasErrors = true;
}
continue;
}
// Determine repo from URL
const isV8 = cl.url.startsWith('https://chromium-review.googlesource.com/c/v8/v8/');
const repo = isV8 ? 'v8' : 'chromium';
// Fetch Gerrit details to get commit SHA
const gerritDetails = await getGerritPatchDetails(cl.url);
if (!gerritDetails) {
const error = 'Could not fetch CL details from Gerrit';
checkedCLs.set(cl.url, { valid: false, error });
console.error(` ❌ CL ${cl.clNumber}: ${error}`);
hasErrors = true;
continue;
}
// Fetch from Chromium Dash to get the earliest version
const dashDetails = await fetchChromiumDashCommit(gerritDetails.commitSha, repo);
if (!dashDetails) {
const error = 'Could not fetch commit details from Chromium Dash';
checkedCLs.set(cl.url, { valid: false, error });
console.error(` ❌ CL ${cl.clNumber}: ${error}`);
hasErrors = true;
continue;
}
const clEarliestVersion = dashDetails.earliest;
if (!clEarliestVersion) {
const error = 'CL has no earliest version (may not be merged yet)';
checkedCLs.set(cl.url, { valid: false, error });
console.error(` ❌ CL ${cl.clNumber}: ${error}`);
hasErrors = true;
continue;
}
// For V8 CLs, we need to find the corresponding Chromium commit
let chromiumVersion = clEarliestVersion;
if (isV8 && dashDetails.relations) {
const chromiumRelation = dashDetails.relations.find(
(rel) => rel.from_commit === gerritDetails.commitSha
);
if (chromiumRelation) {
const chromiumDash = await fetchChromiumDashCommit(chromiumRelation.to_commit, 'chromium');
if (chromiumDash?.earliest) {
chromiumVersion = chromiumDash.earliest;
}
}
}
// CL should have landed after the base version and at or before the new version
const isInRange =
compareVersions(chromiumVersion, baseVersion) > 0 &&
compareVersions(chromiumVersion, newVersion) <= 0;
if (!isInRange) {
const error = `CL earliest version ${chromiumVersion} is outside roller range (${baseVersion} -> ${newVersion})`;
checkedCLs.set(cl.url, { valid: false, error });
console.error(` ❌ CL ${cl.clNumber}: ${error}`);
hasErrors = true;
continue;
}
checkedCLs.set(cl.url, { valid: true });
console.log(` ✅ CL ${cl.clNumber}: version ${chromiumVersion} is within range`);
}
}
console.log(hasErrors ? '\n❌ Lint failed' : '\n✅ Lint passed');
if (hasErrors) {
console.log(' NOTE: Add "Skip-Lint: <reason>" to a commit message to skip linting that commit.');
}
process.exit(hasErrors && process.env.CI ? 1 : 0);
}
if ((await fs.realpath(process.argv[1])) === fileURLToPath(import.meta.url)) {
main()
.then(() => {
process.exit(0);
})
.catch((err) => {
console.error(`ERROR: ${err.message}`);
process.exit(1);
});
}

View File

@@ -6,7 +6,7 @@ import { spawnSync } from 'node:child_process';
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
import { resolve as _resolve } from 'node:path';
import { compareVersions, ELECTRON_DIR } from '../../lib/utils';
import { ELECTRON_DIR } from '../../lib/utils';
import { createGitHubTokenStrategy } from '../github-token';
import { ELECTRON_ORG, ELECTRON_REPO } from '../types';
@@ -612,6 +612,26 @@ const getNotes = async (fromRef: string, toRef: string, newVersion: string) => {
return notes;
};
const compareVersions = (v1: string, v2: string) => {
const [split1, split2] = [v1.split('.'), v2.split('.')];
if (split1.length !== split2.length) {
throw new Error(
`Expected version strings to have same number of sections: ${split1} and ${split2}`
);
}
for (let i = 0; i < split1.length; i++) {
const p1 = parseInt(split1[i], 10);
const p2 = parseInt(split2[i], 10);
if (p1 > p2) return 1;
else if (p1 < p2) return -1;
// Continue checking the value if this portion is equal
}
return 0;
};
const removeSupercededStackUpdates = (commits: Commit[]) => {
const updateRegex = /^Updated ([a-zA-Z.]+) to v?([\d.]+)/;
const notupdates = [];

View File

@@ -1,14 +1,14 @@
{
"bullseye_amd64": {
"Key": "20250129T203412Z-2",
"Sha256Sum": "f2e052b0cdab9b6f9bfe311c5269264d5f4e38a018bbc27ba2314b73ac8f7053",
"Sha256Sum": "986ffe8f444b650c38de1786a930516bf9447ec7003a6c367de4aade8ebdb186",
"SysrootDir": "debian_bullseye_amd64-sysroot",
"Tarball": "debian_bullseye_amd64_sysroot.tar.xz",
"URL": "https://dev-cdn.electronjs.org/linux-sysroots"
},
"bullseye_arm64": {
"Key": "20250129T203412Z-2",
"Sha256Sum": "f4f680a60e314418f95513ac63e9942ad565005ebbd36b660b20cd605d11a664",
"Sha256Sum": "6be0900393d73e69518f0996807dbc542c0d47cab1c4903c9d188347f945114a",
"SysrootDir": "debian_bullseye_arm64-sysroot",
"Tarball": "debian_bullseye_arm64_sysroot.tar.xz",
"URL": "https://dev-cdn.electronjs.org/linux-sysroots"
@@ -22,44 +22,44 @@
},
"bullseye_armhf": {
"Key": "20250129T203412Z-2",
"Sha256Sum": "f99ef848d2f6046437d3277da4442f82dafba040cafdf7f461c9726298e45653",
"Sha256Sum": "060631cd0583b5204c646d41a5fbbe6080fd7a822feefba01900bd8e41a67b13",
"SysrootDir": "debian_bullseye_armhf-sysroot",
"Tarball": "debian_bullseye_armhf_sysroot.tar.xz",
"URL": "https://dev-cdn.electronjs.org/linux-sysroots"
},
"bullseye_i386": {
"Key": "20250129T203412Z-2",
"Sha256Sum": "4c35cf12fc7f53def4f0b105ba7a09e4a5ef5671aa5a898ab19be09e1e8d16b9",
"Sha256Sum": "a6b63543ac2a57f477a6ea54b1e36dc8bfeb2f19c963866f79b1b2a93ed43a6e",
"SysrootDir": "debian_bullseye_i386-sysroot",
"Tarball": "debian_bullseye_i386_sysroot.tar.xz",
"URL": "https://dev-cdn.electronjs.org/linux-sysroots"
},
"bullseye_mips64el": {
"Key": "20250129T203412Z-2",
"Sha256Sum": "a84374ea0966f1026088fdbe34521ff56760878aa93f9af21160caf4155659fc",
"Sha256Sum": "814ccd5d9524020b23a16a5a581644ca8ba2f1e3515a1ddcbb62e938d4f4e0b0",
"SysrootDir": "debian_bullseye_mips64el-sysroot",
"Tarball": "debian_bullseye_mips64el_sysroot.tar.xz",
"URL": "https://dev-cdn.electronjs.org/linux-sysroots"
},
"bullseye_mipsel": {
"Key": "20250129T203412Z-2",
"Sha256Sum": "f7f06a49f92ee8c9a1d16c424b668c6dfed33006f2ef015124c660143bb89ee8",
"Sha256Sum": "7f3218966b7bc636409a0f3d5104d9046b03faf660847f9026df9ce2c9775d53",
"SysrootDir": "debian_bullseye_mipsel-sysroot",
"Tarball": "debian_bullseye_mipsel_sysroot.tar.xz",
"URL": "https://dev-cdn.electronjs.org/linux-sysroots"
},
"bullseye_ppc64el": {
"Key": "20250129T203412Z-2",
"Sha256Sum": "9e3c152f17c292c3e9be31b3fe63666eebac3e13d2e0d83f8de0acaa77417ac2",
"Sha256Sum": "bdab0a372cf5bfdc154226cc5ed72d417096c725085d193509d1f12e0debec66",
"SysrootDir": "debian_bullseye_ppc64el-sysroot",
"Tarball": "debian_bullseye_ppc64el_sysroot.tar.xz",
"URL": "https://dev-cdn.electronjs.org/linux-sysroots"
},
"trixie_riscv64": {
"Key": "20250129T203412Z-2",
"Sha256Sum": "d997eaa308ce148c4a429549ca360bf3f58b5861fe7f5f1d826ccf0a8eccbe48",
"Sha256Sum": "2183652af753225da2371d7bccddcb0269ee388e4508ed1fdeb810cb05cba898",
"SysrootDir": "debian_trixie_riscv64-sysroot",
"Tarball": "debian_trixie_riscv64_sysroot.tar.xz",
"URL": "https://dev-cdn.electronjs.org/linux-sysroots"
}
}
}

View File

@@ -83,16 +83,8 @@ void WebContentsView::ApplyBorderRadius() {
int WebContentsView::NonClientHitTest(const gfx::Point& point) {
if (api_web_contents_) {
// Convert the point to the contents view's coordinate space rather than
// the InspectableWebContentsView's coordinate space, because the draggable
// region is relative to the web content area. When DevTools is docked
// (e.g. to the left), the contents view is offset within the parent,
// so we need to account for that offset.
auto* inspectable_view =
api_web_contents_->inspectable_web_contents()->GetView();
auto* contents_view = inspectable_view->GetContentsView();
gfx::Point local_point(point);
views::View::ConvertPointFromWidget(contents_view, &local_point);
views::View::ConvertPointFromWidget(view(), &local_point);
SkRegion* region = api_web_contents_->draggable_region();
if (region && region->contains(local_point.x(), local_point.y()))
return HTCAPTION;

View File

@@ -41,7 +41,6 @@
#include "content/public/common/process_type.h"
#include "content/public/common/result_codes.h"
#include "electron/buildflags/buildflags.h"
#include "electron/fuses.h"
#include "media/base/localized_strings.h"
#include "services/network/public/cpp/features.h"
#include "services/tracing/public/cpp/stack_sampling/tracing_sampler_profiler.h"
@@ -63,7 +62,6 @@
#include "shell/common/logging.h"
#include "shell/common/node_bindings.h"
#include "shell/common/node_includes.h"
#include "shell/common/v8_util.h"
#include "ui/base/idle/idle.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/ui_base_switches.h"
@@ -240,15 +238,6 @@ void ElectronBrowserMainParts::PostEarlyInitialization() {
v8::Isolate* const isolate = js_env_->isolate();
v8::HandleScope scope(isolate);
// Enable trap handlers before user script execution.
#if ((BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)) && \
defined(ARCH_CPU_X86_64)) || \
((BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC)) && defined(ARCH_CPU_ARM64))
if (electron::fuses::IsWasmTrapHandlersEnabled()) {
electron::SetUpWebAssemblyTrapHandler();
}
#endif
node_bindings_->Initialize(isolate, isolate->GetCurrentContext());
// Create the global environment.
node_env_ = node_bindings_->CreateEnvironment(

View File

@@ -29,7 +29,6 @@
#include "shell/browser/api/electron_api_system_preferences.h"
#include "shell/browser/api/electron_api_web_contents.h"
#include "shell/browser/ui/inspectable_web_contents_view.h"
#include "shell/browser/ui/views/frameless_view.h"
#include "shell/browser/ui/views/root_view.h"
#include "shell/browser/web_contents_preferences.h"
#include "shell/browser/web_view_manager.h"
@@ -42,19 +41,14 @@
#include "ui/base/hit_test.h"
#include "ui/compositor/compositor.h"
#include "ui/display/screen.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/gfx/geometry/outsets.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/native_ui_types.h"
#include "ui/ozone/public/ozone_platform.h"
#include "ui/views/background.h"
#include "ui/views/controls/webview/webview.h"
#include "ui/views/view_utils.h"
#include "ui/views/widget/native_widget_private.h"
#include "ui/views/widget/widget.h"
#include "ui/views/window/client_view.h"
#include "ui/views/window/frame_view.h"
#include "ui/views/window/non_client_view.h"
#include "ui/wm/core/shadow_types.h"
#include "ui/wm/core/window_util.h"
@@ -438,12 +432,9 @@ NativeWindowViews::NativeWindowViews(const int32_t base_window_id,
window->AddPreTargetHandler(this);
#if BUILDFLAG(IS_LINUX)
// We need to set bounds again after widget init for two reasons:
// 1. For CSD windows, user-specified bounds need to be inflated by frame
// insets, but the frame view isn't available at first.
// 2. The widget clamps bounds to fit the screen, but we want to allow
// windows larger than the display.
SetBounds(gfx::Rect(GetPosition(), size), false);
// On linux after the widget is initialized we might have to force set the
// bounds if the bounds are smaller than the current display
SetBounds(gfx::Rect(GetPosition(), bounds.size()), false);
#endif
}
@@ -884,14 +875,16 @@ void NativeWindowViews::SetBounds(const gfx::Rect& bounds, bool animate) {
}
#endif
widget()->SetBounds(LogicalToWidgetBounds(bounds));
widget()->SetBounds(bounds);
}
gfx::Rect NativeWindowViews::GetBounds() const {
#if BUILDFLAG(IS_WIN)
if (IsMinimized())
return WidgetToLogicalBounds(widget()->GetRestoredBounds());
return widget()->GetRestoredBounds();
#endif
return WidgetToLogicalBounds(widget()->GetWindowBoundsInScreen());
return widget()->GetWindowBoundsInScreen();
}
gfx::Rect NativeWindowViews::GetContentBounds() const {
@@ -912,7 +905,7 @@ gfx::Rect NativeWindowViews::GetNormalBounds() const {
if (IsMaximized() && transparent())
return restore_bounds_;
#endif
return WidgetToLogicalBounds(widget()->GetRestoredBounds());
return widget()->GetRestoredBounds();
}
void NativeWindowViews::SetContentSizeConstraints(
@@ -1488,22 +1481,6 @@ gfx::NativeWindow NativeWindowViews::GetNativeWindow() const {
return widget()->GetNativeWindow();
}
gfx::Insets NativeWindowViews::GetRestoredFrameBorderInsets() const {
auto* non_client_view = widget()->non_client_view();
if (!non_client_view)
return gfx::Insets();
auto* frame_view = non_client_view->frame_view();
if (!frame_view)
return gfx::Insets();
if (auto* frameless = views::AsViewClass<FramelessView>(frame_view)) {
return frameless->RestoredFrameBorderInsets();
}
return gfx::Insets();
}
void NativeWindowViews::SetProgressBar(double progress,
NativeWindow::ProgressState state) {
#if BUILDFLAG(IS_WIN)
@@ -1669,42 +1646,21 @@ NativeWindowHandle NativeWindowViews::GetNativeWindowHandle() const {
return GetAcceleratedWidget();
}
gfx::Rect NativeWindowViews::LogicalToWidgetBounds(
const gfx::Rect& bounds) const {
gfx::Rect widget_bounds(bounds);
const gfx::Insets frame_insets = GetRestoredFrameBorderInsets();
widget_bounds.Outset(
gfx::Outsets::TLBR(frame_insets.top(), frame_insets.left(),
frame_insets.bottom(), frame_insets.right()));
return widget_bounds;
}
gfx::Rect NativeWindowViews::WidgetToLogicalBounds(
const gfx::Rect& bounds) const {
gfx::Rect logical_bounds(bounds);
logical_bounds.Inset(GetRestoredFrameBorderInsets());
return logical_bounds;
}
gfx::Rect NativeWindowViews::ContentBoundsToWindowBounds(
const gfx::Rect& bounds) const {
if (!has_frame())
return bounds;
gfx::Rect window_bounds(bounds);
if (auto* ncv = widget()->non_client_view()) {
#if BUILDFLAG(IS_WIN)
if (widget()->non_client_view()) {
HWND hwnd = GetAcceleratedWidget();
gfx::Rect dpi_bounds = DIPToScreenRect(hwnd, bounds);
window_bounds =
ScreenToDIPRect(hwnd, ncv->GetWindowBoundsForClientBounds(dpi_bounds));
#else
window_bounds = WidgetToLogicalBounds(
ncv->GetWindowBoundsForClientBounds(window_bounds));
#endif
window_bounds = ScreenToDIPRect(
hwnd, widget()->non_client_view()->GetWindowBoundsForClientBounds(
dpi_bounds));
}
#endif
if (root_view_.HasMenu() && root_view_.is_menu_bar_visible()) {
int menu_bar_height = root_view_.GetMenuBarHeight();
@@ -1731,10 +1687,6 @@ gfx::Rect NativeWindowViews::WindowBoundsToContentBounds(
content_bounds.set_width(content_bounds.width() - (rect.right - rect.left));
content_bounds.set_height(content_bounds.height() - (rect.bottom - rect.top));
content_bounds.set_size(ScreenToDIPRect(hwnd, content_bounds).size());
#else
if (auto* frame_view = widget()->non_client_view()->frame_view()) {
content_bounds = frame_view->GetBoundsForClientView();
}
#endif
if (root_view_.HasMenu() && root_view_.is_menu_bar_visible()) {

View File

@@ -16,7 +16,6 @@
#include "shell/browser/ui/views/root_view.h"
#include "third_party/abseil-cpp/absl/container/flat_hash_set.h"
#include "ui/base/ozone_buildflags.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/views/controls/webview/unhandled_keyboard_event_handler.h"
#include "ui/views/widget/widget_observer.h"
@@ -157,12 +156,6 @@ class NativeWindowViews : public NativeWindow,
gfx::Rect ContentBoundsToWindowBounds(const gfx::Rect& bounds) const override;
gfx::Rect WindowBoundsToContentBounds(const gfx::Rect& bounds) const override;
// Translates between logical/opaque window bounds exposed to callers
// and the absolute bounds of the underlying widget, which can be larger to
// fit CSD, e.g. transparent outer regions for shadows and resize targets.
gfx::Rect LogicalToWidgetBounds(const gfx::Rect& bounds) const;
gfx::Rect WidgetToLogicalBounds(const gfx::Rect& bounds) const;
void IncrementChildModals();
void DecrementChildModals();
@@ -212,8 +205,6 @@ class NativeWindowViews : public NativeWindow,
overlay_symbol_color_ = color;
}
gfx::Insets GetRestoredFrameBorderInsets() const;
// views::WidgetObserver:
void OnWidgetActivationChanged(views::Widget* widget, bool active) override;
void OnWidgetBoundsChanged(views::Widget* widget,

View File

@@ -53,11 +53,10 @@ void ElectronDesktopWindowTreeHostLinux::OnWidgetInitDone() {
UpdateFrameHints();
}
bool ElectronDesktopWindowTreeHostLinux::IsShowingFrame(
ui::PlatformWindowState window_state) const {
return window_state != ui::PlatformWindowState::kFullScreen &&
window_state != ui::PlatformWindowState::kMaximized &&
window_state != ui::PlatformWindowState::kMinimized;
bool ElectronDesktopWindowTreeHostLinux::IsShowingFrame() const {
return !native_window_view_->IsFullscreen() &&
!native_window_view_->IsMaximized() &&
!native_window_view_->IsMinimized();
}
void ElectronDesktopWindowTreeHostLinux::SetWindowIcons(
@@ -81,7 +80,7 @@ void ElectronDesktopWindowTreeHostLinux::Show(
gfx::Insets ElectronDesktopWindowTreeHostLinux::CalculateInsetsInDIP(
ui::PlatformWindowState window_state) const {
// If we are not showing frame, the insets should be zero.
if (!IsShowingFrame(window_state)) {
if (!IsShowingFrame()) {
return gfx::Insets();
}
@@ -89,7 +88,9 @@ gfx::Insets ElectronDesktopWindowTreeHostLinux::CalculateInsetsInDIP(
if (!view)
return {};
gfx::Insets insets = view->RestoredFrameBorderInsets();
gfx::Insets insets = view->RestoredMirroredFrameBorderInsets();
if (base::i18n::IsRTL())
insets.set_left_right(insets.right(), insets.left());
return insets;
}
@@ -206,7 +207,7 @@ void ElectronDesktopWindowTreeHostLinux::UpdateFrameHints() {
if (ui::OzonePlatform::GetInstance()->IsWindowCompositingSupported()) {
// Set the opaque region.
std::vector<gfx::Rect> opaque_region;
if (IsShowingFrame(window_state)) {
if (IsShowingFrame()) {
// The opaque region is a list of rectangles that contain only fully
// opaque pixels of the window. We need to convert the clipping
// rounded-rect into this format.

View File

@@ -74,7 +74,7 @@ class ElectronDesktopWindowTreeHostLinux
private:
void UpdateWindowState(ui::PlatformWindowState new_state);
bool IsShowingFrame(ui::PlatformWindowState window_state) const;
bool IsShowingFrame() const;
gfx::ImageSkia saved_window_icon_;

View File

@@ -62,9 +62,9 @@ class InspectableWebContentsView : public views::View {
// views::View:
void Layout(PassKey) override;
private:
views::View* GetContentsView() const;
private:
// Owns us.
raw_ptr<InspectableWebContents> inspectable_web_contents_;

View File

@@ -142,6 +142,13 @@ void ClientFrameViewLinux::Init(NativeWindowViews* window,
UpdateThemeValues();
}
gfx::Insets ClientFrameViewLinux::RestoredMirroredFrameBorderInsets() const {
auto border = RestoredFrameBorderInsets();
return base::i18n::IsRTL() ? gfx::Insets::TLBR(border.top(), border.right(),
border.bottom(), border.left())
: border;
}
gfx::Insets ClientFrameViewLinux::RestoredFrameBorderInsets() const {
gfx::Insets insets = GetFrameProvider()->GetFrameThicknessDip();
const gfx::Insets input = GetInputInsets();
@@ -156,9 +163,7 @@ gfx::Insets ClientFrameViewLinux::RestoredFrameBorderInsets() const {
merged.set_bottom(expand_if_visible(insets.bottom(), input.bottom()));
merged.set_right(expand_if_visible(insets.right(), input.right()));
return base::i18n::IsRTL() ? gfx::Insets::TLBR(merged.top(), merged.right(),
merged.bottom(), merged.left())
: merged;
return merged;
}
gfx::Insets ClientFrameViewLinux::GetInputInsets() const {
@@ -169,7 +174,7 @@ gfx::Insets ClientFrameViewLinux::GetInputInsets() const {
gfx::Rect ClientFrameViewLinux::GetWindowContentBounds() const {
gfx::Rect content_bounds = bounds();
content_bounds.Inset(RestoredFrameBorderInsets());
content_bounds.Inset(RestoredMirroredFrameBorderInsets());
return content_bounds;
}
@@ -203,13 +208,13 @@ void ClientFrameViewLinux::OnWindowButtonOrderingChange() {
}
int ClientFrameViewLinux::ResizingBorderHitTest(const gfx::Point& point) {
return ResizingBorderHitTestImpl(point, RestoredFrameBorderInsets());
return ResizingBorderHitTestImpl(point, RestoredMirroredFrameBorderInsets());
}
gfx::Rect ClientFrameViewLinux::GetBoundsForClientView() const {
gfx::Rect client_bounds = bounds();
if (!frame_->IsFullscreen()) {
client_bounds.Inset(RestoredFrameBorderInsets());
client_bounds.Inset(RestoredMirroredFrameBorderInsets());
client_bounds.Inset(
gfx::Insets::TLBR(GetTitlebarBounds().height(), 0, 0, 0));
}
@@ -263,6 +268,20 @@ void ClientFrameViewLinux::SizeConstraintsChanged() {
InvalidateLayout();
}
gfx::Size ClientFrameViewLinux::CalculatePreferredSize(
const views::SizeBounds& available_size) const {
return SizeWithDecorations(
FramelessView::CalculatePreferredSize(available_size));
}
gfx::Size ClientFrameViewLinux::GetMinimumSize() const {
return SizeWithDecorations(FramelessView::GetMinimumSize());
}
gfx::Size ClientFrameViewLinux::GetMaximumSize() const {
return SizeWithDecorations(FramelessView::GetMaximumSize());
}
void ClientFrameViewLinux::Layout(PassKey) {
LayoutSuperclass<FramelessView>(this);
@@ -455,7 +474,7 @@ gfx::Rect ClientFrameViewLinux::GetTitlebarBounds() const {
std::max(font_height, theme_values_.titlebar_min_height) +
GetTitlebarContentInsets().height();
gfx::Insets decoration_insets = RestoredFrameBorderInsets();
gfx::Insets decoration_insets = RestoredMirroredFrameBorderInsets();
// We add the inset height here, so the .Inset() that follows won't reduce it
// to be too small.
@@ -474,6 +493,15 @@ gfx::Rect ClientFrameViewLinux::GetTitlebarContentBounds() const {
titlebar.Inset(GetTitlebarContentInsets());
return titlebar;
}
gfx::Size ClientFrameViewLinux::SizeWithDecorations(gfx::Size size) const {
gfx::Insets decoration_insets = RestoredMirroredFrameBorderInsets();
size.Enlarge(0, GetTitlebarBounds().height());
size.Enlarge(decoration_insets.width(), decoration_insets.height());
return size;
}
views::View* ClientFrameViewLinux::TargetForRect(views::View* root,
const gfx::Rect& rect) {
return views::FrameView::TargetForRect(root, rect);

View File

@@ -42,9 +42,9 @@ class ClientFrameViewLinux : public FramelessView,
void Init(NativeWindowViews* window, views::Widget* frame) override;
// FramelessView:
gfx::Insets RestoredFrameBorderInsets() const override;
// These are here for ElectronDesktopWindowTreeHostLinux to use.
gfx::Insets RestoredMirroredFrameBorderInsets() const;
gfx::Insets RestoredFrameBorderInsets() const;
gfx::Insets GetInputInsets() const;
gfx::Rect GetWindowContentBounds() const;
SkRRect GetRoundedWindowContentBounds() const;
@@ -74,6 +74,10 @@ class ClientFrameViewLinux : public FramelessView,
void SizeConstraintsChanged() override;
// Overridden from View:
gfx::Size CalculatePreferredSize(
const views::SizeBounds& available_size) const override;
gfx::Size GetMinimumSize() const override;
gfx::Size GetMaximumSize() const override;
void Layout(PassKey) override;
void OnPaint(gfx::Canvas* canvas) override;
@@ -123,6 +127,8 @@ class ClientFrameViewLinux : public FramelessView,
gfx::Insets GetTitlebarContentInsets() const;
gfx::Rect GetTitlebarContentBounds() const;
gfx::Size SizeWithDecorations(gfx::Size size) const;
raw_ptr<ui::NativeTheme> theme_;
ThemeValues theme_values_;

View File

@@ -30,10 +30,6 @@ void FramelessView::Init(NativeWindowViews* window, views::Widget* frame) {
frame_ = frame;
}
gfx::Insets FramelessView::RestoredFrameBorderInsets() const {
return gfx::Insets();
}
int FramelessView::ResizingBorderHitTest(const gfx::Point& point) {
return ResizingBorderHitTestImpl(point, gfx::Insets(kResizeInsideBoundsSize));
}
@@ -112,16 +108,16 @@ gfx::Size FramelessView::CalculatePreferredSize(
}
gfx::Size FramelessView::GetMinimumSize() const {
if (!window_)
return gfx::Size();
return window_->GetMinimumSize();
return window_->GetContentMinimumSize();
}
gfx::Size FramelessView::GetMaximumSize() const {
if (!window_)
return gfx::Size();
return window_->GetMaximumSize();
gfx::Size size = window_->GetContentMaximumSize();
// Electron public APIs returns (0, 0) when maximum size is not set, but it
// would break internal window APIs like HWNDMessageHandler::SetAspectRatio.
return size.IsEmpty() ? gfx::Size(INT_MAX, INT_MAX) : size;
}
BEGIN_METADATA(FramelessView)
END_METADATA

View File

@@ -7,7 +7,6 @@
#include "base/memory/raw_ptr.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/views/window/non_client_view.h"
namespace views {
@@ -38,10 +37,6 @@ class FramelessView : public views::FrameView {
// and forces a re-layout and re-paint.
virtual void InvalidateCaptionButtons() {}
// Any insets from the (transparent) widget bounds to the logical/opaque
// bounds of the view, used for CSD and resize targets on some platforms.
virtual gfx::Insets RestoredFrameBorderInsets() const;
NativeWindowViews* window() const { return window_; }
views::Widget* frame() const { return frame_; }

View File

@@ -39,7 +39,6 @@ class OpaqueFrameView : public FramelessView {
void Init(NativeWindowViews* window, views::Widget* frame) override;
int ResizingBorderHitTest(const gfx::Point& point) override;
void InvalidateCaptionButtons() override;
gfx::Insets RestoredFrameBorderInsets() const override;
// views::FrameView:
gfx::Rect GetBoundsForClientView() const override;
@@ -100,6 +99,11 @@ class OpaqueFrameView : public FramelessView {
// rather than having extra vertical space above the tabs.
bool IsFrameCondensed() const;
// The insets from the native window edge to the client view when the window
// is restored. This goes all the way to the web contents on the left, right,
// and bottom edges.
gfx::Insets RestoredFrameBorderInsets() const;
// The insets from the native window edge to the flat portion of the
// window border. That is, this function returns the "3D portion" of the
// border when the window is restored. The returned insets will not be larger

View File

@@ -274,21 +274,6 @@ bool WinFrameView::GetShouldPaintAsActive() {
return ShouldPaintAsActive();
}
gfx::Size WinFrameView::GetMinimumSize() const {
// Chromium expects minimum size to be in content dimensions on Windows
// because it adds the frame border automatically in OnGetMinMaxInfo.
return window_->GetContentMinimumSize();
}
gfx::Size WinFrameView::GetMaximumSize() const {
// Chromium expects minimum size to be in content dimensions on Windows
// because it adds the frame border automatically in OnGetMinMaxInfo.
gfx::Size size = window_->GetContentMaximumSize();
// Electron public APIs returns (0, 0) when maximum size is not set, but it
// would break internal window APIs like HWNDMessageHandler::SetAspectRatio.
return size.IsEmpty() ? gfx::Size(INT_MAX, INT_MAX) : size;
}
BEGIN_METADATA(WinFrameView)
END_METADATA

View File

@@ -35,8 +35,6 @@ class WinFrameView : public FramelessView {
gfx::Rect GetWindowBoundsForClientBounds(
const gfx::Rect& client_bounds) const override;
int NonClientHitTest(const gfx::Point& point) override;
gfx::Size GetMinimumSize() const override;
gfx::Size GetMaximumSize() const override;
WinCaptionButtonContainer* caption_button_container() {
return caption_button_container_;

View File

@@ -8,7 +8,6 @@
#include <utility>
#include <vector>
#include "base/base_switches.h"
#include "base/memory/raw_ptr.h"
#include "gin/converter.h"
#include "shell/common/api/electron_api_native_image.h"
@@ -18,15 +17,6 @@
#include "ui/gfx/image/image_skia.h"
#include "v8/include/v8.h"
#if BUILDFLAG(IS_LINUX) && (defined(ARCH_CPU_X86_64) || defined(ARCH_CPU_ARM64))
#define ENABLE_WEB_ASSEMBLY_TRAP_HANDLER_LINUX
#include "base/command_line.h"
#include "base/debug/stack_trace.h"
#include "components/crash/core/app/crashpad.h" // nogncheck
#include "content/public/common/content_switches.h"
#include "v8/include/v8-wasm-trap-handler-posix.h"
#endif
namespace electron {
namespace {
@@ -250,51 +240,6 @@ v8::Local<v8::Value> DeserializeV8Value(v8::Isolate* isolate,
return V8Deserializer(isolate, data).Deserialize();
}
void SetUpWebAssemblyTrapHandler() {
#if BUILDFLAG(IS_WIN)
// On Windows we use the default trap handler provided by V8.
v8::V8::EnableWebAssemblyTrapHandler(true);
#elif BUILDFLAG(IS_MAC)
// On macOS, Crashpad uses exception ports to handle signals in a
// different process. As we cannot just pass a callback to this other
// process, we ask V8 to install its own signal handler to deal with
// WebAssembly traps.
v8::V8::EnableWebAssemblyTrapHandler(true);
#elif defined(ENABLE_WEB_ASSEMBLY_TRAP_HANDLER_LINUX)
const bool crash_reporter_enabled =
crash_reporter::GetHandlerSocket(nullptr, nullptr);
if (crash_reporter_enabled) {
// If either --enable-crash-reporter or --enable-crash-reporter-for-testing
// is enabled it should take care of signal handling for us, use the default
// implementation which doesn't register an additional handler.
v8::V8::EnableWebAssemblyTrapHandler(false);
return;
}
const bool use_v8_default_handler =
base::CommandLine::ForCurrentProcess()->HasSwitch(
::switches::kDisableInProcessStackTraces);
if (use_v8_default_handler) {
// There is no signal handler yet, but it's okay if v8 registers one.
v8::V8::EnableWebAssemblyTrapHandler(/*use_v8_signal_handler=*/true);
return;
}
if (base::debug::SetStackDumpFirstChanceCallback(
v8::TryHandleWebAssemblyTrapPosix)) {
// Crashpad and Breakpad are disabled, but the in-process stack dump
// handlers are enabled, so set the callback on the stack dump handlers.
v8::V8::EnableWebAssemblyTrapHandler(/*use_v8_signal_handler=*/false);
return;
}
// As the registration of the callback failed, we don't enable trap
// handlers.
#endif
}
namespace util {
/**

View File

@@ -30,8 +30,6 @@ v8::Local<v8::Value> DeserializeV8Value(v8::Isolate* isolate,
v8::Local<v8::Value> DeserializeV8Value(v8::Isolate* isolate,
base::span<const uint8_t> data);
void SetUpWebAssemblyTrapHandler();
namespace util {
[[nodiscard]] base::span<uint8_t> as_byte_span(

View File

@@ -6,9 +6,10 @@
#include <algorithm>
#include "base/base_switches.h"
#include "base/command_line.h"
#include "base/debug/stack_trace.h"
#include "content/public/renderer/render_frame.h"
#include "electron/fuses.h"
#include "net/http/http_request_headers.h"
#include "shell/common/api/electron_bindings.h"
#include "shell/common/gin_helper/dictionary.h"
@@ -17,7 +18,6 @@
#include "shell/common/node_includes.h"
#include "shell/common/node_util.h"
#include "shell/common/options_switches.h"
#include "shell/common/v8_util.h"
#include "shell/renderer/electron_render_frame_observer.h"
#include "shell/renderer/web_worker_observer.h"
#include "third_party/blink/public/common/web_preferences/web_preferences.h"
@@ -26,6 +26,13 @@
#include "third_party/blink/renderer/core/execution_context/execution_context.h" // nogncheck
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h" // nogncheck
#if BUILDFLAG(IS_LINUX) && (defined(ARCH_CPU_X86_64) || defined(ARCH_CPU_ARM64))
#define ENABLE_WEB_ASSEMBLY_TRAP_HANDLER_LINUX
#include "components/crash/core/app/crashpad.h" // nogncheck
#include "content/public/common/content_switches.h"
#include "v8/include/v8-wasm-trap-handler-posix.h"
#endif
namespace electron {
ElectronRendererClient::ElectronRendererClient()
@@ -240,13 +247,45 @@ void ElectronRendererClient::WillDestroyWorkerContextOnWorkerThread(
}
void ElectronRendererClient::SetUpWebAssemblyTrapHandler() {
#if ((BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)) && \
defined(ARCH_CPU_X86_64)) || \
((BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC)) && defined(ARCH_CPU_ARM64))
if (electron::fuses::IsWasmTrapHandlersEnabled()) {
electron::SetUpWebAssemblyTrapHandler();
// See CL:5372409 - copied from ShellContentRendererClient.
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
// Mac and Windows use the default implementation (where the default v8 trap
// handler gets set up).
ContentRendererClient::SetUpWebAssemblyTrapHandler();
return;
#elif defined(ENABLE_WEB_ASSEMBLY_TRAP_HANDLER_LINUX)
const bool crash_reporter_enabled =
crash_reporter::GetHandlerSocket(nullptr, nullptr);
if (crash_reporter_enabled) {
// If either --enable-crash-reporter or --enable-crash-reporter-for-testing
// is enabled it should take care of signal handling for us, use the default
// implementation which doesn't register an additional handler.
ContentRendererClient::SetUpWebAssemblyTrapHandler();
return;
}
#endif
const bool use_v8_default_handler =
base::CommandLine::ForCurrentProcess()->HasSwitch(
::switches::kDisableInProcessStackTraces);
if (use_v8_default_handler) {
// There is no signal handler yet, but it's okay if v8 registers one.
v8::V8::EnableWebAssemblyTrapHandler(/*use_v8_signal_handler=*/true);
return;
}
if (base::debug::SetStackDumpFirstChanceCallback(
v8::TryHandleWebAssemblyTrapPosix)) {
// Crashpad and Breakpad are disabled, but the in-process stack dump
// handlers are enabled, so set the callback on the stack dump handlers.
v8::V8::EnableWebAssemblyTrapHandler(/*use_v8_signal_handler=*/false);
return;
}
// As the registration of the callback failed, we don't enable trap
// handlers.
#endif // defined(ENABLE_WEB_ASSEMBLY_TRAP_HANDLER_LINUX)
}
node::Environment* ElectronRendererClient::GetEnvironment(

View File

@@ -11,7 +11,6 @@
#include "base/no_destructor.h"
#include "base/process/process.h"
#include "base/strings/utf_string_conversions.h"
#include "electron/fuses.h"
#include "electron/mas.h"
#include "net/base/network_change_notifier.h"
#include "services/network/public/cpp/wrapper_shared_url_loader_factory.h"
@@ -23,7 +22,6 @@
#include "shell/common/gin_helper/dictionary.h"
#include "shell/common/node_bindings.h"
#include "shell/common/node_includes.h"
#include "shell/common/v8_util.h"
#include "shell/services/node/parent_port.h"
#if !IS_MAS_BUILD()
@@ -132,15 +130,6 @@ void NodeService::Initialize(
v8::Isolate* const isolate = js_env_->isolate();
v8::HandleScope scope{isolate};
// Enable trap handlers before user script execution.
#if ((BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)) && \
defined(ARCH_CPU_X86_64)) || \
((BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC)) && defined(ARCH_CPU_ARM64))
if (electron::fuses::IsWasmTrapHandlersEnabled()) {
electron::SetUpWebAssemblyTrapHandler();
}
#endif
node_bindings_->Initialize(isolate, isolate->GetCurrentContext());
network_change_notifier_ = net::NetworkChangeNotifier::CreateIfNeeded(

View File

@@ -1,221 +0,0 @@
import * as cp from 'node:child_process';
import * as path from 'node:path';
import { ifdescribe } from './lib/spec-helpers';
ifdescribe(process.platform === 'darwin' && process.mas)('Mac App Store build', () => {
describe('private API usage', () => {
// Get paths to all Electron binaries
const getElectronBinaries = () => {
const contentsPath = path.dirname(path.dirname(process.execPath));
return {
mainProcess: process.execPath,
framework: path.join(contentsPath, 'Frameworks', 'Electron Framework.framework', 'Electron Framework'),
helpers: {
main: path.join(contentsPath, 'Frameworks', 'Electron Helper.app', 'Contents', 'MacOS', 'Electron Helper'),
gpu: path.join(contentsPath, 'Frameworks', 'Electron Helper (GPU).app', 'Contents', 'MacOS', 'Electron Helper (GPU)'),
plugin: path.join(contentsPath, 'Frameworks', 'Electron Helper (Plugin).app', 'Contents', 'MacOS', 'Electron Helper (Plugin)'),
renderer: path.join(contentsPath, 'Frameworks', 'Electron Helper (Renderer).app', 'Contents', 'MacOS', 'Electron Helper (Renderer)')
}
};
};
const checkBinaryForPrivateAPIs = (binaryPath: string, binaryName: string) => {
// Use nm without -U to get all symbols (both defined and undefined)
const nmResult = cp.spawnSync('nm', ['-g', binaryPath], {
encoding: 'utf-8',
maxBuffer: 50 * 1024 * 1024
});
if (nmResult.error) {
throw new Error(`Failed to run nm on ${binaryName}: ${nmResult.error.message}`);
}
const symbols = nmResult.stdout;
// List of known private APIs that should not be present in MAS builds
// These are from the mas_avoid_private_macos_api_usage.patch
const privateAPIs = [
'abort_report_np',
'pthread_fchdir_np',
'pthread_chdir_np',
'SetApplicationIsDaemon',
'_LSSetApplicationLaunchServicesServerConnectionStatus',
'CGSSetWindowCaptureExcludeShape',
'CGRegionCreateWithRect',
'CTFontCopyVariationAxesInternal',
'AudioDeviceDuck',
'CGSMainConnectionID',
'IOBluetoothPreferenceSetControllerPowerState',
'CGSSetDenyWindowServerConnections',
'CGFontRenderingGetFontSmoothingDisabled',
'CTFontDescriptorIsSystemUIFont',
'sandbox_init_with_parameters',
'sandbox_create_params',
'sandbox_set_param',
'sandbox_free_params',
'sandbox_compile_string',
'sandbox_apply',
'sandbox_free_profile',
'sandbox_extension_issue_file',
'sandbox_extension_consume',
'sandbox_extension_release',
'_CSCheckFixDisable',
'responsibility_get_pid_responsible_for_pid',
'_NSAppendToKillRing',
'_NSPrependToKillRing',
'_NSYankFromKillRing',
'__NSNewKillRingSequence',
'__NSInitializeKillRing',
'_NSSetKillRingToYankedState'
];
const foundPrivateAPIs: string[] = [];
for (const api of privateAPIs) {
// Check if the symbol appears in the nm output
// Look for ' U ' (undefined) or ' T ' (defined in text section) followed by the API
// nm output format is like: " U _symbol_name"
const regex = new RegExp(`\\s+[UT]\\s+(_${api})\\b`);
const match = symbols.match(regex);
if (match) {
// Keep the full symbol name including the underscore
foundPrivateAPIs.push(match[1]);
}
}
return foundPrivateAPIs;
};
it('should not use private macOS APIs in main process', function () {
this.timeout(60000);
const binaries = getElectronBinaries();
const foundPrivateAPIs = checkBinaryForPrivateAPIs(binaries.mainProcess, 'Electron main process');
if (foundPrivateAPIs.length > 0) {
throw new Error(
`Found private macOS APIs in main process:\n${foundPrivateAPIs.join('\n')}\n\n` +
'These APIs are not allowed in Mac App Store builds and will cause rejection.'
);
}
// Also check for private framework linkage
const otoolResult = cp.spawnSync('otool', ['-L', binaries.mainProcess], {
encoding: 'utf-8'
});
if (otoolResult.error) {
throw new Error(`Failed to run otool: ${otoolResult.error.message}`);
}
const frameworks = otoolResult.stdout;
if (frameworks.includes('PrivateFrameworks')) {
throw new Error(
'Found linkage to PrivateFrameworks which is not allowed in Mac App Store builds:\n' +
frameworks
);
}
});
it('should not use private macOS APIs in Electron Framework', function () {
this.timeout(60000);
// Check the Electron Framework binary (mentioned in issue #49616)
const binaries = getElectronBinaries();
const foundAPIs = checkBinaryForPrivateAPIs(binaries.framework, 'Electron Framework');
if (foundAPIs.length > 0) {
throw new Error(
`Found private macOS APIs in Electron Framework:\n${foundAPIs.join('\n')}\n\n` +
'These APIs are not allowed in Mac App Store builds and will cause rejection.\n' +
'See patches/chromium/mas_avoid_private_macos_api_usage.patch.patch'
);
}
});
it('should not use private macOS APIs in helper processes', function () {
this.timeout(60000);
const binaries = getElectronBinaries();
const allFoundAPIs: Record<string, string[]> = {};
for (const [helperName, helperPath] of Object.entries(binaries.helpers)) {
const displayName = `Electron Helper${helperName !== 'main' ? ` (${helperName.charAt(0).toUpperCase() + helperName.slice(1)})` : ''}`;
const foundAPIs = checkBinaryForPrivateAPIs(helperPath, displayName);
if (foundAPIs.length > 0) {
allFoundAPIs[displayName] = foundAPIs;
}
}
if (Object.keys(allFoundAPIs).length > 0) {
const errorLines = Object.entries(allFoundAPIs).map(([helper, apis]) =>
`${helper}:\n ${apis.join('\n ')}`
);
throw new Error(
`Found private macOS APIs in helper processes:\n\n${errorLines.join('\n\n')}\n\n` +
'These APIs are not allowed in Mac App Store builds and will cause rejection.'
);
}
});
it('should not reference private Objective-C classes', function () {
this.timeout(60000);
// Check for private Objective-C classes (appear as _OBJC_CLASS_$_ClassName)
const privateClasses = [
'NSAccessibilityRemoteUIElement',
'CAContext'
];
const binaries = getElectronBinaries();
const binariesToCheck = [
{ path: binaries.mainProcess, name: 'Electron main process' },
{ path: binaries.framework, name: 'Electron Framework' },
{ path: binaries.helpers.main, name: 'Electron Helper' },
{ path: binaries.helpers.renderer, name: 'Electron Helper (Renderer)' }
];
const foundClasses: Record<string, string[]> = {};
for (const binary of binariesToCheck) {
const nmResult = cp.spawnSync('nm', ['-g', binary.path], {
encoding: 'utf-8',
maxBuffer: 50 * 1024 * 1024
});
if (nmResult.error) {
throw new Error(`Failed to run nm on ${binary.name}: ${nmResult.error.message}`);
}
const symbols = nmResult.stdout;
const foundInBinary: string[] = [];
for (const className of privateClasses) {
// Look for _OBJC_CLASS_$_ClassName pattern
if (symbols.includes(`_OBJC_CLASS_$_${className}`)) {
foundInBinary.push(className);
}
}
if (foundInBinary.length > 0) {
foundClasses[binary.name] = foundInBinary;
}
}
if (Object.keys(foundClasses).length > 0) {
const errorLines = Object.entries(foundClasses).map(([binary, classes]) =>
`${binary}:\n ${classes.join('\n ')}`
);
throw new Error(
`Found references to private Objective-C classes:\n\n${errorLines.join('\n\n')}\n\n` +
'These are not allowed in Mac App Store builds and will cause rejection.'
);
}
});
});
});

463
yarn.lock
View File

@@ -638,7 +638,7 @@ __metadata:
ts-node: "npm:6.2.0"
typescript: "npm:^5.8.3"
url: "npm:^0.11.4"
webpack: "npm:^5.104.1"
webpack: "npm:^5.95.0"
webpack-cli: "npm:^6.0.1"
wrapper-webpack-plugin: "npm:^2.2.0"
yaml: "npm:^2.8.1"
@@ -1206,7 +1206,7 @@ __metadata:
languageName: node
linkType: hard
"@jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25":
"@jridgewell/trace-mapping@npm:^0.3.20, @jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25":
version: 0.3.25
resolution: "@jridgewell/trace-mapping@npm:0.3.25"
dependencies:
@@ -1978,26 +1978,6 @@ __metadata:
languageName: node
linkType: hard
"@types/eslint-scope@npm:^3.7.7":
version: 3.7.7
resolution: "@types/eslint-scope@npm:3.7.7"
dependencies:
"@types/eslint": "npm:*"
"@types/estree": "npm:*"
checksum: 10c0/a0ecbdf2f03912679440550817ff77ef39a30fa8bfdacaf6372b88b1f931828aec392f52283240f0d648cf3055c5ddc564544a626bcf245f3d09fcb099ebe3cc
languageName: node
linkType: hard
"@types/eslint@npm:*":
version: 9.6.1
resolution: "@types/eslint@npm:9.6.1"
dependencies:
"@types/estree": "npm:*"
"@types/json-schema": "npm:*"
checksum: 10c0/69ba24fee600d1e4c5abe0df086c1a4d798abf13792d8cfab912d76817fe1a894359a1518557d21237fbaf6eda93c5ab9309143dee4c59ef54336d1b3570420e
languageName: node
linkType: hard
"@types/estree-jsx@npm:^1.0.0":
version: 1.0.5
resolution: "@types/estree-jsx@npm:1.0.5"
@@ -2007,13 +1987,20 @@ __metadata:
languageName: node
linkType: hard
"@types/estree@npm:*, @types/estree@npm:^1.0.8":
"@types/estree@npm:*":
version: 1.0.8
resolution: "@types/estree@npm:1.0.8"
checksum: 10c0/39d34d1afaa338ab9763f37ad6066e3f349444f9052b9676a7cc0252ef9485a41c6d81c9c4e0d26e9077993354edf25efc853f3224dd4b447175ef62bdcc86a5
languageName: node
linkType: hard
"@types/estree@npm:^1.0.5":
version: 1.0.5
resolution: "@types/estree@npm:1.0.5"
checksum: 10c0/b3b0e334288ddb407c7b3357ca67dbee75ee22db242ca7c56fe27db4e1a31989cb8af48a84dd401deb787fe10cc6b2ab1ee82dc4783be87ededbe3d53c79c70d
languageName: node
linkType: hard
"@types/express-serve-static-core@npm:^4.17.33":
version: 4.19.7
resolution: "@types/express-serve-static-core@npm:4.19.7"
@@ -2092,13 +2079,6 @@ __metadata:
languageName: node
linkType: hard
"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.15, @types/json-schema@npm:^7.0.9":
version: 7.0.15
resolution: "@types/json-schema@npm:7.0.15"
checksum: 10c0/a996a745e6c5d60292f36731dd41341339d4eeed8180bb09226e5c8d23759067692b1d88e5d91d72ee83dfc00d3aca8e7bd43ea120516c17922cbcb7c3e252db
languageName: node
linkType: hard
"@types/json-schema@npm:^7.0.8":
version: 7.0.11
resolution: "@types/json-schema@npm:7.0.11"
@@ -2613,154 +2593,154 @@ __metadata:
languageName: node
linkType: hard
"@webassemblyjs/ast@npm:1.14.1, @webassemblyjs/ast@npm:^1.14.1":
version: 1.14.1
resolution: "@webassemblyjs/ast@npm:1.14.1"
"@webassemblyjs/ast@npm:1.12.1, @webassemblyjs/ast@npm:^1.12.1":
version: 1.12.1
resolution: "@webassemblyjs/ast@npm:1.12.1"
dependencies:
"@webassemblyjs/helper-numbers": "npm:1.13.2"
"@webassemblyjs/helper-wasm-bytecode": "npm:1.13.2"
checksum: 10c0/67a59be8ed50ddd33fbb2e09daa5193ac215bf7f40a9371be9a0d9797a114d0d1196316d2f3943efdb923a3d809175e1563a3cb80c814fb8edccd1e77494972b
"@webassemblyjs/helper-numbers": "npm:1.11.6"
"@webassemblyjs/helper-wasm-bytecode": "npm:1.11.6"
checksum: 10c0/ba7f2b96c6e67e249df6156d02c69eb5f1bd18d5005303cdc42accb053bebbbde673826e54db0437c9748e97abd218366a1d13fa46859b23cde611b6b409998c
languageName: node
linkType: hard
"@webassemblyjs/floating-point-hex-parser@npm:1.13.2":
version: 1.13.2
resolution: "@webassemblyjs/floating-point-hex-parser@npm:1.13.2"
checksum: 10c0/0e88bdb8b50507d9938be64df0867f00396b55eba9df7d3546eb5dc0ca64d62e06f8d881ec4a6153f2127d0f4c11d102b6e7d17aec2f26bb5ff95a5e60652412
"@webassemblyjs/floating-point-hex-parser@npm:1.11.6":
version: 1.11.6
resolution: "@webassemblyjs/floating-point-hex-parser@npm:1.11.6"
checksum: 10c0/37fe26f89e18e4ca0e7d89cfe3b9f17cfa327d7daf906ae01400416dbb2e33c8a125b4dc55ad7ff405e5fcfb6cf0d764074c9bc532b9a31a71e762be57d2ea0a
languageName: node
linkType: hard
"@webassemblyjs/helper-api-error@npm:1.13.2":
version: 1.13.2
resolution: "@webassemblyjs/helper-api-error@npm:1.13.2"
checksum: 10c0/31be497f996ed30aae4c08cac3cce50c8dcd5b29660383c0155fce1753804fc55d47fcba74e10141c7dd2899033164e117b3bcfcda23a6b043e4ded4f1003dfb
"@webassemblyjs/helper-api-error@npm:1.11.6":
version: 1.11.6
resolution: "@webassemblyjs/helper-api-error@npm:1.11.6"
checksum: 10c0/a681ed51863e4ff18cf38d223429f414894e5f7496856854d9a886eeddcee32d7c9f66290f2919c9bb6d2fc2b2fae3f989b6a1e02a81e829359738ea0c4d371a
languageName: node
linkType: hard
"@webassemblyjs/helper-buffer@npm:1.14.1":
version: 1.14.1
resolution: "@webassemblyjs/helper-buffer@npm:1.14.1"
checksum: 10c0/0d54105dc373c0fe6287f1091e41e3a02e36cdc05e8cf8533cdc16c59ff05a646355415893449d3768cda588af451c274f13263300a251dc11a575bc4c9bd210
"@webassemblyjs/helper-buffer@npm:1.12.1":
version: 1.12.1
resolution: "@webassemblyjs/helper-buffer@npm:1.12.1"
checksum: 10c0/0270724afb4601237410f7fd845ab58ccda1d5456a8783aadfb16eaaf3f2c9610c28e4a5bcb6ad880cde5183c82f7f116d5ccfc2310502439d33f14b6888b48a
languageName: node
linkType: hard
"@webassemblyjs/helper-numbers@npm:1.13.2":
version: 1.13.2
resolution: "@webassemblyjs/helper-numbers@npm:1.13.2"
"@webassemblyjs/helper-numbers@npm:1.11.6":
version: 1.11.6
resolution: "@webassemblyjs/helper-numbers@npm:1.11.6"
dependencies:
"@webassemblyjs/floating-point-hex-parser": "npm:1.13.2"
"@webassemblyjs/helper-api-error": "npm:1.13.2"
"@webassemblyjs/floating-point-hex-parser": "npm:1.11.6"
"@webassemblyjs/helper-api-error": "npm:1.11.6"
"@xtuc/long": "npm:4.2.2"
checksum: 10c0/9c46852f31b234a8fb5a5a9d3f027bc542392a0d4de32f1a9c0075d5e8684aa073cb5929b56df565500b3f9cc0a2ab983b650314295b9bf208d1a1651bfc825a
checksum: 10c0/c7d5afc0ff3bd748339b466d8d2f27b908208bf3ff26b2e8e72c39814479d486e0dca6f3d4d776fd9027c1efe05b5c0716c57a23041eb34473892b2731c33af3
languageName: node
linkType: hard
"@webassemblyjs/helper-wasm-bytecode@npm:1.13.2":
version: 1.13.2
resolution: "@webassemblyjs/helper-wasm-bytecode@npm:1.13.2"
checksum: 10c0/c4355d14f369b30cf3cbdd3acfafc7d0488e086be6d578e3c9780bd1b512932352246be96e034e2a7fcfba4f540ec813352f312bfcbbfe5bcfbf694f82ccc682
"@webassemblyjs/helper-wasm-bytecode@npm:1.11.6":
version: 1.11.6
resolution: "@webassemblyjs/helper-wasm-bytecode@npm:1.11.6"
checksum: 10c0/79d2bebdd11383d142745efa32781249745213af8e022651847382685ca76709f83e1d97adc5f0d3c2b8546bf02864f8b43a531fdf5ca0748cb9e4e0ef2acaa5
languageName: node
linkType: hard
"@webassemblyjs/helper-wasm-section@npm:1.14.1":
version: 1.14.1
resolution: "@webassemblyjs/helper-wasm-section@npm:1.14.1"
"@webassemblyjs/helper-wasm-section@npm:1.12.1":
version: 1.12.1
resolution: "@webassemblyjs/helper-wasm-section@npm:1.12.1"
dependencies:
"@webassemblyjs/ast": "npm:1.14.1"
"@webassemblyjs/helper-buffer": "npm:1.14.1"
"@webassemblyjs/helper-wasm-bytecode": "npm:1.13.2"
"@webassemblyjs/wasm-gen": "npm:1.14.1"
checksum: 10c0/1f9b33731c3c6dbac3a9c483269562fa00d1b6a4e7133217f40e83e975e636fd0f8736e53abd9a47b06b66082ecc976c7384391ab0a68e12d509ea4e4b948d64
"@webassemblyjs/ast": "npm:1.12.1"
"@webassemblyjs/helper-buffer": "npm:1.12.1"
"@webassemblyjs/helper-wasm-bytecode": "npm:1.11.6"
"@webassemblyjs/wasm-gen": "npm:1.12.1"
checksum: 10c0/0546350724d285ae3c26e6fc444be4c3b5fb824f3be0ec8ceb474179dc3f4430336dd2e36a44b3e3a1a6815960e5eec98cd9b3a8ec66dc53d86daedd3296a6a2
languageName: node
linkType: hard
"@webassemblyjs/ieee754@npm:1.13.2":
version: 1.13.2
resolution: "@webassemblyjs/ieee754@npm:1.13.2"
"@webassemblyjs/ieee754@npm:1.11.6":
version: 1.11.6
resolution: "@webassemblyjs/ieee754@npm:1.11.6"
dependencies:
"@xtuc/ieee754": "npm:^1.2.0"
checksum: 10c0/2e732ca78c6fbae3c9b112f4915d85caecdab285c0b337954b180460290ccd0fb00d2b1dc4bb69df3504abead5191e0d28d0d17dfd6c9d2f30acac8c4961c8a7
checksum: 10c0/59de0365da450322c958deadade5ec2d300c70f75e17ae55de3c9ce564deff5b429e757d107c7ec69bd0ba169c6b6cc2ff66293ab7264a7053c829b50ffa732f
languageName: node
linkType: hard
"@webassemblyjs/leb128@npm:1.13.2":
version: 1.13.2
resolution: "@webassemblyjs/leb128@npm:1.13.2"
"@webassemblyjs/leb128@npm:1.11.6":
version: 1.11.6
resolution: "@webassemblyjs/leb128@npm:1.11.6"
dependencies:
"@xtuc/long": "npm:4.2.2"
checksum: 10c0/dad5ef9e383c8ab523ce432dfd80098384bf01c45f70eb179d594f85ce5db2f80fa8c9cba03adafd85684e6d6310f0d3969a882538975989919329ac4c984659
checksum: 10c0/cb344fc04f1968209804de4da018679c5d4708a03b472a33e0fa75657bb024978f570d3ccf9263b7f341f77ecaa75d0e051b9cd4b7bb17a339032cfd1c37f96e
languageName: node
linkType: hard
"@webassemblyjs/utf8@npm:1.13.2":
version: 1.13.2
resolution: "@webassemblyjs/utf8@npm:1.13.2"
checksum: 10c0/d3fac9130b0e3e5a1a7f2886124a278e9323827c87a2b971e6d0da22a2ba1278ac9f66a4f2e363ecd9fac8da42e6941b22df061a119e5c0335f81006de9ee799
"@webassemblyjs/utf8@npm:1.11.6":
version: 1.11.6
resolution: "@webassemblyjs/utf8@npm:1.11.6"
checksum: 10c0/14d6c24751a89ad9d801180b0d770f30a853c39f035a15fbc96266d6ac46355227abd27a3fd2eeaa97b4294ced2440a6b012750ae17bafe1a7633029a87b6bee
languageName: node
linkType: hard
"@webassemblyjs/wasm-edit@npm:^1.14.1":
version: 1.14.1
resolution: "@webassemblyjs/wasm-edit@npm:1.14.1"
"@webassemblyjs/wasm-edit@npm:^1.12.1":
version: 1.12.1
resolution: "@webassemblyjs/wasm-edit@npm:1.12.1"
dependencies:
"@webassemblyjs/ast": "npm:1.14.1"
"@webassemblyjs/helper-buffer": "npm:1.14.1"
"@webassemblyjs/helper-wasm-bytecode": "npm:1.13.2"
"@webassemblyjs/helper-wasm-section": "npm:1.14.1"
"@webassemblyjs/wasm-gen": "npm:1.14.1"
"@webassemblyjs/wasm-opt": "npm:1.14.1"
"@webassemblyjs/wasm-parser": "npm:1.14.1"
"@webassemblyjs/wast-printer": "npm:1.14.1"
checksum: 10c0/5ac4781086a2ca4b320bdbfd965a209655fe8a208ca38d89197148f8597e587c9a2c94fb6bd6f1a7dbd4527c49c6844fcdc2af981f8d793a97bf63a016aa86d2
"@webassemblyjs/ast": "npm:1.12.1"
"@webassemblyjs/helper-buffer": "npm:1.12.1"
"@webassemblyjs/helper-wasm-bytecode": "npm:1.11.6"
"@webassemblyjs/helper-wasm-section": "npm:1.12.1"
"@webassemblyjs/wasm-gen": "npm:1.12.1"
"@webassemblyjs/wasm-opt": "npm:1.12.1"
"@webassemblyjs/wasm-parser": "npm:1.12.1"
"@webassemblyjs/wast-printer": "npm:1.12.1"
checksum: 10c0/972f5e6c522890743999e0ed45260aae728098801c6128856b310dd21f1ee63435fc7b518e30e0ba1cdafd0d1e38275829c1e4451c3536a1d9e726e07a5bba0b
languageName: node
linkType: hard
"@webassemblyjs/wasm-gen@npm:1.14.1":
version: 1.14.1
resolution: "@webassemblyjs/wasm-gen@npm:1.14.1"
"@webassemblyjs/wasm-gen@npm:1.12.1":
version: 1.12.1
resolution: "@webassemblyjs/wasm-gen@npm:1.12.1"
dependencies:
"@webassemblyjs/ast": "npm:1.14.1"
"@webassemblyjs/helper-wasm-bytecode": "npm:1.13.2"
"@webassemblyjs/ieee754": "npm:1.13.2"
"@webassemblyjs/leb128": "npm:1.13.2"
"@webassemblyjs/utf8": "npm:1.13.2"
checksum: 10c0/d678810d7f3f8fecb2e2bdadfb9afad2ec1d2bc79f59e4711ab49c81cec578371e22732d4966f59067abe5fba8e9c54923b57060a729d28d408e608beef67b10
"@webassemblyjs/ast": "npm:1.12.1"
"@webassemblyjs/helper-wasm-bytecode": "npm:1.11.6"
"@webassemblyjs/ieee754": "npm:1.11.6"
"@webassemblyjs/leb128": "npm:1.11.6"
"@webassemblyjs/utf8": "npm:1.11.6"
checksum: 10c0/1e257288177af9fa34c69cab94f4d9036ebed611f77f3897c988874e75182eeeec759c79b89a7a49dd24624fc2d3d48d5580b62b67c4a1c9bfbdcd266b281c16
languageName: node
linkType: hard
"@webassemblyjs/wasm-opt@npm:1.14.1":
version: 1.14.1
resolution: "@webassemblyjs/wasm-opt@npm:1.14.1"
"@webassemblyjs/wasm-opt@npm:1.12.1":
version: 1.12.1
resolution: "@webassemblyjs/wasm-opt@npm:1.12.1"
dependencies:
"@webassemblyjs/ast": "npm:1.14.1"
"@webassemblyjs/helper-buffer": "npm:1.14.1"
"@webassemblyjs/wasm-gen": "npm:1.14.1"
"@webassemblyjs/wasm-parser": "npm:1.14.1"
checksum: 10c0/515bfb15277ee99ba6b11d2232ddbf22aed32aad6d0956fe8a0a0a004a1b5a3a277a71d9a3a38365d0538ac40d1b7b7243b1a244ad6cd6dece1c1bb2eb5de7ee
"@webassemblyjs/ast": "npm:1.12.1"
"@webassemblyjs/helper-buffer": "npm:1.12.1"
"@webassemblyjs/wasm-gen": "npm:1.12.1"
"@webassemblyjs/wasm-parser": "npm:1.12.1"
checksum: 10c0/992a45e1f1871033c36987459436ab4e6430642ca49328e6e32a13de9106fe69ae6c0ac27d7050efd76851e502d11cd1ac0e06b55655dfa889ad82f11a2712fb
languageName: node
linkType: hard
"@webassemblyjs/wasm-parser@npm:1.14.1, @webassemblyjs/wasm-parser@npm:^1.14.1":
version: 1.14.1
resolution: "@webassemblyjs/wasm-parser@npm:1.14.1"
"@webassemblyjs/wasm-parser@npm:1.12.1, @webassemblyjs/wasm-parser@npm:^1.12.1":
version: 1.12.1
resolution: "@webassemblyjs/wasm-parser@npm:1.12.1"
dependencies:
"@webassemblyjs/ast": "npm:1.14.1"
"@webassemblyjs/helper-api-error": "npm:1.13.2"
"@webassemblyjs/helper-wasm-bytecode": "npm:1.13.2"
"@webassemblyjs/ieee754": "npm:1.13.2"
"@webassemblyjs/leb128": "npm:1.13.2"
"@webassemblyjs/utf8": "npm:1.13.2"
checksum: 10c0/95427b9e5addbd0f647939bd28e3e06b8deefdbdadcf892385b5edc70091bf9b92fa5faac3fce8333554437c5d85835afef8c8a7d9d27ab6ba01ffab954db8c6
"@webassemblyjs/ast": "npm:1.12.1"
"@webassemblyjs/helper-api-error": "npm:1.11.6"
"@webassemblyjs/helper-wasm-bytecode": "npm:1.11.6"
"@webassemblyjs/ieee754": "npm:1.11.6"
"@webassemblyjs/leb128": "npm:1.11.6"
"@webassemblyjs/utf8": "npm:1.11.6"
checksum: 10c0/e85cec1acad07e5eb65b92d37c8e6ca09c6ca50d7ca58803a1532b452c7321050a0328c49810c337cc2dfd100c5326a54d5ebd1aa5c339ebe6ef10c250323a0e
languageName: node
linkType: hard
"@webassemblyjs/wast-printer@npm:1.14.1":
version: 1.14.1
resolution: "@webassemblyjs/wast-printer@npm:1.14.1"
"@webassemblyjs/wast-printer@npm:1.12.1":
version: 1.12.1
resolution: "@webassemblyjs/wast-printer@npm:1.12.1"
dependencies:
"@webassemblyjs/ast": "npm:1.14.1"
"@webassemblyjs/ast": "npm:1.12.1"
"@xtuc/long": "npm:4.2.2"
checksum: 10c0/8d7768608996a052545251e896eac079c98e0401842af8dd4de78fba8d90bd505efb6c537e909cd6dae96e09db3fa2e765a6f26492553a675da56e2db51f9d24
checksum: 10c0/39bf746eb7a79aa69953f194943bbc43bebae98bd7cadd4d8bc8c0df470ca6bf9d2b789effaa180e900fab4e2691983c1f7d41571458bd2a26267f2f0c73705a
languageName: node
linkType: hard
@@ -2868,12 +2848,12 @@ __metadata:
languageName: node
linkType: hard
"acorn-import-phases@npm:^1.0.3":
version: 1.0.4
resolution: "acorn-import-phases@npm:1.0.4"
"acorn-import-attributes@npm:^1.9.5":
version: 1.9.5
resolution: "acorn-import-attributes@npm:1.9.5"
peerDependencies:
acorn: ^8.14.0
checksum: 10c0/338eb46fc1aed5544f628344cb9af189450b401d152ceadbf1f5746901a5d923016cd0e7740d5606062d374fdf6941c29bb515d2bd133c4f4242d5d4cd73a3c7
acorn: ^8
checksum: 10c0/5926eaaead2326d5a86f322ff1b617b0f698aa61dc719a5baa0e9d955c9885cc71febac3fb5bacff71bbf2c4f9c12db2056883c68c53eb962c048b952e1e013d
languageName: node
linkType: hard
@@ -2886,16 +2866,7 @@ __metadata:
languageName: node
linkType: hard
"acorn@npm:^8.15.0":
version: 8.15.0
resolution: "acorn@npm:8.15.0"
bin:
acorn: bin/acorn
checksum: 10c0/dec73ff59b7d6628a01eebaece7f2bdb8bb62b9b5926dcad0f8931f2b8b79c2be21f6c68ac095592adb5adb15831a3635d9343e6a91d028bbe85d564875ec3ec
languageName: node
linkType: hard
"acorn@npm:^8.9.0":
"acorn@npm:^8.7.1, acorn@npm:^8.8.2, acorn@npm:^8.9.0":
version: 8.12.1
resolution: "acorn@npm:8.12.1"
bin:
@@ -2952,17 +2923,6 @@ __metadata:
languageName: node
linkType: hard
"ajv-keywords@npm:^5.1.0":
version: 5.1.0
resolution: "ajv-keywords@npm:5.1.0"
dependencies:
fast-deep-equal: "npm:^3.1.3"
peerDependencies:
ajv: ^8.8.2
checksum: 10c0/18bec51f0171b83123ba1d8883c126e60c6f420cef885250898bf77a8d3e65e3bfb9e8564f497e30bdbe762a83e0d144a36931328616a973ee669dc74d4a9590
languageName: node
linkType: hard
"ajv@npm:^6.12.4, ajv@npm:^6.12.5":
version: 6.12.6
resolution: "ajv@npm:6.12.6"
@@ -2975,7 +2935,7 @@ __metadata:
languageName: node
linkType: hard
"ajv@npm:^8.0.0, ajv@npm:^8.12.0, ajv@npm:^8.16.0, ajv@npm:^8.9.0":
"ajv@npm:^8.0.0, ajv@npm:^8.12.0, ajv@npm:^8.16.0":
version: 8.17.1
resolution: "ajv@npm:8.17.1"
dependencies:
@@ -3437,15 +3397,6 @@ __metadata:
languageName: node
linkType: hard
"baseline-browser-mapping@npm:^2.9.0":
version: 2.9.19
resolution: "baseline-browser-mapping@npm:2.9.19"
bin:
baseline-browser-mapping: dist/cli.js
checksum: 10c0/569928db78bcd081953d7db79e4243a59a579a34b4ae1806b9b42d3b7f84e5bc40e6e82ae4fa06e7bef8291bf747b33b3f9ef5d3c6e1e420cb129d9295536129
languageName: node
linkType: hard
"basic-auth@npm:^2.0.1":
version: 2.0.1
resolution: "basic-auth@npm:2.0.1"
@@ -3602,18 +3553,17 @@ __metadata:
languageName: node
linkType: hard
"browserslist@npm:^4.28.1":
version: 4.28.1
resolution: "browserslist@npm:4.28.1"
"browserslist@npm:^4.21.10":
version: 4.23.3
resolution: "browserslist@npm:4.23.3"
dependencies:
baseline-browser-mapping: "npm:^2.9.0"
caniuse-lite: "npm:^1.0.30001759"
electron-to-chromium: "npm:^1.5.263"
node-releases: "npm:^2.0.27"
update-browserslist-db: "npm:^1.2.0"
caniuse-lite: "npm:^1.0.30001646"
electron-to-chromium: "npm:^1.5.4"
node-releases: "npm:^2.0.18"
update-browserslist-db: "npm:^1.1.0"
bin:
browserslist: cli.js
checksum: 10c0/545a5fa9d7234e3777a7177ec1e9134bb2ba60a69e6b95683f6982b1473aad347c77c1264ccf2ac5dea609a9731fbfbda6b85782bdca70f80f86e28a402504bd
checksum: 10c0/3063bfdf812815346447f4796c8f04601bf5d62003374305fd323c2a463e42776475bcc5309264e39bcf9a8605851e53560695991a623be988138b3ff8c66642
languageName: node
linkType: hard
@@ -3837,10 +3787,10 @@ __metadata:
languageName: node
linkType: hard
"caniuse-lite@npm:^1.0.30001759":
version: 1.0.30001768
resolution: "caniuse-lite@npm:1.0.30001768"
checksum: 10c0/16808cb39f9563098deab6d45bcd0642a79fc5ace8dbcea8106b008b179820353e3ec089ed7e54f1f3c8bb84f2c2835b451f308212d8f36c2b7942f879e91955
"caniuse-lite@npm:^1.0.30001646":
version: 1.0.30001659
resolution: "caniuse-lite@npm:1.0.30001659"
checksum: 10c0/11dc1c0795505d5c629cdf02361d7d60249646a49ed2868997144c3d9c6b0c3e18d87f6ea2b48b6deed593c483271003cebca7dd805fbda96607a9b83899eeaa
languageName: node
linkType: hard
@@ -5006,10 +4956,10 @@ __metadata:
languageName: unknown
linkType: soft
"electron-to-chromium@npm:^1.5.263":
version: 1.5.286
resolution: "electron-to-chromium@npm:1.5.286"
checksum: 10c0/5384510f9682d7e46f98fa48b874c3901d9639de96e9e387afce1fe010fbac31376df0534524edc15f66e9902bfacee54037a5e598004e9c6a617884e379926d
"electron-to-chromium@npm:^1.5.4":
version: 1.5.18
resolution: "electron-to-chromium@npm:1.5.18"
checksum: 10c0/2c553c4e7618e887398af0fb7ddd8055beb69d37a810ad73fcea0f3e9027f1fc879ef280151fb6bae8e5b961f5597452eafc1ae5a0adca5bd49211545a34afe7
languageName: node
linkType: hard
@@ -5084,13 +5034,13 @@ __metadata:
languageName: node
linkType: hard
"enhanced-resolve@npm:^5.19.0":
version: 5.19.0
resolution: "enhanced-resolve@npm:5.19.0"
"enhanced-resolve@npm:^5.17.1":
version: 5.17.1
resolution: "enhanced-resolve@npm:5.17.1"
dependencies:
graceful-fs: "npm:^4.2.4"
tapable: "npm:^2.3.0"
checksum: 10c0/966b1dffb82d5f6a4d6a86e904e812104a999066aa29f9223040aaa751e7c453b462a3f5ef91f8bd4408131ff6f7f90651dd1c804bdcb7944e2099a9c2e45ee2
tapable: "npm:^2.2.0"
checksum: 10c0/81a0515675eca17efdba2cf5bad87abc91a528fc1191aad50e275e74f045b41506167d420099022da7181c8d787170ea41e4a11a0b10b7a16f6237daecb15370
languageName: node
linkType: hard
@@ -5355,10 +5305,10 @@ __metadata:
languageName: node
linkType: hard
"es-module-lexer@npm:^2.0.0":
version: 2.0.0
resolution: "es-module-lexer@npm:2.0.0"
checksum: 10c0/ae78dbbd43035a4b972c46cfb6877e374ea290adfc62bc2f5a083fea242c0b2baaab25c5886af86be55f092f4a326741cb94334cd3c478c383fdc8a9ec5ff817
"es-module-lexer@npm:^1.2.1":
version: 1.5.4
resolution: "es-module-lexer@npm:1.5.4"
checksum: 10c0/300a469488c2f22081df1e4c8398c78db92358496e639b0df7f89ac6455462aaf5d8893939087c1a1cbcbf20eed4610c70e0bcb8f3e4b0d80a5d2611c539408c
languageName: node
linkType: hard
@@ -5470,7 +5420,7 @@ __metadata:
languageName: node
linkType: hard
"escalade@npm:^3.1.1, escalade@npm:^3.2.0":
"escalade@npm:^3.1.1, escalade@npm:^3.1.2":
version: 3.2.0
resolution: "escalade@npm:3.2.0"
checksum: 10c0/ced4dd3a78e15897ed3be74e635110bbf3b08877b0a41be50dcb325ee0e0b5f65fc2d50e9845194d7c4633f327e2e1c6cce00a71b617c5673df0374201d67f65
@@ -8659,10 +8609,10 @@ __metadata:
languageName: node
linkType: hard
"loader-runner@npm:^4.3.1":
version: 4.3.1
resolution: "loader-runner@npm:4.3.1"
checksum: 10c0/a523b6329f114e0a98317158e30a7dfce044b731521be5399464010472a93a15ece44757d1eaed1d8845019869c5390218bc1c7c3110f4eeaef5157394486eac
"loader-runner@npm:^4.2.0":
version: 4.3.0
resolution: "loader-runner@npm:4.3.0"
checksum: 10c0/a44d78aae0907a72f73966fe8b82d1439c8c485238bd5a864b1b9a2a3257832effa858790241e6b37876b5446a78889adf2fcc8dd897ce54c089ecc0a0ce0bf0
languageName: node
linkType: hard
@@ -10114,10 +10064,10 @@ __metadata:
languageName: node
linkType: hard
"node-releases@npm:^2.0.27":
version: 2.0.27
resolution: "node-releases@npm:2.0.27"
checksum: 10c0/f1e6583b7833ea81880627748d28a3a7ff5703d5409328c216ae57befbced10ce2c991bea86434e8ec39003bd017f70481e2e5f8c1f7e0a7663241f81d6e00e2
"node-releases@npm:^2.0.18":
version: 2.0.18
resolution: "node-releases@npm:2.0.18"
checksum: 10c0/786ac9db9d7226339e1dc84bbb42007cb054a346bd9257e6aa154d294f01bc6a6cddb1348fa099f079be6580acbb470e3c048effd5f719325abd0179e566fd27
languageName: node
linkType: hard
@@ -10956,13 +10906,20 @@ __metadata:
languageName: node
linkType: hard
"picocolors@npm:^1.0.0, picocolors@npm:^1.1.1":
"picocolors@npm:^1.0.0":
version: 1.1.1
resolution: "picocolors@npm:1.1.1"
checksum: 10c0/e2e3e8170ab9d7c7421969adaa7e1b31434f789afb9b3f115f6b96d91945041ac3ceb02e9ec6fe6510ff036bcc0bf91e69a1772edc0b707e12b19c0f2d6bcf58
languageName: node
linkType: hard
"picocolors@npm:^1.0.1":
version: 1.1.0
resolution: "picocolors@npm:1.1.0"
checksum: 10c0/86946f6032148801ef09c051c6fb13b5cf942eaf147e30ea79edb91dd32d700934edebe782a1078ff859fb2b816792e97ef4dab03d7f0b804f6b01a0df35e023
languageName: node
linkType: hard
"picomatch@npm:^2.0.4":
version: 2.0.7
resolution: "picomatch@npm:2.0.7"
@@ -12586,7 +12543,7 @@ __metadata:
languageName: node
linkType: hard
"schema-utils@npm:^3.0.0":
"schema-utils@npm:^3.0.0, schema-utils@npm:^3.1.1, schema-utils@npm:^3.2.0":
version: 3.3.0
resolution: "schema-utils@npm:3.3.0"
dependencies:
@@ -12597,18 +12554,6 @@ __metadata:
languageName: node
linkType: hard
"schema-utils@npm:^4.3.0, schema-utils@npm:^4.3.3":
version: 4.3.3
resolution: "schema-utils@npm:4.3.3"
dependencies:
"@types/json-schema": "npm:^7.0.9"
ajv: "npm:^8.9.0"
ajv-formats: "npm:^2.1.1"
ajv-keywords: "npm:^5.1.0"
checksum: 10c0/1c8d2c480a026d7c02ab2ecbe5919133a096d6a721a3f201fa50663e4f30f6d6ba020dfddd93cb828b66b922e76b342e103edd19a62c95c8f60e9079cc403202
languageName: node
linkType: hard
"semver-compare@npm:^1.0.0":
version: 1.0.0
resolution: "semver-compare@npm:1.0.0"
@@ -12714,7 +12659,7 @@ __metadata:
languageName: node
linkType: hard
"serialize-javascript@npm:^6.0.2":
"serialize-javascript@npm:^6.0.1, serialize-javascript@npm:^6.0.2":
version: 6.0.2
resolution: "serialize-javascript@npm:6.0.2"
dependencies:
@@ -13619,10 +13564,10 @@ __metadata:
languageName: node
linkType: hard
"tapable@npm:^2.3.0":
version: 2.3.0
resolution: "tapable@npm:2.3.0"
checksum: 10c0/cb9d67cc2c6a74dedc812ef3085d9d681edd2c1fa18e4aef57a3c0605fdbe44e6b8ea00bd9ef21bc74dd45314e39d31227aa031ebf2f5e38164df514136f2681
"tapable@npm:^2.1.1, tapable@npm:^2.2.0":
version: 2.2.1
resolution: "tapable@npm:2.2.1"
checksum: 10c0/bc40e6efe1e554d075469cedaba69a30eeb373552aaf41caeaaa45bf56ffacc2674261b106245bd566b35d8f3329b52d838e851ee0a852120acae26e622925c9
languageName: node
linkType: hard
@@ -13673,15 +13618,15 @@ __metadata:
languageName: node
linkType: hard
"terser-webpack-plugin@npm:^5.3.16":
version: 5.3.16
resolution: "terser-webpack-plugin@npm:5.3.16"
"terser-webpack-plugin@npm:^5.3.10":
version: 5.3.10
resolution: "terser-webpack-plugin@npm:5.3.10"
dependencies:
"@jridgewell/trace-mapping": "npm:^0.3.25"
"@jridgewell/trace-mapping": "npm:^0.3.20"
jest-worker: "npm:^27.4.5"
schema-utils: "npm:^4.3.0"
serialize-javascript: "npm:^6.0.2"
terser: "npm:^5.31.1"
schema-utils: "npm:^3.1.1"
serialize-javascript: "npm:^6.0.1"
terser: "npm:^5.26.0"
peerDependencies:
webpack: ^5.1.0
peerDependenciesMeta:
@@ -13691,21 +13636,21 @@ __metadata:
optional: true
uglify-js:
optional: true
checksum: 10c0/39e37c5b3015c1a5354a3633f77235677bfa06eac2608ce26d258b1d1a74070a99910319a6f2f2c437eb61dc321f66434febe01d78e73fa96b4d4393b813f4cf
checksum: 10c0/66d1ed3174542560911cf96f4716aeea8d60e7caab212291705d50072b6ba844c7391442541b13c848684044042bea9ec87512b8506528c12854943da05faf91
languageName: node
linkType: hard
"terser@npm:^5.31.1":
version: 5.46.0
resolution: "terser@npm:5.46.0"
"terser@npm:^5.26.0":
version: 5.32.0
resolution: "terser@npm:5.32.0"
dependencies:
"@jridgewell/source-map": "npm:^0.3.3"
acorn: "npm:^8.15.0"
acorn: "npm:^8.8.2"
commander: "npm:^2.20.0"
source-map-support: "npm:~0.5.20"
bin:
terser: bin/terser
checksum: 10c0/93ad468f13187c4f66b609bbfc00a6aee752007779ca3157f2c1ee063697815748d6010fd449a16c30be33213748431d5f54cc0224ba6a3fbbf5acd3582a4356
checksum: 10c0/94daae4881258eb7d09abd46378e23d11ee46caa507b2fb26c5595c7e490914be734e0de38c50041dc38fae5fca24de11badf042dfbbfc1d336ed117335c420a
languageName: node
linkType: hard
@@ -14450,17 +14395,17 @@ __metadata:
languageName: node
linkType: hard
"update-browserslist-db@npm:^1.2.0":
version: 1.2.3
resolution: "update-browserslist-db@npm:1.2.3"
"update-browserslist-db@npm:^1.1.0":
version: 1.1.0
resolution: "update-browserslist-db@npm:1.1.0"
dependencies:
escalade: "npm:^3.2.0"
picocolors: "npm:^1.1.1"
escalade: "npm:^3.1.2"
picocolors: "npm:^1.0.1"
peerDependencies:
browserslist: ">= 4.21.0"
bin:
update-browserslist-db: cli.js
checksum: 10c0/13a00355ea822388f68af57410ce3255941d5fb9b7c49342c4709a07c9f230bbef7f7499ae0ca7e0de532e79a82cc0c4edbd125f1a323a1845bf914efddf8bec
checksum: 10c0/a7452de47785842736fb71547651c5bbe5b4dc1e3722ccf48a704b7b34e4dcf633991eaa8e4a6a517ffb738b3252eede3773bef673ef9021baa26b056d63a5b9
languageName: node
linkType: hard
@@ -14688,13 +14633,13 @@ __metadata:
languageName: node
linkType: hard
"watchpack@npm:^2.5.1":
version: 2.5.1
resolution: "watchpack@npm:2.5.1"
"watchpack@npm:^2.4.1":
version: 2.4.2
resolution: "watchpack@npm:2.4.2"
dependencies:
glob-to-regexp: "npm:^0.4.1"
graceful-fs: "npm:^4.1.2"
checksum: 10c0/dffbb483d1f61be90dc570630a1eb308581e2227d507d783b1d94a57ac7b705ecd9a1a4b73d73c15eab596d39874e5276a3d9cb88bbb698bafc3f8d08c34cf17
checksum: 10c0/ec60a5f0e9efaeca0102fd9126346b3b2d523e01c34030d3fddf5813a7125765121ebdc2552981136dcd2c852deb1af0b39340f2fcc235f292db5399d0283577
languageName: node
linkType: hard
@@ -14762,48 +14707,46 @@ __metadata:
languageName: node
linkType: hard
"webpack-sources@npm:^3.3.3":
version: 3.3.3
resolution: "webpack-sources@npm:3.3.3"
checksum: 10c0/ab732f6933b513ba4d505130418995ddef6df988421fccf3289e53583c6a39e205c4a0739cee98950964552d3006604912679c736031337fb4a9d78d8576ed40
"webpack-sources@npm:^3.2.3":
version: 3.2.3
resolution: "webpack-sources@npm:3.2.3"
checksum: 10c0/2ef63d77c4fad39de4a6db17323d75eb92897b32674e97d76f0a1e87c003882fc038571266ad0ef581ac734cbe20952912aaa26155f1905e96ce251adbb1eb4e
languageName: node
linkType: hard
"webpack@npm:^5.104.1":
version: 5.105.0
resolution: "webpack@npm:5.105.0"
"webpack@npm:^5.95.0":
version: 5.95.0
resolution: "webpack@npm:5.95.0"
dependencies:
"@types/eslint-scope": "npm:^3.7.7"
"@types/estree": "npm:^1.0.8"
"@types/json-schema": "npm:^7.0.15"
"@webassemblyjs/ast": "npm:^1.14.1"
"@webassemblyjs/wasm-edit": "npm:^1.14.1"
"@webassemblyjs/wasm-parser": "npm:^1.14.1"
acorn: "npm:^8.15.0"
acorn-import-phases: "npm:^1.0.3"
browserslist: "npm:^4.28.1"
"@types/estree": "npm:^1.0.5"
"@webassemblyjs/ast": "npm:^1.12.1"
"@webassemblyjs/wasm-edit": "npm:^1.12.1"
"@webassemblyjs/wasm-parser": "npm:^1.12.1"
acorn: "npm:^8.7.1"
acorn-import-attributes: "npm:^1.9.5"
browserslist: "npm:^4.21.10"
chrome-trace-event: "npm:^1.0.2"
enhanced-resolve: "npm:^5.19.0"
es-module-lexer: "npm:^2.0.0"
enhanced-resolve: "npm:^5.17.1"
es-module-lexer: "npm:^1.2.1"
eslint-scope: "npm:5.1.1"
events: "npm:^3.2.0"
glob-to-regexp: "npm:^0.4.1"
graceful-fs: "npm:^4.2.11"
json-parse-even-better-errors: "npm:^2.3.1"
loader-runner: "npm:^4.3.1"
loader-runner: "npm:^4.2.0"
mime-types: "npm:^2.1.27"
neo-async: "npm:^2.6.2"
schema-utils: "npm:^4.3.3"
tapable: "npm:^2.3.0"
terser-webpack-plugin: "npm:^5.3.16"
watchpack: "npm:^2.5.1"
webpack-sources: "npm:^3.3.3"
schema-utils: "npm:^3.2.0"
tapable: "npm:^2.1.1"
terser-webpack-plugin: "npm:^5.3.10"
watchpack: "npm:^2.4.1"
webpack-sources: "npm:^3.2.3"
peerDependenciesMeta:
webpack-cli:
optional: true
bin:
webpack: bin/webpack.js
checksum: 10c0/4aea6b976485b5364e122f301c08f48efa84ddb2c0cb5d09f27445d1f2da0b9875cd889e41b58cac3ff05618a9c965be716df52586d151b5f52a7bbed7662174
checksum: 10c0/b9e6d0f8ebcbf0632494ac0b90fe4acb8f4a9b83f7ace4a67a15545a36fe58599c912ab58e625e1bf58ab3b0916c75fe99da6196d412ee0cab0b5065edd84238
languageName: node
linkType: hard