<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>http://lorwiki.zhbert.ru/index.php?action=history&amp;feed=atom&amp;title=XUL%2FXPCOM_%28JavaScript%29</id>
	<title>XUL/XPCOM (JavaScript) - История изменений</title>
	<link rel="self" type="application/atom+xml" href="http://lorwiki.zhbert.ru/index.php?action=history&amp;feed=atom&amp;title=XUL%2FXPCOM_%28JavaScript%29"/>
	<link rel="alternate" type="text/html" href="http://lorwiki.zhbert.ru/index.php?title=XUL/XPCOM_(JavaScript)&amp;action=history"/>
	<updated>2026-10-12T23:39:27Z</updated>
	<subtitle>История изменений этой страницы в вики</subtitle>
	<generator>MediaWiki 1.39.0</generator>
	<entry>
		<id>http://lorwiki.zhbert.ru/index.php?title=XUL/XPCOM_(JavaScript)&amp;diff=233&amp;oldid=prev</id>
		<title>Admin: 1 версия импортирована</title>
		<link rel="alternate" type="text/html" href="http://lorwiki.zhbert.ru/index.php?title=XUL/XPCOM_(JavaScript)&amp;diff=233&amp;oldid=prev"/>
		<updated>2023-02-27T18:39:16Z</updated>

		<summary type="html">&lt;p&gt;1 версия импортирована&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;ru&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Предыдущая версия&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Версия от 21:39, 27 февраля 2023&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;ru&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(нет различий)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://lorwiki.zhbert.ru/index.php?title=XUL/XPCOM_(JavaScript)&amp;diff=232&amp;oldid=prev</id>
		<title>lor&gt;Cetjs2: /* Подготовка */</title>
		<link rel="alternate" type="text/html" href="http://lorwiki.zhbert.ru/index.php?title=XUL/XPCOM_(JavaScript)&amp;diff=232&amp;oldid=prev"/>
		<updated>2018-10-11T10:45:40Z</updated>

		<summary type="html">&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;Подготовка&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая страница&lt;/b&gt;&lt;/p&gt;&lt;div&gt;Принцип написания XPCOM компонента на JavaScript схож с принципом написания оного на C++. Однако, здесь в более явном виде используются понятия модуля и фабрики. Алгоритм действий прост:&lt;br /&gt;
&lt;br /&gt;
* создать XPIDL описание интерфейса, сгенерировать &amp;lt;tt&amp;gt;.xpt&amp;lt;/tt&amp;gt; библиотеку;&lt;br /&gt;
* создать JavaScript реализацию интерфейса, фабрики, модуля;&lt;br /&gt;
* положить &amp;lt;tt&amp;gt;.xpt&amp;lt;/tt&amp;gt; библиотеку и &amp;lt;tt&amp;gt;.js&amp;lt;/tt&amp;gt; реализацию в каталог &amp;lt;tt&amp;gt;components&amp;lt;/tt&amp;gt; нашего проекта.&lt;br /&gt;
&lt;br /&gt;
Итак, приступим.&lt;br /&gt;
&lt;br /&gt;
== Подготовка ==&lt;br /&gt;
Подготовка включает в себя все разделы вплоть до «Генерация заголовка и xpt библиотеки» включительно в статье [[XUL/XPCOM]]. Тут ничего не поменялось, кроме разве что GUID.&lt;br /&gt;
&lt;br /&gt;
== Пишем JavaScript XPCOM ==&lt;br /&gt;
Создаём файл &amp;lt;tt&amp;gt;IMyComponent.js&amp;lt;/tt&amp;gt; с таким содержимым:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
const Ci = Components.interfaces;&lt;br /&gt;
&lt;br /&gt;
// константы, аналогично как в C++&lt;br /&gt;
const CLASS_ID    = Components.ID(&amp;quot;b058921b-cdc2-43b3-8515-e2b9d6133263&amp;quot;);&lt;br /&gt;
const CLASS_NAME  = &amp;quot;Simple JavaScript Componennt&amp;quot;;&lt;br /&gt;
const CONTRACT_ID = &amp;quot;@mydomain.com/XPCOMSample/MyComponent;1&amp;quot;;&lt;br /&gt;
const INTERFACE   = Ci.IMyComponent;&lt;br /&gt;
&lt;br /&gt;
// Собственно наш компонент&lt;br /&gt;
function MyComponent() {}&lt;br /&gt;
&lt;br /&gt;
MyComponent.prototype =&lt;br /&gt;
{&lt;br /&gt;
    // Метод сложения двух чисел, описанный в .idl файле&lt;br /&gt;
    Add: function(a, b)&lt;br /&gt;
    {&lt;br /&gt;
        return a + b;&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    // Мы также должны реализовать QueryInterface, чтобы&lt;br /&gt;
    // проверить правильность использования объекта. Это означает, что&lt;br /&gt;
    // мы не сможем использовать этот объект как указатель на интерфейс, который в нём&lt;br /&gt;
    // не реализован. Методы AddRef() и Release() из nsISupports не реализованы.&lt;br /&gt;
    QueryInterface: function(aIID)&lt;br /&gt;
    {&lt;br /&gt;
        // Мы знаем только о базовом интерфейсе nsISupports и нашем IMyComponent,&lt;br /&gt;
        // иначе выбрасываем исключение.&lt;br /&gt;
        if(!aIID.equals(INTERFACE) &amp;amp;&amp;amp; !aIID.equals(Ci.nsISupports))&lt;br /&gt;
            throw Components.results.NS_ERROR_NO_INTERFACE;&lt;br /&gt;
&lt;br /&gt;
        return this;&lt;br /&gt;
    }&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// Наша фабрика, создаёт и возвращает синглетон MyComponent.&lt;br /&gt;
// Частично реализует интерфейс nsIFactory.&lt;br /&gt;
var MyComponentFactory =&lt;br /&gt;
{&lt;br /&gt;
    singleton: null,&lt;br /&gt;
&lt;br /&gt;
    // Вызывается из скрипта для создания объекта XPCOM компонента&lt;br /&gt;
    createInstance: function(aOuter, aIID)&lt;br /&gt;
    {&lt;br /&gt;
        if(aOuter != null)&lt;br /&gt;
            throw Components.results.NS_ERROR_NO_AGGREGATION;&lt;br /&gt;
&lt;br /&gt;
        // объект уже создан?&lt;br /&gt;
        if(this.singleton == null)&lt;br /&gt;
            this.singleton = new MyComponent();&lt;br /&gt;
&lt;br /&gt;
        return this.singleton.QueryInterface(aIID);&lt;br /&gt;
    }&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// Модуль, реализует интерфейс nsIModule, позволяет работать с нашей фабрикой&lt;br /&gt;
var MyComponentModule =&lt;br /&gt;
{&lt;br /&gt;
    registerSelf: function(aCompMgr, aFileSpec, aLocation, aType)&lt;br /&gt;
    {&lt;br /&gt;
        aCompMgr = aCompMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);&lt;br /&gt;
        aCompMgr.registerFactoryLocation(CLASS_ID, CLASS_NAME, CONTRACT_ID, aFileSpec, aLocation, aType);&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    unregisterSelf: function(aCompMgr, aLocation, aType)&lt;br /&gt;
    {&lt;br /&gt;
        aCompMgr = aCompMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);&lt;br /&gt;
        aCompMgr.unregisterFactoryLocation(CLASS_ID, aLocation);&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    getClassObject: function(aCompMgr, aCID, aIID)&lt;br /&gt;
    {&lt;br /&gt;
        // Абсолютно неправильное использование объекта модуля.&lt;br /&gt;
        // В принципе, такого не должно возникать.&lt;br /&gt;
        if(!aIID.equals(Components.interfaces.nsIFactory))&lt;br /&gt;
            throw Components.results.NS_ERROR_NOT_IMPLEMENTED;&lt;br /&gt;
&lt;br /&gt;
        // Запрос нашего интерфейса, которому однозначно сопоставлена&lt;br /&gt;
        // фабрика.&lt;br /&gt;
        if(aCID.equals(CLASS_ID))&lt;br /&gt;
            return MyComponentFactory;&lt;br /&gt;
&lt;br /&gt;
        // Мы не смогли обработать запрос объекта, и ничего не знаем о запрошенном&lt;br /&gt;
        // интерфейсе.&lt;br /&gt;
        throw Components.results.NS_ERROR_NO_INTERFACE;&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    canUnload: function(aCompMgr) { return true; }&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// Главный загрузчик, должен возвращать объект нашего модуля&lt;br /&gt;
function NSGetModule(aCompMgr, aFileSpec) { return MyComponentModule; }&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Запуск ==&lt;br /&gt;
Копируем &amp;lt;tt&amp;gt;.xpt&amp;lt;/tt&amp;gt; библиотеку и &amp;lt;tt&amp;gt;.js&amp;lt;/tt&amp;gt; файл в каталог &amp;lt;tt&amp;gt;components&amp;lt;/tt&amp;gt; нашего &amp;lt;tt&amp;gt;XUL&amp;lt;/tt&amp;gt; проекта, и создаём &amp;lt;tt&amp;gt;.xul&amp;lt;/tt&amp;gt; файл абсолютно идентичный таковому из статьи [[XUL XPCOM|«Пишем XPCOM компонент на C++»]]. Запуск и результат также должны совпадать с результатами из статьи [[XUL XPCOM|«Пишем XPCOM компонент на C++»]] — вы должны увидеть окно с текстом &amp;lt;tt&amp;gt;3 + 4 = 7&amp;lt;/tt&amp;gt; внутри.&lt;br /&gt;
&lt;br /&gt;
== Анализ ==&lt;br /&gt;
Как Вы видите, единственное отличие от предыдущей статьи в том, что XPCOM компонент реализован не на C++, а на JavaScript. Естественно, такие компоненты проще писать и сопровождать.&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* [[Файл:example4.tar.bz2| Исходники example4 с готовым компонентом (переименуйте в .tar.bz2)]]&lt;br /&gt;
* [http://kb.mozillazine.org/Implementing_XPCOM_components_in_JavaScript Создание XPCOM компонента на JavaScript]&amp;lt;br&amp;gt;&lt;br /&gt;
* [http://www.builderau.com.au/program/soa/Creating_XPCOM_components_with_JavaScript/0,339024614,339206503,00.htm Создание XPCOM компонента на JavaScript-2]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Категория:XUL]]&lt;/div&gt;</summary>
		<author><name>lor&gt;Cetjs2</name></author>
	</entry>
</feed>