帮我创建一个Firefox扩展(Javascript XPCOM组件)

9
我一直在看不同的教程,我知道我已经接近成功了,但是由于一些教程有点过时,而且自从Firefox 3以来有些东西已经改变了,所以我在实现细节上有些迷茫。我已经编写了firefox扩展的javascript代码,现在我需要将它转换成XPCOM组件。
这是我需要的功能: 我的Javascript文件很简单,我有两个函数startServer()stopServer。我需要在浏览器启动时运行startServer(),并在Firefox退出时运行stopServer()

编辑:

我已经更新了我的代码,并得到了一个可行的解决方案(感谢Neil)。以下是在MyExtension/components/myextension.js中的内容。

Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
const CI = Components.interfaces, CC = Components.classes, CR = Components.results;

// class declaration
function MyExtension() {}

MyExtension.prototype = {
    classDescription: "My Firefox Extension",
    classID:          Components.ID("{xxxx-xxxx-xxx-xxxxx}"),
    contractID:       "@example.com/MyExtension;1",
    QueryInterface: XPCOMUtils.generateQI([CI.nsIObserver]),

    // add to category manager
    _xpcom_categories: [{
        category: "profile-after-change"
    }],

    // start socket server
    startServer: function () { /* socket initialization code */ },

    // stop socket server
    stopServer: function () { /* stop server */ },


    observe: function(aSubject, aTopic, aData) 
    {
        var obs = CC["@mozilla.org/observer-service;1"].getService(CI.nsIObserverService);

        switch (aTopic) 
        {
            case "quit-application":
                this.stopServer();
                obs.removeObserver(this, "quit-application");
                break;
            case "profile-after-change":
                this.startServer();
                obs.addObserver(this, "quit-application", false);
                break;
            default:
                throw Components.Exception("Unknown topic: " + aTopic);
        }
    }
};

var components = [MyExtension];

function NSGetModule(compMgr, fileSpec) {
    return XPCOMUtils.generateModule(components);
}
1个回答

5
据我所知,您的所有代码都要放进组件中。
您需要一个JavaScript对象来表示您的组件,并将其注册到组件注册器中。(它可以是一个新对象,也可以是一个多任务的现有对象。)这样做的方式取决于您是否针对Firefox 3.x还是Firefox 4。
您需要使用类别管理器注册profile-after-change通知。这样做的方式也取决于您是针对Firefox 3、Firefox 3.5/6还是Firefox 4。
profile-after-change通知触发时,您的组件就会被创建并调用observe方法。这是您启动服务器并请求观察退出应用程序通知的地方。请注意,这也调用了observe方法,因此它必须检查它正在接收哪个通知。
function myExt() {}
myExt.prototype = {
  observe: function(aSubject, aTopic, aData) {
    switch (aTopic) {
      case "quit-application":
        stopServer();
        obs.removeObserver(this, "quit-application");
        break;
      case "profile-after-change":
        startServer();
        obs.addObserver(this, "quit-application", false);
        break;
    }
  }
};

我已经更新了我的代码,包括到目前为止的更改。该组件已在compreg.dat中注册,但是observe:函数没有被调用。 - David
那么,compreg.dat文件在a) [COMPONENTS]、b) [CLASSIDS]、c) [CONTRACTIDS]和d) [CATEGORIES]中是否都有您组件的条目? - Neil
是的,我终于让它工作了,方法是不使用XPCOMUtils模块进行查询接口和XPCOM注册。我必须编写更多的代码,但我仍然很好奇为什么在使用该模块时它不能正常工作。 - David
谢谢您的更新,让我意识到您的 QueryInterface 广告了错误的接口,您需要将 nsIObserver 作为您的接口之一进行广告。 - Neil
谢谢你发现了这个问题,那正是我遇到的困难。 - David
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接