DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (a81015259a98)

VCS Links

Line Code
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 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220

<center><b><font size=+2>XPConnect Sample</font></b>

<p>
<a href="mailto:arielb@rice.edu">Ariel Blackenroth &lt;arielb@rice.edu&gt;</a>
<br>
<a href="mailto:mang@subcarrier.org">Michael Ang &lt;mang@subcarrier.org&gt;</a>
<br>
Last modified 
<script>
document.write(document.lastModified);
</script>
</center>

<p>In the spirit of "worse is better" this somewhat rough guide is being
released to the world.  It will be expanded upon and improved.

<p>XPConnect allows JavaScript
to transparantly access and manipulate XPCOM objects; this communication
between JavaScript and
native code is done by having their interfaces defined in the XPIDL interface
definition language. See the <a href="http://www.mozilla.org/scriptable/roadmap.html">Roadmap
for documentation on XPCOM, XPConnect, XPTCall and XPIDL</a> for more information.

<p><b>Overview</b>

<p>
This sample demonstrates accessing a XPCOM object through XPConnect.
The JavaScript executed when this page loads creates an instance
of the object by
using the <tt>Components</tt> object, then accesses it through
the <a href="http://lxr.mozilla.org/seamonkey/source/xpcom/sample/nsISample.idl">nsISample</a> interface by calling <tt>QueryInterface</tt>:
<br>
<pre>
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var sample = Components.classes["@mozilla.org/sample;1"].createInstance();
sample = sample.QueryInterface(Components.interfaces.nsISample);
</pre>

<p>
The buttons on the form are connected to JavaScript event handlers which
call the methods defined in C++.


<p><b><a href="http://lxr.mozilla.org/mozilla/source/xpcom/sample/nsISample.idl">nsISample.idl</a></b>
<p>This is the interface declaration for the XPCOM object. It defines
two functions, their parameters, and one attribute. It also defines
the interface's id. The idl file is compiled by the xpidl compiler
into a C++ header, nsISample.h and a .xpt file which is a binary representation
of the interface used at runtime.
<br><tt>attribute string value;</tt>
<br><tt>void writeValue(in string aPrefix);</tt>
<br><tt>void poke(in string aValue);</tt><b></b>
<p><b><a href="http://lxr.mozilla.org/mozilla/source/xpcom/sample/nsSample.cpp">nsSample.cpp</a></b>
<p>This contains the implementation of nsISample.idl. SampleImpl
inherits from nsISample.h, the header dynamically created by the xpidl
compiler. The attribute Value has been expanded into a get and set
and the return values have been modified to NS_IMETHOD, a success status
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>
defines the inherited methods from nsISupports.h.
<br><tt>NS_IMPL_ISUPPORTS1(SampleImpl, nsISample)</tt>
<br>In the constructor, the macro NS_INIT_REFCNT is called which sets the
reference count to 0.<p>
Note that the methods in the C++ bindings use InterCaps style, while the IDL
and JavaScript versions should use interCaps naming.  The JavaScript binding
matches the case of the IDL, <b>except</b> <a
href="http://bugzilla.mozilla.org/show_bug.cgi?id=14460">QueryInterface</a>.
<p><b><a href="http://lxr.mozilla.org/mozilla/source/xpcom/sample/nsSampleFactory.cpp">nsSampleFactory.cpp</a></b>
<p>This is the class which builds the instance of the nsSample class.
The COM framework uses factories to create instance of implementations
rather than having the implementations instantiate themselves in order to
increase portability of code. This factory inherits from nsFactory,
which is also an XPCOM object. To gain more knowledge of factories
see the <a href="http://www.mozilla.org/projects/xpcom/generic-factory.html">generic
factory document</a> or the <a href="http://www.mozilla.org/docs/modunote.htm#Basics">Modularization techniques document</a>.
<p><b><a href="http://lxr.mozilla.org/mozilla/source/xpcom/sample/nsSample.js">nsSample.js</a></b>
<p>This file implements the nsISample interface, and associated factory glue,
in JavaScript.

<p><b>Compiling the idl</b>

<p>The XPIDL compiler (xpidl on Unix, xpidl.exe on Windows, and a CodeWarrior plugin on Mac)
is compiled at build time (except on Mac) thus
you will have to build mozilla in order to test this out. If you
have already built mozilla then the compiler will be located at <tt>mozilla\dist\WIN32_D.OBJ\bin\xpidl.exe</tt>.

<p>Once you have the XPIDL compiler enter the following command at your
prompt:
<br><tt>D:\mozilla\xpcom\sample>d:\mozilla\dist\WIN32_D.OBJ\bin\xpidl -I
d:\mozilla\dist\idl -m header nsISample.idl</tt>

<p>The <tt>-I d:\mozilla\dist\idl</tt> points the compiler to the folder
containing the other idl files, needed because nsISample.idl inherits from
nsISupports.idl. The <tt>-m header</tt> instruction tells the compiler
to build the C++ header. To build the .xpt file substitute <tt>-m
typelib</tt>. 

<p>
For more information on compilation see the <a href="http://www.mozilla.org/scriptable/xpidl/">xpidl
compiler page</a>.

<p><b>Building the Sample</b>

<p>To build the Sample just enter
<br><tt>d:\mozilla\xpcom\sample>nmake /f makefile.win</tt>

<p>In order to do this you need to have your environment variables set
correctly. See the <a href="http://www.mozilla.org/build/">Build</a>
page for more information.

<p><b>Running the sample</b>
<p>Using Mozilla, load
<a href="resource://res/samples/xpconnect-sample.html">resource://res/samples/xpconnect-sample.html</a> (i.e. what
you're reading now). Pay attention
to the console when clicking "write". Notice that the value
printed is calculated in C++ code defined in <a href="http://lxr.mozilla.org/seamonkey/source/xpcom/sample/nsSample.cpp">nsSample.cpp</a>.

<!-- XXX keep in sync with stuff in pre tag below -->
<script>
/* to use nsSample.js version, use "@mozilla.org/jssample;1" */
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var sample = Components.classes["@mozilla.org/sample;1"].createInstance();
sample = sample.QueryInterface(Components.interfaces.nsISample);
dump("sample = " + sample + "\n");

function get()
{
  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
  var field = document.getElementById('Value');
  field.value = sample.value;
}

function set()
{
  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
  var field = document.getElementById('Value');
  sample.value = field.value;
}

function poke()
{
  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
  var field = document.getElementById('Value');
  sample.poke(field.value);
}

function sampleWrite()
{
  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
  sample.writeValue("here is what I'm writing: ");
}
</script>

<p>
<form name="form">
<input type="button" value="Get" onclick="get();">
<input type="button" value="Set" onclick="set();">
<input type="button" value="Poke" onclick="poke();">
<input type="text" id="Value">
<input type="button" value="Write" onclick="sampleWrite();">
<form>

<hr>

<p>
JavaScript and form source:

<!-- XXX keep in sync with actual script -->
<pre>
&lt;script&gt;
/* to use nsSample.js version, use "@mozilla.org/jssample;1" */
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var sample = Components.classes["@mozilla.org/sample;1"].createInstance();
sample = sample.QueryInterface(Components.interfaces.nsISample);
dump("sample = " + sample + "\n");

function get()
{
  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");  var field = document.getElementById('Value');
  field.value = sample.value;
}

function set()
{
  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");  var field = document.getElementById('Value');
  sample.value = field.value;
}

function poke()
{
  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");  var field = document.getElementById('Value');
  sample.poke(field.value);
}

function sampleWrite()
{
  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
  sample.writeValue("here is what I'm writing: ");
}
&lt;/script&gt;

&lt;form name=&quot;form&quot;&gt;
&lt;input type=&quot;button&quot; value=&quot;Get&quot; onclick=&quot;get();&quot;&gt;
&lt;input type=&quot;button&quot; value=&quot;Set&quot; onclick=&quot;set();&quot;&gt;
&lt;input type=&quot;button&quot; value=&quot;Poke&quot; onclick=&quot;poke();&quot;&gt;
&lt;input type=&quot;text&quot; id=&quot;Value&quot;&gt;
&lt;input type=&quot;button&quot; value=&quot;Write&quot; onclick=&quot;sampleWrite();&quot;&gt;
&lt;form>

</pre>

<p>
<hr>
<b>Resources:</b>
<ul>
<li><a href="http://lxr.mozilla.org/seamonkey/source/xpcom/sample/">mozilla/xpcom/sample source directory</a>
</ul>
<hr>
<b>Comments to:</b>
<a href="mailto:mang@subcarrier.org?Subject=XPCOM sample documentation">Michael Ang &lt;mang@subcarrier.org&gt;</a>