使用XPCOM

开始使用XPCOM的最好方法是,看客户端怎么使用XPCOM。尤其是当你要设计接口给其他人使用时。
像Mozilla浏览器的应用程序复杂,模块化的客户XPCOM组件,实际上,几乎用到的所有的功能,包括 导航、窗口管理、cookies管理,书签, 安全、搜索、渲染和其他特性都是定义为XPCOM组件并通过接口访问。Mozilla由XPCOM组件构成。本章演示了Mozilla怎么使用XPCOM组件,比如Cookie Manager,和怎么定义访问WebLock组件。

Component Examples

Cookie Manager

Cookie管理器是XPCOM组件形式的浏览器可用的功能之一,开发者可以在自己的程序中重用。当用户访问Cookie管理对话框浏览,组织或者删除系统存储的cookies时,使用的就是Cookie管理组件。
使用XPCOM_第1张图片
该对话框用XUL 和JavaScript来编写,使用XPConnect连接Cookie管理组件,XUL是公开Cookie管理组件的方法之一,这在Mozilla的世界是很有用的。Cookie管理组件的功能通过nsICookieManager接口使用,其公共方法如下:
 The nsICookieManager Interface
removeAll                           从cookie列表中删除所有的cookie
enumerator                         枚举cookie列表
remove                                删除特定的cookie
在XPCOM的接口中,即使底层实现变了,接口保证不变。接口是公开的,换句话说,实现是私有的。当用户选择一个cookies并点击删除,就会调用nsICookieManager中的remove    方法。方法由Cookie管理组件实施,选中的cookie会被从cookie列表删除。
以下代码显示怎么用javascript调用Cookie管理组件的remove删除cookie。
// xpconnect to cookiemanager
// get the cookie manager component in JavaScript
var cookiemanager = Components.classes["@mozilla.org/
cookiemanager;1"].getService();
cookiemanager = cookiemanager.QueryInterface
(Components.interfaces.nsICookieManager);
// called as part of a largerDeleteAllCookies() function
function FinalizeCookieDeletions() {
for (var c=0; c<deletedCookies.length; c++) {
cookiemanager.remove(deletedCookies[c].host,
deletedCookies[c].name,
deletedCookies[c].path);
}
deletedCookies.length = 0;
}
这并不是全部,当然,这显示了 XPCOM的重要的一方面。XPCOM强制打开了二进制互操作性的契约安排,使得可以在运行时访问,使用和重用XPCOM组件。也使得可以使用其他语言编写的组件,JavaScript, Python, 和其他,或者从其他语言调用基于C++的XPCOM组件。
在Mozilla浏览器中,JavaScript经常用到组件。一个关于Mozilla代码的调查显示,Cookie管理组件只被javascript调用。

The WebBrowserFind Component

组件到处都在用,在高级的浏览器功能,例如,nsWebBrowserFind,提供了 find() 和findNext()方法来在网页中进行查找内容,在低级的任务中,例如数据操作。虽然不是每个Mozilla的API函数都是或者应该是XPCOM的,如果不是浏览器提供的典型功能在组件中可以用,可以通过浏览器扩展进行重用。除了Cookie管理组件之外,WebBrowserFind组件也是可以用的浏览器一组大的接口,nsIWebBrowserFind提供的方法如下:
findNext                    查找下一个出现查找字符串
findBackwards         布尔值属性,调整findNext()向后查找
searchFrames            布尔值属性,表明是否查找当前文档的子框架
matchCase              布尔值属性,表明是否区分大小写
entireWord                布尔值属性,表明是否匹配整个字符串
一旦你有接口获取组件,就可以询问组件支持其他哪些接口。这种服务,定义在nsISupports基本的接口,并被所有XPCOM组件实现,它允许你查询并转换组件的接口,作为XPCOM的运行时对象类型功能的一部分。它有QueryInterface方法处理,

The WebLock Component

现在我们来看 WebLock 组件,在面向对象编程中,通常先定义接口, 定义的功能提供的是抽象的,,不担心功能是怎么实现的,所以我们把实现的细节放在一边。 WebLock组件的接口如下:
lock                                        把浏览器锁定到当前网站
unlock                                   浏览器解锁,可以无限制的使用
addSite                                添加新的网站到白名单
removeSite                          从白名单中删除一个网站
sites                                     枚举白名单的网站
WebLock组件以接口定义的方式实现了所有的这些方法。当浏览器启动时注册自己,并提供一个创建自身实例的工厂,当用户或管理员点击weblock图标时。

Component Use in Mozilla

在Mozilla中如何获得并使用组件的。在本章的前面部分你已经看到部分JavaScript代码片段,但是并没有解释通常怎么用XPCOM组件。本节讨论Mozilla实际的组件,分为三个部分:一个是在Mozilla查找二进制组件,另外两个是使用XPCOM组件的两种主要方法。
• “Finding Mozilla Components”
• “Using XPCOM Components in Your C++”
• “XPConnect: Using XPCOM Components From Script”


Finding Mozilla Components

本书提供了关于XPCOM组件和接口的相关知识。Mozilla也提供了一些工具可以查询和显示Gecko中可用的接口的信息,例如XPCOM Component Viewer,为未来的客户创建好的XPCOM组件信息的挑战在于冻结接口而实现不断变化的过程。 Component Viewer 不区分哪些组件的接口是冻结的。在LXR代码中,冻结的接口用@status frozen 标记。

XPCOM Component Viewer是一个浏览器插件,
使用XPCOM_第2张图片

Using XPCOM Components in Your C++

XPConnect使得XPCOM组件很容易当作javascript对象来访问,但是在 C++ 用XPCOM组件不用那么麻烦。
nsCOMPtr<nsIServiceManager> servMan;
nsresult rv = NS_GetServiceManager(getter_AddRefs(servMan));
if (NS_FAILED(rv))
return -1;
nsCOMPtr<nsICookieManager> cookieManager;
rv = servMan->GetServiceByContractID("@mozilla.org/cookiemanager",
NS_GET_IID(nsICookieManager), getter_AddRefs(cookieManager));
if (NS_FAILED(rv))
return -1;
PRUint32 len;
deletedCookies->GetLength(&len);
for (int c=0; c<len; c++)
cookiemanager->Remove(deletedCookies[c].host,
deletedCookies[c].name,
deletedCookies[c].path);

如果你的程序是用C++写的,上面的代码显示了怎么一步步使用XPCOM组件,指定你想用的组件的接口,然后调用接口的方法。

XPConnect: Using XPCOM Components From Script

本章开头的Cookie管理组件给我们进一步讨论从javascript使用XPCOM组件提供了一个很好的机会,以下代码显示用 getService()创建一个单例的Cookie管理组件,
var cookiemanager = Components.classes["@mozilla.org/
cookiemanager;1"].getService();
cookiemanager = cookiemanager
.QueryInterface(Components.interfaces.nsICookieManager);
function loadCookies() {
// load cookies into a table
var enumerator = cookiemanager.enumerator;
var count = 0;
var showPolicyField = false;
while (enumerator.hasMoreElements()) {
var nextCookie = enumerator.getNext();
nextCookie = nextCookie.QueryInterface
(Components.interfaces.nsICookie);
....
}
function FinalizeCookieDeletions() {
for (var c=0; c<deletedCookies.length; c++) {
cookiemanager.remove(deletedCookies[c].host,
deletedCookies[c].name,
deletedCookies[c].path,
}
deletedCookies.length = 0;
}
















你可能感兴趣的:(gecko,XPCOM)