1 |
|
---|
2 | <center><b><font size=+2>XPConnect Sample</font></b>
|
---|
3 |
|
---|
4 | <p>
|
---|
5 | <a href="mailto:[email protected]">Ariel Blackenroth <[email protected]></a>
|
---|
6 | <br>
|
---|
7 | <a href="mailto:[email protected]">Michael Ang <[email protected]></a>
|
---|
8 | <br>
|
---|
9 | Last modified
|
---|
10 | <script>
|
---|
11 | document.write(document.lastModified);
|
---|
12 | </script>
|
---|
13 | </center>
|
---|
14 |
|
---|
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.
|
---|
17 |
|
---|
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.
|
---|
24 |
|
---|
25 | <p><b>Overview</b>
|
---|
26 |
|
---|
27 | <p>
|
---|
28 | This sample demonstrates accessing a XPCOM object through XPConnect.
|
---|
29 | The JavaScript executed when this page loads creates an instance
|
---|
30 | of the object by
|
---|
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>:
|
---|
33 | <br>
|
---|
34 | <pre>
|
---|
35 | netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
---|
36 | var sample = Components.classes["@mozilla.org/sample;1"].createInstance();
|
---|
37 | sample = sample.QueryInterface(Components.interfaces.nsISample);
|
---|
38 | </pre>
|
---|
39 |
|
---|
40 | <p>
|
---|
41 | The buttons on the form are connected to JavaScript event handlers which
|
---|
42 | call the methods defined in C++.
|
---|
43 |
|
---|
44 |
|
---|
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,
|
---|
78 | in JavaScript.
|
---|
79 |
|
---|
80 | <p><b>Compiling the idl</b>
|
---|
81 |
|
---|
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>.
|
---|
86 |
|
---|
87 | <p>Once you have the XPIDL compiler enter the following command at your
|
---|
88 | prompt:
|
---|
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>
|
---|
91 |
|
---|
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
|
---|
96 | typelib</tt>.
|
---|
97 |
|
---|
98 | <p>
|
---|
99 | For more information on compilation see the <a href="http://www.mozilla.org/scriptable/xpidl/">xpidl
|
---|
100 | compiler page</a>.
|
---|
101 |
|
---|
102 | <p><b>Building the Sample</b>
|
---|
103 |
|
---|
104 | <p>To build the Sample just enter
|
---|
105 | <br><tt>d:\mozilla\xpcom\sample>nmake /f makefile.win</tt>
|
---|
106 |
|
---|
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.
|
---|
110 |
|
---|
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>.
|
---|
117 |
|
---|
118 | <!-- XXX keep in sync with stuff in pre tag below -->
|
---|
119 | <script>
|
---|
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");
|
---|
125 |
|
---|
126 | function get()
|
---|
127 | {
|
---|
128 | netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
---|
129 | var field = document.getElementById('Value');
|
---|
130 | field.value = sample.value;
|
---|
131 | }
|
---|
132 |
|
---|
133 | function set()
|
---|
134 | {
|
---|
135 | netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
---|
136 | var field = document.getElementById('Value');
|
---|
137 | sample.value = field.value;
|
---|
138 | }
|
---|
139 |
|
---|
140 | function poke()
|
---|
141 | {
|
---|
142 | netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
---|
143 | var field = document.getElementById('Value');
|
---|
144 | sample.poke(field.value);
|
---|
145 | }
|
---|
146 |
|
---|
147 | function sampleWrite()
|
---|
148 | {
|
---|
149 | netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
---|
150 | sample.writeValue("here is what I'm writing: ");
|
---|
151 | }
|
---|
152 | </script>
|
---|
153 |
|
---|
154 | <p>
|
---|
155 | <form name="form">
|
---|
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();">
|
---|
161 | <form>
|
---|
162 |
|
---|
163 | <hr>
|
---|
164 |
|
---|
165 | <p>
|
---|
166 | JavaScript and form source:
|
---|
167 |
|
---|
168 | <!-- XXX keep in sync with actual script -->
|
---|
169 | <pre>
|
---|
170 | <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");
|
---|
176 |
|
---|
177 | function get()
|
---|
178 | {
|
---|
179 | netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); var field = document.getElementById('Value');
|
---|
180 | field.value = sample.value;
|
---|
181 | }
|
---|
182 |
|
---|
183 | function set()
|
---|
184 | {
|
---|
185 | netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); var field = document.getElementById('Value');
|
---|
186 | sample.value = field.value;
|
---|
187 | }
|
---|
188 |
|
---|
189 | function poke()
|
---|
190 | {
|
---|
191 | netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); var field = document.getElementById('Value');
|
---|
192 | sample.poke(field.value);
|
---|
193 | }
|
---|
194 |
|
---|
195 | function sampleWrite()
|
---|
196 | {
|
---|
197 | netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
---|
198 | sample.writeValue("here is what I'm writing: ");
|
---|
199 | }
|
---|
200 | </script>
|
---|
201 |
|
---|
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();">
|
---|
208 | <form>
|
---|
209 |
|
---|
210 | </pre>
|
---|
211 |
|
---|
212 | <p>
|
---|
213 | <hr>
|
---|
214 | <b>Resources:</b>
|
---|
215 | <ul>
|
---|
216 | <li><a href="http://lxr.mozilla.org/seamonkey/source/xpcom/sample/">mozilla/xpcom/sample source directory</a>
|
---|
217 | </ul>
|
---|
218 | <hr>
|
---|
219 | <b>Comments to:</b>
|
---|
220 | <a href="mailto:[email protected]?Subject=XPCOM sample documentation">Michael Ang <[email protected]></a>
|
---|