扫盲 Firefox 定制——从“user.js”到“omni.ja”

2019-07-19 原文 #编程随想 的其它文章

扫盲 Firefox 定制——从“user.js”到“omni.ja”

最近一年,写过好几篇涉及“Web 安全”的博文。这些博文或多或少都会提及“Firefox 的定制”。考虑到某些读者对这方面不太了解,单独写一篇扫盲。
如果你从来不用 Firefox 浏览器,本教程就不用看了(以免浪费时间)。
本文主要面向不太熟悉 Firefox 的菜鸟;对于 Firefox 的老鸟,顶多只需要看“高级话题”相关的章节。


★预备知识


◇“浏览器实例”(profile)是啥?


Firefox 支持【多实例】(多个 profile)。你可以把“profile”这个概念通俗理解为:“独立的浏览器环境”。
也就是说,实例之间是【互相隔离】滴,每个实例都有自己【独立的】“书签、浏览历史、下载历史、cookies ......”
就算你从来没有创建过实例,只要你通过 Firefox 上网,你的 Firefox 至少会有一个实例(也就是你正在用的这个)。

◇如何找到当前实例的目录?


每个实例(profile)都对应一个目录,属于该实例的那些东西(书签、浏览历史、下载历史、cookies ...)全都存储在该目录下。
要想查看你正在使用的 Firefox 实例对应的目录,很简单:
1. 在浏览器地址栏输入 about:support 然后敲回车
2. 这时候会显示一个支持页面,其中有一项 Profile Directory (俺用的是英文版,中文版的叫法略有不同),对应的就是【当前实例的目录】。


★扫盲“配置选项”(Preferences)


◇啥是“配置选项”?


“配置选项”也叫“首选项”,洋文称之为“Preferences”。
通俗地说就是:Firefox 提供了一大堆可供用户定制的参数。通过修改这些参数,可以对 Firefox 进行【全方位】定制。
每个 Preference 包含如下几个要素:

名称
每个 Preference 的名称必定是【唯一】滴。
“名称”由英文单词构成,单词之间以“小数点”或“下划线”分隔。

数据类型
Preferences 的“数据类型”必须是“布尔型、整数型、字符串型”这三者之一。
“布尔型”的值只能是 true 或 false。
“整数型”的值可以是负数。

默认值
每个 Preference 都有个“默认值”。
“默认值”包含在 Firefox 的安装包里面。
绝大多数用户并【不需要】去修改“默认值”。
(注:极少数有此需求的读者,可以去本文的 高级话题——autoconfig 这个章节)

当前值
每个 Preference 都对应某个“当前值”。
当你修改 Preference 的时候,修改的就是它的“当前值”。
一开始的时候,每个 Preference 的“当前值”就等于它的“默认值”;如果该 Preference 被定制了(修改了),其“当前值”与“默认值”就有可能不同。

◇谁可以修改“配置选项”?


首先,Firefox 的用户当然可以修改配置选项(具体如何做,后续章节会细聊)
除了用户,【浏览器扩展】也可以添加或修改“配置选项”。某些扩展会提供定制界面,让用户设定某些参数。这些参数也保存在浏览器的 Preference 里面。
有必要强调一下:网站上的 JS 是【无法修改】Preference 滴!
道理很简单:因为 Firefox 的 Preference 中保存了很多与安全性相关的配置参数。如果允许网站的 JS 修改这些参数,将会成为巨大的安全隐患。

◇为啥要修改“配置选项”?


俺总结下来,大致有如下几种需求:
1. 安全加固
你可以通过定制很多的 Preferences 以大大强化 Firefox 的安全性(包括隐私防护能力)。
每次 Firefox 的新版本增加了某个比较重要的安全相关的定制选项,俺会在每季度的《近期安全动态和点评》提醒大伙儿。
2. 性能优化
通过定制 Preference 可以优化性能(包括:“网络传输、内存使用、界面渲染”等方面)
3. 易用性
通过定制 Preference,你还可以改进 Firefox 界面的易用性。


★“about:config”界面


◇进入界面


修改 Firefox 的 Preference,最简单的方式就是“about:config”界面了。
你在浏览器地址栏输入 about:config 然后敲回车,就进入该界面。
(提醒一下:打开该界面时,你可能会看到一个警告提示,别慌张)

“about:config”界面主要是个的表格,共4列,分别是:
第1列:Preference 的“名称”
第2列:Preference 的“状态”(如果显示“default”表示该 Preference 还没被修改过,显示“modified”表示已经被改过)
第3列:Preference 的“数据类型”
第4列:Preference 的“当前值”

◇【筛选/过滤】Preferences


该界面默认会列出 Firefox【所有的】Preference(成百上千个)。某些菜鸟一看到这个架势,可能会有点晕。
别慌,界面上方有一个搜索框,可以帮你进行【筛选/过滤】。
该搜索框针对 Preference 的名称进行【模糊匹配】。比如说:你在搜索框中输入 network ,那么界面上就只列出名称中包含 network 的那些 Preferences。

◇【修改】某个 Preference 的值


对于“布尔型”的 Preference,你双击 Preference 所在的这行,就可以修改它的“当前值”(在 true 与 false 之间切换)
对于其它数据类型,双击 Preference 所在的行,会弹出一个对话框,让你输入【新的】数值。

◇【重置】某个 Preference 的值


所谓的“重置”(reset)就是指“恢复默认值”。
(对于已经被改过的 Preference)选中它所在的那行;点右键;在快捷菜单上有一项“Reset”(重置);使用这个菜单项就可以把该选项重新恢复成默认值。

◇【添加】一个新的 Preference


在“about:config”界面的表格上点右键;在快捷菜单上有一项“New”(新增);可以让你添加一个新的 Preference。
添加时会让你指定新 Preference 的“名称”和“数值”。

◇一个小小的练习——如何去掉“about:config”界面的警告


你在“about:config”界面的搜索框中输入 general.warnOnAboutConfig ,此时只会过滤出一个 Preference,这个 Preference 是“布尔型”。当它的值是 true ,每次你打开“about:config”界面都会显示警告提示;反之,则不显示。
你可以修改这个 Preference 的值。修改之后再【重新打开】“about:config”界面,体会一下效果。


★“prefs.js”配置文件


◇功能简介


每个 Firefox 实例中都有名为 prefs.js 的配置文件。这个文件保存了当前实例中【所有】Preferences 的设置。

◇文件位置


该文件位于每个【实例目录】下。

◇文件格式


该文件的扩展名是 .js ,说明其内容是 javascript 语法。
在 javascript 语法中,任何一行中如果出现【双斜杠】 // ,那么“从双斜杠一直到行尾”都算【注释】;另外,包含在 /* */ 之间的内容也是【注释】。(注:第二种注释可以跨越多行)
除了注释之外,该文件的每一行有效代码对应一个 Preferences。文件中的每个有效代码行全都是如下这个样子:
user_pref("配置项名称", 配置项数值);

由于每一个 Preferences 的名称都是字符串,因此上述代码中的 配置项名称 总是包含在【半角引号】中。
如果某个 Preferences 的数据类型属于“字符串型”,那么上述代码中的“配置项数值”也要包含在【半角引号】中;否则,就不需要使用引号。

◇注意事项!!!


【不要】直接修改 prefs.js 文件!!!
如果你想通过【配置文件】的方式定制 Firefox 的 Preferences,请使用【user.js】(参见下一个章节)。


★“user.js”配置文件


◇功能简介


Firefox 使用名为 user.js 的文件对 Preferences 进行个性化定制。

◇文件位置


该文件位于【实例目录】下。请注意: 默认情况下【没有】这个文件!
如果你想用这种方式定制 Firefox,需要在【当前实例】的目录下【手动创建】该文件,然后往这个文件中添加代码。

◇文件格式


该文件的格式与 prefs.js 相同。具体介绍参见“前一个章节”。

◇配置举例


前面介绍“about:config”界面时,已经让你做了一个小小的练习。
现在,咱们在“user.js”中继续进行这个练习——
当你创建好一个空的 user.js 文件,在文件中添加如下代码,并存盘。
user_pref("general.warnOnAboutConfig", false);
(注:上述代码中的“括号、引号、逗号、分号”必须都是【半角符号】)
上述文件存盘之后,你把 Firefox 重新启动,然后再打开“about:config”界面,这时候就不会再有那个讨厌的警告信息了。

◇【重置】某个 Preference 的值


如果你已经在“user.js”中修改过某个 Preference,之后又想恢复其默认值。请参照如下步骤:
1. 先在“user.js”中把这个 Preference 的配置“删除”或“注释掉”;
2. 重启浏览器;
3. 再到“about:config”界面进行重置操作。

◇注意事项!!!


当你要通过这种方式修改某个选项,先搞清楚这个选项的含义和用途,并了解可能的【副作用】。


★上述三种配置方式的【原理】


◇加载配置


当 Firefox 启动的时候,会读取 user.js prefs.js ,拿到这两个文件中的 Preferences 配置,并保存在内存中。
如果发现这两个文件的配置有冲突,以 user.js 为准(也就是说:“ user.js 的配置”会覆盖“ prefs.js 的配置”)。
如果同一个配置项在某个文件中出现多次,后面的代码行会覆盖前面的代码行。

◇修改配置


当你打开“about:config”界面,Firefox 会把内存中的 Preferences 信息显示给你看。
如果你在这个界面上进行了修改,修改的结果会保存在内存中,同时也会保存到 prefs.js 文件中。
另外,Firefox【不会】去修改你用于定制的 user.js 文件。


★高级话题——autoconfig


“高级话题”是专门针对“Firefox 老鸟”,尤其是那些具有“geek 精神”(善于折腾)的用户。
(熟悉本博客的读者应该知道:俺一向鼓励【折腾】,并写过一篇博文《 聊聊【折腾】的重要性 》)
至于菜鸟嘛,先搞定前面章节介绍的内容,学会怎么用“user.js”;然后再考虑本文的“高级话题”。
考虑到本章节的特点,“高级话题”的介绍只是【点到为止】——对于【善折腾】的读者,俺只需给出一个方向,他们自然能沿着这个方向走得足够远。

◇“user.js”的局限性


通过“user.js”,虽然可以让你定制每一个 Preference;但至少有如下局限性:

局限性1——【无法】修改某个 Preference 的【默认值】
请注意:在 user.js 中修改的是【当前值】。不管“当前值”如何变,“默认值”【没】变。
在某些特殊场合,你可能想要定制 Preference 的【默认值】。

局限性2——【无法】锁定某个 Preference
所谓的“锁定”就是“禁止修改”的意思。
比如说:某个第三方扩展会修改某个 Preference 的值;但你又不希望这个 Preference 被修改。这时候就可以把这个 Preference【锁定】。

◇比“user.js”更牛逼的【autoconfig】


Firefox 的扩展能力及其强大,当然能满足上述这些怪异的需求。
Mozilla 提供了名为【autoconfig】的机制,可以更进一步地定制 Preference。具体参见 Mozilla 官网的“ 这篇教程 ”(洋文)。
user.js 中,咱们只能使用 user_pref 这个函数;而在【autoconfig】这种定制方式中,还提供了更多的函数,至少包括如下(代码中绿色的部分是注释):
defaultPref("配置项名称", 配置项数值);  // 该函数用于:定制配置项的【默认值】
lockPref("配置项名称", 配置项数值);  // 该函数用于:设置配置项的默认值并【锁定】
unlockPref("配置项名称");  // 该函数用于:【解锁】配置项
clearPref("配置项名称");  //  该函数用于:把配置项的【当前值】恢复为【默认值】


★高级话题——定制“omni.ja”


◇“autoconfig”的局限性


“autoconfig”虽然比“user.js”更牛逼,但其能力只局限于 Preference 相关的定制。
有些你想定制的东西(比如:默认的键盘快捷键)【并不】保存在 Preference 中——也就是说,即便你去捣鼓“autoconfig”也【搞不定】!这时候就要引入【终极大杀器】——直接修改【omni.ja】。

顺便插一句:
自从 Firefox Quantum(Firefox 57)之后,旧的“XPCOM 扩展机制”已经淘汰,换成新的“WebExtensions 扩展机制”。但是,“新扩展机制”的功能比原来要弱(据说是为了安全性的考虑)。比如:对“键盘快捷键”的定制能力就变弱了。
在这种情况下,“定制 omni.ja”的优势就更加明显——因为它能做到“用扩展无法完成的事情”。

◇比“autoconfig”更强大的【omni.ja】


Firefox 是一个很复杂的开源项目,代码量超大。它的核心代码(比如:渲染引擎、JS 引擎)是基于 C++ 语言开发(并在逐步迁移到 Rust 语言)。而软件界面(UI)相关的部分,大体上还是 Web 那套东西(不外乎就是:XML、JS、JSON、CSS ...)。
这些与 UI 相关的东西,大部分都打包在(安装包自带的) omni.ja 文件中。如果你摸透了 omni.ja 的结构,就可以对 Firefox 的界面进行任意定制。
说到这里,某些熟悉 Firefox 的用户会反问:为啥不用 userChrome.css 定制 Firefox?
这个东东俺当然知道(而且还写过专门的教程,链接在“ 这里 ”)。但它的能力很【有限】——只能修改 CSS 样式,【无法】定制界面的功能。

举个【简单】例子:
比如说 Firefox 的默认快捷键中,【Ctrl + q】会退出整个进程;
如果你不喜欢这个快捷键,可以换成一个更顺手的(通过修改 omni.ja 里面的 chrome/en-US/locale/browser/browser.dtd

举个【复杂】例子:
或许很多 Firefox 用户不知道——你可以用【Alt + 数字键】或【Ctrl + 数字键】来切换 Firefox 的标签页。
(注:俺在 Linux 用的是 Alt,而 Windows 环境用的是 Ctrl)
当你在 Firefox 界面上按了这个组合键,会触发某个 JS 代码,然后由这个 JS 代码来改变当前标签页的状态。
而这段 JS 代码就包含在 omni.ja 这个压缩包的某个文件中( chrome/browser/content/browser/browser.xul )。如果你能修改这段 JS 代码,就可以实现自己想要的某些效果。

友情提醒:
安装好的 Firefox 有【两个】 omni.ja ——大的那个有30多兆,小的那个有十多兆。
当你要折腾的时候,别搞错了!!!
比如说:当俺在折腾键盘快捷键时,修改的是【大的】那个。

◇简述“omni.ja”的格式


如何“解压缩”?
虽然 omni.ja 的扩展名是 .ja ,但其实是个 zip 压缩包;但它又【不是】标准的 zip 压缩包——因为它的文件头有点特殊。
俺在 Linux 下用 unzip 命令进行解压缩,完全 OK(使用 Mac OS 的同学也可以用这个命令);
对于使用 Windows 的同学,(Mozilla 官网的文档建议)先把扩展名改为 .zip 再用资源管理器自带的解压功能(注:其它解压 zip 的工具不一定能行)。

如何“压缩(重新打包)”?
当你【修改完】 omni.ja 内部的文件之后,要【重新打包】该文件。
对于 POSIX 环境(Linux & UNIX),Mozilla 官网的文档建议使用如下命令:
zip -qr9XD omni.ja *

◇定制“omni.ja”的注意事项


简单说几个注意事项:

第1条
omni.ja 内部的文件很多。只修改那些【你有把握】的文件。
如果你把 omni.ja 内部的某些文件改坏了,可能会导致 Firefox 无法启动,而且也没有任何报错信息。

第2条
每次修改完 omni.ja ,为了让你的修改生效,要记得:先退出 Firefox【进程】;然后清空整个缓存目录;最后再启动 Firefox。

第3条
由于每次修改完都要做“打包、清缓存、重启 Firefox”这几件事情。俺建议:搞个命令行脚本帮你自动干这些事儿,以提升效率。

第4条
omni.ja 会随着 Firefox 的版本而变化。也就是说,每次有新版本,你还需要在新版本上再修改一次。
如果结合第3条与第4条,你更应该写一个脚本,帮你【自动化】完成整个定制流程。


俺博客上,和本文相关的帖子(需翻墙)
无需任何插件或扩展,定制 Firefox 外观
基于安全考虑,如何选择及切换 Firefox 版本?
弃用 Chrome 改用 Firefox 的几点理由——关于 Chrome 69 隐私丑闻的随想
如何用 GreaseMonkey 扩展 Google Reader
聊聊【折腾】的重要性
版权声明
本博客所有的原创文章,作者皆保留版权。转载必须包含本声明,保持本文完整,并以超链接形式注明作者 编程随想 和本文原始地址:
https://program-think.blogspot.com/2019/07/Customize-Firefox.html

文章版权归原作者所有。
二维码分享本站