Интернет, компьютеры, софт и прочий Hi-Tech

Подписаться через RSS2Email.ru

XUL XPCOM JavaScript

Принцип написания XPCOM компонента на JavaScript схож с принципом написания оного на C++. Однако, здесь в более явном виде используются понятия модуля и фабрики. Алгоритм действий прост:

  • создать XPIDL описание интерфейса, сгенерировать .xpt библиотеку;
  • создать JavaScript реализацию интерфейса, фабрики, модуля;
  • положить .xpt библиотеку и .js реализацию в каталог components нашего проекта.

Итак, приступим.

Содержание


Подготовка

Подготовка включает в себя все разделы вплоть до Генерация заголовка и xpt библиотеки включительно в статье XUL_XPCOM. Тут ничего не поменялось, кроме разве что GUID.

Пишем JavaScript XPCOM

Создаём файл IMyComponent.js с таким содержимым:

const Ci = Components.interfaces;

// константы, аналогично как в C++
const CLASS_ID    = Components.ID("b058921b-cdc2-43b3-8515-e2b9d6133263");
const CLASS_NAME  = "Simple JavaScript Componennt";
const CONTRACT_ID = "@mydomain.com/XPCOMSample/MyComponent;1";
const INTERFACE   = Ci.IMyComponent;

// Собственно наш компонент
function MyComponent() {}

MyComponent.prototype =
{
    // Метод сложения двух чисел, описанный в .idl файле
    Add: function(a, b)
    {
        return a + b;
    },

    // Мы также должны реализовать QueryInterface, чтобы
    // проверить правильность использования объекта. Это означает, что мы не
    // сможем использовать этот объект как указатель на интерфейс, который в нём
    // не реализован. Методы AddRef() и Release() из nsISupports не реализованы.
    QueryInterface: function(aIID)
    {
        // Мы знаем только о базовом интерфейсе nsISupports и нашем
        // IMyComponent, иначе выбрасываем исключение.
        if(!aIID.equals(INTERFACE) && !aIID.equals(Ci.nsISupports))
            throw Components.results.NS_ERROR_NO_INTERFACE;

        return this;
    }
};

// Наша фабрика, создаёт и возвращает синглетон MyComponent.
// Частично реализует интерфейс nsIFactory.
var MyComponentFactory =
{
    singleton: null,

    // Вызывается из скрипта для создания объекта XPCOM компонента
    createInstance: function(aOuter, aIID)
    {
        if(aOuter != null)
            throw Components.results.NS_ERROR_NO_AGGREGATION;

        // объект уже создан?
        if(this.singleton == null)
            this.singleton = new MyComponent();

        return this.singleton.QueryInterface(aIID);
    }
};

// Модуль, реализует интерфейс nsIModule, позволяет работать с нашей фабрикой
var MyComponentModule =
{
    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 MyComponentFactory;

        // Мы не смогли обработать запрос объекта, и ничего не знаем о
        // запрошенном интерфейсе.
        throw Components.results.NS_ERROR_NO_INTERFACE;
    },

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

// Главный загрузчик, должен возвращать объект нашего модуля
function NSGetModule(aCompMgr, aFileSpec) { return MyComponentModule; }

Запуск

Копируем .xpt библиотеку и .js файл в каталог components нашего XUL проекта, и создаём .xul файл абсолютно идентичный таковому из статьи Пишем XPCOM компонент на C++. Запуск и результат также должны совпадать с результатами из статьи Пишем XPCOM компонент на C++ - Вы должны увидеть окно с текстом 3 + 4 = 7 внутри.

Анализ

Как Вы видите, единственное отличие от предыдущей статьи в том, что XPCOM компонент реализован не на C++, а на JavaScript. Естественно, такие компоненты проще писать и сопровождать.

Ссылки

Источник статьи: http://www.linux.org.ru/wiki/en/XUL_XPCOM_JavaScript (08.09.2009)

Биржа долевых инвестиций SIMEX.

Последнее редактирование: 2009-09-10 08:13:44

Метки материала: XUL, XPCOM, JavaScript, XPIDL, интерфейс, xpt, js, COM, Компонентная объектная модель, Component Object Model, компоненты XPCOM, C++, интерфейсы, компонент, SDK, XULRunner, Gecko, Gecko SDK, XPConnect, объект, исходники, Mozilla, программирование

Оставьте, пожалуйста, свой комментарий к публикации

Представиться как     Антибот:
   

Просьба не постить мусор. Если вы хотите потестить xBB, воспользуйтесь кнопкой предварительного просмотра на панели инструментов xBBEditor-а.


© 2007-2017, Дмитрий Скоробогатов.
Разрешается воспроизводить, распространять и/или изменять материалы сайта
в соответствии с условиями GNU Free Documentation License,
версии 1.2 или любой более поздней версии, опубликованной FSF,
если только иное не указано в самих материалах.