Added big note saying 'please disable security before trying to run this' so nobody gets frustrated. Updated sample component progid reference to actually match the .cpp. Now the page actually works! (John Morrison <3jrgm@qlink.queensu.ca> caught this in mozilla.xpcom) Thanks to Rick Bradley <roundeye@bellsouth.net> for pointing me to the problem, and for encouraging me to add a note. r=mccabe. Not part of the build. git-svn-id: svn://10.0.0.236/trunk@55912 18797224-902f-48f8-a5cc-f745e15eee43
219 lines
8.3 KiB
HTML
219 lines
8.3 KiB
HTML
|
|
<center><b><font size=+2>XPConnect Sample</font></b>
|
|
|
|
<p>
|
|
<a href="mailto:arielb@netscape.com">Ariel Blackenroth <arielb@netscape.com></a>
|
|
<br>
|
|
<a href="mailto:mang@subcarrier.org">Michael Ang <mang@subcarrier.org></a>
|
|
<br>
|
|
Last modified Aug 4, 1999
|
|
</center>
|
|
|
|
<hr>
|
|
NOTE: The example on this page currently won't work out of the box, because
|
|
access to arbitrary XPConnect components through <tt>Components</tt>
|
|
object is disabled for web-page JavaScript. When we get our security
|
|
story straightened out, we'll restore most access. For now, you can get around
|
|
it by finding '<tt>pref("security.checkxpconnect", <b>true</b>);'</tt> in the
|
|
preferences file (<tt>all.js</tt>) and setting it to <tt><b>false</b></tt>.
|
|
<hr>
|
|
|
|
<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>
|
|
var sample = Components.classes["component://mozilla/sample/sample-world"].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_ISUPPORTS(SampleImpl, nsISample::GetIID());</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 instatiate 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.jssample.1" */
|
|
var sample = Components.classes["component://netscape/sample"].createInstance();
|
|
sample = sample.QueryInterface(Components.interfaces.nsISample);
|
|
dump("sample = " + sample + "\n");
|
|
|
|
function get()
|
|
{
|
|
var field = document.getElementById('Value');
|
|
field.value = sample.value;
|
|
}
|
|
|
|
function set()
|
|
{
|
|
var field = document.getElementById('Value');
|
|
sample.value = field.value;
|
|
}
|
|
|
|
function poke()
|
|
{
|
|
var field = document.getElementById('Value');
|
|
sample.poke(field.value);
|
|
}
|
|
|
|
function write()
|
|
{
|
|
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="write();">
|
|
<form>
|
|
|
|
<hr>
|
|
|
|
<p>
|
|
JavaScript and form source:
|
|
|
|
<!-- XXX keep in sync with actual script -->
|
|
<pre>
|
|
<script>
|
|
/* to use nsSample.js version, use "mozilla.jssample.1" */
|
|
var sample = Components.classes["component://netscape/sample"].createInstance();
|
|
sample = sample.QueryInterface(Components.interfaces.nsISample);
|
|
dump("sample = " + sample + "\n");
|
|
|
|
function get()
|
|
{
|
|
var field = document.getElementById('Value');
|
|
field.value = sample.value;
|
|
}
|
|
|
|
function set()
|
|
{
|
|
var field = document.getElementById('Value');
|
|
sample.value = field.value;
|
|
}
|
|
|
|
function poke()
|
|
{
|
|
var field = document.getElementById('Value');
|
|
sample.poke(field.value);
|
|
}
|
|
|
|
function write()
|
|
{
|
|
sample.writeValue("here is what I'm writing: ");
|
|
}
|
|
</script>
|
|
|
|
<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="write();">
|
|
<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 <mang@subcarrier.org></a>
|