注: 本文完成时, Jetpack 版本为 1.7.
对于一个扩展来说,最主要的三部分为: (1).界面定制 (2).网页操作 (3).事件交互
1. 界面定制
Jetpack 摈弃了原来使用 XUL 进行界面开发的形式, 完全使用 Javascript 进行开发, 好处是 javascript 程序员可以很快上手, 缺点是现在可用的构件比 XUL 下要少好多很多. Jetpack 将操作界面的 Javascript 称为 "Add-on Code".
Add-on Code: 用来操作扩展界面上的元素的 javascript,
(1). 所有的 "Add-on Code" 应该放在根目录的 Lib 目录下, 例如 main.js.
(2). 在 Lib 下的 js 文件, 相互间可以通过 require 进行包含引用. 其自身通过 export 导出函数.
2. 网页操作
Jetpack 将操作网页的 Javascript 称为 "Content Script".
Content Scripts: 用来操作 Firefox 打开的 html 页面上元素的 javascript, 即我们一般意义所称的 javascript;
(1). 所有的 "content scripts" 应该放在根目录的 data 目录下, 例如 jquery.1.7.2.js.
(2). data 目录下的 js 文件可以通过一些组件, 如 page-mod, panel, widge 内置的 api 嵌入到 web 页面中.
(3). data 目录下的 js 文件不支持 require 来进行相互引用.
3. 事件交互
(1). 使用 Port
Add-on Code 与 Content Scripts 通过 EventEmitter 框架进行事件驱动. 其交互模式如下图:
(a). 添加事件: port.on(type, listener), type 指的是事件类型(包括 close, open, show 等, type 也可以是用户自定义事件, 但要保证和 emit 里的事件名称相一致), listener 指的是事件监听对象
(b). 移除事件: removeListener(type, listener), 参数同上
(c). 触发事件: port.emit(type,...), 参数同上. 注: type 后面的参数将被 json 化进行传递
注: port 的事件是异步进行发送的, 即其消息发送后就立退返回.
(2). 使用 postMessage
Jetpack 的 conetxt-menu 不支持 port 来进行事件交互, 必须使用 postMessage 来进行事件交互.[conetxt-menu 指的是页面(包括网页的页面和 panel 上内嵌的页面)上的右键菜单]
(a). 触发事件: self.postMessage(contentScriptMessage);
(b). 添加事件: self.on( "message", function(addonMessage) { // Handle the message } );
注: 使用 postMessage 时, 不再使用 port, 而是直接使用 self. 可以理解为: port 是用来区分用户自定义事件的 namespace, 凡是通过 port 进行 on 和 emit 的都是用户自定义事件.
由于我写的扩展里没有使用到 contex-menu, 所以对 postMessage 的理解不够深入, 这里就不展开来说了.
环境: Firefox13 + Jetpack 1.7