Помогите мне создать расширение Firefox (компонент Javascript XPCOM)

Я просматривал разные руководства и знаю, что близок к этому, но я теряюсь в деталях реализации, потому что некоторые из них немного устарели, а некоторые вещи изменились по сравнению с Firefox 3. У меня уже есть написал javascript для расширения Firefox, теперь мне нужно превратить его в компонент XPCOM.

Это функциональность, которая мне нужна: мой файл Javascript простой, у меня есть две функции startServer() и stopServer. Мне нужно запустить startServer() при запуске браузера и stopServer() при закрытии браузера.

Редактировать:

Я обновил свой код рабочим решением (спасибо Нилу). Следующее находится в 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);
}

person Community    schedule 29.01.2011    source источник


Ответы (1)


Насколько я могу судить, весь ваш код входит в ваш компонент.

Вам нужен объект JavaScript, представляющий ваш компонент, и зарегистрируйте его в регистраторе компонентов. (Это может быть новый объект или вы можете выполнять несколько задач одновременно с существующим.) То, как это делается, зависит от того, нацелен ли вы на Firefox 3.x или Firefox 4.

Вам необходимо зарегистрироваться для получения profile-after-change уведомления с помощью диспетчера категорий. То, как это делается, также зависит от того, нацелен ли вы на Firefox 3, Firefox 3.5 / 6 или Firefox 4.

Когда срабатывает уведомление о профиле после изменения, ваш компонент создается и вызывается метод наблюдения. Здесь вы запускаете свой сервер и просите просмотреть уведомление о выходе из приложения. Обратите внимание, что это также вызывает метод наблюдения, поэтому он должен проверить, какое уведомление он получает.

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;
    }
  }
};
person Neil    schedule 29.01.2011
comment
До сих пор я обновил свой код своими изменениями. Компонент зарегистрирован в compreg.dat, но функция наблюдения: не вызывается. - person David; 30.01.2011
comment
Итак, есть ли в compreg.dat записи для вашего компонента во всех разделах а) [КОМПОНЕНТЫ] б) [КЛАССИДЫ] в) [КОНТРАКТИДЫ] г) [КАТЕГОРИИ]? - person Neil; 31.01.2011
comment
Да, я наконец-то заставил его работать, не используя модуль XPCOMUtils для интерфейса запросов и регистрации XPCOM. Мне пришлось написать намного больше кода, но мне все еще любопытно, почему он не работал, когда я использовал модуль. - person David; 31.01.2011
comment
Спасибо за это обновление, оно заставило меня понять, что ваш QueryInterface рекламировал неправильный интерфейс, вам нужно рекламировать nsIObserver как (один из) ваших интерфейсов. - person Neil; 31.01.2011
comment
Спасибо, что уловили это. Это была моя проблема. - person David; 31.01.2011
comment
Обратите внимание, что XPCOMUtils.generateQI автоматически предполагает, что nsISupports является одним из интерфейсов, которые вы хотите рекламировать, поэтому вам не нужно упоминать об этом явно. Только если вы напишете свой собственный метод QueryInterface, вам потребуется явно поддерживать nsISupports. - person Neil; 31.01.2011
comment
Я этого не знал, спасибо. Если что-то еще я делаю неправильно, не стесняйтесь комментировать. - person David; 31.01.2011
comment
Строка wrappedJSObject полезна для отладки, но вы можете не захотеть оставлять ее в готовом расширении. Также nsIMyExtension и его typelib могут не понадобиться, но я не могу сказать наверняка. - person Neil; 01.02.2011
comment
Да, это правда, мне не нужна библиотека типов, но из этого руководства я понял (возможно, ошибочно ), что если я не предоставляю интерфейс, мне нужно вставить строку wrappedJSObject. Я протестирую без него. - person David; 01.02.2011
comment
Вам нужна только библиотека типов или wrappedJSObject, чтобы предоставить настраиваемый доступ к вашему объекту из других объектов. В этом случае единственный доступ, который нужен к вашему объекту, - это запускать уведомления наблюдателя, для которых nsIObserver является правильным интерфейсом. - person Neil; 01.02.2011