作为当下最流行的浏览器之一,firefox不仅提供了可靠的日常功能及安全的信息访问,同时它还为开发人员提供了方便的接口,使得开发人员对于firefox的扩展变得更为容易。
因为目前正在项目的间歇期,而下一个项目可能会涉及到firefox的扩展开发,于是我便打算利用这段空闲时间,好好学习一下。
首先需要弄清楚两个概念: Extension和Plugin。
单从字面上讲,Extension表意扩展,而plugin则是插件的意思。Plugins are different from extensions, which modify or enhance the functionality of the browser itself. 在我的理解是,Extension是对firefox功能上的拓展,通过Extension,我们可以向firefox用户提供新的功能,或者是不同于以往的浏览器体验。Plugin则是为了改变或是改善浏览器已有的功能,是对firefox自身的一种改变或者说提高。
而对于我来说,所要关注的就是Extension的开发了。
首先当然还是从hello world 开始。Mozilla的开发中心提供了一个可以注册下载的Extension Wizard,其中包含了一个简单的extension包,我们可以以此为开发基础。下图是extension包中的文件结构:
<ext path>\
install.rdf
chrome.manifest
chrome\
content\
先不去看Mozilla的介绍文档,我们先大致看下这些文件里面都有什么内容。首先是install.rdf:
<?xml version="1.0" encoding="UTF-8"?>
<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:id>huang@yao</em:id>
<em:name>huang</em:name>
<em:version>1.0</em:version>
<em:creator>yao</em:creator>
<em:description>My first extension</em:description>
<em:targetApplication>
<Description>
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id> <!-- firefox -->
<em:minVersion>1.5</em:minVersion>
<em:maxVersion>3.0.*</em:maxVersion>
</Description>
</em:targetApplication>
</Description>
</RDF>
从名字上我们可以猜测这个文件是用来提供安装信息给firefox的,里面的内容也证实了这个推断。
<em:id>huang@yao</em:id>,是这个扩展包的ID,用来唯一标志我们当前创建的扩展包。 格式上要求是email格式,但不必是真实的邮件地址。
<em:type>2</em:type>,扩展包的类型,可能有多种类型,但在这里,我们一般设置为2即可。
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>, 该irefox的应用程序ID,关于这一点,我还没能在Mozilla的网站上找到更详细的介绍,以后会细化这部分。
<em:minVersion>1.5</em:minVersion>,扩展包所能支持的firefox最低版本号。
<em:maxVersion>3.0.*</em:maxVersion>, 相应的,扩展包所能支持的最高版本号。
在https://developer.mozilla.org/en/Install_Manifests 中有着完整的属性列表。
再看第二个文件,chrome.manifest。从名字上我们可以认为,这个文件是用来提供安装和打包时所需资源的一个集合。以下是其中的代码:
content huang content/
locale huang en-US locale/en-US/
skin huang classic/1.0 skin/
overlay chrome://browser/content/browser.xul chrome://huang/content/firefoxOverlay.xul
content huang content/, 这行很好理解,这个扩展包里的content在content/相对地址huang的文件夹中。
相应的locale en-US的相关文件在locale/en-US/中。
皮肤文件skin/中。
最后一行有点奇怪,overlay,字面上的意思是覆盖,那么是用第二个参数来覆盖第一个参数? chrome这个协议名又是怎么回事?后一个文件或许还可以理解为当前content文件夹下的firefoxOverlay.xul文件,那前一个文件是哪里的呢? xul又是什么类型的文件? 带着这些问题,我们继续看下去。
XUL
Firefox的扩展包是用XUL和javascript来写的,XUL是一种基于xml文件格式的,用于提供用户界面及控件的语言。结合js相应用户行为的能力,两者便形成了extension的核心内容。
为了扩展浏览器,我们需要通过增加或是删除控件的方式来修改浏览器的UI。而正如刚才所说的,有两种办法来修改浏览器的UI,一是通过添加XUL 的DOM空间,另一个是通过JS来处理事件。
而我们刚才所提到的chrome://browser/content/browser.xul这样一个xul文件就是Firefox浏览器自己默认的UI形式。我们可以在这个文件夹下找到它:
$FIREFOX_INSTALL_DIR/chrome/browser.jar contains content/browser/browser.xul
打开这个文件,我们可以看到其实它就是一个XML格式的,最外层是是个window的节点,里面包含了许多attributes以及子节点。我们来看看它都有哪些子节点:
script: 类似于HTML中的定义,script节点用来引入其他脚本或脚本文件。注意,这里的代码源都是以chrome开头的,现在我们只知道chrome是一种类协议名,但还不清楚它究竟是做什么用的
<script type="..." src="chrome://..."/>
stringbundleset: stringbundle容器,包含一个或多个stringbundle, 用来为为XUL文件提供字符串常量。
<stringbundleset id="stringbundleset">
<stringbundle id="bundle_brand" src="chrome://..."/>
</stringbundleset>
commandset: command容器,包含一个或多个command, 为整个window提供时间处理中心。
<commandset id="mainCommandSet">
<command id="cmd_newNavigator" oncommand="OpenBrowserWindow()"/>
</commandset>
broadcasterset:broadcaster的容器, 当你想要多个元素共享属性值,或者响应某个状态改变时,就会用到broadcaster。任何订阅了同一个broadcast的元素,都可以访问其中的属性,或是当状态发生变化时接收来是broadcaster的通知,并进行相应的操作。
<broadcasterset id="mainBroadcasterSet">
<broadcaster id="viewBookmarksSidebar" autoCheck="false" label="&bookmarksButton.label;"
type="checkbox" group="sidebar" sidebarurl="chrome://browser/content/bookmarks/bookmarksPanel.xul"
oncommand="toggleSidebar('viewBookmarksSidebar');"/>
</broadcasterset>
剩下的那些节点都是跟用户界面有关的了,将在以后的篇章里进行介绍。