Bug 1637515 [wpt PR 23559] - Update wpt metadata, a=testonly
[gecko.git] / build / docs / defining-xpcom-components.rst
blob2621ad7d1f369cedf0b736b400aa4f5bc142a1df
1 .. _defining_xpcom_components:
3 =========================================
4 Defining XPCOM C++-implemented Components
5 =========================================
7 Native XPCOM components are registered at build time, and compiled into static
8 data structures which allow them to be accessed with little runtime overhead.
9 Each module which wishes to register components must provide a manifest
10 describing each component it implements, its type, and how it should be
11 constructed.
13 Manifest files are Python data files registered in ``moz.build`` files in a
14 ``XPCOM_MANIFESTS`` file list:
16 .. code-block:: python
18     XPCOM_MANIFESTS += [
19       'components.conf',
20     ]
22 The files may define any of the following special variables:
24 .. code-block:: python
26     # Optional: A function to be called once, the first time any component
27     # listed in this manifest is instantiated.
28     InitFunc = 'nsInitFooModule'
29     # Optional: A function to be called at shutdown if any component listed in
30     # this manifest has been instantiated.
31     UnloadFunc = 'nsUnloadFooModule'
32     
33     # Optional: A processing priority, to determine how early or late the
34     # manifest is processed. Defaults to 50. In practice, this mainly affects
35     # the order in which unload functions are called at shutdown, with higher
36     # priority numbers being called later.
37     Priority = 10
38     
39     # Optional: A list of header files to include before calling init or
40     # unload functions, or any legacy constructor functions.
41     #
42     # Any header path beginning with a `/` is loaded relative to the root of
43     # the source tree, and must not rely on any local includes.
44     #
45     # Any relative header path must be exported.
46     Headers = [
47         '/foo/nsFooModule.h',
48         'nsFoo.h',
49     ]
50     
51     # A list of component classes provided by this module.
52     Classes = [
53         {
54             # ...
55         },
56         # ...
57     ]
59 Class definitions may have the following properties:
61 ``name`` (optional)
62   If present, this component will generate an entry with the given name in the
63   ``mozilla::components`` namespace in ``mozilla/Components.h``, which gives
64   easy access to its CID, service, and instance constructors as (e.g.,)
65   ``components::Foo::CID()``, ``components::Foo::Service()``, and
66   ``components::Foo::Create()``, respectively.
68 ``cid``
69   A UUID string containing this component's CID, in the form 
70   ``'{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}'``.
72 ``contract_ids`` (optional)
73   A list of contract IDs to register for this class.
75 ``categories`` (optional)
76   A dict of category entries to register for this component's contract ID.
77   Each key in the dict is the name of the category. Each value is either a
78   string containing a single entry name, or a list of entry name strings.
80 ``type`` (optional, default=``nsISupports``)
81   The fully-qualified type of the class implementing this component. Defaults
82   to ``nsISupports``, but **must** be provided if the ``init_method`` property
83   is specified, or if neither the ``constructor`` nor ``legacy_constructor``
84   properties are provided.
86 ``headers`` (optional)
87   A list of headers to include in order to call this component's constructor,
88   in the same format as the global ``Headers`` property.
90 ``init_method`` (optional)
91   The name of a method to call on newly-created instances of this class before
92   returning them. The method must take no arguments, and must return a
93   ``nsresult``. If it returns failure, that failure is propagated to the
94   ``getService`` or ``createInstance`` caller.
96 ``constructor`` (optional)
97   The fully-qualified name of a constructor function to call in order to
98   create instances of this class. This function must be declared in one of the
99   headers listed in the ``headers`` property, must take no arguments, and must
100   return ``already_AddRefed<iface>`` where ``iface`` is the interface provided
101   in the ``type`` property.
102   
103   This property is incompatible with ``legacy_constructor``.
105 ``jsm`` (optional)
106   If provided, must be the URL of a JavaScript module which contains a
107   JavaScript implementation of the component. The ``constructor`` property
108   must contain the name of an exported function which can be constructed to
109   create a new instance of the component.
111 ``legacy_constructor`` (optional)
112   This property is deprecated, and should not be used in new code.
113   
114   The fully-qualified name of a constructor function to call in order to
115   create instances of this class. This function must be declared in one of the
116   headers listed in the ``headers`` property, and must have the signature
117   ``nsresult(nsISupports* aOuter, const nsID& aIID, void** aResult)``, and
118   behave equivalently to ``nsIFactory::CreateInstance``.
119   
120   This property is incompatible with ``constructor``.
122 ``singleton`` (optional, default=``False``)
123   If true, this component's constructor is expected to return the same
124   singleton for every call, and no ``mozilla::components::<name>::Create()``
125   method will be generated for it.
127 ``overridable`` (optional, default=``False``)
128   If true, this component's contract ID is expected to be overridden by some
129   tests, and its ``mozilla::components::<name>::Service()`` getter will
130   therefore look it up by contract ID for every call. This component must,
131   therefore, provide at least one contract ID in its ``contract_ids`` array.
132   
133   If false, the ``Service()`` getter will always retrieve the service based on
134   its static data, and it cannot be overridden.
135   
136   Note: Enabling this option is expensive, and should not be done when it can
137   be avoided, or when the getter is used by any hot code.
139 ``external`` (optional, default=``False`` if any ``headers`` are provided, ``True`` otherwise)
140   If true, a constructor for this component's ``type`` must be defined in
141   another translation unit, using ``NS_IMPL_COMPONENT_FACTORY(type)``. The
142   constructor must return an ``already_AddRefed<nsISupports>``, and will be
143   used to construct instances of this type.
144   
145   This option should only be used in cases where the headers which define the
146   component's concrete type cannot be easily included without local includes.
147   
148   Note: External constructors may not specify an ``init_method``, since the
149   generated code will not have the necessary type information required to call
150   it. This option is also incompatible with ``constructor`` and
151   ``legacy_constructor``.
153 ``processes`` (optional, default=``ProcessSelector.ANY_PROCESS``)
154   An optional specifier restricting which types of process this component may
155   be loaded in. This must be a property of ``ProcessSelector`` with the same
156   name as one of the values in the ``Module::ProcessSelector`` enum.
159 Conditional Compilation
160 =======================
162 This manifest may run any appropriate Python code to customize the values of
163 the ``Classes`` array based on build configuration. To simplify this process,
164 the following globals are available:
166 ``defined``
167   A function which returns true if the given build config setting is defined
168   and true.
170 ``buildconfig``
171   The ``buildconfig`` python module, with a ``substs`` property containing a
172   dict of all available build substitutions.
175 Component Constructors
176 ======================
178 There are several ways to define component constructors, which vary mostly
179 depending on how old the code that uses them is:
181 Class Constructors
182 ------------------
184 This simplest way to define a component is to include a header defining a
185 concrete type, and let the component manager call that class's constructor:
187 .. code-block:: python
189   'type': 'mozilla::foo::Foo',
190   'headers': ['mozilla/Foo.h'],
192 This is generally the preferred method of defining non-singleton constructors,
193 but may not be practicable for classes which rely on local includes for their
194 definitions.
196 Singleton Constructors
197 ----------------------
199 Singleton classes are generally expected to provide their own constructor
200 function which caches a singleton instance the first time it is called, and
201 returns the same instance on subsequent calls. This requires declaring the
202 constructor in an included header, and implementing it in a separate source
203 file:
205 .. code-block:: python
207   'type': 'mozilla::foo::Foo',
208   'headers': ['mozilla/Foo.h'],
209   'constructor': 'mozilla::Foo::GetSingleton',
211 ``Foo.h``
213 .. code-block:: c++
215     class Foo final : public nsISupports {
216      public:
217       static already_AddRefed<Foo> GetSingleton();
218     };
220 ``Foo.cpp``
222 .. code-block:: c++
224     already_AddRefed<Foo> Foo::GetSingleton() {
225       // ...
226     }
228 External Constructors
229 ---------------------
231 For types whose headers can't easily be included, constructors can be defined
232 using a template specialization on an incomplete type:
234 .. code-block:: python
236   'type': 'mozilla::foo::Foo',
237   'external: True,'
239 ``Foo.cpp``
241 .. code-block:: c++
243     NS_IMPL_COMPONENT_FACTORY(Foo) {
244       return do_AddRef(new Foo()).downcast<nsISupports>();
245     }
247 Legacy Constructors
248 -------------------
250 These should not be used in new code, and are left as an exercise for the
251 reader.
254 Registering Categories
255 ======================
257 Classes which need define category entries with the same value as their
258 contract ID may do so using the following:
260 .. code-block:: python
262     'contract_ids': ['@mozilla.org/foo;1'],
263     'categories': {
264         'content-policy': 'm-foo',
265         'Gecko-Content-Viewers': ['image/jpeg', 'image/png'],
266     },
268 This will define each of the following category entries:
270 * ``"content-policy"`` ``"m-foo",`` ``"@mozilla.org/foo;1"``
271 * ``"Gecko-Content-Viewers"`` ``"image/jpeg"`` ``"@mozilla.org/foo;1"``
272 * ``"Gecko-Content-Viewers"`` ``"image/png"`` ``"@mozilla.org/foo;1"``