|
1 <!-- This Source Code Form is subject to the terms of the Mozilla Public |
|
2 - License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> |
|
4 |
|
5 |
|
6 <center><b><font size=+2>XPConnect Sample</font></b> |
|
7 |
|
8 <p> |
|
9 <a href="mailto:arielb@rice.edu">Ariel Blackenroth <arielb@rice.edu></a> |
|
10 <br> |
|
11 <a href="mailto:mang@subcarrier.org">Michael Ang <mang@subcarrier.org></a> |
|
12 <br> |
|
13 Last modified |
|
14 <script> |
|
15 document.write(document.lastModified); |
|
16 </script> |
|
17 </center> |
|
18 |
|
19 <p>In the spirit of "worse is better" this somewhat rough guide is being |
|
20 released to the world. It will be expanded upon and improved. |
|
21 |
|
22 <p>XPConnect allows JavaScript |
|
23 to transparantly access and manipulate XPCOM objects; this communication |
|
24 between JavaScript and |
|
25 native code is done by having their interfaces defined in the XPIDL interface |
|
26 definition language. See the <a href="http://www.mozilla.org/scriptable/roadmap.html">Roadmap |
|
27 for documentation on XPCOM, XPConnect, XPTCall and XPIDL</a> for more information. |
|
28 |
|
29 <p><b>Overview</b> |
|
30 |
|
31 <p> |
|
32 This sample demonstrates accessing a XPCOM object through XPConnect. |
|
33 The JavaScript executed when this page loads creates an instance |
|
34 of the object by |
|
35 using the <tt>Components</tt> object, then accesses it through |
|
36 the <a href="http://lxr.mozilla.org/seamonkey/source/xpcom/sample/nsISample.idl">nsISample</a> interface by calling <tt>QueryInterface</tt>: |
|
37 <br> |
|
38 <pre> |
|
39 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); |
|
40 var sample = Components.classes["@mozilla.org/sample;1"].createInstance(); |
|
41 sample = sample.QueryInterface(Components.interfaces.nsISample); |
|
42 </pre> |
|
43 |
|
44 <p> |
|
45 The buttons on the form are connected to JavaScript event handlers which |
|
46 call the methods defined in C++. |
|
47 |
|
48 |
|
49 <p><b><a href="http://lxr.mozilla.org/mozilla/source/xpcom/sample/nsISample.idl">nsISample.idl</a></b> |
|
50 <p>This is the interface declaration for the XPCOM object. It defines |
|
51 two functions, their parameters, and one attribute. It also defines |
|
52 the interface's id. The idl file is compiled by the xpidl compiler |
|
53 into a C++ header, nsISample.h and a .xpt file which is a binary representation |
|
54 of the interface used at runtime. |
|
55 <br><tt>attribute string value;</tt> |
|
56 <br><tt>void writeValue(in string aPrefix);</tt> |
|
57 <br><tt>void poke(in string aValue);</tt><b></b> |
|
58 <p><b><a href="http://lxr.mozilla.org/mozilla/source/xpcom/sample/nsSample.cpp">nsSample.cpp</a></b> |
|
59 <p>This contains the implementation of nsISample.idl. SampleImpl |
|
60 inherits from nsISample.h, the header dynamically created by the xpidl |
|
61 compiler. The attribute Value has been expanded into a get and set |
|
62 and the return values have been modified to NS_IMETHOD, a success status |
|
63 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> |
|
64 defines the inherited methods from nsISupports.h. |
|
65 <br><tt>NS_IMPL_ISUPPORTS(SampleImpl, nsISample)</tt> |
|
66 <br>In the constructor, the macro NS_INIT_REFCNT is called which sets the |
|
67 reference count to 0.<p> |
|
68 Note that the methods in the C++ bindings use InterCaps style, while the IDL |
|
69 and JavaScript versions should use interCaps naming. The JavaScript binding |
|
70 matches the case of the IDL, <b>except</b> <a |
|
71 href="http://bugzilla.mozilla.org/show_bug.cgi?id=14460">QueryInterface</a>. |
|
72 <p><b><a href="http://lxr.mozilla.org/mozilla/source/xpcom/sample/nsSampleFactory.cpp">nsSampleFactory.cpp</a></b> |
|
73 <p>This is the class which builds the instance of the nsSample class. |
|
74 The COM framework uses factories to create instance of implementations |
|
75 rather than having the implementations instantiate themselves in order to |
|
76 increase portability of code. This factory inherits from nsFactory, |
|
77 which is also an XPCOM object. To gain more knowledge of factories |
|
78 see the <a href="http://www.mozilla.org/projects/xpcom/generic-factory.html">generic |
|
79 factory document</a> or the <a href="http://www.mozilla.org/docs/modunote.htm#Basics">Modularization techniques document</a>. |
|
80 <p><b><a href="http://lxr.mozilla.org/mozilla/source/xpcom/sample/nsSample.js">nsSample.js</a></b> |
|
81 <p>This file implements the nsISample interface, and associated factory glue, |
|
82 in JavaScript. |
|
83 |
|
84 <p><b>Compiling the idl</b> |
|
85 |
|
86 <p>The XPIDL compiler (xpidl on Unix, xpidl.exe on Windows, and a CodeWarrior plugin on Mac) |
|
87 is compiled at build time (except on Mac) thus |
|
88 you will have to build mozilla in order to test this out. If you |
|
89 have already built mozilla then the compiler will be located at <tt>mozilla\dist\WIN32_D.OBJ\bin\xpidl.exe</tt>. |
|
90 |
|
91 <p>Once you have the XPIDL compiler enter the following command at your |
|
92 prompt: |
|
93 <br><tt>D:\mozilla\xpcom\sample>d:\mozilla\dist\WIN32_D.OBJ\bin\xpidl -I |
|
94 d:\mozilla\dist\idl -m header nsISample.idl</tt> |
|
95 |
|
96 <p>The <tt>-I d:\mozilla\dist\idl</tt> points the compiler to the folder |
|
97 containing the other idl files, needed because nsISample.idl inherits from |
|
98 nsISupports.idl. The <tt>-m header</tt> instruction tells the compiler |
|
99 to build the C++ header. To build the .xpt file substitute <tt>-m |
|
100 typelib</tt>. |
|
101 |
|
102 <p> |
|
103 For more information on compilation see the <a href="http://www.mozilla.org/scriptable/xpidl/">xpidl |
|
104 compiler page</a>. |
|
105 |
|
106 <p><b>Building the Sample</b> |
|
107 |
|
108 <p>To build the Sample just enter |
|
109 <br><tt>d:\mozilla\xpcom\sample>nmake /f makefile.win</tt> |
|
110 |
|
111 <p>In order to do this you need to have your environment variables set |
|
112 correctly. See the <a href="http://www.mozilla.org/build/">Build</a> |
|
113 page for more information. |
|
114 |
|
115 <p><b>Running the sample</b> |
|
116 <p>Using Mozilla, load |
|
117 <a href="resource://res/samples/xpconnect-sample.html">resource://res/samples/xpconnect-sample.html</a> (i.e. what |
|
118 you're reading now). Pay attention |
|
119 to the console when clicking "write". Notice that the value |
|
120 printed is calculated in C++ code defined in <a href="http://lxr.mozilla.org/seamonkey/source/xpcom/sample/nsSample.cpp">nsSample.cpp</a>. |
|
121 |
|
122 <!-- XXX keep in sync with stuff in pre tag below --> |
|
123 <script> |
|
124 /* to use nsSample.js version, use "@mozilla.org/jssample;1" */ |
|
125 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); |
|
126 var sample = Components.classes["@mozilla.org/sample;1"].createInstance(); |
|
127 sample = sample.QueryInterface(Components.interfaces.nsISample); |
|
128 dump("sample = " + sample + "\n"); |
|
129 |
|
130 function get() |
|
131 { |
|
132 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); |
|
133 var field = document.getElementById('Value'); |
|
134 field.value = sample.value; |
|
135 } |
|
136 |
|
137 function set() |
|
138 { |
|
139 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); |
|
140 var field = document.getElementById('Value'); |
|
141 sample.value = field.value; |
|
142 } |
|
143 |
|
144 function poke() |
|
145 { |
|
146 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); |
|
147 var field = document.getElementById('Value'); |
|
148 sample.poke(field.value); |
|
149 } |
|
150 |
|
151 function sampleWrite() |
|
152 { |
|
153 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); |
|
154 sample.writeValue("here is what I'm writing: "); |
|
155 } |
|
156 </script> |
|
157 |
|
158 <p> |
|
159 <form name="form"> |
|
160 <input type="button" value="Get" onclick="get();"> |
|
161 <input type="button" value="Set" onclick="set();"> |
|
162 <input type="button" value="Poke" onclick="poke();"> |
|
163 <input type="text" id="Value"> |
|
164 <input type="button" value="Write" onclick="sampleWrite();"> |
|
165 <form> |
|
166 |
|
167 <hr> |
|
168 |
|
169 <p> |
|
170 JavaScript and form source: |
|
171 |
|
172 <!-- XXX keep in sync with actual script --> |
|
173 <pre> |
|
174 <script> |
|
175 /* to use nsSample.js version, use "@mozilla.org/jssample;1" */ |
|
176 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); |
|
177 var sample = Components.classes["@mozilla.org/sample;1"].createInstance(); |
|
178 sample = sample.QueryInterface(Components.interfaces.nsISample); |
|
179 dump("sample = " + sample + "\n"); |
|
180 |
|
181 function get() |
|
182 { |
|
183 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); var field = document.getElementById('Value'); |
|
184 field.value = sample.value; |
|
185 } |
|
186 |
|
187 function set() |
|
188 { |
|
189 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); var field = document.getElementById('Value'); |
|
190 sample.value = field.value; |
|
191 } |
|
192 |
|
193 function poke() |
|
194 { |
|
195 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); var field = document.getElementById('Value'); |
|
196 sample.poke(field.value); |
|
197 } |
|
198 |
|
199 function sampleWrite() |
|
200 { |
|
201 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); |
|
202 sample.writeValue("here is what I'm writing: "); |
|
203 } |
|
204 </script> |
|
205 |
|
206 <form name="form"> |
|
207 <input type="button" value="Get" onclick="get();"> |
|
208 <input type="button" value="Set" onclick="set();"> |
|
209 <input type="button" value="Poke" onclick="poke();"> |
|
210 <input type="text" id="Value"> |
|
211 <input type="button" value="Write" onclick="sampleWrite();"> |
|
212 <form> |
|
213 |
|
214 </pre> |
|
215 |
|
216 <p> |
|
217 <hr> |
|
218 <b>Resources:</b> |
|
219 <ul> |
|
220 <li><a href="http://lxr.mozilla.org/seamonkey/source/xpcom/sample/">mozilla/xpcom/sample source directory</a> |
|
221 </ul> |
|
222 <hr> |
|
223 <b>Comments to:</b> |
|
224 <a href="mailto:mang@subcarrier.org?Subject=XPCOM sample documentation">Michael Ang <mang@subcarrier.org></a> |