<!DOCTYPE root [
  <!ATTLIST item
    id ID #REQUIRED
  >
  <!ATTLIST info
    id ID #REQUIRED
  >
  <!ATTLIST entry
    xlink:type CDATA #FIXED "simple"
  >
  <!ATTLIST reference
    xlink:type CDATA #FIXED "simple"
  >
]>
<?xml-stylesheet type="text/css" href="files/style.css"?>
<!--
The following page lists current languages which can work with XPCOM components.
http://developer.mozilla.org/en/docs/XPCOM:Language_Bindings
  -->
<root xmlns:html="http://www.w3.org/1999/xhtml"
      xmlns:xlink="http://www.w3.org/1999/xlink">
<contents>Table of Contents
  <section>
    <entry xlink:href="#comments"
          >Comments (useful for licensing)</entry>
    <entry xlink:href="#template-scratch"
          >Create a template component from scratch.</entry>
    <entry xlink:href="#create-module"
          >Create a module to register your component.</entry>
    <entry xlink:href="#mozilla-makefile"
          >Create a Makefile.in to build your component within Mozilla's source tree.</entry>
    <entry xlink:href="#createInstance"
          >Get a new instance of a component.</entry>
    <entry xlink:href="#getService"
          >Get a component as a service.</entry>
    <entry xlink:href="#addInterface"
          >Add an interface to your component for QueryInterface support.</entry>
    <entry xlink:href="#QI-component"
          >Query a component for support of a particular interface.</entry>
    <entry xlink:href="#report-error"
          >Report a XPCOM error code to XPCOM.</entry>
    <entry xlink:href="#handle-error"
          >Handle a XPCOM error code.</entry>
    <entry xlink:href="#check-is-null"
          >Check if a value is null.</entry>
    <entry xlink:href="#set-to-null"
          >Set a value to null.</entry>
    <entry xlink:href="#pass-current-arg"
          >Pass an argument you already have to a component's method (in parameter).</entry>
    <entry xlink:href="#pass-new-arg"
          >Pass an argument you created to a component's method (in parameter).</entry>
    <entry xlink:href="#pass-current-return"
          >Pass a return argument you already have to a component's method.</entry>
    <entry xlink:href="#pass-new-return"
          >Pass a return argument you created to a component's method.</entry>
    <entry xlink:href="#return-value"
          >Return a value from a component's method.</entry>
    <entry xlink:href="#pass-multiple-return"
          >Pass more than one return value to a component's method.</entry>
    <entry xlink:href="#return-multiple-values"
          >Return more than one value from a component's method.</entry>
    <entry xlink:href="#pass-array"
          >Pass an array to a component's method.</entry>
    <entry xlink:href="#handle-array"
          >Handle a passed-in array in a component's method.</entry>
    <entry xlink:href="#properties-interface"
          >Access properties of an interface.</entry>
    <entry xlink:href="#properties-component"
          >Access properties of a component.</entry>
    <entry xlink:href="#property-getter-setter"
          >Define a component's property, and getters and setters therein.</entry>
    <entry xlink:href="#dump"
          >Dump a string to the debug console.</entry>
  </section>
</contents>

<items>
  <item id="comments">
    <task>Comments (useful for licensing)</task>

    <code type=".idl"><![CDATA[
/* This line is commented out (C style comments)
 */

// This line is commented out (C style comments)
    ]]></code>

    <code type=".h"><![CDATA[
/* This line is commented out (C style comments)
 */

// This line is commented out (C style comments)
    ]]></code>

    <code type=".cpp"><![CDATA[
/* This line is commented out (C style comments)
 */

// This line is commented out (C style comments)
    ]]></code>

    <code type=".js"><![CDATA[
/* This line is commented out (C style comments)
 */

// This line is commented out (C style comments)
    ]]></code>
  </item>
  <item id="template-scratch">
    <task>Create a template component from scratch.</task>

    <code type=".idl">
#include "nsISupports.idl"
<info id="uuid"/>
<instruction>Replace the uuid string below with a new UUID.</instruction>
<instruction>On irc://irc.mozilla.org, /msg firebot uuid</instruction>
<instruction>On Linux or Windows with CygWin, from the command line, type uuidgen.</instruction>

[scriptable, uuid(1a956d87-4399-4f2d-ab8e-b57e8c932c38)]
interface fooIBar : nsISupports {
};
    </code>

    <code type=".h">
<instruction>Find the generated fooIBar.h file in a subdirectory of
$(MOZ_OBJDIR)/dist/include.</instruction>
<instruction>It will contain a section resembling:</instruction>
/* Header file */
class fooBar : public fooIBar
{
public:
  NS_DECL_ISUPPORTS
  NS_DECL_FOOIBAR

  fooIBar();

private:
  ~fooIBar();

protected:
  /* additional members */
};

<instruction>Copy this section, stopping before the line:</instruction>
/* Implementation file */
    </code>

    <code type=".cpp">
<instruction>Find the generated fooIBar.h file in a subdirectory of 
$(MOZ_OBJDIR)/dist/include.</instruction>
<instruction>It will contain a section resembling:</instruction>
/* Implementation file */
NS_IMPL_ISUPPORTS1(fooBar, fooIBar)


fooBar::fooBar()
{
  /* member initializers and constructor code */
}

fooBar::~fooBar()
{
  /* destructor code */
}

<instruction>Copy this section, stopping before the line:</instruction>
/* End of implementation class template. */

<instruction>Don't forget to create a module cpp file for your component!</instruction>
    </code>

    <code type=".js">
<instruction>JavaScript components, unlike C++ components, include their
factory and module constructs in the same file.  Copy the code from
<file xlink:href="files/templateComponent.js" xlink:type="simple">templateComponent.js</file>,
filling in the license boilerplate (or removing it per licensing requirements),
and then changing these lines:</instruction>

// Do a global replace of "fooIBar" with your component's implemented interface name.
var componentIDL = "fooIBar";
// Do a global replace of "fooBar" with your component's constructor function name.
var componentConstructor = "fooBar";
/* Replace this UUID with a new one.  Do not use the one you used in the IDL file.
   See the <reference xlink:href="#uuid">above instructions</reference> on how to get a UUID.
 */
var componentId   = Components.ID("{758cfec1-0b29-4f39-aeae-7083f80eda5c}");
/* Replace this contract id with an appropriate one.  Use your website domain
   name, and a short component title.
 */
var contractId    = "@foo.org/bar-contract-id;1";
    </code>
  </item>

  <item id="create-module">
    <task>Create a module to register your component.</task>
    <code type=".idl"><instruction>Nothing to do here.</instruction></code>
    <code type=".h"><instruction>Nothing to do here.</instruction></code>
    <code type=".cpp"><not_documented/></code>
    <code type=".js">
<instruction>If you copied templateComponent.js and updated it for your needs,
there is nothing to do here.</instruction>
    </code>
  </item>

  <item>
    <task>Create a Makefile.in to build your component within Mozilla's source tree.</task>
    <code type=".in"><not_documented/></code>
  </item>

  <item>
    <task>Build your component without modifying Mozilla's source tree.</task>
    <code type=".idl">
<instruction>You'll need to build the XPIDL executable.  This will require you
have checked out the mozilla source code and set the $(MOZCONFIG) environment
variable.  Then:</instruction>

cd mozilla
make -f client.mk configure
cd $(MOZ_OBJDIR)
make tier_0 tier_1 tier_2

<instruction>Then change to your IDL's source directory.  XPT_LIB is the name
of the .xpt file you want to create, minus the extension.</instruction>

$(MOZ_OBJDIR)/dist/bin/xpidl -m typelib -o $(TARGET_DIR)/$(XPT_LIB) $(IDL_FILE)
    </code>
    <code type=".cpp"><not_documented/></code>
    <code type=".js">
<instruction>Follow the steps for IDL building.
Then copy the JS file to your target directory.</instruction>
    </code>
  </item>

  <item id="createInstance">
    <task>Get a new instance of a component.</task>
    <code type=".cpp">
nsresult rv;
nsCOMPtr&lt;fooIBar&gt; <sample>obj</sample> = do_CreateInstance(contractId, &amp;rv);
if (NS_FAILED(rv))
  return rv;
    </code>
    <code type=".js">
var <sample>obj</sample> = Components.classes[contractId]
                    .createInstance(Components.interfaces.fooIBar);
    </code>
  </item>

  <item id="getService">
    <task>Get a component as a service.</task>
    <code type=".cpp">
nsresult rv;
nsCOMPtr&lt;fooIBar&gt; <sample>obj</sample> = do_GetService(contractId, &amp;rv);
if (NS_FAILED(rv))
  return rv;
    </code>
    <code type=".js">
var <sample>obj</sample> = Components.classes[contractId]
                    .getService(Components.interfaces.fooIBar);
    </code>
  </item>

  <item id="addInterface">
    <task>Add an interface to your component for QueryInterface support.</task>
    <code type=".h">
<instruction>Add the interface name as a public base class for your class.</instruction>
class bazBaz : public fooIBar,
               public bazIWop
{
public:
  // nsISupports
  NS_DECL_NSISUPPORTS

  // fooIBar
  NS_DECL_FOOIBAR

<instruction>Add the interface name, prefixed by "NS_DECL_", and all in capital
letters, to the public portion of your component's class.</instruction>
  // bazIWop
  <sample>NS_DECL_BAZIWOP</sample>
}
    </code>
    <code type=".cpp">
<instruction>Find the generated fooIBar.h file in a subdirectory of 
$(MOZ_OBJDIR)/dist/include.</instruction>
<instruction>It will contain a section resembling:</instruction>
/* Implementation file */
NS_IMPL_ISUPPORTS1(fooBar, fooIBar)

fooBar::fooBar()
{
  /* member initializers and constructor code */
}

fooBar::~fooBar()
{
  /* destructor code */
}

<instruction>Copy this section, after the NS_IMPL_ISUPPORTS1 line, stopping
before the line:</instruction>
/* End of implementation class template. */
<instruction>In your C++ file, find the line that says NS_IMPL_ISUPPORTS with
a number at the end (NS_IMPL_ISUPPORTS1, NS_IMPL_ISUPPORTS2,
NS_IMPL_ISUPPORTS3, etc.)</instruction>
<instruction>Add one to that number (1 -> 2, 2 -> 3, etc.) and add the new
interface name as a new argument.  Using the example above, it might be:
</instruction>

NS_IMPL_ISUPPORTS<sample>2</sample>(fooBar, fooIBar, <sample>bazIWop</sample>)

<instruction>If you implement nsIClassInfo, adjust it accordingly.</instruction>
    </code>
    <code type=".js">
<instruction>For each method of the new interface, add a method to the
prototype which throws Components.results.NS_ERROR_NOT_IMPLEMENTED.  Using the
<file xlink:href="files/templateComponent.js" xlink:type="simple">templateComponent.js</file>
example, this might look like: </instruction>
fooIBar.prototype = {
  // bazIWop
  wop: function wop(arg1, arg2)
  {
    NOT_IMPLEMENTED();
  },

  /* ... */
}
<instruction>In the QueryInterface method of your constructor's prototype, add
a line for the new component.  If you're nice enough to have implemented
nsIClassInfo, add a line for that one too.  From the
<file xlink:href="files/templateComponent.js" xlink:type="simple">templateComponent.js</file>
example:</instruction>
    if (aIID.equals(Components.interfaces.fooIBar) ||
        <sample>aIID.equals(Components.interfaces.bazIWop) ||</sample>
        aIID.equals(Components.interfaces.nsISupports))
      return this;
    </code>
  </item>

  <item id="QI-component">
    <task>Query a component for support of a particular interface.</task>
    <code type=".cpp">
<![CDATA[bar = do_QueryInterface(fooIBar, &rv);]]>
// Test for an error code on rv.
</code>
    <code type=".js">
if (bar instanceof Components.interfaces.fooIBar)
{
  /* ... */
}
    </code>
  </item>

  <item>
    <task>Report to XPCOM that everything happened normally.</task>
    <code type=".cpp">
return NS_OK;
    </code>
    <code type=".js">
<instruction>Do not throw any exceptions, just return your out value.</instruction>
    </code>
  </item>

  <item id="report-error">
    <task>Report a XPCOM error code to XPCOM.</task>
    <code type=".cpp">
return NS_ERROR_(ERROR_NAME);
    </code>
    <code type=".js">
throw Components.results.NS_ERROR_(ERROR_NAME);
    </code>
  </item>


  <item id="handle-error">
    <task>Handle a XPCOM error code.</task>
    <code type=".cpp">
<instruction>C++ treats an XPCOM error as a returned value from a function.
So if you want a XPCOM error code to propagate, you need to call:</instruction>
NS_ENSURE_SUCCESS(rv, rv);

// Or

if (NS_FAILED(rv))
  return rv;

<instruction>If you want to selectively handle the error, use:</instruction>

if (rv == NS_ERROR_(ERROR_NAME))
{
  // ...
}

<instruction>Generally speaking, it is bad form not to check for XPCOM errors
in C++.</instruction>
    </code>
    <code type=".js">
<instruction>JavaScript treats XPCOM errors as thrown exceptions.  If you want
a XPCOM error to propagate, you need do nothing.</instruction>

<instruction>If you want to selectively handle the error, use:</instruction>
try
{
  // do method
}
catch (e)
{
  // Within XPCOM component code, e is a number.
  // Outside XPCOM component code, e is an error.
}
    </code>
  </item>

  <item id="check-is-null">
    <task>Check if a value is null.</task>
    <code type=".cpp">
<instruction>With nsCOMPtr's, you just need to check if the value itself evaluates to null in a condition.</instruction>
<sample>bar</sample> = do_QueryInterface(fooIBar);
if (!<sample>bar</sample>)
{
  // the value is null.
}

<instruction>With DOM strings, there is a convenience function.</instruction>
if (DOMStringIsNull(string))
{
  // the value is null.
}
    </code>
    <code type=".js">
<instruction>You should explicitly check against the null object.</instruction>
if (bar === null)
{
  // the value is null.
}

<instruction>If you know your value is an object, you can do this instead:</instruction>
var <sample>node</sample> = walker.nextNode();
if (!<sample>node</sample>)
{
  // the value is null.
}
    </code>
  </item>

  <item id="set-to-null">
    <task>Set a value to null.</task>
    <code type=".cpp">
<instruction>With nsCOMPtr's, you use the nsnull value.</instruction>
bar = nsnull;

<instruction>With DOM strings, you use the SetDOMStringToNull method.</instruction>
SetDOMStringToNull(bar);
    </code>
    <code type=".js">
bar = null;
    </code>
  </item>

  <item id="pass-current-arg">
    <task>Pass an argument you already have to a component's method (in parameter).</task>
    <code type=".cpp">
nsresult
nsXPathGenerator::GetStep(nsINode* iterator,
                          nsINode* aRoot,
                          <sample>nsXPathBaseNodeFilter * nodeListFilter</sample>,
                          nsString &amp; currentStep,
                          generatorWrapper &amp; data)
{
  // ...
  rv = traversal->CreateTreeWalker(rootAsDOM,
                                   whatToShow,
                                   <sample>nodeFilter</sample>,
                                   PR_TRUE,
                                   getter_AddRefs(walker));
 // ...
}
</code>
    <code type=".js">
fooBar = {
  getWop: function getWop(<sample>baz</sample>)
  {
    return this.getRealWop(<sample>baz</sample>);
  }
}</code>
  </item>

  <item id="pass-new-arg">
    <task>Pass an argument you created to a component's method (in parameter).</task>
    <code type=".cpp">
  nsCOMPtr&lt;nsIDOMNode&gt; <sample>rootAsDOM</sample> = do_QueryInterface(aRoot, &amp;rv);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = traversal->CreateTreeWalker(<sample>rootAsDOM</sample>,
                                   whatToShow,
                                   nodeFilter,
                                   PR_TRUE,
                                   getter_AddRefs(walker));
</code>
    <code type=".js">
const nsIDOMNodeFilter = Components.interfaces.nsIDOMNodeFilter;
var <sample>filter</sample> = {
  acceptNode: function acceptNode(aNode)
  {
    return Components.interfaces.nsIDOMNodeFilter.FILTER_SKIP;
  }
};

var walker = document.createTreeWalker(document, nsIDOMNodeFilter.SHOW_ELEMENT, <sample>filter</sample>, true);
    </code>
  </item>

  <item id="pass-current-return">
    <task>Pass a return argument you already have to a component's method.</task>
    <code type=".cpp">
nsresult
nsTreeWalker::FirstChildOf(nsINode* aNode,
                           PRBool aReversed,
                           PRInt32 aIndexPos,
                           <sample>nsINode** _retval</sample>)
{
    /* These lines don't matter for this example */
    *_retval = nsnull;
    PRInt32 start = aReversed ? (PRInt32)aNode->GetChildCount() : -1;

    return ChildOf(aNode, start, aReversed, aIndexPos, <sample>_retval</sample>);
}

/*
nsresult
nsTreeWalker::ChildOf(nsINode* aNode,
                      PRInt32 childNum,
                      PRBool aReversed,
                      PRInt32 aIndexPos,
                      <sample>nsINode** _retval</sample>)
 */

</code>
    <code type=".js">
<instruction>Just return what the component returns.</instruction>
return obj.doSomething();
    </code>
  </item>

  <item id="pass-new-return">
    <task>Pass a return argument you created to a component's method.</task>
    <code type=".cpp"><instruction>If it is a nsCOMPtr, do the following:</instruction>
nsresult rv = foo->bar(getter_AddRefs(ptr));
<instruction>If it is a primitive type (PRBool, PRUint, etc.), do the following:</instruction>
nsresult rv = foo->bar(&amp;value);</code>
    <code type=".js">
<instruction>You don't actually pass it in; it'll be what the method returns (if no exceptions
were thrown).</instruction>
retval = foo.bar();
    </code>
  </item>

  <item id="return-value">
    <task>Return a value from a component's method.</task>
    <code type=".cpp">
<instruction>Objects you must NS_ADDREF (except for null values).  If the value
may be null, use NS_IF_ADDREF(value).</instruction>
<instruction>Primitive types, or variants, do not get NS_ADDREF or NS_IF_ADDREF
called on them.</instruction>
// fooIBaz
NS_IMETHODIMP
fooBar::GetBaz(<sample>PRUint32 *aBaz</sample>)
{
  <sample>*aBaz</sample> = mBaz;
  return NS_OK;
}

//fooIBaz
NS_IMETHODIMP
fooBar::GetWop(<sample>nsIWop** aWop</sample>)
{
  NS_ADDREF(<sample>*aWop</sample> = mWop);
  return NS_OK;
}
    </code>
    <code type=".js">
return val;
    </code>
  </item>

  <item id="pass-multiple-return">
    <task>Pass more than one return value to a component's method.</task>
    <code type=".idl">
<instruction>IDL allows you to prefix params with the out keyword, for return values.</instruction>
PRBool test(in AString aTarget, out PRBool <sample>otherValue</sample>);

<instruction>Incidentally, the above IDL method declaration is equivalent to:</instruction>
void test(in AString aTarget, out PRBool <sample>otherValue</sample>, out PRBool <sample>_retval</sample>);

<instruction>XPIDL also allows you to prefix params with the inout keyword,
 for values that are passed in and return something different.</instruction>

void test(in AString aTarget, inout PRBool <sample>otherValue</sample>);
    </code>
    <code type=".cpp">
<instruction>Just set the out arguments as you normally would.
The function declaration will have the correct arrangement of arguments
you need to create.</instruction>
    </code>
    <code type=".js">
<instruction>The last out parameter of the IDL becomes the return value of the
method call.</instruction>
<instruction>Other out parameters should be passed in as objects.
Their .value property will be set to the returned value for that parameter.
</instruction>

var <sample>otherValue</sample> = {};
var <sample>_retval</sample> = obj.test("foo", <sample>otherValue</sample>);
<sample>otherValue</sample> = <sample>otherValue</sample>.value;

<instruction>For inout parameters, set the value property to the value you are
passing in, and the method will set the value property to the value it returns.
</instruction>
var <sample>otherValue</sample> = {value: true};
var <sample>_retval</sample> = obj.test("foo", <sample>otherValue</sample>);
<sample>otherValue</sample> = <sample>otherValue</sample>.value;
    </code>
  </item>

  <item id="return-multiple-values">
    <task>Return more than one value from a component's method.</task>
    <code type=".idl">
<instruction>IDL allows you to prefix params with the out keyword, for return values.</instruction>
PRBool test(in AString aTarget, out PRBool <sample>otherValue</sample>);

<instruction>Incidentally, the above IDL method declaration is equivalent to:</instruction>
void test(in AString aTarget, out PRBool <sample>otherValue</sample>, out PRBool <sample>_retval</sample>);

<instruction>XPIDL also allows you to prefix params with the inout keyword,
 for values that are passed in and return something different.</instruction>

void test(in AString aTarget, inout PRBool <sample>otherValue</sample>);
    </code>
    <code type=".cpp">
<instruction>If you are able to set a return value for one parameter in a C++
based component, you can set as many return values as you want.  Just repeat
the same process.</instruction>
    </code>
    <code type=".js">
<instruction>If the IDL specifies a void return, the last out param of the IDL definition
becomes your return value.</instruction>
<instruction>If the IDL specifies a non-void return, that becomes your return value.</instruction>
<instruction>For all other out parameters, you must set each out parameter's value property
to the value you intend to return.</instruction>
var <sample>_retval</sample> = false;
<sample>otherValue</sample>.value = true;
return <sample>_retval</sample>;
    </code>
  </item>

  <item id="pass-array">
    <task>Pass an array to a component's method.</task>
    <code type=".idl">
<instruction>There are actually two ways IDL can define an array.  The first is as a pair of arguments:
the length of the array, and the actual array itself.</instruction>
void PrintIntegerArray(in PRUint32 <sample>count</sample>, 
                       [array, size_is(count)] in PRInt32 <sample>valueArray</sample>);
<instruction>The second is to declare a 
<html:a href="lxr.mozilla.org/seamonkey/source/xpcom/ds/nsIArray.idl">nsIArray</html:a>
or
<html:a href="lxr.mozilla.org/seamonkey/source/xpcom/ds/nsIMutableArray.idl">nsIMutableArray</html:a>
argument.  nsIArray is read-only, while nsIMutableArray is read and write.</instruction>
void CreateEncrypted(in nsIArray <sample>aRecipientCerts</sample>);
<instruction>For nsIArray and nsIMutableArray, the class name is:</instruction>
"@mozilla.org/array;1"
<instruction>As a rule of thumb, use XPIDL-based arrays for arrays of a single
primitive type, in or out (not inout). For anything else, use nsIArray or
nsIMutableArray.</instruction>
<instruction>Note XPIDL-based arrays do not do refcounting (AddRef, Release) on members.</instruction>
    </code>
    <code type=".cpp">
<instruction>You treat XPIDL-based arrays and multiple objects in the same way.</instruction>
<instruction>The following is borrowed from
http://lxr.mozilla.org/seamonkey/source/js/src/xpconnect/src/xpcwrappednativeinfo.cpp .
</instruction>
    nsIID** <sample>iidArray</sample> = nsnull;
    PRUint32 <sample>iidCount</sample> = 0;
    nsresult rv = classInfo->GetInterfaces(&amp;<sample>iidCount</sample>, &amp;<sample>iidArray</sample>);
</code>
    <code type=".js">
<instruction>You treat XPIDL-based arrays and multiple objects in the same way.</instruction>
var count = {};
var <sample>valueArray</sample> = obj.printIntegerArray(<sample>count</sample>);
// <sample>valueArray</sample>.length should be <sample>count</sample>.value;
    </code>
  </item>

  <item id="handle-array">
    <task>Handle a passed-in XPIDL-based array in a component's method.</task>
    <code type=".cpp">
<instruction>This code was borrowed from
http://lxr.mozilla.org/seamonkey/source/extensions/xforms/nsXFormsStubElement.cpp .</instruction>
NS_IMETHODIMP
nsXFormsStubElement::GetScriptingInterfaces(PRUint32 *<sample>aCount</sample>, nsIID ***<sample>aArray</sample>)
{
  return nsXFormsUtils::CloneScriptingInterfaces(sScriptingIIDs,
                                                 NS_ARRAY_LENGTH(sScriptingIIDs),
                                                 <sample>aCount</sample>, <sample>aArray</sample>);
}

<instruction>This code was borrowed from
http://lxr.mozilla.org/seamonkey/source/extensions/xforms/nsXFormsUtils.cpp .</instruction>
<instruction>Keep your eyes on the pointers (*aOutArray, **iids, ***aOutArray).</instruction>
/* static */ nsresult
nsXFormsUtils::CloneScriptingInterfaces(const nsIID *aIIDList,
                                        unsigned int aIIDCount,
                                        PRUint32 *<sample>aOutCount</sample>,
                                        nsIID ***<sample>aOutArray</sample>)
{
  nsIID **iids = NS_STATIC_CAST(nsIID**,
                                nsMemory::Alloc(aIIDCount * sizeof(nsIID*)));
  if (!iids) {
    return NS_ERROR_OUT_OF_MEMORY;
  }
 
  for (PRUint32 i = 0; i &lt; aIIDCount; ++i) {
    iids[i] = NS_STATIC_CAST(nsIID*,
                             nsMemory::Clone(&amp;aIIDList[i], sizeof(nsIID)));
 
    if (!iids[i]) {
      for (PRUint32 j = 0; j &lt; i; ++j)
        nsMemory::Free(iids[j]);
      nsMemory::Free(iids);
      return NS_ERROR_OUT_OF_MEMORY;
    }
  }
 
  *<sample>aOutArray</sample> = iids;
  *<sample>aOutCount</sample> = aIIDCount;
  return NS_OK;
}
    </code>
    <code type=".js">
<instruction>Remember to set the length of the array as the value of the length object.</instruction>
/* 
  void exec(in AString aTarget,
            out unsigned long <sample>aCount</sample>,
            [retval, array, size_is(<sample>aCount</sample>)] out wstring <sample>aValues</sample>);
 */
function exec(aTarget, <sample>aCount</sample>)
{
  var <sample>aValues</sample> = this.regexp.exec(aTarget);
  aCount.value  = <sample>aValues</sample>.length;
  return <sample>aValues</sample>;
}
    </code>
  </item>

  <item id="properties-interface">
    <task>Access properties of an interface.</task>
    <code type=".cpp">
fooIBar::PROPERTY_NAME
    </code>
    <code type=".js">
Components.interfaces.fooIBar.PROPERTY_NAME
    </code>
  </item>

  <item id="properties-component">
    <task>Access properties of a component.</task>
    <code type=".cpp">
nsCOMPtr&lt;nsIFooBar&gt; fooBarPtr = do_QueryInterface(component, &amp;rv);
NS_ENSURE_SUCCESS(rv, rv);
PRBool <sample>myBaz</sample>;
rv = fooBarPtr->GetBaz(&amp;<sample>myBaz</sample>);
NS_ENSURE_SUCCESS(rv, rv);

nsCOMPtr&lt;nsIWop&gt; <sample>myWop</sample>;
rv = fooBarPtr->GetWop(<sample>myWop</sample>);
NS_ENSURE_SUCCESS(rv, rv);

// Your value now lives in *<sample>myWop</sample>.
    </code>
    <code type=".js">
// QI the component to the interface first.
<sample>myWop</sample> = component.wop;
    </code>
  </item>

  <item id="property-getter-setter">
    <task>Define a component's property, and getters and setters therein.</task>
    <code type=".idl">
  attribute PRUint32 <sample>baz</sample>;
  attribute nsIWop <sample>wop</sample>;
    </code>
    <code type=".h">
<instruction>This should be handled by your importing the IDL header.</instruction>
    </code>
    <code type=".cpp">
fooBar::fooBar() :
  mBaz(0),
  mWop(nsnull)
{
}

// fooIBar baz property 
NS_IMETHODIMP
fooBar::GetBaz(PRUint32 <sample>*aBaz</sample>)
{
  <sample>*aBaz</sample> = mBaz;
  return NS_OK;
}
NS_IMETHODIMP
fooBar::SetBaz(PRUint32 <sample>aBaz</sample>)
{
  mBaz = <sample>aBaz</sample>;
  return NS_OK;
}

// fooIBar wop property
NS_IMETHODIMP
fooBar::GetWop(nsIWop** <sample>aWop</sample>)
{
  NS_ADDREF(<sample>*aWop</sample> = mWop);
  return NS_OK;
}
NS_IMETHODIMP
fooBar::SetWop(nsIWop* <sample>aWop</sample>)
{
  mWop = <sample>aWop</sample>;
}
    </code>
    <code type=".js">
<instruction>One way is just to name the property in the constructor.</instruction>
function fooBar() {
  // fooIBar
  this.baz = 0;
}

<instruction>A more flexible way is to use getters and setters.</instruction>
function fooBar() {
  this.mBaz = 0;
}
fooBar.prototype = {

  // fooIBaz
  get baz() {
    return this.mBaz;
  }
  set baz(aBaz) {
    this.mBaz = aBaz;
  }

}
    </code>
  </item>

  <item id="dump">
    <task>Dump a string to the debug console.</task>
    <code type=".cpp">
#ifdef DEBUG
printf "This is going to the console.\n";
#endif
    </code>
    <code type=".js">
var str = "This is going to the console.\n";
dump(str);
    </code>
  </item>
</items>

<interfaces>
  <interface name="nsISupports">
<instruction>Your basic QueryInterface, AddRef, Release implementation.</instruction>
<instruction>For JS-based components, you only need to implement QueryInterface.</instruction>
  </interface>
  <interface name="nsIDOMClassInfo"><not_documented/></interface>
  <interface name="nsISecurityCheckedComponent"><not_documented/></interface>
  <interface name="nsIConsoleService"><not_documented/></interface>
  <interface name="nsIObserverService"><not_documented/></interface>
  <interface name="nsIObserver"><not_documented/></interface>
  <interface name="nsIDOMNode"><not_documented/></interface>
  <interface name="nsIDOM3Node"><not_documented/></interface>
</interfaces>
</root>
