金喜正规买球

怎样在javascript中构建XPCOM组件?

原创|其它|编辑:郝浩|2009-03-11 10:47:37.000|阅读 1105 次

概述:这是一个在javascript中构建XPCOM组件"hello world"的教程。这个教程不会描述XPCOM是怎么工作或者为什么那么工作,也不打算对每一部分代码进行解释。这个会在其他文章里面祥述elsewhere. 这个教程展示给你用最少的步骤来完成一个能工作的组件的过程。

# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>

这是一个在javascript中构建XPCOM组件"hello world"的教程。这个教程不会描述XPCOM是怎么工作或者为什么那么工作,也不打算对每一部分代码进行解释。这个会在其他文章里面祥述. 这个教程展示给你用最少的步骤来完成一个能工作的组件的过程。

Caveat: This was done on a Mac. YMMV with Windows.

 

实现

这个组件将会公开一个方法,他返回"Hello World!".

定义接口

如果你想在JavaScript中用你的接口, 或者从其他 XPCOM components中调用, 你要定义一个公开接口 (如果你的组件仅仅用在Javascript中, 你可以使用 wrappedJSObject 技巧来避免这里所建立的接口. 参看 上的例子).

Mozilla应用中已经定义了很多接口,你可能不必再定义一个. 你可以浏览现有的Mozilla源代码里面的XPCOM接口,或者使用, 他是一个浏览注册接口和组件的GUI工具. 你可以下载旧的跟Firefox 1.5匹配的viewer,在.

如果一个现存的接口满足你的要求,那你就不需要再写一个IDL, 编译typelib, 可以直接跳过下一节 .

如果你没有发现现有的合适的接口,那你就要定义一个自己的。XPCOM使用一个IDL的修订版来定义接口, 叫做. 这里有一个XPIDL对HelloWorld组件的定义:

HelloWorld.idl

#include "nsISupports.idl"

[scriptable, uuid(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)]
interface nsIHelloWorld : nsISupports
{
string hello();
};

注意你要为每一个XPCOM组件建立一个UUID。参看。

编译 Typelib

你的接口定义必须编译成为二进制(XPT)以便于注册和在Mozilla应用中使用。编译可以利用Gecko SDK. Windows and Linux versions 的SDK可以从获取. 我编译了一个Mac version的SDK (1.8 branch, OS X PPC 10.4), 暂时放在 .

执行下面的命令来编译typelib. 其中, {sdk_dir}是你放置Gecko SDK的目录.

{sdk_dir}/bin/xpidl -m typelib -w -v -I {sdk_dir}/idl -e HelloWorld.xpt HelloWorld.idl

这将会在当前目录建立一个typelib文件HelloWorld.xpt.

建立组件

HelloWorld.js

/***********************************************************
constants
***********************************************************/

// reference to the interface defined in nsIHelloWorld.idl
const nsIHelloWorld = Components.interfaces.nsIHelloWorld;

// reference to the required base interface that all components must support
const nsISupports = Components.interfaces.nsISupports;

// UUID uniquely identifying our component
// You can get from: //kruithof.xs4all.nl/uuid/uuidgen here
const CLASS_ID = Components.ID("{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx}");

// description
const CLASS_NAME = "My Hello World Javascript XPCOM Component";

// textual unique identifier
const CONTRACT_ID = "@dietrich.ganx4.com/helloworld;1";

/***********************************************************
class definition
***********************************************************/

//class constructor
function HelloWorld() {
};

// class definition
HelloWorld.prototype = {

// define the function we want to expose in our interface
hello: function() {
return "Hello World!";
},

QueryInterface: function(aIID)
{
if (!aIID.equals(nsIHelloWorld) &&
 !aIID.equals(nsISupports))
throw Components.results.NS_ERROR_NO_INTERFACE;
return this;
}
};

/***********************************************************
class factory

This object is a member of the global-scope Components.classes.
It is keyed off of the contract ID. Eg:

myHelloWorld = Components.classes["@dietrich.ganx4.com/helloworld;1"].
createInstance(Components.interfaces.nsIHelloWorld);

***********************************************************/
var HelloWorldFactory = {
createInstance: function (aOuter, aIID)
{
if (aOuter != null)
throw Components.results.NS_ERROR_NO_AGGREGATION;
return (new HelloWorld()).QueryInterface(aIID);
}
};

/***********************************************************
module definition (xpcom registration)
***********************************************************/
var HelloWorldModule = {
_firstTime: true,
registerSelf: function(aCompMgr, aFileSpec, aLocation, aType)
{
aCompMgr = aCompMgr.
QueryInterface(Components.interfaces.nsIComponentRegistrar);
aCompMgr.registerFactoryLocation(CLASS_ID, CLASS_NAME,
CONTRACT_ID, aFileSpec, aLocation, aType);
},

unregisterSelf: function(aCompMgr, aLocation, aType)
{
aCompMgr = aCompMgr.
QueryInterface(Components.interfaces.nsIComponentRegistrar);
aCompMgr.unregisterFactoryLocation(CLASS_ID, aLocation);
},

getClassObject: function(aCompMgr, aCID, aIID)
{
if (!aIID.equals(Components.interfaces.nsIFactory))
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;

if (aCID.equals(CLASS_ID))
return HelloWorldFactory;

throw Components.results.NS_ERROR_NO_INTERFACE;
},

canUnload: function(aCompMgr) { return true; }
};

/***********************************************************
module initialization

When the application registers the component, this function
is called.
***********************************************************/
function NSGetModule(aCompMgr, aFileSpec) { return HelloWorldModule; }

安装

针对扩展:

  1. 复制 HelloWorld.js 和 HelloWorld.xpt 到 {extensiondir}/components/。
  2. 从你的 profile 目录里删除 compreg.dat 和 xpti.dat。
  3. 重启应用程序。

针对 Firefox:

  1. 如果运行于源码,请复制 HelloWorld.js 和 HelloWorld.xpt 到 {objdir}/dist/bin/components 目录。
  2. 从 components 目录删除 compreg.dat 和 xpti.dat。
  3. 从 profile 目录删除 compreg.dat 和 xpti.dat。
  4. 重启应用程序。

使用你的组件

try {
// this is needed to generally allow usage of components in javascript
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");

var myComponent = Components.classes['@dietrich.ganx4.com/helloworld;1']
.createInstance(Components.interfaces.nsIHelloWorld);

alert(myComponent.hello());
} catch (anError) {
alert("ERROR: " + anError);
}

标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@fc6vip.cn

文章转载自:mozillazine

为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP