Bug 1852754: part 9) Add tests for dynamically loading <link rel="prefetch"> elements...
[gecko.git] / build / docs / defining-xpcom-components.rst
blob51a1bb4fed854cd81602375f479f2fda77903657
1 .. _defining_xpcom_components:
3 =========================================
4 Defining XPCOM C++-implemented Components
5 =========================================
7 This document explains how to write a :code:`components.conf` file. For
8 documentation on the idl format see :ref:`XPIDL`. For a tutorial on writing
9 a new XPCOM interface, see
10 :ref:`writing_xpcom_interface`.
12 Native XPCOM components are registered at build time, and compiled into static
13 data structures which allow them to be accessed with little runtime overhead.
14 Each module which wishes to register components must provide a manifest
15 describing each component it implements, its type, and how it should be
16 constructed.
18 Manifest files are Python data files registered in ``moz.build`` files in a
19 ``XPCOM_MANIFESTS`` file list:
21 .. code-block:: python
23     XPCOM_MANIFESTS += [
24       'components.conf',
25     ]
27 The files may define any of the following special variables:
29 .. code-block:: python
31     # Optional: A function to be called once, the first time any component
32     # listed in this manifest is instantiated.
33     InitFunc = 'nsInitFooModule'
34     # Optional: A function to be called at shutdown if any component listed in
35     # this manifest has been instantiated.
36     UnloadFunc = 'nsUnloadFooModule'
38     # Optional: A processing priority, to determine how early or late the
39     # manifest is processed. Defaults to 50. In practice, this mainly affects
40     # the order in which unload functions are called at shutdown, with higher
41     # priority numbers being called later.
42     Priority = 10
44     # Optional: A list of header files to include before calling init or
45     # unload functions, or any legacy constructor functions.
46     #
47     # Any header path beginning with a `/` is loaded relative to the root of
48     # the source tree, and must not rely on any local includes.
49     #
50     # Any relative header path must be exported.
51     Headers = [
52         '/foo/nsFooModule.h',
53         'nsFoo.h',
54     ]
56     # A list of component classes provided by this module.
57     Classes = [
58         {
59             # ...
60         },
61         # ...
62     ]
64     # A list of category registrations
65     Categories = {
66         'category': {
67             'name': 'value',
68             'other-name': ('value', ProcessSelector.MAIN_PROCESS_ONLY),
69             # ...
70         },
71         # ...
72     }
74 Class definitions may have the following properties:
76 ``name`` (optional)
77   If present, this component will generate an entry with the given name in the
78   ``mozilla::components`` namespace in ``mozilla/Components.h``, which gives
79   easy access to its CID, service, and instance constructors as (e.g.,)
80   ``components::Foo::CID()``, ``components::Foo::Service()``, and
81   ``components::Foo::Create()``, respectively.
83 ``cid``
84   A UUID string containing this component's CID, in the form
85   ``'{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}'``.
87 ``contract_ids`` (optional)
88   A list of contract IDs to register for this class.
90 ``categories`` (optional)
91   A dict of category entries to register for this component's contract ID.
92   Each key in the dict is the name of the category. Each value is either a
93   string containing a single entry, or a list of entries.  Each entry is either
94   a string name, or a dictionary of the form ``{'name': 'value', 'backgroundtasks':
95   BackgroundTasksSelector.ALL_TASKS}``.  By default, category entries are registered
96   for **no background tasks**: they have
97   ``'backgroundtasks': BackgroundTasksSelector.NO_TASKS``.
99 ``type`` (optional, default=``nsISupports``)
100   The fully-qualified type of the class implementing this component. Defaults
101   to ``nsISupports``, but **must** be provided if the ``init_method`` property
102   is specified, or if neither the ``constructor`` nor ``legacy_constructor``
103   properties are provided.
105 ``headers`` (optional)
106   A list of headers to include in order to call this component's constructor,
107   in the same format as the global ``Headers`` property.
109 ``init_method`` (optional)
110   The name of a method to call on newly-created instances of this class before
111   returning them. The method must take no arguments, and must return a
112   ``nsresult``. If it returns failure, that failure is propagated to the
113   ``getService`` or ``createInstance`` caller.
115 ``constructor`` (optional)
116   The fully-qualified name of a constructor function to call in order to
117   create instances of this class. This function must be declared in one of the
118   headers listed in the ``headers`` property, must take no arguments, and must
119   return ``already_AddRefed<iface>`` where ``iface`` is the interface provided
120   in the ``type`` property.
122   This property is incompatible with ``legacy_constructor``.
124 ``jsm`` (optional)
125   If provided, must be the URL of a JavaScript module which contains a
126   JavaScript implementation of the component. The ``constructor`` property
127   must contain the name of an exported function which can be constructed to
128   create a new instance of the component.
130 ``legacy_constructor`` (optional)
131   This property is deprecated, and should not be used in new code.
133   The fully-qualified name of a constructor function to call in order to
134   create instances of this class. This function must be declared in one of the
135   headers listed in the ``headers`` property, and must have the signature
136   ``nsresult(const nsID& aIID, void** aResult)``, and behave equivalently to
137   ``nsIFactory::CreateInstance``.
139   This property is incompatible with ``constructor``.
141 ``singleton`` (optional, default=``False``)
142   If true, this component's constructor is expected to return the same
143   singleton for every call, and no ``mozilla::components::<name>::Create()``
144   method will be generated for it.
146 ``overridable`` (optional, default=``False``)
147   If true, this component's contract ID is expected to be overridden by some
148   tests, and its ``mozilla::components::<name>::Service()`` getter will
149   therefore look it up by contract ID for every call. This component must,
150   therefore, provide at least one contract ID in its ``contract_ids`` array.
152   If false, the ``Service()`` getter will always retrieve the service based on
153   its static data, and it cannot be overridden.
155   Note: Enabling this option is expensive, and should not be done when it can
156   be avoided, or when the getter is used by any hot code.
158 ``external`` (optional, default=``False`` if any ``headers`` are provided, ``True`` otherwise)
159   If true, a constructor for this component's ``type`` must be defined in
160   another translation unit, using ``NS_IMPL_COMPONENT_FACTORY(type)``. The
161   constructor must return an ``already_AddRefed<nsISupports>``, and will be
162   used to construct instances of this type.
164   This option should only be used in cases where the headers which define the
165   component's concrete type cannot be easily included without local includes.
167   Note: External constructors may not specify an ``init_method``, since the
168   generated code will not have the necessary type information required to call
169   it. This option is also incompatible with ``constructor`` and
170   ``legacy_constructor``.
172 ``processes`` (optional, default=``ProcessSelector.ANY_PROCESS``)
173   An optional specifier restricting which types of process this component may
174   be loaded in. This must be a property of ``ProcessSelector`` with the same
175   name as one of the values in the ``Module::ProcessSelector`` enum.
178 Conditional Compilation
179 =======================
181 This manifest may run any appropriate Python code to customize the values of
182 the ``Classes`` array based on build configuration. To simplify this process,
183 the following globals are available:
185 ``defined``
186   A function which returns true if the given build config setting is defined
187   and true.
189 ``buildconfig``
190   The ``buildconfig`` python module, with a ``substs`` property containing a
191   dict of all available build substitutions.
194 Component Constructors
195 ======================
197 There are several ways to define component constructors, which vary mostly
198 depending on how old the code that uses them is:
200 Class Constructors
201 ------------------
203 This simplest way to define a component is to include a header defining a
204 concrete type, and let the component manager call that class's constructor:
206 .. code-block:: python
208   'type': 'mozilla::foo::Foo',
209   'headers': ['mozilla/Foo.h'],
211 This is generally the preferred method of defining non-singleton constructors,
212 but may not be practicable for classes which rely on local includes for their
213 definitions.
215 Singleton Constructors
216 ----------------------
218 Singleton classes are generally expected to provide their own constructor
219 function which caches a singleton instance the first time it is called, and
220 returns the same instance on subsequent calls. This requires declaring the
221 constructor in an included header, and implementing it in a separate source
222 file:
224 .. code-block:: python
226   'type': 'mozilla::foo::Foo',
227   'headers': ['mozilla/Foo.h'],
228   'constructor': 'mozilla::Foo::GetSingleton',
230 ``Foo.h``
232 .. code-block:: c++
234     class Foo final : public nsISupports {
235      public:
236       static already_AddRefed<Foo> GetSingleton();
237     };
239 ``Foo.cpp``
241 .. code-block:: c++
243     already_AddRefed<Foo> Foo::GetSingleton() {
244       // ...
245     }
247 External Constructors
248 ---------------------
250 For types whose headers can't easily be included, constructors can be defined
251 using a template specialization on an incomplete type:
253 .. code-block:: python
255   'type': 'mozilla::foo::Foo',
256   'external: True,'
258 ``Foo.cpp``
260 .. code-block:: c++
262     NS_IMPL_COMPONENT_FACTORY(Foo) {
263       return do_AddRef(new Foo()).downcast<nsISupports>();
264     }
266 Legacy Constructors
267 -------------------
269 These should not be used in new code, and are left as an exercise for the
270 reader.
273 Registering Categories
274 ======================
276 Classes which need define category entries with the same value as their
277 contract ID may do so using the following:
279 .. code-block:: python
281     'contract_ids': ['@mozilla.org/foo;1'],
282     'categories': {
283         'content-policy': 'm-foo',
284         'Gecko-Content-Viewers': ['image/jpeg', 'image/png'],
285     },
287 This will define each of the following category entries:
289 * ``"content-policy"`` ``"m-foo",`` ``"@mozilla.org/foo;1"``
290 * ``"Gecko-Content-Viewers"`` ``"image/jpeg"`` ``"@mozilla.org/foo;1"``
291 * ``"Gecko-Content-Viewers"`` ``"image/png"`` ``"@mozilla.org/foo;1"``
293 Some category entries do not have a contract ID as a value. These entries can
294 be specified by adding to a global ``Categories`` dictionary:
296 .. code-block:: python
298     Categories = {
299         'update-timer': {
300             'nsUpdateService': '@mozilla.org/updates/update-service;1,getService,background-update-timer,app.update.interval,43200,86400',
301         }
302     }
304 It is possible to limit these on a per-process basis by using a tuple as the
305 value:
307 .. code-block:: python
309     Categories = {
310         '@mozilla.org/streamconv;1': {
311             '?from=gzip&to=uncompressed': ('', ProcessSelector.ALLOW_IN_SOCKET_PROCESS),
312         }
313     }