1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
---
title: JS XPCOM
slug: Fragmenty_kodu/JS_XPCOM
tags:
- Strony_wymagające_dopracowania
translation_of: Archive/Add-ons/Code_snippets/JS_XPCOM
---
<p>Na tej stronie znajduje się kilka fragmentów kodu, użytecznych przy tworzeniu z komponentami XPCOM w JavaScript.</p>
<h3 id="Contract_IDs" name="Contract_IDs">ID kontraktów</h3>
<p>ID kontraktu przyznaje unikalną nazwę dla obiektu XPCOM. ID używane są do tworzenia lub uzyskiwania dostępu do obiektów XPCOM.</p>
<h3 id="Interfaces" name="Interfaces">Interfejsy</h3>
<p>Wszystkie obiekty XPCOM implementują jeden lub więcej interfejsów. Interfejs jest, upraszczając, listą stałych i metod, które można wywołać przez obiekt. Przykładem jest <a href="/pl/NsIFile" title="pl/NsIFile">nsIFile</a>. Każdy obiekt XPCOM musi posiadać zaimplementowany interfejs <a href="/pl/NsISupports" title="pl/NsISupports">nsISupports</a>.</p>
<h3 id="Accessing_XPCOM_components_from_JavaScript" name="Accessing_XPCOM_components_from_JavaScript">Uzyskiwanie dostępu do komponentów XPCOM z poziomu JavaScript</h3>
<p>Obiekty XPCOM są tworzone jako nowe instacje (każda oznacza kompletnie nowy obiekt) lub jako usługi (każdy dostęp dotyczy tego samego obiektu, nazywanego singletonem). Od danego obiektu zależy to, czy musisz stworzyć instację czy dostęp poprzez usługę. Chronologicznie, by dostać się do obiektu XPCOM, musisz znać ID kontraktu obiektu oraz interfejs, który chciałbyś na nim użyć.</p>
<h4 id="Creating_an_instance_of_a_component" name="Creating_an_instance_of_a_component">Tworzenie instancji komponentu</h4>
<pre>var component = Components.classes["@mozilla.org/file/local;1"]
.createInstance(Components.interfaces.nsIFile);
</pre>
<p>Powyższy kod tworzy nową instację obiektu z ID kontraktu <code>@mozilla.org/file/local;1</code> i daje ci możliwość wywoływania metody interfejsu <a href="/pl/NsIFile" title="pl/NsIFile">nsIFile</a> na ID.</p>
<h4 id="Getting_an_XPCOM_service" name="Getting_an_XPCOM_service">Otrzymywanie usługi XPCOM</h4>
<pre>var preferences = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefService);
</pre>
<p>Dzięki temu fragmentowi kodu, możesz wywoływać metody interfejsu <code><a href="/pl/NsIPrefService" title="pl/NsIPrefService">nsIPrefService</a></code> na preferencjach obiektu.</p>
<h4 id="Getting_a_different_interface_for_a_component" name="Getting_a_different_interface_for_a_component">Otrzymywanie różnych interfejsów jednego komponentu</h4>
<p>Niektóre komponenty posiadają możliwość implementacji więcej niż jednego interfejsu. Czasami JavaScript zna wszystkie wszystkie możliwe dla komponentu interfejsu, ale w większości przypadków będziesz samodzielnie to sprawdzić. Z preferencjami usługi z poprzedniego przykładu, możemy napisać dalej:</p>
<pre>preferences = preferences.QueryInterface(Components.interfaces.nsIPrefBranch2);
</pre>
<p>Powyższa linijka umożliwia ci używanie metod interfejsu <code><a href="/pl/NsIPrefBranch2" title="pl/NsIPrefBranch2">nsIPrefBranch2</a></code>.</p>
<h3 id="Implementing_XPCOM_components_in_JavaScript" name="Implementing_XPCOM_components_in_JavaScript">Implementacja komponentów XPCOM w JavaScript</h3>
<p>Poniżej znajduje się prosty zalążek komponentu XPCOM w JavaScript. W dokładnie takiej kolejności, musisz wykonać następujące kroki:</p>
<ul>
<li>Zmienić 3 łańcuchy na początku initModule na własne.</li>
<li>Zmienić testowanie w metodzie QueryInterface umożliwiając sobie pracę z obojętnie jakimi interfejsami, które zaimplementujesz.</li>
<li>Dodać do prototypu metody, które pojawią się w implementowanym interfejsie.</li>
<li>Dodać kody inicjacji do konstruktora ExampleComponent.</li>
</ul>
<pre>function ExampleComponent()
{
// Dodaj tutaj inicjację twego komponentu.
}
ExampleComponent.prototype = {
QueryInterface: function(iid)
{
if (iid.equals(Components.interfaces.myInterface)
|| iid.equals(Ci.nsISupports))
{
return this;
}
else
{
throw Components.results.NS_ERROR_NO_INTERFACE;
}
}
};
var initModule =
{
ServiceCID: Components.ID("{examplee-xamp-leex-ampl-eexampleexam}"), // Insert a guid in the quotes
ServiceContractID: "@example.com/example;1", // W cudzysłowiach wpisz ID kontraktu
ServiceName: "", // W cudzysłowiach wpisz nazwę
registerSelf: function (compMgr, fileSpec, location, type)
{
compMgr = compMgr.QueryInterface(Ci.nsIComponentRegistrar);
compMgr.registerFactoryLocation(this.ServiceCID,this.ServiceName,this.ServiceContractID,
fileSpec,location,type);
},
unregisterSelf: function (compMgr, fileSpec, location)
{
compMgr = compMgr.QueryInterface(Ci.nsIComponentRegistrar);
compMgr.unregisterFactoryLocation(this.ServiceCID,fileSpec);
},
getClassObject: function (compMgr, cid, iid)
{
if (!cid.equals(this.ServiceCID))
throw Components.results.NS_ERROR_NO_INTERFACE
if (!iid.equals(Components.interfaces.nsIFactory))
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
return this.instanceFactory;
},
canUnload: function(compMgr)
{
return true;
},
instanceFactory:
{
createInstance: function (outer, iid)
{
if (outer != null)
throw Components.results.NS_ERROR_NO_AGGREGATION;
return new ExampleComponent().QueryInterface(iid);
}
}
}; //Module
function NSGetModule(compMgr, fileSpec)
{
return initModule;
}</pre>
|