编写Firefox扩展

编写Firefox扩展

FireFox和Thunderbird有很好的扩展架构,你可以通过XML和ECMAScript结合的方式而不用通过编写C程序的方式来编写扩展

在这个Blog里面,我将会看看如何创建一个简单的扩展,这个扩展将一个“Hello World”菜单项添加到FireFox的Tools菜单中。

Creating contents.rdf

contents.rdf是一个资源描述框架Resource Description Framework (RDF)文件,这个文件描述了扩展的内容,RDF采用了XML语法,它提供了一个可以让应用程序非常容易处理的数据模型。如果你编写简单的扩展,你不需要对E\RDF有很多的了解,但是如果感兴趣的话,你需要从W3C获得更多信息。

首先,创建一个名称为content的目录,这个目录将包含扩展主要的内容(Content)。contents.rdf要放在这个目录下面。你需要创建一个如下所示的目录结构:

c:\myextensions\

+- helloworld

+- content

+- contents.rdf

下面是 contents.rdf.的代码

<?xml version="1.0"?>

<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"

xmlns:chrome="http://www.mozilla.org/rdf/chrome#">



<RDF:Seq about="urn:mozilla:package:root">

<RDF:li resource="urn:mozilla:package:helloworld"/>

</RDF:Seq>



<RDF:Description about="urn:mozilla:package:helloworld"

chrome:displayName="Hello World"

chrome:author="Brian Duff"

chrome:authorURL="http://modev.dubh.org/helloworld"

chrome:name="helloworld"

chrome:extension="true"

chrome:description="A simple demonstration firefox extension.">

</RDF:Description>



<RDF:Seq about="urn:mozilla:overlays">

<RDF:li resource="chrome://browser/content/browser.xul"/>

</RDF:Seq>



<RDF:Seq about="chrome://browser/content/browser.xul">

<RDF:li>chrome://helloworld/content/helloworld-Overlay.xul</RDF:li>

</RDF:Seq>



</RDF:RDF>

这个文件的重要部分(也是每个扩展需要改变的部分)用粗体显示出来。我们为扩展提供了一个包(package)。这个包就使这个扩展与其它扩展区别开来,在这里我们选择helloworld包:

<RDF:Seq about="urn:mozilla:package:root">

<RDF:li resource="urn:mozilla:package:helloworld"/>

</RDF:Seq>

接下来,我们为这个扩展提供一个描述:

<RDF:Description about="urn:mozilla:package:helloworld"

chrome:displayName="Hello World"

chrome:author="Brian Duff"

chrome:authorURL="http://modev.dubh.org/helloworld"

chrome:name="helloworld"

chrome:extension="true"

chrome:description="A simple demonstration firefox extension.">

</RDF:Description>

下面,我们告诉mozilla产品的那个部分是我们需要扩展的。FireFox以及ThunderBird的所有的用户界面元素是通过一个称为XUL的界面定义语言描述的。这次界面元素被称为“chrome”。你可以扩展这两个产品的大多数可以部分。在这里,我们要扩展FireFox的浏览器主界面。定义为:

chrome://browser/content/browser.xul

<RDF:Seq about="urn:mozilla:overlays">

<RDF:li resource="chrome://browser/content/browser.xul"/>

</RDF:Seq>

现在我们已经描述了我们想扩展什么,我们需要提供一个XUL文件来将我们的自定义用户界面安装到浏览器窗口中。我们将在后面再一个helloworld-Overlay.xul文件中定义这些。我们必须告诉mozilla文件在什么地方以及它扩展了什么:

<RDF:Seq about="chrome://browser/content/browser.xul">

<RDF:li>chrome://helloworld/content/helloworld-Overlay.xul</RDF:li>

</RDF:Seq>

我们已经完成了创建扩展的第一步,下面的任务是定义我们要安装到主窗口中的用户界面元素。

Overlaying User Interface Elements

XUL是XML用户界面语言。XUL提供了一种称为 dynamic overlays 的结构,这种结构可以让你在不修改原始XUL文件的情况下修改窗口或者控件的用户界面元素。This way, the definition of extension user interface is de-coupled from the XUL files used to define the main interface elements in Firefox and Thunderbird。

我们开始创建 helloworld-Overlay.xul. 这个文件应该与 contents.rdf. 位于同一个目录。

<?xml version="1.0"?>



<overlay id="helloworldOverlay"

xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">



<menupopup id="menu_ToolsPopup">

<menuitem label="Hello World" position="1" />

</menupopup>



</overlay>

这个简单的范例在Tools菜单的顶部创建了一个“Hello world”的菜单项。我们的菜单项定义在了menupopup元素中。在XUL中,menupopup表示了一个菜单项的容器,例如一个弹出菜单或者一个主菜单的下拉项,我们在menupopup中放置了一个id为menu_ToolsPopup的菜单项。这个menu_ToolsPopup,在browser.xul中定义并且对应Tools菜单的下拉部分。

Creating an Install Manifest

最近版本的FireFox以及Thunderbird包含了一个新的扩展管理工具,这个工具可以轻松的安装和管理扩展。要告诉扩展管理工具关于你的扩展的一些信息,你必须写另外一个RDF文件叫做install.rdf。这个文件应该位于contents目录同级的位置中:

c:\myextensions\

+- helloworld

+- install.rdf

+- content

+- contents.rdf

+- helloworld-Overlay.xul



下面是安装的清单文件:

<?xml version="1.0"?>



<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"

xmlns:em="http://www.mozilla.org/2004/em-rdf#">



<Description about="urn:mozilla:install-manifest">



<em:name>Hello World</em:name>

<em:id>{12a1584b-2123-473d-8752-e82e74e3cb1b}</em:id>

<em:version>0.1</em:version>



<em:targetApplication>

<Description>

<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>

<em:minVersion>0.9</em:minVersion>

<em:maxVersion>1.0</em:maxVersion>

</Description>

</em:targetApplication>



<em:file>

<Description about="urn:mozilla:extension:file:helloworld.jar">

<em:package>content/</em:package>

</Description>

</em:file>



</Description>



</RDF>

首先,我们提供一个扩展的描述。这些描述信息会显示在Firefox的扩展管理工具中:

<em:name>Hello World</em:name>

<em:id>{12a1584b-2123-473d-8752-e82e74e3cb1b}</em:id>

<em:version>0.1</em:version>

在em:id部分中的内容是全局唯一标示(GUID)。这个GUID的目的是为了将你的扩展与其它扩展区分开来。当你在编写你自己的扩展时,你总要为每个单独的扩展产生一个新的GUID。Hoskinson提供了一个GUID generator web service。可以用它来产生GUID。

下面,我们描述我们要扩展哪个应用程序:

<em:targetApplication>

<Description>

<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>

<em:minVersion>0.9</em:minVersion>

<em:maxVersion>1.0</em:maxVersion>

</Description>

</em:targetApplication>

每个Mozilla下的可扩展应用程序都有一个自己的GUID:你必须在这里正确的指定你所要扩展的程序的那个GUID。在本例中,我们使用FireFox的GUID。我们同时描述这个扩展可以工作的Firefox的最低和最高版本。

最后,我们告诉扩展管理工具需要安装的文件。下面,我将介绍如何将扩展打包以便可以自动安装到Firefox中:

<em:file>

<Description about="urn:mozilla:extension:file:helloworld.jar">

<em:package>content/</em:package>

</Description>

</em:file>

Packaging an Extension Installer

我们的扩展现在已经完成了。但是为了让用户可以更容易的安装它,我们需要将它打包以便Firefox安装。我们需要将上面的文件打包到一个XPI(Cross platform installer)文件中。一个XPI文件就是一个普通的zip 文件。我们的XPI文件的结构如下所示:

helloworld.xpi

+- install.rdf

+- chrome/

+- helloworld.jar

helloworld.jar是另外一个包含我们创建在content目录中所有文件的zip文件。

helloworld.jar

+- content/

+- contents.rdf

+- helloworld-Overlay.xul

通过上面的信息,我们可以通过zip工具创建helloworld.xpi。另外,你也可以通过类似Ant这样的build工具来编译这些文件,下面是我使用的Ant build文件:

<?xml version="1.0"?>



<project name="helloworld" default="createxpi">



<target name="createjar">

<zip destfile="helloworld.jar" basedir="."

includes="content/**" />

</target>



<target name="createxpi" depends="createjar">

<zip destfile="helloworld.xpi">

<zipfileset dir="." includes="helloworld.jar"

prefix="chrome" />

<zipfileset dir="." includes="install.rdf" />

</zip>

</target>



</project>

如果创建了名称为build.xml的build文件并且将它放到与install.rdf同级的目录中,你可以直接运行ant来创建.xpi文件。当创建xpi文件后,你可以在Firefox的File->Open中安装这个扩展。

Download the source code (24KB ZIP file).
posted on 2008-09-22 12:32  jannock  阅读(934)  评论(0编辑  收藏  举报