2
<center><b><font size=+2>XPConnect Sample</font></b>
5
<a href="mailto:arielb@rice.edu">Ariel Blackenroth <arielb@rice.edu></a>
7
<a href="mailto:mang@subcarrier.org">Michael Ang <mang@subcarrier.org></a>
11
document.write(document.lastModified);
15
<p>In the spirit of "worse is better" this somewhat rough guide is being
16
released to the world. It will be expanded upon and improved.
18
<p>XPConnect allows JavaScript
19
to transparantly access and manipulate XPCOM objects; this communication
20
between JavaScript and
21
native code is done by having their interfaces defined in the XPIDL interface
22
definition language. See the <a href="http://www.mozilla.org/scriptable/roadmap.html">Roadmap
23
for documentation on XPCOM, XPConnect, XPTCall and XPIDL</a> for more information.
28
This sample demonstrates accessing a XPCOM object through XPConnect.
29
The JavaScript executed when this page loads creates an instance
31
using the <tt>Components</tt> object, then accesses it through
32
the <a href="http://lxr.mozilla.org/seamonkey/source/xpcom/sample/nsISample.idl">nsISample</a> interface by calling <tt>QueryInterface</tt>:
35
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
36
var sample = Components.classes["@mozilla.org/sample;1"].createInstance();
37
sample = sample.QueryInterface(Components.interfaces.nsISample);
41
The buttons on the form are connected to JavaScript event handlers which
42
call the methods defined in C++.
45
<p><b><a href="http://lxr.mozilla.org/mozilla/source/xpcom/sample/nsISample.idl">nsISample.idl</a></b>
46
<p>This is the interface declaration for the XPCOM object. It defines
47
two functions, their parameters, and one attribute. It also defines
48
the interface's id. The idl file is compiled by the xpidl compiler
49
into a C++ header, nsISample.h and a .xpt file which is a binary representation
50
of the interface used at runtime.
51
<br><tt>attribute string value;</tt>
52
<br><tt>void writeValue(in string aPrefix);</tt>
53
<br><tt>void poke(in string aValue);</tt><b></b>
54
<p><b><a href="http://lxr.mozilla.org/mozilla/source/xpcom/sample/nsSample.cpp">nsSample.cpp</a></b>
55
<p>This contains the implementation of nsISample.idl. SampleImpl
56
inherits from nsISample.h, the header dynamically created by the xpidl
57
compiler. The attribute Value has been expanded into a get and set
58
and the return values have been modified to NS_IMETHOD, a success status
59
for the method. The macro NS_DECL_ISUPPORTS, defined in <a href="http://lxr.mozilla.org/mozilla/source/xpcom/base/nsISupportsUtils.h">mozilla/xpcom/public/nsISupportsUtils.h</a>
60
defines the inherited methods from nsISupports.h.
61
<br><tt>NS_IMPL_ISUPPORTS1(SampleImpl, nsISample)</tt>
62
<br>In the constructor, the macro NS_INIT_REFCNT is called which sets the
63
reference count to 0.<p>
64
Note that the methods in the C++ bindings use InterCaps style, while the IDL
65
and JavaScript versions should use interCaps naming. The JavaScript binding
66
matches the case of the IDL, <b>except</b> <a
67
href="http://bugzilla.mozilla.org/show_bug.cgi?id=14460">QueryInterface</a>.
68
<p><b><a href="http://lxr.mozilla.org/mozilla/source/xpcom/sample/nsSampleFactory.cpp">nsSampleFactory.cpp</a></b>
69
<p>This is the class which builds the instance of the nsSample class.
70
The COM framework uses factories to create instance of implementations
71
rather than having the implementations instatiate themselves in order to
72
increase portability of code. This factory inherits from nsFactory,
73
which is also an XPCOM object. To gain more knowledge of factories
74
see the <a href="http://www.mozilla.org/projects/xpcom/generic-factory.html">generic
75
factory document</a> or the <a href="http://www.mozilla.org/docs/modunote.htm#Basics">Modularization techniques document</a>.
76
<p><b><a href="http://lxr.mozilla.org/mozilla/source/xpcom/sample/nsSample.js">nsSample.js</a></b>
77
<p>This file implements the nsISample interface, and associated factory glue,
80
<p><b>Compiling the idl</b>
82
<p>The XPIDL compiler (xpidl on Unix, xpidl.exe on Windows, and a CodeWarrior plugin on Mac)
83
is compiled at build time (except on Mac) thus
84
you will have to build mozilla in order to test this out. If you
85
have already built mozilla then the compiler will be located at <tt>mozilla\dist\WIN32_D.OBJ\bin\xpidl.exe</tt>.
87
<p>Once you have the XPIDL compiler enter the following command at your
89
<br><tt>D:\mozilla\xpcom\sample>d:\mozilla\dist\WIN32_D.OBJ\bin\xpidl -I
90
d:\mozilla\dist\idl -m header nsISample.idl</tt>
92
<p>The <tt>-I d:\mozilla\dist\idl</tt> points the compiler to the folder
93
containing the other idl files, needed because nsISample.idl inherits from
94
nsISupports.idl. The <tt>-m header</tt> instruction tells the compiler
95
to build the C++ header. To build the .xpt file substitute <tt>-m
99
For more information on compilation see the <a href="http://www.mozilla.org/scriptable/xpidl/">xpidl
102
<p><b>Building the Sample</b>
104
<p>To build the Sample just enter
105
<br><tt>d:\mozilla\xpcom\sample>nmake /f makefile.win</tt>
107
<p>In order to do this you need to have your environment variables set
108
correctly. See the <a href="http://www.mozilla.org/build/">Build</a>
109
page for more information.
111
<p><b>Running the sample</b>
112
<p>Using Mozilla, load
113
<a href="resource://res/samples/xpconnect-sample.html">resource://res/samples/xpconnect-sample.html</a> (i.e. what
114
you're reading now). Pay attention
115
to the console when clicking "write". Notice that the value
116
printed is calculated in C++ code defined in <a href="http://lxr.mozilla.org/seamonkey/source/xpcom/sample/nsSample.cpp">nsSample.cpp</a>.
118
<!-- XXX keep in sync with stuff in pre tag below -->
120
/* to use nsSample.js version, use "@mozilla.org/jssample;1" */
121
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
122
var sample = Components.classes["@mozilla.org/sample;1"].createInstance();
123
sample = sample.QueryInterface(Components.interfaces.nsISample);
124
dump("sample = " + sample + "\n");
128
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
129
var field = document.getElementById('Value');
130
field.value = sample.value;
135
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
136
var field = document.getElementById('Value');
137
sample.value = field.value;
142
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
143
var field = document.getElementById('Value');
144
sample.poke(field.value);
147
function sampleWrite()
149
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
150
sample.writeValue("here is what I'm writing: ");
156
<input type="button" value="Get" onclick="get();">
157
<input type="button" value="Set" onclick="set();">
158
<input type="button" value="Poke" onclick="poke();">
159
<input type="text" id="Value">
160
<input type="button" value="Write" onclick="sampleWrite();">
166
JavaScript and form source:
168
<!-- XXX keep in sync with actual script -->
171
/* to use nsSample.js version, use "@mozilla.org/jssample;1" */
172
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
173
var sample = Components.classes["@mozilla.org/sample;1"].createInstance();
174
sample = sample.QueryInterface(Components.interfaces.nsISample);
175
dump("sample = " + sample + "\n");
179
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); var field = document.getElementById('Value');
180
field.value = sample.value;
185
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); var field = document.getElementById('Value');
186
sample.value = field.value;
191
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); var field = document.getElementById('Value');
192
sample.poke(field.value);
195
function sampleWrite()
197
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
198
sample.writeValue("here is what I'm writing: ");
202
<form name="form">
203
<input type="button" value="Get" onclick="get();">
204
<input type="button" value="Set" onclick="set();">
205
<input type="button" value="Poke" onclick="poke();">
206
<input type="text" id="Value">
207
<input type="button" value="Write" onclick="sampleWrite();">
216
<li><a href="http://lxr.mozilla.org/seamonkey/source/xpcom/sample/">mozilla/xpcom/sample source directory</a>
220
<a href="mailto:mang@subcarrier.org?Subject=XPCOM sample documentation">Michael Ang <mang@subcarrier.org></a>