使用 ADD-ON SDK 开发 基于 Html JQuery 和 CSS 的 firefox 插件入门教程1: 创建一个简单的 Add-on

时间:2024-01-20 13:18:51

【本文转载自http://sixpoint.me/942/implementing-simple-addon/】

实现一个简单的插件

教程的这个部分带你使用 SDK 来实现, 运行并打包一个插件. 这个插件在 Firefox 的右键菜单中添加一个菜单项, 用来将选中的文字翻译成英语.

插件的初始化

创建一个叫做 translator 的文件夹, 用来放置插件所需的所有文件.

你并不需要在 SDk 的根目录下创建这个文件夹. 一旦你在 SDK 的根目录执行了 bin\activate (win) 或者 source bin/activate (*nux), cfx 就会记住 SDK 的位置, 从而让你可以在任何位置引用到 SDK.

所以将插件目录和 SDK 目录分开比较好, 这样你就可以方便的升级 SDK 并且方便你的代码的版本管理.

接着使用 cfx init 命令来为你的插件创建一个基础框架. 定位到 translator 目录并执行 cfx init. 你会看到类似下面的输出:

1
2
3
4
5
6
7
8
9
10
11
12
  * lib directory created
  * data directory created
  * test directory created
  * doc directory created
  * README.md written
  * package.json written
  * test/test-main.js written
  * lib/main.js written
  * doc/main.md written
Your sample add-on is now ready for testing:
      try "cfx test" and then "cfx run". Have fun!"

首先, cfx init 创建了插件所需的基本的目录:

  • /data 包含 HTML, 图标等资源文件, 以及插件中所有的 content scripts 文件.你可以从插件的代码中使用 add-on SDK 的 self 模块来访问 data 子目录.
  • /doc 包含插件的文档
  • /lib 包含实现插件的 JavsScript 文件.
  • /test 包含测试代码

接着, cfx init 在 translator 插件的根目录创建创建了一个叫做 package.json 的文件. 它包含了插件的信息, 内用如下:

{
“name”:”translator”,
“fullName”:”translator”,
“description”:”This is an example of addon description.”,
“author”:”",
“license”:”MPL”,
“version”:”0.1″
}

最后, cfx init 在 doc, lib, test 目录下创建了一下示例文件, 我们会替换它们.

添加代码

在 lib 目录下, 打开 main.js 文件并替换成下面的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// 导入所需 APIs
var contextMenu = require("context-menu");
var request = require("request");
var selection = require("selection");
  
exports.main = function(options, callbacks) {
  console.log(options.loadReason);
  
  // 创建一个新右键菜单项
  var menuItem = contextMenu.Item({
  
    label: "Translate Selection",
  
    // 当有选中内容时, 显示这个菜单项
  
    context: contextMenu.SelectionContext(),
  
    // 当点击这个菜单项时, 发送一个包含选中内容和当前 URL 的信息( message)
    contentScript: 'self.on("click", function () {' +
                   '  var text = window.getSelection().toString();' +
                   '  self.postMessage(text);' +
                   '});',
  
    // 当接收到这个 message 后, 调用 Google Translate API 将选中内容替换成对应的翻译内容
    onMessage: function (text) {
      if (text.length === 0) {
        throw ("Text to translate must not be empty");
      }
      console.log("input: " + text);
      var req = request.Request({
        content: {
          v: "1.0",
          q: text,
          langpair: "|en"
        },
        onComplete: function (response) {
          translated = response.json.responseData.translatedText;
          console.log("output: " + translated);
          selection.text = translated;
        }
      });
      req.get();
    }
  });
};
  
exports.onUnload = function (reason) {
  console.log(reason);
};

导入模块 (modules)

前三行用来从 addon-kit 包中导入三个 SDK 模块:

  • context-menu 允许插件添加右键菜单项
  • request 允许插件提交网络请求
  • selection 允许插件访问活动浏览器窗口中选中的内容

创建一个右键菜单项

接着, 上面的代码创建了一个右键菜单项. 它提供了:

  • 要显示菜单项的名称: “Translate Selection”
  • 这个菜单项要显示在哪个右键菜单中: SelectionContext(). 含义: 当页面上有内容被选中时的右键菜单.
  • 当点击这个菜单项时要执行的代码: 这段代码将选中的内容发送到分配给 onMessage 属性的函数
  • onMessage 属性的值: 这个函数将被选中的内容作为参数, 在用户点击该菜单项时被调用. 它使用 Google 基于 AJAX 的翻译服务将选中的内容翻译成英文, 并将选中的内容替换成翻译后的结果.

监听 Load 和 Unload

创建右键菜单项的代码包含在一个分配给全局对象 exports 的 main 属性的一个函数中.

如果你的插件 exports 一个叫做 main 的函数, 那么这个函数会在插件加载 (load) 的时候调用.

1
exports.main = function (options, callbacks) {};

options 是一个对象, 它描述你的插件是以什么参数来加载的. 特别的, options.loadReason 是下面字符串中的一个,
用来描述你的插件加载的原因: install, enable, startup, upgrade, 或者 downgrade.

相反的, 如果你的插件 exports 一个叫做 onUnload 的函数, 那么那个函数会在插件 unloaded 的时候调用.

1
exports.onUnload = function (reason) {};

reason 是下面字符串中的一个, 用来描述插件 unloaded 的原因: uninstall, disable, shutdown, upgrade, 或者 downgrade.

你可以不必使用 exports.main 或者 exports.onUnloaded. 你可以只是把你的插件的代码放置到最高层,
而不是把代码包含在一个分配给 exports.main 的函数中. 它同样会被加载, 但是你就不能访问 options 或者 callbacks
参数了.

Logging

注意这里调用了 console.log() 函数. console 是一个可以被所有模块访问的全局对象, 通过它你可以输出错误, 警告, 或者提示信息.

对于一个已经打包成 xpi 文件并安装到 Firefox 中的插件来说, 这些 log 信息被发送到 Firefox 的 Error Console. 如果你使用 cfx 从命令行启动的 Firefox, 用来开发和调试, 这些信息会被发送到你启动 Firefox 的命令行终端.

要了解更多关于 console 对象的内容, 参见文档.

运行

要运行你写的插件程序, 定位到 translator 目录并输入:

1
cfx run

你第一次输入的时候会显示如下信息:

1
2
No 'id' in package.json: creating a new ID for you.
package.json modified: please re-run 'cfx run'

不用管它, 再运行一次就会一个安装着你的插件的 Firefox 实例了.

你第一次执行 cfx run 时 cfx 生成的 ID 是你的插件的一个重要的唯一标识符, 叫做 Program ID. 它被许多其他工具和服务用来区分不同的插件.

参考 Program ID, 了解更多.

一旦 cfx run 启动了 Firefox, 你就可以使用你的插件了. 打开一个包含非英语内容的页面, 选择一些文字内容, 然后右击打开右键菜单. 你会看到一个叫做 “Translate Selection” 的菜单项.

使用 ADD-ON SDK 开发 基于 Html JQuery 和 CSS 的 firefox 插件入门教程1: 创建一个简单的 Add-on

选择那个菜单项, 这是你选中的内容应该会被翻译成英语了:

使用 ADD-ON SDK 开发 基于 Html JQuery 和 CSS 的 firefox 插件入门教程1: 创建一个简单的 Add-on

在控制台终端中, 我们会看到如下的信息:

1
2
3
4
5
6
7
8
9
10
11
info: input: Le projet Mozilla est une communauté mondiale de personnes
qui pensent que l'ouverture, l'innovation et la saisie des chances qui nous
sont offertes sont les clés de la vitalité d'Internet. Nous travaillons
ensemble depuis 1998 pour nous assurer qu'Internet se développe d'une manière
qui bénéficie à tout le monde. On nous connaît surtout pour la création du
navigateur Web Mozilla Firefox.
info: output: The Mozilla project is a global community of people who believe
that openness, innovation and seizing opportunities offered to us are the
keys to the vitality of the Internet. We have been working together since
1998 to ensure that the Internet develops in a way that benefits everyone.
We are best known for creating the Mozilla Firefox Web browser.

准备部署插件:

一旦你的插件测试完成, 就可以将它打包, 像其他插件一样部署了. Add-on SDK 简化了打包部署的这一过程.

要打包你的插件, 定位到你的插件的根目录并在控制台输入 cfx xpi. 你会看到如下信息:

1
Exporting extension to translator.xpi.

这时, 在你执行命令的这个目录下, 就可以看到 translator.xpi 文件了.

安装插件

通过将插件安装到 Firefox 中来测试这个安装包的正确性.

Ctrl+O 打开一个文件选择对话框, 选择之前生成的 translator.xpi 文件, 打开它并安装该插件.

发布

要发布你的插件, 可以将它上传到 addons.mozilla.org