Не удается создать службу Javascript XPCOM для расширения Firefox

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

Timestamp: 07/06/2012 09:23:28 Error: uncaught exception: [Exception... 
"Component returned failure code: 0x80570016 (NS_ERROR_XPC_GS_RETURNED_FAILURE)
[nsIJSCID.getService]"  nsresult: "0x80570016 (NS_ERROR_XPC_GS_RETURNED_FAILURE)"
location: "JS frame :: chrome://logger/content/logger.js :: <TOP_LEVEL> :: line 21"
data: no]

Я сократил компонент до минимума, используя отличный генератор шаблонов на ted.mielczarek.org. Код компонента следующий ...

const nsISupports = Components.interfaces.nsISupports;
const CLASS_ID = Components.ID("808e1607-caea-418c-b563-d9fe1df6ee08");
const CLASS_NAME = "Test component";
const CONTRACT_ID = "@test/loggerservice;1";

function LoggerService() {
  this.wrappedJSObject = this;
}

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

Остальная часть шаблона, который создает интерфейс модуля и фабрики, не изменилась.

Файл chrome.manifest выглядит так ...

content   logger                 chrome/content/
skin      logger   classic/1.0   chrome/skin/
locale    logger   en-US         chrome/locale/en-US/

component {808e1607-caea-418c-b563-d9fe1df6ee08} components/loggerservice.js
contract @test/loggerservice;1 {808e1607-caea-418c-b563-d9fe1df6ee08}

overlay chrome://browser/content/browser.xul chrome://logger/content/logger-overlay.xul
style   chrome://global/content/customizeToolbar.xul chrome://logger/skin/overlay.css

Наконец, файл logger-overlay.xul включает файл сценария - logger.js, который пытается получить ссылку на компонент LoggerService, используя следующий код ...

this.loggerService = Components.classes["@test/logger;1"].getService().wrappedJSObject;

и именно эта строка сообщает в консоли ошибок Firefox.

Я не представляю, насколько я могу это сделать проще - любое понимание было бы очень признательно.


person drew    schedule 07.06.2012    source источник


Ответы (1)


Это хороший шаблонный генератор, но, к сожалению, устаревший. Во-первых, вы должны использовать XPCOMUtils, это избавит от большей части шаблон. Что еще более важно, этот генератор шаблонов не был обновлен до изменений XPCOM в Gecko 2.0 и определяет функцию NSGetModule вместо NSGetFactory. Однако такой код модуля должен работать:

Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");

function LoggerService() {
  this.wrappedJSObject = this;
}

LoggerService.prototype = {
  classID: Components.ID("808e1607-caea-418c-b563-d9fe1df6ee08"),
  classDescription: "Test component",
  contractID: "@test/loggerservice;1",

  QueryInterface: XPCOMUtils.generateQI([])
}

if ("generateNSGetFactory" in XPCOMUtils)
  var NSGetFactory = XPCOMUtils.generateNSGetFactory([LoggerService]);  // 2.0+
else
  var NSGetModule = XPCOMUtils.generateNSGetModule([LoggerService]);    // 1.9.x

Вы можете удалить NSGetModule код, если ваше расширение не должно быть совместимо с Firefox 3.6. Вы также можете удалить свойства classDescription и contractID, они уже указаны в chrome.manifest.

Примечание. Если вам нужен только объект, который будет оставаться в течение всего сеанса просмотра и к которому можно будет получить доступ из любого места, тогда модуля кода JavaScript было бы лучшим выбором - никаких шаблонов XPCOM и никаких wrappedJSObject хаков.

person Wladimir Palant    schedule 07.06.2012
comment
Владимир - спасибо - высший совет! Теперь код стал намного чище с использованием XPCOMUtils. Наконец-то я могу продолжить и развивать свой сервис! - person drew; 07.06.2012