Hope this time bug report is taken more seriously ....
Android: race introduced by per-hostname content script registration (66e7596)
Summary
Since 1.75.1b14, scriptlets (built-in ones included) don’t run on the first load of a page on Firefox for Android. A reload fixes it. 1.75.1b12 is the last build that works. 1.75.1b18 and 1.75.1rc0 have the bug.
filter example for deltabit.co :
deltabit.co##+js(trusted-click-element, .clickable.player-poster, , 20)
1.75.1b12: the poster is clicked and the video starts.
1.75.1b14 and later: nothing happens on first load and nothing shows in the logger. After a reload it works.
Cause (bisected)
Between b12 and b18, the only commit that changes how scriptlets are delivered on Firefox is:
66e759691: “Register content scripts on a per hostname basis”
https://github.com/gorhill/uBlock/commit/66e759691bfff26302c69836a8373798061725fd
b12 registers one content script for all sites (http:///, https:///) at startup. It is already registered before any navigation, so it always runs at document_start.
b14+ registers a content script per hostname, lazily, inside webNavigation.onBeforeNavigate → browser.contentScripts.register().
contentScripts.register() is asynchronous. When the registration doesn’t complete before the new document reaches document_start, nothing is injected for that load. There is no error and no logger entry. On reload the hostname is already registered, so it works. This race is lost very often on Android because IPC there is slower.
The follow-up commits (8f93ff1fc, 4594da551, 6a567cc55) don’t change this. rc0 has identical code in platform/firefox/vapi-scripting.js and src/js/scriptlet-filtering.js. No hidden setting restores the old behavior.
The commit message itself mentions it may be reverted if it proves less reliable than the previous single-registration approach.
Environment
Firefox for Android (Fenix), Android 14
uBO 1.75.1b14 / b16 / b18 / rc0: broken
uBO 1.75.1b12: works
Steps to reproduce
Add the filter above.
Open https://deltabit.co/... in a new tab: the scriptlet doesn’t run.
Reload: the scriptlet runs.