読み込んでいます...
2009年04月14日

在前面我们说了Firefox的一些结构以及Firefox项目的开发方法和运行流程。现在,基本上Firefox开发的过程,方法我相信已经有了一个大概的框架,一般人都能够通过前面的几篇文章简单的制作出一些应用。OK,但是如果动手做的同学们就会发现,我这个插件好像还是什么也干不了啊,也不能读写文件,也不能动态加载什么的,当然,这要看你的需求了,如果你只是点几下,跳转网页什么的,当然不必,因为功能实在太弱了,而如果要做动态书签,在线收藏夹等等,就没有那么简单了,要与本地文件,远程HTML联系,客户端,服务器联系等等做一些复杂的操作,就需要使用XPCOM。我们首先需要知道XPCOM是什么,官方给我们了一个这样的解释。。

XPCOM is a cross platform component object model, similar to Microsoft COM. It has multiple language bindings, letting the XPCOM components be used and implemented in JavaScript, Java, and Python in addition to C++. Interfaces in XPCOM are defined in a dialect of IDL called XPIDL. (here)

上面一句话就是说的是XPCOM是一个跨平台的组件对象模型,和微软的COM组件类似,可以绑定多个语言,包括 JavaScript,Java,Python和C++。其实XPCOM在使用中,更多的是一些API,例如读写文件,获取浏览器的应用程序或者扩展的基本信息,都需要使用XPCOM进行获取。

一般来说,我们可以使用Firefox已经给我们提供好的XPCOM组件进行开发,而且Firefox也提供了很多功能,包括文件读写,本地文件夹创建,浏览器事件获取,组件管理等等,高深的东西我们暂时不用去探讨,因为我也不知道。。所以我们后面再说。

我们了解了基本的XPCOM的概念之后,就可以看看已经为我们提供的XPCOM的API,可以到这个页面去看,我们可以看到已经有很多现成的API提供给我们了,包括nsCategoryManager,nsDirectoryService,nsLocalFile等等,这些分别是类别管理,目录管理和本地文件管理等API。同样我们可以打开一个API去查看,例如nsLocalFile,我们可以看到申明的方法。

var file =
    Components.classes["@mozilla.org/file/local;1"].
    createInstance(Components.interfaces.nsILocalFile); 

我们再仔细看看上面那段代码,其中"@mozilla.org/file/local;1"是ContractID,而 Components.interfaces.nsILocalFile类名,其中Components.interfaces是接口的统称,这应该很好理解。而申明后,我们的file变量就是一个XPCOM变量了,要知道这个接口都有什么属性和方法,我们可以另外查nsILocalFile接口就行了,然后就可以像Javascript或者C++一样使用了,至于怎么使用,当然是面向对象了,如果你连这个概念都不知道的话,那我也没办法了。

另外,在使用XPCOM做开发的时候,我们还可以使用一个比较实用的类,在Firefox里叫FUEL。FUEL的官方解释如下。

FUEL is a JavaScript Library designed to help developers build extensions using terminology and interfaces that are familiar to them. FUEL is new in Firefox 3.

也就是说FUEL是一个JavaScript的类库,是为了能够更加方便的让开发人员去开发一个扩展,而且FUEL对开发人员来说是非常容易上手的。值得注意的是,FUEL只在Firefox 3里面有效。

其实说白了,FUEL也基本上来说是XPCOM的又一个封装(如果我理解没错的话,至少我这么认为),FUEL提供了很多对象,包括 Application,Bookmark,Extension等等,而这里面Application是根对象,其他的都是从Application对象中“派生出来”的,我们可以使用FUEL提供的申明方法去申明。

var Application =
    Components.classes["@mozilla.org/fuel/application;1"].
    getService(Components.interfaces.fuelIApplication);

而我们要获取Extension对象的时候,就必须使用现有的Application对象来获取,我们可以看到Application对象中包括extension属性,所以我们可以使用Application.extension属性获取Extension对象,后面的我就不用说了,Extension对象有get方法,那么就可以直接使用Application.extension.get获取。

我们可以看到Application还有方法,例如这里有restart方法,我们执行这个方法后,Firefox就会重启,所以,XPCOM就是一种高于 XUL界面设计和Javascript基本的开发的更高的一种抽象,Firefox Team将这些类库封装起来提供开发人员让开发人员能够更好的开发扩展(虽然不是那么好用),我们后面会用XPCOM进行一些操作,当然,在这之前,确保你真的理解了这一章我在说什么。

PS:XPCOM一开始确实很不好理解,我甚至都快看到Firefox源代码了,才理解了,但是理解之后,又觉得不是很难理解,所以说难者不会,会者不难。

  1. wangyi @

    请问在调试xpi的时候,有没有方法让载入的xpi直接被浏览器安装,不用等个三四秒,也不用重启?

  2. wangyi @

    今天是我学习ff开发的第二天,看到这里感觉就是使用xpcom就是为了引入对象,最主要的就是通过生成某个类的实例来调用一些已经被写好的方法,这样理解对吗?
    不过今天遇到些问题,看了网上教程中的几个实例,试着运行下发现都不能与ff3.0兼容,于是自己改了改,但发现js根本没被调用到。(我在xul中script标签里已经链接了相应的js)不知道是不是因为格式不对,因为netbean自带的例子中的js写法有点怪,是先写函数名,然后冒号然后在一对小括号里放参数列表,再写方法体,而实例中的函数写法则是JavaScript里函数的标准写法。问了一个人如何去debug,别人告诉我写alert语句,我晕死,根本调试不了,还望高人指点。

  3. 诡异的西红柿 @

    [q]请问在调试xpi的时候,有没有方法让载入的xpi直接被浏览器安装,不用等个三四秒,也不用重启?[/q]
    我想应该不行,这是FF本身的东西。。

  4. 诡异的西红柿 @

    [q] 今天是我学习ff开发的第二天,看到这里感觉就是使用xpcom就是为了引入对象,最主要的就是通过生成某个类的实例来调用一些已经被写好的方法,这样理解对吗。。。[/q]
    这样理解是对的,XPCOM就是引入API而已。。
    你网上的实例我不知道是怎样的,但是我想如果正确的写是应该没有问题的,可能是你的js写的有问题。。
    另外,debug暂时也只有那个alert的方法,没有更好的方法的说。。现在js的debug也很难。。VS2008能够debug js都已经拿特性来说了。。

  5. 诡异的西红柿 @

    我建立你在写之前好好了解和熟悉一下js,应该会很有用的,呵呵。。

  6. wangyi @

    可是我是直接拷贝的例子中js的源码啊?js中就一个函数,我在这个函数体的第一句我就写了个alert,但根本无法触发相应的事件,说明整个程序运行时根本就没进入到主窗体对应的js文件。我copy的实例是这个网上教程里的,
    http://tech.ddvip.com/2008-10/122325604573906_6.html
    我可以把我的源代码发到你邮箱里,希望能够给予指点,不胜感激。今天够郁闷的,连有现成源代码的都无法做好插件,这开发就进行不下去了。

  7. wangyi @

    看网上写有一款叫firebug的软件用于调试不错,下了下来,但还不太会用,不知道你使用了那个软件没?

  8. wangyi @

    请问你平时用不用msn之类的即时聊天工具啊?

  9. 诡异的西红柿 @

    [q]看网上写有一款叫firebug的软件用于调试不错,下了下来,但还不太会用,不知道你使用了那个软件没?[/q]
    我没用这个软件。。

  10. 诡异的西红柿 @

    [q]请问你平时用不用msn之类的即时聊天工具啊?[/q]
    不怎么用,都是工作的时候才用的,很少看,而且我也很少加陌生人的,呵呵,不好意思啊。。

  11. wangyi @

    非常感谢你的回复,那个问题我早上一起来看了你的评论后就搞定了,不过有个地方没很好的理解,我在主窗体对应的js文件最后模仿overlay.js写了这样一句:
    window.addEventListener("load", 方法名称, false);
    最后发现要不要这句话都可以,请问这是怎么回事呢?前面的文章里你有写到:
    “在扩展加载的时候,默认情况下并不会加载一些方法,在HTML有onload方法,虽然Firefox的扩展也支持,但是在默认情况下是不支持的,我们必须添加以下代码让扩展在加载时支持我们需要的方法。”
    看来主窗体对应的js里的函数是默认会被加载的了,但哪些是默认情况下不会加载的方法,如何区分?

  12. 诡异的西红柿 @

    我的意思是onload方法本身是支持的。。。只有window.addEventListener("load", 方法名称, false)这样的会在默认的时候加载,只要你不申明,所有的代码都不会被加载,你总要告诉xul文件一个入口才行。。

  13. wangyi @

    请问一下js中变量是不是只能在函数体内声明,不能作为成员变量在类内方法体外声明吗?

  14. wangyi @

    例子中的options.xul没有相应的js啊?

  15. wangyi @

    请问下,对于网页的跳转能够在后台处理吗?我给你发邮件了,麻烦能不能看下,不是需要调试的问题。想寻找一种解决方案,把网页跳转的过程隐藏起来。

  16. 置顶的更新 : GuoJing's Blog | 用心对待每一行代码 @

    [...] Firefox Add-on – XPCOM初探 [...]

:-D :-? 8) :cry: 8-O :lol: :-x :-| :?: :-P :oops: :roll: :( :) :-o :wink: more »