For support and discussion:
This document describes some dos and don'ts when writing an interface in IDL for Mozilla. For a complete guide, see the How To Freeze document.
/* don't capitalize first letters! */
void OpenFile(in nsIFile file);
attribute AString Filename;
/* Avoid underscores! */
attribute long unknown_entries;
void openFile(in nsIFile file);
attribute AString filename;
attribute long unknownEntries;
/* These refer to the same value, why make them functions? */
long getColorValue();
void setColorValue(in long value);
/* we just want a getter, but we can still use an attribute!
* besides, a method implies an action. */
long brightness();
attribute long colorValue;
readonly attribute long brightness;
/* seems a bit verbose */
readonly attribute long numberOfEntries;
/* why shorten this? is this Attribute? Attrition? */
long getAttrCount(in ACString name);
readonly attribute long entryCount;
long getAttributeCount(in ACString name);
nsA- string classes are more efficient than the "string" type. /* use the new string classes! */
void processName(in string name);
/* high bit will get stripped by XPConnect. is that ok? */
void fillBuffer(in string data);
/* new string classes will avoid excess allocation,
* especially when the caller uses nsCAutoString */
void getHeaderValues(out string prefix, out string postfix);
void processName(in ACString name);
void fillBuffer(in ACString data);
void getHeaderValues(out ACString prefix, out ACString postfix);
AString or AUTF8String to represent unicode strings. Avoid
the "wstring" type where possible.nsA- string classes are more efficient than the old "wstring" type. /* Even if errorMsg is UTF8, it will get corrupted by XPConnect */
void displayError(in string errorMsg);
/* use AString to allow fragment to have a length */
void parseFragment(in wstring fragment);
void displayError(in AUTF8String errorMsg);
void parseFragment(in AString fragment);
out parametersout parameters are extra work for scripts, which must create a temporary object to hold the
resulting value. /* This will be frustrating to call from a script */
void getHeaderValue(in ACString header, out AString value);
/* why isn't this just an attribute? */
void getLinkSource(out AString source);
AString getHeaderValue(in ACString header);
readonly attribute AString linkSource;
#includes. /* Can't compile the idl file without this, we derive from nsISupports */
#include "nsISupports.idl"
/* does every consumer need to also include this? */
#include "nsIAtom.idl"
/* Need this for definition of PRThreadPriority */
#include "nsIThread.idl"
interface nsIFoo : nsISupports {
void setThreadPriority(in nsIThread thread, in PRThreadPriority pri);
nsIAtom getThreadAtom(in nsIThread thread);
};
/* Can't compile the idl file without this */
#include "nsISupports.idl"
/* Need this for definition of PRThreadPriority */
#include "nsIThread.idl"
/* Let consumers #include the right header if they need the full definition. */
interface nsIAtom;
interface nsIFoo : nsISupports {
...
};
#include only other .idl files.#include the correct header.
#include a .h file in order to get the definition, you may have problems
with the generated header if the #included .h file changes later. Excessive #includes
can also cause unnecessary rebuilding when a header changes. %{C
#include "nsIArena.h" /* C++ only header */
#include "nsIThread.h" /* Available as nsIThread.idl */
%}
/* now have to predeclare nsIThread since IDL doesn't know about it */
interface nsIThread;
/* If header is available (and we really need it) just #include it */
#include "nsIThread.idl"
/* otherwise, predeclare it */
interface nsIArena;
// nsIFoo.idl:
%{C
// ugh! This doesn't belong in IDL!
#define NS_FOO_CONTRACTID "@mozilla.org/foo/component;1"
%}
// nsIFoo.idl contains only true IDL
...
// nsFoo.h contains the ContractID declaration:
...
#define NS_FOO_CONTRACTID "@mozilla.org/foo/component;1"
...