diff --git a/docs/api/command-line-switches.md b/docs/api/command-line-switches.md index a23f12b6de..79fea53586 100644 --- a/docs/api/command-line-switches.md +++ b/docs/api/command-line-switches.md @@ -366,6 +366,13 @@ Keep in mind that standalone switches can sometimes be split into individual fea Finally, you'll need to ensure that the version of Chromium in Electron matches the version of the browser you're using to cross-reference the switches. +### Chromium features relevant to Electron apps + +* `AlwaysLogLOAFURL`: enables script attribution for + [`long-animation-frame`](https://developer.mozilla.org/en-US/docs/Web/API/Performance_API/Long_animation_frame_timing) + `PerformanceObserver` events for non-http(s), non-data, non-blob URLs (such as `file:` or custom + protocol URLs). + [app]: app.md [append-switch]: command-line.md#commandlineappendswitchswitch-value [debugging-main-process]: ../tutorial/debugging-main-process.md diff --git a/patches/chromium/.patches b/patches/chromium/.patches index 25f4d793d8..b94baf5e80 100644 --- a/patches/chromium/.patches +++ b/patches/chromium/.patches @@ -146,3 +146,4 @@ viz_fix_visual_artifacts_while_resizing_window_with_dcomp.patch fix_os_crypt_async_cookie_encryption.patch graphite_handle_out_of_order_recording_errors.patch move_wayland_pointer_lock_overrides_to_common_code.patch +loaf_add_feature_to_enable_sourceurl_for_all_protocols.patch diff --git a/patches/chromium/loaf_add_feature_to_enable_sourceurl_for_all_protocols.patch b/patches/chromium/loaf_add_feature_to_enable_sourceurl_for_all_protocols.patch new file mode 100644 index 0000000000..4a3930693f --- /dev/null +++ b/patches/chromium/loaf_add_feature_to_enable_sourceurl_for_all_protocols.patch @@ -0,0 +1,52 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Niklas Wenzel +Date: Wed, 4 Feb 2026 06:02:40 -0800 +Subject: LoAF: Add feature to enable sourceURL for all protocols + +Backports https://crrev.com/c/7510894 (minus the test changes). + +Can be removed when that CL is included via a Chromium roll. + +Change-Id: Id5e58a151b13cc0ac054f4ec237b038255d683fd +Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7510894 +Commit-Queue: Noam Rosenthal +Reviewed-by: Dave Tapuska +Reviewed-by: Noam Rosenthal +Cr-Commit-Position: refs/heads/main@{#1579397} + +diff --git a/third_party/blink/renderer/core/frame/animation_frame_timing_monitor.cc b/third_party/blink/renderer/core/frame/animation_frame_timing_monitor.cc +index 0d621b6b397a2f8c33732a7bc1a68830539438be..f0749e9a9db7c5cd6b9d12440800241a14640cdd 100644 +--- a/third_party/blink/renderer/core/frame/animation_frame_timing_monitor.cc ++++ b/third_party/blink/renderer/core/frame/animation_frame_timing_monitor.cc +@@ -520,8 +520,15 @@ void AnimationFrameTimingMonitor::Trace(Visitor* visitor) const { + visitor->Trace(frame_handling_input_); + } + ++BASE_FEATURE(kAlwaysLogLOAFURL, base::FEATURE_DISABLED_BY_DEFAULT); ++ + namespace { ++ + bool ShouldAllowScriptURL(const String& url) { ++ if (base::FeatureList::IsEnabled(kAlwaysLogLOAFURL)) { ++ return true; ++ } ++ + KURL kurl(url); + return kurl.ProtocolIsData() || kurl.ProtocolIsInHTTPFamily() || + kurl.ProtocolIs("blob") || kurl.IsEmpty(); +diff --git a/third_party/blink/renderer/core/frame/animation_frame_timing_monitor.h b/third_party/blink/renderer/core/frame/animation_frame_timing_monitor.h +index f2fe39be2db525d89fcd9787c2ae9285babab26d..c395cf39d404f6c4f6f6e23c9fb8dfe92151a7d2 100644 +--- a/third_party/blink/renderer/core/frame/animation_frame_timing_monitor.h ++++ b/third_party/blink/renderer/core/frame/animation_frame_timing_monitor.h +@@ -22,6 +22,11 @@ class TimeTicks; + + namespace blink { + ++// When enabled, long-animation-frame events will always include the sourceURL, ++// regardless of protocol. This is useful during development when using `file:` ++// URLs or custom protocols defined by embedders. ++CORE_EXPORT BASE_DECLARE_FEATURE(kAlwaysLogLOAFURL); ++ + class LocalFrame; + + // Monitors long-animation-frame timing (LoAF). diff --git a/spec/chromium-spec.ts b/spec/chromium-spec.ts index ec7e721e95..05de8b340c 100644 --- a/spec/chromium-spec.ts +++ b/spec/chromium-spec.ts @@ -3213,6 +3213,29 @@ describe('chromium features', () => { expect(rgb).to.equal(''); }); }); + + describe('long-animation-frame', () => { + it('should include script attribution on custom protocols if AlwaysLogLOAFURL is enabled', async () => { + const rc = await startRemoteControlApp(['--enable-features=AlwaysLogLOAFURL']); + const hasAttribution = await rc.remotely(async (fixture: string) => { + const { BrowserWindow, protocol, net } = require('electron/main'); + const { pathToFileURL } = require('node:url'); + + protocol.handle('custom', () => net.fetch(pathToFileURL(fixture).toString())); + + // `show: true` is necessary on Windows and Linux due to https://github.com/electron/electron/issues/32001 + const w = new BrowserWindow({ show: true }); + await w.loadURL('custom://my-url'); + + const hasAttribution = await w.webContents.executeJavaScript('hasAttributionPromise'); + + global.setTimeout(() => require('electron').app.quit()); + + return hasAttribution; + }, path.join(fixturesPath, 'chromium', 'long-animation-frame.html')); + expect(hasAttribution).to.be.true(); + }); + }); }); describe('font fallback', () => { diff --git a/spec/fixtures/chromium/long-animation-frame.html b/spec/fixtures/chromium/long-animation-frame.html new file mode 100644 index 0000000000..11d87ca6ab --- /dev/null +++ b/spec/fixtures/chromium/long-animation-frame.html @@ -0,0 +1,29 @@ + + + +
+ + +