tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

index.rst (28280B)


      1 ============
      2 DevTools API
      3 ============
      4 
      5 .. warning::
      6  Deprecated: This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the compatibility table at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time.
      7 
      8 .. warning::
      9  The DevTools API is still WIP. If you notice any inconsistency, please let The Firefox Developer Tools Team know.
     10 
     11 
     12 While this api is currently a work-in-progress, there are usable portions of :doc:`page inspector <../page_inspector/index>` and :doc:`debugger <../debugger/index>` that may be used currently.
     13 
     14 
     15 Introduction
     16 ************
     17 
     18 The DevTools API provides a way to register and access developer tools in Firefox.
     19 
     20 In terms of User Interface, each registered tool lives in its own tab (we call one tab a **panel**). These tabs are located in a box we call a **Toolbox**. A toolbox can be *hosted* within a browser tab (at the bottom or on the side), or in its own window (we say that the toolbox is *undocked*). A Toolbox (and all the tools it contains) is linked to a **Target**, which is the object the tools are debugging. A target is usually a web page (a tab), but can be other things (a chrome window, a remote tab,…).
     21 
     22 In terms of code, each tool has to provide a **ToolDefinition** object. A definition is a JS light object that exposes different information about the tool (like its name and its icon), and a *build* method that will be used later-on to start an instance of this tool. The **gDevTools** global object provides methods to register a tool definition and to access tool instances. An instance of a tool is called a **ToolPanel**. The ToolPanel is built only when the tool is selected (not when the toolbox is opened). There is no way to "close/destroy" a ToolPanel. The only way to close a toolPanel is to close its containing toolbox. All these objects implement the **EventEmitter** interface.
     23 
     24 
     25 API
     26 ***
     27 
     28 gDevTools
     29 ---------
     30 
     31 The ``gDevTools`` API can be used to register new tools, themes and handle toolboxes for different tabs and windows. To use the ``gDevTools`` API from an add-on, it can be imported with following snippet
     32 
     33 .. code-block:: JavaScript
     34 
     35  const { gDevTools } = require("resource:///modules/devtools/gDevTools.jsm");
     36 
     37 
     38 Methods
     39 ~~~~~~~
     40 
     41 ``registerTool(toolDefinition)``
     42  Registers a new tool and adds a tab to each existing toolbox.
     43 
     44  **Parameters:**
     45 
     46  - ``toolDefinition {ToolDefinition}`` - An object that contains information about the tool. See :ref:`ToolDefinition <devtoolsapi-tool-definition>` for details.
     47 
     48 ``unregisterTool(toolId)``
     49  Unregisters the given tool and removes it from all toolboxes.
     50 
     51  **Parameters:**
     52 
     53  - ``tool {ToolDefinition|String}`` - The tool definition object or the id of the tool to unregister.
     54 
     55 ``registerTheme(themeDefinition)``
     56  Registers a new theme.
     57 
     58  **Parameters:**
     59 
     60  - ``themeDefinition {ThemeDefinition}`` - An object that contains information about the theme.
     61 
     62 ``unregisterTheme(theme)``
     63  Unregisters the given theme.
     64 
     65  **Parameters:**
     66 
     67  - ``theme {ThemeDefinition|String}`` - The theme definition object or the theme identifier.
     68 
     69 ``showToolbox(commands[, toolId [, hostType [, hostOptions]]])``
     70  Opens a toolbox for given target either by creating a new one or activating an existing one.
     71 
     72  **Parameters:**
     73 
     74  - ``commands {Object}`` - The commands object designating which debugging context the toolbox will debug.
     75  - ``toolId {String}`` - The tool that should be activated. If unspecified the previously active tool is shown.
     76  - ``hostType {String}`` - The position the toolbox will be placed. One of ``bottom``, ``side``, ``window``, ``custom``. See :ref:`HostType <devtoolsapi-host-type>` for details.
     77  - ``hostOptions {Object}`` - An options object passed to the selected host. See :ref:`HostType <devtoolsapi-host-type>` for details.
     78 
     79  **Return value:**
     80  A `Promise <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise>`_ that is fulfilled with the :ref:`Toolbox <devtoolsapi-toolbox>` instance once it has been initialized and the selected tool is loaded.
     81 
     82 ``getToolbox(target)``
     83  Fetch the :ref:`Toolbox <devtoolsapi-toolbox>` object for the given target.
     84 
     85  **Parameters:**
     86 
     87  - ``target {Target}`` - The target the toolbox is debugging.
     88 
     89  **Return value:**
     90  :ref:`Toolbox <devtoolsapi-toolbox>` object or undefined if there's no toolbox for the given target..
     91 
     92 ``closeToolbox(target)``
     93  Closes the toolbox for given target.
     94 
     95  **Parameters:**
     96 
     97  - ``target {Target}`` - The target of the toolbox that should be closed.
     98 
     99  **Return value:**
    100  A `Promise <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise>`_ that is fulfilled once the toolbox has been destroyed.
    101 
    102 ``getDefaultTools()``
    103  Returns an `Array <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array>`_ of :ref:`ToolDefinition <devtoolsapi-tool-definition>` objects for the built-in tools.
    104 
    105 ``getAdditionalTools()``
    106  Returns an `Array <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array>`_ of :ref:`ToolDefinition <devtoolsapi-tool-definition>` objects for tools added by addons.
    107 
    108 ``getToolDefinition(toolId)``
    109  Fetch the :ref:`ToolDefinition <devtoolsapi-tool-definition>` object for a tool if it exists and is enabled.
    110 
    111  **Parameters:**
    112 
    113  - ``toolId {String}`` - The ID of the tool.
    114 
    115  **Return value:**
    116  A :ref:`ToolDefinition <devtoolsapi-tool-definition>` if a tool with the given ID exists and is enabled, null otherwise.
    117 
    118 ``getToolDefinitionMap()``
    119  Returns a toolId → :ref:`ToolDefinition <devtoolsapi-tool-definition>` map for tools that are enabled.
    120 
    121 ``getToolDefinitionArray()``
    122  Returns an `Array <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array>`_ of :ref:`ToolDefinition <devtoolsapi-tool-definition>` objects for enabled tools sorted by the order they appear in the toolbox.
    123 
    124 ``getThemeDefinition(themeId)``
    125  Fetch the ``ThemeDefinition`` object for the theme with the given id.
    126 
    127  **Parameters:**
    128 
    129  - ``themeId {String}`` - The ID of the theme.
    130 
    131  **Return value:**
    132  A ``ThemeDefinition`` object if the theme exists, null otherwise.
    133 
    134 ``getThemeDefinitionMap()``
    135  Returns a toolId → ``ThemeDefinition`` map for available themes.
    136 
    137 ``getThemeDefinitionArray()``
    138  Returns an `Array <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array>`_ of ``ThemeDefinition`` objects for available themes.
    139 
    140 
    141 Events
    142 ~~~~~~
    143 
    144 Following events are emitted by the ``gDevTools`` object via the :ref:`EventEmitter <devtoolsapi-event-emitter>` interface.
    145 
    146 
    147 ``tool-registered (toolId)``
    148  A new tool has been registered.
    149 
    150 ``tool-unregistered(tool)``
    151  A tool has been unregistered. The parameter is a :ref:`ToolDefinition <devtoolsapi-tool-definition>` object.
    152 
    153 ``theme-registered(themeId)``
    154  A new theme has been registered.
    155 
    156 ``theme-unregistered(theme)``
    157  A theme has been unregistered. The parameter is a ``ThemeDefinition`` object.
    158 
    159 ``toolbox-ready(toolbox)``
    160  A new toolbox has been created and is ready to use. The parameter is a :ref:`Toolbox <devtoolsapi-toolbox>` object instance.
    161 
    162 ``toolbox-destroy(target)``
    163  The toolbox for the specified target is about to be destroyed.
    164 
    165 ``toolbox-destroyed(target)``
    166  The toolbox for the specified target has been destroyed.
    167 
    168 ``{toolId}-init(toolbox, iframe)``
    169  A tool with the given ID has began to load in the given toolbox to the given frame.
    170 
    171 ``{toolId}-build(toolbox, panel)``
    172  A tool with the given ID has began to initialize in the given toolbox. The panel is the object returned by the ``ToolDefinition.build()`` method.
    173 
    174 ``{toolId}-ready(toolbox, panel)``
    175  A tool with the given ID has finished its initialization and is ready to be used. The panel is the object returned by the ``ToolDefinition.build()`` method.
    176 
    177 ``{toolId}-destroy(toolbox, panel)``
    178  A tool with the given ID is about to be destroyed. The panel is the object returned by the ``ToolDefinition.build()`` method.
    179 
    180 
    181 .. _devtoolsapi-toolbox:
    182 
    183 Toolbox
    184 -------
    185 
    186 A Toolbox is a frame for the :ref:`ToolPanel <devtoolsapi-tool-panel>` that is debugging a specific target.
    187 
    188 
    189 Properties
    190 ~~~~~~~~~~
    191 
    192 
    193 ``target``
    194  **Target**. The Target this toolbox is debugging.
    195 
    196 
    197 ``hostType``
    198  **Toolbox.HostType**. The type of the host this Toolbox is docked to. The value is one of the ``Toolbox.HostType`` constants.
    199 
    200 ``zoomValue``
    201  The current zoom level of the Toolbox.
    202 
    203 
    204 Constants
    205 ~~~~~~~~~
    206 
    207 The Toolbox constructor contains following constant properties.
    208 
    209 
    210 ``Toolbox.HostType.BOTTOM``
    211  Host type for the default toolbox host at the bottom of the browser window.
    212 
    213 ``Toolbox.HostType.SIDE``
    214  Host type for the host at the side of the browser window.
    215 
    216 ``Toolbox.HostType.WINDOW``
    217  Host type for the separate Toolbox window.
    218 
    219 ``Toolbox.HostType.CUSTOM``
    220  Host type for a custom frame host.
    221 
    222 
    223 Methods
    224 ~~~~~~~
    225 
    226 ``getCurrentPanel()``
    227  Get the currently active :ref:`ToolPanel <devtoolsapi-tool-panel>`.
    228 
    229  **Return value:**
    230  The :ref:`ToolPanel <devtoolsapi-tool-panel>` object that was returned from ``ToolPanel.build()``.
    231 
    232 ``getPanel(toolId)``
    233  Get the :ref:`ToolPanel <devtoolsapi-tool-panel>` for given tool.
    234 
    235  **Parameters:**
    236 
    237  - ``toolId {String}`` - The tool identifier.
    238 
    239  **Return value:**
    240  The :ref:`ToolPanel <devtoolsapi-tool-panel>` object if the tool with the given ``toolId`` is active, otherwise ``undefined``.
    241 
    242 ``getPanelWhenReady(toolId)``
    243  Similar to ``getPanel()`` but waits for the tool to load first. If the tool is not already loaded or currently loading the returned `Promise <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise>`_ won't be fulfilled until something triggers the tool to load.
    244 
    245  **Parameters:**
    246 
    247  - ``toolId {String}`` - The tool identifier.
    248 
    249  **Return value:**
    250  A `Promise <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise>`_ that is fulfilled with the :ref:`ToolPanel <devtoolsapi-tool-panel>` object once the tool has finished loading.
    251 
    252 ``getToolPanels()``
    253  Returns a ``toolId``:ref:`ToolPanel <devtoolsapi-tool-panel>` `Map <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map>`_ for currently loaded tools.
    254 
    255 ``getNotificationBox()``
    256  Returns a ``XULElem("notificationbox")`` element for the Toolbox that can be used to display notifications to the user.
    257 
    258 ``loadTool(toolId)``
    259  Loads the tool with the given ``toolId`` in the background but does not activate it.
    260 
    261  **Parameters:**
    262 
    263  - ``toolId {String}`` - The tool identifier.
    264 
    265  **Return value:**
    266  A `Promise <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise>`_ that is fulfilled with the :ref:`ToolPanel <devtoolsapi-tool-panel>` object of the loaded panel once the tool has loaded.
    267 
    268 ``selectTool(toolId)``
    269  Selects the tool with the given ``toolId``.
    270 
    271  **Parameters:**
    272 
    273  - ``toolId {String}`` - The tool identifier.
    274 
    275  **Return value:**
    276  A `Promise <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise>`_ that is fulfilled with the :ref:`ToolPanel <devtoolsapi-tool-panel>` object of the selected panel once the tool has loaded and activated.
    277 
    278 ``selectNextTool()``
    279  Selects the next tool in the ``Toolbox``.
    280 
    281  **Return value:**
    282  A `Promise <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise>`_ that is fulfilled with the :ref:`ToolPanel <devtoolsapi-tool-panel>` object of the selected panel.
    283 
    284 ``selectPreviousTool()``
    285  Selects the previous tool in the ``Toolbox``.
    286 
    287  **Return value:**
    288  A `Promise <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise>`_ that is fulfilled with the :ref:`ToolPanel <devtoolsapi-tool-panel>` object of the selected panel.
    289 
    290 ``highlightTool(toolId)``
    291  Highlights the tab for the given tool.
    292 
    293  **Parameters:**
    294 
    295  - ``toolId {String}`` - The tool to highlight.
    296 
    297 ``unhighlightTool(toolId)``
    298  Unhighlights the tab for the given tool.
    299 
    300  **Parameters:**
    301 
    302  - ``toolId {String}`` - The tool to unhighlight.
    303 
    304 ``openSplitConsole()``
    305  Opens the split Console to the bottom of the toolbox.
    306 
    307  **Return value:**
    308  A `Promise <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise>`_ that is fulfilled once the Console has loaded.
    309 
    310 ``closeSplitConsole()``
    311  Closes the split console.
    312 
    313 ``toggleSplitConsole()``
    314  Toggles the state of the split console.
    315 
    316  **Return value:**
    317  A `Promise <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise>`_ that is fulfilled once the operation has finished.
    318 
    319 ``switchHost(hostType)``
    320  Switches the location of the toolbox
    321 
    322  **Parameters:**
    323 
    324  - ``hostType {Toolbox.HostType}`` - The type of the new host.
    325 
    326  **Return value:**
    327  A `Promise <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise>`_ that is fulfilled once the new host is ready.
    328 
    329 ``reloadTarget(force)``
    330  Reloads the current target of the toolbox.
    331 
    332  **Parameters:**
    333 
    334  - ``force {Boolean} -`` If true the target is shift-reloaded i.e. the cache is bypassed during the reload.
    335 
    336 ``zoomIn()``
    337  Increases the zoom level of the ``Toolbox`` document.
    338 
    339 ``zoomOut()``
    340  Decreases the zoom level of the ``Toolbox`` document.
    341 
    342 ``zoomReset()``
    343  Resets the zoom level of the ``Toolbox`` document.
    344 
    345 ``setZoom(value)``
    346  Set the zoom level to an arbitrary value.
    347 
    348  **Parameters:**
    349 
    350  - ``value {Number}`` - The zoom level such as ``1.2``.
    351 
    352 ``destroy()``
    353  Closes the toolbox.
    354 
    355  **Return value:**
    356  A `Promise <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise>`_ that is resolved once the ``Toolbox`` is destroyed.
    357 
    358 
    359 Events
    360 ~~~~~~
    361 
    362 The Toolbox object emits following events via the :ref:`EventEmitter <devtoolsapi-event-emitter>` interface.
    363 
    364 
    365 ``host-changed``
    366  The Host for this Toolbox has changed.
    367 
    368 ``ready``
    369  The ``Toolbox`` is ready to use.
    370 
    371 ``select(toolId)``
    372  A tool has been selected. This event is emitted before the corresponding ``{toolId}-selected`` event.
    373 
    374 ``{toolId}-init(frame)``
    375  A tool is about to be loaded. The frame is the `iframe <https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe>`_ element that has been created for the tool.
    376 
    377 ``{toolId}-build(panel)``
    378  The frame for a tool has loaded and the ``ToolPanel.build()`` method has been called but the asynchronous initialization has not started. The parameter is a :ref:`ToolPanel <devtoolsapi-tool-panel>` object.
    379 
    380 ``{toolId}-ready(panel)``
    381  The asynchronous initialization for a tool has completed and it is ready to be used. The parameter is a :ref:`ToolPanel <devtoolsapi-tool-panel>` object.
    382 
    383 ``{toolId}-selected(panel)``
    384  A tool has been selected. The parameter is a :ref:`ToolPanel <devtoolsapi-tool-panel>` object.
    385 
    386 ``{toolId}-destroy(panel)``
    387  A tool is about to be destroyed. The parameter is a :ref:`ToolPanel <devtoolsapi-tool-panel>` object.
    388 
    389 ``destroy``
    390  The ``Toolbox`` is about to be destroyed.
    391 
    392 ``destroyed``
    393  The ``Toolbox`` has been destroyed.
    394 
    395 
    396 .. _devtoolsapi-tool-definition:
    397 
    398 ToolDefinition
    399 --------------
    400 
    401 A ``ToolDefinition`` object contains all the required information for a tool to be shown in the toolbox.
    402 
    403 
    404 Methods
    405 ~~~~~~~
    406 
    407 ``isToolSupported(toolbox)``
    408  A method that is called during toolbox construction to check if the tool supports debugging the given target of the given toolbox.
    409 
    410  **Parameters:**
    411 
    412  - ``toolbox {Toolbox}`` - The toolbox where the tool is going to be displayed, if supported.
    413 
    414  **Return value:**
    415  A boolean indicating if the tool supports the given toolbox's target.
    416 
    417 ``build(window, toolbox)``
    418  A method that builds the :ref:`ToolPanel <devtoolsapi-tool-panel>` for this tool.
    419 
    420  **Parameters:**
    421 
    422  - ``window {Window}`` - The `Window <https://developer.mozilla.org/en-US/docs/Web/API/Window>`_ object for frame the tool is being built into.
    423  - ``toolbox {Toolbox}`` - The :ref:`Toolbox <devtoolsapi-toolbox>` the tool is being built for.
    424 
    425  **Return value:**
    426  A :ref:`ToolPanel <devtoolsapi-tool-panel>` for the tool.
    427 
    428 
    429 ``onKey(panel, toolbox)``
    430  **Optional.** A method that is called when the keyboard shortcut for the tool is activated while the tool is the active tool.
    431 
    432  **Parameters:**
    433 
    434  - ``panel {ToolPanel}`` - The :ref:`ToolPanel <devtoolsapi-tool-panel>` for the tool.
    435  - ``toolbox {Toolbox}`` - The toolbox for the shortcut was triggered for.
    436 
    437  **Return value:**
    438  Undefined.
    439 
    440 
    441 Properties
    442 ~~~~~~~~~~
    443 
    444 The ToolDefinition object can contain following properties. Most of them are optional and can be used to customize the presence of the tool in the Browser and the Toolbox.
    445 
    446 
    447 ``id``
    448  **String, required.** An unique identifier for the tool. It must be a valid id for an HTML `Element <https://developer.mozilla.org/en-US/docs/Web/API/Element>`_.
    449 
    450 ``url``
    451  **String, required.** An URL of the panel document.
    452 
    453 ``label``
    454  **String, optional.** The tool's name. If undefined the ``icon`` should be specified.
    455 
    456 ``tooltip``
    457  **String, optional.** The tooltip for the tool's tab.
    458 
    459 ``panelLabel``
    460  **String, optional.** An accessibility label for the panel.
    461 
    462 ``ordinal``
    463  **Integer, optional.** The position of the tool's tab within the toolbox. **Default:** 99
    464 
    465 ``visibilityswitch``
    466  **String, optional.** A preference name that controls the visibility of the tool. **Default:** ``devtools.{id}.enabled``
    467 
    468 ``icon``
    469  **String, optional.** An URL for the icon to show in the toolbox tab. If undefined the label should be defined.
    470 
    471 ``highlightedicon``
    472  **String, optional.** An URL for an icon that is to be used when the tool is highlighted (see e.g. paused, inactive debugger). **Default:** ``{icon}``
    473 
    474 ``iconOnly``
    475  **Boolean, optional.** If true, the label won't be shown in the tool's tab. **Default:** false
    476 
    477 ``invertIconForLightTheme``
    478  **Boolean, optional.** If true the colors of the icon will be inverted for the light theme. **Default:** false
    479 
    480 ``key``
    481  **String, optional.** The key used for keyboard shortcut. Either ``key`` or ``keycode`` value.
    482 
    483 ``modifiers``
    484  **String, optional.** ``modifiers`` for the keyboard shortcut.
    485 
    486 ``preventClosingOnKey``
    487  **Boolean, optional.** If true the tool won't close if its keybinding is pressed while it is active. **Default:** false
    488 
    489 ``inMenu``
    490  **Boolean, optional.** If true the tool will be shown in the Developer Menu. **Default:** false
    491 
    492 ``menuLabel``
    493  **String, optional.** A label for the Developer Menu item. **Default:** ``{label}``
    494 
    495 ``accesskey``
    496  **String, optional.** ``accesskey`` for the Developer Menu ``xul:menuitem``.
    497 
    498 
    499 Example
    500 ~~~~~~~
    501 
    502 Here's a minimal definition for a tool.
    503 
    504 .. code-block:: JavaScript
    505 
    506  let def = {
    507    id: "my-tool",
    508    label: "My Tool",
    509    icon: "chrome://browser/skin/devtools/tool-webconsole.svg",
    510    url: "about:blank",
    511    isToolSupported: toolbox => true,
    512    build: (window, toolbox) => new MyToolPanel(window, toolbox)
    513  };
    514 
    515  // Register it.
    516  gDevTools.registerTool(def);
    517 
    518 
    519 .. _devtoolsapi-target-type:
    520 
    521 TargetType
    522 ----------
    523 
    524 FIXME:
    525 
    526 
    527 .. _devtoolsapi-host-type:
    528 
    529 HostType
    530 --------
    531 
    532 FIXME
    533 
    534 
    535 .. _devtoolsapi-tool-panel:
    536 
    537 ToolPanel
    538 ---------
    539 
    540 The ToolPanel is an interface the toolbox uses to manage the panel of a tool. The object that ``ToolDefinition.build()`` returns should implement the methods described below.
    541 
    542 Methods
    543 ~~~~~~~
    544 
    545 
    546 ``open()``
    547  **Optional**. A method that can be used to perform asynchronous initialization. If the method returns a `Promise <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise>`_, many operations (e.g. ``gDevTools.showToolbox()`` or ``toolbox.selectTool()``) and events (e.g. ``toolbox-ready`` are delayed until the promise has been fulfilled.
    548 
    549  **Return value:**
    550  The method should return a `Promise <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise>`_ that is resolved with the ``ToolPanel`` object once it's ready to be used.
    551 
    552 ``destroy()``
    553  A method that is called when the toolbox is closed or the tool is unregistered. If the tool needs to perform asynchronous operations during destruction the method should return a `Promise <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise>`_ that is resolved once the process is complete.
    554 
    555  **Return value:**
    556  A `Promise <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise>`_ if the function performs asynchronous operations, otherwise ``undefined``.
    557 
    558 
    559 Example
    560 ~~~~~~~
    561 
    562 Here's a basic template for a ToolPanel implementation.
    563 
    564 .. code-block:: JavaScript
    565 
    566  // In the ToolDefinition object, do
    567  //   build: (window, target) => new MyPanel(window, target),
    568 
    569  class MyPanel {
    570    constructor(window, target) {
    571      // The window object that has loaded the URL defined in the ToolDefinition
    572      this.window = window;
    573      // The Target this toolbox is debugging.
    574      this.target = target;
    575 
    576      // Do synchronous initialization here.
    577      window.document.body.addEventListener("click", this.handleClick);
    578    }
    579 
    580    open() {
    581      // Any asynchronous operations should be done here.
    582      return this.doSomethingAsynchronous()
    583        .then(() => this);
    584    }
    585 
    586    destroy() {
    587      // Synchronous destruction.
    588      this.window.document.body.removeEventListener("click", this.handleClick);
    589 
    590      // Async destruction.
    591      return this.destroySomethingAsynchronously()
    592        .then(() => console.log("destroyed"));
    593    }
    594 
    595    handleClick: function(event) {
    596      console.log("Clicked", event.originalTarget);
    597    }
    598  }
    599 
    600 
    601 .. _devtoolsapi-event-emitter:
    602 
    603 EventEmitter
    604 ------------
    605 
    606 ``EventEmitter`` is an interface many Developer Tool classes and objects implement and use to notify others about changes in their internal state.
    607 
    608 When an event is emitted on the ``EventEmitter``, the listeners will be called with the event name as the first argument and the extra arguments are spread as the remaining parameters.
    609 
    610 .. note::
    611  Some components use Add-on SDK event module instead of the DevTools EventEmitter. Unfortunately, their API's are a bit different and it's not always evident which one a certain component is using. The main differences between the two modules are that the first parameter for Add-on SDK events is the first payload argument instead of the event name and the ``once`` method does not return a Promise. The work for unifying the event paradigms is ongoing in `bug 952653 <https://bugzilla.mozilla.org/show_bug.cgi?id=952653>`_.
    612 
    613 
    614 Methods
    615 ~~~~~~~
    616 
    617 The following methods are available on objects that have been decorated with the ``EventEmitter`` interface.
    618 
    619 ``emit(eventName, ...extraArguments)``
    620  Emits an event with the given name to this object.
    621 
    622  **Parameters:**
    623 
    624  - ``eventName {String}`` - The name of the event.
    625  - ``extraArguments {...Any}`` - Extra arguments that are passed to the listeners.
    626 
    627 ``on(eventName, listener)``
    628  Adds a listener for the given event.
    629 
    630 ``off(eventName, listener)``
    631  Removes the previously added listener from the event.
    632 
    633 ``once(eventName, listener)``
    634  Adds a listener for the event that is removed after it has been emitted once.
    635 
    636  **Return value:**
    637  A `Promise <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise>`_ that is fulfilled with the first extra argument for the event when then event is emitted. If the event contains multiple payload arguments, the rest are discarded and can only be received by providing the listener function to this method.
    638 
    639 
    640 Examples
    641 ~~~~~~~~
    642 
    643 Here's a few examples using the ``gDevTools`` object.
    644 
    645 .. code-block:: JavaScript
    646 
    647  let onInit = (eventName, toolbox, netmonitor) => console.log("Netmonitor initialized!");
    648 
    649  // Attach a listener.
    650  gDevTools.on("netmonitor-init", onInit);
    651 
    652  // Remove a listener.
    653  gDevTools.off("netmonitor-init", onInit);
    654 
    655  // Attach a one time listener.
    656  gDevTools.once("netmonitor-init", (eventName, toolbox, netmonitor) => {
    657    console.log("Network Monitor initialized once!", toolbox, netmonitor);
    658  });
    659 
    660  // Use the Promise returned by the once method.
    661  gDevTools.once("netmonitor-init").then(toolbox => {
    662    // Note that the second argument is not available here.
    663    console.log("Network Monitor initialized to toolbox", toolbox);
    664  });
    665 
    666 
    667 ToolSidebar
    668 -----------
    669 
    670 To build a sidebar in your tool, first, add a xul:tabbox where you want the sidebar to live:
    671 
    672 .. rstcheck: ignore-languages=xml
    673 .. code-block:: xml
    674 
    675  <splitter class="devtools-side-splitter"/>
    676  <tabbox id="mytool-sidebar" class="devtools-sidebar-tabs" hidden="true">
    677    <tabs/>
    678    <tabpanels flex="1"/>
    679  </tabbox>
    680 
    681 A sidebar is composed of tabs. Each tab will hold an iframe. For example, in the Inspector, there are 3 tabs (Computed View, Rule View, Layout View). The user can select the tab they want to see.
    682 
    683 If the availability of the tabs depends on some tool-related conditions, we might want to not let the user select a tab. This API provides methods to hide the tabstripe. For example, in the Web Console, there are 2 views (Network View and Object View). These views are only available in certain conditions controlled by the WebConsole code. So it's up the WebConsole the hide and show the sidebar, and select the correct tab.
    684 
    685 If the loaded document exposes a ``window.setPanel(ToolPanel)`` function, the sidebar will call it once the document is loaded.
    686 
    687 .. list-table:: Methods
    688  :widths: 70 30
    689  :header-rows: 1
    690 
    691  * - Method
    692    - Description
    693 
    694  * - ``new ToolSidebar(xul:tabbox, ToolPanel, showTabstripe=true)``
    695    - ToolSidebar constructor
    696 
    697  * - ``void addTab(tabId, url, selected=false)``
    698    - Add a tab in the sidebar
    699 
    700  * - ``void select(tabId)``
    701    - Select a tab
    702 
    703  * - ``void hide()``
    704    - Hide the sidebar
    705 
    706  * - ``void show()``
    707    - Show the sidebar
    708 
    709  * - ``void toggle()``
    710    - Toggle the sidebar
    711 
    712  * - ``void getWindowForTab(tabId)``
    713    - Get the iframe containing the tab content
    714 
    715  * - ``tabId getCurrentTabID()``
    716    - Return the id of tabId of the current tab
    717 
    718  * - ``tabbox getTab(tabId)``
    719    - Return a tab given its id
    720 
    721  * - ``destroy()``
    722    - Destroy the ToolSidebar object
    723 
    724 .. list-table:: Events
    725  :widths: 70 30
    726  :header-rows: 1
    727 
    728  * - Events
    729    - Description
    730 
    731  * - ``new-tab-registered``
    732    - A new tab has been added
    733 
    734  * - ``{tabId}-ready``
    735    - Tab is loaded and can be used
    736 
    737  * - ``{tabId}-selected``
    738    - Tab has been selected and is visible
    739 
    740  * - ``{tabId}-unselected``
    741    - Tab has been unselected and is not visible
    742 
    743  * - ``show``
    744    - The sidebar has been opened.
    745 
    746  * - ``hide``
    747    - The sidebar has been closed.
    748 
    749 
    750 Examples
    751 --------
    752 
    753 Register a tool
    754 
    755 .. code-block:: JavaScript
    756 
    757  gDevTools.registerTool({
    758    // FIXME: missing key related properties.
    759    id: "inspector",
    760    icon: "chrome://browser/skin/devtools/inspector-icon.png",
    761    url: "chrome://browser/content/devtools/inspector/inspector.xul",
    762    get label() {
    763      let strings = Services.strings.createBundle("chrome://browser/locale/devtools/inspector.properties");
    764      return strings.GetStringFromName("inspector.label");
    765    },
    766 
    767    isToolSupported: function(toolbox) {
    768      return toolbox.commands.descriptorFront.isLocalTab;
    769    },
    770 
    771    build: function(iframeWindow, toolbox, node) {
    772      return new InspectorPanel(iframeWindow, toolbox, node);
    773    }
    774  });
    775 
    776 
    777 Open a tool, or select it if the toolbox is already open:
    778 
    779 .. code-block:: JavaScript
    780 
    781  let target = TargetFactory.forTab(gBrowser.selectedTab);
    782  let toolbox = gDevTools.openToolbox(target, null, "inspector");
    783 
    784  toolbox.once("inspector-ready", function(event, panel) {
    785    let inspector = toolbox.getToolPanels().get("inspector");
    786    inspector.selection.setNode(target, "browser-context-menu");
    787  });
    788 
    789 
    790 Add a sidebar to an existing tool:
    791 
    792 .. code-block:: JavaScript
    793 
    794  let sidebar = new ToolSidebar(xulTabbox, toolPanel);
    795  sidebar.addTab("tab1", "chrome://browser/content/.../tab1.xhtml", true);
    796  sidebar.addTab("tab2", "chrome://browser/content/.../tab2.xhtml", false);
    797  sidebar.show();