2020年代仍有Firefox userChrome JS脚本(介绍、简略教程、资源)
直到现在(2022年中更新时)Firefox的 userChrome script(简称uc脚本) 仍然可以使用。我们无法知道在遥远的或不久的将来Mozilla会不会让uc脚本完全失效,这两年已有人在说,但自57以后,是uc脚本让一些人(例如我)不需要(或暂时不需要)放弃Firefox转用其他浏览器。目前看来,uc脚本仍然可以让我们这些普通用户安心使用下去。
本人的技术重点不在于浏览器,只是个浏览器用户。本文非专业性很强的文章
背景
2017年Firefox的“量子”版本(57)发布,中止了所有旧扩展(Addon/Extension,又称附加组件,与“插件 Plugins 不同)的支持。XUL、XPCOM、XBL等旧的被称为Legacy的技术被宣称要废弃。57开始只支持webExtension的扩展。
这一改变我相信使得很多人离开Firefox,因为可自订性、可玩性降低很多(例如主界面不能再随意更改、扩展不能再任意操作浏览器about:config
内的项目),一大堆的旧扩展作废。
但旧技术也没有完全被剥离,仍然有人通过 userChrome script(简称uc脚本) 的方式实现一些webExtension无法实现(或暂时无法实现)的功能。甚至有人通过uc脚本复活了好多个Legacy扩展的100%功能。可以说只要uc脚本仍可用,以前的Firefox玩法都可以继续。
在本来就小众的Firefox用户群中,uc脚本更加小众,本篇将介绍一些资源和笔者自己写的uc脚本,还有简略的脚本编写教程(默认你会js)(我这个教程写得不算好,但目前没发现有大神在写)。
userChrome JS脚本与
userChrome.css
有关但不同,脚本是JavaScript的,不是CSS
如何启用uc脚本
Firefox每更新一个版本,启用uc脚本的方法就很可能会变化。以下这些常跟进Firefox的变化提供启用方法的:
-
xiaoxiaoflood/firefox-scripts: (现在需要自行为新的Firefox版本打这个补丁)
方法一般就是将一些用于启用的js、xml、css文件放入Firefox程序目录及profile中,然后就可以把你的具体.uc.js
文件放入对应位置使用。
以上所列这些启用方式,每一套也称为一种uc脚本管理器。
除了启用uc脚本的方法会变化,uc脚本代码也需要根据Firefox版本的更新而修改。如果常更新是较麻烦的,因此我自己使用半年更新一次的Firefox ESR。
编写uc脚本的简略教程
启用浏览器工具箱
编写uc脚本需要使用浏览器工具箱(Browser Tools)来调试。可以让你用鼠标选择和可查看浏览器主界面上的任意一部位的部件(导航栏、地址栏、标签栏等),也可以让你输入执行整个浏览器级别的js代码。
浏览器工具箱(Browser Tools)开启的快捷键是Ctrl+Shift+Alt+I
。
注意与网页开发所用的工具箱
Ctrl+Shift+I
不同,我们需要的这个是可以调试整个浏览器的,而那个只调试一个tab内的网页
而Firefox默认是禁用了Browser Tools的。启用的方法为:
-
先打开一个tab页面的开发者工具(
Ctrl+Shift+I
) -
右上角三个点->设置
-
勾选高级设置下面的以下两个
-
Enable browser chrome and add-on debugging toolboxes
-
Enable remote debugging
-
现在可以关闭网页开发工具,打开浏览器工具箱了。打开时会弹窗确认允许远程调试连接。
编写代码
学了WebExtension的而未学Firefox Legacy技术的可以看看这篇比较文章
这里不详细讲,也不会去教js,默认读者有一些js基础了。只简略说些常见的做法,具体还请参考下面的参考资源,本篇中的许多具体脚本的链接也可以作为例子学习。
uc脚本的代码有可能因Firefox版本更新而需要改变
主界面上的部件、按钮等都是有DOM节点的,一般都有id和class,可以像平常使用js一样对它们做一些操作。请在浏览器工具箱中慢慢研究。
.uc.js特别的头部
打开一个.uc.js
一般常看到
// ==UserScript==
// @name <script name>
// @author <someone>
// @include main
// @onlyonce
// ==/UserScript==
这些//
开头的,虽然对于JS来说是没有用的注释,但对于uc脚本来说,在一个.uc.js
文件被执行前,是会先寻找并解析这种@开头的关键字的(这也可能因你所用uc脚本管理器而异)。
@include
指定你的这个.uc.js
文件在怎么样的Firefox窗口中执行。Firefox是可以打开多窗口的(包括那些下载对话框之类的,也算一种窗口)。经常,我们只需要脚本在Firefox的主窗口执行(注意主窗口也可以打开多个),所以使用@include main
排除那些下载、关于等非主窗口。
@onlyonce
指定该uc.js
在整个Firefox中只被执行一遍(而不是每打开一个窗口就执行一次)。例如添加自定义widget(即工具栏按钮)的代码在整个Firefox只应该被执行一遍,它就会在每个浏览器窗口中出现该widget,这时就需要@onlyonce
。
注意,以xiaoxialflood的uc脚本启动管理器为例,是否使用
@onlyonce
,影响这个uc.js
文件被加载执行时的global对象(需要看这个页面中描述的targetObj
参数才能表述清楚)。
Standard code modules
操作DOM节点还不够,有些Firefox内置的功能最好调用一些内部Standard code modules来使用。例如常看到
const xxx = Components.utils.import("resource://xxx/xxx.jsm");
const xxx = Components.classes["@mozilla.org/xxx/xxx;1"].getService(Components.xxx.xxx);
这些Standard code modules具体是通过.jsm
文件(Firefox源码中,也是JS)封装的。
根据Mozilla此文 ,使用
ChromeUtils.import
好过Components.utils.import
XUL namespace
uc中常需用到XUL这个namespace。关于namespace,这里有介绍,常见的namespace有
注意这些URL不是给我们打开访问的,只是形式(一种假网址)
HTML: http://www.w3.org/1999/xhtml
XUL: http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul
XBL: http://www.mozilla.org/xbl
脚本中可用document.createElementNS
来创建XUL namespace的元素,也可以用简化的document.createXULElement
来直接创建浏览器UI常用的XUL。
css内也会出现如
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
管理好每个.uc.js文件的命名空间
编写uc脚本时,将js变量和对象名称限制在命名空间内是个好习惯,例如在一个.uc.js
文件内:
console.log("xxx.uc.js");
(() => {
你的代码
})();
除了上面方式,也可以创建一个有名称的Object来当你的命名空间。
一些资源
我自己写的uc脚本
因我自己使用半年更新一次的Firefox ESR,我写的这些脚本也只会为ESR更新。
-
把标签栏放在FIrefox窗口底部最下方。不是地址栏下方,而是网页内容下方,整个窗口最下方
虽然少,但这个帖子说明了仍有人有这个需求:现在还有没有标签栏可以下置的浏览器? - 知乎。因此也希望各个浏览器能考虑将其添加为原生选项。
-
如果你要经常更改
about:config
里的某一个值,那么打开修改挺麻烦的。可以这个快捷菜单。把你自己经常要改的加进去 -
右键单击标签栏上的标签按钮来关闭标签。如果想调出标签按钮菜单,按住shift再右击。
这个也可以配合一个仅在活动标签显示关闭按钮的css使用
-
快速地通过点击Firefox窗口左侧(最大化时就是屏幕左侧)边缘来开关侧边栏。
以前的Legacy扩展All in One Sidebar(AiOS)已废弃,但Firefox官方加入了原生的侧边栏,只是没有通过边缘快速开关的功能。用这个简单的uc脚本实现了AiOS基本一样的体验。
-
在每个标签按钮上用柱条显示该标签页占用的CPU及内存。在标签栏最右边,显示浏览器总的CPU及内存。
-
你可以右键点击新建标签的加号按钮,然后选择新建标签打开剪贴板中的网址
更多我的脚本和代码在 https://garywill.github.io/
如何使Firefox保持安装临时扩展
在没有我们这里的方法之前,Firefox不支持终端中用CLI命令加载扩展,只允许安装经过Mozilla签名的(上AMO去提交并签名再下载回来。可以不发布)。在about:debugging
页面中可以用点击“加载临时扩展”以安装未打包、未签名的扩展,但关闭Firefox后不会维持,要重新操作一遍。
通过uc脚本代码,可以使Firefox每次启动时自动加载临时扩展:
var FileUtils = Cu.import("resource://gre/modules/FileUtils.jsm").FileUtils
var nsifile = new FileUtils.File("未打包的扩展路径,目录下应有manifest.json");
Cu.import("resource://gre/modules/AddonManager.jsm");
AddonManager.installTemporaryAddon(nsifile);
其他人的uc脚本或Legacy技术资源
-
xiaoxiaoflood/firefox-scripts (现在需要自行为新的Firefox版本打这个补丁)
如何使用旧的XUL/XPCOM Firefox legacy扩展
Mozilla官方已经删掉了所有XUL/XPCOM旧技术创建的扩展,ca-archive收集了它们。可以找旧的Firefox 52 esr或56来安装ca-archive,然后便可以在浏览器内浏览、下载、安装legacy扩展。
甚至,xiaoxiaoflood/firefox-scripts提供通过uc脚本使legacy扩展能够在新(57以后)的Firefox运行的可能。
文档或其他参考资源
-
Unified XUL Platform MDN Backup https://udn.realityripple.com/
-
Firefox程序目录中的
omni.ja
把它解压出来,你会看到里面有许多.jsm
文件。那些是我们写uc脚本需要调用的各种模块(都是JS)。目前网上关于写uc脚本有用的说明很多已经消失了(有些正在逐渐消失),所以有时需要自己看Firefox源码。说到Firefox源代码,到searchfox上看也是一个方法
-
Mozilla已存档的旧技术文档,其中就包含有编写uc脚本会用到的legacy扩展资料、Firefox的Component Utils用法、内部的Standard code modules(
.jsm
)等 -
Firefox 吧项目组收集的Firefox外部资源列表(对我们用处不大): Firefox 吧项目组
关注一下
📺 Bilibili 收集有趣科技 和发布原创视频 | 🖥️ Github 有用的和没用的开源项目代码
玩而后赏
子曰,玩而予赏,善莫大焉?
又曰,玩而不赏,良心安焉?
写作不易,感谢支持!
虽然,小小玩意,不足挂齿;
亦是,卅年老刀,献丑于此。
其实,多赏非求,少许亦可。
进者,参观主页,玩物更多。
未联系作者获得同意前,不可转载
转载必须附上源地址,并连我博客上的宣传内容一并转载