blog
blog copied to clipboard
将划词翻译迁移到火狐浏览器
最近将划词翻译发布到了火狐里,记录一下遇到的三个问题。截止目前,火狐浏览器的最新版本是 v69.0.3。
manifest.json 中的 incognito 不支持 split
目前,火狐浏览器是不支持在隐身模式下使用 split 方式的,见 https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/incognito
CSS 中文件的引用方式不同
在 Chrome 扩展中,插入到内容脚本中的 CSS 如果要引用扩展里的文件(图片、字体等),需要使用 chrome-extension://[PACKAGE ID]/[PATH TO FILE] 这种绝对地址的形式(见 Chrome 文档),Chrome 会把相对路径基于当前内容脚本所在的网址来解析;但在火狐浏览器中,内容脚本的 CSS 是相对于这个 CSS 文件来解析的,所以可以直接使用相对路径来引用文件。这一点我觉得火狐浏览器的做法还是挺好的。
Storage API 不能保存 Vue 的数据对象
划词翻译里有这样一段代码:
new Vue({
data: {
options: { ... }
},
watch: {
options: {
deep: true,
handler(val) { chrome.storage.local.set(val) }
}
}
})
这段代码在 Chrome 里是没有问题的,但在 Firefox 里会报一个错误:TypeError: can't access dead object,看官方文档说是跟对象里引用了 DOM 有关,我猜应该是跟 Vue 把对象转成了 getter/setter 有关联,把 val 先转成一个普通的对象之后,再用 Storage API 保存就没有问题了。
疑似火狐浏览器的 Bug
在火狐浏览器里拖动窗口时,即使释放了鼠标,窗口还是跟着鼠标移动。划词翻译用的是 interactjs v1.2.8,但升级到最新版 v1.6.2 之后,还是会有类似的问题,而且 Web 控制台和浏览器控制台里都没有报错信息。
在一步步调试代码之后,发现了问题的原因,简单来说,当下面的代码在火狐浏览器的内容脚本里运行的时候,浏览器控制台里会报错:
var caf = window.cancelAnimationFrame
caf(1) // TypeError: 'cancelAnimationFrame' called on an object that does not implement interface Window.
奇怪的地方有:
- 这段代码在普通的网页下运行是没有问题的。
- 这个报错在划词翻译里没有抛出来,只是静默的中断了当前函数的运行,结果后面取消事件监听的代码没执行,最终导致即使释放了鼠标,窗口还是跟着鼠标移动。
- 我无意中还发现,
cancelAnimationFrame === window.cancelAnimationFrame在内容脚本里是false,但在普通网页里是true。
火狐的官方论坛里有一个人跟我遇到了同样的问题:How to use highcharts in content script,这人也是因为报了这个错导致不能使用 HighCharts,但回复里说这不是火狐浏览器的原因,是因为代码开启了严格模式,但我在测试的时候没有用严格模式也是有问题的。
给 interact.js 提了个 PR(taye/interact.js#810)修复了这个问题,在 interact.js 把这个 PR 合并进去之前(也可能不会合并……),可以通过引入下面这个 js 文件的方式修复这个问题:
// firefox-fix.js
window.requestAnimationFrame = window.requestAnimationFrame.bind(window)
window.cancelAnimationFrame = window.cancelAnimationFrame.bind(window)
在 manifest.json 中把这个文件放在 interact.js 前面:
{
"content_scripts": [
{
"js": ["firefox-fix.js", "interact.js"],
}
],
}