More compatible `.user.js` URL support
To be honest, I personally don't like the idea of putting filenames into query/search/parameters or even anchor/fragment/hash, it's a source of a lot of confusion. (just like all these different names)
But whether I like it or not, a lot of confusion already exists and is being relied upon.
Sometimes we have to make some trade-offs between compatibility/convenience and recommended practices.
I think there are some bottom lines we have to stick to when it comes to serious security and clarity stuffs.
For example we would never add syntax support to @match other than Match patterns. This is a serious security setback and a source of all sorts of confusion.
However, I don't seem to see clear serious issues with URL format support (in any case, the installation of remote scripts is at the user's own choice and risk), and better compatibility could really come in handy for a few users.
Furthermore, Greasemonkey does have a crazy but clear definition of this:
The Whole Internet Any server across the entire web may host user scripts. For
Greasemonkey, the only requirement is that the (entire) URL ends with.user.jsand that it is not served with atext/htmlcontent type. This even works in the fragment, so you can append#.user.jsto any URL serving a script to trigger installation. Servers supporting HTTPS are best, in order to be compatible with Greasemonkey's built in update checker.
So it looks like we should fix this compatibility issue instead of being opinionated.
After further investigation, I have more doubts about implementing this compatibility.
The definition of Greasemonkey is indeed clear and executed in its extension, but this actually conflicts with the project.
For example, the following URL is considered valid in this extension, but the installation will not be triggered in Greasemonkey:
https://foo.bar/example.user.js#123
https://foo.bar/example.user.js?v=1
So, if there will inevitably be incompatibility and there is no unified specification, what rules should we refer to?
The result is that each extension is implemented according to its own different considerations, and if so, I would rather keep the status quo.
Due to implementation conflicts, at the moment I see little practical gain if this option is implemented, other than breaking the current implementation and adding complexity and confusion.
I would now prefer to improve the README documentation by explicitly stating that the extension only supports remote user scripts ending in .user.js in the URL PATH part.
Else I need to get more convincing evidence or norms to advance this issue.
@arjpar
@ACTCD
URL
This is the userscript URL (as mentioned in #820, #787) in question (Bypass Paywalls Clean userscript):
https://gitflic.ru/project/magnolia1234/bypass-paywalls-clean-filters/blob/raw?file=userscript/bpc.en.user.js
Greasemonkey, Violentmonkey, and Tampermonkey all support this URL
Unlike your experience in your comment above, Greasemonkey (in FF) allows me to import that userscript by going to the userscript URL directly in the browser. It also supports autoupdate and manual update.
Both Violentmonkey & Tampermonkey, two very popular userscript managers support importing that userscript by its URL, as well as updating it.
If you need steps to reproduce I will be happy to provide it.
Violentmonkey & Greasemonkey userscript validation
This is how I believe Violentmonkey & Greasemonkey checks if a userscript is indeed a userscript.
Violentmonkey
- First, VM checks if the URL's domain is a part of a trusted list of known domains for userscripts (https://github.com/violentmonkey/violentmonkey/blob/067769f189032ad0dcc22aeb732699d2702fd5b0/src/background/utils/tab-redirector.js#L53)
- Second, if the URL is not a part of the whitelist, VM analyzes the file's contents to determine if it is a userscript (https://github.com/violentmonkey/violentmonkey/blob/067769f189032ad0dcc22aeb732699d2702fd5b0/src/background/utils/tab-redirector.js#L84, https://github.com/violentmonkey/violentmonkey/blob/067769f189032ad0dcc22aeb732699d2702fd5b0/src/background/utils/script.js#L91)
Greasemonkey
- First, GM registers a web request listener that specifically looks for URLs ending in .user.js (https://github.com/greasemonkey/greasemonkey/blob/8a51d1432e8c1adbd761d2654b030e11efc11b74/src/bg/user-script-detect.run.js#L3)
- Second, once a matching URL is found it checks the content type header to ensure that it is compatible with javascript (https://github.com/greasemonkey/greasemonkey/blob/8a51d1432e8c1adbd761d2654b030e11efc11b74/src/bg/user-script-detect.js)
- Third, GM once the content type is valid it parses the userscript block to get the metadata and validate that it is indeed a userscript (https://github.com/greasemonkey/greasemonkey/blob/8a51d1432e8c1adbd761d2654b030e11efc11b74/src/parse-user-script.js#L56)
Conclusion
Therefore since both Greasemonkey, Violentmonkey, and Tampermonkey all support either importing the userscript, updating the userscript, or both, I believe userscripts should support this type of URL.
If you need me to elaborate more, I'd be happy to do so.
@arjpar Thanks for the info, but that not directly answer to my doubts.
You simply see the consistency in it, not the inconsistency.
Greasemonkey only supports URL ends with .user.js, and instead does not support the URL formats supported by this extension. And it gets a similar implementation in Violentmonkey, which does not trigger installation.
Tampermonkey also does not support installation triggers for the URL you provide.
Note that I'm talking about installation triggering, not URL importing, which is the extra inconsistency.
Except for Greasemonkey, none of the others clearly document this.
There is no specification there, only different implementations.
For all those who read the issue.
Putting the file identifier (filename) in the ?QUERY or #HASH parts is not universal and recommended, you could:
-
File an issue to the provider, requesting that they comply with the URL specification
- What is a URL?
- RFC1738 and related revisions
- https://www.w3.org/Addressing/URL/url-spec.txt
- https://url.spec.whatwg.org/
- https://en.wikipedia.org/wiki/URL
-
Find or set up a reverse proxy to convert URLs
-
Host scripts to other specification-compliant providers
@arjpar Thanks for the info, but that not directly answer to my doubts.
You simply see the consistency in it, not the inconsistency.
Greasemonkeyonly supports URL ends with.user.js, and instead does not support the URL formats supported by this extension. And it gets a similar implementation inViolentmonkey, which does not trigger installation.
Tampermonkeyalso does not support installation triggers for the URL you provide.Note that I'm talking about installation triggering, not URL importing, which is the extra inconsistency.
Except for
Greasemonkey, none of the others clearly document this.There is no specification there, only different implementations.
For all of the extensions you and I mentioned, Greasemonkey, Violentmonkey, and Tampermonkey they all support installation triggering for the userscript URL I specified. Either way for the URL I specified, they all trigger installation & recognize it as a userscript, and can install & update as well. This extension cannot. I tested all of those extensions on Firefox 139.
By installation trigger I mean going to the URL in the browser and seeing how the userscript extension, either GM, VM, or TM, recognizes it and gives the option to install it either way.
By inconsistency I understand you mean that there is no unified specification to determine how userscript URLs are validated and how there are simply different implementations. But since this extension doesn't properly detect the given URL, and all the other prominent userscript managers do, this leaves out Userscripts regardless of there being a specification or not.
Perhaps I'm still misunderstood, on what you mean regarding the inconsistency and "installation triggering". Could you elaborate if possible?
@arjpar
For all of the extensions you and I mentioned, Greasemonkey, Violentmonkey, and Tampermonkey they all support installation triggering for the userscript URL I specified.
By installation trigger I mean going to the URL in the browser and seeing how the userscript extension, either GM, VM, or TM, recognizes it and gives the option to install it either way.
It seems that our test results are inconsistent.
I also tested all three extensions in Firefox 140 for these URLs:
https://raw.githubusercontent.com/quoid/userscripts/refs/heads/main/src/ext/shared/dev/DEMO.Alert-URL.user.js
https://raw.githubusercontent.com/quoid/userscripts/refs/heads/main/src/ext/shared/dev/DEMO.Alert-URL.user.js?v=1
https://raw.githubusercontent.com/quoid/userscripts/refs/heads/main/src/ext/shared/dev/DEMO.Alert-URL.user.js#v=1
https://raw.githubusercontent.com/quoid/userscripts/refs/heads/main/LICENSE#demo.user.js
https://gitflic.ru/project/magnolia1234/bypass-paywalls-clean-filters/blob/raw?file=userscript/bpc.en.user.js
Under all default settings, not all extensions trigger installation in all URLs, including your URL.
I tested again and recorded the results as follows:
| Userscripts | GM | VM | TM | |
|---|---|---|---|---|
path.user.js |
✅ | ✅ | ✅ | ✅ |
.user.js?v=1 |
✅ | ❌ | ✅ | ✅ |
.user.js#v=1 |
✅ | ❌ | ❌ | ✅ |
foo#.user.js |
❌ | ✅ | ❌ | ❌ |
foo?.user.js |
❌ | ✅ | ✅ | ❌ |
This is exactly the same as my previous test results, and through the table, it should clearly express what I said inconsistency.
And I should also mention that all major hosting providers use the first three specification-compliant URL formats, including but not limited to: GreasyFork, OpenUserJS, GitHub, GitLab, etc.
So, again, please ask your service provider to follow the URL specification. https://github.com/quoid/userscripts/issues/822#issuecomment-2993068280
This is not an issue in the project, we use a URL parsing method that complies with the specification. And we don't want to encourage bad practices, add unnecessary complexity, and more confusion.
@arjpar @stevenya97 @Samadaeus @Morku @AuroraWright
I wrote this for myself and it will update automatically, if also helps you guys: https://greasyfork.org/en/users/1493917-bpc-relay-bot
Except for inline @require lib, no changes were made to the scripts. That is to say, it mainly does URL conversion only. I do not provide any technical support for the scripts themselves.
Nice work! I've set up a GitHub Action with a fork to do a similar thing for myself and to have it notify me on a Telegram channel. Having it on greasyfork is very convenient for many people!
@OliviaGraceParker Nice, thank you for letting me know. It just won't load the article, but at least have a button now for quicker access.
Screenshot:
Tested de/at/ch