I'm frustrated because an important feature of the cross-platform WebExtensions API for web browser extensions has been broken in Mac Safari — and only in Mac Safari — for two years. It works everywhere else: Firefox, Google Chrome, other Chromium-based web browsers, and even in Mobile Safari! The feature I'm talking about is
run_at document_start. If the value
"run_at": "document_start" is specified for a content script in an extension's manifest file, then web pages will run the extension's content script during their "loading" state, as opposed to during their "interactive" or "complete" state. (See the
Document.readyState API for more details.) This is crucial because with
document_start, scripts are injected "before any other DOM is constructed or any other script is run." In order to achieve their functionality, some web browser extensions need to run their scripts before the web page gets a chance to run its scripts, otherwise it's too late.
One extension that needs
document_start bug prevents StopTheScript from working properly in Mac Safari, and thus I can't release a Mac version. I've been sitting on the Mac version for two years just waiting for a bug fix in Mac Safari. I actually blogged about the bug two years ago, a year before Apple enabled Safari web extensions on iOS. I've personally discussed this bug with an Apple Safari engineer, and I've also filed a bug report (FB10033445) with Apple's Feedback Assistant. At this point I'm feeling despair that Apple might never fix it. The bug still exists in the current versions of Safari (15.6.1) and Safari Technology Preview (16.0).
You can download a sample Xcode project that demonstrates the bug. The project contains both Mac and iOS app targets. The web extension is located inside the folder
"Shared (Extension)/Resources/" and is shared between the two apps. You can test the same extension in Firefox by opening the page
about:debugging#/runtime/this-firefox and using the "Load Temporary Add-on" button. In Google Chrome, you can open the Extensions window, enable "Developer mode", and use the "Load unpacked" button.
Here are the steps to reproduce the bug in Mac Safari:
The extension adds a red box in the upper left corner of each web page that displays the
readyState of the page, as well as the number of child elements, if any, of the HTML
<body> elements. When
document_start works correctly, you should just see "loading" in the box, with no child elements. When it's buggy, you may see "interactive" or "complete", along with a number of children.
In Mobile Safari on iOS there's a related bug (FB9157626) that can cause
run_at document_start to fail if Preload Top Hit is enabled in Safari Settings. Unfortunately, Preload Top Hit is enabled by default. Fortunately, you can easily disable Preload Top Hit, and the StopTheScript install instructions recommend disabling it.
Besides causing extension problems, Preload Top Hit is also privacy nightmare, as I've blogged about before, so everyone ought to disable it anyway.