浅谈基于Mozilla ThunderBird的扩展开发

我目前主要从事基于Mozilla ThunderBird邮件客户端的扩展开发,可惜国内对于基于Mozilla平台的扩展开发关注度很小,而且其中大部分都是做基于firefox下的扩展。当然不可否认的是,其实两者区别不是很大,毕竟是基于同样的Mozilla内核构建起来的。

以前虽然对firefox的扩展性有所耳闻,但也只是听说而已,没有任何研究。这几天对于ThunderBird的一些研究让我对Mozilla这个平台肃然起敬,其UI和逻辑分离,高度可扩展性的思想确实很棒。但由于资料稀少,研究的人也不多,造成像我一样的新手望而却步,一开始为了编译成功其源代码,为了实现一个最简单的“hello world”扩展都耗费了大量的时间和精力(我读各种各样的文档就花了一周的时间了,累死了),更有甚者,因为得不到资料方面的支持,放弃了对这个平台的研究。

本文的目的就是希望能为像我这样希望进入这个平台的新手们提供一个敲门砖

对于Mozilla平台下的thunderbirdfirefox的源代码编译问题,请参考我这篇文章:

Window下编译ThunderBird源代码

Thunderbirdfirefox的编译方法都是一样,只是参数不同而已,请记住,对我们来说最重要的是Mozilla平台。

此外,再介绍一个优秀的基于Thunderbird的扩展--Enigmail,对于我们新手来说,阅读前辈的代码不失为一个好方法。它的编译方法见我这篇文章:

Windows下编译Enigmail源代码

好了,现在开始进入正题,如何基于Mozilla平台开发一个简单的扩展呢?先来谈谈涉及到的技术:

1)XUL:它是“XML化的用户界面语言(XML User Interface Language的缩写,这是一种以平台无关性为目标,用来描述用户界面的语言,现在被广泛地应用于 Mozilla 平台。再有,Mozilla 本身的界面就是用 XUL 进行描述的。

2)CSS:它是层叠样式表(Cascading Style Sheets的缩写,这是一种可以通过规则来控制 HTML/XUL/XML 等显示外观的语言。

上述两种技术是用来负责控制程序的界面,一个是用来描述界面,一个用来在被描述的界面上加入一些界面效果(如:字体颜色,是否透明,边框大小等)

3)DOM:它是文档对象模型(Document Object Model的缩写,这是一个允许通过脚本来动态访问和更新 HTML/XML 文档的内容,结构和样式的接口。

DOM 主要用来为 JavaScritp 提供一个 HTML/XML 的文档操作接口,并且,它也可以用来操作 CSS。由于扩展的界面是由 XUL 定义的,而 XUL 只是 XML 的一个特殊应用,所以我们也可以通过 DOM 来对扩展界面进行动态操作(如:按钮的禁止与否,动态装载数据等)。同时,又有许多的文件和数据会采用 XML 进行存储和传输,所以创建和分析 XML 文档又显得尤为重要。通过 DOM 接口,我们可以将程序的逻辑处理部分与界面表现部分有机的结合起来。

4XPCOM:它是跨平台组件对象模型(Cross -platform Component Object Model的缩写,它很像微软的提出的组件模型技术,但它是跨平台的,即其运行环境可以不依赖于某种特定的操作系统平台。

由于 JavaScript 语言只内置了几个与本地访问无关的对象,而对于桌面开发来说,显然不能满足要求。而 XPCOM 为面向桌面的开发提供了这种可能,并且它使开发出的扩展程序可以跨平台的运行,而不用依赖于某个特殊的操作系统。只有使用 XPCOM,我们的扩展才可以做出实用的功能,没有 XPCOM,本地与远程的资源整合可以说是不可能。虽然扩展开发是用 JavaScript 来做的,但每个封装的对象或函数可能都要调用 XPCOM 对象来完成特定的功能。

5)XPConnect:一种将 XPCOM JavaScript 连接起来的技术。该技术允许组件被脚本化,而且能够用 JavaScript 来进行组件的开发。

6)XBL:它是可扩展绑定语言 Extensible Binding Language的缩写。

7)RDF:它是资源定义框架(Resource Definition Framework的缩写。Mozilla 使用这种文件格式来保存扩展的注册信息和描述信息等。

8)JavaScript:使用 JavaScript 开发扩展是编程语言的首选。JavaScipt 是扩展开发的核心部分,它主要用来实现程序的业务逻辑描述,起着粘合剂一样的功能。可以说,从网页下的 JavaScript 开发到扩展下的 JavaScript 开发,是一种由轻量级到重量级的转变。

其中很多东西想必大家都熟悉,可有一点不同值得注意,在Mozilla平台下不是用这些东西来做网页之类的,而是进行桌面开发!确切地说,开发的扩展都是面向桌面应用的程序。

对于更为详细的介绍,请参阅基于 Mozilla 的扩展开发,可以说这篇文章是目前国内对Mozilla平台最为出色的技术文章了,值得我们好好研究。我这里也是大部分结合他这篇文章在thunderbird上完成开发的。

作者的一篇文章,却帮助了无数像我这样的新手,在这里特别向作者Lewis Lv致敬!

好了,现在我们开始进入”Hello World”的世界!先看看我们要实现的效果图,就是在thunderbird的菜单中插入我们自定义的菜单项.
浅谈基于Mozilla ThunderBird的扩展开发

项目的结构如下:

浅谈基于Mozilla ThunderBird的扩展开发helloworld/
浅谈基于Mozilla ThunderBird的扩展开发chrome
.manifest
浅谈基于Mozilla ThunderBird的扩展开发install
.rdf
浅谈基于Mozilla ThunderBird的扩展开发chrome
/
浅谈基于Mozilla ThunderBird的扩展开发helloworld
/
浅谈基于Mozilla ThunderBird的扩展开发content
/
浅谈基于Mozilla ThunderBird的扩展开发contents
.rdf
浅谈基于Mozilla ThunderBird的扩展开发overlay
.js
浅谈基于Mozilla ThunderBird的扩展开发overlay
.xul
浅谈基于Mozilla ThunderBird的扩展开发


负责注册 Chrome 的文件chrome.manifest 的内容如下:

浅谈基于Mozilla ThunderBird的扩展开发overlaychrome://messenger/content/mailWindowOverlay.xulchrome://helloworld/content/overlay.xul
浅谈基于Mozilla ThunderBird的扩展开发contenthelloworldjar:chrome/helloworld.jar!/content/
浅谈基于Mozilla ThunderBird的扩展开发

install.rdf 的内容如下:

浅谈基于Mozilla ThunderBird的扩展开发<?xmlversion="1.0"?>
浅谈基于Mozilla ThunderBird的扩展开发
<RDFxmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
浅谈基于Mozilla ThunderBird的扩展开发xmlns:em
="http://www.mozilla.org/2004/em-rdf#">
浅谈基于Mozilla ThunderBird的扩展开发
浅谈基于Mozilla ThunderBird的扩展开发
<Descriptionabout="urn:mozilla:install-manifest">
浅谈基于Mozilla ThunderBird的扩展开发
<em:id>{241b5bc7-a8aa-44a6-a18d-3054dc6047cf}</em:id>
浅谈基于Mozilla ThunderBird的扩展开发
<em:name>HelloWorld</em:name>
浅谈基于Mozilla ThunderBird的扩展开发
<em:version>1.0</em:version>
浅谈基于Mozilla ThunderBird的扩展开发
<em:type>2</em:type>
浅谈基于Mozilla ThunderBird的扩展开发
<em:creator>phinecos</em:creator>
浅谈基于Mozilla ThunderBird的扩展开发
<em:description>”helloworlddemo”</em:description>
浅谈基于Mozilla ThunderBird的扩展开发
<em:homepageURL>http://kb.mozillazine.org/Getting_started_with_extension_development</em:homepageURL>
浅谈基于Mozilla ThunderBird的扩展开发
浅谈基于Mozilla ThunderBird的扩展开发
<em:targetApplication>
浅谈基于Mozilla ThunderBird的扩展开发
<!--Thunderbird-->
浅谈基于Mozilla ThunderBird的扩展开发
<Description>
浅谈基于Mozilla ThunderBird的扩展开发
<em:id>{3550f703-e582-4d05-9a08-453d09bdfdc6}</em:id>
浅谈基于Mozilla ThunderBird的扩展开发
<em:minVersion>2.0</em:minVersion>
浅谈基于Mozilla ThunderBird的扩展开发
<em:maxVersion>2.0.0.*</em:maxVersion>
浅谈基于Mozilla ThunderBird的扩展开发
</Description>
浅谈基于Mozilla ThunderBird的扩展开发
</em:targetApplication>
浅谈基于Mozilla ThunderBird的扩展开发
浅谈基于Mozilla ThunderBird的扩展开发
<!--ThisisnotneededforFirefox1.1andlater.Onlyincludethis
浅谈基于Mozilla ThunderBird的扩展开发ifyouwanttomakeyourextensioncompatiblewitholderversions
-->
浅谈基于Mozilla ThunderBird的扩展开发
<em:file>
浅谈基于Mozilla ThunderBird的扩展开发
<Descriptionabout="urn:mozilla:extension:file:helloworld.jar">
浅谈基于Mozilla ThunderBird的扩展开发
<em:package>content/</em:package>
浅谈基于Mozilla ThunderBird的扩展开发
</Description>
浅谈基于Mozilla ThunderBird的扩展开发
</em:file>
浅谈基于Mozilla ThunderBird的扩展开发
</Description>
浅谈基于Mozilla ThunderBird的扩展开发
</RDF>
浅谈基于Mozilla ThunderBird的扩展开发

上面的<em:id>{<chmetcnv unitname="F" sourcevalue="3550" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on"></chmetcnv>241b5bc7-a8aa-44a6-a18d-3054dc6047cf}</em:id>中的id号是一个GUID,你可以用微软的 guidgen.exe 工具来生成的。

contents.rdf 的内容如下:


浅谈基于Mozilla ThunderBird的扩展开发<?xmlversion="1.0"?>
浅谈基于Mozilla ThunderBird的扩展开发
<RDF:RDFxmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
浅谈基于Mozilla ThunderBird的扩展开发xmlns:chrome
="http://www.mozilla.org/rdf/chrome#">
浅谈基于Mozilla ThunderBird的扩展开发
浅谈基于Mozilla ThunderBird的扩展开发
<RDF:Seqabout="urn:mozilla:package:root">
浅谈基于Mozilla ThunderBird的扩展开发
<RDF:liresource="urn:mozilla:package:helloworld"/>
浅谈基于Mozilla ThunderBird的扩展开发
</RDF:Seq>
浅谈基于Mozilla ThunderBird的扩展开发
浅谈基于Mozilla ThunderBird的扩展开发
<!--packageinformation-->
浅谈基于Mozilla ThunderBird的扩展开发
<RDF:DescriptionRDF:about="urn:mozilla:package:helloworld"
浅谈基于Mozilla ThunderBird的扩展开发chrome:name
="helloworld"
浅谈基于Mozilla ThunderBird的扩展开发chrome:extension
="true"
浅谈基于Mozilla ThunderBird的扩展开发chrome:displayName
="HelloWorld"
浅谈基于Mozilla ThunderBird的扩展开发chrome:author
="phinecos"
浅谈基于Mozilla ThunderBird的扩展开发chrome:authorURL
="http://kb.mozillazine.org/Getting_started_with_extension_development"
浅谈基于Mozilla ThunderBird的扩展开发chrome:description
="TheClassicalDemoWithHelloWorld">
浅谈基于Mozilla ThunderBird的扩展开发
</RDF:Description>
浅谈基于Mozilla ThunderBird的扩展开发
浅谈基于Mozilla ThunderBird的扩展开发
<!--overlayinformation-->
浅谈基于Mozilla ThunderBird的扩展开发
<RDF:Seqabout="urn:mozilla:overlays">
浅谈基于Mozilla ThunderBird的扩展开发
<RDF:liresource="chrome://messenger/content/mailWindowOverlay.xul"/>
浅谈基于Mozilla ThunderBird的扩展开发
</RDF:Seq>
浅谈基于Mozilla ThunderBird的扩展开发
浅谈基于Mozilla ThunderBird的扩展开发
<RDF:Seqabout="chrome://messenger/content/mailWindowOverlay.xul">
浅谈基于Mozilla ThunderBird的扩展开发
<RDF:li>chrome://helloworld/content/overlay.xul</RDF:li>
浅谈基于Mozilla ThunderBird的扩展开发
</RDF:Seq>
浅谈基于Mozilla ThunderBird的扩展开发
</RDF:RDF>
浅谈基于Mozilla ThunderBird的扩展开发


下面,让我们看一下“Hello World” overlay.xul 实现。

浅谈基于Mozilla ThunderBird的扩展开发<?xmlversion="1.0"?>
浅谈基于Mozilla ThunderBird的扩展开发
<overlayid="helloworld-overlay"
浅谈基于Mozilla ThunderBird的扩展开发xmlns
="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
浅谈基于Mozilla ThunderBird的扩展开发
<scripttype="application/x-javascript"src="overlay.js"/>
浅谈基于Mozilla ThunderBird的扩展开发
浅谈基于Mozilla ThunderBird的扩展开发
<menubarid="mail-menubar">
浅谈基于Mozilla ThunderBird的扩展开发
<menuid="MyAboutMenu"label="About"insertbefore="tasksMenu">
浅谈基于Mozilla ThunderBird的扩展开发
<menupopupid="menu_TestAbout">
浅谈基于Mozilla ThunderBird的扩展开发
<menuitemid="helloworld-hello"label="Hello,world!"oncommand="helloWorld();"/>
浅谈基于Mozilla ThunderBird的扩展开发
</menupopup>
浅谈基于Mozilla ThunderBird的扩展开发
</menu>
浅谈基于Mozilla ThunderBird的扩展开发
</menubar>
浅谈基于Mozilla ThunderBird的扩展开发
</overlay>
浅谈基于Mozilla ThunderBird的扩展开发

overlay.js负责定义 helloWorld 函数

浅谈基于Mozilla ThunderBird的扩展开发functionhelloWorld()
浅谈基于Mozilla ThunderBird的扩展开发浅谈基于Mozilla ThunderBird的扩展开发
浅谈基于Mozilla ThunderBird的扩展开发{
浅谈基于Mozilla ThunderBird的扩展开发alert(
"Hello,world!");
浅谈基于Mozilla ThunderBird的扩展开发}

浅谈基于Mozilla ThunderBird的扩展开发

好了,这个最简单的扩展就完成了,接下来就是如何安装了,在这个阶段我个人遇到了很大的阻力,浪费了许多精力在找问题上,希望朋友们别走后路,呵呵。

第一步,先要将扩展从目录形式转换为 XPI 安装包形式,所使用的打包工具就是 ZIP 压缩软件。常用的 ZIP 压缩软件有 WinRARWinZIP;记得必须将扩展按下面的格式进行打包:

浅谈基于Mozilla ThunderBird的扩展开发helloworld.xpi/
浅谈基于Mozilla ThunderBird的扩展开发chrome
.manifest
浅谈基于Mozilla ThunderBird的扩展开发install
.rdf
浅谈基于Mozilla ThunderBird的扩展开发chrome
/
浅谈基于Mozilla ThunderBird的扩展开发helloworld
.jar/
浅谈基于Mozilla ThunderBird的扩展开发content
/
浅谈基于Mozilla ThunderBird的扩展开发contents
.rdf
浅谈基于Mozilla ThunderBird的扩展开发overlay
.js
浅谈基于Mozilla ThunderBird的扩展开发overlay
.xul
浅谈基于Mozilla ThunderBird的扩展开发

这里我要说一句,在用WinRAR打包时,最好一开始都打包成zip格式,再修改格式为jarxpi,否则安装时总是会报错,我在这里就耗费了大量时间,摸索了大半天才发现这个可行的方法,

浅谈基于Mozilla ThunderBird的扩展开发

最后当然是安装了,点击thunderbird工具“—”附加软件,就可以从本地xpi文件安装这个”hello world”插件了.


Reference:

1, 基于 Mozilla 的扩展开

2, http://developer.mozilla.org/en/docs/Main_Page

3, http://enigmail.mozdev.org/download/source.php