# Technical Documentation: mozilla-firefox/firefox

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/mozilla-firefox/firefox)

### Overview (README.md)

[Firefox](https://firefox.com/) is a fast, reliable and private web browser from the non-profit [Mozilla organization](https://mozilla.org/).

### Contributing

To learn how to contribute to Firefox read the [Firefox Contributors' Quick Reference document](https://firefox-source-docs.mozilla.org/contributing/contribution_quickref.html).

We use [bugzilla.mozilla.org](https://bugzilla.mozilla.org/) as our issue tracker, please file bugs there.

### Resources

* [Firefox Source Docs](https://firefox-source-docs.mozilla.org/) is our primary documentation repository
* Nightly development builds can be downloaded from [Firefox Nightly page](https://www.mozilla.org/firefox/channel/desktop/#nightly)

If you have a question about developing Firefox, and can't find the solution
on [Firefox Source Docs](https://firefox-source-docs.mozilla.org/), you can try asking your question on Matrix at
chat.mozilla.org in the [Introduction channel](https://chat.mozilla.org/#/room/#introduction:mozilla.org).

---

### Index (`docs/index.md`)

# Firefox Source Tree Documentation

```{{toctree}}
:caption: Overview
:maxdepth: 2

{overview_doc}
```

```{{toctree}}
:caption: Getting Started
:maxdepth: 1

{setup_doc}
```

```{{toctree}}
:caption: Working On Firefox
:maxdepth: 2

{contributing_doc}
```

```{{toctree}}
:caption: Firefox User Guide
:maxdepth: 2

{user_guide}
```

```{{toctree}}
:caption: Source Code Documentation
:maxdepth: 2

{source_doc}
```

```{{toctree}}
:caption: The Firefox Build System
:maxdepth: 1

{build_doc}
```

```{{toctree}}
:caption: Testing & Test Infrastructure
:maxdepth: 1

{testing_doc}
```

```{{toctree}}
:caption: AI Agent Tools
:maxdepth: 1

{ai_agent_tools_doc}
```

```{{toctree}}
:caption: Releases & Updates
:maxdepth: 1

{release_doc}
```

```{{toctree}}
:caption: Localization & Internationalization
:maxdepth: 2

{l10n_doc}
```

```{{toctree}}
:caption: Firefox and Python
:maxdepth: 1

{python_doc}
```

```{{toctree}}
:caption: Metrics Collected in Firefox
:maxdepth: 1

{metrics_doc}
```

## Indices and tables

* {{ref}}`genindex`
* {{ref}}`modindex`
* {{ref}}`search`

---

### Accessible Docs Index (`accessible/docs/index.md`)

# Accessibility

These pages contain design documents for the accessibility implementation in Gecko.
They live in the mozilla-central repository under the accessible/docs directory.

The [Accessibility page on the Mozilla Wiki](https://wiki.mozilla.org/Accessibility) contains general information about accessibility and the accessibility team at Mozilla.

The [Mochitest FAQ docs](/testing/mochitest-plain/faq.md#how-can-i-run-accessibility-tests-a11y-checks) contain guidance on debugging a11y-checks failures and working with AccessibilityUtils when writing frontend test cases.

```{toctree}
:maxdepth: 1

GuidelinesForNewContributors
Architecture
DocumentAccessibilityLifecycle
GeckoViewThreadTopography
ColorsAndHighContrastMode
HCMSettings
HCMMediaQueries
HCMCSSChecklist
TaggedPdfOutput
```

---

### Browser Docs Index (`browser/docs/index.md`)

# Firefox Front-end

This is the documentation for the code powering the Firefox Desktop front-end.

```{toctree}
:maxdepth: 2

how_to/index
urlbar/index
BrowserUsageTelemetry
FrontendCodeReviewBestPractices
CommandLineParameters
BrowserStartup
CategoryManagerIndirection
components/customizableui/docs/index
components/enterprisepolicies/docs/index
components/taskbartabs/docs/index
extensions/formautofill/docs/index
extensions/newtab/docs/index
components/aboutwelcome/docs/index
installer/windows/installer/index
components/attribution/docs/index
/toolkit/mozapps/defaultagent/default-browser-agent/index
components/migration/docs/index
components/pagedata/docs/index
places/index
components/asrouter/docs/index
search/index
components/sessionstore/docs/index
components/tabbrowser/docs/index
touchbar/index
components/uitour/docs/index
branding/docs/index
components/storybook/docs/README.storybook.stories
components/storybook/docs/README.reusable-widgets.stories
components/storybook/docs/README.other-widgets.stories
components/storybook/docs/README.lit-guide.stories
components/storybook/docs/README.xul-and-html.stories
components/storybook/docs/README.figma-code-connect.stories
components/storybook/docs/README.typography.stories
/toolkit/themes/shared/design-system/docs/README.design-tokens.stories
components/backup/docs/index
components/sidebar/docs/index
components/mozcachedohttp/docs/index
desktop-launcher/index
app/pbproxy/private-browsing-proxy/index
/installation_dir_layout/index
```

---

### Browser Docs Overview (`browser/docs/overview.md`)

# Firefox for Desktop

## Desktop architecture

One of the keys to understanding how Firefox is architected is to know that Gecko is used to render
both web content as well as the UI of the browser. This means that, to a large extent, the UI of
Firefox is made using web technologies like HTML, CSS, and JavaScript. For example, the document
`chrome://browser/content/browser.xhtml` is the markup for a single Firefox browser window. You
can think of it almost like index.html for a webpage.

The decision to use Gecko for rendering the UI was made during an era when HTML was not yet
expressive enough or sufficient to build desktop UIs. A different markup language,
[XUL](https://en.wikipedia.org/wiki/XUL), was developed for that purpose instead, which Gecko also
knows how to interpret. Since that time, HTML and CSS has evolved to the point where XUL is not
strictly necessary for most use-cases. Where possible, we have been gradually migrating our UI to
use less XUL and more standard HTML and CSS.

## Reusable UI Widgets

Many of the UI widgets in use in the user interface are built as web components that can be reused.

{doc}`Read more <components/storybook/docs/README.reusable-widgets.stories>`

## Tabbrowser

The tabbrowser component manages the tabs in a browser window.

{ref}`Read more <tabbrowser>`

## Address Bar

The address bar (varyingly also referred to as the Awesome Bar, or Quantum Bar) handles users
entering web addresses including a popup with suggestions from various sources including history,
bookmarks and search engines.

{doc}`Read more <urlbar/index>`

## Search

The search service manages the list of search engines available in the address bar.

{ref}`Read more <Search>`

## Places

The places component includes the database that stores history and bookmarks as well as a set of UI
components that present those to the user.

{doc}`Read more <places/index>`

## Firefox Sync and Application Services

Application services includes the sync engines and Firefox Accounts integration.

{doc}`Read more </services/index>`

## Developer Tools

The developer tools support web developers when building webpages but as the Firefox UI is itself
built using web technologies it is also possible to use the developer tools to debug the Firefox UI.

{doc}`Read more </devtools/index>`

### Browser Toolbox

The Browser Toolbox is a way to launch the developer tools in a separate process so that they can be
used to debug the main browser UI.

{doc}`Read more </devtools-user/browser_toolbox/index>`

### Profiler

The Firefox Profiler is the way to measure the performance of your code. Go to
[profiler.firefox.com](https://profiler.firefox.com) to enable the button in Firefox and record a
performance profile. These profiles can be uploaded and shared. It can identify slow parts of the
code, and reveal the underlying behavior of how code runs.

## Installer

The Windows installer for Firefox is built with NSIS. There are currently no installers for other
operating systems.

{doc}`Read more <installer/windows/installer/index>`

## Application Update

Application Update is responsible for requesting available updates from the update servers,
downloading them, verifying their integrity and then ultimately installing them. A binary patch tool
(bsdiff) is used to reduce the size of update files and update files are delivered in the
bespoke mar (Mozilla ARchive) format.

{doc}`Read more </toolkit/mozapps/update/docs/index>`

---

### Build Docs Build Overview (`build/docs/build-overview.md`)

(build-overview)=

# Build System Overview

This document provides an overview on how the build system works. It is
targeted at people wanting to learn about internals of the build system.
It is not meant for persons who casually interact with the build system.
That being said, knowledge empowers, so consider reading on.

The build system is composed of many different components working in
harmony to build the source tree. We begin with a graphic overview.

```{eval-rst}
.. graphviz::

   digraph build_components {
      rankdir="LR";
      "configure" -> "config.status" -> "build backend" -> "build output"
   }
```

## Phase 1: Configuration

Phase 1 centers around the `configure` script, which is a bash shell script.
The file is generated from a file called `configure.in` which is written in M4
and processed using Autoconf 2.13 to create the final configure script.
You don't have to worry about how you obtain a `configure` file: the build
system does this for you.

The primary job of `configure` is to determine characteristics of the system
and compiler, apply options passed into it, and validate everything looks OK to
build. The primary output of the `configure` script is an executable file
in the object directory called `config.status`. `configure` also produces
some additional files (like `autoconf.mk`). However, the most important file
in terms of architecture is `config.status`.

The existence of a `config.status` file may be familiar to those who have worked
with Autoconf before. However, Mozilla's `config.status` is different from almost
any other `config.status` you've ever seen: it's written in Python! Instead of
having our `configure` script produce a shell script, we have it generating
Python.

Now is as good a time as any to mention that Python is prevalent in our build
system. If we need to write code for the build system, we do it in Python.
That's just how we roll. For more, see {ref}`python`.

`config.status` contains 2 parts: data structures representing the output of
`configure` and a command-line interface for preparing/configuring/generating
an appropriate build backend. (A build backend is merely a tool used to build
the tree - like GNU Make or Tup). These data structures essentially describe
the current state of the system and what the existing build configuration looks
like. For example, it defines which compiler to use, how to invoke it, which
application features are enabled, etc. You are encouraged to open up
`config.status` to have a look for yourself!

Once we have emitted a `config.status` file, we pass into the realm of
phase 2.

## Phase 2: Build Backend Preparation and the Build Definition

Once `configure` has determined what the current build configuration is,
we need to apply this to the source tree so we can actually build.

What essentially happens is the automatically-produced `config.status` Python
script is executed as soon as `configure` has generated it. `config.status`
is charged with the task of tell a tool how to build the tree. To do this,
`config.status` must first scan the build system definition.

The build system definition consists of various `moz.build` files in the tree.
There is roughly one `moz.build` file per directory or per set of related directories.
Each `moz.build` files defines how its part of the build config works. For
example it says *I want these C++ files compiled* or *look for additional
information in these directories.* config.status starts with the `moz.build`
file from the root directory and then descends into referenced `moz.build`
files by following `DIRS` variables or similar.

As the `moz.build` files are read, data structures describing the overall
build system definition are emitted. These data structures are then fed into a
build backend, which then performs actions, such as writing out files to
be read by a build tool. e.g. a `make` backend will write a
`Makefile`.

When `config.status` runs, you'll see the following output:

```
Reticulating splines...
Finished reading 1096 moz.build files into 1276 descriptors in 2.40s
Backend executed in 2.39s
2188 total backend files. 0 created; 1 updated; 2187 unchanged
Total wall time: 5.03s; CPU time: 3.79s; Efficiency: 75%
```

What this is saying is that a total of *1096* `moz.build` files were read.
Altogether, *1276* data structures describing the build configuration were
derived from them. It took *2.40s* wall time to just read these files and
produce the data structures. The *1276* data structures were fed into the
build backend which then determined it had to manage *2188* files derived
from those data structures. Most of them already existed and didn't need
changed. However, *1* was updated as a result of the new configuration.
The whole process took *5.03s*. Although, only *3.79s* was in
CPU time. That likely means we spent roughly *25%* of the time waiting on
I/O.

For more on how `moz.build` files work, see {ref}`mozbuild-files`.

## Phase 3: Invocation of the Build Backend

When most people think of the build system, they think of phase 3. This is
where we take all the code in the tree and produce Firefox or whatever
application you are creating. Phase 3 effectively takes whatever was
generated by phase 2 and runs it. Since the dawn of Mozilla, this has been
make consuming Makefiles. However, with the transition to moz.build files,
you may soon see non-Make build backends, such as Tup or Visual Studio.

When building the tree, most of the time is spent in phase 3. This is when
header files are installed, C++ files are compiled, files are preprocessed, etc.

---

### Build Docs Index (`build/docs/index.md`)

# Build System

## Important Concepts

```{toctree}
:maxdepth: 1

glossary
build-overview
supported-configurations
Mozconfig Files <mozconfigs>
mozbuild-files
mozbuild-symbols
files-metadata
Profile Guided Optimization <pgo>
slow
environment-variables
build-targets
python
test_manifests
mozinfo
preprocessor
jar-manifests
defining-binaries
defining-xpcom-components
toolchains
toolchains-update-policy
locales
unified-builds
cross-compile
rust
sparse
Support for projects building with GN <gn>
telemetry
sccache-dist
test_certificates
```

## integrated development environment (IDE)

```{toctree}
:maxdepth: 1

cppeclipse
visualstudio
```

## mozbuild

mozbuild is a Python package containing a lot of the code for the
Mozilla build system.

```{toctree}
:maxdepth: 1

mozbuild/index
```

## Snap Package

[Snap](https://snapcraft.io/docs) is a packaging format

```{toctree}
:maxdepth: 1

snap
```

## Flatpak Package

[Flatpak](https://docs.flatpak.org/en/latest/) is a packaging format

```{toctree}
:maxdepth: 1

flatpak
chrome-registration
```

---

### Ai Agent Tools Index (`docs/ai-agent-tools/index.md`)

# AI Agent Tools for Firefox Development

This section documents tools and workflows for using AI assistants to interact
with and test Firefox during development.

```{toctree}
:maxdepth: 2

firefox-devtools-mcp
code-review-context
skills
```

---

### Bug Mgmt Index (`docs/bug-mgmt/index.md`)

# Bug Handling

```{toctree}
:maxdepth: 1

guides/index
policies/index
processes/index
```

## Related documentation

- [bugzilla.mozilla.org documentation](https://bmo.readthedocs.org/)
- [bugzilla.mozilla.org field
  definitions](https://wiki.mozilla.org/BMO/UserGuide/BugFields)
- [Lando
  documentation](https://moz-conduit.readthedocs.io/en/latest/lando-user.html)
- [Mozilla Phabricator (Code Review)
  documentation](https://moz-conduit.readthedocs.io/en/latest/phabricator-user.html)

---

### Code Quality Index (`docs/code-quality/index.md`)

# Code quality

Because Firefox is a complex piece of software, a lot of tools are
executed to identify issues at development phase.
In this document, we try to list these all tools.

```{toctree}
:glob: true
:maxdepth: 1

static-analysis/index
lint/index
coding-style/index
typescript/index
```

```{eval-rst}
.. list-table:: C/C++
   :header-rows: 1
   :widths: 20 20 20 20 20

   * - Tools
     - Has autofixes
     - Meta bug
     - More info
     - Upstream
   * - Custom clang checker
     -
     -
     - :searchfox:`Source <build/clang-plugin>`
     -
   * - Clang-Tidy
     - Yes
     - `bug 712350 <https://bugzilla.mozilla.org/show_bug.cgi?id=712350>`__
     - :doc:`Static analysis <static-analysis/index>`
     - https://clang.llvm.org/extra/clang-tidy/checks/list.html
   * - Clang analyzer
     -
     - `bug 712350 <https://bugzilla.mozilla.org/show_bug.cgi?id=712350>`__
     -
     - https://clang-analyzer.llvm.org/
   * - cpp virtual final
     -
     -
     - :ref:`cpp virtual final <cpp-virtual-final>`
     -
   * - clang-format
     - Yes
     - `bug 1188202 <https://bugzilla.mozilla.org/show_bug.cgi?id=1188202>`__
     - :doc:`coding-style/format_cpp_code_with_clang-format`
     - https://clang.llvm.org/docs/ClangFormat.html
```

```{eval-rst}
.. list-table:: CSS
   :widths: 20 20 20 20 20
   :header-rows: 1

   * - Tools
     - Has autofixes
     - Meta bug
     - More info
     - Upstream
   * - Stylelint
     - Yes
     - `bug 1762027 <https://bugzilla.mozilla.org/show_bug.cgi?id=1762027>`__
     - :doc:`lint/linters/stylelint`
     - https://stylelint.io/
   * - Mozilla Stylelint
     -
     -
     - :doc:`lint/linters/stylelint-plugin-mozilla`
     -
```

```{eval-rst}
.. list-table:: JavaScript
   :widths: 20 20 20 20 20
   :header-rows: 1

   * - Tools
     - Has autofixes
     - Meta bug
     - More info
     - Upstream
   * - Eslint
     - Yes
     - `bug 1229856 <https://bugzilla.mozilla.org/show_bug.cgi?id=1229856>`__
     - :doc:`lint/linters/eslint`
     - https://eslint.org/
   * - Mozilla ESLint
     -
     - `bug 1229856 <https://bugzilla.mozilla.org/show_bug.cgi?id=1229856>`__
     - :doc:`lint/linters/eslint-plugin-mozilla`
     -
   * - Prettier
     - Yes
     - `bug 1558517 <https://bugzilla.mozilla.org/show_bug.cgi?id=1558517>`__
     - :doc:`coding-style/coding_style_js`
     - https://prettier.io/
   * - pnpm-audit
     -
     - `bug 2065363 <https://bugzilla.mozilla.org/show_bug.cgi?id=2065363>`__
     - :doc:`lint/linters/pnpm-audit`
     - https://pnpm.io/cli/audit
```

```{eval-rst}
.. list-table:: Python
   :widths: 20 20 20 20 20
   :header-rows: 1

   * - Tools
     - Has autofixes
     - Meta bug
     - More info
     - Upstream
   * - ruff
     - Yes
     - `bug 1811850 <https://bugzilla.mozilla.org/show_bug.cgi?id=1811850>`__
     - :doc:`lint/linters/ruff`
     - https://github.com/charliermarsh/ruff
   * - black
     - Yes
     - `bug 1555560 <https://bugzilla.mozilla.org/show_bug.cgi?id=1555560>`__
     - :doc:`lint/linters/black`
     - https://black.readthedocs.io/en/stable
```

```{eval-rst}
.. list-table:: Rust
   :widths: 20 20 20 20 20
   :header-rows: 1

   * - Tools
     - Has autofixes
     - Meta bug
     - More info
     - Upstream
   * - Rustfmt
     - Yes
     - `bug 1454764 <https://bugzilla.mozilla.org/show_bug.cgi?id=1454764>`__
     - :doc:`lint/linters/rustfmt`
     - https://github.com/rust-lang/rustfmt
   * - Clippy
     - Yes
     - `bug 1361342 <https://bugzilla.mozilla.org/show_bug.cgi?id=1361342>`__
     - :doc:`lint/linters/clippy`
     - https://github.com/rust-lang/rust-clippy
   * - cargo-audit
     -
     - `bug 1747536 <https://bugzilla.mozilla.org/show_bug.cgi?id=1747536>`__
     - :doc:`lint/linters/cargo-audit`
     - https://rustsec.org/
```

```{eval-rst}
.. list-table:: Java/Kotlin
   :widths: 20 20 20 20 20
   :header-rows: 1

   * - Tools
     - Has autofixes
     - Meta bug
     - More info
     - Upstream
   * - Spotless
     - Yes
     - `bug 1571899 <https://bugzilla.mozilla.org/show_bug.cgi?id=1571899>`__
     - :doc:`lint/linters/android-format`
     - https://github.com/diffplug/spotless
```

```{eval-rst}
.. list-table:: Others
   :widths: 20 20 20 20 20
   :header-rows: 1

   * - Tools
     - Has autofixes
     - Meta bug
     - More info
     - Upstream
   * - shellcheck
     -
     -
     -
     - https://www.shellcheck.net/
   * - Typo detection
     - Yes
     -
     - :doc:`lint/linters/codespell`
     - https://github.com/codespell-project/codespell
   * - Fluent Lint
     - No
     -
     - :doc:`lint/linters/fluent-lint`
     -
   * - YAML linter
     - No
     -
     - :doc:`lint/linters/yamllint`
     - https://github.com/adrienverge/yamllint
```

---

### Content Security Index (`docs/content-security/index.md`)

# Web Security Checks in Gecko

## Key Concepts and Terminology

### Security Principal (nsIPrincipal)

A Security Principal represents the security context for a piece of code or data. Firefox uses four types of principals:

- **ContentPrincipal**: Used for typical web pages and can be serialized to an origin URL, e.g., <https://example.com/>.
- **NullPrincipal**: Used for pages that are never same-origin with anything else, such as iframes with the sandbox attribute or documents loaded with a data: URI. This is also known as an opaque origin.
- **SystemPrincipal**: Used for the browser's user interface, commonly referred to as "browser chrome", and various other background services (OCSP requests, fetching favicons). Pages like <about:preferences> use the SystemPrincipal.
- **ExpandedPrincipal**: Used by browser extensions that need to assume the security context of a website. An ExpandedPrincipal is best understood as a list of principals.

### OriginAttributes

`OriginAttributes` help in managing and enforcing security policies by distinguishing different security contexts that might otherwise be considered the same based on their Principal. They are used to:

- Isolate data and resources in private browsing mode.
- Implement cache isolation.
- Manage user context identifiers for container tabs.
- Enforce first-party isolation.

### Attributes

The `OriginAttributes` class extends the functionality of `dom::OriginAttributesDictionary` and includes additional methods for setting and managing various attributes.

Key attributes include:

- **FirstPartyDomain**: Used to isolate data based on the domain.
- **UserContextId**: Identifies different user contexts, such as container tabs.
- **PrivateBrowsingId**: Indicates whether a request is made in private browsing mode.
- **PartitionKey**: Used to implement cache isolation.

### Load Info Object (nsILoadInfo)

The `nsILoadInfo` object is crucial for security checks. It holds all security-relevant attributes, including security flags indicating what checks need to be performed and the associated Principal.

### Attributes

- `loadingPrincipal`: The principal of the document where the result of the load will be used.
- `triggeringPrincipal`: The principal that triggered the URL to load.
- `securityFlags`: Indicate the type of security checks required.
- `contentPolicyType`: Specifies the type of content being loaded, used for security checks like Content Security Policy.

## Loading Lifecycle in Firefox

### From Request to Response

1. **Request Initiation**: A web page initiates a request.
2. **nsIChannel Creation**: Firefox creates an `nsIChannel` object, representing the request.
3. **nsILoadInfo Attachment**: An `nsILoadInfo` object is required for the creation of an `nsIChannel` and holds security-related information.
4. **Security Checks**: Security checks are performed using the `ContentSecurityManager`.
5. **Request Execution**: If all checks pass, the request proceeds.

### Role of nsIChannel and nsILoadInfo

- **nsIChannel**: Manages the transport algorithm (e.g., HTTP, WebSocket).
- **nsILoadInfo**: Holds security relevant meta information of a network load and determines what security checks need to be enforced.

## Security Checks During Loading

### Pre-Request Checks

- **Same-Origin Policy**: Ensures resources are only accessed if they share the same origin.
- **Content Security Policy**: Enforces content restrictions based on policies defined by the site.
- **Mixed Content Blocking**: Implements the Mixed Content standard, including blocking and upgrading of insecure (HTTP) content on secure (HTTPS) pages.

### ContentSecurityManager and doContentSecurityCheck()

- **ContentSecurityManager**: Centralized manager for performing security checks.
- **PerformSecurityCheck()**: Key function that is invoked to perform all relevant security checks before a request is executed.

### Subsumes Concept

- **Definition**: A principal subsumes another if it has access to the same resources.
- **Implementation**: `aPrincipal->Subsumes(aOtherPrincipal)` is used to check access permissions.

Code example:

```
bool subsumes = principal1->Subsumes(principal2);
```

Subsumption is asymmetrical. One principal subsuming the other does not imply the inverse. A typical example is the `SystemPrincipal`, which subsumes all other
principals.

### References

The interface definitions in source code have a lot of detailed comments:

- The {searchfox}`nsIPrincipal <caps/nsIPrincipal.idl>` interface definition.
- The {searchfox}`nsILoadInfo <netwerk/base/nsILoadInfo.idl>` interface definition.
- The {searchfox}`nsIContentSecurityManager <dom/interfaces/security/nsIContentSecurityManager.idl>` interface definition

---

### Contributing Index (`docs/contributing/index.md`)

(working-on-firefox)=

# Working on Firefox

Welcome to the Firefox codebase. This is the home of the Firefox
development process and source code documentation.

```{toctree}
:caption: Making Changes To Firefox
:maxdepth: 1

contribution_quickref
stack_quickref
reviewable-patch-series
phabricator_vs_github
pocket-guide-shipping-firefox
editor
reviews
levelling-up
how_to_submit_a_patch
data-collection
data-review
searchfox
ai-coding
```

```{toctree}
:caption: Version control
:maxdepth: 1

jujutsu
git-tricks
```

```{toctree}
:caption: Code reviews
:maxdepth: 1

Code_Review_FAQ
reviewer_checklist
```

```{toctree}
:caption: Debugging
:maxdepth: 1

debugging/index
```

```{toctree}
:caption: Signing
:glob: true
:maxdepth: 1

signing/*
```

```{toctree}
:caption: Additional Information
:maxdepth: 1

directory_structure
build/artifact_builds
build/building_mobile_firefox
build/working_with_esr_115
engineering_show_and_tell
filing-good-bugs
helpful-error-messages
```

---

### Crash Reporting Index (`docs/crash-reporting/index.md`)

# Firefox Crash Reporting

Firefox ships with an open-source crash reporting system. This system is
combination of projects:

- [Google
  Breakpad](https://chromium.googlesource.com/breakpad/breakpad)
  client and server libraries
- Mozilla-specific crash reporting user interface and bootstrap code
- [Socorro](https://github.com/mozilla-services/socorro) Collection
  and reporting server

## Where did my crash get submitted?

Crash data submitted using the Mozilla Crash Reporter is located on
[crash-stats](https://crash-stats.mozilla.org/). If you want to find
a specific crash that you submitted, you first need to find the Crash ID
that the server has assigned your crash. Type `about:crashes` into
your location bar to get a page listing both submitted and unsubmitted
crash reports. For more information, see [How to get a stacktrace for a bug report](/contributing/debugging/stacktrace_report.md).

## Reports and queries

crash-stats has built-in reports of "topcrashes" for each release
grouped by signature. There is also a [custom query tool](https://crash-stats.mozilla.org/search/)
which allows users to limit searches on more precise information.

Finally, a set of Mozilla employees have access to directly query the
underlying data in either SQL summary or using mapreduce on the storage
cluster. If you are interested in obtaining this advanced access, read
[Crash Stats Documentation: Protected Data Access](https://crash-stats.mozilla.org/documentation/protected_data_access/)

## See also

- [Understanding Crash Reports](/contributing/debugging/understanding_crash_reports.md)
- [A guide to searching crash reports](searching_crash_reports.md)
- [crash-stats](https://crash-stats.mozilla.org/)
- [Crash pings (Telemetry) and crash reports (Socorro/Crash
  Stats)](https://bluesock.org/~willkg/blog/mozilla/crash_pings_crash_reports.html)
- [Building with Debug Symbols](/setup/building_with_debug_symbols.md)
- {ref}`Environment variables affecting crash reporting <environment-variables-affecting-crash-reporting>`
- [Uploading symbols to Mozilla's symbol server](uploading_symbol.md)
- [Crash Reporter](/toolkit/crashreporter/crashreporter/index.md)
- [Crash Manager](/toolkit/components/crashes/crash-manager/index.md)
- [Crash Ping Lifecycle](/toolkit/components/crashes/crash-manager/crash-ping-lifecycle.md)

```{toctree}
:hidden:
:maxdepth: 1

searching_crash_reports
uploading_symbol
```

---

### Glossary Index (`docs/glossary/index.md`)

# A Glossary of Common Terms

:::{topic} Content
Usually refers to webpages being rendered, may also be seen as "running in
content" in which case it can include UI privileged code running in a process
that is rendering webpages.
:::

:::{topic} Chrome
Usually the parts of the application UI outside of the rendered webpage
:::

:::{topic} XUL
A proprietary UI definition language that we are slowly phasing out and replacing with standard HTML.
:::

:::{topic} l10n
An abbreviation for Localization.
:::

:::{topic} i18n
An abbreviation for Internationalisation
:::

:::{topic} a11y
An abbreviation for Accessibility
:::

---

### Gtest Index (`docs/gtest/index.md`)

# GTest

GTest (googletest) is Google's framework for writing C++ tests on a
variety of platforms (Linux, Mac OS X, Windows, ...).
Based on the xUnit architecture, it supports automatic test
discovery, a rich set of assertions, user-defined assertions, death
tests, fatal and non-fatal failures, value- and type-parameterized
tests, various options for running the tests, and XML test report
generation.

## Integration

GTest is run as a standard test task on Win/Mac/Linux and Android, under
treeherder symbol 'GTest'.

## Running tests

The Firefox build process will build GTest on supported platforms as
long as you don't disable tests in your mozconfig. However xul-gtest will
only be built when tests are required to save an expensive second
linking process.

To run the unit tests use 'mach gtest' when invoking Gecko.

### Running selected tests

Tests can be selected using mach. You can also use environment variables
support by GTest. See [Running Test Programs: Running a Subset of the
Tests](https://github.com/google/googletest/blob/master/docs/advanced.md#running-a-subset-of-the-tests)
for more details.

```
mach gtest Moz2D.*
```

### Configuring GTest

GTest can be controlled from other environment variables. See [Running
Test Programs: Advanced
Options](https://github.com/google/googletest/blob/master/docs/advanced.md#running-test-programs-advanced-options)
for more details.

## Debugging a GTest Unit Test

To debug a gtest, pass --debug to the normal command.

```shell
./mach gtest --debug [ Prefix.Test ]
```

If that doesn't work, you can try running the firefox binary under the
debugger with the MOZ_RUN_GTEST environment variable set to 1.

```shell
MOZ_RUN_GTEST=1 ./mach run --debug [--debugger gdb]
```

:::{warning}
Don't forget to build + run 'mach gtest' to relink when using
MOZ_RUN_GTEST since it's not part of a top level build.
:::

Note that this will load an alternate libxul - the one which has the
test code built in, which resides in a gtest/subdirectory of your
objdir. This gtest-enabled libxul is not built as part of the regular
build, so you must ensure that it is built before running the above
command. A simple way to do this is to just run "mach gtest" which will
rebuild libxul and run the tests. You can also extract the commands
needed to just rebuild that libxul [from
mach](https://hg.mozilla.org/mozilla-central/file/3673d2c688b4/python/mozbuild/mozbuild/mach_commands.py#l486)
and run those directly. Finally, note that you may have to run through
the tests once for gdb to load all the relevant libraries and for
breakpoint symbols to resolve properly.

Note that you can debug a subset of the tests (including a single test)
by using the GTEST_FILTER environment variable:

```shell
GTEST_FILTER='AsyncPanZoom*' MOZ_RUN_GTEST=1 ./mach run --debug [--debugger gdb]
```

### Debugging with Xcode

See {doc}`/contributing/debugging/debugging_on_macos` for initial
setup. You'll likely want to create a separate scheme for running GTest
("Product" > "Scheme" > "New Scheme…"). In addition to GTEST_FILTER, Set
the following environment variables:

```
MOZ_XRE_DIR=/path-to-object-directory/obj-ff-dbg/dist/bin
MOZ_RUN_GTEST=True
```

and under the "Options" tab for the scheme, set the working directory
to:

```
☑️ Use custom working directory: /path-to-object-directory/obj-ff-dbg/_tests/gtest
```

### Debugging with Visual Studio Code

Add a configuration like this to your launch.json file (you can edit it
via Run / Open Configurations):

```
        {
            "name": "(gdb) Launch gtest",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/obj-x86_64-pc-linux-gnu/dist/bin/firefox",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}/obj-x86_64-pc-linux-gnu/_tests/gtest",
            "environment": [{"name": "MOZ_RUN_GTEST", "value": "True"},
                            {"name": "GTEST_FILTER", "value": "AsyncPanZoom*"}],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ]
        },
```

## Writing a GTest Unit Test

Most of the [GTest
documentation](https://github.com/google/googletest/blob/master/googletest/README.md)
will apply here. The [GTest
primer](https://github.com/google/googletest/blob/master/docs/primer.md)
is a recommended read.

:::{warning}
GTest will run tests in parallel. Don't add unit tests that are not
threadsafe, such as tests that require focus or use specific sockets.
:::

:::{warning}
GTest will run without initializing mozilla services. Initialize and
tear down any dependencies you have in your test fixtures. Avoid
writing integration tests and focus on testing individual units.
:::

See <https://hg.mozilla.org/mozilla-central/rev/ed612eec41a44867a> for an
example of how to add a simple test.

If you're converting an existing C++ unit test to a GTest, [this
commit](https://hg.mozilla.org/mozilla-central/rev/40740cddc131) may
serve as a useful reference.

### Setting prefs for a test

If tests cover functionality that is disabled by default, you'll have to
change the relevant preferences either in the individual test:

```
bool oldPref = Preferences::GetBool(prefKey);
Preferences::SetBool(prefKey, true);
… // test code
Preferences::SetBool(prefKey, oldPref);
```

or, if it applies more broadly, the change can be applied to the whole
fixture (see [the GTest
docs](https://github.com/google/googletest/blob/master/googletest/README.md),
or
[AutoInitializeImageLib](https://searchfox.org/mozilla-central/search?q=AutoInitializeImageLib%3A%3AAutoInitializeImageLib&path=)
as an example).

### Adding a test to the build system

Find a gtest directory appropriate for the module. If none exist create
a directory using the following convention: '<submodule>/tests/gtest'.
Create a moz.build file (in the newly created directory) with a module
declaration, replacing gfxtest with a unique name, and set
UNIFIED_SOURCES to contain all of the test file names.

What we're doing here is creating a list of source files that will be
compiled and linked only against the gtest version of libxul. This will
let these source files call internal xul symbols without making them
part of the binary we ship to users.

```
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.

Library('gfxtest')

UNIFIED_SOURCES = [
    <ListTestFiles>,
]

FINAL_LIBRARY = 'xul-gtest'
```

Update '<submodule>/moz.build' in the parent directory to build your new
subdirectory in:

```python
TEST_DIRS += [
    "gtest",
]
```

When adding tests to an existing moz.build file (it has FINAL_LIBRARY =
'xul-gtest'), add the following. That's it--there is no test manifest
required. Your tests will be automatically registered using a static
constructor.

```python
UNIFIED_SOURCES = [
    "TestFoo.cpp",
]
```

### Notes

The include file for the class you are testing may not need to be
globally exported, but it does need to be made available to the unit
test you are writing. In that case, add something like this to the
Makefile.in inside of the testing directory.

```python
LOCAL_INCLUDES += [
    "/gfx/2d",
    "/gfx/2d/unittest",
    "/gfx/layers",
]
```

Gtests currently run from the test package under the **GTest** symbol on
[Treeherder](https://treeherder.mozilla.org/) if you want to verify
that your test is working. Formerly they were run under the **B**
symbol, during `make check`.

## MozGTestBench

A Mozilla GTest Microbench is just a GTest that reports the test
duration to perfherder. It's an easy way to add low level performance
test. Keep in mind that there's a non-zero cost to monitoring
performance test so use them sparingly. You can still perform test
assertions.

### Writing a Microbench GTest

Use 'MOZ_GTEST_BENCH' instead of 'TEST' to time the execution of your
test. Example:

```cpp
#include "gtest/MozGTestBench.h" // For MOZ_GTEST_BENCH

...

MOZ_GTEST_BENCH(GfxBench, TEST_NAME, []{
  // Test to time the execution
});
```

Make sure this file is registered with the file system using the
instructions above. If everything worked correctly you should see this
in the GTest log for your corresponding test:

```js
PERFHERDER_DATA: {"framework": {"name": "platform_microbench"}, "suites": [{"name": "GfxBench", "subtests": [{"name": "CompositorSimpleTree", "value": 252674, "lowerIsBetter": true}]}]}
```

### Sheriffing policy

Microbench tests measure the speed of a very specific operation. A
regression in a micro-benchmark may not lead to a user visible
regression and should not be treated as strictly as a Talos regression.
Large changes in microbench scores will also be expected when the code
is directly modified and should be accepted if the developer intended to
change that code. Micro-benchmarks however provide a framework for
adding performance tests for platform code and regression tests for
performance fixes. They will catch unintended regressions in code and
when correlated with a Talos regression might indicate the source of the
regression.

---

### Metrics Index (`docs/metrics/index.md`)

# Firefox metrics

The metrics collected by Firefox using the
[Glean SDK](https://mozilla.github.io/glean/book/index.html)
are documented in
[The Glean Dictionary](https://dictionary.telemetry.mozilla.org/apps/firefox_desktop/).

---

### Nspr Index (`docs/nspr/index.md`)

# NSPR

```{warning}
NSPR is a legacy library. We do not recommend using it in new projects.
It is maintained primarily for existing Mozilla code that still depends
on it; modern platform and standard-library facilities should be
preferred instead.
```

**Netscape Portable Runtime (NSPR)** provides a platform-neutral API for
system level and libc-like functions. The API is used in the Mozilla
clients, many of Red Hat's and Oracle's server applications, and other
software offerings.

## Documentation

{doc}`about_nspr`

: This topic describes, in general terms, the goals of NSPR and a bit
  about how it does it.

{doc}`reference/index`

: The reference describes each API public macro, structure and function
  in the NSPR API.

{doc}`nspr_build_instructions`

: How to checkout and build from source.

{doc}`nspr_release_procedure`

: How to cut a new NSPR release: bumping the version and producing the
  distributions.

{doc}`listing`

: All NSPR pages

(getting-nspr)=

## Getting NSPR

NSPR is available in various source and binary packages, depending on
your platform:

- **Windows:** Build the source package, using the {doc}`nspr_build_instructions`.

- **Mac:** Install the [MacPorts](http://www.macports.org/) *nspr*
  package, or the [Homebrew](http://brew.sh) *nspr* package.

- **Ubuntu:** Install the *libnspr4-dev* package via `apt-get.`

- **Debian:** Install the *libnspr4-dev* package via `apt-get`.

- **openSUSE Linux:** Install one or more of the following via `yast`
  or `zypper` :

  - *mozilla-nspr* : Binary libraries for your platform
  - *mozilla-nspr-32bit* : Binary libraries needed to run 32-bit
    programs on a 64-bit OS
  - *mozilla-nspr-devel* : Files needed (in addition to the above
    libraries) to compile programs using NSPR
  - *mozilla-nspr-debuginfo* : Debug information (including build
    symbols) for package *mozilla-nspr*
  - *mozilla-nspr-debuginfo-32bit* : Debug information (including
    build symbols) for package *mozilla-nspr-32bit*
  - *mozilla-nspr-debugsource* : Debug sources for all of the above

## Community

View Mozilla forums:

- [Mailing list](https://lists.mozilla.org/listinfo/dev-tech-nspr)
- [Newsgroup](http://groups.google.com/group/mozilla.dev.tech.nspr)
- [RSS
  feed](http://groups.google.com/group/mozilla.dev.tech.nspr/feeds)

(related-topics)=

## Related Topics

- {doc}`/networking/index`, {doc}`/security/nss/index`

```{toctree}
:hidden:
:maxdepth: 1

listing
```

---

### Overview Index (`docs/overview/index.md`)

# A Quick Guide to Mozilla Applications

```{toctree}
gecko
/browser/overview
/mobile/android/index
ios
```

---

### Performance Index (`docs/performance/index.md`)

# Performance

This page explains how to optimize the performance of the Firefox code base.

The [test documentation](/testing/perfdocs/index.md)
explains how to test for performance in Firefox.
The [profiler documentation](/tools/profiler/index.md)
explains how to use the Gecko profiler.

```{toctree}
:hidden:
:glob:

*
memory/index
build_metrics/build_metrics
platform_microbenchmarks/platform_microbenchmarks
```

## General Performance references

* Tips on generating valid performance metrics by [benchmarking](Benchmarking.md)
* [GPU Performance](GPU_performance.md) Tips for reducing impacts on browser performance in front-end code.
* [Automated Performance testing and Sheriffing](automated_performance_testing_and_sheriffing.md) Information on automated performance testing and sheriffing at Mozilla.
* [Performance best practices for Firefox front-end engineers](bestpractices.md) Tips for reducing impacts on browser performance in front-end code.
* [Reporting a performance problem](reporting_a_performance_problem.md) A user friendly guide to reporting a performance problem. A development environment is not required.
* [Scroll Linked Effects](scroll-linked_effects.md) Information on scroll-linked effects, their effect on performance, related tools, and possible mitigation techniques.

## Memory profiling and leak detection tools

* The [Developer Tools Memory panel](/devtools-user/memory/index.md) supports taking heap snapshots, diffing them, computing dominator trees to surface "heavy retainers", and recording allocation stacks.
* [About:memory](memory/about_colon_memory.md) about:memory is the easiest-to-use tool for measuring memory usage in Mozilla code, and is the best place to start. It also lets you do other memory-related operations like trigger GC and CC, dump GC & CC logs, and dump DMD reports. about:memory is built on top of Firefox's [memory reporting](memory/memory_reporting.md) infrastructure.
* [DMD](memory/dmd.md) is a tool that identifies shortcomings in about:memory's measurements, and can also do multiple kinds of general heap profiling.
* [AWSY](memory/awsy.md) (are we slim yet?) is a memory usage and regression tracker.
* [Bloatview](memory/bloatview.md) prints per-class statistics on allocations and refcounts, and provides gross numbers on the amount of memory being leaked broken down by class. It is used as part of Mozilla's continuous integration testing.
* [Refcount Tracing and Balancing](memory/refcount_tracing_and_balancing.md) are ways to track down leaks caused by incorrect uses of reference counting. They are slow and not particular easy to use, and thus most suitable for use by expert developers.
* [GC and CC Logs](memory/gc_and_cc_logs.md)
* [LogAlloc](https://searchfox.org/firefox-main/source/memory/replace/logalloc/README) is a tool that dumps a log of memory allocations in Gecko. That log can then be replayed against Firefox's default memory allocator independently or through another replace-malloc library, allowing the testing of other allocators under the exact same workload.
* [See also the documentation on Leak-hunting strategies and tips.](memory/leak_hunting_strategies_and_tips.md)

## Profiling and performance tools

* [JIT Profiling with perf](jit_profiling_with_perf.md) Using perf to collect JIT profiles.
* [JIT Profiling with samply](jit_profiling_with_samply.md) Using samply to collect JIT profiles
* [Profiling with simpleperf](profiling_with_simpleperf.md) `simpleperf` is the Android equivalent of Linux's `perf`
* [Profiling with Instruments](profiling_with_instruments.md) How to use Apple's Instruments tool to profile Mozilla code.
* [Profiling with xperf](profiling_with_xperf.md) How to use Microsoft's Xperf tool to profile Mozilla code.
* [Profiling with Concurrency Visualizer](profiling_with_concurrency_visualizer.md) How to use Visual Studio's Concurrency Visualizer tool to profile Mozilla code.
* [Profiling with Zoom](profiling_with_zoom.md) Zoom is a profiler for Linux done by the people who made Shark.
* [Adding a new telemetry probe](https://firefox-source-docs.mozilla.org/toolkit/components/telemetry/start/adding-a-new-probe.html) Information on how to add a new measurement to the Telemetry performance-reporting system

## Power Profiling

* [An overview of power profiling](power_profiling_overview.md). It includes details about hardware, what can be measured, and recommended approaches. It should be the starting point for anybody new to power profiling.
* **(Mac, Linux)** [tools/power/rapl](tools_power_rapl.md) is a command-line utility in the Mozilla codebase that uses the Intel RAPL interface to gather direct power estimates for the package, cores, GPU and memory.
* **(Mac-only)** [powermetrics](powermetrics.md) is a command-line utility that gathers and displays a wide range of global and per-process measurements, including CPU usage, GPU usage, and various wakeups frequencies.
* **(All-platforms)** [TimerFirings](timerfirings_logging.md) logging is a built-in logging mechanism that prints data on every time fired.
* **(Mac-only)** [Activity Monitor and top](activity_monitor_and_top.md) The battery status menu, Activity Monitor and top are three related Mac tools that have major flaws but often consulted by users, and so are worth understanding.
* **(Windows, Mac and Linux)** [Intel Power Gadget](intel_power_gadget.md) Intel Power Gadget provides real-time graphs for package and processor RAPL estimates. It also provides an API through which those estimates can be obtained.
* **(Linux only)** [perf](perf.md) perf is a powerful command-line utility that can measure many different things, including energy estimates and high-context measurements of things such as wakeups.
* **(Linux-only)** [turbostat](turbostat.md) is a command-line utility that gathers and displays various power-related measurements, with a focus on per-CPU measurements such as frequencies and C-states.
* **(Linux-only)** [powertop](https://01.org/powertop) is an interactive command-line utility that gathers and displays various power-related measurements.

## Performance Metrics

* [PerfStats](perfstats.md) - A framework for low-overhead collection of internal performance metrics.

---

### Performance Power Profiling Overview (`docs/performance/power_profiling_overview.md`)

# Power profiling

This article covers important background information about power
profiling, with an emphasis on Intel processors used in desktop and
laptop machines. It serves as a starting point for anybody doing power
profiling for the first time.

## Basic physics concepts

In physics, *[power](https://en.wikipedia.org/wiki/Power_%28physics%29)*
is the rate of doing
*[work](https://en.wikipedia.org/wiki/Work_%28physics%29 "Work (physics)")*.
It is equivalent to an amount of
*[energy](https://en.wikipedia.org/wiki/Energy_%28physics%29 "Energy (physics)"){.mw-redirect}*
consumed per unit time. In SI units, energy is measured in Joules, and
power is measured in Watts, which is equivalent to Joules per second.

Although power is an instantaneous concept, in practice measurements of
it are determined in a non-instantaneous fashion, i.e. by dividing an
energy amount by a non-infinitesimal time period. Strictly speaking,
such a computation gives the *average power* but this is often referred
to as just the *power* when context makes it clear.

In the context of computing, a fully-charged mobile device battery (as
found in a laptop or smartphone) holds a certain amount of energy, and
the speed at which that stored energy is depleted depends on the power
consumption of the mobile device. That in turn depends on the software
running on the device. Web browsers are popular applications and can be
power-intensive, and therefore can significantly affect battery life. As
a result, it is worth optimizing (i.e. reducing) the power consumption
caused by Firefox and Firefox OS.

## Intel processor basics

### Processor layout

The following diagram (from the [Intel Power Governor
documentation)](https://software.intel.com/en-us/articles/intel-power-governor)
shows how machines using recent Intel processors are constructed.



The important points are as follows.

- The processor has one or more *packages*. These are part of the
  actual processor that you buy from Intel. Client processors (e.g.
  Core i3/i5/i7) have one package. Server processors (e.g. Xeon)
  typically have two or more packages.
- Each package contains multiple *cores*.
- Each core typically has
  [hyper-threading](https://en.wikipedia.org/wiki/Hyper-threading),
  which means it contains two logical *CPUs*.
- The part of the package outside the cores is called the [*uncore* or
  *system agent*](https://en.wikipedia.org/wiki/Uncore)*.* It includes
  various components including the L3 cache, memory controller, and,
  for processors that have one, the integrated GPU.
- RAM is separate from the processor.

### C-states

Intel processors have aggressive power-saving features. The first is the
ability to switch frequently (thousands of times per second) between
active and idle states, and there are actually several different kinds
of idle states. These different states are called
*[C-states](https://en.wikipedia.org/wiki/Advanced_Configuration_and_Power_Interface#Processor_states).*
C0 is the active/busy state, where instructions are being executed. The
other states have higher numbers and reflect increasing deeper idle
states. The deeper an idle state is, the less power it uses, but the
longer it takes to wake up from.

Note: the [ACPI
standard](https://en.wikipedia.org/wiki/Advanced_Configuration_and_Power_Interface)
specifies four states, C0, C1, C2 and C3. Intel maps these to
processor-specific states such as C0, C1, C2, C6 and C7. and many tools
report C-states using the latter names. The exact relationship is
confusing, and chapter 13 of the [Intel optimization
manual](http://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-optimization-manual.html)
has more details. The important thing is that C0 is always the active
state, and for the idle states a higher number always means less power
consumption.

The other thing to note about C-states is that they apply both to cores
and the entire package --- i.e. if all cores are idle then the entire
package can also become idle, which reduces power consumption even
further.

The fraction of time that a package or core spends in an idle C-state is
called the *C-state residency*. This is a misleading term --- the active
state, C0, is also a C-state --- but one that is nonetheless common.

Intel processors have model-specific registers (MSRs) containing
measurements of how much time is spent in different C-states, and tools
such as [powermetrics](powermetrics.md)
(Mac), powertop and
[turbostat](turbostat.md) (Linux) can
expose this information.

A *wakeup* occurs when a core or package transitions from an idle state
to the active state. This happens when the OS schedules a process to run
due to some kind of event. Common causes of wakeups include scheduled
timers going off and blocked I/O system calls receiving data.
Maintaining C-state residency is crucial to keep power consumption low,
and so reducing wakeup frequency is one of the best ways to reduce power
consumption.

One consequence of the existence of C-states is that observations made
during power profiling --- even more than with other kinds of profiling
--- can disturb what is being observed. For example, the Gecko Profiler
takes samples at 1000Hz using a timer. Each of these samples can trigger
a wakeup, which consumes power and obscures Firefox's natural wakeup
patterns. For this reason, integrating power measurements into the Gecko
Profiler is unlikely to be useful, and other power profiling tools
typically use much lower sampling rates (e.g. 1Hz.)

### P-states

Intel processors also support multiple *P-states*. P0 is the state where
the processor is operating at maximum frequency and voltage, and
higher-numbered P-states operate at a lower frequency and voltage to
reduce power consumption. Processors can have dozens of P-states, but
the transitions are controlled by the hardware and OS and so P-states
are of less interest to application developers than C-states.

## Power and power-related measurements

There are several kinds of power and power-related measurements. Some
are global (whole-system) and some are per-process. The following
sections list them from best to worst.

### Power measurements

The best measurements are measured in joules and/or watts, and are taken
by measuring the actual hardware in some fashion. These are global
(whole-system) measurements that are affected by running programs but
also by other things such as (for laptops) how bright the monitor
backlight is.

- Devices such as ammeters give the best results, but these can be
  expensive and difficult to set up.
- A cruder technique that works with mobile machines and devices is to
  run a program for a long time and simply time how long it takes for
  the battery to drain. The long measurement times required are a
  disadvantage, though.

### Power estimates

The next best measurements come from recent (Sandy Bridge and later)
Intel processors that implement the *RAPL* (Running Average Power Limit)
interface that provides MSRs containing energy consumption estimates for
up to four *power planes* or *domains* of a machine, as seen in the
diagram above.

- PKG: The entire package.
  - PP0: The cores.
  - PP1: An uncore device, usually the GPU (not available on all
    processor models.)
- DRAM: main memory (not available on all processor models.)

The following relationship holds: PP0 + PP1 \<= PKG. DRAM is independent
of the other three domains.

These values are computed using a power model that uses
processor-internal counts as inputs, and they have been
[verified](http://www.computer.org/csdl/proceedings/ispass/2013/5776/00/06557170.pdf)
as being fairly accurate. They are also updated frequently, at
approximately 1,000 Hz, though the variability in their update latency
means that they are probably only accurate at lower frequencies, e.g. up
to 20 Hz or so. See section 14.9 of Volume 3 of the [Intel Software
Developer's
Manual](http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html)
for more details about RAPL.

Tools that can take RAPL readings include the following.

- `tools/power/rapl`: all planes; Linux and Mac.
- [Intel Power
  Gadget](intel_power_gadget.md): PKG and
  PP0 planes; Windows, Mac and Linux.
- [powermetrics](powermetrics.md): PKG
  plane; Mac.
- [perf](perf.md): all planes; Linux.
- [turbostat](turbostat.md): PKG, PP0 and
  PP1 planes; Linux.

Of these,
[tools/power/rapl](tools_power_rapl.md) is
generally the easiest and best to use because it reads all power planes,
it's a command line utility, and it doesn't measure anything else.

### Proxy measurements

The next best measurements are proxy measurements, i.e. measurements of
things that affect power consumption such as CPU activity, GPU activity,
wakeup frequency, C-state residency, disk activity, and network
activity. Some of these are measured on a global basis, and some can be
measured on a per-process basis. Some can also be measured via
instrumentation within Firefox itself.

The correlation between each proxy measure and power consumption is hard
to know and can vary greatly. When used carefully, however, they can
still be useful. This is because they can often be measured in a more
fine-grained fashion than power measurements and estimates, which is
vital for gaining insight into how a program can reduce power
consumption.

Most profiling tools provide at least some proxy measurements.

### Hybrid proxy measurements

These are combinations of proxy measurements. The combinations are
semi-arbitrary, they amplify the unreliability of proxy measurements,
and unlike non-hybrid proxy measurements, they don't have a clear
physical meaning. Avoid them.

The most notable example of a hybrid proxy measurement is the ["Energy
Impact" used by OS X's Activity
[Monitor](activity_monitor_and_top.md#what-does-energy-impact-measure).

## Ways to user power-related measurements

### Low-context measurements

Most power-related measurements are global or per-process. Such
low-context measurements are typically good for understand *if* power
consumption is good or bad, but in the latter case they often don't
provide much insight into why the problem is occurring, which part of
the code is at fault, or how it can be fixed. Nonetheless, they can
still help improve understanding of a problem by using *differential
profiling*.

- Compare browsers to see if Firefox is doing better or worse than
  another browser on a particular workload.
- Compare different versions of Firefox to see if Firefox has improved
  or worsened over time on a particular workload. This can identify
  specific changes that caused regressions, for example.
- Compare different configurations of Firefox to see if a particular
  feature is affecting things.
- Compare different workloads. This can be particularly useful if the
  workloads only vary slightly. For example, it can be useful to
  gradually remove elements from a web page and see how the
  power-related measurements change. Even just switching a tab from
  the foreground to the background can make a difference.

### High-context measurements

A few power-related measurements can be obtained in a high-context
fashion, e.g. with stack traces that clearly pinpoint specific parts of
the code as being responsible.

- Standard performance profiling tools that measure CPU usage or
  proxies of CPU usage (such as instruction counts) typically provide
  high-context measurements. This is useful because high CPU usage
  typically causes high power consumption.
- Some tools can provide high-context wakeup measurements:
  [dtrace](dtrace.md) (on Mac) and
  [perf](perf.md) (on Linux.)
- Source-level instrumentation, such as [TimerFirings
  logging](timerfirings_logging.md), can
  identify which timers are firing frequently.

## Power profiling how-to

This section aims to put together all the above information and provide
a set of strategies for finding, diagnosing and fixing cases of high
power consumption.

- First of all, all measurements are best done on a quiet machine that
  is running little other than the program of interest. Global
  measurements in particular can be completely skewed and unreliable
  if this is not the case.
- Find or confirm a test case where Firefox's power consumption is
  high. "High" can most easily be gauged by comparing against other
  browsers. Use power measurements or estimates (e.g. via
  [tools/power/rapl](tools_power_rapl.md),
  or `mach power` on Mac, or [Intel Power
  Gadget](intel_power_gadget.md) on
  Windows) for the comparisons. Avoid lower-quality measurements,
  especially Activity Monitor's "Energy Impact".
- Try using differential profiling to narrow down the cause.
  - Try turning hardware acceleration on or off; e10s on or off;
    Flash on or off.
  - Try putting the relevant tab in the foreground vs. in the
    background.
  - If the problem manifests on a particular website, try saving a
    local copy of the site and then manually removing HTML elements
    to see if a particular page feature is causing the problem
- Many power problems are caused by either high CPU usage or high
  wakeup frequency. Use one of the low-context tools to determine if
  this is the case (e.g. on Mac use
  [powermetrics](powermetrics.md).) If
  so, follow that up by using a tool that gives high-context
  measurements, which hopefully will identify the cause of the
  problem.
  - For high CPU usage, many profilers can be used: Firefox's dev
    tools profiler, the Gecko Profiler, or generic performance
    profilers.
  - For high wakeup counts, use
    [dtrace](dtrace.md) or
    [perf](perf.md) or [TimerFirings logging](timerfirings_logging.md).
- On Mac workloads that use graphics, Activity Monitor's "Energy"
  tab can tell you if the high-performance GPU is being used, which
  uses more power than the integrated GPU.
- If neither CPU usage nor wakeup frequency identifies the problem,
  more ingenuity may be needed. Looking at other measurements (C-state
  residency, GPU usage, etc.) may be helpful.
- Animations are sometimes the cause of high power consumption. The
  [animation
  inspector](/devtools-user/page_inspector/how_to/work_with_animations/index.md#animation-inspector)
  in the Firefox Devtools can identify them. Alternatively, [here is
  an
  explanation](https://bugzilla.mozilla.org/show_bug.cgi?id=1190721#c10)
  of how one developer diagnosed two animation-related problems the
  hard way (which required genuine platform expertise).
- The approximate cause of power problems often isn't that hard to
  find. Fixing them is often the hard part. Good luck.
- If you do fix a problem by improving a proxy measurement, you should
  verify that it also improves a power measurement or estimate. That
  way you know the fix had a genuine effect.

## Further reading

Chapter 13 of the [Intel optimization
manual](http://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-optimization-manual.html)
has many details about optimizing for power consumption. Section 13.5
("Tuning Software for Intelligent Power Consumption") in particular is
worth reading.

---

### Rust Components Index (`docs/rust-components/index.md`)

# Rust Components

This section is meant to make it easier to use and implement cross-platform components written in Rust.

```{toctree}
:titlesonly:
:maxdepth: 2

Topic Guides <topic-guides/index>
API References <api/index>
Developing Rust Components <developing-rust-components/index>
uniffi-bindgen-gecko-js developers guide <uniffi-bindgen-gecko-js-dev-guide/index>
```

---

### Setup Index (`docs/setup/index.md`)

# Getting Set Up To Work On The Firefox Codebase

This page will help you get set up to build Firefox on your own machine.

Don't hesitate to look at the {doc}`Firefox Contributors Quick Reference </contributing/contribution_quickref>` to read a quick tutorial.

```{toctree}
:caption: Thank you for contributing to Firefox

/contributing/contributing_to_mozilla
```

## Setting Up Your Machine

### For Firefox Desktop

```{toctree}
:maxdepth: 1

windows_build
windows_wsl_build
macos_build
linux_build
linux_32bit_build_on_64bit_OS
common_build_errors
```

### For Firefox Android

{doc}`/mobile/android/index`

### For Firefox iOS

{doc}`/overview/ios`

## Getting Ready to Contribute

```{toctree}
contributing_code
building_with_debug_symbols
configuring_build_options
editing_moz_configure
```

---

### Testing Rust Code Index (`docs/testing-rust-code/index.md`)

# Testing & Debugging Rust Code

This page explains how to test and debug Rust code in Firefox.

The [build documentation](/build/buildsystem/rust.md) explains how to add
new Rust code to Firefox. The [code documentation](/writing-rust-code/index.md)
explains how to write and work with Rust code in Firefox.

## Testing Mozilla crates

Rust code will naturally be tested as part of system tests such as Mochitests.
This section describes the two methods for unit testing of individual Rust
crates. Which method should be used depends on the circumstances.

### Rust tests

If a Mozilla crate has "normal" Rust tests (i.e. `#[test]` functions that run
with `cargo test`), you can add the crate's name to `RUST_TESTS` in
[toolkit/library/rust/moz.build](https://searchfox.org/firefox-main/source/toolkit/library/rust/moz.build).
(Cargo features can be activated for Rust tests by adding them to
`RUST_TEST_FEATURES` in the same file.)

Rust tests are run with `./mach rusttests`. They run on automation in a couple
of `rusttests` jobs, but not on all platforms.

Rust tests have one major restriction: they cannot link against Gecko symbols.
Therefore, Rust tests cannot be used for crates that use Gecko crates like
`nsstring` and `xpcom`.

It's also possible to use `RUST_TESTS` in a different `moz.build` file. See
`testing/geckodriver/moz.build` and the [geckodriver testing docs] for an
example.

[geckodriver testing docs]: /testing/geckodriver/Testing.md

### GTests

Another way to unit test a Mozilla crate is by writing a GTest that uses FFI to
call into Rust code. This requires the following steps.

- Create a new test crate whose name is the same as the name of crate being
  tested, with a `-gtest` suffix.
- Add to the test crate a Rust file, a C++ file containing GTest `TEST()`
  functions that use FFI to call into the Rust file, a `Cargo.toml` file that
  references the Rust file, and a `moz.build` file that references the C++
  file.
- Add an entry to the `[dependencies]` section in
  [toolkit/library/gtest/rust/Cargo.toml](https://searchfox.org/firefox-main/source/toolkit/library/gtest/rust/Cargo.toml).
- Add an `extern crate` entry to
  [toolkit/library/gtest/rust/lib.rs](https://searchfox.org/firefox-main/source/toolkit/library/gtest/rust/lib.rs).

See
[xpcom/rust/gtest/nsstring/](https://searchfox.org/firefox-main/source/xpcom/rust/gtest/nsstring)
for a simple example. (Note that the `moz.build` file is in the parent
directory for that crate.)

A Rust GTest can be run like any other GTest via `./mach gtest`, using the C++
`TEST()` functions as the starting point.

Unlike Rust tests, GTests can be used when linking against Gecko symbols is required.

## Testing third-party crates

In general we don't run tests for third-party crates. The assumption is that
these crates are sufficiently well-tested elsewhere.

## Debugging Rust code

In theory, Rust code is debuggable much like C++ code, using standard tools
like `gdb`, `rr`, and the Microsoft Visual Studio Debugger. In practice, the
experience can be worse, because shortcomings such as the following can occur.

- Inability to print local variables, even in non-optimized builds.
- Inability to call generic functions.
- Missing line numbers and stack frames.
- Printing of basic types such as `Option` and `Vec` is sometimes sub-optimal.
  If you see a warning "Missing auto-load script at offset 0 in section
  `.debug_gdb_scripts`" when starting `gdb`, the `rust-gdb` wrapper may give
  better results.

## Logging from Rust code

### Rust logging

The `RUST_LOG` environment variable (from the `env_logger` crate) can be used
to enable logging to stderr from Rust code in Firefox. The logging macros from
the `log` crate can be used. In order of importance, they are: `error!`,
`warn!`, `info!`, `debug!`, `trace!`.

For example, to show all log messages of `info` level or higher, run:

```
RUST_LOG=info firefox
```

Module-level logging can also be specified, see the [documentation] for the
`env_logger` crate for details.

To restrict logging to child processes, use `RUST_LOG_CHILD` instead of
`RUST_LOG`.

[documentation]: https://docs.rs/env_logger/

### Gecko logging

Rust logging can also be forwarded to the [Gecko logger] for capture via
`MOZ_LOG` and `MOZ_LOG_FILE`.

[Gecko logger]: /xpcom/logging.md

- When parsing modules from `MOZ_LOG`, modules containing `::` are considered
  to be Rust modules. To log everything in a top-level module like
  `neqo_transport`, specify it as `neqo_transport::*`. For example:

```
MOZ_LOG=timestamp,sync,nsHostResolver:5,neqo_transport::*:5,proxy:5 firefox
```

- When logging from a submodule the `::*` is allowed but isn't necessary.
  So these two lines are equivalent:

```
MOZ_LOG=timestamp,sync,neqo_transport::recovery:5 firefox
MOZ_LOG=timestamp,sync,neqo_transport::recovery::*:5 firefox
```

- `debug!` and `trace!` logs will not appear in non-debug builds. This is due
  to our use of the `release_max_level_info` feature in the `log` crate.

- When using both `MOZ_LOG` and `RUST_LOG`, modules that are specified in
  `MOZ_LOG` will not appear in `RUST_LOG`.

---

### Update Infrastructure Index (`docs/update-infrastructure/index.md`)

# Mozilla Update Infrastructure

Firefox, Thunderbird, and Mozilla VPN updates rely on [backend service known as Balrog](https://github.com/mozilla-releng/balrog). Periodically, these applications check for updates by pinging an URL[^1] which contains information about both the application running, and details of the system it is running on. If Balrog finds an update based on the provided information, it returns a simple XML response with a link to the update file, and some metadata about it.

# Watershed Updates

Most of the time, an update will take an application directly from whatever version it is currently running to the latest version of that application. This is greatly preferred, both to save time, bandwidth, reduce restarts, and increase security by ensuring we get to the latest version of something as quickly as possible. Unfortunately, sometimes we must route through an intermediate version first, typically the version that is currently running does not provide Balrog with enough information to accurately serve a correct update to the latest version. These are colloquially known as "watershed" updates. (This name comes from the fact that these updates change something about the update process itself, making them a kind of "watershed moment" for updates.)

At the time of writing (July, 2024), we currently have the following watershed updates in place for Firefox's release channel:

* 12.0, all platforms. In this release [we added support for distinguishing the running and supported architectures in macOS builds in the update URL](https://bugzilla.mozilla.org/show_bug.cgi?id=583671).
* 43.0.1, Windows only. This release was [preparation for desupporting SHA-1 hashes in our Windows builds](https://bugzilla.mozilla.org/show_bug.cgi?id=1234277).
* 45.0.2, Linux only. We added support for [sending the GTK 3 version to the update URL](https://bugzilla.mozilla.org/show_bug.cgi?id=1227023).
* 47.0.2, Windows only. We [added CPU instruction set information to the update URL](https://bugzilla.mozilla.org/show_bug.cgi?id=1271761) to later allow SSE1 to be deprecated.
* 56.0, Windows only. We added support for [sending information about the JAWS accessibility application to the update URL](https://bugzilla.mozilla.org/show_bug.cgi?id=1402376) to avoid updating people on crashy versions of it. Additionally, we [added support for LZMA compression to the updater](https://bugzilla.mozilla.org/show_bug.cgi?id=641212) and [swapped to new MAR signing keys](https://bugzilla.mozilla.org/show_bug.cgi?id=1324498).
* 57.0.4[^2], Linux & Mac only. We [added support for LZMA compression to the updater](https://bugzilla.mozilla.org/show_bug.cgi?id=641212) and [swapped to new MAR signing keys](https://bugzilla.mozilla.org/show_bug.cgi?id=1324498). (Note: Windows was not required here because they picked up this change in the above 56.0 watershed.)
* 72.0.2, all platforms. This is a required version due to a [necessary two-step password database migration](https://bugzilla.mozilla.org/show_bug.cgi?id=1615382).
* 109.0.1, macOS only. This updates the channel-prefs.js file (normally excluded from updates) due to [signature issues](https://bugzilla.mozilla.org/show_bug.cgi?id=1804303).
* 127.0, Windows only. The issuer for our code-signing certificate changed, [requiring an updated Mozilla Maintenance Service](https://bugzilla.mozilla.org/show_bug.cgi?id=1894689).

[^1]: Here is a sample URL: <https://aus5.mozilla.org/update/3/Firefox/85.0/20200518093924/WINNT_x86_64-msvc-x64/en-US/release/Windows_NT%2010.0.0.0.18363.1016%20(x64)/default/default/update.xml>
[^2]: While not directly related to the watershed, it is notable that due to LZMA MAR support shipping in the previous version (56.0), which was _not_ a watershed for Linux and Mac, we shipped two different sets of MARs for 57.0, 57.0.1, 57.0.2, 57.0.3, and 57.0.4: we had bz2 MARs, which builds older than 56.0 were served, and a separate set of LZMA MARs that were shipped to 56.0 and higher. More details on this can be found on [this awfully complicated spreadsheet that was produced around that time](https://docs.google.com/spreadsheets/d/1xcs9iTShJI8WBvxrz547Zr5JClqdRUYEZRMbQqdQ58I/edit#gid=0).

# Desupport Updates

From time to time we stop supporting a platform, hardware or library that we depend on. When we do this, we must ensure we don't update affected users to a version that they can no longer run. This can take two forms:

* In the distant past, we would simply stop serving updates altogether, leaving users on their current version.
* More recently, we will first move users to our `esr` channel - generally giving them another year of support before ending updates altogether.

Below is a list of desupports and moves to `esr` that we've done on the Firefox release channel:

* (Ancient, desupported at various old versions): Darwin 6, Darwin 7, Darwin 8, Darwin 9, Windows_95, Windows_98, Windows_NT 4, Windows_NT 5.0, Windows_NT 5.1.0, Windows_NT 5.1.1, GTK 2.0., GTK 2.1., GTK 2.2., GTK 2.3., GTK 2.4., GTK 2.5., GTK 2.6., GTK 2.7., GTK 2.8., GTK 2.9., GTK 2.10., GTK 2.11., GTK 2.12., GTK 2.13., GTK 2.14., GTK 2.15., GTK 2.16., GTK 2.17., PPC Architecture
* <46.0: [Desupported GTK <3.4](https://bugzilla.mozilla.org/show_bug.cgi?id=1270358)
* <49.0: Desupported [Darwin 10, 11, and 12](https://bugzilla.mozilla.org/show_bug.cgi?id=1275607) (macOS 10.6, 10.7, 10.8), [SSE and MMX instruction sets](https://bugzilla.mozilla.org/show_bug.cgi?id=1284901)
* <52.0: [Moved Windows XP, Server 2003, and Vista users to esr52](https://bugzilla.mozilla.org/show_bug.cgi?id=1318922)
* <53.0: [Desupported 32-bit macOS hardware](https://bugzilla.mozilla.org/show_bug.cgi?id=1325584)
* <77.0: [Moved Darwin 13, 14, and 15](https://bugzilla.mozilla.org/show_bug.cgi?id=1639199) (macOS 10.9, 10.10, and 10.11) to esr78
* <116.0: [Moved Darwin 16, 17, and 18](https://bugzilla.mozilla.org/show_bug.cgi?id=1836375) (macOS 10.12, 10.13, and 10.14) to esr115
* <116.0: [Moved Windows 7, 8, and 8.1](https://bugzilla.mozilla.org/show_bug.cgi?id=1594270) to esr115

---

### Writing Rust Code Index (`docs/writing-rust-code/index.md`)

# Writing Rust Code

This page explains how to write and work with Rust code in Firefox, with an
emphasis on interoperation with C++ code.

The [build documentation](/build/buildsystem/rust.md) explains how to add
new Rust code to Firefox. The [test documentation](/testing-rust-code/index.md)
explains how to test and debug Rust code in Firefox.

```{toctree}
:titlesonly:
:maxdepth: 1
:glob:

*
```

---

### Dom Docs Index (`dom/docs/index.md`)

# DOM

These linked pages contain design documents for the DOM implementation in Gecko. They live in-tree under the 'dom/docs' directory.

```{toctree}
:maxdepth: 1

handling_shadowDOM
ipc/index
navigation/index
push/index
scriptSecurity/index
scriptSecurity/xray_vision
workersAndStorage/index
webIdlBindings/index
ioutils_migration
fedcm
streams
promise/safe-promise-resolve
use-counters
loggingKeyboardIME
```

---

### Browser Branding Docs Index (`browser/branding/docs/index.md`)

# Firefox Branding

Firefox has multiple different sets of "branding" that are used to hold channel-specific things such as:

- Logos and other iconography
- Product names (eg: "Mozilla Firefox", "Firefox Developer Edition")
- Channel-specific preferences (eg: `app.update.interval`)

Brandings are stored in the {searchfox}`branding subdirectory <browser/branding>` and map to builds as follows:

- `official` is used for Release and Beta builds
- `aurora` is used for Developer Edition builds
- `nightly` is used for Nightly and Try builds
- `unofficial` is used when no other branding is specified (eg: local developer builds)

## Additional reading

```{toctree}
UpdatingMacIcons
```

---

### Browser Docs How To Index (`browser/docs/how_to/index.md`)

# How-To's

This section contains practical guides for common Firefox operations that
often occur when adding features, or changing existing features of the browser.

## Getting Started

If you're writing a new how-to guide, copy the {doc}`template` and follow its
structure to ensure consistency across all guides.

## Available Guides

```{toctree}
:maxdepth: 1

add_preview_strings
upgrading_profile_data
```

More guides will be added here as they are written.

## Template

```{toctree}
:maxdepth: 1

template
```

---

### Build Docs Mozbuild Index (`build/docs/mozbuild/index.md`)

# mozbuild

mozbuild is a Python package providing functionality used by Mozilla's
build system.

## Modules Overview

- mozbuild.backend -- Functionality for producing and interacting with build
  backends. A build backend is an entity that consumes build system metadata
  (from mozbuild.frontend) and does something useful with it (typically writing
  out files that can be used by a build tool to build the tree).
- mozbuild.compilation -- Functionality related to compiling. This
  includes managing compiler warnings.
- mozbuild.frontend -- Functionality for reading build frontend files
  (what defines the build system) and converting them to data structures
  which are fed into build backends to produce backend configurations.
- mozpack -- Functionality related to packaging builds.

## Overview

The build system consists of frontend files that define what to do. They
say things like "compile X" "copy Y."

The mozbuild.frontend package contains code for reading these frontend
files and converting them to static data structures. The set of produced
static data structures for the tree constitute the current build
configuration.

There exist entities called build backends. From a high level, build
backends consume the build configuration and do something with it. They
typically produce tool-specific files such as make files which can be used
to build the tree.

Piecing it all together, we have frontend files that are parsed into data
structures. These data structures are fed into a build backend. The output
from build backends is used by builders to build the tree.

---

### Devtools Docs Contributor README (`devtools/docs/contributor/README.md`)

# Firefox Developer Tools: Contributor Docs

This is a guide to working on the code for Firefox Developer Tools. If you're looking for help with using the tools, see the [user docs](https://firefox-source-docs.mozilla.org/devtools-user/). For other ways to get involved, check out our [community site](https://firefox-dev.tools).

---

### Devtools Docs Contributor Architecture Overview (`devtools/docs/contributor/architecture-overview.md`)

# DevTools architecture overview

Broadly speaking, the tools are divided in two parts: the server and the client. A **server** is anything that can be debugged: for example, your browser, but it could also be Firefox for Android, running on another device. The **client** is the front-end side of the tools, and it is what developers interact with when using the tools.

Since these two parts are decoupled, we can connect to any server using the same client. This enables us to debug multiple types of servers, using the same protocol to communicate.

You will often hear about `actors`. Each feature that can be debugged (for example, network) is exposed via an `actor`, which provides data about that specific feature. It's up to each server to implement some or all actors; the client needs to find out and decide what it can render on the front-side when it connects to the server. So when we want to debug a new feature, we might need to do work in two parts of the code: the server (perhaps implementing a new actor, or extending existing ones) and the client (to display the debugging data returned by the actor).

Often, an actor will correspond to a panel. But a panel might want to get data from multiple actors.

You might also hear about `the toolbox`. The toolbox is what everyone else calls `developer tools` i.e. the front-end that you see when you open the tools in your browser.

---

### Devtools Docs Contributor Index (`devtools/docs/contributor/index.md`)

```{toctree}
:name: devtools-contributor-doc
:hidden:
:maxdepth: 1

Getting started <README.md>
Architecture overview <architecture-overview.md>
Contributing <contributing.md>
Bugs and issues <bugs-issues.md>
```

# Firefox DevTools Contributor Docs

This is the contributor documentation for Firefox Developer Tools. If you're looking for help with using the tools, see the [user docs](https://firefox-source-docs.mozilla.org/devtools-user/index.html). Note that this section only contains technical information specific to Firefox DevTools, make sure to first read the [Firefox contributor documentation](https://firefox-source-docs.mozilla.org/contributing/index.html) which explains how to contribute to Firefox in general (setting up the environment, submitting patches, etc.).

## Automated tests

```{toctree}
:maxdepth: 1

Automated tests <tests/README.md>
xpcshell <tests/xpcshell.md>
Chrome mochitests <tests/mochitest-chrome.md>
DevTools mochitests <tests/mochitest-devtools.md>
Node tests <tests/node-tests.md>
Memory Allocation tests </devtools/tests/memory/index.md>
JavaScript Objects tests<tests/js-object-tests.md>
Writing tests <tests/writing-tests.md>
Debugging intermittent failures </testing/debugging-intermittents/index.md>
Performance tests overview<tests/performance-tests-overview.md>
Backward Compatibility tests <tests/backward-compat-tests.md>
DAMP Performance tests <tests/performance-tests-damp.md>
Writing a new test <tests/writing-perf-tests.md>
Example <tests/writing-perf-tests-example.md>
Advanced tips <tests/writing-perf-tests-tips.md>
```

## Files and directories

```{toctree}
:maxdepth: 1

Files and directories <files/README.md>
Adding New Files <files/adding-files.md>
```

## Tool Architectures

```{toctree}
:maxdepth: 1

Inspector Panel Architecture <tools/inspector-panel.md>
Inspector Highlighters <tools/highlighters.md>
Memory <tools/memory-panel.md>
Debugger <tools/debugger-panel.md>
Responsive Design Mode <tools/responsive-design-mode.md>
Console <tools/console-panel.md>
Network </devtools/netmonitor/architecture.md>
Storage <tools/storage.md>
Inspector <tools/inspector.md>
Responsive Design Mode devices <responsive/devices.md>
```

## Frontend

```{toctree}
:maxdepth: 1

CSS <frontend/css.md>
Panel SVGs <frontend/svgs.md>
React <frontend/react.md>
React Guidelines <frontend/react-guidelines.md>
Redux <frontend/redux.md>
Redux Guidelines <frontend/redux-guidelines.md>
Telemetry <frontend/telemetry.md>
Content Security Policy <frontend/csp.md>
```

## Backend

```{toctree}
:maxdepth: 1

Remote Debugging Protocol <backend/protocol.md>
Backend Overview <backend/watcher-architecture.md>
Client API <backend/client-api.md>
Debugger API <backend/debugger-api.md>
Backward Compatibility <backend/backward-compatibility.md>
Actors Organization <backend/actor-hierarchy.md>
Writing Actors With protocol.js <backend/protocol.js.md>
Registering A New Actor <backend/actor-registration.md>
Actor Best Practices <backend/actor-best-practices.md>
```

## Performance

```{toctree}
:maxdepth: 1

Investigating performance issues <performance/performance.md>
Writing efficient React code <performance/react-performance-tips.md>
```

## Preferences

```{toctree}
:maxdepth: 1

Preferences <preferences.md>
```

## Recurring tasks

```{toctree}
:maxdepth: 1

Release tasks<release.md>
Performance sheriffing<performance-sheriffing.md>
```

---

### Devtools Docs User Index (`devtools/docs/user/index.md`)

---
myst:
  substitutions:
    image1: |-
      ```{image} iframe_button.png
      :class: center```
    image2: |-
      ```{image} camera_button.png
      :class: center```
    image3: |-
      ```{image} responsive_button.png
      :class: center```
    image4: |-
      ```{image} menu_button.png
      :class: center```
    image5: |-
      ```{image} close_button.png
      :class: center```
---

```{toctree}
:name: devtools-user-doc
:hidden:
:maxdepth: 1

3d_view/index
about_colon_debugging/index
accessibility_inspector/index
application/index
browser_console/index
browser_toolbox/index
custom_formatters/index
debugger/index
debugger-api/index
deprecated_tools/index
devtoolsapi/index
devtoolscolors/index
dom_property_viewer/index
eyedropper/index
index/index
javascript_tracer/index
json_viewer/index
keyboard_shortcuts/index
local_mode/index
measure_a_portion_of_the_page/index
memory/index
migrating_from_firebug/index
network_monitor/index
page_inspector/index
performance/index
responsive_design_mode/index
rulers/index
settings/index
shader_editor/index
storage_inspector/index
style_editor/index
taking_screenshots/index
tips/index
tools_toolbox/index
validators/index
view_source/index
web_audio_editor/index
web_console/index
working_with_iframes/index
```

# Firefox DevTools User Docs

Firefox Developer Tools is a set of web developer tools built into Firefox. You can use them to examine, edit, and debug HTML, CSS, and JavaScript.

This section contains detailed guides to all of the tools as well as information on how to debug Firefox for Android, how to extend DevTools, and how to debug the browser as a whole.

If you have any feedback on DevTools or want to contribute to the project, you can [join the DevTools community](https://firefox-dev.tools/).

:::{note}
If you are just getting started with web development and using developer tools, our [learning](https://developer.mozilla.org/en-US/docs/Learn) docs will help you — see [Getting started with the Web](https://developer.mozilla.org/en-US/docs/Learn/Getting_started_with_the_web) and [What are browser developer tools?](https://developer.mozilla.org/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools) for good starting points.
:::

## The Core Tools

You can open the Firefox Developer Tools from the menu by selecting **Tools > Web Developer > Web Developer Tools** or use the keyboard shortcut {kbd}`Ctrl` + {kbd}`Shift` + {kbd}`I` or {kbd}`F12` on Windows and Linux, or {kbd}`Cmd` + {kbd}`Opt` + {kbd}`I` on macOS.

The ellipsis menu on the right-hand side of Developer Tools contains several commands that let you perform actions or change tool settings.

:::{figure} devtools_layoutmenu.png
:align: center
:::

```{eval-rst}
.. list-table::
   :widths: 20 80

   * - .. image:: iframe_button.png
     - This button only appears when there are multiple iframes on a page. Click it to display a list of the iframes on the current page and select the one with which you want to work.

   * - .. image:: camera_button.png
     - Click this button to take a screenshot of the current page. (*Note:* This feature is not turned on by default and must be enabled in settings before the icon will appear.)

   * - .. image:: responsive_button.png
     - Toggles Responsive Design Mode

   * - .. image:: menu_button.png
     - Opens the menu that includes docking options, the ability to show or hide the split console, and Developer Tools settings. The menu also includes links to the documentation for Firefox Web Tools and the Mozilla Community.

   * - .. image:: close_button.png
     - Closes the Developer Tools
```

### {doc}`Page Inspector </devtools-user/page_inspector/index>`

```{image} landingpage_pageinspector.png
:alt: The all-new Inspector panel in Firefox 57.
:class: border
:target: /devtools-user/page_inspector/index.html
```

View and edit page content and layout. Visualize many aspects of the page including the box model, animations, and grid layouts

### {doc}`Web Console </devtools-user/web_console/index>`

```{image} landingpage_console.png
:alt: The all-new Console panel in Firefox 57.
:class: border
:target: /devtools-user/web_console/index.html
```

See messages logged by a web page and interact with the page using JavaScript.

### [JavaScript Debugger](debugger/index.md)

```{image} landingpage_debugger.png
:alt: The all-new Debugger panel in Firefox 57.
:class: border
:target: debugger
```

Stop, step through, and examine the JavaScript running on a page.

### {doc}`Network Monitor </devtools-user/network_monitor/index>`

```{image} landingpage_network.png
:alt: The Network panel in Firefox 57 DevTools.
:class: border
:target: /devtools-user/network_monitor/index.html
```

See the network requests made when a page is loaded.

### [Performance Panel](https://profiler.firefox.com/docs/)

```{image} landingpage_performance_2022.png
:alt: Performance Panel in Firefox 103 Developer Tools.
:class: border
:target: https://profiler.firefox.com/docs/
```

Analyze your site's general responsiveness, JavaScript, and layout performance.

### {doc}`Responsive Design Mode </devtools-user/responsive_design_mode/index>`

```{image} landingpage_responsivedesign.png
:alt: Responsive Design mode in Firefox 57 Developer Tools.
:class: border
:target: /devtools-user/responsive_design_mode/index.html
```

See how your website or app will look and behave on different devices and network types.

### {doc}`Accessibility inspector </devtools-user/accessibility_inspector/index>`

```{image} landingpage_accessibility.png
:alt: Performance Tools in Firefox 57 Developer Tools.
:class: border
:target: /devtools-user/accessibility_inspector/index.html
```

Provides a means to access the page's accessibility tree, allowing you to check what's missing or otherwise needs attention.

### [Application panel](application/index.md)

```{image} just-application-panel.png
:alt: Performance Tools in Firefox 57 Developer Tools.
:class: border
:target: application
```

Provides tools for inspecting and debugging modern web apps (also known as [Progressive Web Apps](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps)). This includes inspection of [service workers](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API) and [web app manifests](https://developer.mozilla.org/en-US/docs/Web/Manifest)

:::{note}
The collective term for the UI inside which the DevTools all live is the {doc}`Toolbox <tools_toolbox/index>`
:::

## More Tools

These developer tools are also built into Firefox. Unlike the "Core Tools" above, you might not use them every day.

```{eval-rst}
.. list-table::
  :widths: 25 75
  :header-rows: 0

  * - :doc:`Memory <memory/index>`
    - Figure out which objects are keeping memory in use.

  * - :doc:`Storage Inspector <storage_inspector/index>`
    - Inspect cookies, local storage, indexedDB, and session storage present in a page.

  * - :doc:`DOM Property Viewer <dom_property_viewer/index>`
    - Inspect the page's DOM properties, functions, etc.

  * - :doc:`Eyedropper <eyedropper/index>`
    - Select a color from the page.

  * - :doc:`Style Editor <style_editor/index>`
    - View and edit CSS styles for the current page.

  * - :doc:`Taking screenshot <taking_screenshots/index>`
    - Take a screenshot of the entire page or of a single element.

  * - :doc:`Measure a portion of the page <measure_a_portion_of_the_page/index>`
    - Measure a specific area of a web page.

  * - :doc:`Rulers <rulers/index>`
    - Overlay horizontal and vertical rulers on a web page

  * - :doc:`Custom formatters <custom_formatters/index>`
    - Customize the way objects are displayed within the DevTools.

  * - :doc:`JavaScript tracer <javascript_tracer/index>`
    - Live display all JavaScript function calls.

  * - :doc:`Local Mode <local_mode/index>`
    - Easily open local files through custom https:// URL.
```

```{image} logo-developer-quantum.png
:class: center
```

```{eval-rst}
.. rst-class:: center

  For the latest developer tools and features, try Firefox Developer Edition.

  `Download Firefox Developer Edition <https://www.mozilla.org/en-US/firefox/developer/>`_


```

## AI Tools

| | |
| --- | --- |
| [Firefox DevTools MCP](https://github.com/mozilla/firefox-devtools-mcp) | A Model Context Protocol (MCP) server that enables AI assistants to automate and interact with Firefox. |

## Connecting the Developer Tools

If you open the developer tools using {ref}`keyboard shortcuts <keyboard-shortcuts-opening-and-closing-tools>` or the equivalent menu items, they'll target the document hosted by the currently active tab. But you can attach the tools to a variety of other targets, too, both within the current browser and in different browsers or even different devices.

```{eval-rst}
.. list-table::
   :widths: 30 70
   :header-rows: 0

   * - :doc:`about:debugging <about_colon_debugging/index>`
     - Debug add-ons, content tabs, and workers running in the browser.

   * - :ref:`Connecting to Firefox for Android <about-colon-debugging-connecting-to-a-remote-device>`
     - Connect the developer tools to an instance of Firefox running on an Android device.

   * - :doc:`Connecting to iframes <working_with_iframes/index>`
     - Connect the developer tools to a specific iframe in the current page.

```

## Debugging the browser

By default, the developer tools are attached to a web page or web app. But you can also connect them to the browser as a whole. This is useful for browser and add-on development.

```{eval-rst}
.. list-table::
   :widths: 30 70
   :header-rows: 0

   * - :doc:`Browser Console <browser_console/index>`
     - See messages logged by the browser itself and by add-ons, and run JavaScript code in the browser's scope.

   * - :doc:`Browser Toolbox <browser_toolbox/index>`
     - Attach the Developer Tools to the browser itself.


```

## Extending DevTools

For information on extending the Firefox DevTools, see [Extending the developer tools](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Extending_the_developer_tools) over in the [Browser Extensions](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions) section of MDN.

## Migrating from Firebug

Firebug has come to the end of its lifespan (see [Firebug lives on in Firefox DevTools](https://hacks.mozilla.org/2016/12/firebug-lives-on-in-firefox-devtools/) for details of why), and we appreciate that some people will find migrating to another less familiar set of DevTools to be challenging. To ease a transition from Firebug to the Firefox developer tools, we have written a handy guide — {doc}`Migrating from Firebug <./migrating_from_firebug/index>`

## Contribute

If you want to help improve the developer tools, these resources will get you started.

```{eval-rst}
.. list-table::
   :widths: 30 70
   :header-rows: 0

   * - `Get Involved <https://firefox-dev.tools/>`_
     - Our community website explains how to get involved.

   * - `codetribute.mozilla.org <https://codetribute.mozilla.org/projects/devtools/>`_
     - A tool helping to find bugs to work on.

   * - :ref:`Read source docs <devtools-contributor-doc>`
     - Firefox DevTools source code documentation.
```

---

### Bug Mgmt Guides Index (`docs/bug-mgmt/guides/index.md`)

# Guides

Reference for the fields used to describe a bug and how they are meant to be
set.

```{toctree}
:maxdepth: 1

bug-pipeline
bug-types
severity
priority
status-flags
other-metadata
```

---

### Bug Mgmt Policies Index (`docs/bug-mgmt/policies/index.md`)

# Policies

What each team is expected to do with the bugs it owns.

```{toctree}
:maxdepth: 1

triage-bugzilla
new-feature-triage
attention-dashboard
regressions-github
```

---

### Bug Mgmt Processes Index (`docs/bug-mgmt/processes/index.md`)

# Processes

Step by step procedures for the bugs that need special handling.

```{toctree}
:maxdepth: 1

regressions
fixing-security-bugs
security-approval
accessibility-review
doc-requests
shared-bug-queues
labels
regression-engineering-owner
```

---

### Code Quality Coding Style Index (`docs/code-quality/coding-style/index.md`)

# Coding style

Firefox code is using different programming languages.
For each language, we are enforcing a specific coding style.

## Getting Help

If you need help or have questions, please don’t hesitate to contact us via Matrix
in the "Lint and Formatting" room
([#lint:mozilla.org](https://chat.mozilla.org/#/room/#lint:mozilla.org)).

```{toctree}
:caption: Coding Style User Guide
:glob: true
:maxdepth: 2

*
```

---

### Code Quality Lint Index (`docs/code-quality/lint/index.md`)

# Linting

Linters are used in mozilla-central to help enforce coding style and avoid bad practices.
They cover a wide variety of languages and checks.

## Getting Help

If you need help or have questions, please don’t hesitate to contact us via Matrix
in the "Lint and Formatting" room
([#lint:mozilla.org](https://chat.mozilla.org/#/room/#lint:mozilla.org)).

```{toctree}
:caption: Getting Started
:maxdepth: 2

usage
```

```{toctree}
:caption: Linter Implementations
:glob: true
:maxdepth: 1

linters/*
```

```{toctree}
:caption: Linter Specifics
:maxdepth: 1

mozlint
create
```

---

### Code Quality Static Analysis Index (`docs/code-quality/static-analysis/index.md`)

# Static Analysis

Static Analysis is running an analysis of the source code without actually executing the code. For the most part, at Mozilla static analysis refers to the stuff we do with [clang-tidy](http://clang.llvm.org/extra/clang-tidy/). It uses
checkers in order to prevent different programming errors present in the
code. The checkers that we use are split into 3 categories:

1. {searchfox}`Firefox specific checkers <build/clang-plugin>`. They detect incorrect Gecko programming
   patterns which could lead to bugs or security issues.
2. [Clang-tidy checkers](https://clang.llvm.org/extra/clang-tidy/checks/list.html). They aim to suggest better programming practices
   and to improve memory efficiency and performance.
3. [Clang-analyzer checkers](https://clang-analyzer.llvm.org/). These checks are more advanced, for example
   some of them can detect dead code or memory leaks, but as a typical
   side effect they have false positives. Because of that, we have
   disabled them for now, but will enable some of them in the near
   future.

In order to simplify the process of static-analysis we have focused on
integrating this process with Phabricator and mach. A list of some
checkers that are used during automated scan can be found
{searchfox}`here <tools/clang-tidy/config.yaml>`.

This documentation is split into two parts:

```{toctree}
:glob: true
:maxdepth: 1

existing
writing-new/index
```

---

### Code Quality Typescript Index (`docs/code-quality/typescript/index.md`)

# TypeScript

In firefox-main, we are introducing the use of [TypeScript](https://www.typescriptlang.org/)
to help provide type autocompletion, static analysis and type checking of our
JavaScript code.

:::{note}
At the moment we are in the bootstrap/experimentation phase, there are various
parts of infrastructure that have not yet been created, and incomplete type
definitions which may cause issues for projects. Hence TypeScript is not
recommended for all projects for the time being.

We are currently prioritising enabling type autocompletion across the code base,
before we proceed to more work on type checking.

You can work towards enabling TypeScript by ensuring your code passes the
[ESLint jsdoc rules](https://searchfox.org/firefox-main/search?q=jsdoc%2F&path=eslint-plugin-mozilla%2Flib%2Fconfigs&case=false&regexp=false).

If you are interested, please ask in the Lint and Formatting channel (#lint:mozilla.org)
on Matrix.
:::

## Where TypeScript is Currently Enabled

TypeScript is currently only enabled on a [limited set of directories](https://searchfox.org/firefox-main/source/tools/lint/typescript.yml).

## Editor Support

VS Code has TypeScript support built-in and should work "out of the box".

For other editors, see this [TypeScript Wiki Page](https://github.com/Microsoft/TypeScript/wiki/TypeScript-Editor-Support).

## Running TypeScript Locally

The TypeScript linter may be run on the directories where it is enabled using:

```
./mach lint -l typescript path/to/file # (or to the directory)
```

## Updating Gecko Type Definitions

Updating types currently happens manually, although [we are in the process of
automating it](https://bugzilla.mozilla.org/show_bug.cgi?id=1975513).

In the meantime, developers using TypeScript must update the type definitions
[manually using some scripts](updatingTypes.md).

## Best Practices

For working with TypeScript we have some [best practices](bestPractices.md)
which will help to get the type definitions set up correctly.

## Frequently Asked Questions

* Why does running TypeScript check and report errors in other files?
  * Changes in one file may impact on another, and TypeScript can detect this.
  * Additionally, the way that TypeScript works means that it will run across
    the whole project regardless, so we report all the issues that it reports.
* Will my patches get backed out due to TypeScript failures?
  * Currently no. Whilst we have a [TypeScript Linter on CI](../lint/linters/typescript.md)
    it is currently tier-3 which is hidden from the sheriffs view.
  * Failures will however, be reported on reviews on Phabricator.
  * We will promote the linter to tier-2 and tier-1 once we have more automation
    in place for type generation.
* Why isn't this being encouraged for everyone?
  * As discussed in the note at the top of the page, we are still in the set-up
    and experimentation phase. There is a lot of infrastructure that is required
    to make TypeScript usable on a day to day basis.
* Are we planning to allow using TypeScript files and compiling directly from
  TypeScript?
  * No. In the past we've worked to avoid processing or compilation steps,
    wherever possible when developing JavaScript. This helps to reduce code-test
    cycle times and make debugging simpler.
  * Whilst it is possible we could change the approach in future, it is not an
    objective of enabling TypeScript over the firefox-main code base.
* Something isn't working as I would expect, where should I look/ask?
  * We have a [meta bug](https://bugzilla.mozilla.org/show_bug.cgi?id=1945456)
    for TypeScript issues in firefox-main. We work through them over time, though
    we appreciate help as well.
  * See the [Getting Help](#getting-help) section.

## Getting Help

The Lint & Formatting channel (#lint:mozilla.org) on Matrix is the best place
    to ask questions.

## Further Reading

* The [TypeScript documentation](https://www.typescriptlang.org/docs/) is very
  useful in understanding how TypeScript works and how types may be set up.
  * The [JavaScript section starting here](https://www.typescriptlang.org/docs/handbook/intro-to-js-ts.html),
    is especially useful for firefox-main development.

```{toctree}
:hidden:
:maxdepth: 1

bestPractices
updatingTypes
```

---

### Contributing Debugging Index (`docs/contributing/debugging/index.md`)

# Debugging Firefox

How to inspect a running Firefox, and how to make sense of a crash or a hang
that already happened.

```{toctree}
:caption: Debuggers
:maxdepth: 1

debugging_firefox_with_gdb
debugging_firefox_with_lldb
debugging_firefox_with_rr
debugging_firefox_with_pernosco
debugging_firefox_with_valgrind
```

```{toctree}
:caption: Platforms and specific areas
:maxdepth: 1

debugging_on_macos
debugging_on_windows
debugging_a_hang_on_macos
debugging_webrtc_calls
```

```{toctree}
:caption: Crash reports and minidumps
:maxdepth: 1

understanding_crash_reports
capturing_minidump
debugging_a_minidump
process_dump_task_manager
stacktrace_report
stacktrace_windbg
local_symbols
```

---

### Nspr Reference Index (`docs/nspr/reference/index.md`)

# NSPR API Reference

```{toctree}
:maxdepth: 2
```

## Introduction to NSPR

- {ref}`nspr-naming-conventions`

- {ref}`nspr-threads`

  - {ref}`thread-scheduling`

    - {ref}`setting-thread-priorities`
    - {ref}`preempting-threads`
    - {ref}`interrupting-threads`

- {ref}`nspr-thread-synchronization`

  - {ref}`locks-and-monitors`
  - {ref}`condition-variables`

- {ref}`nspr-sample-code`

## NSPR Types

- {ref}`calling-convention-types`

- {ref}`algebraic-types`

  - {ref}`c-16-2c-and-32-bit-integer-types`

    - {ref}`signed-integers`
    - {ref}`unsigned-integers`

  - {ref}`nspr-types-64-bit-integer-types`

  - {ref}`floating-point-number-type`

  - {ref}`native-os-integer-types`

- {ref}`miscellaneous-types`

  - {ref}`size-type`
  - {ref}`pointer-difference-types`
  - {ref}`boolean-types`
  - {ref}`status-type-for-return-values`

## Threads

- {ref}`threading-types-and-constants`

- {ref}`threading-functions`

  - {ref}`creating-2c-joining-2c-and-identifying-threads`
  - {ref}`controlling-thread-priorities`
  - {ref}`controlling-per-thread-private-data`
  - {ref}`interrupting-and-yielding`
  - {ref}`setting-global-thread-concurrency`
  - {ref}`getting-a-thread-27s-scope`

## Process Initialization

- {ref}`identity-and-versioning`

  - {ref}`name-and-version-constants`

- {ref}`initialization-and-cleanup`

- {ref}`module-initialization`

## Locks

- {ref}`lock-type`
- {ref}`lock-functions`

## Condition_Variables

- {ref}`condition-variable-type`
- {ref}`condition-variable-functions`

## Monitors

- {ref}`monitor-type`
- {ref}`monitor-functions`

## Cached Monitors

- {ref}`cached-monitors-functions`

## I/O Types

- {ref}`directory-type`
- {ref}`file-descriptor-types`
- {ref}`file-info-types`
- {ref}`network-address-types`
- {ref}`types-used-with-socket-options-functions`
- {ref}`type-used-with-memory-mapped-i-2fo`
- {ref}`offset-interpretation-for-seek-functions`

## I/O Functions

- {ref}`functions-that-operate-on-pathnames`
- {ref}`functions-that-act-on-file-descriptors`
- {ref}`directory-i-2fo-functions`
- {ref}`socket-manipulation-functions`
- {ref}`converting-between-host-and-network-addresses`
- {ref}`memory-mapped-i-2fo-functions`
- {ref}`anonymous-pipe-function`
- {ref}`polling-functions`
- {ref}`manipulating-layers`

## Network Addresses

- {ref}`network-address-types-and-constants`
- {ref}`network-address-functions`

## Atomic Operations

- {doc}`pr_atomicincrement`
- {doc}`pr_atomicdecrement`
- {doc}`pr_atomicset`

## Interval Timing

- {ref}`interval-time-type-and-constants`
- {ref}`interval-functions`

## Date and Time

- {ref}`types-and-constants`
- {ref}`time-parameter-callback-functions`
- [Functions](date_and_time.md#functions)

## Memory_Management Operations

- {ref}`memory-allocation-functions`
- {ref}`memory-allocation-macros`

## String Operations

- {doc}`pl_strlen`
- {doc}`pl_strcpy`
- {doc}`pl_strdup`
- {doc}`pl_strfree`

## Floating Point Number to String Conversion

- {doc}`pr_strtod`
- {doc}`pr_dtoa`
- {doc}`pr_cnvtf`

## Linked Lists

- {ref}`linked-list-types`

  - {doc}`prclist`

- {ref}`linked-list-macros`

  - {doc}`pr_init_clist`
  - {doc}`pr_init_static_clist`
  - {doc}`pr_append_link`
  - {doc}`pr_insert_link`
  - {doc}`pr_next_link`
  - {doc}`pr_prev_link`
  - {doc}`pr_remove_link`
  - {doc}`pr_remove_and_init_link`
  - {doc}`pr_insert_before`
  - {doc}`pr_insert_after`

## Dynamic Library Linking

- {ref}`library-linking-types`

  - {doc}`prlibrary`
  - {doc}`prstaticlinktable`

- {ref}`library-linking-functions`

  - {doc}`pr_setlibrarypath`
  - {doc}`pr_getlibrarypath`
  - {doc}`pr_getlibraryname`
  - {doc}`pr_freelibraryname`
  - {doc}`pr_loadlibrary`
  - {doc}`pr_unloadlibrary`
  - {doc}`pr_findsymbol`
  - {doc}`pr_findsymbolandlibrary`
  - {ref}`finding-symbols-defined-in-the-main-executable-program`

- {ref}`platform-notes`

  - `Dynamic Library Search Path`
  - {ref}`exporting-symbols-from-the-main-executable-program`

## Process Management and Interprocess Communication

- {ref}`process-management-types-and-constants`

  - {doc}`prprocess`
  - {doc}`prprocessattr`

- {ref}`process-management-functions`

  - {ref}`setting-the-attributes-of-a-new-process`
  - {ref}`creating-and-managing-processes`

## Logging

- {ref}`conditional-compilation-and-execution`

- {ref}`log-types-and-variables`

  - `PRLogModuleInfo`
  - {doc}`prlogmodulelevel`
  - {doc}`nspr_log_modules`
  - {doc}`nspr_log_file`

- {ref}`logging-functions-and-macros`

  - {doc}`prlogmoduleinfo`
  - `PR_SetLogFile`
  - `PR_SetLogBuffering`
  - `PR_LogPrint`
  - `PR_LogFlush`
  - `PR_LOG_TEST`
  - `PR_LOG`
  - {doc}`pr_assert`
  - `PR_NOT_REACHED`

- {ref}`use-example`

## Named Shared Memory

- {ref}`shared-memory-protocol`
- {ref}`named-shared-memory-functions`

## Anonymous Shared_Memory

- {ref}`anonymous-memory-protocol`
- {ref}`anonymous-shared-memory-functions`

## IPC Semaphores

- {ref}`ipc-semaphore-functions`

## Random Number Generator

- {ref}`random-number-generator-function`

## Hash Tables

- {ref}`hash-table-types-and-constants`
- {ref}`hash-table-functions`

## NSPR Error Handling

- {ref}`error-type`
- {ref}`error-functions`
- {ref}`error-codes`

---

### Nspr Reference Pr Newthreadprivateindex (`docs/nspr/reference/pr_newthreadprivateindex.md`)

# PR_NewThreadPrivateIndex

Returns a new index for a per-thread private data table and optionally
associates a destructor with the data that will be assigned to the
index.

## Syntax

```{code}
#include <prthread.h>

PRStatus PR_NewThreadPrivateIndex(
   PRUintn *newIndex,
   PRThreadPrivateDTOR destructor);
```

### Parameters

{doc}`pr_newthreadprivateindex` has the following parameters:

`newIndex`

: On output, an index that is valid for all threads in the process. You
  use this index with {doc}`pr_setthreadprivate` and
  {doc}`pr_getthreadprivate`.

`destructor`

: Specifies a destructor function {doc}`prthreadprivatedtor` for the
  private data associated with the index. This function can be
  specified as `NULL`.

### Returns

The function returns one of the following values:

- If successful, `PR_SUCCESS`.
- If the total number of indices exceeds 128, `PR_FAILURE`.

## Description

If {doc}`pr_newthreadprivateindex` is successful, every thread in the same
process is capable of associating private data with the new index. Until
the data for an index is actually set, the value of the private data at
that index is `NULL`. You pass this index to {doc}`pr_setthreadprivate`
and {doc}`pr_getthreadprivate` to set and retrieve data associated with the
index.

When you allocate the index, you may also register a destructor function
of type {doc}`prthreadprivatedtor`. If a destructor function is registered
with a new index, it will be called at one of two times, as long as the
private data is not `NULL`:

- when replacement private data is set with {doc}`pr_setthreadprivate`
- when a thread exits

The index maintains independent data values for each binding thread. A
thread can get access only to its own thread-specific data. There is no
way to deallocate a private data index once it is allocated.

---

### Performance Memory Index (`docs/performance/memory/index.md`)

# Memory profiling and leak detection

Tools for measuring how much memory Firefox uses, and for tracking down memory
that is never released.

```{toctree}
:caption: Measuring memory usage
:maxdepth: 1

about_colon_memory
memory_reporting
awsy
bloatview
```

```{toctree}
:caption: Leak detection
:maxdepth: 1

leak_hunting_strategies_and_tips
leaked_until_shutdown
refcount_tracing_and_balancing
gc_and_cc_logs
```

```{toctree}
:caption: Heap profiling with DMD
:maxdepth: 1

dmd
heap_scan_mode
```

## The DevTools Memory panel

The Memory panel is documented in the DevTools user documentation, under
[Memory](/devtools-user/memory/index.md).

---

### Rust Components Api Index (`docs/rust-components/api/index.md`)

# Rust components API References

Choose a language to get started

- [JS](./js/index.md)
- [Kotlin](https://mozilla.github.io/application-services/kotlin/index.html)
- [Swift](https://mozilla.github.io/application-services/swift/index.html)

```{toctree}
:hidden:
:maxdepth: 1

js/index
```

---

### Rust Components Developing Rust Components Index (`docs/rust-components/developing-rust-components/index.md`)

# Developing Shared Rust Components

Shared Rust Components is a strategy to create a single component that provides the same functionality for Firefox Desktop, Firefox Android and Firefox iOS.

This strategy was first adopted for sync in response to issues stemming from separate sync implementations for each application. Separate sync implementations lead to duplicate logic across platforms, which was difficult to maintain. Furthermore, the likelihood of errors was very high -- especially since each implementation had to sync with the other implementations. Since then more components have adopted the Rust components strategy and some non-Firefox projects have started using the components (for example nimbus-experimenter).

The basic idea is to write the component in Rust then generate a set of Kotlin/Swift/JS bindings that can be consumed by the Firefox applications.
Rust was chosen because it supports a large number of target platforms, including Android and iOS.
The [UniFFI](https://mozilla.github.io/uniffi-rs/latest/) library was created to handle bindings
generation.

## Pros and cons of adding a shared Rust component

### Pros

* Less work than creating a multiple implementations.
* More consistent behavior across different applications.
* Better sync integrations (this follows from the last point, since behavior differences often become larger bugs when sync is involved).
* Build JavaScript, Kotlin, and Swift docs from the Rust docstrings.

### Cons

* More work than creating a single implementation.
* Requires engineers to write and understand Rust.
* Still requires some application glue code to integrate the component.
  Often it's trivial like [TabsStore](https://searchfox.org/firefox-main/source/services/sync/modules/TabsStore.sys.mjs), but sometimes it's larger.

### Neutral

* Performance is usually similar to JavaScript/Kotlin code.
  FFI overhead typically negates any speedups from using Rust.

## Shared Rust component ownership

Teams that write shared Rust components are responsible for maintaining their health.
This includes monitoring error reports and working with application teams to maintain integrations as the application code changes.
Error reports are currently only available for Android, but we will soon be extending this to all platforms.

```{toctree}
:titlesonly:
:maxdepth: 1

example-component
uniffi
logging
observability
threading
other-desktop-specific-concerns
```

---

### Rust Components Topic Guides Index (`docs/rust-components/topic-guides/index.md`)

# Topic Guides

Here are the guides on various topics related to Rust components.

```{toctree}
:titlesonly:
:maxdepth: 1
:glob:

*
```

---

### Rust Components Uniffi Bindgen Gecko Js Dev Guide Index (`docs/rust-components/uniffi-bindgen-gecko-js-dev-guide/index.md`)

# uniffi-bindgen-gecko-js Developers Guide

This section describes the internal workings of `uniffi-bindgen-gecko-js` for developers working with this code.
It builds on the [UniFFI user guide](https://mozilla.github.io/uniffi-rs/latest/) internals documentation, which is recommended reading before diving into these specifics.

## UniFFI bindings pipeline

`uniffi-bindgen-gecko-js` uses the bindings pipeline ([docs](https://github.com/mozilla/uniffi-rs/blob/main/docs/manual/src/internals/bindings_ir.md) [more docs](https://github.com/mozilla/uniffi-rs/blob/main/docs/manual/src/internals/bindings_ir_pipeline.md)).
`uniffi-bindgen-gecko-js` is the first bindings generator to adopt this code, although we hope to eventually move all bindings to this system.
This means the `uniffi-bindgen-gecko-js` code may look different than other bindings, but we hope it's only temporary.

```{toctree}
:titlesonly:
:maxdepth: 1

js-and-cpp-layers
lifting-and-lowering
rust-calls
js-callback-interfaces
```

---

### Dom Bindings Docs Index (`dom/bindings/docs/index.md`)

# WebIDL

WebIDL describes interfaces web browsers are supposed to implement.

The interaction between WebIDL and the build system is somewhat complex.
This document will attempt to explain how it all works.

## Overview

`.webidl` files throughout the tree define interfaces the browser
implements. Since Gecko/Firefox is implemented in C++, there is a
mechanism to convert these interfaces and associated metadata to
C++ code. That's where the build system comes into play.

All the code for interacting with `.webidl` files lives under
`dom/bindings`. There is code in the build system to deal with
WebIDLs explicitly.

## WebIDL source file flavors

Not all `.webidl` files are created equal! There are several flavors,
each represented by a separate symbol from {ref}`mozbuild_symbols`.

WEBIDL_FILES

: Refers to regular/static `.webidl` files. Most WebIDL interfaces
  are defined this way.

GENERATED_EVENTS_WEBIDL_FILES

: In addition to generating a binding, these `.webidl` files also
  generate a source file implementing the event object in C++

PREPROCESSED_WEBIDL_FILES

: The `.webidl` files are generated by preprocessing an input file.
  They otherwise behave like *WEBIDL_FILES*.

TEST_WEBIDL_FILES

: Like *WEBIDL_FILES* but the interfaces are for testing only and
  aren't shipped with the browser.

PREPROCESSED_TEST_WEBIDL_FILES

: Like *TEST_WEBIDL_FILES* except the `.webidl` is obtained via
  preprocessing, much like *PREPROCESSED_WEBIDL_FILES*.

GENERATED_WEBIDL_FILES

: The `.webidl` for these is obtained through an *external*
  mechanism. Typically there are custom build rules for producing these
  files.

## Producing C++ code

The most complicated part about WebIDLs is the process by which
`.webidl` files are converted into C++.

This process is handled by code in the {py:mod}`mozwebidlcodegen`
package. {py:class}`mozwebidlcodegen.WebIDLCodegenManager` is
specifically where you want to look for how code generation is
performed. This includes complex dependency management.

## Requirements

This section aims to document the build and developer workflow requirements
for WebIDL.

Parser unit tests

: There are parser tests provided by `dom/bindings/parser/runtests.py`
  that should run as part of `make check`. There must be a mechanism
  to run the tests in *human* mode so they output friendly error
  messages.

  The current mechanism for this is `mach webidl-parser-test`.

Mochitests

: There are various mochitests under `dom/bindings/test`. They should
  be runnable through the standard mechanisms.

Working with test interfaces

: `TestExampleGenBinding.cpp` calls into methods from the
  `TestExampleInterface`, `TestExampleProxyInterface`,
  `TestExampleThrowingConstructorInterface`,
  and `TestExampleWorkerInterface` interfaces.
  These interfaces need to be generated as part of the build. These
  interfaces should not be exported or packaged.

  There is a `compiletests` make target in `dom/bindings` that
  isn't part of the build that facilitates turnkey code generation
  and test file compilation.

Minimal rebuilds

: Reprocessing every output for every change is expensive. So we don't
  inconvenience people changing `.webidl` files, the build system
  should only perform a minimal rebuild when sources change.

  This logic is mostly all handled in
  {py:class}`mozwebidlcodegen.WebIDLCodegenManager`. The unit tests for
  that Python code should adequately test typical rebuild scenarios.

  Bug 940469 tracks making the existing implementation better.

Explicit method for performing codegen

: There needs to be an explicit method for invoking code generation.
  It needs to cover regular and test files.

  This is implemented via `make export` in `dom/bindings`.

No-op binding generation should be fast

: So developers touching `.webidl` files are not inconvenienced,
  no-op binding generation should be fast. Watch out for the build system
  processing large dependency files it doesn't need in order to perform
  code generation.

Ability to generate example files

: *Any* interface can have example `.h`/`.cpp` files generated.
  There must be a mechanism to facilitate this.

  This is currently facilitated through `mach webidl-example`. e.g.
  `mach webidl-example HTMLStyleElement`.

---

### Dom Docs Navigation Index (`dom/docs/navigation/index.md`)

# DOM Navigation

```{toctree}
:maxdepth: 1

embedding
BrowsingContext
nav_replace
```

---

### Dom Docs Push Index (`dom/docs/push/index.md`)

# Push

<div class="note">
<div class="admonition-title">Note</div>
This document describes how Firefox implements the Web Push standard internally, and is intended for developers working directly on Push. If you are looking for how to consume push, please refer to the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Push_API" target="_blank">following MDN document</a>

</div>

## High level push architecture

The following sequence diagram describes the high level push architecture as observed by web application. The diagram describes the interactions between a Web application's client code running in the browser, Firefox, [Autopush](https://autopush.readthedocs.io/en/latest/) (Firefox's push server that delivers push notifications) and a third party server that sends the push notifications to Autopush

The dotted lines are done by the consumer of push.

```{mermaid}
sequenceDiagram
	participant TP as Web Application JS
	participant F as Firefox
	participant A as Autopush
	participant TPS as Third party Server
		TP->>F: subscribe(scope)
		activate TP
		activate F
		F->>A: subscribe(scope) using web socket
		activate A
		A->>F: URL
		deactivate A
		F->>F: Create pub/privKey Encryption pair
		F->>F: Persist URL, pubKey, privKey indexed using an id derived from scope
		F->>TP: URL + pubKey
		deactivate F
		TP-->>TPS: URL + pubKey
		deactivate TP
		TPS-->>TPS: Encrypt payload using pubKey
		TPS-->>A: Send encrypted payload using URL
		activate A
		A->>F: Send encrypted payload using web socket
		deactivate A
		activate F
		F->>F: Decrypt payload using privKey
		F->>F: Display Notification
		deactivate F
```

## Firefox Desktop

### Flow diagram for source code

The source code for push is available under [`dom/push`](https://searchfox.org/firefox-main/source/dom/push) in mozilla-central.

The following flow diagram describes how different modules interact with each other to provide the push API to consumers.

```{mermaid}
flowchart TD
    subgraph Public API

    W[Third party Web app]-->|imports| P[PushManager.webidl]
    end
    subgraph Browser Code
        P-->|Implemented by| MM
        MM{Main Thread?}-->|Yes| B[Push.sys.mjs]
        MM -->|NO| A[PushManager.cpp]
        B-->|subscribe,getSubscription| D[PushComponents.sys.mjs]
        A-->|subscribe,getSubscription| D
        D-->|subscribe,getSubscription| M[PushService.sys.mjs]
        M-->|Storage| S[PushDB.sys.mjs]
        M-->|Network| N[PushWebSocket.sys.mjs]
        F[FxAccountsPush.sys.mjs] -->|uses| D
    end
    subgraph Server
    N-. Send, Receive.-> O[Autopush]
    end
    subgraph Local Storage
    S-->|Read,Write| PP[(IndexedDB)]
    end
```

### The Push Web Socket

Push in Firefox Desktop communicates with Autopush using a web socket connection.

The web socket connection is created as the browser initializes and is managed by the following state diagram.

```{mermaid}
stateDiagram-v2
		state "Shut Down" as SD
		state "Waiting for WebSocket to start" as W1
		state "Waiting for server hello" as W2
		state "Ready" as R
    [*] --> SD
		 SD --> W1: beginWSSetup
		 W1 --> W2: wsOnStart Success
		 W2 --> R: handleHelloReply
		 R --> R: send (subscribe)
         R --> R: Receive + notify observers
		 R --> SD: wsOnStop
		 R --> SD: sendPing Fails
		 W1 --> SD: wsOnStart fails
		 W2 --> SD: invalid server hello
		 R --> [*]
```

Once the Push web socket is on the `Ready` state, it is ready to send new subscriptions to Autopush, and receive push notifications from those subscriptions.

Push uses an observer pattern to notify observers of any incoming push notifications. See the [high level architecture](#high-level-push-architecture) section.

### Push Storage

Push uses IndexedDB to store subscriptions for the following reasons:

1. In case the consumer attempts to re-subscribe, storage is used as a cache to serve the URL and the public key
1. In order to persist the private key, so that it can be used to decrypt any incoming push notifications

The following is what gets persisted:

```{mermaid}
erDiagram
    Subscription {
        string channelID "Key, Derived from scope"
        string pushEndpoint "Unique endpoint for this subscription"
        string scope "Usually the origin, unique value for internal consumers"
        Object p256dhPublicKey "Object representing the public key"
        Object p256dhPrivateKey "Object representing the private key"
    }
```

## Firefox for Android

See also:

* [Rust Push Component](https://mozilla.github.io/application-services/book/rust-docs/push/index.html)
* [Push Service Bridge HTTP Interface](https://autopush.readthedocs.io/en/latest/http.html#push-service-bridge-http-interface)
* [Android Components: Push](https://github.com/mozilla/gecko-dev/blob/master/mobile/android/android-components/components/feature/push/README.md)

### Flow diagram for source code

The source code for push is available under the following paths in mozilla-central:

* [`dom/push/`](https://searchfox.org/firefox-main/source/dom/push/)
* [`mobile/shared/components/geckoview/GeckoViewPush.sys.mjs`](https://searchfox.org/firefox-main/source/mobile/shared/components/geckoview/GeckoViewPush.sys.mjs)
* [`mobile/android/geckoview/src/main/java/org/mozilla/geckoview/WebPush*.java`](https://searchfox.org/firefox-main/source/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/)
* Under `mobile/android/android-components/components`:
  * [`feature/push/src/main/java/mozilla/components/feature/push/`](https://searchfox.org/firefox-main/source/mobile/android/android-components/components/feature/push/src/main/java/mozilla/components/feature/push/)
  * [`browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/webpush/`](https://searchfox.org/firefox-main/source/mobile/android/android-components/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/webpush/)
  * [`concept/engine/src/main/java/mozilla/components/concept/engine/webpush`](https://searchfox.org/firefox-main/source/mobile/android/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/webpush/)
* [Rust Push Component](https://github.com/mozilla/application-services/tree/main/components/push)

The following flow diagram describes how different modules interact with each other to provide the push API to consumers.

```{mermaid}
flowchart TD
    subgraph Public API

    W[Third party Web app]-->|imports| P[PushManager.webidl]
    end
    subgraph Browser Code
        P-->|Implemented by| MM
        MM{Main Thread?}-->|Yes| B[Push.sys.mjs]
        MM -->|NO| A[PushManager.cpp]
        B-->|subscribe,getSubscription| D[GeckoViewPush.sys.mjs]
        A-->|subscribe,getSubscription| D
        D-->|PushSubscribe,PushGetSubscription| WPC[WebPushController.java]
        WPC-->|onSubscribe,onGetSubscription| WPEI[WebPushEngineIntegration.kt]
        WPEI-->|subscribe,getSubscription| APF[AutoPushFeature.kt]
        APF-->|start| PS[AbstractFirebasePushService.kt]
        FCM[Firebase Cloud Messaging]-->|onNewToken| PS
        PS-->|onNewToken| APF
        APF-->|subscribe,getSubscription| PRS[push/src/lib.rs]
        PRS-->|subscribe,get_subscription| PM[internal/push_manager.rs]
        PM-->|Storage| S[internal/storage/db.rs]
        PM-->|Network| N[internal/communications.rs]
    end
    subgraph Server
    N-. bridge interface.-> O[Autopush]
    end
    subgraph Local Storage
    S-->|Read,Write| SQL[(SQLite)]
    end
```

---

### Dom Docs ScriptSecurity Index (`dom/docs/scriptSecurity/index.md`)

# Script Security

:::{container} summary
This page provides an overview of the script security architecture in
Gecko.
:::

Like any web browser, Gecko can load JavaScript from untrusted and
potentially hostile web pages and run it on the user's computer. The
security model for web content is based on the [same-origin policy](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy),
in which code
gets full access to objects from its origin but highly restricted access
to objects from a different origin. The rules for determining whether an
object is same-origin with another, and what access is allowed
cross-origin, are now mostly standardized across browsers.

Gecko has an additional problem, though: while its core is written in
C++, the front-end code is written in JavaScript. This JavaScript code,
which is commonly referred to as *chrome code*, runs with system
privileges. If the code is compromised, the attacker can take over the
user's computer. Legacy SDK extensions also run with chrome privileges.

Having the browser front end in JavaScript has benefits: it can be much
quicker to develop in JavaScript than in C++, and contributors do not
need to learn C++. However, JavaScript is a highly dynamic, malleable
language, and without help it's difficult to write system-privileged
code that interacts safely with untrusted web content. From the point of
view of chrome code, the script security model in Gecko is intended to
provide that help to make writing secure, system-privileged JavaScript a
realistic expectation.

(security-policy)=

## Security policy

Gecko implements the following security policy:

- **Objects that are same-origin** are able to access each other
  freely. For example, the objects associated with a document served
  from <https://example.org/> can access each other, and they can also
  access objects served from <https://example.org/foo>.
- **Objects that are cross-origin** get highly restricted access to
  each other, according to the same-origin policy.
  For example, code served from <https://example.org/> trying to access
  objects from <https://somewhere-else.org/> will have restricted
  access.
- **Objects in a privileged scope** are allowed complete access to
  objects in a less privileged scope, but by default they see a
  [restricted view](#privileged-to-unprivileged-code)
  of such objects, designed to prevent them from being tricked by the
  untrusted code. An example of this scope is chrome-privileged
  JavaScript accessing web content.
- **Objects in a less privileged scope** don't get any access to
  objects in a more privileged scope, unless the more privileged scope
  [explicitly clones those objects](#unprivileged-to-privileged-code).
  An example of this scope is web content accessing objects in a
  chrome-privileged scope.

(compartments)=

## Compartments

Compartments are the foundation for Gecko's script security
architecture. A compartment is a specific, separate area of memory. In
Gecko, there's a separate compartment for every global object. This
means that each global object and the objects associated with it live in
their own region of memory.

```{image} images/compartments.png
```

Normal content windows are globals, of course, but so are chrome
windows, sandboxes, workers, the `ContentFrameMessageManager` in a frame
script, and so on.

Gecko guarantees that JavaScript code running in a given compartment is
only allowed to access objects in the same compartment. When code from
compartment A tries to access an object in compartment B, Gecko gives it
a *cross-compartment wrapper*. This is a proxy in compartment A for the
real object, which lives in compartment B.

```{image} images/cross-compartment-wrapper.png
```

Inside the same compartment, all objects share a global and are
therefore same-origin with each other. Therefore there's no need for any
security checks, there are no wrappers, and there is no performance
overhead for the common case of objects in a single window interacting
with each other.

Whenever cross-compartment access happens, the wrappers enable us to
implement the appropriate security policy. Because the wrapper we choose
is specific to the relationship between the two compartments, the
security policy it implements can be static: when the caller uses the
wrapper, there's no need to check who is making the call or where it is
going.

(cross-compartment-access)=

## Cross-compartment access

(same-origin)=

### Same-origin

As we've already seen, the most common scenario for same-origin access
is when objects belonging to the same window object interact. This all
takes place within the same compartment, with no need for security
checks or wrappers.

When objects share an origin but not a global - for example two web
pages from the same protocol, port, and domain - they belong to two
different compartments, and the caller gets a *transparent wrapper* to
the target object.

```{image} images/same-origin-wrapper.png
```

Transparent wrappers allow access to all the target's properties:
functionally, it's as if the target is in the caller's compartment.

(cross-origin)=

### Cross-origin

If the two compartments are cross-origin, the caller gets a
*cross-origin wrapper*.

```{image} images/cross-origin-wrapper.png
```

This denies access to all the object's properties, except for a few
properties of Window and Location objects, as defined by
the [same-origin
policy](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy#cross-origin_script_api_access).

(privileged-to-unprivileged-code)=

### Privileged to unprivileged code

The most obvious example of this kind of security relation is between
system-privileged chrome code and untrusted web content, but there are
other examples in Gecko. The Add-on SDK runs content scripts in
sandboxes, which are initialized with an [expanded
principal](#expanded-principal),
giving them elevated privileges with respect to the web content they
operate on, but reduced privileges with respect to chrome.

If the caller has a higher privilege than the target object, the caller
gets an *Xray wrapper* for the object.

```{image} images/xray-wrapper.png
```

Xrays are designed to prevent untrusted code from confusing trusted code
by redefining objects in unexpected ways. For example, privileged code
using an Xray to a DOM object sees only the original version of the DOM
object. Any expando properties are not visible, and if any native DOM properties have been
redefined, they are not visible in the Xray.

The privileged code is able to waive Xrays if it wants unfiltered access to the untrusted object.

See [Xray vision](xray_vision.md) for much more information on Xrays.

(unprivileged-to-privileged-code)=

### Unprivileged to privileged code

If the caller has lower privileges than the target object, then the
caller gets an *opaque wrapper.*

```{image} images/opaque-wrapper.png
```

An opaque wrapper denies all access to the target object.

However, the privileged target is able to copy objects and functions
into the less privileged scope using the `exportFunction()` and
`cloneInto()` functions, and the less privileged scope is then able
to use them.

(security-checks)=

## Security checks

To determine the security relation between two compartments, Gecko uses
two concepts: *security principals* and the act of *subsuming*. To
establish the security relationship between two compartments A and B,
Gecko asks:

*Does the security principal for compartment A subsume the security
principal for compartment B, and vice versa?*

(subsumes)=

### Subsumes

```{eval-rst}
+-----------------------------------+-----------------------------------+
| *A subsumes B*                    | A has all of the privileges of B, |
|                                   | and possibly more, and therefore  |
|                                   | A is allowed to see and do        |
|                                   | anything that B can see and do.   |
+-----------------------------------+-----------------------------------+
| *A Subsumes B &&* *B Subsumes A*  | A and B are same-origin.          |
+-----------------------------------+-----------------------------------+
| *A Subsumes B && B !Subsumes A*   | A is more privileged than B.      |
|                                   |                                   |
|                                   | A gets access to all of B, by     |
|                                   | default with Xray vision, which   |
|                                   | it may choose to waive.           |
|                                   |                                   |
|                                   | B gets no access to A, although A |
|                                   | may choose to export objects to   |
|                                   | B.                                |
+-----------------------------------+-----------------------------------+
| *A !Subsumes B && B !Subsumes A*  | A and B are cross-origin.         |
+-----------------------------------+-----------------------------------+
```

(security-principals)=

### Security principals

There are four types of security principal: the system principal,
content principals, expanded principals, and the null principal.

(system-principal)=

#### System principal

The system principal passes all security checks. It subsumes itself and
all other principals. Chrome code, by definition, runs with the system
principal, as do frame scripts.

(content-principal)=

#### Content principal

A content principal is associated with some web content and is defined
by the origin
of the content. For example, a normal DOM window has a content principal
defined by the window's origin. A content principal subsumes only other
content principals with the same origin. It is subsumed by the system
principal, any expanded principals that include its origin, and any
other content principals with the same origin.

(expanded-principal)=

#### Expanded principal

An expanded principal is specified as an array of origins:

```JavaScript
["http://mozilla.org", "http://moz.org"]
```

The expanded principal subsumes every content principal it contains. The
content principals do not subsume the expanded principal, even if the
expanded principal only contains a single content principal.

Thus `["http://moz.org"]` subsumes `"http://moz.org"` but not vice
versa. The expanded principal gets full access to the content principals
it contains, with Xray vision by default, and the content principals get
no access to the expanded principal.

This also enables the script security model to treat compartments that
have expanded principals more like part of the browser than like web
content. This means, for example, that it can run when JavaScript is
disabled for web content.

Expanded principals are useful when you want to give code extra
privileges, including cross-origin access, but don't want to give the
code full system privileges. For example, expanded principals are used
in the Add-on SDK to give content scripts cross-domain privileges for a predefined set of
domains,
and to protect content scripts from access by untrusted web content,
without having to give content scripts system privileges.

(null-principal)=

#### Null principal

The null principal fails almost all security checks. It has no
privileges and can't be accessed by anything but itself and chrome. It
subsumes no other principals, even other null principals. (This is what
is used when HTML5 and other specs say "origin is a globally unique
identifier".)

(principal-relationships)=

### Principal relationships

The diagram below summarizes the relationships between the different
principals. The arrow connecting principals A and B means "A subsumes
B". (A is the start of the arrow, and B is the end.)

```{image} images/principal-relationships.png
```

(computing-a-wrapper)=

## Computing a wrapper

The following diagram shows the factors that determine the kind of
wrapper that compartment A would get when trying to access an object in
compartment B.

```{image} images/computing-a-wrapper.png
```

---

### Dom Docs WebIdlBindings Index (`dom/docs/webIdlBindings/index.md`)

# Web IDL bindings

<div class="note">
<div class="admonition-title">Note</div>

Need to document the setup for indexed and named
setters/creators/deleters.

</div>

The [Web IDL](https://webidl.spec.whatwg.org/) bindings are generated
at build time based on two things: the actual Web IDL file and a
configuration file that lists some metadata about how the Web IDL should
be reflected into Gecko-internal code.

All Web IDL files should be placed in
[`dom/webidl`](https://searchfox.org/firefox-main/source/dom/webidl/)
and added to the list in the
[moz.build](https://searchfox.org/firefox-main/source/dom/webidl/moz.build)
file in that directory.

Note that if you're adding new interfaces, then the test at
`dom/tests/mochitest/general/test_interfaces.html` will most likely
fail. This is a signal that you need to get a review from a [DOM
peer](https://wiki.mozilla.org/Modules/All#Document_Object_Model).
Resist the urge to just add your interfaces to the
[moz.build](https://searchfox.org/firefox-main/source/dom/webidl/moz.build) list
without the review; it will just annoy the DOM peers and they'll make
you get the review anyway.

The configuration file, `dom/bindings/Bindings.conf`, is basically a
Python dict that maps interface names to information about the
interface, called a _descriptor_. There are all sorts of possible
options here that handle various edge cases, but most descriptors can be
very simple.

All the generated code is placed in the `mozilla::dom` namespace. For
each interface, a namespace whose name is the name of the interface with
`Binding` appended is created, and all the things pertaining to that
interface's binding go in that namespace.

There are various helper objects and utility methods in
[`dom/bindings`](https://searchfox.org/firefox-main/source/dom/bindings)
that are also all in the `mozilla::dom` namespace and whose headers
are all exported into `mozilla/dom` (placed in
`$OBJDIR/dist/include` by the build process).

## Adding Web IDL bindings to a class

To add a Web IDL binding for interface `MyInterface` to a class
`mozilla::dom::MyInterface` that's supposed to implement that
interface, you need to do the following:

1. If your interface doesn't inherit from any other interfaces, inherit
   from `nsWrapperCache` and hook up the class to the cycle collector
   so it will trace the wrapper cache properly. Note that you may not
   need to do this if your objects can only be created, never gotten
   from other objects. If you also inherit from `nsISupports`, make
   sure the `nsISupports` comes before the `nsWrapperCache` in your
   list of parent classes. If your interface _does_ inherit from another
   interface, just inherit from the C++ type that the other interface
   corresponds to.

   If you do need to hook up cycle collection, it will look like this in
   the common case of also inheriting from nsISupports:

   ``` cpp
   // Add strong pointers your class holds here. If you do, change to using
   // NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE.
   NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(MyClass)
   NS_IMPL_CYCLE_COLLECTING_ADDREF(MyClass)
   NS_IMPL_CYCLE_COLLECTING_RELEASE(MyClass)
   NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MyClass)
     NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
     NS_INTERFACE_MAP_ENTRY(nsISupports)
   NS_INTERFACE_MAP_END
   ```

1. If your class doesn't inherit from a class that implements
   `GetParentObject`, then add a function of that name that, for a
   given instance of your class, returns the same object every time
   (unless you write explicit code that handles your parent object
   changing by reparenting JS wrappers, as nodes do). The idea is that
   walking the `GetParentObject` chain will eventually get you to a
   Window, so that every Web IDL object is associated with a particular
   Window.
   For example, `nsINode::GetParentObject` returns the node's owner
   document. The return type of `GetParentObject` doesn't matter other
   than it must either singly-inherit from `nsISupports` or have a
   corresponding
   [`ToSupports`](https://searchfox.org/firefox-main/search?q=ToSupports&path=&case=true&regexp=false)
   method that can produce an `nsISupports` from it. (This allows the
   return value to be implicitly converted to a
   [`ParentObject`](https://searchfox.org/firefox-main/search?q=ParentObject&path=&case=true&regexp=false)
   instance by the compiler via one of that class's non-explicit
   constructors.)
   If many instances of `MyInterface` are expected to be created
   quickly, the return value of `GetParentObject` should itself inherit
   from `nsWrapperCache` for optimal performance. Returning null from
   `GetParentObject` is allowed in situations in which it's OK to
   associate the resulting object with a random global object for
   security purposes; this is not usually ok for things that are exposed
   to web content. Again, if you do not need wrapper caching you don't
   need to do this. The actual type returned from `GetParentObject`
   must be defined in a header included from your implementation header,
   so that this type's definition is visible to the binding code.

1. Add the Web IDL for `MyInterface` in `dom/webidl` and to the list
   in `dom/webidl/moz.build`.

1. Add an entry to `dom/bindings/Bindings.conf` that sets some basic
   information about the implementation of the interface. If the C++
   type is not `mozilla::dom::MyInterface`, you need to set the
   `'nativeType'` to the right type. If the type is not in the header
   file one gets by replacing '::' with '/' and appending '`.h`', then
   add a corresponding `'headerFile'` annotation (or
   [`HeaderFile`](#headerfile-path-to-headerfile-h) annotation to the .webidl file). If
   you don't have to set any annotations, then you don't need to add an
   entry either and the code generator will simply assume the defaults
   here. Note that using a `'headerFile'` annotation is generally not
   recommended. If you do use it, you will need to make sure your
   header includes all the headers needed for your [`Func`](#func-funcname)
   annotations.

1. Add external interface entries to `Bindings.conf` for whatever
   non-Web IDL interfaces your new interface has as arguments or return
   values.

1. Implement a `WrapObject` override on `mozilla::dom::MyInterface`
   that just calls through to
   `mozilla::dom::MyInterface_Binding::Wrap`. Note that if your C++
   type is implementing multiple distinct Web IDL interfaces, you need
   to choose which `mozilla::dom::MyInterface_Binding::Wrap` to call
   here. See `AudioContext::WrapObject`, for example.

1. Expose whatever methods the interface needs on
   `mozilla::dom::MyInterface`. These can be inline, virtual, have any
   calling convention, and so forth, as long as they have the right
   argument types and return types. You can see an example of what the
   function declarations should look like by running
   `mach webidl-example MyInterface`. This will produce two files in
   `dom/bindings` in your objdir: `MyInterface-example.h` and
   `MyInterface-example.cpp`, which show a basic implementation of the
   interface using a class that inherits from `nsISupports` and has a
   wrapper cache.

See this [sample patch that migrates window.performance.\* to Web IDL
bindings](https://hg.mozilla.org/mozilla-central/rev/dd08c10193c6).

<div class="note"><div class="admonition-title">Note</div>

If your object can only be reflected into JS by creating it, not by
retrieving it from somewhere, you can skip steps 1 and 2 above and
instead add `'wrapperCache': False` to your descriptor. You will
need to flag the functions that return your object as
[`[NewObject]`](https://webidl.spec.whatwg.org/#NewObject) in
the Web IDL. If your object is not refcounted then the return value of
functions that return it should return a UniquePtr.

</div>

(c-reflections-of-webidl-constructs)=

## C++ reflections of Web IDL constructs

### C++ reflections of Web IDL operations (methods)

A Web IDL operation is turned into a method call on the underlying C++
object. The return type and argument types are determined [as described
below](#c-reflections-of-webidl-constructs). In addition to those, all [methods that are
allowed to throw](#throws-getterthrows-setterthrows) will get an `ErrorResult&` argument
appended to their argument list. Non-static methods that use certain
Web IDL types like `any` or `object` will get a `JSContext*`
argument prepended to the argument list. Static methods will be passed a
[`const GlobalObject&`](#globalobject) for the relevant global and
can get a `JSContext*` by calling `Context()` on it.

The name of the C++ method is simply the name of the Web IDL operation
with the first letter converted to uppercase.

Web IDL overloads are turned into C++ overloads: they simply call C++
methods with the same name and different signatures.

For example, this Web IDL:

``` webidl
interface MyInterface
{
  undefined doSomething(long number);
  double doSomething(MyInterface? otherInstance);

  [Throws]
  MyInterface doSomethingElse(optional long maybeNumber);
  [Throws]
  undefined doSomethingElse(MyInterface otherInstance);

  undefined doTheOther(any something);

  undefined doYetAnotherThing(optional boolean actuallyDoIt = false);

  static undefined staticOperation(any arg);
};
```

will require these method declarations:

``` cpp
class MyClass
{
  void DoSomething(int32_t a number);
  double DoSomething(MyClass* aOtherInstance);

  already_AddRefed<MyInterface> DoSomethingElse(Optional<int32_t> aMaybeNumber,
                                                ErrorResult& rv);
  void DoSomethingElse(MyClass& aOtherInstance, ErrorResult& rv);

  void DoTheOther(JSContext* cx, JS::Handle<JS::Value> aSomething);

  void DoYetAnotherThing(bool aActuallyDoIt);

  static void StaticOperation(const GlobalObject& aGlobal, JS::Handle<JS::Value> aSomething);
}
```

### C++ reflections of Web IDL attributes

A Web IDL attribute is turned into a pair of method calls for the getter
and setter on the underlying C++ object. A readonly attribute only has a
getter and no setter.

The getter's name is the name of the attribute with the first letter
converted to uppercase. This has `Get` prepended to it if any of these
conditions hold:

1. The type of the attribute is nullable.
1. The getter can throw.
1. The return value of the attribute is returned via an out parameter in
   the C++.

The method signature for the getter looks just like an operation with no
arguments and the attribute's type as the return type.

The setter's name is `Set` followed by the name of the attribute with
the first letter converted to uppercase. The method signature looks just
like an operation with an undefined return value and a single argument
whose type is the attribute's type.

### C++ reflections of Web IDL constructors

A Web IDL constructor is turned into a static class method named
`Constructor`. The arguments of this method will be the arguments of
the Web IDL constructor, with a
[`const GlobalObject&`](#globalobject) for the relevant global
prepended. For the non-worker case, the global is typically the inner
window for the DOM Window the constructor function is attached to. If a
`JSContext*` is also needed due to some of the argument types, it will
come after the global. The return value of the constructor for
`MyInterface` is exactly the same as that of a method returning an
instance of `MyInterface`. Constructors are always allowed to throw.

For example, this IDL:

``` webidl
interface MyInterface {
  constructor();
  constructor(unsigned long someNumber);
};
```

will require the following declarations in `MyClass`:

``` cpp
class MyClass {
  // Various nsISupports stuff or whatnot
  static
  already_AddRefed<MyClass> Constructor(const GlobalObject& aGlobal,
                                        ErrorResult& rv);
  static
  already_AddRefed<MyClass> Constructor(const GlobalObject& aGlobal,
                                        uint32_t aSomeNumber,
                                        ErrorResult& rv);
};
```

### C++ reflections of Web IDL types

The exact C++ representation for Web IDL types can depend on the precise
way that they're being used (e.g., return values, arguments, and
sequence or dictionary members might all have different
representations).

Unless stated otherwise, a type only has one representation. Also,
unless stated otherwise, nullable types are represented by wrapping
[`Nullable<>`](#nullable-t) around the base type.

In all cases, optional arguments which do not have a default value are
represented by wrapping [`const Optional<>&`](#optional-t) around the
representation of the argument type. If the argument type is a C++
reference, it will also become a [`NonNull<>`](#nonnull-t) around the
actual type of the object in the process. Optional arguments which do
have a default value are just represented by the argument type itself,
set to the default value if the argument was not in fact passed in.

Variadic Web IDL arguments are treated as a
[`const Sequence<>&`](#sequence-t) around the actual argument type.

Here's a table, see the specific sections below for more details and
explanations.

| Web IDL Type                | Argument Type                     | Return Type                                                                                                      | Dictionary/Member Type                 |
| -------------------------- | --------------------------------- | ---------------------------------------------------------------------------------------------------------------- | -------------------------------------- |
| any                        | `JS::Handle<JS::Value>`           | `JS::MutableHandle<JS::Value>`                                                                                   | `JS::Value`                            |
| boolean                    | `bool`                            | `bool`                                                                                                           | `bool`                                 |
| byte                       | `int8_t`                          | `int8_t`                                                                                                         | `int8_t`                               |
| ByteString                 | `const nsACString&`               | `nsCString&` _(outparam)_<br>`nsACString&` _(outparam)_                                                          | `nsCString`                            |
| Date                       |                                   |                                                                                                                  | `mozilla::dom::Date`                   |
| DOMString                  | `const nsAString&`                | [`mozilla::dom::DOMString&`](#domstring-c) _(outparam)_<br>`nsAString&` _(outparam)_<br>`nsString&` _(outparam)_ | `nsString`                             |
| UTF8String                 | `const nsACString&` _(outparam)_  | `nsACString&`                                                                                                    | `nsCString`                            |
| double                     | `double`                          | `double`                                                                                                         | `double`                               |
| float                      | `float`                           | `float`                                                                                                          | `float`                                |
| interface:<br>non-nullable | `Foo&`                            | `already_addRefed<Foo>`                                                                                          | [`OwningNonNull<Foo>`](#owningnonnull-t) |
| interface:<br>nullable     | `Foo*`                            | `already_addRefed<Foo>`<br>`Foo*`                                                                                | `RefPtr<Foo>`                          |
| long                       | `int32_t`                         | `int32_t`                                                                                                        | `int32_t`                              |
| long long                  | `int64_t`                         | `int64_t`                                                                                                        | `int64_t`                              |
| object                     | `JS::Handle<JSObject*>`           | `JS::MutableHandle<JSObject*>`                                                                                   | `JSObject*`                            |
| octet                      | `uint8_t`                         | `uint8_t`                                                                                                        | `uint8_t`                              |
| sequence                   | [`const Sequence<T>&`](#sequence-t) | `nsTArray<T>&` _(outparam)_                                                                                      |                                        |
| short                      | `int16_t`                         | `int16_t`                                                                                                        | `int16_t`                              |
| unrestricted double        | `double`                          | `double`                                                                                                         | `double`                               |
| unrestricted float         | `float`                           | `float`                                                                                                          | `float`                                |
| unsigned long              | `uint32_t`                        | `uint32_t`                                                                                                       | `uint32_t`                             |
| unsigned long long         | `uint64_t`                        | `uint64_t`                                                                                                       | `uint64_t`                             |
| unsigned short             | `uint16_t`                        | `uint16_t`                                                                                                       | `uint16_t`                             |
| USVString                  | `const nsAString&`                | [`mozilla::dom::DOMString&`](#domstring-c) _(outparam)_<br>`nsAString&` _(outparam)_<br>`nsString&` _(outparam)_ | `nsString`                             |

#### `any`

`any` is represented in three different ways, depending on use:

- `any` arguments become `JS::Handle<JS::Value>`. They will be in
  the compartment of the passed-in JSContext.
- `any` return values become a `JS::MutableHandle<JS::Value>` out
  param appended to the argument list. This comes after all IDL
  arguments, but before the `ErrorResult&`, if any, for the method.
  The return value is allowed to be in any compartment; bindings will
  wrap it into the context compartment as needed.
- `any` dictionary members and sequence elements become
  `JS::Value`. The dictionary members and sequence elements are
  guaranteed to be marked by whomever puts the sequence or dictionary
  on the stack, using `SequenceRooter` and `DictionaryRooter`.

Methods using `any` always get a `JSContext*` argument.

For example, this Web IDL:

``` webidl
interface Test {
  attribute any myAttr;
  any myMethod(any arg1, sequence<any> arg2, optional any arg3);
};
```

will correspond to these C++ function declarations:

``` cpp
void MyAttr(JSContext* cx, JS::MutableHandle<JS::Value> retval);
void SetMyAttr(JSContext* cx, JS::Handle<JS::Value> value);
void MyMethod(JSContext* cx, JS::Handle<JS::Value> arg1,
              const Sequence<JS::Value>& arg2,
              const Optional<JS::Handle<JS::Value>>& arg3,
              JS::MutableHandle<JS::Value> retval);
```

#### `boolean`

The `boolean` Web IDL type is represented as a C++ `bool`.

For example, this Web IDL:

``` webidl
interface Test {
  attribute boolean myAttr;
  boolean myMethod(optional boolean arg);
};
```

will correspond to these C++ function declarations:

``` cpp
bool MyAttr();
void SetMyAttr(bool value);
bool MyMethod(const Optional<bool>& arg);
```

#### Integer types

Integer Web IDL types are mapped to the corresponding C99 stdint types.

For example, this Web IDL:

``` webidl
interface Test {
  attribute short myAttr;
  long long myMethod(unsigned long? arg);
};
```

will correspond to these C++ function declarations:

``` cpp
int16_t MyAttr();
void SetMyAttr(int16_t value);
int64_t MyMethod(const Nullable<uint32_t>& arg);
```

#### Floating point types

Floating point Web IDL types are mapped to the C++ type of the same
name. So `float` and `unrestricted float` become a C++ `float`,
while `double` and `unrestricted double` become a C++ `double`.

For example, this Web IDL:

``` webidl
interface Test {
  float myAttr;
  double myMethod(unrestricted double? arg);
};
```

will correspond to these C++ function declarations:

``` cpp
float MyAttr();
void SetMyAttr(float value);
double MyMethod(const Nullable<double>& arg);
```

(domstring-c)=

#### `DOMString`

Strings are reflected in three different ways, depending on use:

- String arguments become `const nsAString&`.
- String return values become a
  [`mozilla::dom::DOMString&`](#domstring-c) out param
  appended to the argument list. This comes after all IDL arguments,
  but before the `ErrorResult&`, if any, for the method. Note that
  this allows callees to declare their methods as taking an
  `nsAString&` or `nsString&` if desired.
- Strings in sequences, dictionaries, owning unions, and variadic
  arguments become `nsString`.

Nullable strings are represented by the same types as non-nullable ones,
but the string will return true for `DOMStringIsNull()`. Returning
null as a string value can be done using `SetDOMStringToNull` on the
out param if it's an `nsAString` or calling `SetNull()` on a
`DOMString`.

For example, this Web IDL:

``` webidl
interface Test {
  DOMString myAttr;
  [Throws]
  DOMString myMethod(sequence<DOMString> arg1, DOMString? arg2, optional DOMString arg3);
};
```

will correspond to these C++ function declarations:

``` cpp
void GetMyAttr(nsString& retval);
void SetMyAttr(const nsAString& value);
void MyMethod(const Sequence<nsString>& arg1, const nsAString& arg2,
              const Optional<nsAString>& arg3, nsString& retval, ErrorResult& rv);
```

#### `USVString`

`USVString` is reflected just like `DOMString`.

#### `UTF8String`

`UTF8String` is a string with guaranteed-valid UTF-8 contents. It is
not a standard in the Web IDL spec, but its observables are the same as
those of `USVString`.

It is a good fit for when the specification allows a `USVString`, but
you want to process the string as UTF-8 rather than UTF-16.

It is reflected in three different ways, depending on use:

- Arguments become `const nsACString&`.
- Return values become an `nsACString&` out param appended to the
  argument list. This comes after all IDL arguments, but before the
  `ErrorResult&`, if any, for the method.
- In sequences, dictionaries owning unions, and variadic arguments it
  becomes `nsCString`.

Nullable `UTF8String`s are represented by the same types as
non-nullable ones, but the string will return true for `IsVoid()`.
Returning null as a string value can be done using `SetIsVoid()` on
the out param.

#### `ByteString`

`ByteString` is reflected in three different ways, depending on use:

- `ByteString` arguments become `const nsACString&`.
- `ByteString` return values become an `nsCString&` out param
  appended to the argument list. This comes after all IDL arguments,
  but before the `ErrorResult&`, if any, for the method.
- `ByteString` in sequences, dictionaries, owning unions, and
  variadic arguments becomes `nsCString`.

Nullable `ByteString` are represented by the same types as
non-nullable ones, but the string will return true for `IsVoid()`.
Returning null as a string value can be done using `SetIsVoid()` on
the out param.

#### `object`

`object` is represented in three different ways, depending on use:

- `object` arguments become `JS::Handle<JSObject*>`. They will be
  in the compartment of the passed-in JSContext.
- `object` return values become a `JS::MutableHandle<JSObject*>`
  out param appended to the argument list. This comes after all IDL
  arguments, but before the `ErrorResult&`, if any, for the method.
  The return value is allowed to be in any compartment; bindings will
  wrap it into the context compartment as needed.
- `object` dictionary members and sequence elements become
  `JSObject*`. The dictionary members and sequence elements are
  guaranteed to be marked by whoever puts the sequence or dictionary on
  the stack, using `SequenceRooter` and `DictionaryRooter`.

Methods using `object` always get a `JSContext*` argument.

For example, this Web IDL:

``` webidl
interface Test {
  object myAttr;
  object myMethod(object arg1, object? arg2, sequence<object> arg3, optional object arg4,
                  optional object? arg5);
};
```

will correspond to these C++ function declarations:

``` cpp
void GetMyAttr(JSContext* cx, JS::MutableHandle<JSObject*> retval);
void SetMyAttr(JSContext* cx, JS::Handle<JSObject*> value);
void MyMethod(JSContext* cx, JS::Handle<JSObject*> arg1, JS::Handle<JSObject*> arg2,
              const Sequence<JSObject*>& arg3,
              const Optional<JS::Handle<JSObject*>>& arg4,
              const Optional<JS::Handle<JSObject*>>& arg5,
              JS::MutableHandle<JSObject*> retval);
```

#### Interface types

There are four kinds of interface types in the Web IDL bindings. Callback
interfaces are used to represent script objects that browser code can
call into. External interfaces are used to represent objects that have
not been converted to the Web IDL bindings yet. Web IDL interfaces are
used to represent Web IDL binding objects. "SpiderMonkey" interfaces are
used to represent objects that are implemented natively by the
JavaScript engine (e.g., typed arrays).

##### Callback interfaces

Callback interfaces are represented in C++ as objects inheriting from
[`mozilla::dom::CallbackInterface`](#callbackinterface), whose
name, in the `mozilla::dom` namespace, matches the name of the
callback interface in the Web IDL. The exact representation depends on
how the type is being used.

- Nullable arguments become `Foo*`.
- Non-nullable arguments become `Foo&`.
- Return values become `already_AddRefed<Foo>` or `Foo*` as
  desired. The pointer form is preferred because it results in faster
  code, but it should only be used if the return value was not addrefed
  (and so it can only be used if the return value is kept alive by the
  callee until at least the binding method has returned).
- Web IDL callback interfaces in sequences, dictionaries, owning unions,
  and variadic arguments are represented by `RefPtr<Foo>` if nullable
  and [`OwningNonNull<Foo>`](#owningnonnull-t) otherwise.

If the interface is a single-operation interface, the object exposes two
methods that both invoke the same underlying JS callable. The first of
these methods allows the caller to pass in a `this` object, while the
second defaults to `undefined` as the `this` value. In either case,
the `this` value is only used if the callback interface is implemented
by a JS callable. If it's implemented by an object with a property whose
name matches the operation, the object itself is always used as
`this`.

If the interface is not a single-operation interface, it just exposes a
single method for every IDL method/getter/setter.

The signatures of the methods correspond to the signatures for throwing
IDL methods/getters/setters with an additional trailing
`mozilla::dom::CallbackObject::ExceptionHandling aExceptionHandling`
argument, defaulting to `eReportExceptions`.
If `aReportExceptions` is set to `eReportExceptions`, the methods
will report JS exceptions before returning. If `aReportExceptions` is
set to `eRethrowExceptions`, JS exceptions will be stashed in the
`ErrorResult` and will be reported when the stack unwinds to wherever
the `ErrorResult` was set up.

For example, this Web IDL:

``` webidl
callback interface MyCallback {
  attribute long someNumber;
  short someMethod(DOMString someString);
};
callback interface MyOtherCallback {
  // single-operation interface
  short doSomething(Node someNode);
};
interface MyInterface {
  attribute MyCallback foo;
  attribute MyCallback? bar;
};
```

will lead to these C++ class declarations in the `mozilla::dom`
namespace:

``` cpp
class MyCallback : public CallbackInterface
{
  int32_t GetSomeNumber(ErrorResult& rv, ExceptionHandling aExceptionHandling = eReportExceptions);
  void SetSomeNumber(int32_t arg, ErrorResult& rv,
                     ExceptionHandling aExceptionHandling = eReportExceptions);
  int16_t SomeMethod(const nsAString& someString, ErrorResult& rv,
                     ExceptionHandling aExceptionHandling = eReportExceptions);
};

class MyOtherCallback : public CallbackInterface
{
public:
  int16_t
  DoSomething(nsINode& someNode, ErrorResult& rv,
              ExceptionHandling aExceptionHandling = eReportExceptions);

  template<typename T>
  int16_t
  DoSomething(const T& thisObj, nsINode& someNode, ErrorResult& rv,
              ExceptionHandling aExceptionHandling = eReportExceptions);
};
```

and these C++ function declarations on the implementation of
`MyInterface`:

``` cpp
already_AddRefed<MyCallback> GetFoo();
void SetFoo(MyCallback&);
already_AddRefed<MyCallback> GetBar();
void SetBar(MyCallback*);
```

A consumer of MyCallback would be able to use it like this:

``` cpp
void
SomeClass::DoSomethingWithCallback(MyCallback& aCallback)
{
  ErrorResult rv;
  int32_t number = aCallback.GetSomeNumber(rv);
  if (rv.Failed()) {
    // The error has already been reported to the JS console; you can handle
    // things however you want here.
    return;
  }

  // For some reason we want to catch and rethrow exceptions from SetSomeNumber, say.
  aCallback.SetSomeNumber(2*number, rv, eRethrowExceptions);
  if (rv.Failed()) {
    // The exception is now stored on rv. This code MUST report
    // it usefully; otherwise it will assert.
  }
}
```

##### External interfaces

External interfaces are represented in C++ as objects that XPConnect
knows how to unwrap to. This can mean XPCOM interfaces (whether declared
in XPIDL or not) or it can mean some type that there's a castable native
unwrapping function for. The C++ type to be used should be the
`nativeType` listed for the external interface in the
[`Bindings.conf`](#bindings-conf-details) file. The exact representation
depends on how the type is being used.

- Arguments become `nsIFoo*`.
- Return values can be `already_AddRefed<nsIFoo>` or `nsIFoo*` as
  desired. The pointer form is preferred because it results in faster
  code, but it should only be used if the return value was not addrefed
  (and so it can only be used if the return value is kept alive by the
  callee until at least the binding method has returned).
- External interfaces in sequences, dictionaries, owning unions, and
  variadic arguments are represented by `RefPtr<nsIFoo>`.

##### Web IDL interfaces

Web IDL interfaces are represented in C++ as C++ classes. The class
involved must either be refcounted or must be explicitly annotated in
`Bindings.conf` as being directly owned by the JS object. If the class
inherits from `nsISupports`, then the canonical `nsISupports` must
be on the primary inheritance chain of the object. If the interface has
a parent interface, the C++ class corresponding to the parent must be on
the primary inheritance chain of the object. This guarantees that a
`void*` can be stored in the JSObject which can then be
`reinterpret_cast` to any of the classes that correspond to interfaces
the object implements. The C++ type to be used should be the
`nativeType` listed for the interface in the
[`Bindings.conf`](#bindings-conf-details) file, or
`mozilla::dom::InterfaceName` if none is listed. The exact
representation depends on how the type is being used.

- Nullable arguments become `Foo*`.
- Non-nullable arguments become `Foo&`.
- Return values become `already_AddRefed<Foo>` or `Foo*` as
  desired. The pointer form is preferred because it results in faster
  code, but it should only be used if the return value was not addrefed
  (and so it can only be used if the return value is kept alive by the
  callee until at least the binding method has returned).
- Web IDL interfaces in sequences, dictionaries, owning unions, and
  variadic arguments are represented by `RefPtr<Foo>` if nullable and
  [`OwningNonNull<Foo>`](#owningnonnull-t) otherwise.

For example, this Web IDL:

``` webidl
interface MyInterface {
  attribute MyInterface myAttr;
  undefined passNullable(MyInterface? arg);
  MyInterface? doSomething(sequence<MyInterface> arg);
  MyInterface doTheOther(sequence<MyInterface?> arg);
  readonly attribute MyInterface? nullableAttr;
  readonly attribute MyInterface someOtherAttr;
  readonly attribute MyInterface someYetOtherAttr;
};
```

Would correspond to these C++ function declarations:

``` cpp
already_AddRefed<MyClass> MyAttr();
void SetMyAttr(MyClass& value);
void PassNullable(MyClass* arg);
already_AddRefed<MyClass> doSomething(const Sequence<OwningNonNull<MyClass>>& arg);
already_AddRefed<MyClass> doTheOther(const Sequence<RefPtr<MyClass>>& arg);
already_Addrefed<MyClass> GetNullableAttr();
MyClass* SomeOtherAttr();
MyClass* SomeYetOtherAttr(); // Don't have to return already_AddRefed!
```

##### "SpiderMonkey" interfaces

Typed array, array buffer, and array buffer view arguments are
represented by the objects in [`TypedArray.h`](#typed-arrays-arraybuffers-array-buffer-views). For
example, this Web IDL:

``` webidl
interface Test {
  undefined passTypedArrayBuffer(ArrayBuffer arg);
  undefined passTypedArray(ArrayBufferView arg);
  undefined passInt16Array(Int16Array? arg);
}
```

will correspond to these C++ function declarations:

``` cpp
void PassTypedArrayBuffer(const ArrayBuffer& arg);
void PassTypedArray(const ArrayBufferView& arg);
void PassInt16Array(const Nullable<Int16Array>& arg);
```

Typed array return values become a `JS::MutableHandle<JSObject*>` out
param appended to the argument list. This comes after all IDL arguments,
but before the `ErrorResult&`, if any, for the method. The return
value is allowed to be in any compartment; bindings will wrap it into
the context compartment as needed.

Typed arrays store a `JSObject*` and hence need to be rooted
properly. On-stack typed arrays can be declared as
`RootedTypedArray<TypedArrayType>` (e.g.
`RootedTypedArray<Int16Array>`). Typed arrays on the heap need to be
traced.

#### Dictionary types

A dictionary argument is represented by a const reference to a struct
whose name is the dictionary name in the `mozilla::dom` namespace.
The struct has one member for each of the dictionary's members with the
same name except the first letter uppercased and prefixed with "m". The
members that are required or have default values have types as described
under the corresponding Web IDL type in this document. The members that
are not required and don't have default values have those types wrapped
in [`Optional<>`](#optional-t).

Dictionary return values are represented by an out parameter whose type
is a non-const reference to the struct described above, with all the
members that have default values preinitialized to those default values.

Note that optional dictionary arguments are always forced to have a
default value of an empty dictionary by the IDL parser and code
generator, so dictionary arguments are never wrapped in `Optional<>`.

If necessary, dictionaries can be directly initialized from a
`JS::Value` in C++ code by invoking their `Init()` method. Consumers
doing this should declare their dictionary as
`RootedDictionary<DictionaryName>`. When this is done, passing in a
null `JSContext*` is allowed if the passed-in `JS::Value` is
`JS::NullValue()`. Likewise, a dictionary struct can be converted to a
`JS::Value` in C++ by calling `ToJSValue` with the dictionary as the
second argument. If `Init()` or `ToJSValue()` returns false, they
will generally set a pending exception on the JSContext; reporting those
is the responsibility of the caller.

For example, this Web IDL:

``` text
dictionary Dict {
  long foo = 5;
  DOMString bar;
};

interface Test {
  undefined initSomething(optional Dict arg = {});
};
```

will correspond to this C++ function declaration:

``` cpp
void InitSomething(const Dict& arg);
```

and the `Dict` struct will look like this:

``` cpp
struct Dict {
  bool Init(JSContext* aCx, JS::Handle<JS::Value> aVal, const char* aSourceDescription = "value");

  Optional<nsString> mBar;
  int32_t mFoo;
}
```

Note that the dictionary members are sorted in the struct in
alphabetical order.

##### API for working with dictionaries

There are a few useful methods found on dictionaries and dictionary
members that you can use to quickly determine useful things.

- **member.WasPassed()** - as the name suggests, was a particular
  member passed?
  (e.g., `if (arg.foo.WasPassed() { /* do nice things!*/ }`)
- **dictionary.IsAnyMemberPresent()** - great for checking if you need
  to do anything.
  (e.g., `if (!arg.IsAnyMemberPresent()) return; // nothing to do`)
- **member.Value()** - getting the actual data/value of a member that
  was passed.
  (e.g., `mBar.Assign(args.mBar.value())`)

Example implementation using all of the above:

``` cpp
void
MyInterface::InitSomething(const Dict& aArg){
  if (!aArg.IsAnyMemberPresent()) {
    return; // nothing to do!
  }
  if (aArg.mBar.WasPassed() && !mBar.Equals(aArg.mBar.value())) {
    mBar.Assign(aArg.mBar.Value());
  }
}
```

#### Enumeration types

Web IDL enumeration types are represented as C++ enum classes. The values
of the C++ enum are named by taking the strings in the Web IDL
enumeration, replacing all non-alphanumerics with underscores, and
uppercasing the first letter, with a special case for the empty string,
which becomes the value `_empty`.

For a Web IDL enum named `MyEnum`, the C++ enum is named `MyEnum` and
placed in the `mozilla::dom` namespace, while the values are placed in
the `mozilla::dom::MyEnum` namespace.

The type of the enum class is automatically selected to be the smallest
unsigned integer type that can hold all the values. In practice, this
is always uint8_t, because Web IDL enums tend to not have more than 255
values.

For example, this Web IDL:

``` webidl
enum MyEnum {
  "something",
  "something-else",
  "",
  "another"
};
```

would lead to this C++ enum declaration:

``` cpp
enum class MyEnum : uint8_t {
  Something,
  Something_else,
  _empty,
  Another
};
```

`mozilla::dom::GetEnumString` is a templated helper function declared in
[`BindingUtils.h`](https://searchfox.org/firefox-main/source/dom/bindings/BindingUtils.h)
and exported to `mozilla/dom/BindingUtils.h` that can be used to convert an enum
value to its corresponding string value. It returns a `const nsCString&`
containing the string value.

`mozilla::dom::StringToEnum` is a templated helper function in
[`BindingUtils.h`](https://searchfox.org/firefox-main/source/dom/bindings/BindingUtils.h)
and exported to `mozilla/dom/BindingUtils.h` that can be used to convert a
string to the corresponding enum value. It needs to be supplied with the enum
class as a template argument, and returns a `mozilla::Maybe<Enum>`. If the string
value passed to it as an argument is not one of the string values for the enum
then it returns `mozilla::Nothing()`, else it returns the right enum value in
the `mozilla::Maybe`.

`mozilla::dom::WebIDLEnumSerializer` is a templated alias in
[`BindingIPCUtils.h`](https://searchfox.org/firefox-main/source/dom/bindings/BindingIPCUtils.h)
exported to `mozilla/dom/BindingIPCUtils.h` to implement an IPC serializer with
the right validation for WebIDL enums. It uses a
`mozilla::MaxContinuousEnumValue` that is generated for every WebIDL enum to
implement the validation.

`mozilla::dom::MakeWebIDLEnumeratedRange` is a templated helper function in
[`BindingUtils.h`](https://searchfox.org/firefox-main/source/dom/bindings/BindingUtils.h)
and exported to `mozilla/dom/BindingUtils.h` that can be used to create a
`mozilla::EnumeratedRange` for a WebIDL enum.

#### Callback function types

Callback functions are represented as an object, inheriting from
[`mozilla::dom::CallbackFunction`](#callbackfunction), whose name,
in the `mozilla::dom` namespace, matches the name of the callback
function in the Web IDL. If the type is nullable, a pointer is passed in;
otherwise a reference is passed in.

The object exposes two `Call` methods, which both invoke the
underlying JS callable. The first `Call` method has the same signature
as a throwing method declared just like the callback function, with an
additional trailing `mozilla::dom::CallbackObject::ExceptionHandling aExceptionHandling`
argument, defaulting to `eReportExceptions`,
and calling it will invoke the callable with `undefined` as the
`this` value. The second `Call` method allows passing in an explicit
`this` value as the first argument. This second call method is a
template on the type of the first argument, so the `this` value can be
passed in in whatever form is most convenient, as long as it's either a
type that can be wrapped by XPConnect or a Web IDL interface type.

If `aReportExceptions` is set to `eReportExceptions`, the `Call`
methods will report JS exceptions before returning. If
`aReportExceptions` is set to `eRethrowExceptions`, JS exceptions
will be stashed in the `ErrorResult` and will be reported when the
stack unwinds to wherever the `ErrorResult` was set up.

For example, this Web IDL:

``` webidl
callback MyCallback = long (MyInterface arg1, boolean arg2);
interface MyInterface {
  attribute MyCallback foo;
  attribute MyCallback? bar;
};
```

will lead to this C++ class declaration, in the `mozilla::dom`
namespace:

``` cpp
class MyCallback : public CallbackFunction
{
public:
  int32_t
  Call(MyInterface& arg1, bool arg2, ErrorResult& rv,
       ExceptionHandling aExceptionHandling = eReportExceptions);

  template<typename T>
  int32_t
  Call(const T& thisObj, MyInterface& arg1, bool arg2, ErrorResult& rv,
       ExceptionHandling aExceptionHandling = eReportExceptions);
};
```

and these C++ function declarations in the `MyInterface` class:

``` cpp
already_AddRefed<MyCallback> GetFoo();
void SetFoo(MyCallback&);
already_AddRefed<MyCallback> GetBar();
void SetBar(MyCallback*);
```

A consumer of MyCallback would be able to use it like this:

``` cpp
void
SomeClass::DoSomethingWithCallback(MyCallback& aCallback, MyInterface& aInterfaceInstance)
{
  ErrorResult rv;
  int32_t number = aCallback.Call(aInterfaceInstance, false, rv);
  if (rv.Failed()) {
    // The error has already been reported to the JS console; you can handle
    // things however you want here.
    return;
  }

  // Now for some reason we want to catch and rethrow exceptions from the callback,
  // and use "this" as the this value for the call to JS.
  number = aCallback.Call(*this, true, rv, eRethrowExceptions);
  if (rv.Failed()) {
    // The exception is now stored on rv.  This code MUST report
    // it usefully; otherwise it will assert.
  }
}
```

#### Sequences

Sequence arguments are represented by
[`const Sequence<T>&`](#sequence-t), where `T` depends on the type
of elements in the Web IDL sequence.

Sequence return values are represented by an `nsTArray<T>` out param
appended to the argument list, where `T` is the return type for the
elements of the Web IDL sequence. This comes after all IDL arguments, but
before the `ErrorResult&`, if any, for the method.

#### Arrays

IDL array objects are not supported yet. The spec on these is likely to
change drastically anyway.

#### Union types

Union types are reflected as a struct in the `mozilla::dom` namespace.
There are two kinds of union structs: one kind does not keep its members
alive (is "non-owning"), and the other does (is "owning"). Const
references to non-owning unions are used for plain arguments. Owning
unions are used in dictionaries, sequences, and for variadic arguments.
Union return values become a non-const owning union out param. The name
of the struct is the concatenation of the names of the types in the
union, with "Or" inserted between them, and for an owning struct
"Owning" prepended. So for example, this IDL:

``` text
undefined passUnion((object or long) arg);
(object or long) receiveUnion();
undefined passSequenceOfUnions(sequence<(object or long)> arg);
undefined passOtherUnion((HTMLDivElement or ArrayBuffer or EventInit) arg);
```

would correspond to these C++ function declarations:

``` cpp
void PassUnion(const ObjectOrLong& aArg);
void ReceiveUnion(OwningObjectObjectOrLong& aArg);
void PassSequenceOfUnions(const Sequence<OwningObjectOrLong>& aArg);
void PassOtherUnion(const HTMLDivElementOrArrayBufferOrEventInit& aArg);
```

Union structs expose accessors to test whether they're of a given type
and to get hold of the data of that type. They also expose setters that
set the union as being of a particular type and return a reference to
the union's internal storage where that type could be stored. The one
exception is the `object` type, which uses a somewhat different form
of setter where the `JSObject*` is passed in directly. For example,
`ObjectOrLong` would have the following methods:

``` cpp
bool IsObject() const;
JSObject* GetAsObject() const;
void SetToObject(JSContext*, JSObject*);
bool IsLong() const;
int32_t GetAsLong() const;
int32_t& SetAsLong()
```

Owning unions used on the stack should be declared as a
`RootedUnion<UnionType>`, for example,
`RootedUnion<OwningObjectOrLong>`.

#### `Date`

Web IDL `Date` types are represented by a `mozilla::dom::Date`
struct.

### C++ reflections of Web IDL declarations

Web IDL declarations (maplike/setlike/iterable) are turned into a set of
properties and functions on the interface they are declared on. Each has
a different set of helper functions it comes with. In addition, for
iterable, there are requirements for C++ function implementation by the
interface developer.

#### Maplike

Example Interface:

``` webidl
interface StringToLongMap {
  maplike<DOMString, long>;
};
```

The bindings for this interface will generate the storage structure for
the map, as well as helper functions for accessing that structure from
C++. The generated C++ API will look as follows:

``` cpp
namespace StringToLongMapBinding {
namespace MaplikeHelpers {
void Clear(mozilla::dom::StringToLongMap* self, ErrorResult& aRv);
bool Delete(mozilla::dom::StringToLongMap* self, const nsAString& aKey, ErrorResult& aRv);
bool Has(mozilla::dom::StringToLongMap* self, const nsAString& aKey, ErrorResult& aRv);
void Set(mozilla::dom::StringToLongMap* self, const nsAString& aKey, int32_t aValue, ErrorResult& aRv);
} // namespace MaplikeHelpers
} // namespace StringToLongMapBindings
```

#### Setlike

Example Interface:

``` webidl
interface StringSet {
  setlike<DOMString>;
};
```

The bindings for this interface will generate the storage structure for
the set, as well as helper functions for accessing that structure from
c++. The generated C++ API will look as follows:

``` cpp
namespace StringSetBinding {
namespace SetlikeHelpers {
void Clear(mozilla::dom::StringSet* self, ErrorResult& aRv);
bool Delete(mozilla::dom::StringSet* self, const nsAString& aKey, ErrorResult& aRv);
bool Has(mozilla::dom::StringSet* self, const nsAString& aKey, ErrorResult& aRv);
void Add(mozilla::dom::StringSet* self, const nsAString& aKey, ErrorResult& aRv);
} // namespace SetlikeHelpers
}
```

#### Iterable

Unlike maplike and setlike, iterable does not have any C++ helpers, as
the structure backing the iterable data for the interface is left up to
the developer. With that in mind, the generated iterable bindings expect
the wrapper object to provide certain methods for the interface to
access.

Iterable interfaces have different requirements, based on if they are
single or pair value iterators.

Example Interface for a single value iterator:

``` webidl
interface LongIterable {
  iterable<long>;
  getter long(unsigned long index);
  readonly attribute unsigned long length;
};
```

For single value iterator interfaces, we treat the interface as an
[indexed getter](#indexed-getters), as required by the spec. See the
[indexed getter implementation section](#indexed-getters) for more
information on building this kind of structure.

Example Interface for a pair value iterator:

``` webidl
interface StringAndLongIterable {
  iterable<DOMString, long>;
};
```

The bindings for this pair value iterator interface require the
following methods be implemented in the C++ object:

``` cpp
class StringAndLongIterable {
public:
  // Returns the number of items in the iterable storage
  size_t GetIterableLength();
  // Returns key of pair at aIndex in iterable storage
  nsAString& GetKeyAtIndex(uint32_t aIndex);
  // Returns value of pair at aIndex in iterable storage
  uint32_t& GetValueAtIndex(uint32_t aIndex);
}
```

### Stringifiers

Named stringifiers operations in Web IDL will just invoke the
corresponding C++ method.

Anonymous stringifiers in Web IDL will invoke the C++ method called
`Stringify`. So, for example, given this IDL:

``` webidl
interface FirstInterface {
  stringifier;
};

interface SecondInterface {
  stringifier DOMString getStringRepresentation();
};
```

the corresponding C++ would be:

``` cpp
class FirstInterface {
public:
  void Stringify(nsAString& aResult);
};

class SecondInterface {
public:
  void GetStringRepresentation(nsAString& aResult);
};
```

### Legacy Callers

Only anonymous legacy callers are supported, and will invoke the C++
method called `LegacyCall`. This will be passed the JS "this" value as
the first argument, then the arguments to the actual operation. A
`JSContext` will be passed if any of the operation arguments need it.
So for example, given this IDL:

``` webidl
interface InterfaceWithCall {
  legacycaller long (float arg);
};
```

the corresponding C++ would be:

``` cpp
class InterfaceWithCall {
public:
  int32_t LegacyCall(JS::Handle<JS::Value> aThisVal, float aArgument);
};
```

### Named getters

If the interface has a named getter, the binding will expect several
methods on the C++ implementation:

- A `NamedGetter` method. This takes a property name and returns
  whatever type the named getter is declared to return. It also has a
  boolean out param for whether a property with that name should exist
  at all.
- A `NameIsEnumerable` method. This takes a property name and
  returns a boolean that indicates whether the property is enumerable.
- A `GetSupportedNames` method. This takes an unsigned integer which
  corresponds to the flags passed to the `iterate` proxy trap and
  returns a list of property names. For implementations of this method,
  the important flags is `JSITER_HIDDEN`. If that flag is set, the
  call needs to return all supported property names. If it's not set,
  the call needs to return only the enumerable ones.

The `NameIsEnumerable` and `GetSupportedNames` methods need to agree
on which names are and are not enumerable. The `NamedGetter` and
`GetSupportedNames` methods need to agree on which names are
supported.

So for example, given this IDL:

``` webidl
interface InterfaceWithNamedGetter {
  getter long(DOMString arg);
};
```

the corresponding C++ would be:

``` cpp
class InterfaceWithNamedGetter
{
public:
  int32_t NamedGetter(const nsAString& aName, bool& aFound);
  bool NameIsEnumerable(const nsAString& aName);
  undefined GetSupportedNames(unsigned aFlags, nsTArray<nsString>& aNames);
};
```

### Indexed getters

If the interface has a indexed getter, the binding will expect the
following methods on the C++ implementation:

- A `IndexedGetter` method. This takes an integer index value and
  returns whatever type the indexed getter is declared to return. It
  also has a boolean out param for whether a property with that index
  should exist at all. The implementation must set this out param
  correctly. The return value is guaranteed to be ignored if the out
  param is set to false.

So for example, given this IDL:

``` webidl
interface InterfaceWithIndexedGetter {
  getter long(unsigned long index);
  readonly attribute unsigned long length;
};
```

the corresponding C++ would be:

``` cpp
class InterfaceWithIndexedGetter
{
public:
  uint32_t Length() const;
  int32_t IndexedGetter(uint32_t aIndex, bool& aFound) const;
};
```

## Throwing exceptions from Web IDL methods, getters, and setters

Web IDL methods, getters, and setters that are [explicitly marked as
allowed to throw](#throws-getterthrows-setterthrows) have an `ErrorResult&` argument as their
last argument. To throw an exception, simply call `Throw()` on the
`ErrorResult&` and return from your C++ back into the binding code.

In cases when the specification calls for throwing a `TypeError`, you
should use `ErrorResult::ThrowTypeError()` instead of calling
`Throw()`.

## Custom extended attributes

Our Web IDL parser and code generator recognize several extended
attributes that are not present in the Web IDL spec.

### `[AllowLarge]`

Can be specified on buffer source types (`ArrayBuffer`, `ArrayBufferView`,
typed arrays) to skip the default 2 GB size check. This allows
incremental migration of consumers to support buffers larger than 2 GB.
Can be combined with `[AllowShared]`. On the C++ side, use
`ProcessData<true>(...)` or `ProcessFixedData<true>(...)` to access the
data.

### `[Alias=propName]`

This extended attribute can be specified on a method and indicates that
another property with the specified name will also appear on the
interface prototype object and will have the same Function object value
as the property for the method. For example:

``` webidl
interface MyInterface {
  [Alias=performSomething] undefined doSomething();
};
```

`MyInterface.prototype.performSomething` will have the same Function
object value as `MyInterface.prototype.doSomething`.

Multiple `[Alias]` extended attribute can be used on the one method.
`[Alias]` cannot be used on a static method, nor on methods on a
global interface (such as `Window`).

Aside from regular property names, the name of an alias can be
[Symbol.iterator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/iterator).
This is specified by writing `[Alias="@@iterator"]`.

### `[BindingAlias=propName]`

This extended attribute can be specified on an attribute and indicates
that another property with the specified name will also appear on the
interface prototype object and will call the same underlying C++
implementation for the getter and setter. This is more efficient than
using the same `BinaryName` for both attributes, because it shares the
binding glue code between them. The properties still have separate
getter/setter functions in JavaScript, so from the point of view of web
consumers it's as if you actually had two separate attribute
declarations on your interface. For example:

``` webidl
interface MyInterface {
  [BindingAlias=otherAttr] readonly attribute boolean attr;
};
```

`MyInterface.prototype.otherAttr` and `MyInterface.prototype.attr`
will both exist, have separate getter/setter functions, but call the
same binding glue code and implementation function on the objects
implementing `MyInterface`.

Multiple `[BindingAlias]` extended attributes can be used on a single
attribute.

### `[BindingTemplate=(name, type, value)]`

This extended attribute can be specified on an attribute, and causes the getter
and setter for this attribute to forward to a common generated implementation,
shared with all other attributes that have a `[BindingTemplate]` with the same
value for the `name` argument. The `TemplatedAttributes` dictionary in
Bindings.conf needs to contain a definition for the template with the name
`name`. The argument `type::value` will be passed when calling the common
generated implementation.

This is aimed at very specialized use cases where an interface has a
large number of attributes that all have the same type, and for which we have a
native implementation that's common to all these attributes, and typically uses
some id based on the attribute's name in the implementation. All the attributes
that use the same template need to mostly have the same extended attributes,
except form a small number that are allowed to differ (`[BindingTemplate]`,
`[BindingAlias]`, `[Pure]`, [`Pref`] and [`Func`], and the annotations for
whether the getter and setter throws exceptions).

### `[ChromeOnly]`

This extended attribute can be specified on any method, attribute, or
constant on an interface or on an interface as a whole. It can also be
specified on dictionary members.

Interface members flagged as `[ChromeOnly]` are only exposed in chrome
Windows (and in particular, are not exposed to webpages). From the point
of view of web content, it's as if the interface member were not there
at all. These members _are_ exposed to chrome script working with a
content object via Xrays.

If specified on an interface as a whole, this functions like
[`[Func]`](#func-funcname) except that the binding code will automatically
check whether the caller script has the system principal (is chrome or a
worker started from a chrome page) instead of calling into the C++
implementation to determine whether to expose the interface object on
the global. This means that accessing a content global via Xrays will
show `[ChromeOnly]` interface objects on it.

If specified on a dictionary member, then the dictionary member will
only appear to exist in system-privileged code.

This extended attribute can be specified together with `[Func]`, and
`[Pref]`. If more than one of these is specified, all conditions will
need to test true for the interface or interface member to be exposed.

### `[Pref=prefname]`

This extended attribute can be specified on any method, attribute, or
constant on an interface or on an interface as a whole. It can also be
specified on dictionary members. It takes a value, which must be the
name of a boolean preference exposed from `StaticPrefs`. The
`StaticPrefs` function that will be called is calculated from the
value of the extended attribute, with dots replaced by underscores
(`StaticPrefs::my_pref_name()` in the example below).

If specified on an interface member, the interface member involved is
only exposed if the preference is set to `true`. An example of how
this can be used:

``` webidl
interface MyInterface {
  attribute long alwaysHere;
  [Pref="my.pref.name"] attribute long onlyHereIfEnabled;
};
```

If specified on an interface as a whole, this functions like
[`[Func]`](#func-funcname) except that the binding will check the value of
the preference directly without calling into the C++ implementation of
the interface at all. This is useful when the enable check is simple and
it's desirable to keep the prefname with the Web IDL declaration.

If specified on a dictionary member, the web-observable behavior when
the pref is set to false will be as if the dictionary did not have a
member of that name defined. That means that on the JS side no
observable get of the property will happen. On the C++ side, the
behavior would be as if the passed-in object did not have a property
with the relevant name: the dictionary member would either be
`!Passed()` or have the default value if there is a default value.

> An example of how this can be used:

``` webidl
[Pref="my.pref.name"]
interface MyConditionalInterface {
};
```

This extended attribute can be specified together with `[ChromeOnly]`,
and `[Func]`. If more than one of these is specified, all conditions
will need to test true for the interface or interface member to be
exposed.

(func-funcname)=

### `[Func="funcname"]`

This extended attribute can be specified on any method, attribute, or
constant on an interface or on an interface as a whole. It can also be
specified on dictionary members. It takes a value, which must be the
name of a static function.

If specified on an interface member, the interface member involved is
only exposed if the specified function returns `true`. An example of
how this can be used:

``` webidl
interface MyInterface {
  attribute long alwaysHere;
  [Func="MyClass::StuffEnabled"] attribute long onlyHereIfEnabled;
};
```

The function is invoked with two arguments: the `JSContext` that the
operation is happening on and the `JSObject` for the global of the
object that the property will be defined on if the function returns
true. In particular, in the Xray case the `JSContext` is in the caller
compartment (typically chrome) but the `JSObject` is in the target
compartment (typically content). This allows the method implementation
to select which compartment it cares about in its checks.

The above IDL would also require the following C++:

``` cpp
class MyClass {
  static bool StuffEnabled(JSContext* cx, JSObject* obj);
};
```

If specified on an interface as a whole, then lookups for the interface
object for this interface on a DOM Window will only find it if the
specified function returns true. For objects that can only be created
via a constructor, this allows disabling the functionality altogether
and making it look like the feature is not implemented at all.

If specified on a dictionary member, the web-observable behavior when
the function returns false will be as if the dictionary did not have a
member of that name defined. That means that on the JS side no
observable get of the property will happen. On the C++ side, the
behavior would be as if the passed-in object did not have a property
with the relevant name: the dictionary member would either be
`!Passed()` or have the default value if there is a default value.

An example of how `[Func]` can be used:

``` webidl
[Func="MyClass::MyConditionalInterfaceEnabled"]
interface MyConditionalInterface {
};
```

In this case, the C++ function is passed a `JS::Handle<JSObject*>`. So
the C++ in this case would look like this:

``` cpp
class MyClass {
  static bool MyConditionalInterfaceEnabled(JSContext* cx, JS::Handle<JSObject*> obj);
};
```

Just like in the interface member case, the `JSContext` is in the
caller compartment but the `JSObject` is the actual object the
property would be defined on. In the Xray case that means obj is in the
target compartment (typically content) and `cx` is typically chrome.

This extended attribute can be specified together with `[ChromeOnly]`,
and `[Pref]`. If more than one of these is specified, all conditions
will need to test true for the interface or interface member to be
exposed.

Binding code will include the headers necessary for a `[Func]`, unless
the interface is using a non-default header file. If a non-default
header file is used, that header file needs to do any header inclusions
necessary for `[Func]` annotations.

### `[Throws]`, `[GetterThrows]`, `[SetterThrows]`

Used to flag methods or attributes as allowing the C++ callee to throw.
This causes the binding generator, and in many cases the JIT, to
generate extra code to handle possible exceptions. Possibly-throwing
methods and attributes get an `ErrorResult&` argument.

`[Throws]` applies to both methods and attributes; for attributes it
means both the getter and the setter can throw. `[GetterThrows]`
applies only to attributes. `[SetterThrows]` applies only to
non-readonly attributes.

For interfaces flagged with `[JSImplementation]`, all methods and
properties are assumed to be able to throw and do not need to be flagged
as throwing.

### `[DependsOn]`

Used for a method or attribute to indicate what the return value depends
on. Possible values are:

- `Everything`

   This value can't actually be specified explicitly; this is the
   default value you get when `[DependsOn]` is not specified. This
   means we don't know anything about the return value's dependencies
   and hence can't rearrange other code that might change values around
   the method or attribute.

- `DOMState`

   The return value depends on the state of the "DOM", by which we mean
   all objects specified via Web IDL. The return value is guaranteed to
   not depend on the state of the JS heap or other JS engine data
   structures, and is guaranteed to not change unless some function with
   [`[Affects=Everything]`](#affects) is executed.

- `DeviceState`

   The return value depends on the state of the device we're running on
   (e.g., the system clock). The return value is guaranteed to not be
   affected by any code running inside Gecko itself, but we might get a
   new value every time the method or getter is called even if no Gecko
   code ran between the calls.

- `Nothing`

   The return value is a constant that never changes. This value cannot
   be used on non-readonly attributes, since having a non-readonly
   attribute whose value never changes doesn't make sense.

Values other than `Everything`, when used in combination with
[`[Affects=Nothing]`](#affects), can used by the JIT to
perform loop-hoisting and common subexpression elimination on the return
values of IDL attributes and methods.

### `[Affects]`

Used for a method or attribute getter to indicate what sorts of state
can be affected when the function is called. Attribute setters are, for
now, assumed to affect everything. Possible values are:

- `Everything`

   This value can't actually be specified explicitly; this is the
   default value you get when `[Affects]` is not specified. This means
   that calling the method or getter might change any mutable state in
   the DOM or JS heap.

- `Nothing`

   Calling the method or getter will have no side-effects on either the
   DOM or the JS heap.

Methods and attribute getters with `[Affects=Nothing]` are allowed to
throw exceptions, as long as they do so deterministically. In the case
of methods, whether an exception is thrown is allowed to depend on the
arguments, as long as calling the method with the same arguments will
always either throw or not throw.

The `Nothing` value, when used with `[DependsOn]` values other than
`Everything`, can used by the JIT to perform loop-hoisting and common
subexpression elimination on the return values of IDL attributes and
methods, as well as code motion past DOM methods that might depend on
system state but have no side effects.

### `[Pure]`

This is an alias for `[Affects=Nothing, DependsOn=DOMState]`.
Attributes/methods flagged in this way promise that they will keep
returning the same value as long as nothing that has
`[Affects=Everything]` executes.

### `[Constant]`

This is an alias for `[Affects=Nothing, DependsOn=Nothing]`. Used to
flag readonly attributes or methods that could have been annotated with
`[Pure]` and also always return the same value. This should only be
used when it's absolutely guaranteed that the return value of the
attribute getter will always be the same from the JS engine's point of
view.

The spec's `[SameObject]` extended attribute is an alias for
`[Constant]`, but can only be applied to things returning objects,
whereas `[Constant]` can be used for any type of return value.

### `[NeedResolve]`

Used to flag interfaces which have a custom resolve hook. This
annotation will cause the `DoResolve` method to be called on the
underlying C++ class when a property lookup happens on the object. The
signature of this method is:
`bool DoResolve(JSContext*, JS::Handle<JSObject*>, JS::Handle<jsid>, JS::MutableHandle<JS::Value>)`.
Here the passed-in object is the object the property lookup is happening
on (which may be an Xray for the actual DOM object) and the jsid is the
property name. The value that the property should have is returned in
the `MutableHandle<Value>`, with `UndefinedValue()` indicating that
the property does not exist.

If this extended attribute is used, then the underlying C++ class must
also implement a method called `GetOwnPropertyNames` with the
signature
`void GetOwnPropertyNames(JSContext* aCx, nsTArray<nsString>& aNames, ErrorResult& aRv)`.
This method will be called by the JS engine's enumerate hook and must
provide a superset of all the property names that `DoResolve` might
resolve. Providing names that `DoResolve` won't actually resolve is
OK.

(headerfile-path-to-headerfile-h)=

### `[HeaderFile="path/to/headerfile.h"]`

Indicates where the implementation can be found. Similar to the
headerFile annotation in Bindings.conf. Just like headerFile in
Bindings.conf, should be avoided.

### `[JSImplementation="@mozilla.org/some-contractid;1"]`

Used on an interface to provide the contractid of the [JavaScript
component implementing the
interface](#implementing-webidl-using-javascript).

### `[StoreInSlot]`

Used to flag attributes that can be gotten very quickly from the JS
object by the JIT. Such attributes will have their getter called
immediately when the JS wrapper for the DOM object is created, and the
returned value will be stored directly on the JS object. Later gets of
the attribute will not call the C++ getter and instead use the cached
value. If the value returned by the attribute needs to change, the C++
code should call the `ClearCachedFooValue` method in the namespace of
the relevant binding, where `foo` is the name of the attribute. This
will immediately call the C++ getter and cache the value it returns, so
it needs a `JSContext` to work on. This extended attribute can only be
used on attributes whose getters are [`[Pure]`](#pure) or
[`[Constant]`](#constant) and which are not
[`[Throws]`](#throws-getterthrows-setterthrows) or [`[GetterThrows]`](#throws-getterthrows-setterthrows).

So for example, given this IDL:

``` webidl
interface MyInterface {
  [Pure, StoreInSlot] attribute long myAttribute;
};
```

the C++ implementation of MyInterface would clear the cached value by
calling
`mozilla::dom::MyInterface_Binding::ClearCachedMyAttributeValue(cx, this)`.
This function will return false on error and the caller is responsible
for handling any JSAPI exception that is set by the failure.

If the attribute is not readonly, setting it will automatically clear
the cached value and reget it again before the setter returns.

### `[Cached]`

Used to flag attributes that, when their getter is called, will cache
the returned value on the JS object. This can be used to implement
attributes whose value is a sequence or dictionary (which would
otherwise end up returning a new object each time and hence not be
allowed in Web IDL).

Unlike [`[StoreInSlot]`](#storeinslot) this does _not_ cause the
getter to be eagerly called at JS wrapper creation time; the caching is
lazy. `[Cached]` attributes must be [`[Pure]`](#pure) or
[`[Constant]`](#constant), because otherwise not calling the C++
getter would be observable, but are allowed to have throwing getters.
Their cached value can be cleared by calling the `ClearCachedFooValue`
method in the namespace of the relevant binding, where `foo` is the
name of the attribute. Unlike `[StoreInSlot]` attributes, doing so
will not immediately invoke the getter, so it does not need a
`JSContext`.

So for example, given this IDL:

``` webidl
interface MyInterface {
  [Pure, Cached] attribute long myAttribute;
};
```

the C++ implementation of MyInterface would clear the cached value by
calling
`mozilla::dom::MyInterface_Binding::ClearCachedMyAttributeValue(this)`.
JS-implemented Web IDL can clear the cached value by calling
`this.__DOM_IMPL__._clearCachedMyAttributeValue()`.

If the attribute is not readonly, setting it will automatically clear
the cached value.

### `[Frozen]`

Used to flag attributes that, when their getter is called, will call
[`Object.freeze`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze)
on the return value before returning it. This extended attribute is only
allowed on attributes that return sequences, dictionaries and
`MozMap`, and corresponds to returning a frozen `Array` (for the
sequence case) or `Object` (for the other two cases).

### `[BinaryName]`

`[BinaryName]` can be specified on method or attribute to change the
C++ function name that will be used for the method or attribute. It
takes a single string argument, which is the name you wish the method or
attribute had instead of the one it actually has.

For example, given this IDL:

``` webidl
interface InterfaceWithRenamedThings {
  [BinaryName="renamedMethod"]
  undefined someMethod();
  [BinaryName="renamedAttribute"]
  attribute long someAttribute;
};
```

the corresponding C++ would be:

``` cpp
class InterfaceWithRenamedThings
{
public:
  void RenamedMethod();
  int32_t RenamedAttribute();
  void SetRenamedAttribute(int32_t);
};
```

### `[Deprecated="tag"]`

When deprecating an interface or method, the `[Deprecated]` annotation
causes the Web IDL compiler to insert code that generates deprecation
warnings. This annotation can be added to interface methods or
interfaces. Adding this to an interface causes a warning to be issued
the first time the object is constructed, or any static method on the
object is invoked.

The complete list of valid deprecation tags is maintained in
[nsDeprecatedOperationList.inc](https://searchfox.org/firefox-main/source/dom/base/nsDeprecatedOperationList.inc).
Each new tag requires that a localized string be defined, containing the
deprecation message to display.

### `[CrossOriginReadable]`

Used to flag an attribute that, when read, will not have the same-origin
constraint tested: it can be read from a context with a different
origin.

### `[CrossOriginWrite]`

Used to flag an attribute that, when written, will not have the
same-origin constraint tested: it can be written from a context with a
different origin.

### `[CrossOriginCallable]`

Used to flag a method that, when called, will not have the same-origin
constraint tested: it can be called from a context with a different
origin.

### `[SecureContext]`

We implement the [standard extended
attribute](https://webidl.spec.whatwg.org/#SecureContext) with a few
details specific to Gecko:

- System principals are considered secure.
- An extension poking at non-secured DOM objects will see APIs marked
  with `[SecureContext]`.
- XPConnect sandboxes don't see `[SecureContext]` APIs, except if
  they're created with `isSecureContext: true`.

### `[NeedsSubjectPrincipal]`, `[GetterNeedsSubjectPrincipal]`, `[SetterNeedsSubjectPrincipal]`

Used to flag a method or an attribute that needs to know the subject
principal. This principal will be passed as argument. The argument
will be a `nsIPrincipal&` because a subject principal is always
available.

`[NeedsSubjectPrincipal]` applies to both methods and attributes; for
attributes it means both the getter and the setter need a subject
principal. `[GetterNeedsSubjectPrincipal]` applies only to attributes.
`[SetterNeedsSubjectPrincipal]` applies only to non-readonly
attributes.

These attributes may also be constrained to non-system principals using
`[{Getter,Setter,}NeedsSubjectPrincipal=NonSystem]`. This changes the argument
type to `nsIPrincipal*`, and passes `nullptr` when called with a system
principal.

### `[NeedsCallerType]`

Used to flag a method or an attribute that needs to know the caller
type, in the `mozilla::dom::CallerType` sense. This can be safely
used for APIs exposed in workers; there it will indicate whether the
worker involved is a `ChromeWorker` or not. At the moment the only
possible caller types are `System` (representing system-principal
callers) and `NonSystem`.

### `[GenerateInit]`

When set on a dictionary it will add two `Init` methods to the generated C++
class with the following signatures:

``` cpp
bool Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription="Value", bool passedToJSImpl=false);
bool Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription="Value", bool passedToJSImpl=false);
```

These methods will initialize the dictionary from `val` by following WebIDL's
[JavaScript type mapping](https://webidl.spec.whatwg.org/#js-dictionary).

### `[GenerateInitFromJSON]`

When set on a dictionary it will add `Init` methods to the generated C++
class with the following signatures:

``` cpp
bool Init(const nsAString& aJSON);
bool Init(const nsACString& aJSON);
```

This extended attribute will only have an effect if all of the types of the
dictionary's members are representable in JSON (they are a string type, a
primitive type that's not an unrestricted float/double, a void type, or a
sequence, union, dictionary or record containing these types).

The method is expected to be called with a JSON string as input. The JSON string
will be parsed into a JavaScript value, and then the dictionary is initialized
with this value by following WebIDL's
[JavaScript type mapping](https://webidl.spec.whatwg.org/#js-dictionary).

Note: As a side-effect of how this is implemented it will also add the two
`Init` methods that would be added by a [`[GenerateInit]`](#generateinit)
extended attribute.

### `[GenerateToJSON]`

When set on a dictionary it will add `ToJSON` methods to the generated C++
class with the following signatures:

``` cpp
bool ToJSON(nsAString& aJSON);
bool ToJSON(nsACString& aJSON);
```

The method will generate a JSON representation of the dictionary members' values
in `aJSON` by converting the dictionary to a JavaScript object by following
WebIDL's [JavaScript type mapping](https://webidl.spec.whatwg.org/#js-dictionary)
and then converting that object to a JSON string.

The same restrictions on types applies as on
[`[GenerateInitFromJSON]`](#generateinitfromjson).

Note: As a side-effect of how this is implemented it will also add the
`ToObjectInternal` method that would be added by a
[`[GenerateConversionToJS]`](#generateconversiontojs) extended attribute.

### `[GenerateConversionToJS]`

When set on a dictionary it will add a `ToObjectInternal` method to the
generated C++ class with the following signature:

``` cpp
bool ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval);
```

The method will create a JavaScript object by following WebIDL's
[JavaScript type mapping](https://webidl.spec.whatwg.org/#js-dictionary).

### `[GenerateEqualityOperator]`

When set on a dictionary it will add an equality operator to the generated C++
class.

This is only allowed on dictionaries who only have members (own or inherited)
with string, primitive or enum types.

### `[Unsorted]`

When set on a dictionary the dictionary's members will not be sorted in
lexicographic order (which is specified by WebIDL).

This should only ever be used on internal APIs that are not exposed to the Web!

### `[ReflectedHTMLAttributeReturningFrozenArray]`

Used to flag a HTML reflected IDL attribute as having a `FrozenArray<T>?` type,
where `T` is either `Element` or an interface that inherits from `Element`. This
should only be used to implement the algorithms for that kind of reflected IDL
attributes.

When this attribute's getter is called, it will cache the JS reflection of the
returned value on the JS object. The C++ getter will be passed an additional
`bool*` argument before the result argument. If this argument is not `null` then
the implementation is supposed to set the `bool` that this argument is pointing
to to whether the
[attr-associated elements](https://html.spec.whatwg.org/#attr-associated-elements)
and the
[cached attr-associated elements](https://html.spec.whatwg.org/#cached-attr-associated-elements)
are equal. If it is not `null`, and the getter sets the pointee to `true` then
the cached JS value will be returned, and the result value from the C++ getter
will be ignored (so there is no need to set the result's value). If it is
`null`, or the getter sets the pointee to `false`, then the cached value will be
set to the JS reflection of the result value from the C++ getter, and that JS
value will then be returned.

Note that this will not cause the JIT to directly get the cached value from the
slot (as `[StoreInSlot]` or `[Cached]` would). The setter will also not clear
the cached value from the slot.

For example, this IDL:

``` webidl
interface Element {
  [Frozen, ReflectedHTMLAttributeReturningFrozenArray]
  attribute sequence<Element>? reflectedHTMLAttribute;
};
```

will require the following declarations in `Element`:

``` cpp
class Element {
  // …
  void GetReflectedHTMLAttribute(
    bool* aUseCachedValue, Nullable<nsTArray<RefPtr<Element>>>& aResult);
  void SetReflectedHTMLAttribute(
    const Nullable<Sequence<OwningNonNull<Element>>>& aValue);
};
```

## Helper objects

The C++ side of the bindings uses a number of helper objects.

(nullable-t)=

### `Nullable<T>`

`Nullable<>` is a struct declared in
[`Nullable.h`](https://searchfox.org/firefox-main/source/dom/bindings/Nullable.h)
and exported to `mozilla/dom/Nullable.h` that is used to represent
nullable values of types that don't have a natural way to represent
null.

`Nullable<T>` has an `IsNull()` getter that returns whether null is
represented and a `Value()` getter that returns a `const T&` and can
be used to get the value when it's not null.

`Nullable<T>` has a `SetNull()` setter that sets it as representing
null and two setters that can be used to set it to a value:
`void SetValue(T)` (for setting it to a given value) and
`T& SetValue()` for directly modifying the underlying `T&`.

(optional-t)=

### `Optional<T>`

`Optional<>` is a struct declared in
[`BindingDeclarations.h`](https://searchfox.org/firefox-main/source/dom/bindings/BindingDeclarations.h)
and exported to `mozilla/dom/BindingDeclarations.h` that is used to
represent optional arguments and dictionary members, but only those that
have no default value.

`Optional<T>` has a `WasPassed()` getter that returns true if a
value is available. In that case, the `Value()` getter can be used to
get a `const T&` for the value.

(nonnull-t)=

### `NonNull<T>`

`NonNull<T>` is a struct declared in
[`BindingUtils.h`](https://searchfox.org/firefox-main/source/dom/bindings/BindingUtils.h)
and exported to `mozilla/dom/BindingUtils.h` that is used to represent
non-null C++ objects. It has a conversion operator that produces `T&`.

(owningnonnull-t)=

### `OwningNonNull<T>`

`OwningNonNull<T>` is a struct declared in
[`OwningNonNull.h`](https://searchfox.org/firefox-main/source/xpcom/base/OwningNonNull.h)
and exported to `mozilla/OwningNonNull.h` that is used to represent
non-null C++ objects and holds a strong reference to them. It has a
conversion operator that produces `T&`.

### Typed arrays, arraybuffers, array buffer views

`TypedArray.h` is exported to `mozilla/dom/TypedArray.h` and exposes
structs that correspond to the various typed array types, as well as
`ArrayBuffer` and `ArrayBufferView`, all in the `mozilla::dom`
namespace. Each struct has a `Data()` method that returns a pointer to
the relevant type (`uint8_t` for `ArrayBuffer` and
`ArrayBufferView`) and a `Length()` method that returns the length
in units of `*Data()`. So for example, `Int32Array` has a `Data()`
returning `int32_t*` and a `Length()` that returns the number of
32-bit ints in the array.

By default, the generated bindings reject typed arrays, `ArrayBuffer`,
and `ArrayBufferView` objects larger than 2 GB. To allow larger buffers,
use the [`[AllowLarge]`](#allowlarge) extended attribute.

(sequence-t)=

### `Sequence<T>`

`Sequence<>` is a type declared in
[`BindingDeclarations.h`](https://searchfox.org/firefox-main/source/dom/bindings/BindingDeclarations.h)
and exported to `mozilla/dom/BindingDeclarations.h` that is used to
represent sequence arguments. It's some kind of typed array, but which
exact kind is opaque to consumers. This allows the binding code to
change the exact definition (e.g., to use auto arrays of different sizes
and so forth) without having to update all the callees.

### `CallbackFunction`

`CallbackFunction` is a type declared in
[CallbackFunction.h](https://searchfox.org/firefox-main/source/dom/bindings/CallbackFunction.h)
and exported to `mozilla/dom/CallbackFunction.h` that is used as a
common base class for all the generated callback function
representations. This class inherits from `nsISupports`, and consumers
must make sure to cycle-collect it, since it keeps JS objects alive.

### `CallbackInterface`

`CallbackInterface` is a type declared in
[CallbackInterface.h](https://searchfox.org/firefox-main/source/dom/bindings/CallbackInterface.h)
and exported to `mozilla/dom/CallbackInterface.h` that is used as a
common base class for all the generated callback interface
representations. This class inherits from `nsISupports`, and consumers
must make sure to cycle-collect it, since it keeps JS objects alive.

### `DOMString`

`DOMString` is a class declared in
[BindingDeclarations.h](https://searchfox.org/firefox-main/source/dom/bindings/BindingDeclarations.h)
and exported to `mozilla/dom/BindingDeclarations.h` that is used for
Web IDL `DOMString` return values. It has a conversion operator to
`nsString&` so that it can be passed to methods that take that type or
`nsAString&`, but callees that care about performance, have an
`StringBuffer` available, and promise to hold on to the
`StringBuffer` at least until the binding code comes off the stack
can also take a `DOMString` directly for their string return value and
call its `SetStringBuffer` method with the `StringBuffer` and its
length. This allows the binding code to avoid extra reference-counting
of the string buffer in many cases, and allows it to take a faster
codepath even if it does end up having to addref the `StringBuffer`.

### `GlobalObject`

`GlobalObject` is a class declared in
[BindingDeclarations.h](https://searchfox.org/firefox-main/source/dom/bindings/BindingDeclarations.h)
and exported to `mozilla/dom/BindingDeclarations.h` that is used to
represent the global object for static attributes and operations
(including constructors). It has a `Get()` method that returns the
`JSObject*` for the global and a `GetAsSupports()` method that
returns an `nsISupports*` for the global on the main thread, if such
is available. It also has a `Context()` method that returns the
`JSContext*` the call is happening on. A caveat: the compartment of
the `JSContext` may not match the compartment of the global!

### `Date`

`Date` is a class declared in
[BindingDeclarations.h](https://searchfox.org/firefox-main/source/dom/bindings/BindingDeclarations.h)
and exported to `mozilla/dom/BindingDeclarations.h` that is used to
represent Web IDL Dates. It has a `TimeStamp()` method returning a
double which represents a number of milliseconds since the epoch, as
well as `SetTimeStamp()` methods that can be used to initialize it
with a double timestamp or a JS `Date` object. It also has a
`ToDateObject()` method that can be used to create a new JS `Date`.

### `ErrorResult`

`ErrorResult` is a class declared in
[ErrorResult.h](https://searchfox.org/firefox-main/source/dom/bindings/ErrorResult.h)
and exported to `mozilla/ErrorResult.h` that is used to represent
exceptions in Web IDL bindings. This has the following methods:

- `Throw`: allows throwing an `nsresult`. The `nsresult` must be
  a failure code.
- `ThrowTypeError`: allows throwing a `TypeError` with the given
  error message. The list of allowed `TypeError`s and corresponding
  messages is in
  [`dom/bindings/Errors.msg`](https://searchfox.org/firefox-main/source/dom/bindings/Errors.msg).
- `ThrowJSException`: allows throwing a preexisting JS exception
  value. However, the `MightThrowJSException()` method must be called
  before any such exceptions are thrown (even if no exception is
  thrown).
- `Failed`: checks whether an exception has been thrown on this
  `ErrorResult`.
- `ErrorCode`: returns a failure `nsresult` representing (perhaps
  incompletely) the state of this `ErrorResult`.
- `operator=`: takes an `nsresult` and acts like `Throw` if the
  result is an error code, and like a no-op otherwise (unless an
  exception has already been thrown, in which case it asserts). This
  should only be used for legacy code that has nsresult everywhere; we
  would like to get rid of this operator at some point.

## Events

Simple `Event` interfaces can be automatically generated by adding the
interface file to GENERATED_EVENTS_WEBIDL_FILES in the
appropriate dom/webidl/moz.build file. You can also take a simple
generated C++ file pair and use it to build a more complex event (i.e.,
one that has methods).

### Event handler attributes

A lot of interfaces define event handler attributes, like:

``` webidl
attribute EventHandler onthingchange;
```

If you need to implement an event handler attribute for an interface, in
the definition (header file), you use the handy
"IMPL_EVENT_HANDLER" macro:

``` cpp
IMPL_EVENT_HANDLER(onthingchange);
```

The "onthingchange" needs to be added to the StaticAtoms.py file:

``` py
Atom("onthingchange", "onthingchange")
```

The actual implementation (.cpp) for firing the event would then look
something like:

``` cpp
nsresult
MyInterface::DispatchThingChangeEvent()
{
  NS_NAMED_LITERAL_STRING(type, "thingchange");
  EventInit init;
  init.mBubbles = false;
  init.mCancelable = false;
  RefPtr<Event> event = Event::Constructor(this, type, init);
  event->SetTrusted(true);
  ErrorResult rv;
  DispatchEvent(*event, rv);
  return rv.StealNSResult();  // Assuming the caller cares about the return code.
}
```

(bindings-conf-details)=

## `Bindings.conf` details

Write me. In particular, need to describe at least use of `concrete`,
`prefable`, and `addExternalInterface`.

### How to get a JSContext passed to a given method

In some rare cases you may need a `JSContext*` argument to be passed
to a C++ method that wouldn't otherwise get such an argument. To see how
to achieve this, search for `implicitJSContext` in
[dom/bindings/Bindings.conf](#bindings-conf-details).

(implementing-webidl-using-javascript)=

## Implementing Web IDL using Javascript

<div class="warning"><div class="admonition-title">Warning</div>

Implementing Web IDL using Javascript is deprecated. New interfaces
should always be implemented in C++!

</div>

It is possible to implement Web IDL interfaces in JavaScript within Gecko
-- however, **this is limited to interfaces that are not exposed in Web
Workers**. When the binding occurs, two objects are created:

- _Content-exposed object:_ what gets exposed to the web page.
- _Implementation object:_ running as a chrome-privileged script. This
  allows the implementation object to have various APIs that the
  content-exposed object does not.

Because there are two types of objects, you have to be careful about
which object you are creating.

### Creating JS-implemented Web IDL objects

To create a JS-implemented Web IDL object, one must create both the
chrome-side implementation object and the content-side page-exposed
object. There are three ways to do this.

#### Using the Web IDL constructor

If the interface has a constructor, a content-side object can be created
by getting that constructor from the relevant content window and
invoking it. For example:

``` js
var contentObject = new contentWin.RTCPeerConnection();
```

The returned object will be an Xray wrapper for the content-side object.
Creating the object this way will automatically create the chrome-side
object using its contractID.

This method is limited to the constructor signatures exposed to
webpages. Any additional configuration of the object needs to be done
methods on the interface.

Creating many objects this way can be slow due to the createInstance
overhead involved.

#### Using a `_create` method

A content-side object can be created for a given chrome-side object by
invoking the static `_create` method on the interface. This method
takes two arguments: the content window in which to create the object
and the chrome-side object to use. For example:

``` js
var contentObject = RTCPeerConnection._create(contentWin, new
MyPeerConnectionImpl());
```

However, if you are in a JS component, you may only be able to get to
the correct interface object via some window object. In this case, the
code would look more like:

``` js
var contentObject = contentWin.RTCPeerConnection._create(contentWin,
new MyPeerConnectionImpl());
```

Creating the object this way will not invoke its `__init` method or
`init` method.

#### By returning a chrome-side object from a JS-implemented Web IDL method

If a JS-implemented Web IDL method is declared as returning a
JS-implemented interface, then a non-Web IDL object returned from that
method will be treated as the chrome-side part of a JS-implemented
WebIdL object and the content-side part will be automatically created.

Creating the object this way will not invoke its `__init` method or
`init` method.

### Implementing a Web IDL object in JavaScript

To implement a Web IDL interface in JavaScript, first add a Web IDL file,
in the same way as you would for a C++-implemented interface. To support
implementation in JS, you must add an extended attribute
`JSImplementation="CONTRACT_ID_STRING"` on your interface, where
CONTRACT_ID_STRING is the XPCOM component contract ID of the JS
implementation -- note ";1" is just a Mozilla convention for versioning
APIs. Here's an example:

``` webidl
[JSImplementation="@mozilla.org/my-number;1"]
interface MyNumber {
  constructor(optional long firstNumber);
  attribute long value;
  readonly attribute long otherValue;
  undefined doNothing();
};
```

Next, create an XPCOM component that implements this interface. Use
the same contract ID as you specified in the Web IDL file. The class
ID doesn't matter, except that it should be a newly generated one. For
`QueryInterface`, you only need to implement `nsISupports`, not
anything corresponding to the Web IDL interface. The name you use for
the XPCOM component should be distinct from the name of the interface,
to avoid confusing error messages.

Web IDL attributes are implemented as properties on the JS object or its
prototype chain, whereas Web IDL methods are implemented as methods on
the object or prototype. Note that any other instances of the interface
that you are passed in as arguments are the full web-facing version of
the object, and not the JS implementation, so you currently cannot
access any private data.

The Web IDL constructor invocation will first create your object. If the
XPCOM component implements `nsIDOMGlobalPropertyInitializer`, then
the object's `init` method will be invoked with a single argument:
the content window the constructor came from. This allows the JS
implementation to know which content window it's associated with.
The `init` method should not return anything. After this, the
content-side object will be created. Then,if there are any constructor
arguments, the object's `__init` method will be invoked, with the
constructor arguments as its arguments.

### Static Members

Static attributes and methods are not supported on JS-implemented Web IDL
(see [bug
863952](https://bugzilla.mozilla.org/show_bug.cgi?id=863952)).
However, with the changes in [bug
1172785](https://bugzilla.mozilla.org/show_bug.cgi?id=1172785) you
can route static methods to a C++ implementation on another object using
a `StaticClassOverride` annotation. This annotation includes the
full, namespace-qualified name of the class that contains an
implementation of the named method. The include for that class must be
found in a directory based on its name.

``` webidl
[JSImplementation="@mozilla.org/dom/foo;1"]
interface Foo {
  [StaticClassOverride="mozilla::dom::OtherClass"]
  static Promise<undefined> doSomething();
};
```

Rather than calling into a method on the JS implementation; calling
`Foo.doSomething()` will result in calling
`mozilla::dom::OtherClass::DoSomething()`.

### Checking for Permissions or Preferences

With JS-implemented Web IDL, the `init` method should only return
undefined. If any other value, such as `null`, is returned, the
bindings code will assert or crash. In other words, it acts like it has
an "undefined" return type. Preference or permission checking should be
implemented by adding an extended attribute to the Web IDL interface.
This has the advantage that if the check fails, the constructor or
object will not show up at all.

For preference checking, add an extended attribute
`Pref="myPref.enabled"` where `myPref.enabled` is the preference
that should be checked. `SettingsLock` is an example of this.

For permissions or other kinds of checking, add an extended attribute
`Func="MyPermissionChecker"` where `MyPermissionChecker` is a
function implemented in C++ that returns true if the interface should be
enabled. This function can do whatever checking is needed. One example
of this is `PushManager`.

### Example

Here's an example JS implementation of the above interface. The
`invisibleValue` field will not be accessible to web content, but is
usable by the doNothing() method.

``` js
function MyNumberInner() {
  this.value = 111;
  this.invisibleValue = 12345;
}

MyNumberInner.prototype = {
  classDescription: "Get my number XPCOM Component",
  contractID: "@mozilla.org/my-number;1",
  QueryInterface: ChromeUtils.generateQI([]),
  doNothing: function() {},
  get otherValue() { return this.invisibleValue - 4; },
  __init: function(firstNumber) {
    if (arguments.length > 0) {
      this.value = firstNumber;
    }
  }
}
```

Finally, add a component and a contract and whatever other manifest
stuff you need to implement an XPCOM component.

### Guarantees provided by bindings

When implementing a Web IDL interface in JavaScript, certain guarantees
will be provided by the binding implementation. For example, string or
numeric arguments will actually be primitive strings or numbers.
Dictionaries will contain only the properties that they are declared to
have, and they will have the right types. Interface arguments will
actually be objects implementing that interface.

What the bindings will NOT guarantee is much of anything about
`object` and `any` arguments. They will get cross-compartment
wrappers that make touching them from chrome code not be an immediate
security bug, but otherwise they can have quite surprising behavior if
the page is trying to be malicious. Try to avoid using these types if
possible.

### Accessing the content object from the implementation

If the JS implementation of the Web IDL interface needs to access the
content object, it is available as a property called `__DOM_IMPL__` on
the chrome implementation object. This property only appears after the
content-side object has been created. So it is available in `__init`
but not in `init`.

### Determining the principal of the caller that invoked the Web IDL API

This can be done by calling
`Component.utils.getWebIDLCallerPrincipal()`.

### Throwing exceptions from JS-implemented APIs

There are two reasons a JS implemented API might throw. The first reason
is that some unforeseen condition occurred and the second is that a
specification requires an exception to be thrown.

When throwing for an unforeseen condition, the exception will be
reported to the console, and a sanitized NS_ERROR_UNEXPECTED exception
will be thrown to the calling content script, with the file/line of the
content code that invoked your API. This will avoid exposing chrome URIs
and other implementation details to the content code.

When throwing because a specification requires an exception, you need to
create the exception from the window your Web IDL object is associated
with (the one that was passed to your `init` method). The binding code
will then rethrow that exception to the web page. An example of how
this could work:

``` js
if (!isValid(passedInObject)) {
  throw new this.contentWindow.TypeError("Object is invalid");
}
```

or

``` js
if (!isValid(passedInObject)) {
  throw new this.contentWindow.DOMException("Object is invalid", "InvalidStateError");
}
```

depending on which exact exception the specification calls for throwing
in this situation.

In some cases you may need to perform operations whose exception message
you just want to propagate to the content caller. This can be done like
so:

``` js
try {
  someOperationThatCanThrow();
} catch (e) {
  throw new this.contentWindow.Error(e.message);
}
```

### Inheriting from interfaces implemented in C++

It's possible to have an interface implemented in JavaScript inherit
from an interface implemented in C++. To do so, simply have one
interface inherit from the other and the bindings code will
auto-generate a C++ object inheriting from the implementation of the
parent interface. The class implementing the parent interface will need
a constructor that takes an `nsPIDOMWindow*` (though it doesn't have
to do anything with that argument).

If the class implementing the parent interface is abstract and you want
to use a specific concrete class as the implementation to inherit from,
you will need to add a `defaultImpl` annotation to the descriptor for
the parent interface in `Bindings.conf`. The value of the annotation
is the C++ class to use as the parent for JS-implemented descendants; if
`defaultImpl` is not specified, the `nativeType` will be used.

For example, consider this interface that we wish to implement in
JavaScript:

``` webidl
[JSImplementation="some-contract"]
interface MyEventTarget : EventTarget {
  attribute EventHandler onmyevent;
  undefined dispatchTheEvent(); // Sends a "myevent" event to this EventTarget
}
```

The implementation would look something like this, ignoring most of the
XPCOM boilerplate:

``` js
function MyEventTargetImpl() {
}
MyEventTargetImpl.prototype = {
  // QI to nsIDOMGlobalPropertyInitializer so we get init() called on us.
  QueryInterface: ChromeUtils.generateQI(["nsIDOMGlobalPropertyInitializer"]),

  init: function(contentWindow) {
    this.contentWindow = contentWindow;
  },

  get onmyevent() {
    return this.__DOM_IMPL__.getEventHandler("onmyevent");
  },

  set onmyevent(handler) {
    this.__DOM_IMPL__.setEventHandler("onmyevent", handler);
  },

  dispatchTheEvent: function() {
    var event = new this.contentWindow.Event("myevent");
    this.__DOM_IMPL__.dispatchEvent(event);
  },
};
```

The implementation would automatically support the API exposed on
`EventTarget` (so, for example, `addEventListener`). Calling the
`dispatchTheEvent` method would cause dispatch of an event that
content script can see via listeners it has added.

Note that in this case the chrome implementation is relying on some
`[ChromeOnly]` methods on EventTarget that were added specifically to
make it possible to easily implement event handlers. Other cases can do
similar things as needed.

---

### Dom Docs WorkersAndStorage Index (`dom/docs/workersAndStorage/index.md`)

# DOM Workers & Storage

These linked pages contain design documents for the Workers & Storage implementations in Gecko. They live in-tree under the 'dom/docs/workerAndStorage' directory.

```{toctree}
:maxdepth: 1

CodeStyle
PerformanceTesting
WorkerLifeCycleAndWorkerRefs
```

---

### Dom Media Docs Index (`dom/media/docs/index.md`)

# Media Playback

```{toctree}
:maxdepth: 1

MediaFormatReader
review/index
AudioStream
AudioSinkWrapper
SpeechRecognition
```

---

### Browser App Desktop Launcher Docs Index (`browser/app/desktop-launcher/docs/index.md`)

# Desktop Launcher app

A substantial number of users will upgrade to Windows 11 in a way that leaves no trace of Firefox on their device. To address these cases we will leave
an install entry point in their personal files, which will migrate at a higher rate than the app itself. In particular, files in the Desktop folder are
backed up by OneDrive and other cloud storage products, and likely to find their way back onto a new device.

This app acts as a replacement for the desktop shortcut to Firefox.

When Firefox is installed on the user's machine, when the user launches this app, it finds the path to Firefox in the appropriate Windows Registry keys
and attempts to launch Firefox from that path.

When there is no Firefox installation found, this app will attempt to download and run the Firefox "stub" installer.

As a final fallback, this app will open the Firefox download URL in the default browser.

## What controls whether or not Desktop Launcher is installed?

At installation time:

- What kind of installer is this?
  : - Stub: install the launcher, do not install shortcuts
  - Full: Let the user decide whether to get launcher, shortcuts, both, or neither. (Currently the full installer can only select to install the launcher
    : using a command-line parameter. Eventually, there will be UI in the full installer. Work tracked by <https://bugzilla.mozilla.org/show_bug.cgi?id=1981597>)
  - Other (MSI, MSIX, zip): install shortcuts

At update time:
: - YES: Does this user already have the launcher installed?
    : - YES: Then update it with the new version.
      - NO: Is this a stub-installed package? (This is stored in `installation_telemetry.json`, see e.g. \[BrowserUsageTelemetry.sys.mjs\](<https://searchfox.org/firefox-main/rev/cd6acbe9eaa55fb4da4fbdec275db6eddd4833b8/browser/modules/BrowserUsageTelemetry.sys.mjs#1875-1904>))
        : - NO: Do nothing
            : - NO: Did we already install the launcher for the user?
                : - YES: Don't install. This is how we avoid re-installing the launcher after a user has removed it.
                  - NO: Does the user have a desktop shortcut that points to Firefox, either in their own Desktop or the public Desktop?
                    : - YES: Remove the shortcut and install the launcher into the user's Desktop folder.
                      - NO: Do nothing

In elevated installer, we will delete the public shortcut and record the event if:
: - It exists

- We haven't deleted it before
- This is a stub installed Firefox

In the unelevated installer, we will delete the user shortcut and record the event if:
: - There is a user shortcut (i.e. this is a personal install)

- We haven't deleted it before
- This is a stub installed Firefox

In the unelevated installer, we will install the desktop launcher and record the event if:
: - It is already installed OR
    : - It wasn't previously installed
      - There is or was a shortcut (shared or personal)
      - The installation type is "stub"

## FAQ

Q: I don't like the Desktop Launcher. How can I get rid of it?

A: Delete it from your Desktop folder. It won't be reinstalled by updates, even if you create a new Firefox shortcut there. (We remember that it was previously installed using a Windows registry key.)

---

### Browser App Installation Dir Layout Docs Index (`browser/app/installation_dir_layout/docs/index.md`)

# Installation Directory Layout

## Rationale

Firefox supports automatic downloading and applying of updates while the user is still using
the browser. However, once the update has been installed, files that the browser relies on
may have changed on disk, which caused the original implementation of update functionality to
force the user to restart the browser after updates. (See
\_this bug: <https://bugzilla.mozilla.org/show_bug.cgi?id=1891600> for details and discussion.)

In order to let users continue to use the browser after updates are applied, the updater needs
to leave in place the files associated with the running browser, for as long as the browser's process
exists.

The approach we are taking to enable this behavior is a new installation layout called "versioned install directories".
What this involves is:

- Under the "base" install directory, there will be one or more "versioned" install directories,
  with names based on the version of Firefox installed in them.
- Each versioned directory contains a complete installation of Firefox at the approapriate version.
- In the base install directory, there will be a launcher exectuable that launches the Firefox
  : executable in the appropriate versioned directory for the current Firefox version,

Example of "single" layout

This process allows all of the file resolution in Firefox to remain unchanged (for example,
C:\\Program Files\\Mozilla Firefox\\136.0.1a\\firefox.exe will load libraries from the directory
C:\\Program Files\\Mozilla Firefox\\136.0.1a\\). Most code will have no need to be aware of the change.

However, when applying updates to an installation,
the updater needs to know if it should:
\- apply updates to a "single" install directory, and leave a single install directory in place (current behavior)
\- apply updates to a single install directory, and migrate it to be a versioned install
\- apply updates to a versioned install directory, using the new versioned install behavior

This means that the updater needs a way to know unambiguously whether an installation
is using a single or versioned layout. This is the functionality provided by this module.

## Module contents

The installation_dir_layout module provides two different implementations of a library `installation_dir_layout.dll`

This library has a single function, `GetInstallationDirLayoutType`, which returns an enumerated type.

The implementation of `installation_dir_layout.dll` in the `single` directory returns `InstallationDirLayoutType::Single`
The implementation of `installation_dir_layout.dll` in the `versioned` directory returns `InstallationDirLayoutType::Versioned`

The interface for both implementations is specified in InstallationDirLayout.h

## DLL installation

When Firefox is installed or updated, the installer or updater will choose the appropriate version of `installation_dir_layout.dll`
to install. This version will be available to firefox.exe and its supporting utilities as a runtime library.

## DLL usage

Code that needs to know about the installation directory layout (such as updater and uninstaller) will load the installed
version of the DLL and call `GetInstallationDirLayoutType`.

---

### Browser App Pbproxy Docs Index (`browser/app/pbproxy/docs/index.md`)

# Private Browsing Proxy

On Windows, Firefox ships with a small binary that always launches
`firefox.exe` in Private Browsing mode (`private_browsing.exe`). Its sole
purpose for existing is to allow Private Browsing shortcuts to have their own
Visual Elements. This is most notably seen when pinning a Private Browsing
shortcut to the Start Menu -- Visual Elements are used for the icon there
rather than the shortcut's icon.

In addition to always passing `-private-window`, `private_browsing.exe`
will forward any other command line arguments given to it to `firefox.exe`.
It will also forward shortcut information from the Windows `STARTUPINFOW`
structure to ensure that Firefox knows how it was started.

---

### Browser Components Aboutwelcome Docs Index (`browser/components/aboutwelcome/docs/index.md`)

# Firefox Welcome Experience (<about:welcome>)

Files related to the Firefox welcome experience, which includes content that appears on `about:welcome`, can be found in the `browser/components/aboutwelcome` directory.
Some of these source files (such as `.js`, `.jsx`, and `.scss`) require an additional build step.
We are working on migrating this to work with `mach`, but in the meantime, please
follow the following steps if you need to make changes in this directory:

## For `.sys.mjs` files (system modules)

No build step is necessary. Use `mach` and run mochitests according to your regular Firefox workflow.

## For `.js`, `.jsx`, `.scss`, or `.css` files

### Prerequisites

You will need the following:

- Node.js 10+ (On Mac, the best way to install Node.js is to use the install link on the [Node.js homepage])
- npm (packaged with Node.js)

To install dependencies, run the following from the root of the mozilla-central repository.
(Using `mach` to call `npm` and `node` commands will ensure you're using the correct versions of Node and npm.)

```shell
(cd browser/components/aboutwelcome && ../../../mach npm install)
```

### Which files should you edit?

You should not make changes to `.js` or `.css` files in the `browser/components/aboutwelcome/content` directory. Instead, you should edit the `.jsx`, `.js`, and `.scss` source files
in `browser/components/aboutwelcome/content-src` directory. These files will be compiled into the `.js` and `.css` files.

## Building assets and running Firefox

To build assets and run Firefox, run the following from the root of the mozilla-central repository:

```shell
./mach npm run bundle --prefix=browser/components/aboutwelcome && ./mach build && ./mach run
```

## Continuous development / debugging

Running `./mach npm run watchmc --prefix=browser/components/aboutwelcome` will start a process that watches files in
`aboutwelcome` and rebuilds the bundled files when JS or CSS files change.

**IMPORTANT NOTE**: This task will add inline source maps to help with debugging, which changes the memory footprint.
Do not use the `watchmc` task for profiling or performance testing!

## Running tests

<About:welcome> unit tests are written using
[mocha](https://mochajs.org), and other errors that may show up there are
[SCSS](https://sass-lang.com/documentation/syntax) issues flagged by
[stylelint](https://stylelint.io). These things are all run using
`npm test` under the `aboutwelcome` slug in Treeherder/Try, so if that slug turns
red, these tests are what is failing. To execute them, do this:

```shell
./mach npm test --prefix=browser/components/aboutwelcome
```

Windows isn't currently supported by `npm test`
([path/invocation difference](https://bugzilla.mozilla.org/show_bug.cgi?id=1737419)).
To run tests that aren't covered by `mach lint` and
`mach test`:

```shell
./mach npm run lint:stylelint --prefix=browser/components/aboutwelcome
./mach npm run testmc:build --prefix=browser/components/aboutwelcome
./mach npm run testmc:unit --prefix=browser/components/aboutwelcome
```

Mochitests run normally, using `mach test browser/components/aboutwelcome`.

## Code Coverage

Our testing setup will run code coverage tools in addition to just the unit
tests. It will error out if the code coverage metrics don't meet certain thresholds.

If you see any missing test coverage, you can inspect the coverage report by
running

```shell
./mach npm test --prefix=browser/components/aboutwelcome &&
./mach npm run debugcoverage --prefix=browser/components/aboutwelcome
```

[node.js homepage]: https://nodejs.org/

---

### Browser Components Asrouter Docs Index (`browser/components/asrouter/docs/index.md`)

# Messaging System

## Vision

Firefox must be an opinionated user agent that keeps folks safe, informed and
effective while browsing the Web. In order to have an opinion, Firefox must
have a voice.

That voice will **respect the user’s attention** while surfacing contextually
relevant and timely information tailored to their individual needs and choices.

## What does Messaging System support?

There are several key windows of opportunity, such as the first-run activation
phase or coordinated feature releases, where Firefox engages with users.

The Firefox Messaging System supports this engagement by targeting messages
exactly to the users who need to see them and enables the development of new
user messages that can be easily tested and deployed. It offers standard
mechanisms to measure user engagement and to perform user messaging experiments
with reduced effort across engineering teams and a faster delivery cycle from
ideation to analysis of results.

This translates to **users seeing fewer and more relevant in-product
messages**, while supporting fast delivery, experimentation, and protection of
our users time and attention.

## Messaging System Overview

At the core of the Firefox Messaging System is the Messaging System Router
(called ASRouter for historical reasons). The router is a generalized Firefox
component and set of conventions that provides:

- Flexible and configurable routing of local or remote Messages to UI
  Templates. This allows new message campaigns to be started and controlled
  on or off-trains
- Traffic Cop message sequencing and intermediation to prevent multiple
  messages being concurrently shown
- Programmable message targeting language to show the right message to the
  right user at the right time
- A template library of reusable Message and Notification UIs
- Full compatibility with Normandy pref-flip experiments
- Generalized and privacy conscious event telemetry
- Flexible Frequency Capping to mitigate user message fatigue
- Localized off train Messages
- Powerful development/debugging/QA tools on <about:asrouter>

## Message Routing

```{image} ./message-routing-overview.png
:align: center
:alt: Message Routing Overview
```

The Firefox Messaging System implements a separation-of-concerns pattern for
Messages, UI Templates, and Timing/Targeting mechanisms. This allows us to
maintain a high standard of security and quality while still allowing for
maximum flexibility around content creation.

## UI Templates

We have built a library of reusable Notification and Message interfaces which
land in the Firefox codebase and ride the trains. These templates have a
defined schema according to the available design components (e.g. titles, text,
icons) and access to a set of enhanced user actions such as triggering URLs,
launching menus, or installing addons, which can be attached to interactive
elements (such as buttons).

Warning! Before reading, you should consider whether a [Messaging Experiment is relevant for your needs](https://docs.google.com/document/d/1S45a_nFn8QRM8gvsxCM6HHROrIQlQQl6fUlJ2j63PGI/edit).

Current templates include:

% In theory, we ought to be able to use the :glob: directive here to

% automatically generate the list below. For unknown reasons, however,

% `mach doc` _sometimes_ gets confused and refuses to find patterns like

% `*.md`.

```{toctree}
:maxdepth: 1

action-only
moments-page
feature-callout
about-welcome
infobars
spotlight
private-browsing
multi-message
menu-message
sidebar-chatbot-promo
```

## Detailed Docs

- Explore key terms in the [Messaging System Glossary](./messaging-glossary.md).

- Learn which actions, triggers, and context properties work on which surfaces in [Messaging Surface Compatibility](./messaging-surfaces.md).

- Learn more about messaging experimentation through [Nimbus](https://experimenter.info/) in the [Messaging System: Experimenter Onboarding](https://mozilla-hub.atlassian.net/wiki/spaces/FIREFOX/pages/233406786/OMC+Experimenter+Onboarding).

- [Messaging system schemas]

- [User actions]

- [Triggers]

% In theory, we ought to be able to use the :glob: directive here to

% automatically generate the list below. For unknown reasons, however,

% `mach doc` _sometimes_ gets confused and refuses to find patterns like

% `*.md`.

```{toctree}
:maxdepth: 2

asrouter-newtab-message
asrouter-newtab-multistage-message
building-and-testing
debugging-docs
frequency-caps
first-run
messaging-glossary
messaging-surfaces
remote_cfr
targeting-attributes
targeting-guide
telemetry
skylight
```

[messaging system schemas]: https://firefox-source-docs.mozilla.org/toolkit/components/messaging-system/docs/index.html#messaging-system-schemas
[triggers]: https://firefox-source-docs.mozilla.org/toolkit/components/messaging-system/docs/TriggerActionSchemas/index.html
[user actions]: https://firefox-source-docs.mozilla.org/toolkit/components/messaging-system/docs/SpecialMessageActionSchemas/index.html

---

### Browser Components Attribution Docs Index (`browser/components/attribution/docs/index.md`)

# Installation Attribution

*Installation Attribution* is a system that allows us to do a few things:

- Gauge the success of marketing campaigns
- Determine (roughly) the origin of an installer that a user ran
- Support the Return to AMO workflow.

We accomplish these things by adding an *attribution code* to Firefox installers which generally contains information supplied by <https://www.mozilla.org> (Bedrock and related services). This information is read by Firefox during and after installation, and sent back to Mozilla through Firefox Telemetry.

The following information is supported by this system:

- Traditional [UTM parameters](https://en.wikipedia.org/wiki/UTM_parameters) (*source*, *medium*, *campaign*, and *content*)
- *experiment*
- *variation*
- *ua*
- *dltoken*
- *dlsource*
- *msstoresignedin*
- *msclkid*

Descriptions of each of these can be found in {doc}`the Telemetry Environment documentation </toolkit/components/telemetry/data/environment>`.

## Firefox Windows Installers & macOS DMGs

Installs done through Windows stub or full NSIS installers or macOS DMGs are capable of being attributed. When these packages are created, they are given initial attribution data of *dlsource=mozillaci*. Users who download their package via <https://www.mozilla.org> will typically have this attribution data overwritten (unless they have Do-not-track (DNT) enabled), with *dlsource=mozorg*, a *dltoken*, and whatever UTM parameters Bedrock deems appropriate.

An additional complication here is that the attribution system is used (or abused, depending on your view) to support the Return to AMO workflow -- forcing the *campaign* and *content* UTM parameters to specific values.

The below diagram illustrates the flow of the cases above:

```
/* Detailed source-code truncated for AI context efficiency. */
```

### Windows

Windows attribution is implementing by injecting data into the signature block of NSIS installers at download time. This technique is described in the "Cheating Authenticode" section of [this Microsoft blog post](https://learn.microsoft.com/en-ca/archive/blogs/ieinternals/caveats-for-authenticode-code-signing#cheating-authenticode).

### macOS

macOS attribution is implemented by adding a `com.apple.application-instance` extended attribute to the `.app` bundle at download time. This special extended attribute is explicitly *not* part of the digital signature of the `.app` bundle as per [this Apple technical note](https://developer.apple.com/library/archive/technotes/tn2206/_index.html#//apple_ref/doc/uid/DTS40007919-CH1-TNTAG401).

## Microsoft Store

Firefox installs done through the Microsoft Store support extracting campaign IDs that may be embedded into them. This allows us to attribute installs through different channels by providing particular links to the Microsoft Store with attribution data included. For example:

`ms-windows-store://pdp/?productid=9NZVDKPMR9RD&cid=source%3Dgoogle.com%26medium%3Dorganic%26campaign%3D(not%20set)%26content%3D(not%20set)`

[https://www.microsoft.com/store/apps/9NZVDKPMR9RD?cid=source%3Dgoogle.com%26medium%3Dorganic%26campaign%3D(not%20set)%26content%3D(not%20set)](<https://www.microsoft.com/store/apps/9NZVDKPMR9RD?cid=source%3Dgoogle.com%26medium%3Dorganic%26campaign%3D(not%20set)%26content%3D(not%20set)>)

Microsoft Store Ads presents its Ads Campaign ID to installed applications as a uniquely formatted `storeBingAd_[uuid]`, for example `storeBingAd_45cbbf091fb541f0ae959d50ffb8c5b8`. Firefox records this as `msclkid=[uuid]`, for example `msclkid=45cbbf091fb541f0ae959d50ffb8c5b8` in installation attribution.

For more on how custom campaign IDs work in general in the Microsoft Store environment, [see Microsoft's documentation](https://docs.microsoft.com/en-us/windows/uwp/publish/create-a-custom-app-promotion-campaign).

The Microsoft Store provides a single `cid` (Campaign ID). Their documentation claims it is limited to 100 characters, although in our own testing we've been able to retrieve the first 208 characters of Campaign IDs. Firefox expects this Campaign ID to follow the same format as stub and full installer attribution codes, which have a maximum of length of 1010 characters. Since Campaign IDs are more limited than what Firefox allows, we need to be a bit more thoughtful about what we include in them vs. stub and full installer attribution. At the time of writing, we've yet to be able to test whether we can reliably pull more than the advertised 100 characters of a Campaign ID in the real world -- something that we should do before we send any crucial information past the first 100 characters.

In addition to the attribution data retrieved through the campaign ID, we also add an extra key to it to indicate whether or not the user was signed into the Microsoft Store when they installed. This `msstoresignedin` key can have a value of `true` or `false`.

There are a couple of other caveats to keep in mind:

- A campaign ID is only set the *first* time a user installs Firefox through the Store. Subsequent installs will inherit the original campaign ID (even if it was an empty string). This means that only brand new installs will be attributed -- not reinstalls.
- At the time of writing, it is not clear whether or not installs done without being signed into the Microsoft Store will be able to find their campaign ID. Microsoft's documentation claims they can, but our own testing has not been able to verify this.

---

### Browser Components Backup Docs Index (`browser/components/backup/docs/index.md`)

(components-backup)=

# Backup Component

The Backup Component is responsible for creating backups of user profile data
into a single file that can be easily restored from.

```{toctree}
:maxdepth: 3

architecture
backup-service
backup-resources
backup-ui-actors
archive-encryption
schemas
```

---

### Browser Components Customizableui Docs Index (`browser/components/customizableui/docs/index.md`)

(components-customizableui)=

# CustomizableUI Component

This component is responsible for managing and manipulating the default and
customized state of various UI surfaces in the browser. Most of the logic for
doing this resides in `CustomizableUI`, but some responsibility is also
delegated to modules like `CustomizableWidgets` and `CustomizeMode`.

```{toctree}
:maxdepth: 3

customizableui
drag-position-manager
overflowable-toolbar
panelmultiview
search-widget-tracker
toolbar-context-menu
customize-mode
```

---

### Browser Components Enterprisepolicies Docs Index (`browser/components/enterprisepolicies/docs/index.md`)

# Enterprise Policies

## Introduction

Enterprise policies control Firefox behavior and let you centrally manage various aspects of Firefox across devices.
Policies can be applied using Group Policy, Microsoft Intune, or by creating a file called `policies.json` and defining behavior within the JSON.

The reference documentation for each policy, including guides for applying and managing them, is in the [Firefox Admin Documentation](https://firefox-admin-docs.mozilla.org/).
For other resources for deploying Firefox in an organization, see the [Firefox Enterprise](https://www.firefox.com/en-US/browsers/enterprise/) page.

## Kiosk Mode

Firefox Kiosk Mode is a basic full-screen mode intended for environments where the content displayed in the browser is controlled by a kiosk owner.
It's designed for cases where users have no keyboard access or where keyboard access is restricted (particularly <kbd>Ctrl</kbd> and <kbd>Alt</kbd>).
Kiosk administrators are responsible for ensuring that content displayed on the device cannot unexpectedly navigate users away.

To run Kiosk Mode, start Firefox from the command line with the `--kiosk` option:

```bash
firefox --kiosk
# Or provide a URL
firefox --kiosk 'https://example.com/my-dashboard'
```

To put the kiosk window on a particular monitor, use `--kiosk-monitor` with the monitor number, instead:

```bash
# --kiosk-monitor implies --kiosk
firefox --kiosk-monitor 1 'https://example.com/my-dashboard'
```

Kiosk Mode does three main things:

1. Main browser windows (not popup windows) switch to full-screen mode that can't be exited within Firefox.
2. The context menu isn't shown.
3. Status for URLs and page loading isn't shown.

Two policies that are important for for a kiosk are
[UserMessaging](https://firefox-admin-docs.mozilla.org/reference/policies/usermessaging/) and
[DisableFirefoxStudies](https://firefox-admin-docs.mozilla.org/reference/policies/disablefirefoxstudies/).
Together they stop Firefox from interrupting the kiosk content with recommendations, onboarding, What's New, and studies.

Kiosk mode also won't suppress updates, the notifications and restart prompts for them, block `about:` pages, developer tools, and other behavior, so you should use policies for controlling these, too.

## Policy schema and metadata

For policies, there is a schema file located at {searchfox}`policies-schema.json <browser/components/enterprisepolicies/schemas/policies-schema.json>`.
Documentation and admin tools read this schema and can describe a policy without having to hardcode details about it beforehand.
The following `policies-schema.json` members are **required** for each policy:

`description`
: The description is written for the admins setting it and covers what the policy does.

`x-category`
: The category the policy is listed under, such as `Security` or `Bookmarks`.

`x-compatibility`
: Which release channels the policy is available, described below.

`x-restart-required`
: Whether the policy needs a restart before it's applied. Firefox ignores this since it applies all policies at startup, so set it to `true` for a new policy. Firefox Enterprise is the only consumer.

`examples`
: At least one value an admin could set, in the shape the policy accepts.

For each policy, the required members are enforced by a meta file
{searchfox}`policies-schema.meta.json <browser/components/enterprisepolicies/schemas/policies-schema.meta.json>`,
which is checked by
{searchfox}`test_policies_schema.js <browser/components/enterprisepolicies/tests/xpcshell/test_policies_schema.js>` xpcshell tests.

### Compatibility data

An `x-compatibility` block states the first version that supports a policy:

```json
"x-compatibility": {
  "firefox": { "version_added": "141" },
  "firefox_esr": { "version_added": "140.1.0" },
  "firefox_enterprise": { "version_added": "149" }
}
```

In an `x-compatibility` block, all three release channels are required.
A version for each channel is a string of up to three numbers, or `false` if the channel doesn't support the policy.

An optional `notes` member can accompany compat information.
Notes as a sibling of all channels apply to every channel, like `DisableLaunchOnLogin`:

```json
"x-compatibility": {
  "firefox": { "version_added": "155" },
  "firefox_esr": { "version_added": false },
  "firefox_enterprise": { "version_added": "155" },
  "notes": [
    "Windows support added in 155, macOS support added in 156. Has no effect on Linux."
  ]
}
```

Notes inside a release channel apply only to that channel:

```json
"x-compatibility": {
  "firefox": {
    "version_added": "60",
    "notes": "The policy accepted an object form in 123, and accepts a boolean form since 134."
  },
  "firefox_esr": { "version_added": "60" },
  "firefox_enterprise": { "version_added": "149" }
}
```

---

### Browser Components Migration Docs Index (`browser/components/migration/docs/index.md`)

(components-migration)=

# Migration

The migration component is responsible for bringing data from outside applications running on the same computer into Firefox. This is typically done via a wizard where users can choose what types of data to migrate over.

The migrator is also used during a "Profile Refresh" to pave over a newly created Firefox profile with some data from an older one.

```{toctree}
:maxdepth: 3

migration-utils
migrators
migration-wizard
```

---

### Browser Components Mozcachedohttp Docs Index (`browser/components/mozcachedohttp/docs/index.md`)

# moz-cached-ohttp Protocol

The `moz-cached-ohttp://` protocol handler enables Firefox to load resources over Oblivious HTTP (OHTTP)
from privileged contexts, including in the privileged about content process. This mechanism provides
privacy-preserving resource loading, and was originally designed for loading images in <about:newtab>.

```{toctree}
:maxdepth: 2

usage
api
```

## Overview

The moz-cached-ohttp protocol implements a cache-first strategy that:

1. First attempts to load resources from the HTTP cache to minimize OHTTP requests
2. Falls back to loading via OHTTP when resources are not available in cache
3. Automatically caches OHTTP responses for future requests
4. Respects HTTP cache expiration headers for proper cache management, but
   otherwise defaults to 24 hours for the cache expiry.

## Supported Contexts

The protocol is restricted to specific contexts for security:

- **Privileged about content process**: Primary use case is for privacy-preserving image loading on <about:newtab>
- **System principals in parent process**: For tests and internal usage

## URL Format

The protocol uses a specific URL format to encode the target resource URL:

```
moz-cached-ohttp://newtab-image/?url=<encoded-url>
```

Where `<encoded-url>` is the URL-encoded target **HTTPS-only** image URL.

:::{note}
Only the `newtab-image` host is currently supported. The host determines which OHTTP configuration and relay will be used for the request. See `HOST_MAP` in `MozCachedOHTTPProtocolHandler.sys.mjs`.
:::

:::{warning}
Only HTTPS target URLs are supported for security. HTTP URLs will be rejected.
:::

Example:

```
moz-cached-ohttp://newtab-image/?url=https%3A%2F%2Fexample.com%2Fimage.jpg
```

:::{note}
The OHTTP Relay and Gateway must both be configured to enable requests. The OHTTP Gateway also needs to have an allowlist that includes the resource endpoint, otherwise requests are likely to return `403 Forbidden` responses.
:::

## Host-Based Configuration

The protocol uses a host-based configuration system that maps URL hosts to specific OHTTP settings. This design allows different types of resource requests to use different OHTTP configurations in the future.

### Currently Supported Hosts

- **newtab-image**: Used for New Tab page image loading

  - Gateway Config URL preference: `browser.newtabpage.activity-stream.discoverystream.ohttp.configURL`
  - Relay URL preference: `browser.newtabpage.activity-stream.discoverystream.ohttp.relayURL`

### Future Extensibility

The host-based design allows easy addition of new hosts with different OHTTP configurations:

```javascript
// Future hosts could be added like:
// moz-cached-ohttp://other-service/?url=<encoded-url>
// moz-cached-ohttp://ads-service/?url=<encoded-url>
```

Each host would map to its own set of configuration preferences, allowing different services to use different OHTTP infrastructure.

---

### Browser Components Pagedata Docs Index (`browser/components/pagedata/docs/index.md`)

# PageDataService

The page data service is responsible for collecting additional data about a page. This could include
information about the media on a page, product information, etc. When enabled it will automatically
try to find page data for pages that the user browses or it can be directed to asynchronously look
up the page data for a url.

The `PageDataService` is an EventEmitter and listeners can subscribe to its notifications via the
`on` and `once` methods.

The service can be enabled by setting `browser.pagedata.enabled` to true. Additional logging can be
enabled by setting `browser.pagedata.log` to true.

## PageData Data Structure

At a high level the page data service can collect many different kinds of data. When queried the
service will respond with a `PageData` structure which holds some general information about the
page, the time when the data was discovered and a map of the different types of data found. This map
will be empty if no specific data was found. The key of the map is from the
`PageDataSchema.DATA_TYPE` enumeration. The value is the JSON data which differs in structure
depending on the data type.

```
{
  "url": <url of the page as a string>,
  "date": <epoch based timestamp>,
  "siteName": <a friendly name for the website>,
  "image": <url for an image for the page as a string>,
  "data": <map of data types>,
}
```

## PageData Collection

Page data is gathered in one of two ways.

Page data is automatically gathered for webpages the user visits. This collection is trigged after
a short delay and then updated when necessary. Any data is cached in memory for a period of time.
When page data has been found a `page-data` event is emitted. The event's argument holds the
`PageData` structure. The `getCached` function can be used to access any cached data for a url.

## Supported Types of page data

The following types of page data (`PageDataSchema.DATA_TYPE`) are currently supported:

- `PRODUCT`
- `DOCUMENT`
- `ARTICLE`
- `AUDIO`
- `VIDEO`

---

### Browser Components Places Docs Architecture Overview (`browser/components/places/docs/architecture-overview.md`)

# Places architecture overview

Because Mozilla used to ship a framework called XULRunner, Places is split into a Toolkit and a Browser part. The toolkit part is usually made up of product-agnostic APIs, those can be used by any kind of project, not just Web Browsers. The browser part is the one containing code specific to the Firefox browser.

## Codebase

Most of the codebase is written in:
: - **JavaScript**

- **C++** (for ex., database initialization code or some of the visit tracking code).

## Frontend

The frontend part of the bookmarking experience includes various kind of views:
: - {searchfox}`Trees <browser/components/places/content/places-tree.js>`

- {searchfox}`Menus <mozilla-central/rev/4c184ca81b28f1ccffbfd08f465709b95bcb4aa1:browser/components/places/content/browserPlacesViews.js#1990>`
- {searchfox}`Toolbars <mozilla-central/rev/4c184ca81b28f1ccffbfd08f465709b95bcb4aa1:browser/components/places/content/browserPlacesViews.js#894>`

All the views share a common {searchfox}`Controller <browser/components/places/content/controller.js>` that is responsible to handle operations and commands required by the views. Each view creates a Result object and receives notifications about changes from it.

As an example, removing a bookmark from a view will call into the controller that calls into PlacesTransactions to actually do the removal. The removal will notify a {searchfox}`Places event <dom/chrome-webidl/PlacesEvent.webidl>`, that is caught by the Result, that will immediately update its internal representation of the bookmarks tree. Then the Result sends a notification to the view that will handle it, updating what the user is seeing. The system works according to the classical [Model-View-Controller] pattern.

Fronted dialogs and panels are written using xhtml and shadow DOM. The bookmark dialogs in particular are wrappers around a common template, {searchfox}`editBookmarkPanel.inc.xhtml <browser/components/places/content/editBookmarkPanel.inc.xhtml>`, it could be extended or overloaded like an object (overlay, similar to Web Component).

Most of the logic for the edit bookmark overlay lives in the generic script {searchfox}`editBookmark.js <browser/components/places/content/editBookmark.js>`.

### Structure of Frontend

Most part of frontend code is located in : {searchfox}`Browser/Components/Places/Content <browser/components/places/content>`:

- {searchfox}`BookmarkProperties <browser/components/places/content/bookmarkProperties.js>` , BookmarkProperties.xhtml - responsible for editBookmarks & newBookmark Dialog. The panel is initialized based on data given in the js object passed as `window.arguments[0]`. `Window.arguments[0]` is set to the guid of the item, if the dialog is accepted.
- BookmarksHistoyTooltip.xhtml - code responsible for tooltip
- {searchfox}`BookmarksSidebar <browser/components/places/content/bookmarksSidebar.js>`, bookmarksSidebar.xhtml - code responsible for sidebar window. Searches through existing bookmarks tree for desired bookmark.
- {searchfox}`BrowserPlacesViews <browser/components/places/content/browserPlacesViews.js>` - controls most views (menu, panels, toolbox). The base view implements everything that's common to the toolbar and menu views.
- {searchfox}`Controller <browser/components/places/content/controller.js>` - controller shared by all places views. Connect UI and actual operations.
- {searchfox}`EditBookmark <browser/components/places/content/editBookmark.js>`, editBookmarkPanel.inc.xhtml - controls edit bookmark panel. Observes changes for bookmarks and connects all UI manipulations with backend.
- {searchfox}`HistorySidebar <browser/components/places/content/historySidebar.js>`, historySidebar.xhtml - code responsible for history sidebar window. Searches through existing tree for requested History.
- {searchfox}`Places-menupopup <browser/components/places/content/places-menupopup.js>` - custom element definition for Places menus
- {searchfox}`Places-tree <browser/components/places/content/places-tree.js>` - class `MozPlacesTree` - builds a custom element definition for the places tree. This is loaded into all XUL windows. Has to be wrapped in a block to prevent leaking to a window scope.
- Places.css, places.js, places.xhtml - responsible for Library window
- PlacesCommands.inc.xhtml - commands for multiple windows
- PlacesContextMenu.inc.xhtml - definition for context menu
- {searchfox}`TreeView <browser/components/places/content/treeView.js>` - implementation of the tree view

## Backend

Because any bookmark operation done by the user in the frontend is undo-able, Firefox usually doesn’t directly invoke the Bookmarks / History API, it instead goes through a wrapper called PlacesTransactions.

The scope of this module is to translate requests for bookmark changes into operation descriptors, and store them in a log. When a bookmark has been modified by the user, PlacesTransactions stores the previous state of it in the log; that state can be restored if the user picks Undo (or CTRL+Z) in the Library window. This prevents data loss in case the user removes bookmarks inadvertently.

Toolkit Places also provides a way to query bookmarks, through Results. This is one of the oldest parts of the codebase that will likely be rewritten in the future. It uses XPCOM (Cross Platform Component Object Model) a Mozilla technology that allows C++ and Javascript to communicate. It’s a declarative system, where interfaces must be defined and documented in XPIDL files. In practice all the available methods and attributes are documented in nsINavHistoryService.idl. Querying bookmarks returns a nsINavHistoryResult object that has a root node. The root node has children representing bookmarks or folders. It works like a tree, containers must be opened and then one can inspect their children. This is the base used by most of the Firefox frontend bookmark views.

### Structure of Backend

Most part of backend code is located in : {searchfox}`Toolkit/Components/Places <toolkit/components/places>`:

- {doc}`Bookmarks` - Asynchronous API for managing bookmarks
- {doc}`History` - Asynchronous API for managing history
- {searchfox}`PlacesUtils <toolkit/components/places/PlacesUtils.sys.mjs>` - This module exports functions for Sync to use when applying remote records
- {doc}`PlacesTransactions` - This module serves as the transactions manager for Places

## Storage

Places uses [SQLite] (C-language library with a stable, cross-platform, and backwards compatible file format) as its data storage backend.
All the data is contained in a places.sqlite file, in the roaming Firefox profile folder. The database is accessed using a wrapper of the SQLite library called {searchfox}`mozStorage <storage>`.
For storing our favicons we use favicons.sqlite which is represented as ATTACH-ed to places.sqlite. That makes it easier to use our two separate sqlites as one single database.

## Synchronization

Places works in strict contact with [Firefox Sync], to synchronize bookmarks and history across devices, thus you can meet Sync specific code in various parts of the Places codebase. Some of the code may refer to Weave, the old project name for Sync.

[firefox sync]: https://www.mozilla.org/en-US/firefox/sync/
[model-view-controller]: https://en.wikipedia.org/wiki/Model–view–controller
[sqlite]: https://www.sqlite.org/index.html

---

### Browser Components Places Docs Index (`browser/components/places/docs/index.md`)

# Places

This document describes the implementation of the Firefox Places component.

It is a robust system to manage History and Bookmarks through a database on the backend side and a model-view-controller system that connects frontend UI user manipulation.

## History and Bookmarks

In Firefox 2, History and Bookmarks used to be kept into separate databases in the Resource Description Framework format ([RDF format]).

However, Firefox 3 implemented the Places system. It has been done due to multiple reasons, such as:

- **Performance**: certain search or maintenance operations were very slow
- **Reliability**: the filesystem facing side of RDF was not so robust, often causing corruption or unexpected states
- **Flexibility**: being able to cross data allows for interesting features, like the Awesome Bar
- **Maintainability**: the future of RDF was unclear, while SQLite is actively maintained and used by a large number of applications

## Where to Start

For the high-level, non-technical summary of how History and Bookmarks works, read {doc}`nontechnical-overview`.
For more specific, technical details of implementation, read {doc}`architecture-overview`.

## Governance

See [Bookmarks & History (Places)](https://firefox-source-docs.mozilla.org/mots/index.html#bookmarks-history)

## Table of Contents

```{toctree}
:maxdepth: 2

nontechnical-overview
architecture-overview
API for managing bookmarks <Bookmarks>
API for managing history <History>
Transactions Manager <PlacesTransactions>
Observer Notifications <notifyObservers>
```

[rdf format]: https://en.wikipedia.org/wiki/Resource_Description_Framework

---

### Browser Components Places Docs Nontechnical Overview (`browser/components/places/docs/nontechnical-overview.md`)

# Nontechnical Overview

This document provides a high level, nontechnical overview of Firefox’s Places component (Bookmarks and History).

More information regarding Bookmarks - [Bookmarks in Firefox]

There are multiple ways to access and manipulate Bookmarks, such as:

```{contents}
:depth: 2
```

## Firefox menu bar

To access bookmarks click on Bookmarks link in Firefox menu bar on the top of your screen.
If the Firefox Menu bar is missing, it is usually because Firefox is in full screen mode or it is not the selected application.

In this case you can:
: - Turn off full screen mode

- Select the Firefox application

:::{figure} assets/nontechnical-overview/firefox-bookmarks-menu.png
:align: center
:alt: Image of the Bookmarks Menu in Firefox menu bar
:scale: 50%

Firefox menu bar - Bookmarks Menu
:::

## Main application button

:::{figure} assets/nontechnical-overview/firefox-bookmarks-main-application.png
:align: center
:alt: Image of the main Bookmarks application button
:scale: 45%

Firefox - Bookmarks Main Application
:::

## Bookmarks Toolbar

:::{figure} assets/nontechnical-overview/firefox-bookmarks-toolbar.png
:align: center
:alt: Image of the Bookmarks Toolbar
:scale: 50%

Firefox - Bookmarks Toolbar
:::

On the top of your Firefox screen just under the search bar - Bookmarks are on the left side.

Firefox's toolbar provides easy access to common features:
: - Click the menu button , click `More Tools` and choose `Customize Toolbar`.

    - **To turn on the Title bar:** Put a check mark next to `Title Bar` in the lower left.
    - **To turn on the Bookmarks toolbar:** Click the Toolbars dropdown menu at the bottom of the screen and select Bookmarks Toolbar.

- Click the `Done` button.

## Firefox sidebar

Firefox comes with a convenient Sidebar button which lets you access your bookmarks, history and synced tabs in one click. For using it, you have to:

1. [Add the sidebar button to your controls].
2. Toggle sidebar button on and off for preferable options (for ex., add bookmarks).

## The Library window

1. Click the `hamburger Menu` icon in the upper-right corner of your screen.
2. In the middle of the drop-down menu select `Library`.
3. In the `Library` menu select `Bookmarks`.
4. Press `Show All Bookmark` button.

## Keyboard shortcuts

- Show / Manage Bookmarks (Library Window) - {kbd}`Shift` + {kbd}`Ctrl` / {kbd}`Cmd` + {kbd}`O`
- Add / Edit Bookmark - {kbd}`Ctrl` / {kbd}`Cmd` + {kbd}`D`
- Bookmark all tabs into 1 bookmark folder - {kbd}`Shift` + {kbd}`Ctrl` / {kbd}`Cmd` + {kbd}`D`
- Delete bookmark / Bookmarks / Bookmarks folder - {kbd}`Delete`
- Show / Hide the Bookmarks toolbar - {kbd}`Shift` + {kbd}`Ctrl` / {kbd}`Cmd` + {kbd}`B`
- Focus Next Bookmark/Folder whose name (or sorted property) starts with a given character or character sequence - Type the character or quickly type the character sequence - in Bookmarks Library, Bookmarks Toolbar, Bookmarks Menu, Bookmarks Sidebar

## Firefox Context Menu

Single // Multiple bookmarks on selection will allow you to perform different manipulations, such as:

- Open (Open / Open in New Tab / Open in New Window / Open in New Private Window)
- Delete
- Edit (Cut / Copy / Paste)
- Add (Bookmark / Folder / Separator)

:::{figure} assets/nontechnical-overview/bookmark-folder-menu.png
:align: center
:alt: Image of the Bookmark Menu
:scale: 50%

Firefox - Bookmark Menu
:::

## Undo / Redo

Undo / Redo options available In Library Window and Sidebar Panel.
You can reverse your commands (creating bookmark, deleting bookmark, copy/paste etc.) with:

- Keyboard combinations:

  - Undo - {kbd}`Ctrl` / {kbd}`Cmd` + {kbd}`Z`
  - Redo - {kbd}`Shift` + {kbd}`Ctrl` / {kbd}`Cmd` + {kbd}`Z`

- Choosing option in Menu - Edit - Undo / Redo

:::{figure} assets/nontechnical-overview/bookmark-undo-redo.png
:align: center
:alt: Image of the Undo/Redo options for Bookmark
:scale: 50%

Firefox - Undo / Redo for bookmark
:::

## Import Bookmarks

There are various options to import bookmarks to Firefox. Some of them are:

- [from Internet Explorer or Microsoft Edge]
- [from Google Chrome]
- [from an HTML file]

## Restore Bookmarks

Firefox automatically creates backups of your bookmarks and saves the last 15 backups for safekeeping.

**To restore your bookmarks:**

1. Click on *hamburger menu* button to open the Menu panel.

2. Go to *Bookmarks* - *Manage Bookmarks*.

3. Select the backup from which you want to restore:

   > 1. The dated entries are automatic bookmark backups.
   > 2. From a manual backup ( *Choose file…* ).

4. After selecting the option and confirming your choice your bookmarks would be restored.

**For manually add backup:**

1. Click on *hamburger menu* button to open the Menu panel.
2. Go to *Bookmarks* - *Manage Bookmarks*.
3. In the *Library window*, click the button and then select *Backup…*.
4. In the Bookmarks backup filename window that opens, choose a location to save the file, which is named `bookmarks-date.json` by default. The desktop is usually a good spot, but any place that is easy to remember will work.
5. Save the bookmarks json file. The Bookmarks backup filename window will close and then you can close the *Library* window.

[add the sidebar button to your controls]: https://support.mozilla.org/en-US/kb/use-firefox-sidebar-access-bookmarks-history-synced
[bookmarks in firefox]: https://support.mozilla.org/en-US/kb/bookmarks-firefox
[from an html file]: https://support.mozilla.org/en-US/kb/import-bookmarks-html-file
[from google chrome]: https://support.mozilla.org/en-US/kb/import-bookmarks-google-chrome
[from internet explorer or microsoft edge]: https://support.mozilla.org/en-US/kb/import-bookmarks-internet-explorer-or-microsoft-edge

---

### Browser Components Search Docs Index (`browser/components/search/docs/index.md`)

(browser-search)=

# Search UI

This document describes the implementation of parts of Firefox's search interfaces.

The search area covers:

- Search bar on the toolbar
- In-content search
- One-off search buttons on both the search and address bars

Search Engine handling is taken care of with the [toolkit Search Service].

Most of the search code lives in {searchfox}`browser/components/search`.

```{toctree}
application-search-engines
Preferences
telemetry
```

[toolkit search service]: https://firefox-source-docs.mozilla.org/toolkit/search/index.html

---

### Browser Components Sessionstore Docs Index (`browser/components/sessionstore/docs/index.md`)

(sessionstore)=

# Session Restore

Session restore keeps track of the windows, tabs and tab groups a user has open
or recently closed, along with state information for each tab (history, scroll
position, form data, etc.). It persists that state to disk, and puts it back
when Firefox starts again or when the user reopens something they closed.

`SessionStore` is the component's entry point. It observes browser windows and
their tabs, holds the collected state in memory, and exposes the API that the
rest of the front-end uses to read state, to reopen closed tabs, windows and tab
groups, and to save and restore whole sessions. The remaining modules in
{searchfox}`browser/components/sessionstore
<browser/components/sessionstore/>` support it:

`SessionStartup`
: Reads the session file at startup and decides whether the previous session
  should be restored.

`SessionSaver`, `SessionFile` and `SessionWriter`
: Schedule and perform the disk I/O that persists the session state.

`TabState`, `TabStateCache` and `TabStateFlusher`
: Collect per-tab state, cache it, and let callers wait for a tab's latest data.

`RunState`
: Tracks whether session restore is stopped, running or quitting.

`GlobalState`, `SessionCookies`, `TabAttributes` and `TabGroupState`
: Hold the parts of the session state that aren't per-tab.

```{toctree}
:maxdepth: 1

events
api
```

---

### Browser Components Sidebar Docs Index (`browser/components/sidebar/docs/index.md`)

(components-sidebar)=

# Sidebar

The new sidebar builds on existing legacy sidebar code treating `browser-sidebar.js` as a `SidebarController`. As part of the new sidebar and vertical tabs project, we've added new components including top-level system module `SidebarManager.sys.mjs` and a per window state manager, `SidebarState.sys.ms`. We've added new UI components that use a combination of moz components and custom lit components. The sidebar team maintains the existing synced tabs and history panels.

## Introducing a new panel

Every panel that is registered and enabled in `` browser-sidebar.js` `` and the `toolsNameMap` map will show as an option in the Customize Sidebar menu (which is a sidebar panel that contains settings).

The launcher is a container for tools (ie, icons that when clicked open or close the associated panel). Registering a panel - which should be behind a pref until it is ready to be introduced - does not automatically add a new icon to the launcher.

A tool can be added once for all users by adding it to the designated pref branch `sidebar.newTool.migration.` in `profile/firefox.js`. So an example would be `pref("sidebar.newTool.migration.bookmarks", '{}')`. The pref suffix (`bookmarks` in this example) is the `toolID` that should match what you added as the value portion of the relevant entry in the `toolsNameMap` map in `browser-sidebar.js`. It's important to note that if you have a pref governing the visibility of your sidebar panel, it will need to be enabled at the same time in order to be shown in a user's launcher - either via a nimbus rollout or in-tree.

If you only want to add this item if the pref governing visibility is true, you can pass the pref you want to observe, e.g. `pref("sidebar.newTool.migration.reviewchecker", '{ "visibilityPref": "browser.shopping.experience2023.integratedSidebar"}')` where `browser.shopping.experience2023.integratedSidebar` is the pref controlling the visibility of the review checker panel.

In both cases, the tool will be introduced to the launcher one time (appended to a user's customized list of tools) and any customization after that (ie, removing it) takes precedence. If it's not removed, it will persist after that session.

If you only want to introduce a tool to new users, you can do so by adding it to the `DEFAULT_LAUNCHER_TOOLS` list in `SidebarManager` and the `toolsNameMap`. You can do this even if you have previously introduced a tool via a pref branch migration as there is logic that will prevent a tool from being added twice, however the expectation is that when adding it to `defaultTools` the pref governing panel visibility is also enabled in-tree.

## State Management

The sidebar includes a variety of options that users can customize, such as:

- Sidebar visibility (e.g., expand on hover, hide tabs and sidebar)
- Sidebar position (left or right)
- Tab strip orientation (vertical or horizontal)
- Available tools (which can be enabled or disabled)

These options are stored internally as preference values, meaning they persist across
browser windows. For example, if you have two windows open and move the sidebar to the
right in one of them, the other window's sidebar will also move to the right.

In addition to these preferences, there are also *state* values that depend on user
interaction, such as:

- Whether the launcher is expanded, collapsed, or hidden
- Which panel is currently open
- The width of the launcher and panel

These state values are usually stored in `SessionStore`. However, if the user has
disabled session restore (e.g., via permanent private browsing mode), they are serialized
and stored under the `sidebar.backupState` preference instead.

State values are per-window and do not carry over between windows. For example, if you
load a panel in one window, other windows will not display that same panel.

### SidebarState: Per-Window State

`SidebarState` tracks and updates sidebar-related UI state within a specific browser
window. It acts as the single source of truth for the sidebar's current state in that
window. In practice, it functions as a "reactive controller," handling user interactions,
maintaining internal state values, and determining the appropriate DOM updates.

When state values are changed, `SidebarState` immediately applies corresponding
adjustments to the UI. For example:

- When `launcherVisible` is set to `false`, the launcher is hidden, and the sidebar's
  inline padding is adjusted accordingly.
- When `launcherWidth` or `panelWidth` are updated, inline CSS is modified to ensure
  that the sidebar does not occupy more than 75% of the browser's width.

### SidebarManager: Global State

`SidebarManager` handles listening to preference values, global events, and loading the
"backup state" if necessary. When such handlers are triggered, `SidebarManager` delegates
tasks to each instance of `SidebarController` (a per-window module).

Use cases for `SidebarManager` include:

- Updating visibility preferences when the tab orientation changes.
- Managing the default set of tools for new sidebar users.
- Detecting when the sidebar button is removed from `CustomizableUI`, thereby signaling
  all `SidebarController` instances to close the sidebar if it is open.

:::{note}
`SidebarManager` should also be responsible for updating the customize panel when
preferences are changed from another source, but that is currently not the case. This
should be addressed in [Bug 1945530](https://bugzil.la/1945530).
:::

### Example Workflows

#### Per-Window State Change

Suppose a user clicks the toolbar button to show the sidebar. This is how the interaction
is handled:

1. `SidebarController.handleToolbarButtonClick()` is called, which sets `state.launcherVisible`.
2. `SidebarState` calls the setter for `launcherVisible`, removing the `hidden`
   attribute from the launcher element.

#### Global State Change

Suppose a user removes the toolbar button. Since `CustomizableUI` changes are synced
across windows, this is treated as a global state change. The interaction is handled as
follows:

1. `CustomizableUI` notifies listeners (including `SidebarManager`) about a widget
   removal.
2. `SidebarManager.onWidgetRemoved()` is called to handle the event.
3. `onWidgetRemoved` calls the `hide()` function on every `SidebarController` instance.

---

### Browser Components Tabbrowser Docs Index (`browser/components/tabbrowser/docs/index.md`)

(tabbrowser)=

# Tabbed Browser

`gBrowser` displays and manages the contents of a window's tabs. Older code and documentation often call it `<xul:tabbrowser>`, after the DOM element that used to fill this role. That element no longer exists, but the name is still used synonymously with `gBrowser`, so you will meet it.

```{toctree}
:maxdepth: 1

gbrowser
opening-tabs
api
tab-events
progress-listeners
async-tab-switcher
lazy-browsers
tab-unloading
```

---

### Browser Components Taskbartabs Docs Index (`browser/components/taskbartabs/docs/index.md`)

# Web Apps in Firefox

Web Apps in Firefox — also referred to as Taskbar Tabs in-source — is a feature that allows pinning a simplified and site stylized browser window to the taskbar (or system equivalent). This is analagous to what is often referred to as Progressive Web Apps (PWAs).

The feature is enabled by the preference `browser.taskbarTabs.enabled`, which is currently enabled by default on Windows. To create a web app, click on the 'Add tab to taskbar' button on the URL bar, which will create a new window and prompt to pin it to your taskbar. Remove the web app by clicking the 'Remove tab from taskbar' button, which'll turn it back into a normal tab and (if that was the last window) unpin it from your taskbar.

:::{note}
Currently, Web Apps are available on Windows (both MSIX and non-MSIX, enabled by default) and Linux (unsandboxed and under Flatpak, disabled by default).

macOS support is not currently available. macOS assumes that two different visible applications will be in two different processes; however, web apps are in the same profile and process as the rest of the browser, so the Dock isn't able to distinguish them. There are some workarounds, like creating the window in a different process and ferrying events across, but it's a sufficient challenge that it hasn't been done yet.
:::

Internally, they're called 'taskbar tabs' after the initial design which made an analogy to pinned tabs being on your taskbar. The feature is called 'web apps' instead of PWAs (Progressive Web Apps) as implemented in Chromium for two reasons:

* 'PWA' is a vague term, referring to both APIs to support web apps (many of which Firefox supports) and the ability to install them.
* Firefox Web Apps, by design, still appear like a browser instead of appearing as a completely separate application like most PWA implementations.

Firefox Web Apps keeps information about each web app in `taskbartabs/taskbartabs.json` inside the user's profile. This file is intended for use internally by Firefox; if you change it, things might not work properly. It follows the JSON schema in {searchfox}`TaskbarTabs.schema.1.json <browser/components/taskbartabs/TaskbarTabs.1.schema.json>`. Refer to {searchfox}`TaskbarTabsRegistry.sys.mjs <browser/components/taskbartabs/TaskbarTabsRegistry.sys.mjs>` for information on what each property is used for.

```{toctree}
:maxdepth: 1

architecture
```

## External Interactions

### Web Apps and Profiles

Web Apps are tied to the profile they are created with, therefore web app pages have the same access, controls, and add-ons as a normal tab.

### Web Apps and Containers

Web apps are tied to the container — also referred to as Contextual Identity in-source — they are created with. When launching a Web App via the taskbar it will reopen in this tied to container. This affords users the ability to isolate sites without requiring a new profile per Web App.

### Web Apps and Session Restore

Web Apps are similar to Private Windows in that they are not tied to the lifetime of normal browser session restore. Web App windows are not restore for users who have enabled "Open previous windows and tabs", and will not prevent the restoration of windows restored by session restore.

---

### Browser Components Touchbar Docs Index (`browser/components/touchbar/docs/index.md`)

# Touch Bar

The Touch Bar is a hardware component on some MacBook Pros released from 2016.
It is a display above the keyboard that allows more flexible types of
input than is otherwise possible with a normal keyboard. Apple offers Touch Bar
APIs so developers can extend the Touch Bar to display inputs specific to their
application. Firefox consumes these APIs to offer a customizable row of inputs
in the Touch Bar.

In Apple's documentation, the term "the Touch Bar" refers to the hardware.
The term "a Touch Bar" refers not to the hardware but to a collection of inputs
shown on the Touch Bar. This means that there can be multiple "Touch Bars" that
switch out as the user switches contexts. The same naming convention is used in
this document.

In this document and in the code, the word "input" is used to refer to
an interactive element in the Touch Bar. It is often interchangeable with
"button", but "input" can also refer to any element displayed in the Touch Bar.

The Touch Bar should never offer functionality unavailable to Firefox users
without the Touch Bar. Most macOS Firefox users do not have the Touch Bar and
some choose to disable it. Apple's own [Human Interface Guidelines] (HIG)
forbids this kind of Touch Bar functionality. Please read the HIG for more
design considerations before you plan on implementing a new Touch Bar feature.

If you have questions about the Touch Bar that are not answered in this
document, feel free to reach out to [Harry Twyford] (:harry on Slack).
He wrote this document and Firefox's initial Touch Bar implementation.

```{contents} Table of Contents
```

## Overview

Firefox's Touch Bar implementation is equal parts JavaScript and Cocoa
(Objective-C++). The JavaScript code lives in `browser/components/touchbar`
and the Cocoa code lives in `widget/cocoa`, mostly in `nsTouchBar.mm`. The
Cocoa code is a consumer of Apple's Touch Bar APIs and defines what types of
Touch Bar inputs are available to its own consumers. The JS code in
`browser/components/touchbar` provides services to `nsTouchBar.mm` and
defines what inputs the user actually sees in the Touch Bar. There is two-way
communication between the JS and the Cocoa: the Cocoa code asks the JS what
inputs it should display, and the JS asks the Cocoa code to update those inputs
when needed.

## JavaScript API

`browser/components/touchbar/MacTouchBar.sys.mjs` defines what specific inputs are
available to the user, what icon they will have, what action they will perform,
and so on. Inputs are defined in the `gBuiltInInputs` object {searchfox}`in that file <mozilla-central/rev/669fac9888b173c02baa4c036e980c0c204dfe02:browser/components/touchbar/MacTouchBar.sys.mjs#76>`.
When creating a new object in `gBuiltInInputs`, the available properties are
documented in the JSDoc for `TouchBarInput`:

```JavaScript
/**
 * A representation of a Touch Bar input.
 *     @param {string} input.title
 *            The lookup key for the button's localized text title.
 *     @param {string} input.image
 *            A URL pointing to an SVG internal to Firefox.
 *     @param {string} input.type
 *            The type of Touch Bar input represented by the object.
 *            Must be a value from kInputTypes.
 *     @param {Function} input.callback
 *            A callback invoked when a touchbar item is touched.
 *     @param {string} [input.color]
 *            A string in hex format specifying the button's background color.
 *            If omitted, the default background color is used.
 *     @param {bool} [input.disabled]
 *            If `true`, the Touch Bar input is greyed out and inoperable.
 *     @param {Array} [input.children]
 *            An array of input objects that will be displayed as children of
 *            this input. Available only for types KInputTypes.POPOVER and
 *            kInputTypes.SCROLLVIEW.
 */
```

Clarification on some of these properties is warranted.

- `title` is the key to a Fluent translation defined in `browser/locales/<LOCALE>/browser/touchbar/touchbar.ftl`.
- `type` must be a value from the `kInputTypes` enum in `MacTouchBar.sys.mjs`.
  For example, `kInputTypes.BUTTON`. More information on input types follows
  below.
- `callback` points to a JavaScript function. Any chrome-level JavaScript can
  be executed. `execCommand` is a convenience method in `MacTouchBar.sys.mjs`
  that takes a XUL command as a string and executes that command. For instance,
  one input sets `callback` to `execCommand("Browser:Back")`.
- `children` is an array of objects with the same properties as members of
  `gBuiltInInputs`. When used with an input of type
  `kInputTypes.SCROLLVIEW`, `children` can only contain inputs of type
  `kInputTypes.BUTTON`. When used with an input of type
  `kInputTypes.POPOVER`, any input type except another `kInputTypes.POPOVER`
  can be used.

### Input types

Button

: A simple button. If `image` is not specified, the buttons displays the text
  label from `title`. If both `image` and `title` are specified, only the
  `image` is shown. The action specified in `callback` is executed when the
  button is pressed.

  :::{caution}
  Even if the `title` will not be shown in the Touch Bar, you must still
  define a `title` property.
  :::

Main Button

: Similar to a button, but displayed at double the width. A main button
  displays both the string in `title` and the icon in `image`. Only one
  main button should be shown in the Touch Bar at any time, although this is
  not enforced.

Label

: A non-interactive text label. This input takes only the attributes `title`
  and `type`.

Popover

: Initially represented in the Touch Bar as a button, a popover will display an
  entirely different set of inputs when pressed. These different inputs should
  be defined in the `children` property of the parent. Popovers can also be
  shown and hidden programmatically, by calling

  ```JavaScript
  gTouchBarUpdater.showPopover(
    TouchBarHelper.baseWindow,
    [POPOVER],
    {true | false}
  );
  ```

  where the second argument is a reference to a popover TouchBarInput and
  the third argument is whether the popover should be shown or hidden.

Scroll View

: A Scroll View is a scrolling list of buttons. The buttons should be defined
  in the Scroll View's `children` array.

  :::{note}
  In Firefox, a list of search shortcuts appears in the Touch Bar when the
  address bar is focused. This is an example of a ScrollView contained within
  a popover. The popover is opened programmatically with
  `gTouchBarUpdater.showPopover` when the address bar is focused and it is
  hidden when the address bar is blurred.
  :::

### Examples

Some examples of `gBuiltInInputs` objects follow.

A simple button

```JavaScript
Back: {
  title: "back",
  image: "chrome://browser/skin/back.svg",
  type: kInputTypes.BUTTON,
  callback: () => execCommand("Browser:Back", "Back"),
},
```

A button is defined with a title, icon, type, and a callback. The callback
simply calls the XUL command to go back.

The search popover

: This is the input that occupies the Touch Bar when the address bar is focused.

  ```JavaScript
  SearchPopover: {
    title: "search-popover",
    image: "chrome://global/skin/icons/search-glass.svg",
    type: kInputTypes.POPOVER,
    children: {
      SearchScrollViewLabel: {
        title: "search-search-in",
        type: kInputTypes.LABEL,
      },
      SearchScrollView: {
        key: "search-scrollview",
        type: kInputTypes.SCROLLVIEW,
        children: {
          Bookmarks: {
            title: "search-bookmarks",
            type: kInputTypes.BUTTON,
            callback: () =>
              gTouchBarHelper.insertRestrictionInUrlbar(
                UrlbarShared.RESTRICT_TOKENS.BOOKMARK
              ),
          },
          History: {
            title: "search-history",
            type: kInputTypes.BUTTON,
            callback: () =>
              gTouchBarHelper.insertRestrictionInUrlbar(
                UrlbarShared.RESTRICT_TOKENS.HISTORY
              ),
          },
          OpenTabs: {
            title: "search-opentabs",
            type: kInputTypes.BUTTON,
            callback: () =>
              gTouchBarHelper.insertRestrictionInUrlbar(
                UrlbarShared.RESTRICT_TOKENS.OPENPAGE
              ),
          },
          Tags: {
            title: "search-tags",
            type: kInputTypes.BUTTON,
            callback: () =>
              gTouchBarHelper.insertRestrictionInUrlbar(
                UrlbarShared.RESTRICT_TOKENS.TAG
              ),
          },
        },
      },
    },
  },
  ```

  At the top level, a Popover is defined. This allows a collection of children
  to be shown in a separate Touch Bar. The Popover has two children: a Label,
  and a Scroll View. The Scroll View displays five similar buttons that call a
  helper method to insert search shortcut symbols into the address bar.

### Adding a new input

Adding a new input is easy: just add a new object to `gBuiltInInputs`. This
will make the input available in the Touch Bar customization window (accessible
from the Firefox menu bar item).

If you want to to add your new input to the default set, add its identifier
{searchfox}`here <mozilla-central/rev/ebe492edacc75bb122a2b380e4cafcca3470864c:widget/cocoa/nsTouchBar.mm#100>`, where `type` is a value from `kAllowedInputTypes` in that
file and `key` is the value you set for `title` in `gBuiltInInputs`.
You should request approval from UX before changing the default set of inputs.

If you are interested in adding new features to Firefox's implementation of the
Touch Bar API, read on!

## Cocoa API

Firefox implements Apple's Touch Bar API in its Widget: Cocoa code with an
`nsTouchBar` class. `nsTouchBar` interfaces between Apple's Touch Bar API
and the `TouchBarHelper` JavaScript API.

The best resource to understand the Touch Bar API is Apple's
[official documentation]. This documentation will cover how Firefox implements
these APIs and how one might extend `nsTouchBar` to enable new Touch Bar
features.

Every new Firefox window initializes `nsTouchBar` ({searchfox}`link <mozilla-central/rev/ebe492edacc75bb122a2b380e4cafcca3470864c:widget/cocoa/nsCocoaWindow.mm#2877>`). The function
`makeTouchBar` is looked for automatically on every new instance of an
`NSWindow*`. If `makeTouchBar` is defined, that window will own a new
instance of `nsTouchBar`.

At the time of this writing, every window initializes `nsTouchBar` with a
default set of inputs. In the future, Firefox windows other than the main
browser window (such as the Library window or DevTools) may initialize
`nsTouchBar` with a different set of inputs.

`nsTouchBar` has two different initialization methods: `init` and
`initWithInputs`. The former is a convenience method for the latter, calling
`initWithInputs` with a nil argument. When that happens, a Touch Bar is
created containing a default set of inputs. `initWithInputs` can also take an
`NSArray<TouchBarInput*>*`. In that case, a non-customizable Touch Bar will be
initialized with only those inputs available.

### NSTouchBarItemIdentifiers

The architecture of the Touch Bar is based largely around an `NSString*`
wrapper class called `NSTouchBarItemIdentifier`. Every input in the Touch Bar
has a unique `NSTouchBarItemIdentifier`. They are structured in reverse-URI
format like so:

`com.mozilla.firefox.touchbar.[TYPE].[KEY]`

[TYPE] is a string indicating the type of the input, e.g. "button". If an
input is a child of another input, the parent's type is prepended to the child's
type, e.g. "scrubber.button" indicates a button contained in a scrubber.

[KEY] is the `title` attribute defined for that input on the JS side.

If you need to generate an identifier, use the convenience method
`[TouchBarInput nativeIdentifierWithType:withKey:]`.

:::{caution}
Do not create a new input that would have the same identifier as any other
input. All identifiers must be unique.
:::

:::{warning}
`NSTouchBarItemIdentifier` {searchfox}`is used in one other place <mozilla-central/rev/ebe492edacc75bb122a2b380e4cafcca3470864c:widget/cocoa/nsTouchBar.mm#71>`: setting
`customizationIdentifier`. Do not ever change this string. If it is changed,
any customizations users have made to the layout of their Touch Bar in Firefox
will be erased.
:::

Each identifier is tied to a `TouchBarInput`. `TouchBarInput` is a class
that holds the properties specified for each input in `gBuiltInInputs`.
`nsTouchBar` uses them to create instances of `NSTouchBarItem`
which are the actual objects used by Apple's Touch Bar API and displayed in the
Touch Bar. It is important to understand the difference between
`TouchBarInput` and `NSTouchBarItem`!

### TouchBarInput creation flow

Creating a Touch Bar and its `TouchBarInputs` flows as follows:

1. `[nsTouchBar init]` is called from `[NSWindow makeTouchBar]`.
2. `init` populates two NSArrays: `customizationAllowedItemIdentifiers` and
   `defaultItemIdentifiers`. It also initializes a `TouchBarInput` object
   for every element in the union of the two arrays and stores them in
   `NSMutableDictionary<NSTouchBarItemIdentifier, TouchBarInput*>* mappedLayoutItems`.
3. `touchBar:makeItemForIdentifier:` is called for every element in the union
   of the two arrays of identifiers. This method retrieves the `TouchBarInput`
   for the given identifier and uses it to initialize a `NSTouchBarItem`.
   `touchBar:makeItemForIdentifier:` reads the `type` attribute from the
   `TouchBarInput` to determine what `NSTouchBarItem` subclass should be
   initialized. Our Touch Bar code currently supports `NSCustomTouchBarItem`
   (buttons, main buttons); `NSPopoverTouchBarItem` (popovers);
   `NSTextField` (labels); and `NSScrollView` (ScrollViews).
4. Once the `NSTouchBarItem` is initialized, its properties are populated with
   an assortment of "update" methods. These include `updateButton`,
   `updateMainButton`, `updateLabel`, `updatePopover`, and
   `updateScrollView`.
5. Since the localization of `TouchBarInput` titles happens asynchronously in
   JavaScript code, the l10n callback executes
   `[nsTouchBarUpdater updateTouchBarInputs:]`. This method reads the
   identifier of the input(s) that need to be updated and calls their respective
   "update" methods. This method is most often used to update `title` after
   l10n is complete. It can also be used to update any property of a
   `TouchBarInput`; for instance, one might wish to change `color`
   when a specific event occurs in the browser.

[harry twyford]: mailto:<harry@mozilla.com>
[human interface guidelines]: https://developer.apple.com/design/human-interface-guidelines/macos/touch-bar/touch-bar-overview/
[official documentation]: https://developer.apple.com/documentation/appkit/nstouchbar?language=objc

---

### Browser Components Uitour Docs Index (`browser/components/uitour/docs/index.md`)

# UITour

```{toctree}
UITour-lib
```

```{js:autoclass} Mozilla.UITour
:members: none
```

---

### Browser Components Urlbar Docs Index (`browser/components/urlbar/docs/index.md`)

# Address Bar and Search Bars

This document describes the implementation of Firefox's address bar, also known
as the quantumbar or urlbar. The address bar was also called the awesomebar
until Firefox 68, when it was substantially rewritten.

The same code also runs the search bar in the toolbar and the search bar on the
New Tab page, so most of these pages apply to all three.

The address bar is a specialized search access point that aggregates data from
several different sources, including:

- Places (Firefox's history and bookmarks system)
- Search engines (including search suggestions)
- WebExtensions
- Open tabs

## Where to Start

If you want a high level, nontechnical summary of how the address bar works,
read {doc}`nontechnical-overview`.

If you are interested in the technical details, you might want to skip ahead to
{doc}`overview`.

## Codebase

The code lives in {searchfox}`browser/components/urlbar <browser/components/urlbar/>`,
which is where the often-used *urlbar* shorthand comes from.

## Table of Contents

```{toctree}
nontechnical-overview
overview
lifetime
process-boundary
message-path
utilities
telemetry
firefox-suggest-telemetry
debugging
ranking
dynamic-result-types
adding-a-search-bar
preferences
testing
contact
```

## API Reference

```{toctree}
ProvidersManager
UrlbarChildController
UrlbarInputBase
UrlbarMuxer
UrlbarParentController
UrlbarProvider
UrlbarQueryContext
UrlbarResult
UrlbarView
```

---

### Browser Components Urlbar Docs Nontechnical Overview (`browser/components/urlbar/docs/nontechnical-overview.md`)

(urlbar-nontechnical-overview)=

# Nontechnical Overview

This document provides a high level, nontechnical overview of Firefox's address
bar, with a focus on the different types of results it shows and how it chooses
them.

```{contents}
:depth: 2
```

## Terminology

This document uses a small number of terms of art that would be helpful to
understand up front.

Input

: The text box component of the address bar. In contrast, we use "address bar"
  to refer to the whole system comprising the input, the view, and the logic
  that determines the results that are shown in the view based on the text in
  the input.

Result

: An individual item that is shown in the view. There are many different types
  of results, including bookmarks, history, open tabs, and search suggestions.

View

: The panel that opens below the input when the input is focused. It contains
  the results.

## Maximum Result Count

The view shows a maximum of 10 results by default. This number is controlled by
a hidden preference, `browser.urlbar.maxRichResults`.

## Search Strings

If the user has not modified the text in the input or the text in the input is
empty, we say that the user's **search string** is empty, or in other words,
there is no search string. In contrast, when the user has modified the text in
the input and the text is non-empty, then the search string is that non-empty
text.

:::{figure} assets/nontechnical-overview/empty-url.png
:align: center
:alt: Image of the address bar input showing a URL
:scale: 50%

Empty search string: The input text has not been modified
:::

:::{figure} assets/nontechnical-overview/empty-placeholder.png
:align: center
:alt: Image of the address bar input showing its placeholder text
:scale: 50%

Empty search string: The input text is empty (and the input is showing its
placeholder text)
:::

:::{figure} assets/nontechnical-overview/non-empty.png
:align: center
:alt: Image of the address bar input showing "porcupines" text
:scale: 50%

Non-empty search string: The input text has been modified and is non-empty
:::

The distinction between empty and non-empty search strings is helpful to
understand for the following sections.

## Top Sites

When the search string is empty and the user focuses the input, the view opens
and shows the user's top sites. They are the same top sites that appear on the
new-tab page except their number is capped to the maximum number of address bar
results (10). If the user has fewer top sites than the maximum number of results
(as is the case in a new profile), then only that number of results is shown.

:::{figure} assets/nontechnical-overview/top-sites.png
:align: center
:alt: Image of the address bar view showing top sites
:scale: 50%

Top sites on a new en-US profile
:::

This behavior can be turned off by going to <about:preferences#privacy> and
unchecking “Shortcuts” in the “Address Bar” section. In that case, the view
closes when the search string is empty.

## Searches

When the search string is non-empty, the address bar performs a search and
displays the matching results in the view. Multiple separate searches of
different sources are actually performed, and the results from each source are
combined, sorted, and capped to the maximum result count to display the final
list of results. In address bar terminology, each source is called a
**provider**.

Each provider produces one or more types of results based on the search
string. The most common result types include the following (not exhaustive):

:::{figure} assets/nontechnical-overview/search-suggestion.png
:align: center
:alt: Image of a search suggestion result with text "porcupine meatballs"
:scale: 50%

Search suggestions from the user's default engine (magnifying glass icon)
:::

:::{figure} assets/nontechnical-overview/form-history.png
:align: center
:alt: Image of a previous search result with text "porcupines"
:scale: 50%

Previous searches the user has performed from the address bar and search bar
(clock icon)
:::

:::{figure} assets/nontechnical-overview/bookmark.png
:align: center
:alt: Image of a bookmark result with text "Porcupine - Wikipedia"
:scale: 50%

Bookmarks
:::

:::{figure} assets/nontechnical-overview/history.png
:align: center
:alt: Image of a history result with text "Porcupines | National Geographic"
:scale: 50%

History
:::

:::{figure} assets/nontechnical-overview/open-tab.png
:align: center
:alt: |-
:  Image of an open tab result with text "Porcupines \| San Diego Zoo
:  Animals & Plants"
:scale: 50%

Open tabs (switch to tab)
:::

:::{figure} assets/nontechnical-overview/remote-tab.png
:align: center
:alt: |-
:  Image of a remote tab result with text "Porcupine \| rodent \|
:  Britannica"
:scale: 50%

Remote tabs (via Sync)
:::

How the address bar combines and sorts results from different providers is
discussed below in [Result Composition].

## The Heuristic Result

The first result in the view is special and is called the **heuristic**
result. As the user types each character in their search string, the heuristic
result is updated and automatically selected, and its purpose is to show the
user what will happen when they press the enter key without first selecting a
(non-heuristic) result. The heuristic result is so called because it shows
Firefox's best guess for what the user is trying to do based on their search
string.

The heuristic result is determined by running through a number of different
heuristics and picking the one that first matches the search string. The most
important heuristics in the order that Firefox runs through them are:

*Is the search string...*

1. An omnibox extension keyword? Extensions using the omnibox API can register
   keywords by which they become activated.

2. A bookmark keyword? The user can associate a keyword with each bookmark.
   Typing a bookmark keyword plus an optional search string and pressing enter
   will visit the bookmark.

   :::{figure} assets/nontechnical-overview/bookmark-keyword.png
   :align: center
   :alt: |-
   :  Image of the address bar input with text "bug 1677126" and a
   :  bookmark keyword heuristic result
   :scale: 50%

   Typing "bug" triggers a Bugzilla bookmark with the keyword "bug"
   :::

3. A domain name or URL that should be autofilled? **Autofill** is the name of
   the feature where the input completes the domain names and URLs of bookmarks
   and frequently visited sites as the user is typing them. (Firefox autofills
   “to the next slash”, meaning it first autofills domain names and then partial
   paths.)

   :::{figure} assets/nontechnical-overview/autofill.png
   :align: center
   :alt: |-
   :  Image of the address bar input with text "mozilla.org/" with
   :  "illa.org/" selected and an autofill heuristic result
   :scale: 50%

   After typing "moz", the rest of mozilla.org is automatically completed
   :::

4. A valid URL? If so, visit the URL. (This includes fixing common typos like
   “mozilla..org” and “mozilla.ogr”. Valid URLs are based on the [Public Suffix
   List][public suffix list]. The user can also specify an allow-list using hidden preferences to
   support domains like localhost.)

   :::{figure} assets/nontechnical-overview/visit.png
   :align: center
   :alt: |-
   :  Image of the address bar input with text "porcupine-fancy.org" and a
   :  visit heuristic result
   :scale: 50%

   Typing a URL that isn't bookmarked or in history
   :::

5. Ultimately fall back to performing a search using the default engine. (The
   user can opt out of this fallback by setting the hidden preference
   `keyword.enabled` to false. In that case, Firefox stops at the previous
   step and attempts to visit the user's search string as if it were a URL.)

   :::{figure} assets/nontechnical-overview/search-heuristic.png
   :align: center
   :alt: |-
   :  Image of the address bar input with text "porcupines" and a search
   :  heuristic result
   :scale: 50%

   Typing a string that will perform a search using the default engine
   :::

## Result Composition

For a given search string, the address bar performs multiple separate searches
of different providers and then combines their results to display the final
list. The way in which results are combined and sorted is called **result
composition**. Result composition is based on the concept of result groups, one
group after another, with different types of results in each group.

The default result composition is described next, starting with the first
result.

### 1. Heuristic Result

The first result is always the heuristic result.

### 2. Extension Omnibox Results

The next group of results is those provided by extensions using the omnibox
API. Most users never encounter these results because they are provided only by
extensions that use this feature, and even then the user must type certain
extension-defined keywords to trigger them. There are at most 6 results in this
group.

### 3. Search Suggestions

The next group is search suggestions. Typically this group contains 6 results,
but the exact number depends on certain factors described later in [Result
Composition Nuances](#result-composition-nuances). There are actually three types of search suggestions:

- Previous searches the user has performed from the address bar and search bar
  (denoted with a clock icon):

  ```{image} assets/nontechnical-overview/form-history.png
  :align: center
  :alt: Image of a previous search result with text "porcupines"
  :scale: 50%
  ```

  This is the only type of search suggestion that is generated by Firefox alone,
  without the help of a search engine. When the user performs a search using an
  engine from the address bar or search bar (and only the address bar and search
  bar), Firefox stores the search string, and then when the user starts to type
  it again, Firefox includes it as a result to make it easy to perform past
  searches. (Firefox does not store search strings used within web pages like
  google.com.)

- Suggestions from the user's default engine (denoted with a magnifying glass
  icon):

  ```{image} assets/nontechnical-overview/search-suggestion.png
  :align: center
  :alt: Image of a search suggestion result with text "porcupine meatballs"
  :scale: 50%
  ```

  These are fetched from the engine if the engine provides the necessary access
  point. The ordering and total number of these suggestions is determined by the
  engine.

- Google-specific "tail" suggestions, which look like "... foo" and are provided
  for long and/or specific queries to help the user narrow their search:

  ```{image} assets/nontechnical-overview/tail-suggestions.png
  :align: center
  :alt: |-
  :  Image of a tail suggestion results with text "porcupine abc def" in
  :  the input and two suggestions with text "... definition " and
  :  "... defense"
  :scale: 50%
  ```

  These are fetched from Google when Google is the user's default engine. The
  ordering and total number of these suggestions is determined by Google.

The search suggestions group typically contains two previous searches followed
by four engine suggestions, but the exact numbers depend on the number of
matching previous searches and engine suggestions. Previous searches are limited
in number so that they don’t dominate this group, allowing remote suggestions to
provide content discovery benefits. Tail suggestions are shown only when there
are no other suggestions.

The user can opt out of showing search suggestions in the address bar by
visiting <about:preferences#search> and unchecking "Provide search suggestions" or
"Show search suggestions in address bar results".

### 4. General Results

The final group of results is a general group that includes the following types:

- Bookmarks
- History
- Open tabs (switch to tab)
- Remote tabs (via Sync)
- Sponsored and Firefox Suggest results (part of the Firefox Suggest feature)

This general group is labeled "Firefox Suggest" in the Firefox Suggest feature.

Typically this group contains 3 results, but as with search suggestions, the
exact number depends on certain factors (see [Result Composition Nuances]).

Most results within this group are first matched against the search string on
their titles and URLs and then sorted by a metric called **frecency**, a
combination of how frequently and how recently a page is visited. The top three
results are shown regardless of their specific types.

This is the only group that is sorted by frecency.

A few important complexities of this group are discussed in the next
subsections. The final subsection describes frecency in more detail.

#### Adaptive History

The first few bookmark and history results in the general group may come from
**adaptive history**, a system that associates specific user search strings with
URLs. (It's also known as **input history**.) When the user types a search
string and picks a result, Firefox stores a database record that associates the
string with the result's URL. When the user types the string or a part of it
again, Firefox will try to show the URL they picked last time. This allows
Firefox to adapt to a user's habit of visiting certain pages via specific search
strings.

This mechanism is mostly independent of frecency. URLs in the adaptive history
database have their own sorting score based on how many times they have been
used in the past. The score decays daily so that infrequently used search
strings and URLs aren't retained forever. (If two adaptive history results have
the same score, they are secondarily sorted by frecency.)

Within the general group, the number of adaptive history results is not limited,
but typically there aren't many of them for a given search string.

#### Open and Remote Tabs

Unlike bookmarks and history, open and remote tabs don't have a "natural"
frecency, meaning a frecency that's updated in response to user actions as
described below in [Frecency]. Tabs that match the search string are assigned
constant frecencies so they can participate in the sorting within the general
group. Open tabs are assigned a frecency of 1000, and remote tabs are assigned a
frecency of 1001. Picking appropriate frecencies is a bit of an art, but Firefox
has used these values for some time.

#### Sponsored and Firefox Suggest Results

Sponsored and Firefox Suggest results are an exception within this group. They
are matched on predetermined keywords, and when present, they always appear last
in the general group. Frecency isn't involved at all.

#### Frecency

Frecency is a complex topic on its own, but in summary, each URL stored in
Firefox's internal history database has a numeric score, the frecency,
associated with it. Larger numbers mean higher frecencies, and URLs with higher
frecencies are more likely to be surfaced to the user via the address bar. Each
time the user visits a URL, Firefox increases its frecency by a certain "boost"
amount that depends on how the visit is performed -- whether the user picked it
in the address bar, clicked its link on a page, clicked it in the history
sidebar, etc. In order to prevent frecencies from growing unbounded and to
penalize URLs that haven't been visited in a while, Firefox decays the
frecencies of all URLs over time.

For details on frecency, see [The Frecency Algorithm].

### Preferences that Affect Result Composition

There are a number of options in <about:preferences> that affect result
composition.

The user can opt out of showing search suggestions in the address bar by
unchecking "Provide search suggestions" or "Show search suggestions in address
bar results" in <about:preferences#search>. (The first checkbox applies to both
the address bar and search bar, so it acts as a global toggle.)

:::{figure} assets/nontechnical-overview/prefs-show-suggestions.png
:align: center
:alt: |-
:  Image of the preferences UI that allows the user to opt out of search
:  suggestions
:scale: 50%

Preferences allowing the user to opt out of search suggestions
:::

By default, the search suggestions group is shown before the general results
group, but unchecking "Show search suggestions ahead of browsing history in
address bar results" in <about:preferences#search> does the opposite. In that
case, typically the general results group will contain at most 6 results and the
search suggestions group will contain at most 3. In other words, regardless of
which group comes first, typically the first will contain 6 results and the
second will contain 3.

:::{figure} assets/nontechnical-overview/prefs-suggestions-first.png
:align: center
:alt: |-
:  Image of the preferences UI that allows the user to choose whether
:  search suggestions are shown before general results
:scale: 50%

Preference allowing the user to choose which group is shown first
:::

The “Address Bar” section in <about:preferences#privacy> has several checkboxes
that allow for finer control over the types of results that appear in the view.
The top sites feature can be turned off by unchecking “Shortcuts” in this
section.

:::{figure} assets/nontechnical-overview/prefs-privacy.png
:align: center
:alt: |-
:  Image of the preferences UI that allows the user to choose which
:  results are shown
:scale: 50%

Preferences allowing the user to choose which results are shown
:::

## Result Composition Nuances

Among the search suggestions and general results groups, the group that's shown
first typically contains 6 results and the other group contains 3 results. The
exact number in each group depends on several factors:

- The total maximum result count (controlled by the
  `browser.urlbar.maxRichResults` hidden preference).

  The total number of results in the two groups scales up and down to
  accommodate this number so that the view is always full of results.

- The number of extension results.

  The extension results group comes before both groups, so if there are any
  extension results, there are fewer available slots for search suggestions and
  general results.

- The number of matching results.

  The search string may match only one or two search suggestions or general
  results, for example.

- The number of results in the other group.

  The first group will try to contain 6 results and the second will try to
  contain 3, but if either one is unable to fill up, then the other group will
  be allowed to grow to make up the difference.

## Other Result Types

The most common result types are discussed above. This section walks through the
other types.

An important trait these types have in common is that they do not belong to any
group. Most of them appear at specific positions within the view.

### Search Interventions

Search interventions help the user perform a task based on their search string.
There are three kinds of interventions, and each is triggered by typing a
certain set of {searchfox}`phrases <firefox-main/rev/88b0f8e6a5925058755d2671bdac5a76d84bd224:browser/components/urlbar/UrlbarProviderInterventions.sys.mjs#171>` in the input. They always appear as the second result,
after the heuristic result.

The three kinds of interventions are:

:::{figure} assets/nontechnical-overview/intervention-clear.png
:align: center
:alt: |-
:  Image of the clear intervention result with text "Clear your cache,
:  cookies, history and more"
:scale: 50%

Clear history, cache, and other data search intervention
:::

:::{figure} assets/nontechnical-overview/intervention-refresh.png
:align: center
:alt: |-
:  Image of the refresh intervention result with text "Restore default
:  settings and remove old add-ons for optimal performance"
:scale: 50%

Refresh Firefox search intervention
:::

:::{figure} assets/nontechnical-overview/intervention-update.png
:align: center
:alt: |-
:  Image of the update intervention result with text "The latest Firefox
:  is downloaded and ready to install"
:scale: 50%

Update Firefox search intervention
:::

Currently this feature is limited to English-speaking locales, but work is
ongoing to build a more sophisticated intent-matching platform to support other
locales, more complex search strings, and more kinds of interventions.

### Search Tips

Search tips inform the user they can perform searches directly from the
address bar. There are two kinds of search tips:

:::{figure} assets/nontechnical-overview/search-tip-onboard.png
:align: center
:alt: |-
:  Image of the onboarding search tip with text "Type less, find more:
:  Search Google right from your address bar"
:scale: 50%

Onboarding search tip: Appears on the new-tab page
:::

:::{figure} assets/nontechnical-overview/search-tip-redirect.png
:align: center
:alt: |-
:  Image of the redirect search tip with text "Start your search in the
:  address bar to see suggestions from Google and your browsing history"
:scale: 50%

Redirect search tip: Appears on the home page of the user's default engine
(only for Google, Bing, and DuckDuckGo)
:::

In each case, the view automatically opens and shows the tip even if the user is
not interacting with the address bar. Each tip is shown at most four times, and
the user can stop them from appearing altogether by interacting with the address
bar or clicking the "Okay, Got It" button.

### Tab to Search

Tab to search allows the user to press the tab key to enter [search mode] while
typing the domain name of a search engine. There are two kinds of tab-to-search
results, and they always appear as the second result:

:::{figure} assets/nontechnical-overview/tab-to-search-onboard.png
:align: center
:alt: Image of the tab-to-search result with text "Search with Google"
:scale: 50%

Onboarding tab to search
:::

:::{figure} assets/nontechnical-overview/tab-to-search-regular.png
:align: center
:alt: Image of the tab-to-search result with text "Search with Google"
:scale: 50%

Regular tab to search
:::

The onboarding type is shown until the user has interacted with it three times
over a period of at least 15 minutes, and after that the regular type is shown.

### Search Engine Offers

Typing a single “@” shows a list of search engines. Selecting an engine enters
[search mode].

:::{figure} assets/nontechnical-overview/search-offers.png
:align: center
:alt: Image of the view showing search offer results
:scale: 50%

Search engine offers after typing “@”
:::

:::{figure} assets/nontechnical-overview/search-offers-selected.png
:align: center
:alt: Image of the view showing search offer results with one selected
:scale: 50%

After pressing the down arrow key to select Google
:::

## Search Mode

**Search mode** is a feature that transforms the address bar into a search-only
access point for a particular engine. During search mode, search suggestions are
the only results shown in the view, and for that reason its result composition
differs from the usual composition.

:::{figure} assets/nontechnical-overview/search-mode.png
:align: center
:alt: Image of the view showing search mode
:scale: 50%

Search mode with Google as the selected engine
:::

Firefox shows suggestions in search mode even when the user has otherwise opted
out of them. Our rationale is that by entering search mode, the user has taken
an action that overrides their usual opt out. This allows the user to opt out
generally but opt back in at specific times.

Search mode is an effective replacement for the legacy search bar and may
provide a good path forward for deprecating it.

The user can enter search mode in many ways:

- Picking a search shortcut button at the bottom of the view
- Typing an engine's keyword (which can be set in <about:preferences#search>, and
  built-in engines have default keywords)
- Typing a single "?" followed by a space (to enter search mode with the default
  engine)
- Typing a single "@" to list all engines and then picking one
- If the search bar is not also shown, pressing Ctrl+K (to enter search mode
  with the default engine)

To exit search mode, the user can backspace over the engine chiclet or click its
close button.

[public suffix list]: https://publicsuffix.org/
[the frecency algorithm]: https://docs.google.com/document/d/10LRRXVGWWWcjEZIZ2YlEmuKkQqh2RaTclStFHNnPqQ8/edit#heading=h.588hanspexub

---

### Browser Components Urlbar Docs Overview (`browser/components/urlbar/docs/overview.md`)

(urlbar-architecture-overview)=

# Architecture

The address bar and the search bars are implemented as a
*model-view-controller* (MVC) system. One of the scopes of this architecture is
to allow easy replacement of its components, for easier experimentation.

Each search is represented by a unique object, the *UrlbarQueryContext*. This
object, created by the *View*, describes the search and is passed through all of
the components, along the way it gets augmented with additional information.
The *UrlbarQueryContext* is passed to the *Controller*, and finally to the
*Model*. The model appends results to a property of *UrlbarQueryContext* in
chunks, it sorts them through a *Muxer* and then notifies the *Controller*.

See the specific components below, for additional details about each one's tasks
and responsibilities.

## The UrlbarQueryContext

The *UrlbarQueryContext* object describes a single instance of a search.
It is augmented as it progresses through the system, with various information.
{doc}`UrlbarQueryContext` lists its properties.

## The Model

The *Model* is the component responsible for retrieving search results based on
the user's input, and sorting them accordingly to their importance.
At the core is the {searchfox}`ProvidersManager <browser/components/urlbar/UrlbarProvidersManager.sys.mjs>`,
a component tracking all the available search providers, and managing searches
across them.

The *ProvidersManager* is a singleton, it registers internal providers on
startup and can register/unregister providers on the fly.
It can manage multiple concurrent queries, and tracks them internally as
separate *Query* objects.

The *Controller* starts and stops queries through the *ProvidersManager*.
It's possible to wait for the promise returned by *startQuery* to know when no
more results will be returned, it is not mandatory though.
Queries can be canceled.

:::{note}
Canceling a query will issue an interrupt() on the database connection,
terminating any running and future SQL query, unless a query is running inside
a *runInCriticalSection* task.
:::

The *searchString* gets tokenized by the {searchfox}`UrlbarTokenizer <browser/components/urlbar/UrlbarTokenizer.sys.mjs>`
component into tokens, some of these tokens have a special meaning and can be
used by the user to restrict the search to specific result type (See the
*UrlbarTokenizer::TYPE* enum).

:::{caution}
The tokenizer uses heuristics to determine each token's type, as such the
consumer may want to check the value before applying filters.
:::

{doc}`ProvidersManager` documents the *ProvidersManager* API.

### UrlbarProvider

A provider is specialized into searching and returning results from different
information sources. Internal providers are usually implemented in separate
*sys.mjs* modules with a *UrlbarProvider* name prefix. External providers can be
registered as *Objects* through the *ProvidersManager*.
Each provider is independent and must satisfy a base API, while internal
implementation details may vary deeply among different providers.

:::{important}
Providers are singleton, and must track concurrent searches internally, for
example mapping them by UrlbarQueryContext.
:::

:::{note}
Internal providers can access the Places database through the
*PlacesUtils.promiseLargeCacheDBConnection* utility.
:::

{doc}`UrlbarProvider` documents the API a provider implements.

### UrlbarMuxer

The *Muxer* is responsible for sorting results based on their importance and
additional rules that depend on the UrlbarQueryContext. The muxer to use is
indicated by the UrlbarQueryContext.muxer property.

:::{caution}
The Muxer is a replaceable component, as such what is described here is a
reference for the default View, but may not be valid for other implementations.
:::

{doc}`UrlbarMuxer` documents the API a muxer implements.

## The Controller

The controller is responsible for reacting to the user's input, by communicating
the proper course of action to the Model (e.g. starting/stopping a query) and the
View (e.g. showing/hiding a panel). It is also responsible for reporting Telemetry.

It is split into two classes:

- {searchfox}`UrlbarParentController <browser/components/urlbar/UrlbarParentController.sys.mjs>`
  runs in the parent process. It owns the *ProvidersManager*, drives the query
  lifecycle, and reports Telemetry.
- {searchfox}`UrlbarChildController <browser/components/urlbar/content/UrlbarChildController.mjs>`
  lives alongside the *View* (in a content process for about:newtab, or in the
  parent process for the toolbar). The *Input* and *View* talk to it; it forwards
  query work to the *UrlbarParentController* and dispatches result notifications
  to listeners.

:::{note}
Each *View* has a different controller instance.
:::

{doc}`UrlbarParentController` and {doc}`UrlbarChildController` document the
two classes.

### Direct path and message path

The *UrlbarChildController* reaches its *UrlbarParentController* in one of two
ways, chosen when the controller is created:

- **Direct path.** Both controllers live in the parent process, so the child
  controller creates the parent controller itself and calls it directly. The
  address bar and the search bar in the toolbar use this path.
- **Message path.** The child controller holds a
  {searchfox}`UrlbarParentControllerProxy <browser/components/urlbar/content/UrlbarParentControllerProxy.mjs>`
  instead, which sends each call to the parent process as a message over the
  *Urlbar* JSWindowActor pair.
  {searchfox}`UrlbarParent <browser/components/urlbar/actors/UrlbarParent.sys.mjs>`
  creates the real controller on the other side and sends its notifications
  back. A search bar in a content process, such as the one on about:newtab, uses
  this path.

Both paths give the child controller the same interface, but on the message path
every call and notification is asynchronous. Setting
`browser.urlbar.ipc.chromeMessagePassing` to `true` puts the toolbar's inputs on
the message path too, which lets tests exercise it in the parent process.

On the message path the parent keeps one controller per input. It drops the
controller when the input is garbage collected, or when the input's window
global goes away.

## The View

The View is the component responsible for presenting search results to the
user and handling their input.

% caution
%
% The View is a replaceable component, as such what is described here is a
% reference for the default View, but may not be valid for other implementations.

### {searchfox}`UrlbarInputBase.mjs <browser/components/urlbar/content/UrlbarInputBase.mjs>`

Implements an input box *View*, owns an *UrlbarView*. Each input is a custom
element extending *UrlbarInputBase*: *UrlbarInput* (`<moz-urlbar>`) and
*SearchbarInput* (`<moz-searchbar>`). {doc}`UrlbarInputBase` documents its API.

### {searchfox}`UrlbarView.mjs <browser/components/urlbar/content/UrlbarView.mjs>`

Represents the base *View* implementation, communicates with the *Controller*.
{doc}`UrlbarView` documents its API.

## UrlbarResult

An {searchfox}`UrlbarResult <browser/components/urlbar/content/UrlbarResult.mjs>`
instance represents a single search result with a result type, that
identifies specific kind of results.
Each kind has its own properties, that the *View* may support, and a few common
properties, supported by all of the results.

:::{note}
Result types are also enumerated by *UrlbarShared.RESULT_TYPE*.
:::

{doc}`UrlbarResult` documents its properties.

The following RESULT_TYPEs are supported:

```JavaScript
// An open tab.
// Payload: { icon, url, userContextId }
TAB_SWITCH: 1,
// A search suggestion or engine.
// Payload: { icon, suggestion, keyword, query, providesSearchMode, inPrivateWindow, isPrivateEngine }
SEARCH: 2,
// A common url/title tuple, may be a bookmark with tags.
// Payload: { icon, url, title, tags }
URL: 3,
// A bookmark keyword.
// Payload: { icon, url, keyword, postData }
KEYWORD: 4,
// A WebExtension Omnibox result.
// Payload: { icon, keyword, title, content }
OMNIBOX: 5,
// A tab from another synced device.
// Payload: { icon, url, device, title }
REMOTE_TAB: 6,
// An actionable message to help the user with their query.
// Payload: { buttons, helpL10n, helpUrl, icon, titleL10n, type }
TIP: 7,
// A type of result which layout is defined at runtime.
// Payload: { dynamicType }
DYNAMIC: 8,
```

---

### Browser Extensions Formautofill Docs Index (`browser/extensions/formautofill/docs/index.md`)

# Form Autofill

## Introduction

Form Autofill saves users time and effort when making online purchases by storing their personal information in a profile and automatically populating form fields when the user requires it.

Our objective is to increase user engagement, satisfaction and retention for frequent online shoppers (those who make an online purchase at least once per month). We believe this can be achieved by enabling users to complete forms and “check out” in e-commerce flows as quickly and securely as possible.

Form Autofill handles filling in addresses and credit cards into forms. While the filling aspect of this is straightforward and uses the same mechanism as other autocomplete types, much of the additional work involves analyzing and classifying the form to determine which form field corresponds to which type of data. For instance, text boxes are classified into different types of address data.

For historical reasons, part of the form autofill is implemented using an extension, located in {searchfox}`browser/extensions/formautofill`. It is this extension which adds the form autofill actors used to handle the search for possible results. However, most of the work is done via code in {searchfox}`toolkit/components/formautofill`.

Form Autofill uses the autocomplete popup mechanism to show a list of suggestions to the user based on what they have typed so far. The user can also press the cursor key or tab key to open the autocomplete popup while the focus is within a field.

For more information about autocomplete, see {doc}`Autocomplete </toolkit/components/autocomplete/docs/index>`.

## How Form Autofill Works

The form fill actor `FormAutofillChild` waits for form fields to be focused. When a field is focused, it starts the process of analyzing the form and picking out which fields might be address or credit card related. This process is primarily done by the `getFormInfo` function within {searchfox}`FormAutofillHeuristics.sys.mjs <toolkit/components/formautofill/shared/FormAutofillHeuristics.sys.mjs>`. This process is separate from the mechanism used to trigger an autocomplete popup.

Form Autofill can handle filling in \<input>, \<textarea> and \<select> elements.

There are three mechanisms that can be used to identify a field:

1. **autocomplete attributes**: authors may place an autocomplete attribute on a form field to identify its purpose. This is most likely to be correct although sometimes authoring errors will occur and we attempt to fix some common cases.
2. **fathom**: Fathom is a simple learning system that uses a selection of rules to identify credit card related fields. It currently is used to detect the credit card name and number fields (`cc-name` and `cc-number`) but does not detect other credit card fields or operate on address fields.
3. **regular expressions**: a large list of regular expressions located in {searchfox}`HeuristicsRegExp.sys.mjs <toolkit/components/formautofill/shared/HeuristicsRegExp.sys.mjs>` that is used to match the ids, names, placeholders and labels associated with form elements. This is where most of the analysis of form fields is done for addresses.

The `element.getAutocompleteInfo()` function provides the parsed result of `autocomplete` attribute which includes the field name and section information defined in [autofill spec](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill)

Each field in a form is classified into a number of different field types, for example: `email`, `address-line1`, `country` and so on. Many fields will not be able to be placed into a definite type, and many forms will have multiple fields classified with the same type. Work is ongoing to reduce the number of errors made in classifying fields.

After fields are classified, some additional heuristics are run (within the `parseAndUpdateFieldNamesParent` function in {searchfox}`FormAutofillHeuristics.sys.mjs <toolkit/components/formautofill/shared/FormAutofillHeuristics.sys.mjs>`). These are responsible for further checking for common field classification issues. For example, when multiple address line fields appear in a row, it is likely that they represent a separate line of the address (street, apartment number, building, etc) and appear in order. Another example is that it is common on Japanese web sites to have a separate set of name fields to indicate the pronounciation of one's name; heuristics are included to recognize this situation.

Note that the heuristics within `parseAndUpdateFieldNamesParent` are done within the parent browser process so no longer have access to the form fields directly, so any information needed will need to be stored in the field data (usually called `fieldDetails` within the code).

However, there are a few heuristics in `parseAndUpdateFieldNamesContent` that are done in the web page process beforehand. Most processing happens in the parent process afterwards because all of the form fields across different subframes (iframes) can be searched and collected together as a single form. There are a number of web sites that break up each field into separate child iframes.

Once fields have been identified, they are split into sections. Some sites will have multiple sections for addresses, one for a billing address and one for a shipping address. This handling is done by groupFields within {searchfox}`FormAutofillSection.sys.mjs <toolkit/components/formautofill/shared/FormAutofillSection.sys.mjs>`. The `autocomplete` attribute may be used on a field in a web page to be explicit about which section to use for that field, but otherwise the heuristics try to determine this automatically.

Once the fields are identified, a message is sent back to the child process so that `markAsAutoCompletableField()` may be called on each detected field, allowing the autocomplete actor to recognize that the form fill actor is able to provide results for that form field. In addition, the section and form field details are saved in the field `sectionsByRootId` within `FormAutofillParent` to that they may be retreived when the autocomplete is performed.

Once `markAsAutoCompletableField()` is called for a field, form autofill is available for that field and the user's saved address and credit card information will be examined to see if they apply as possible suggestions in the autocomplete dropdown popup when the user enters or types into that field.

## Additional Cases

- Some fields do not exist in \<form> elements. In this case, the entire document is used as if it was a form.
- Sometimes a set of fields will be split across multiple child iframes. These forms are processed together and explains why some heuristics are performed in the browser process after all of the frames have been analyzed, instead of in the web page child process.
- Often a web site will change the form in response to a user change. For example, changing the country in a form will change other fields to correspond to fields specific to that country. This is referred to as a dynamic form and is handled by rescanning the form and picking out any differences.

## Country Meta Data

The specifics for each region is defined in the file {searchfox}`AddressMetaData.sys.mjs <toolkit/components/formautofill/shared/AddressMetaData.sys.mjs>`. This file contains information about the regions in each country, postal code formats, languages used in each region and so forth. This file contains links to documentation about the format of this data and is a good place to look for information that might be country specific. For example, when we look at data for Brazil, we can see a list of states (federative units), and also see that Brazil has defined a "sublocality_name_type" field which indicates a third level of region besides state and city, used for the neighborhood. The neighborhood appears in the address preference dialog when adding Brazilian addresses and can be autofilled as needed. Most other regions do not include a neighborhood field.

## Form Submission

When a form is submitted, a prompt may be show asking the user if they wish to save the address or credit card information. This helps the user realize that the autofill capability is available. The filled in data on the form can optionally be automatically saved as a new address or credit card. This is done within the `onFormSubmit` function of {searchfox}`FormAutofillParent <toolkit/components/formautofill/FormAutofillParent.sys.mjs>`.

In general, however, we do not show the prompt to save a new address or credit card if the user has not filled in enough fields, fillin is disabled in the user's region, or the form does not contain the right fields. Which fields are necessary is dependent on the region. For example, typically, a street, city and postal code is required. The specific data needed to save the form data is determined from the {searchfox}`AddressMetaData.sys.mjs <toolkit/components/formautofill/shared/AddressMetaData.sys.mjs>` as described above.

If an address is determined to be the same as an existing saved address, the prompt does not appear. Some heuristics within
{searchfox}`AddressParser.sys.mjs <toolkit/components/formautofill/shared/AddressParser.sys.mjs>` are used to determine if the address is the same as an existing saved address, because this can be inexact matching, for example, 'Floor 2' and '2nd floor' are different strings but refer to the same thing. This ensures that the amount of times the user is prompted is reduced when the address is similar.

## Report Issues

If you find any issues about filling a form with incorrect values, please file a [new bug](https://bugzilla.mozilla.org/enter_bug.cgi?product=Toolkit&component=Form%20Autofill) to Toolkit::Form Autofill component.

---

### Browser Extensions Newtab Docs Index (`browser/extensions/newtab/docs/index.md`)

# Firefox Home (New Tab)

All files related to Firefox Home, which includes content that appears on `about:home` and
`about:newtab`, can be found in the `browser/extensions/newtab` directory.
Some of these source files (such as `.js`, `.jsx`, and `.scss`) require an additional build step.
We are working on migrating this to work with `mach`, but in the meantime, please
follow the following steps if you need to make changes in this directory:

## For `.sys.mjs` files (system modules)

No build step is necessary. Use `mach` and run mochitests according to your regular Firefox workflow.

## For `.js`, `.jsx`, `.scss`, or `.css` files

### Prerequisites

You will need the following:

- Node.js 10+ (On Mac, the best way to install Node.js is to use the install link on the [Node.js homepage])
- npm (packaged with Node.js)

To install node dependencies, run the following from the root of the mozilla-central repository.
(This command uses `mach` to call `npm` and `node` commands to ensure the correct versions of Node and npm are being referenced.)

```shell
./mach newtab install
```

**IMPORTANT NOTE**: If you're using Windows, you may need to run the install command differently:

```shell
(cd browser/extensions/newtab && ../../../mach npm install)
```

### Which files should you edit?

You should not make changes to `.js` or `.css` files in `browser/extensions/newtab/css` or
`browser/extensions/newtab/data` directory. Instead, you should edit the `.jsx`, `.js`, and `.scss` source files
in `browser/extensions/newtab/content-src` directory. These files will be compiled into the `.js` and `.css` files.

## Building assets and running Firefox

To build assets and run Firefox, run the following from the root of the mozilla-central repository:

```shell
./mach newtab bundle && ./mach build && ./mach run
```

## Continuous development / debugging

For near real-time reloading, run the following commands in **two separate terminals** to automatically rebuild bundled files whenever JSX or SCSS files change. After making a change, [restart your local instance](/devtools-user/browser_console/index.md#controlling-the-browser) to apply the updates. Run the following terminal commands:

```shell
./mach newtab watch
```

```shell
./mach run
```

**IMPORTANT NOTE**: This task will add inline source maps to help with debugging, which changes the memory footprint. Do not use the `watch` task for profiling or performance testing! After finishing your work, **be sure to stop the watch process**. When stopped, it will automatically run a final bundle step to remove the temporary inline source maps.

## Pre-commit git hook

A pre-commit hook is available in `tools/lint/hooks_newtab.py`. When installed,
it runs the following checks in order, stopping at the first failure:

1. **Bundle** — if newtab source or bundle output files are staged, runs
   `./mach newtab bundle` and blocks the commit if the output files differ
   from what is staged.
2. **Lint** — runs [mozlint](https://firefox-source-docs.mozilla.org/code-quality/lint/usage.html)
   on staged files and blocks the commit if there are errors.
3. **Tests** — optionally runs unit tests (configurable, disabled by default).

To install the hook, run the following from the root of the mozilla-central repository:

```shell
ln -sf "$(git rev-parse --show-toplevel)/tools/lint/hooks_newtab.py" \
       "$(git rev-parse --show-toplevel)/.git/hooks/pre-commit"
```

By default, no tests are run on commit. To configure which tests run, use
`git config newtab.pre-commit.tests` with one of the following values:

```shell
git config newtab.pre-commit.tests jest       # Jest only (~30 seconds)
git config newtab.pre-commit.tests all        # all tests including xpcshell and browser (10+ minutes)
git config newtab.pre-commit.tests none       # skip tests (default)
```

To commit despite failing tests, use `git commit --no-verify` to bypass the hook entirely.

## Running tests

New Tab unit tests are written using [Jest](https://jestjs.io) and
[React Testing Library](https://testing-library.com/docs/react-testing-library/intro/),
and other errors that may show up there are
[SCSS](https://sass-lang.com/documentation/syntax) issues flagged by
[stylelint](https://stylelint.io). These things are all run using
`npm test` under the `node(newtab)` slug in Treeherder/Try, so if that slug turns
red, these tests are what is failing. To execute them, do this:

```shell
./mach npm test --prefix=browser/extensions/newtab
```

These tests are not currently run by `mach test`, but there's a
[task filed to fix that](https://bugzilla.mozilla.org/show_bug.cgi?id=1581165).

Windows isn't currently supported by `npm test`
([path/invocation difference](https://bugzilla.mozilla.org/show_bug.cgi?id=1737419)).
To run newtab specific tests that aren't covered by `mach lint` and
`mach test`:

```shell
./mach npm run lint:stylelint --prefix=browser/extensions/newtab
./mach npm run testmc:jest --prefix=browser/extensions/newtab
```

Mochitests and xpcshell tests run normally, using `mach test`.

## Code Coverage

CI collects Jest code coverage for the unit tests and reports it to the code
coverage tools and Searchfox. There are no coverage thresholds.

To inspect the coverage report locally, run

```shell
./mach npm run testmc:jest:coverage --prefix=browser/extensions/newtab &&
./mach npm run debugcoverage --prefix=browser/extensions/newtab
```

## Discovery Stream Developer tools

You can access the developer tools for the Discovery Stream components of <about:newtab> by
visiting `about:config` and setting `browser.newtabpage.activity-stream.asrouter.devtoolsEnabled`
to `true`.

Then, go to any `about:newtab` page and click on the wrench icon in the top-right corner.

## Detailed Docs

```{toctree}
:glob: true
:titlesonly: true

v2-system-addon/*
```

[node.js homepage]: https://nodejs.org/

---

### Browser Installer Windows Docs Index (`browser/installer/windows/docs/index.md`)

# Installer

The main role of the Firefox installer is to get a user running Firefox as quickly and reliably as possible, while taking all necessary steps to make Firefox an integrated part of the system.

It turns out that the only platform where we need an installer in order to accomplish all of that is Windows. So we only develop and ship and installer for Windows, and on other platforms we distribute a package in a non-executable format typical of applications distributed on that platform.

Currently, the installers are built on the [NSIS](http://nsis.sourceforge.net/Main_Page) installer framework. This is a Windows-only framework which compiles scripts written in its custom language (along with some native plugins) into an executable installer.

We build four different kinds of installers, the {doc}`Stub Installer <StubInstaller>`, the {doc}`Full Installer <FullInstaller>`, an {doc}`MSI package <MSI>` which wraps the full installer, and an {doc}`MSIX package <MSIX>`. The stub is the default installer intended for most individual users, the full installer and MSI are aimed at power users and administrators who need more control, and the MSIX is aimed at enterprise users who need to control deployment.

There's also another installer-related program, which is called {doc}`helper.exe <Helper>`. It's also written in NSIS and has a few different jobs that involve maintaining things that the installer sets up, including the uninstaller and a post-update routine.

```{toctree}
InstallerBuild
StubInstaller
FullInstaller
MSI
MSIX
Helper
NSISPlugins
```

---

### Devtools Docs Contributor Files README (`devtools/docs/contributor/files/README.md`)

# Directories Overview

This page provides a very top level overview of what is on each directory in the DevTools source code:

* `devtools/shared`: Code shared by both the client (front-end UI) and server. If we are using any third party libraries, or importing external repositories into our tree, those libraries generally live here (eg, `devtools/shared/jsbeautify`), assuming they are used by both client and server.
  * `devtools/shared/client`: Code for the [Remote Debugging Protocol](../backend/protocol.md) (RDP) client. You may wonder why this is not in `devtools/client` below: it's mainly because tests in server also need access to the RDP client.
  * `devtools/shared/locales`: Strings used in either the server only, or shared with both the client and server.
* `devtools/server`: Code for the [RDP](../backend/protocol.md) server and transport layer.
  * `devtools/server/actors`: [RDP Actors](../backend/protocol.md#actors). Note that if you're modifying actors, you may need to worry about [backwards compatibility](../backend/backward-compatibility.md) with older clients.
* `devtools/client`: Code for the front-end side of our tools. In theory, each directory corresponds to a panel, but this is not always the case. This directory is only shipped with desktop Firefox, as opposed to other directories above, which are shipped with all Gecko products (Firefox for Android, etc.)
  * `devtools/client/locales`: Strings used in the client front-end.
  * `devtools/client/themes`: CSS and images used in the client front-end.

---

### Devtools Docs Contributor Tests README (`devtools/docs/contributor/tests/README.md`)

# Automated tests

When working on a patch for DevTools, there's almost never a reason not to add a new test. If you are fixing a bug, you probably should write a new test to prevent this bug from occurring again. If you're implementing a new feature, you should write new tests to cover the aspects of this new feature.

Ask yourself:

* Are there enough tests for my patch?
* Are they the right types of tests?

We use three suites of tests:

* [`xpcshell`](xpcshell.md): Unit-test style of tests. No browser window, only a JavaScript shell. Mostly testing APIs directly.
* [Chrome mochitests](mochitest-chrome.md): Unit-test style of tests, but with a browser window. Mostly testing APIs that interact with the DOM.
* [DevTools mochitests](mochitest-devtools.md): Integration style of tests. Fires up a whole browser window with every test and you can test clicking on buttons, etc.

To run all DevTools tests, regardless of suite type:

```bash
./mach test devtools/*
```

Have a look at the child pages for more specific commands for running only a single suite or single test in a suite.

---

### Devtools Docs Contributor Tests Performance Tests Overview (`devtools/docs/contributor/tests/performance-tests-overview.md`)

# DevTools Performance Tests overview

This page provides a short overview of the various DevTools performance tests.

## damp

DAMP (short for DevTools At Maximum Performance) is the main DevTools performance test suite, based on the talos framework. It mostly runs end to end scenarios, opening the toolbox, various panels and interacting with the UI. It might regress for a wide variety of reasons: DevTools frontend changes, DevTools server changes, platform changes etc. To investigate DAMP regressions or improvements, it is usually necessary to analyze DAMP subtests individually.

See [DAMP Performance tests](performance-tests-damp.md) for more details on how to run DAMP, analyze results or add new tests.

## debugger-metrics

debugger-metrics measures the number of modules and the overall size of modules loaded when opening the Debugger in DevTools. This test is a mochitest which can be executed locally with:

```bash
./mach test devtools/client/framework/test/metrics/browser_metrics_debugger.js --headless
```

At the end of the test, logs should contain a `PERFHERDER_DATA` entry containing 4 measures. `debugger-modules` is the number of debugger-specific modules loaded, `debugger-chars` is the number of characters in said modules. `all-modules` is the number of modules loaded including shared modules, `all-chars` is the number of characters in said modules.

A significant regression or improvement to this test can indicate that modules are no longer lazy loaded, or a new part of the UI is now loaded upfront.

## inspector-metrics

See the description for debugger-metrics. This test is exactly the same but applied to the inspector panel. It can be executed locally with:

```bash
./mach test devtools/client/framework/test/metrics/browser_metrics_inspector.js --headless
```

## netmonitor-metrics

See the description for debugger-metrics. This test is exactly the same but applied to the netmonitor panel. It can be executed locally with:

```bash
./mach test devtools/client/framework/test/metrics/browser_metrics_netmonitor.js --headless
```

## webconsole-metrics

See the description for debugger-metrics. This test is exactly the same but applied to the webconsole panel. It can be executed locally with:

```bash
./mach test devtools/client/framework/test/metrics/browser_metrics_webconsole.js --headless
```

## server.pool

server.pool measures the performance of the DevTools `Pool` [class](https://searchfox.org/firefox-main/source/devtools/shared/protocol/Pool.js) which is intensively used by the DevTools server. This test is a mochitest which can be executed with:

```bash
./mach test devtools/client/framework/test/metrics/browser_metrics_pool.js --headless
```

At the end of the test, logs should contain a `PERFHERDER_DATA` entry which contain values corresponding to various APIs of the `Pool` class.

A regression or improvement in this test is most likely linked to a change in a file from devtools/shared/protocol.

## toolbox:parent-process

toolbox:parent-process measures the number of objects allocated by DevTools after opening and closing a DevTools toolbox. This test is a mochitest which can be executed with:

```bash
./mach test devtools/client/framework/test/allocations/browser_allocations_toolbox.js --headless
```

The test will record allocations while opening and closing the Toolbox several times. The `PERFHERDER_DATA` entry in the logs will contain 3 measures. objects-with-stacks is the number of allocated objects for which the allocation site is known and should be easy to fix for developers. You can refer to the [allocation tests documentation](https://searchfox.org/firefox-main/source/devtools/client/framework/test/allocations/docs/index.md) for a more detailed description of this test and how to use it to investigate and fix memory issues.

A regression here may indicate a leak, for instance a module which no longer cleans its dependencies. It can also indicate that DevTools is loading more singletons or other objects which are not tied to the lifecycle of the DevTools objects.

## target:parent-process

target:parent-process measures the number of objects created by DevTools to create a tab target. It does not involve DevTools frontend. This test is a mochitest which can be executed with:

```bash
./mach test devtools/client/framework/test/allocations/browser_allocations_target.js --headless
```

See the description for toolbox:parent-process for more information.

## reload:parent-process

target:parent-process measures the number of objects created by DevTools when reloading a page inspected by a DevTools Toolbox. This test is a mochitest which can be executed with:

```bash
./mach test devtools/client/framework/test/allocations/browser_allocations_reload.js --headless
```

See the description for toolbox:parent-process for more information. Note that this test also records another suite, reload:content-process.

## reload:content-process

See the description for reload:parent-process.

## browser-console:parent-process

browser-console:parent-process measures the number of objects created by DevTools when opening and closing the Browser Console. This test is a mochitest which can be executed with:

```bash
./mach test devtools/client/framework/test/allocations/browser_allocations_browser_console.js --headless
```

See the description for toolbox:parent-process for more information.

---

### Devtools Docs User 3d View Index (`devtools/docs/user/3d_view/index.md`)

# 3D view

:::{warning}
From Firefox 47 onwards, 3D view is no longer available.
:::

When you click on the 3D view button, the page goes into 3D view mode; in this mode, you can see your page presented in a 3D view in which nested blocks of HTML are increasingly "tall," projecting outward from the bottom of the page. This view makes it easy to visualize the nesting of your content.

```{image} 3dview.png
:class: center
```

By clicking and dragging the view, you can rotate and re-orient the 3D presentation of the DOM hierarchy of your page to see it from different angles, to better examine its structure. Off-screen elements become visible, so that you can see where your elements are located in relation to the visible content. You can click on elements to see their HTML in the {ref}`HTML panel<page-inspector-ui-tour-html-pane>` or the {ref}`Style panel<page-inspector-ui-tour-rules-view>`. Conversely, you can click on elements in the breadcrumb bar to change which element is selected in the 3D view.

If you do not see the 3D button in the page inspector, it is possible that your graphics driver needs to be updated. See the [blocklisted drivers page](https://wiki.mozilla.org/Blocklisting/Blocked_Graphics_Drivers) for more information.

## Controlling the 3D view

There are keyboard shortcuts and mouse controls available for the 3D view.

```{eval-rst}
.. list-table::
  :widths: 20 20 60
  :header-rows: 1

  * - Function
    - Keyboard
    - Mouse

  * - Zoom in/out
    - :kbd:`+` / :kbd:`-`
    - Scroll wheel up/down

  * - Rotate left/right
    - :kbd:`a` / :kbd:`d`
    - Mouse left/right

  * - Rotate up/down
    - :kbd:`w` / :kbd:`s`
    - Mouse up/down

  * - Pan left/right
    - :kbd:`←` / :kbd:`→`
    - Mouse left/right

  * - Pan up/down
    - :kbd:`↑` / :kbd:`↓`
    - Mouse up/down

  * - Reset zoom level
    - :kbd:`0`
    - Resets the zoom level to the default

  * - Focus on selected node
    - :kbd:`f`
    - Makes sure the currently selected node is visible

  * - Reset view
    - :kbd:`r`
    - Resets zoom, rotation, and panning to the default

  * - Hide current node
    - :kbd:`x`
    - Makes the currently selected node invisible; this can be helpful if you need to get at a node that's obscured

```

## Use cases for the 3D view

There are a variety of ways the 3D view is useful:

- If you have broken HTML causing layout problems, looking at the 3D view can help find where you've gone wrong. Often, layout problems are caused by improper nesting of content. This can become much more obvious when looking at the 3D view and seeing where your elements are nested wrong.
- If content isn't displaying, you may be able to figure out why; since the 3D view lets you zoom out to see elements that are rendering outside the visible area of the page, you can find stray content this way.
- You can get a look at how your page is structured to see if there may be ways to optimize your layout.
- And, of course, it looks **awesome**.

## See also

- {doc}`Page Inspector <../page_inspector/index>`
- {ref}`HTML panel  <page-inspector-ui-tour-html-pane>`
- {ref}`Style panel  <page-inspector-ui-tour-rules-view>`
- {doc}`Tools <../index>`

---

### Devtools Docs User About Colon Debugging Index (`devtools/docs/user/about_colon_debugging/index.md`)

# <about:debugging>

The `about:debugging` page provides a single place from which you can attach the Firefox Developer Tools to a number of debugging targets. At the moment it supports three main sorts of targets: restartless add-ons, tabs, and workers.

This is also the main entry point to remotely debug Firefox, in particular Firefox for Android.

## Opening the <about:debugging> page

There are two ways to open `about:debugging`:

- Type `about:debugging` in the Firefox URL bar.
- In the **Tools** > **Browser Tools** menu, click **Remote Debugging**.

When <about:debugging> opens, on the left-hand side, you'll see a sidebar with two options and information about your remote debugging setup:

Setup

: Use the Setup tab to configure the connection to your remote device.

This Firefox

: Provides information about temporary extensions you have loaded for debugging, extensions that are installed in Firefox, the tabs that you currently have open, and service workers running on Firefox.

```{image} about_debugging_setup.png
:class: border
```

If your `about:debugging` page is different from the one displayed here, go to `about:config`, find and set the option `devtools.aboutdebugging.new-enabled` to **true**.

## Setup tab

(about-colon-debugging-connecting-to-a-remote-device)=

### Connecting to a remote device

Firefox supports debugging over USB with Android devices, using the <about:debugging> page.

Before you connect:

0. Ensure clicking once on "Enable USB Devices" in <about:debugging> homepage.

```{image} about_debugging_home.png
:class: border
```

1. Enable Developer settings on your Android device.
   Press 7 times on "Build Number" from your "About your phone" in the device settings app.
2. Enable "USB debugging" in the Android Developer settings.
   [Detailed guide for 1. and 2.](https://developer.android.com/studio/debug/dev-options)

```{image} android_usb_debugging.png
:class: border
```

3. Enable **Remote Debugging via USB** in the Advanced Settings in Firefox on the Android device.

```{image} android_firefox_debugging_option.png
:class: border
```

4. Connect the Android device to your computer using a USB cable.
   If a USB cable is not available, {ref}`connect to Android over Wi-Fi <about-colon-debugging-connecting-to-android-over-wi-fi>`.

If your device doesn't appear in the lefthand side of the <about:debugging> page, try clicking the **Refresh devices** button.

**If it still doesn't appear**, it may be because the link between your Android device and your computer is not authorized yet. First make sure you have installed [Android Debug Bridge](https://developer.android.com/studio/command-line/adb.html) from Android Tools on your computer in order for it to be able to connect to your device. Next, disable every debugging setting already activated and repeat the steps described before. Your device should show a popup to authorize your computer to connect to it — accept this and then click the **Refresh devices** button again. The device should appear.

:::{note}
You do not need to install the full Android Studio SDK. Only adb is needed.
:::

To start a debugging session, first open the page that you wish to debug and then click **Connect** next to the device name to open a connection to it. If the connection was successful, you can now click the name of the device to switch to a tab with information about the device.

```{image} device_information.png
:alt: Screenshot of the debugging page for an Android device
:class: border
```

The information on this page is the same as the information on the **This Firefox** tab, but instead of displaying information for your computer, it displays the information for the remote device with the addition of a **Tabs** section with an entry for each of the tabs open on the remote device.

Note: If the version of Firefox on your remote device is more than one major version older than the version running on your computer, you may see a message like the following:

```{image} version_warning.png
:alt: The connected browser has an old version (68.2.0). The minimum supported version
:  (69.0a1). This is an unsupported setup and may cause DevTools to fail. Please update
:  the connected browser.
:class: center
```

The message can look like the following:

```{image} fxand-68-error.png
:alt: This version of Firefox cannot debug Firefox for Android (68). We recommend installing
:  Firefox for Android Nightly on your phone for testing. More details
:class: center
```

See Connection for Firefox for Android 68 for more information.

In the image above, there are three tabs open: **Network or cache Recipe**, **Nightly Home**, and **About Nightly**. To debug the contents of one of these tabs, click the **Inspect** button next to its title. When you do, the Developer Tools open in a new tab.

```{image} remote-debugger-w-url-buttons.png
:alt: Screenshot showing the remote debugging window, with the editable URL bar
:class: border
```

Above the usual list of tools, you can see information about the device you are connected to, including the fact that you are connected (in this example) via USB, to Firefox Preview, on a Pixel 2, as well as the title of the page that you are debugging, and the address of the page.

The URL bar is editable, so that you can change the URL used by the browser on the remote device, by typing in Firefox for Desktop. You can also reload the page by clicking the **Reload** button next to the URL bar, and navigate backward or forward in the browsing history with the **Back** and **Forward** buttons.

(about-colon-debugging-connecting-to-android-over-wi-fi)=

### Connecting to Android over Wi-Fi

Firefox can debug Firefox for Android through `adb` and the ["Wireless debugging" feature](https://developer.android.com/tools/adb#connect-to-a-device-over-wi-fi) of Android 11+, without requiring any USB cable.

Prerequisites:

- Device must run Android 11 or later.
- The [adb](https://developer.android.com/tools/adb) program is available. You do not need Android Studio nor the full Android SDK.
- The Android device and the computer with `about:debugging` are in the same network.

Steps to connect wirelessly with the Android device:

1. Determine the IP address of your Android device on your local network. For example by locating the Internet/Wi-Fi setting and viewing details of the current (Wi-Fi) network.

2. [Enable Developer options](https://developer.android.com/studio/debug/dev-options#enable) on your Android device.

3. Enable Wireless debugging by tapping on the toggle at the "Wireless debugging" bar at the Developer options, then tap on the "Wireless debugging" bar (before the toggle) to open the "Wireless debugging" screen.

   1. An alternative to the previous step is to open "Quick settings developer tiles" at Developer options, and enabling the "Wireless debugging" tile. After this, you can long-press the "Wireless debugging" tile from the Quick Settings panel to launch the "Wireless debugging" screen.

4. Tap on "Pair device with pairing code" in the "Wireless debugging" screen. This displays a six-digit code and an IP address and port. The port is unique to the pairing setup.

5. From the terminal, run `adb pair [ip address from step 1]:[port from step 4]` and enter the six-digit code from step 4.

6. To finally connect wirelessly, look up the (random) port at the "IP address & Port" section of the "Wireless debugging" screen. The port is distinct from step 4. Run `adb connect [ip address from step 1]:[port from step 6]` to connect.

Now, the adb server on your computer is connected with the adb daemon on the Android device. All Firefox apps with the "Remote Debugging via USB" setting enabled will now appear in `about:debugging`.

If you do not see any Firefox for Android debugging target:

- Confirm that adb is connected by running `adb devices`.
- Confirm that the Firefox app is running and that the "Remote Debugging via USB" setting is checked.

### Connecting over the Network

:::{note}
The steps below do not work for Android. Follow the instructions at {ref}`Connecting to Android over Wi-Fi <about-colon-debugging-connecting-to-android-over-wi-fi>` instead.
:::

You can connect to a Firefox Debug server on your network, or on your debugging machine using the **Network Location** settings of the <about:debugging> page.

```{image} network_location.png
:class: center
```

Enter the location and port on which the debugger server is running. When you do, it is added to the Network locations list along with the devices, as shown below:

```{image} connect_network_location.png
:class: center
```

## This Firefox

The **This Firefox** tab combines the features of Extensions, Tabs, and Workers into a single tab with the following sections:

Temporary Extensions

: Displays a list of the extensions that you have loaded using the **Load Temporary Add-on** button.

Extensions

: This section lists information about the extensions that you have installed on your system.

Service Workers, Shared Workers, and Other Workers

: There are three sections on this page that deal with Service Workers, Shared Workers, and Other Workers.

```{image} about_debugging_this_firefox.png
:class: border
```

Whether internal extensions appear in the list on this page depends on the setting of the `devtools.aboutdebugging.showHiddenAddons` preference. If you need to see these extensions, navigate to `about:config` and make sure that the preference is set to `true`.

## Extensions

### Loading a temporary extension

With the **Load Temporary Add-on** button you can temporarily load a WebExtension from a directory on disk. Click the button, navigate to the directory containing the add-on and select its manifest file. The temporary extension is then displayed under the **Temporary Extensions** header.

You don't have to package or sign the extension before loading it, and it stays installed until you restart Firefox.

The major advantages of this method, compared with installing an add-on from an XPI, are:

- You don't have to rebuild an XPI and reinstall when you change the add-on's code;
- You can load an add-on without signing it and without needing to disable signing.

Once you have loaded a temporary extension, you can see information about it and perform operations on it.

```{image} temporary_extension.png
:alt: Screenshot of the debugging information panel for a temporary extension
:class: center
```

You can use the following buttons:

Inspect

: Loads the extension in the debugger.

Reload

: Reloads the temporary extension. This is handy when you have made changes to the extension.

Remove

: Unloads the temporary extension.

Other information about the extension is displayed:

Location

: The location of the extension's source code on your local system.

Extension ID

: The temporary ID assigned to the extension.

Internal UUID

: The internal UUID assigned to the extension.

Manifest URL

: If you click the link, the manifest for this extension is loaded in a new tab.

### Updating a temporary extension

If you install an extension in this way, what happens when you update the extension?

- If you change files that are loaded on demand, like [content scripts](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Content_scripts) or [popups](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Anatomy_of_a_WebExtension#browser_actions_2), then changes you make are picked up automatically, and you'll see them the next time the content script is loaded or the popup is shown.

- For other changes, click the **Reload** button. This does what it says:

  - Reloads any persistent scripts, such as [background scripts](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Anatomy_of_a_WebExtension#background_scripts)
  - Parses the `manifest.json` file again, so changes to [permissions](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions), [content_scripts](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/content_scripts), [browser_action](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/browser_action) or any other keys take effect

### Installed Extensions

The permanently installed extensions are listed in the next section, **Extensions**. For each one, you see something like the following:

```{image} installed_extension.png
:alt: Screenshot of the debugging information panel for an installed extension
:class: center
```

The **Inspect** button, and the **Extension ID** and **Internal UUID** fields are the same as for temporary extensions.

Just as it does with temporarily loaded extensions, the link next to **Manifest URL** opens the loaded manifest in a new tab.

:::{note}
It's recommended that you use the Browser Toolbox, not the Add-on Debugger, for debugging WebExtensions. See [Debugging WebExtensions](https://extensionworkshop.com/documentation/develop/debugging/) for all the details.
:::

The Add-ons section in <about:debugging> lists all WebExtensions that are currently installed. Next to each entry is a button labeled **Inspect**.

:::{note}
This list may include add-ons that came preinstalled with Firefox.
:::

If you click **Inspect**, the Add-on Debugger will start in a new tab.

```{raw} html
<iframe width="560" height="315" src="https://www.youtube.com/embed/efCpDNuNg_c" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<br/>
<br/>
```

## Workers

The Workers section shows all the workers you've got registered on your Firefox, categorized as follows:

- All registered [Service Workers](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API)
- All registered [Shared Workers](https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker)
- Other workers, including Chrome Workers and [Dedicated Workers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers#dedicated_workers)

You can connect the developer tools to each worker, and send push notifications to service workers.

```{image} about_debugging_workers.png
:class: border
```

### Service worker state

The list of service workers shows the state of the service worker in its [lifecycle](https://developers.google.com/web/fundamentals/primers/service-workers/lifecycle). Three states are possible:

- *Registering*: this covers all states between the service worker's initial registration, and its assuming control of pages. That is, it subsumes the *installing*, *activating*, and *waiting* states.
- *Running*: the service worker is currently running. It's installed and activated, and is currently handling events.
- *Stopped*: the service worker is installed and activated, but has been terminated after being idle.

```{image} sample_service_worker.png
:alt: Screenshot of the debugging panel for a service worker that is in the Running
:  state
:class: center
```

This section uses a simple ServiceWorker demo, hosted at <https://serviceworke.rs/push-simple/>.

:::{note}
You can access similar information on the Service Workers registered on a particular domain by going to the Firefox DevTools {doc}`Application panel <../application/index>`.
:::

### Unregistering service workers

Click the **Unregister** button to unregister the service worker.

### Sending push events to service workers

To debug push notifications, you can set a breakpoint in the [push event](https://developer.mozilla.org/en-US/docs/Web/API/PushEvent) listener. However, you can also debug push notifications locally, without needing the server. Click the **Push** button to send a push event to the service worker.

### Service workers not compatible

A warning message is displayed at the top of the **This Firefox** tab if service workers are incompatible with the current browser configuration, and therefore cannot be used or debugged.

```{image} worker_warning.png
:class: center
```

Service workers can be unavailable if the `dom.serviceWorkers.enable` preference is set to false in `about:config`.

## Connection to Firefox for Android 68

Releases of Firefox for Android that are based on version 68 cannot be debugged from desktop Firefox versions 69 or later, because of the difference in release versions. Until such time as Firefox for Android is updated to a newer major release, in synch with desktop Firefox, you should use one of the following Firefox for Android versions:

- [Firefox Preview](https://play.google.com/store/apps/details?id=org.mozilla.fenix), if your desktop Firefox is the main release or Developer Edition
- [Firefox for Android Nightly](https://play.google.com/store/apps/details?id=org.mozilla.fenix)

If you prefer to test with the main release of Firefox for Android (i.e., based on release 68), you can do so with the desktop [Firefox Extended Support Release (ESR)](https://support.mozilla.org/en-US/kb/switch-to-firefox-extended-support-release-esr), which is also based on version 68.

Note that `about:debugging` is not enabled by default in Firefox ESR. To enable it, open the [Configuration Editor](https://support.mozilla.org/en-US/kb/about-config-editor-firefox) (`about:config`) and set `devtools.aboutdebugging.new-enabled` to **true**.

If you used a higher version of Firefox prior to installing Firefox ESR, you will be prompted to create a new user profile, in order to protect your user data. For more information, see [What happens to my profile if I downgrade to a previous version of Firefox?](https://support.mozilla.org/en-US/kb/dedicated-profiles-firefox-installation#w_what-happens-to-my-profile-if-i-downgrade-to-a-previous-version-of-firefox)

---

### Devtools Docs User Accessibility Inspector Index (`devtools/docs/user/accessibility_inspector/index.md`)

# Accessibility Inspector

The Accessibility Inspector provides a means to access important information exposed to assistive technologies on the current page via the accessibility tree, allowing you to check what's missing or otherwise needs attention. This article takes you through the main features of the Accessibility Inspector and how to use it.

## A (very) brief guide to accessibility

Accessibility is the practice of making your websites usable by as many people as possible. This means trying your best to not lock anyone out of accessing information because of any disability they may have, or any other personal circumstances such as the device they are using, the speed of their network connection, or their geographic location or locale. You can find more extensive information in the [Accessibility](https://developer.mozilla.org/en-US/docs/Web/Accessibility) section of MDN Web Docs.

Here we are mainly talking about exposing information to people with visual disabilities — this is done via the [accessibility APIs](https://www.smashingmagazine.com/2015/03/web-accessibility-with-accessibility-api/) available inside web browsers, which expose information on what roles the different elements on your page play (e.g., are they just text, or are they buttons, links, form elements, etc.?).

Semantic DOM elements have roles assigned to them by default that hint at what their purpose is. Sometimes, however, you need to use some non-semantic markup (e.g., [div](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div) s) to build a complex custom control, and the control won't have a default role that reflects its purpose. In such a situation, you can use [WAI-ARIA](https://developer.mozilla.org/en-US/docs/Learn/Accessibility/WAI-ARIA_basics) role attributes to provide your own roles.

Roles and other information exposed by browser accessibility APIs are presented in a hierarchical structure called the accessibility tree. This is a bit like the DOM tree, except that it contains a more limited set of elements and slightly different information about them.

Assistive technologies like screenreaders use this information to find out what's on a web page, tell their users what's there, and enable them to interact with the page. The Accessibility Inspector also uses this information to provide valuable accessibility debugging capabilities in the DevTools.

## Accessing the Accessibility Inspector

When you first open any of the other Developer Tools, the accessibility features are turned off (unless you've already got them turned on in another browser tab, or got the Firefox accessibility engine started already, e.g., you might be a screenreader user or tester).

The accessibility inspector is automatically enabled when you do one of the following:

- Choose **Accessibility** in the **Tools > Browser Tools** menu.
- Select the **Accessibility** tab in the Developer Tools toolbox.
- Right-click in the main browser window, and choose **Inspect Accessibility Properties** in the context menu.
- Right-click an item in the HTML pane of the {doc}`Page Inspector <../page_inspector/index>`, and choose **Show Accessibility Properties** in the context menu.

Once activated, the accessibility engine remains running until you close the Developer Tools toolbox.

:::{note}
The accessibility engine runs in the background when the accessibility features are turned on. When enabled it may affect the metrics from other panels such as {doc}`Memory <../memory/index>` and {doc}`Performance <../performance/index>`, and have some impact onoverall browser performance.
:::

If you don't wish to allow the accessibility features to be automatically enabled, you can use the [Configuration Editor](https://support.mozilla.org/en-US/kb/about-config-editor-firefox) (also known as `about:config`) to define the preference `devtools.accessibility.auto-init.enabled`, and set it to `False`.

If you don't wish to use the accessibility features at all, you can use the [Configuration Editor](https://support.mozilla.org/en-US/kb/about-config-editor-firefox) to set the preference `devtools.accessibility.enabled` to `False`. If you do this, the methods listed above for activating the Accessibility Inspector do nothing.

## Features of the Accessibility panel

The enabled accessibility panel looks like so:

```{image} accessibility-inspector-tabbing_order.png
:alt: Shows issue checker toolbar with "contrast" and "text label" options
:class: border
```

On the left-hand side, there is a tree diagram representing all the items in the accessibility tree for the current page. Items with nested children have arrows that can be clicked to reveal the children, so you can move deeper into the hierarchy. Each item has two properties listed:

- *Role* — the role this item has on the page (e.g., `pushbutton`, or `footer`). This can be either a default role provided by the browser, or a role given to it via a WAI-ARIA `role` attribute.
- *Name* — the name this item has on the page. The name depends on the element; for example, the name of most text elements is their `textContent`, whereas form elements' names are the contents of their associated [label](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label).

On the right-hand side, you can see further information about the currently selected item. The listed properties are as follows:

- *name* — the item's name, as described above.

- *role* — the item's role, as described above.

- *actions* — a list of actions that can be performed on the item, for example, a pushbutton would have "Press" listed, while a link would have "Jump" listed.

- *value* — the value of the item. This can mean different things depending on the type of the item; for example, a form input (role: entry) would have a value of whatever is entered in the input, whereas a link's value would be the URL in the corresponding `<a>` element's `href`.

- *DOMNode* — the type of DOM node that the item in the accessibility tree represents. You can click on the "target" icon that comes after it to select the node in the {doc}`Page Inspector <../page_inspector/index>`. Hovering over the "target" icon highlights the DOM node in the page content.

  ```{image} dom-node-target-icon.png
  :alt: DOMNode property in accessibility inspector with target icon highlighted
  ```

- *description* — any further description provided on the element, usually by the content of a title attribute.

- *keyboardShortcut* — any keyboard shortcut that is available to activate the element, as specified in an `accessKey` attribute.

- *childCount* — the number of child items the current item has in the accessibility tree hierarchy.

- *indexInParent* — an index value indicating what number child the item is, inside its parent. If the item is the first item inside its parent, it has a value of 0. If it is the second, it has a value of 1. And so on.

- *states* — a list of the different accessibility-relevant states that can apply to the current item. For example, one of the links in one demo has states of focusable, linked, selectable text, opaque, enabled, and sensitive. For a full list of internal states, see Gecko states.

- *relations* — a list of the accessibility-relevant relationships between this item and other items. For example, in a form, an entry item could have a "labelled by" relation with a label item, which in turn has a "label for" relation to the entry item.

- *attributes* — a list of all the accessibility-relevant attributes that are applied to the item. This can include style-related attributes such as margin-left and text-indent, and other useful states for accessibility information, such as draggable and level (e.g., what heading level is it, in the case of headings). For a full list of possible attributes, see Gecko object attributes.

:::{note}
The exposed information is the same across all platforms — the inspector exposes Gecko's accessibility tree, rather than information from the platform accessibility layer.
:::

### Keyboard controls

The *Accessibility* tab is fully keyboard-accessible:

- You can tab between *Check for Issues*, *Simulate*, *Show tabbing order*, and left and right panels.
- When one of the panels is focused, you can move the focus up and down items using the up and down arrow keys, and use the left and right arrow keys to expand and collapse expandable rows (e.g., different hierarchy levels of the accessibility tree).

### Print accessibility tree to JSON

You can print the contents of the accessibility tree to JSON by right-clicking on an entry in the Accessibility tab and selecting **Print to JSON:**

```{image} accessibility-inspector-print_tree_to_json.png
:alt: Print to JSON right-click menu in left panel
:class: border
```

When you do, you will get a new tab with the selected accessibility tree loaded into the JSON viewer:

```{image} accessibility_json.png
:alt: Accessibility tree loaded in new tab JSON viewer
:class: center
```

Once opened, you can save or copy the data as necessary. The JSON viewer can also show you the raw JSON data on a separate tab in the viewer.

### Show web page tabbing order

People who are unable to navigate a page with the mouse or a trackpad can use the {kbd}`tab` key to toggle through focusable items on the page (i.e. buttons, links, form controls).The order that items are focused is one of the most important aspects of web accessibility, as it allows keyboard users to properly navigate a web page — if the tab order is incorrect, the page may be confusing!

Firefox can enable a visual overlay showing the tabbing order. This provides a high-level overview of how the page will be navigated using the {kbd}`tab` key, which may highlight problems more effectively than tabbing through the elements. The overlay is toggled on/off using the\*\*Show Tabbing Order\*\* checkbox.

```{image} accessibility-inspector-show_tab_order.png
:alt: Accessibility inspector and page with checkbox Show tab order selected.
:class: border
```

All focusable items have a numbered marker and the currently focused item is highlighted in a different color. In some cases the marker may be hidden by other elements, as is true for items 1 and 2 in the page below.

```{image} accessibility-inspector-hidden_items.png
:alt: A page where some of the markers for selection items are hidden
:class: center
```

These become visible in the overlay when the item is the current item.

```{image} accessibility-inspector-hidden_item_revealed.png
:alt: Shows a hidden selection item in the tabbing order overlay when it is selected.
:class: center
```

:::{note}
The overlay reflects the tab order at the time that the checkbox is selected (i.e. it is not dynamic). If a user does anything that adds items to the tab order (e.g. opens a visual element that contains more links), these new items will not be reflected in the overlay until the Accessibility Inspector is re-launched.
:::

### Check for accessibility issues

You can check for accessibility issues by clicking the drop-down menu next to: **Check for issues**. The available menu items include:

- **None** — Don't show the possible list of issues.
- **All Issues** — Check for all types of issues.
- **Contrast** — Check for [issues with visual contrast.](https://developer.mozilla.org/en-US/docs/Web/Accessibility/Understanding_WCAG/Perceivable/Color_contrast)
- **Keyboard** — Check for [issues with navigating via a keyboard.](https://developer.mozilla.org/en-US/docs/Web/Accessibility/Understanding_WCAG/Keyboard)
- **Text Labels** — Check for [issues with missing text labels.](https://developer.mozilla.org/en-US/docs/Web/Accessibility/Understanding_WCAG/Text_labels_and_names)

When you select one of the menu items, Firefox scans your document for the type of issues you selected. Depending on the size and complexity of your document, this may take a few seconds. When the scan is complete, the left side of the Accessibility Inspector panel displays only the items that have that type of issue. In the right side of the panel, the *Checks* subpanel lists the specific issue with the selected node. For each type of issue, there is a **Learn more** link to further information on *MDN Web Docs* about the issue.

```{image} accessibility-inspector-check_for_issues.png
:alt: Accessibility Inspector - Showing the options when you select the Check for Issues
:  button
:class: border
```

The menu items act as toggles. Select the item to view that type of issue; select the item again to clear the display of issues of that type.

Issues with a particular item are always displayed in the *Checks* subpanel as you browse the tree. The **Check for issues** menuitems are a quick way to view all and only those items that have issues.

### Simulate

The Accessibility Inspector offers, a {doc}`simulator <simulation/index>` that lets you see what a web page would look like to users with various forms of *color vision deficiency* (better known as "color blindness"), as well as *contrast sensitivity loss*.

## Notable related features

When the accessibility features are turned on, there are a number of useful additional features available in the DevTools, which are detailed below:

### Context menu options

An extra context menu option is added, both for the general context menu on the web page when right-clicking a UI feature, and the HTML pane of the page inspector when right-clicking a DOM element:

```{image} web-page-context-menu.png
:alt: 'context menu in the browser viewport, with a highlighted option: Inspect Accessibility
:  Properties'
:class: border
```

```{image} dom-inspector-context-menu.png
:alt: 'context menu in the DOM inspector, with a highlighted option: Show Accessibility
:  Properties'
:class: border
```

When you choose the *Inspect Accessibility Properties*/*Show Accessibility Properties* context menu options, the *Accessibility* tab is immediately opened to show the corresponding accessibility tree item and its properties.

:::{note}
Some DOM elements do not have accessibility properties — in that case, the *Inspect Accessibility Properties*/*Show Accessibility Properties* context menu item is grayed out.
:::

### Highlighting of UI items

In the Accessibility tab, when the mouse hovers over accessibility items, you can see a semi-transparent highlight appear over the UI items they relate to, if appropriate. The role and name of the item will be shown in a small information bar along with color contrast information if appropriate. This is useful for determining how the items in the accessibility tree relate to the UI items on the actual page.

In the following example, you can see that the image has been highlighted and its role, graphic, name, "Road, Asphalt, Sky, Clouds, Fall", and the color contrast ratio, 3.46, appears in the information bar above it.

```{image} image_accessibility.png
:alt: image has been highlighted and graphic, "Road, Asphalt, Sky, Clouds, Fall", and
:  Contrast:3.46 warning sign, appears in the information bar above it
:class: border
```

#### Color contrast

Contrast ratio information is particularly useful when you are designing the color palette for your website because if the contrast is not sufficient, readers with visual impairments such as low vision or color blindness will be unable to read the text. See [Color contrast](https://developer.mozilla.org/en-US/docs/Web/Accessibility/Understanding_WCAG/Perceivable/Color_contrast) for details about recommended contrast ratios.

For example:

```{image} screen_shot_2019-01-29_at_10.11.13.png
:alt: A screenshot of color contrast highlighter with warning sign where text contrast
:  if below the AA WCAG threshold.
:class: center
```

The color contrast in the image above is 2.86, so potentially not enough contrast to make it easy to read. Notice the warning symbol that indicates that the contrast fails to meet the acceptable contrast ratio.

Viewing this information for some foreground text that has a complex background image (e.g. a gradient) gives you a range of color contrast values. For example:

```{image} screen_shot_2019-01-29_at_10.21.07.png
:alt: A screenshot of color contrast highlighter with checked sign where for text over
:  gradient background with contrast satisfying the AAA WCAG guidelines.
:class: center
```

In this example, the contrast ranges from 4.72 to 5.98. The numbers are followed by AAA and a checkmark in green, indicating that the large text has a contrast ratio of 4.5:1 or more, meeting the criteria for enhanced contrast, or Level AAA.

See [Color contrast](https://developer.mozilla.org/en-US/docs/Web/Accessibility/Understanding_WCAG/Perceivable/Color_contrast) for more information on color contrast.

### Accessibility picker

Like the element picker button on the {ref}`Page Inspector <page-inspector-how-to-select-an-element-with-the-node-picker>`, the *Accessibility* tab's element picker button allows you to hover and select UI items on the current page to highlight objects in the accessibility tree.

The accessibility tab element picker looks slightly different from the Page Inspector HTML pane picker, as shown below:

```{image} dom-inspector-picker.png
:alt: highlighted DOM inspector picker button, with a tooltip saying Pick an element
:  from the page
:class: border
```

```{image} accessibility-inspector-picker.png
:alt: highlighted accessibility inspector button, with a tooltip saying Pick accessible
:  object from the page
:class: border
```

When you "perform a pick", you see the accessibility object highlighted in the accessibility tree, and the picker is then deactivated. Note, however, that if you hold the {kbd}`Shift` key down when "performing a pick", you can "preview" the accessibility object in the tree (and its properties in the right-hand pane), but then continue picking as many times as you like(the picker does not get cancelled) until you release the {kbd}`Shift` key.

When the picker is activated, you can also deactivate it by pressing the picker button a second time, or pressing the {kbd}`Esc` key.

## Typical use cases

The Accessibility Inspector is very useful for spotting accessibility problems at a glance. For a start, you can investigate items that don't have a proper text equivalent — images without `alt` text and form elements without proper labels have a `name` property of `null`, for example.

```{image} use-case-no-label.png
:alt: "A form input highlighted in the UI, with information about it shown in the accessibility\
:  \ inspector to reveal that it has no label \u2014 it has a name property of null"
:class: border
```

It is also very handy for verifying semantics — you can use the *Inspect Accessibility Properties* context menu option to quickly see whether an item has the correct role set on it (e.g., whether a button is really a button, or a link is really a link).

```{image} use-case-fake-button.png
:alt: A UI element that looks like a button, with information about it shown in the
:  accessibility inspector to reveal that it isn't a button, it is a section element.
:  It has a name property of null
:class: border
```

## See also

- [Accessibility tutorials](https://developer.mozilla.org/en-US/docs/Learn/Accessibility)
- [Web accessibility overview](https://developer.mozilla.org/en-US/docs/Web/Accessibility)
- [Practical debugging information](https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Accessibility)
- [Understanding WCAG](https://developer.mozilla.org/en-US/docs/Web/Accessibility/Understanding_WCAG)
- [WAI-ARIA basics](https://developer.mozilla.org/en-US/docs/Learn/Accessibility/WAI-ARIA_basics)
- [Accessibility APIs: A Key To Web Accessibility](https://www.smashingmagazine.com/2015/03/web-accessibility-with-accessibility-api/) by Léonie Watson

```{toctree}
:hidden:
:maxdepth: 1

simulation/index
```

---

### Devtools Docs User Application Index (`devtools/docs/user/application/index.md`)

# Application

The **Application panel** provides tools for inspecting and debugging modern web apps (also known as [Progressive Web Apps](https://developer.mozilla.org/en-US/docs/Glossary/Progressive_web_apps)). This includes inspection of [service workers](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API) and [web app manifests](https://developer.mozilla.org/en-US/docs/Web/Manifest).

```{image} sw-registered.jpg
:alt: the firefox application panel zoomed out view showing a picture of two arctic
:  foxes
:class: border
```

## Accessing the Application panel

The Application panel is available on the standard DevTools tab menu under *Application*. If you can’t see it there, you can enable it by going to the "three dot" menu and selecting *Settings* (also accessible by pressing F1), then checking the *Application* checkbox under *Default Developer Tools*.

## Finding an example

If you want to test this functionality and you don't have a handy PWA available, you can grab one of our simple examples to use:

- Add to homescreen demo: Shows pictures of foxes ([source code](https://github.com/mdn/pwa-examples/tree/master/a2hs) | [live version](https://mdn.github.io/pwa-examples/a2hs/))
- Js13kpwa demo: Show information on entries to the JS13K annual competition ([source code](https://github.com/mdn/pwa-examples/tree/master/js13kpwa) | [live version](https://mdn.github.io/pwa-examples/js13kpwa/))

## How to

- {doc}`Debug service workers <service_workers/index>`
- {doc}`Inspect web app manifests <manifests/index>`

```{toctree}
:hidden:
:maxdepth: 1

manifests/index
service_workers/index
```

---

### Devtools Docs User Browser Console Index (`devtools/docs/user/browser_console/index.md`)

# Browser Console

The Browser Console is like the {doc}`Web Console <../web_console/index>`, but applied to the whole browser rather than a single content tab.

So it logs the same sorts of information as the Web Console - network requests, JavaScript, CSS, and security errors and warnings, and messages explicitly logged by JavaScript code. However, rather than logging this information for a single content tab, it logs information for all content tabs, for add-ons, and for the browser's own code.

If you also want to use the other web developer tools in the regular Web {doc}`Toolbox <../tools_toolbox/index>` with add-on or browser code, consider using the {doc}`Browser Toolbox<../browser_toolbox/index>`.

Similarly, you can execute JavaScript expressions using the Browser Console. But while the Web Console executes code in the page window scope, the Browser Console executes them in the scope of the browser's chrome window. This means you can interact with all the browser's tabs using the `gBrowser` global, and even with the XUL used to specify the browser's user interface.

:::{container} block_quote
NB: The Browser Console command line (to execute JavaScript expressions) is disabled by default. To enable it set the `devtools.chrome.enabled` preference to `true` in <about:config>, or set the "Enable browser [chrome](https://developer.mozilla.org/en-US/docs/Glossary/Chrome) and add-on debugging toolboxes" option in the {doc}`developer tool settings <../settings/index>`.
:::

## Opening the Browser Console

You can open the Browser Console in one of two ways:

1. from the menu: select "Browser Console" from the Browser Tools submenu in the Firefox Menu (or Tools menu if you display the menu bar or are on macOS).
2. from the keyboard: press {kbd}`Ctrl` + {kbd}`Shift` + {kbd}`J` (or {kbd}`Cmd` + {kbd}`Shift` + {kbd}`J` on a Mac).

You can also start the Browser Console by launching Firefox from the command line and passing the `-jsconsole` argument:

```bash
/Applications/FirefoxAurora.app/Contents/MacOS/firefox -jsconsole
```

The Browser Console looks like this:

```{image} browser_console_68.png
```

You can see that the Browser Console looks and behaves very much like the {doc}`Web Console <../web_console/index>`:

- most of the window is occupied by a {doc}`pane that display messages <../web_console/console_messages/index>`
- at the top, a {ref}`toolbar  <web-console-ui-tour-toolbar>` enables you to filter the messages that appear.
- at the bottom, a {doc}`command line interpreter <../web_console/the_command_line_interpreter/index>` enables you to evaluate JavaScript expressions.

The Browser Console allows you to show or hide messages from the content process (i.e. the messages from scripts in all the opened pages) by setting or clearing the checkbox labeled **Show Content Messages**. The following image shows the browser console focused on the same page as above after clicking on the **Show Content Messages** checkbox.

```{image} browser_console_68_02.png
```

## Browser Console logging

The Browser console logs the same sorts of messages as the Web Console:

- {ref}`HTTP requests  <web-console-console-messages>`
- {doc}`Warnings and errors <../web_console/console_messages/index>` (including JavaScript, CSS, security warnings and errors, and messages explicitly logged by JavaScript code using the [Console API](https://developer.mozilla.org/en-US/docs/Web/API/console)
- {ref}`Input/output messages  <web-console-console-messages-interpreter-io>` commands send to the browser via the command line, and the result of executing them

However, it displays such messages from:

- web content hosted by all browser tabs
- the browser's own code
- add-ons

### Messages from add-ons

The Browser Console displays messages logged by all Firefox add-ons.

#### Console.sys.mjs

To use the console API from a traditional or bootstrapped add-on, get it from the Console module.

One exported symbol from `Console.sys.mjs` is `console`. Below is an example of how to access it, which adds a message to the Browser Console.

```JavaScript
const { console } = ChromeUtils.importESModule("resource://gre/modules/Console.sys.mjs");
console.log("Hello from Firefox code"); //output messages to the console
```

Learn more:

- [Console API reference](https://developer.mozilla.org/en-US/docs/Web/API/console)
- {searchfox}`Console.sys.mjs source code <toolkit/modules/Console.sys.mjs>`

## Browser Console command line

:::{container} block_quote
The Browser Console command line is disabled by default. To enable it set the `devtools.chrome.enabled` preference to `true` in `about:config`, or set the "Enable chrome debugging" option in the {doc}`developer tool settings <../settings/index>`.
:::

Like the Web Console, the command line interpreter enables you to evaluate JavaScript expressions in real time:

```{image} browser-console-commandline.png
```

Also like the Web Console's command line interpreter, this command line supports autocomplete, history, and various {ref}`keyboard shortcuts <keyboard-shortcuts-web-console>` and {doc}`helper commands <../web_console/helpers/index>`. If the result of a command is an object, you can click on the object to see its details.

But while the Web Console executes code in the scope of the content window it's attached to, the browser console executes code in the scope of the chrome window of the browser. You can confirm this by evaluating `window`:

```{image} browser-console-chromewindow.png
```

This means you can control the browser: opening, closing tabs and windows and changing the content that they host, and modify the browser's UI by creating, changing and removing XUL elements.

### Controlling the browser

The command line interpreter gets access to the `tabbrowser` object, through the `gBrowser` global, and that enables you to control the browser through the command line. Try running this code in the Browser Console's command line (remember that to send multiple lines to the Browser Console, use {kbd}`Shift` + {kbd}`Enter`):

```JavaScript
var newTabBrowser = gBrowser.getBrowserForTab(gBrowser.selectedTab);
newTabBrowser.addEventListener("load", function() {
 newTabBrowser.contentDocument.body.innerHTML = "<h1>this page has been eaten</h1>";
}, true);
newTabBrowser.contentDocument.location.href = "https://mozilla.org/";
```

It adds a listener to the currently selected tab's `load` event that will eat the new page, then loads a new page.

:::{note}
You can restart the browser with the command {kbd}`Ctrl` + {kbd}`Alt` + {kbd}`R` (Windows, Linux) or {kbd}`Cmd` + {kbd}`Alt` + {kbd}`R` (Mac) This command restarts the browser with the same tabs open as before the restart.
:::

### Modifying the browser UI

Since the global `window` object is the browser's chrome window, you can also modify the browser's user interface. On Windows, the following code will add a new item to the browser's main menu:

```JavaScript
var parent = window.document.getElementById("appmenuPrimaryPane");
var makeTheTea = gBrowser.ownerDocument.defaultView.document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "menuitem");
makeTheTea.setAttribute("label", "A nice cup of tea?");
parent.appendChild(makeTheTea);
```

```{image} browser-console-modify-ui-windows.png
```

On macOS, this similar code will add a new item to the **Tools** menu:

```JavaScript
var parent = window.document.getElementById("menu_ToolsPopup");
var makeTheTea = gBrowser.ownerDocument.defaultView.document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "menuitem");
makeTheTea.setAttribute("label", "A nice cup of tea?");
parent.appendChild(makeTheTea);
```

```{image} browser-console-modify-ui-osx.png
```

---

### Devtools Docs User Browser Toolbox Index (`devtools/docs/user/browser_toolbox/index.md`)

---
myst:
  substitutions:
    image1: |-
      ```{image} 2014-01-10-13-08-08-f52b8c.png
      :alt: new fx menu```
---

# Browser Toolbox

The Browser Toolbox enables you to debug add-ons and the browser's own JavaScript code rather than just web pages like the normal {doc}`Toolbox <../tools_toolbox/index>`. The Browser Toolbox's context is the whole browser rather than justsingle page on a single tab.

## Enabling the Browser Toolbox

The Browser Toolbox is not enabled by default. To enable it you need to check the settings "Enable chrome and addon debugging" and "Enable remote debugging".

To do this, open the Developer Tools {doc}`Settings <../settings/index>`, go to the section {ref}`Advanced Settings  <settings-advanced-settings>`, and check the settings "Enable browser chrome and add-on debugging toolboxes" and "Enable remote debugging".

```{image} settings_for_browser_debugger.png
:alt: Developer Tools Settings
:class: border
```

## Opening the Browser Toolbox

Open the Browser Toolbox through the menu button {{ image1 }} and the menu items "Developer" then "Browser Toolbox".

You can also open it with the {kbd}`Ctrl` + {kbd}`Alt` + {kbd}`Shift` + {kbd}`I` key combination ({kbd}`Cmd` + {kbd}`Opt` + {kbd}`Shift` + {kbd}`I` on a Mac).

You will be presented with a dialog like this (it can be removed by setting the `devtools.debugger.prompt-connection` property to false):

```{image} browser-toolbox-warning.png
```

Click OK, and the Browser Toolbox will open in its own window:

```{image} browser-toolbox.png
```

You'll be able to inspect the browser's chrome windows and see, and be able to debug, all the JavaScript files loaded by the browser itself and by any add-ons that are running. Altogether you will have access to the following developer tools:

- {doc}`Debugger <../debugger/index>`
- {doc}`Console <../browser_console/index>`
- {doc}`Style Editor <../style_editor/index>`
- {doc}`Performance <../performance/index>`
- {doc}`Network Monitor <../network_monitor/index>`
- {doc}`Page Inspector <../page_inspector/index>`
- {doc}`Accessibility Inspector <../accessibility_inspector/index>`

You can debug chrome: and about: pages using the normal {doc}`Debugger <../debugger/index>`, just as if they were ordinary content pages.

## Targeting a document

In the normal toolbox, there's a {doc}`button in the toolbar enabling you to target specific iframes in the document <../working_with_iframes/index>`. The same button appears in the browser toolbox where it lists all the top-level chrome and content windows as well as any iframes they contain. This enables you to inspect documents in individual chrome windows and popups, as well as in content tabs.

For example, here's what the frame selection popup lists when there are two browser windows open, one with one content tab, and one with two:

```{image} browser-toolbox-iframes.png
```

## Debugging popups

It's hard to debug popups, because the browser hides them as soon as you click outside them. There is a way to disable this behavior. Click the toolbox menu and select **Disable popup auto-hide**.

```{image} popup_auto-hide.png
:class: center
```

Now when you open any popup, it will stay open until you press the {kbd}`Esc` key. You can use the Inspector's node picker to select that panel, and examine and modify its content.

You can use the same technique to debug [popups created by add-ons](https://extensionworkshop.com/documentation/develop/debugging/#debugging_popups).

:::{note}
This change is not persistent across browser restarts. When you close the browser toolbox, the setting will be cleared.
:::

---

### Devtools Docs User Debugger Api Index (`devtools/docs/user/debugger-api/index.md`)

# Debugger-API

## The `Debugger` Interface

Mozilla’s JavaScript engine, SpiderMonkey, provides a debugging interface named `Debugger` which lets JavaScript code observe and manipulate the execution of other JavaScript code. Both Firefox’s built-in developer tools and the Firebug add-on use `Debugger` to implement their JavaScript debuggers. However, `Debugger` is quite general, and can be used to implement other kinds of tools like tracers, coverage analysis, patch-and-continue, and so on.

`Debugger` has three essential qualities:

- It is a *source level* interface: it operates in terms of the JavaScript language, not machine language. It operates on JavaScript objects, stack frames, environments, and code, and presents a consistent interface regardless of whether the debuggee is interpreted, compiled, or optimized. If you have a strong command of the JavaScript language, you should have all the background you need to use `Debugger` successfully, even if you have never looked into the language’s implementation.
- It is for use *by JavaScript code*. JavaScript is both the debuggee language and the tool implementation language, so the qualities that make JavaScript effective on the web can be brought to bear in crafting tools for developers. As is expected of JavaScript APIs, `Debugger` is a *sound* interface: using (or even misusing) `Debugger` should never cause Gecko to crash. Errors throw proper JavaScript exceptions.
- It is an *intra-thread* debugging API. Both the debuggee and the code using `Debugger` to observe it must run in the same thread. Cross-thread, cross-process, and cross-device tools must use `Debugger` to observe the debuggee from within the same thread, and then handle any needed communication themselves. (Firefox’s builtin tools have a [protocol](https://wiki.mozilla.org/Remote_Debugging_Protocol) defined for this purpose.)

In Gecko, the `Debugger` API is available to chrome code only. By design, it ought not to introduce security holes, so in principle it could be made available to content as well; but it is hard to justify the security risks of the additional attack surface.

The `Debugger` API cannot currently observe self-hosted JavaScript. This is not inherent in the API’s design, but that the self-hosting infrastructure isn’t prepared for the kind of invasions the `Debugger` API can perform.

## Debugger Instances and Shadow Objects

`Debugger` reflects every aspect of the debuggee’s state as a JavaScript value—not just actual JavaScript values like objects and primitives, but also stack frames, environments, scripts, and compilation units, which are not normally accessible as objects in their own right.

Here is a JavaScript program in the process of running a timer callback function:

```{image} shadows.svg
:alt: A running JavaScript program and its Debugger shadows
:class: center
```

A running JavaScript program and its Debugger shadows

This diagram shows the various types of shadow objects that make up the Debugger API (which all follow some general conventions):

- A {doc}`Debugger.Object <debugger.object/index>` represents a debuggee object, offering a reflection-oriented API that protects the debugger from accidentally invoking getters, setters, proxy traps, and so on.
- A {doc}`Debugger.Script <debugger.script/index>` represents a block of JavaScript code—either a function body or a top-level script. Given a `Debugger.Script`, one can set breakpoints, translate between source positions and bytecode offsets (a deviation from the “source level” design principle), and find other static characteristics of the code.
- A {doc}`Debugger.Frame <debugger.frame/index>` represents a running stack frame. You can use these to walk the stack and find each frame’s script and environment. You can also set `onStep` and `onPop` handlers on frames.
- A {doc}`Debugger.Environment <debugger.environment/index>` represents an environment, associating variable names with storage locations. Environments may belong to a running stack frame, captured by a function closure, or reflect some global object’s properties as variables.

The {doc}`Debugger <debugger/index>` instance itself is not really a shadow of anything in the debuggee; rather, it maintains the set of global objects which are to be considered debuggees. A `Debugger` observes only execution taking place in the scope of these global objects. You can set functions to be called when new stack frames are pushed; when new code is loaded; and so on.

Omitted from this picture are {doc}`Debugger.Source <debugger.source/index>` instances, which represent JavaScript compilation units. A `Debugger.Source` can furnish a full copy of its source code, and explain how the code entered the system, whether via a call to `eval`, a `<script>` element, or otherwise. A `Debugger.Script` points to the `Debugger.Source` from which it is derived.

Also omitted is the `Debugger`’s {doc}`Debugger.Memory <debugger.memory/index>` instance, which holds methods and accessors for observing the debuggee’s memory use.

All these types follow some general conventions, which you should look through before drilling down into any particular type’s specification.

All shadow objects are unique per `Debugger` and per referent. For a given `Debugger`, there is exactly one `Debugger.Object` that refers to a particular debuggee object; exactly one `Debugger.Frame` for a particular stack frame; and so on. Thus, a tool can store metadata about a shadow’s referent as a property on the shadow itself, and count on finding that metadata again if it comes across the same referent. And since shadows are per-`Debugger`, tools can do so without worrying about interfering with other tools that use their own `Debugger` instances.

## Examples

Here are some things you can try out yourself that show off some of `Debugger`’s features:

- {doc}`Setting a breakpoint <tutorial-breakpoint/index>` in a page, running a handler function when it is hit that evaluates an expression in the page’s context.
- {doc}`Showing how many objects different call paths allocate. <tutorial-allocation-log-tree/index>`

## Gecko-specific features

While the `Debugger` core API deals only with concepts common to any JavaScript implementation, it also includes some Gecko-specific features:

- {doc}`Global tracking <debugger/index>` supports debugging all the code running in a Gecko instance at once—the ‘chrome debugging’ model.
- {doc}`Object wrapper <debugger.object/index>` functions help manipulate object references that cross privilege boundaries.

### Source Metadata

Generated from file:

: js/src/doc/Debugger/Debugger-API.md

Watermark:

: sha256:6ee2381145a0d2e53d2f798f3f682e82dd7ab0caa0ac4dd5e56601c2e49913a7

Changeset:

: [ffa775dd5bd4](https://hg.mozilla.org/mozilla-central/rev/ffa775dd5bd4)

```{toctree}
:hidden:
:maxdepth: 1

debugger/index
debugger.environment/index
debugger.frame/index
debugger.memory/index
debugger.object/index
debugger.script/index
debugger.source/index
tutorial-allocation-log-tree/index
tutorial-breakpoint/index
```

---

### Devtools Docs User Debugger Index (`devtools/docs/user/debugger/index.md`)

# The Firefox JavaScript Debugger

The JavaScript Debugger enables you to step through JavaScript code and examine or modify its state to help track down bugs.

```{raw} html
<iframe width="560" height="315" src="https://www.youtube.com/embed/QK4hKWmJVLo" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<br/>
<br/>
```

You can use it to debug code running locally in Firefox or running remotely, for example on an Android device running Firefox for Android. See {doc}`about debugging <../about_colon_debugging/index>` to learn how to connect the debugger to a remote target.

To find your way around the debugger, here's a {doc}`quick tour of the UI<ui_tour/index>`.

## How to

To find out what you can do with the debugger, refer to the following how-to guides.

- {doc}`Open the debugger <how_to/open_the_debugger/index>`
- {doc}`Pretty-print a minified file <how_to/pretty-print_a_minified_file/index>`
- {doc}`Search <how_to/search/index>`
- {doc}`Use a source map <how_to/use_a_source_map/index>`
- [Debug worker threads](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers#debugging_worker_threads)

### Pause execution

You probably want to pause the execution of your code, in order to see what is going on at various points. There are multiple ways to tell the Debugger how and when to pause:

- {doc}`Set a breakpoint <how_to/set_a_breakpoint/index>`
- {doc}`Set a conditional breakpoint <how_to/set_a_conditional_breakpoint/index>`
- {doc}`Set an XHR breakpoint <set_an_xhr_breakpoint/index>`
- {doc}`Set event listener <set_event_listener_breakpoints/index>`
- {doc}`Break on exceptions <how_to/breaking_on_exceptions/index>`
- {doc}`Use watchpoints for property reads and writes <how_to/use_watchpoints/index>`
- {doc}`Break on DOM Mutation <break_on_dom_mutation/index>`
- {doc}`Disable breakpoints <how_to/disable_breakpoints/index>`

### Control execution

What can you do after execution pauses?

- {doc}`Step through code <how_to/step_through_code/index>`
- {doc}`Ignoring sources <how_to/ignoring_sources/index>`
- [Debug worker threads](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers#debugging_worker_threads)
- {doc}`Debug eval sources <how_to/debug_eval_sources/index>`

### Look at values

You probably want to see the value of variables or expressions, either during execution or when it is paused.

- {doc}`Set a logpoint <set_a_logpoint/index>`
- {doc}`Set watch expressions <how_to/set_watch_expressions/index>`

## Reference

- {ref}`Keyboard shortcuts <keyboard-shortcuts-debugger>`
- {doc}`Source map errors <source_map_errors/index>`

```{toctree}
:hidden:
:maxdepth: 1

break_on_dom_mutation/index
how_to/index
set_a_logpoint/index
set_an_xhr_breakpoint/index
set_event_listener_breakpoints/index
source_map_errors/index
ui_tour/index
using_the_debugger_map_scopes_feature/index
```

---

### Devtools Docs User Deprecated Tools Index (`devtools/docs/user/deprecated_tools/index.md`)

# Deprecated tools

Over the course of DevTools development, we have added several experimental panels to try out new ideas. Not all of these have had wide adoption, and due to the cost of maintenance, seldom used panels are eventually removed.

We have created this list of deprecated or removed panels. This page documents the deprecated panels and the bugs that track their removal. Although these panels have been removed, you still have access to the old code, and there are alternative webextensions that you can try to get similar functionality.

When we deprecate a panel, we begin by getting feedback from the community to determine the impact of removing that panel. Once we have decided to remove the panel, we will provide a warning message, and finally, we will remove the panel from the codebase.

You may see a warning message, as in the following image, when trying to activate a deprecated panel:

```{image} devtool_settings_deprecated_notice.png
:class: border
```

In addition, if you open the panel for one of these tools, you will also see a warning message about its removal.

```{image} deprecated_tool_notice.png
:class: border
```

## Scratchpad

Scratchpad was removed in Firefox 72 ([bug 1519103](https://bugzilla.mozilla.org/show_bug.cgi?id=1519103)).

### Description

Scratchpad provided an environment for experimenting with JavaScript code. You can write, run, and examine the result of code that interacts with the web page.

```{image} screen_shot_2019-08-26_at_08.08.11.png
:alt: Screenshot of the Scratchpad window with a deprecation message
```

### Alternatives

You can write multi-line JavaScript code in the Web Console Editor Mode, making it similar to the Scratchpad. The Editor Mode can be triggered clicking on the icon on the right of the console input, or with {kbd}`Ctrl` + {kbd}`B` ({kbd}`Cmd` + {kbd}`B` on macOS)

```{image} editor_mode_toggle_icon.png
:alt: Screenshot of the Webconsole in inline mode, with the editor mode icon displayed
:  on the right of the console input
```

When in Editor Mode, the {kbd}`Enter` key adds a new line in the input, and you can evaluate the expression using {kbd}`Ctrl` + {kbd}`Enter` ({kbd}`Cmd` + {kbd}`Enter` on macOS).

```{image} screen_shot_2019-08-26_at_08.18.26.png
:alt: Screenshot of the Webconsole multiline input, showing an evaluation with a Syntax
:  Error and another, correct one.
```

When evaluating, the input isn't cleared, which makes it possible to quickly iterate over a snippet of code.

The results are displayed in the console output, to the right of the input, providing immediate feedback. Unlike in Scratchpad, errors are properly displayed in the output with an expandable stacktrace, making it easier to debug the code you're currently writing.

You can import a Javascript file content in the console input with {kbd}`Ctrl` + {kbd}`O` ({kbd}`Cmd` + {kbd}`O` on macOS), as well as saving the console input content to a file using {kbd}`Ctrl` + {kbd}`S` ({kbd}`Cmd` + {kbd}`S` on macOS).

## WebIDE and Connect page

WebIDE was removed as of Firefox 71 ([bug 1539462](https://bugzilla.mozilla.org/show_bug.cgi?id=1539462)).

### Description

WebIDE allowed you to connect the Firefox Developer Tools to remote browsers, such as Firefox for Android. It was also intended to support application development for Firefox OS.

```{image} webide_68.png
```

### Alternatives

Remote debugging is available in <about:debugging>. Features not ported to <about:debugging> are: WiFi debugging for Firefox for Android, application development. Features that are planned but not ported yet: remote browser screenshots and edit remote browser configuration. More details on the [mailing-list thread](https://groups.google.com/forum/#!topic/mozilla.dev.developer-tools/aWA7JJ-TpRw).

Wireless debugging over Wi-Fi is possible and documented at {ref}`about-colon-debugging-connecting-to-android-over-wi-fi`.

## Canvas debugger

Bugzilla issue: [bug 1403938](https://bugzilla.mozilla.org/show_bug.cgi?id=1403938)

Removed as of Firefox 67

### Description

Canvas Debugger allowed users to inspect the canvas element and see how frequently a given function is called. It was deprecated due to lack of use.

We do not have dedicated documentation for the Canvas Debugger.

```{image} canvas_tool.png
```

### Alternatives

[Spector.js](https://addons.mozilla.org/en-US/firefox/addon/spector-js/#&gid=1&pid=2) is a WebExtension that can provide these features with 3D contexts.

## Web Audio editor

Bugzilla issue: [bug 1403944](https://bugzilla.mozilla.org/show_bug.cgi?id=1403944)

Removed as of Firefox 67

### Description

The Web Audio Editor allowed you to examine an audio context constructed in the page and provided a visualization of its graph. This gave a high-level view of its operation, and enabled you to ensure that all the nodes are connected in the way you expect. It was possible to edit the AudioParam properties for each node in the graph. Some non-AudioParam properties, like an OscillatorNode's type property, were displayed and editable as well. It was deprecated due to lack of use.

More details about the {doc}`Web Audio Editor <../web_audio_editor/index>`

```{image} webaudio_tool.png
:class: border
```

### Alternatives

Alternatives include the [AudioN](https://github.com/google/audion) and <https://github.com/spite/WebAudioExtension> WebExtensions.

## Shader editor

Bugzilla issue: [bug 1342237](https://bugzilla.mozilla.org/show_bug.cgi?id=1342237)

Removed as of Firefox 67

### Description

The Shader Editor allowed users to examine and edit the source of the WebGL vertex and fragment shaders. It was deprecated due to low usage and maintenance costs.

{doc}`Shader Editor <../shader_editor/index>`

```{image} shadereditor_tool.png
:class: border
```

### Alternatives

An alternative to this panel is this extension: <https://github.com/spite/ShaderEditorExtension>, or [Spector.js](https://addons.mozilla.org/en-US/firefox/addon/spector-js/#&gid=1&pid=2) also supports a Shader Editor that requires a library to use a shader reloader hook. Currently only the Babylon library does.

---

### Devtools Docs User Devtoolsapi Index (`devtools/docs/user/devtoolsapi/index.md`)

# DevTools API

:::{warning}
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.
:::

:::{warning}
The DevTools API is still WIP. If you notice any inconsistency, please let The Firefox Developer Tools Team know.
:::

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.

## Introduction

The DevTools API provides a way to register and access developer tools in Firefox.

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,…).

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.

## API

### gDevTools

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

```JavaScript
const { gDevTools } = require("resource://devtools/client/framework/devtools.js");
```

#### Methods

`registerTool(toolDefinition)`

: Registers a new tool and adds a tab to each existing toolbox.

  **Parameters:**

- `toolDefinition {ToolDefinition}` - An object that contains information about the tool. See {ref}`ToolDefinition <devtoolsapi-tool-definition>` for details.

`unregisterTool(toolId)`

: Unregisters the given tool and removes it from all toolboxes.

  **Parameters:**

- `tool {ToolDefinition|String}` - The tool definition object or the id of the tool to unregister.

`registerTheme(themeDefinition)`

: Registers a new theme.

  **Parameters:**

- `themeDefinition {ThemeDefinition}` - An object that contains information about the theme.

`unregisterTheme(theme)`

: Unregisters the given theme.

  **Parameters:**

- `theme {ThemeDefinition|String}` - The theme definition object or the theme identifier.

`showToolbox(commands[, toolId [, hostType [, hostOptions]]])`

: Opens a toolbox for given target either by creating a new one or activating an existing one.

  **Parameters:**

- `commands {Object}` - The commands object designating which debugging context the toolbox will debug.
- `toolId {String}` - The tool that should be activated. If unspecified the previously active tool is shown.
- `hostType {String}` - The position the toolbox will be placed. One of `bottom`, `side`, `window`, `custom`. See {ref}`HostType <devtoolsapi-host-type>` for details.
- `hostOptions {Object}` - An options object passed to the selected host. See {ref}`HostType <devtoolsapi-host-type>` for details.

  **Return value:**
  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.

`getToolbox(target)`

: Fetch the {ref}`Toolbox <devtoolsapi-toolbox>` object for the given target.

  **Parameters:**

- `target {Target}` - The target the toolbox is debugging.

  **Return value:**
  {ref}`Toolbox <devtoolsapi-toolbox>` object or undefined if there's no toolbox for the given target..

`closeToolbox(target)`

: Closes the toolbox for given target.

  **Parameters:**

- `target {Target}` - The target of the toolbox that should be closed.

  **Return value:**
  A [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that is fulfilled once the toolbox has been destroyed.

`getDefaultTools()`

: 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.

`getAdditionalTools()`

: 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.

`getToolDefinition(toolId)`

: Fetch the {ref}`ToolDefinition <devtoolsapi-tool-definition>` object for a tool if it exists and is enabled.

  **Parameters:**

- `toolId {String}` - The ID of the tool.

  **Return value:**
  A {ref}`ToolDefinition <devtoolsapi-tool-definition>` if a tool with the given ID exists and is enabled, null otherwise.

`getToolDefinitionMap()`

: Returns a toolId → {ref}`ToolDefinition <devtoolsapi-tool-definition>` map for tools that are enabled.

`getToolDefinitionArray()`

: 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.

`getThemeDefinition(themeId)`

: Fetch the `ThemeDefinition` object for the theme with the given id.

  **Parameters:**

- `themeId {String}` - The ID of the theme.

  **Return value:**
  A `ThemeDefinition` object if the theme exists, null otherwise.

`getThemeDefinitionMap()`

: Returns a toolId → `ThemeDefinition` map for available themes.

`getThemeDefinitionArray()`

: Returns an [Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) of `ThemeDefinition` objects for available themes.

#### Events

Following events are emitted by the `gDevTools` object via the {ref}`EventEmitter <devtoolsapi-event-emitter>` interface.

`tool-registered (toolId)`

: A new tool has been registered.

`tool-unregistered(tool)`

: A tool has been unregistered. The parameter is a {ref}`ToolDefinition <devtoolsapi-tool-definition>` object.

`theme-registered(themeId)`

: A new theme has been registered.

`theme-unregistered(theme)`

: A theme has been unregistered. The parameter is a `ThemeDefinition` object.

`toolbox-ready(toolbox)`

: A new toolbox has been created and is ready to use. The parameter is a {ref}`Toolbox <devtoolsapi-toolbox>` object instance.

`toolbox-destroy(target)`

: The toolbox for the specified target is about to be destroyed.

`toolbox-destroyed(target)`

: The toolbox for the specified target has been destroyed.

`{toolId}-init(toolbox, iframe)`

: A tool with the given ID has began to load in the given toolbox to the given frame.

`{toolId}-build(toolbox, panel)`

: 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.

`{toolId}-ready(toolbox, panel)`

: 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.

`{toolId}-destroy(toolbox, panel)`

: A tool with the given ID is about to be destroyed. The panel is the object returned by the `ToolDefinition.build()` method.

(devtoolsapi-toolbox)=

### Toolbox

A Toolbox is a frame for the {ref}`ToolPanel <devtoolsapi-tool-panel>` that is debugging a specific target.

#### Properties

`target`

: **Target**. The Target this toolbox is debugging.

`hostType`

: **Toolbox.HostType**. The type of the host this Toolbox is docked to. The value is one of the `Toolbox.HostType` constants.

`zoomValue`

: The current zoom level of the Toolbox.

#### Constants

The Toolbox constructor contains following constant properties.

`Toolbox.HostType.BOTTOM`

: Host type for the default toolbox host at the bottom of the browser window.

`Toolbox.HostType.SIDE`

: Host type for the host at the side of the browser window.

`Toolbox.HostType.WINDOW`

: Host type for the separate Toolbox window.

`Toolbox.HostType.CUSTOM`

: Host type for a custom frame host.

#### Methods

`getCurrentPanel()`

: Get the currently active {ref}`ToolPanel <devtoolsapi-tool-panel>`.

  **Return value:**
  The {ref}`ToolPanel <devtoolsapi-tool-panel>` object that was returned from `ToolPanel.build()`.

`getPanel(toolId)`

: Get the {ref}`ToolPanel <devtoolsapi-tool-panel>` for given tool.

  **Parameters:**

- `toolId {String}` - The tool identifier.

  **Return value:**
  The {ref}`ToolPanel <devtoolsapi-tool-panel>` object if the tool with the given `toolId` is active, otherwise `undefined`.

`getPanelWhenReady(toolId)`

: 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.

  **Parameters:**

- `toolId {String}` - The tool identifier.

  **Return value:**
  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.

`getToolPanels()`

: 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.

`getNotificationBox()`

: Returns a `XULElem("notificationbox")` element for the Toolbox that can be used to display notifications to the user.

`loadTool(toolId)`

: Loads the tool with the given `toolId` in the background but does not activate it.

  **Parameters:**

- `toolId {String}` - The tool identifier.

  **Return value:**
  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.

`selectTool(toolId)`

: Selects the tool with the given `toolId`.

  **Parameters:**

- `toolId {String}` - The tool identifier.

  **Return value:**
  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.

`selectNextTool()`

: Selects the next tool in the `Toolbox`.

  **Return value:**
  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.

`selectPreviousTool()`

: Selects the previous tool in the `Toolbox`.

  **Return value:**
  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.

`highlightTool(toolId)`

: Highlights the tab for the given tool.

  **Parameters:**

- `toolId {String}` - The tool to highlight.

`unhighlightTool(toolId)`

: Unhighlights the tab for the given tool.

  **Parameters:**

- `toolId {String}` - The tool to unhighlight.

`openSplitConsole()`

: Opens the split Console to the bottom of the toolbox.

  **Return value:**
  A [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that is fulfilled once the Console has loaded.

`closeSplitConsole()`

: Closes the split console.

`toggleSplitConsole()`

: Toggles the state of the split console.

  **Return value:**
  A [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that is fulfilled once the operation has finished.

`switchHost(hostType)`

: Switches the location of the toolbox

  **Parameters:**

- `hostType {Toolbox.HostType}` - The type of the new host.

  **Return value:**
  A [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that is fulfilled once the new host is ready.

`reloadTarget(force)`

: Reloads the current target of the toolbox.

  **Parameters:**

- `force {Boolean} -` If true the target is shift-reloaded i.e. the cache is bypassed during the reload.

`zoomIn()`

: Increases the zoom level of the `Toolbox` document.

`zoomOut()`

: Decreases the zoom level of the `Toolbox` document.

`zoomReset()`

: Resets the zoom level of the `Toolbox` document.

`setZoom(value)`

: Set the zoom level to an arbitrary value.

  **Parameters:**

- `value {Number}` - The zoom level such as `1.2`.

`destroy()`

: Closes the toolbox.

  **Return value:**
  A [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that is resolved once the `Toolbox` is destroyed.

#### Events

The Toolbox object emits following events via the {ref}`EventEmitter <devtoolsapi-event-emitter>` interface.

`host-changed`

: The Host for this Toolbox has changed.

`ready`

: The `Toolbox` is ready to use.

`select(toolId)`

: A tool has been selected. This event is emitted before the corresponding `{toolId}-selected` event.

`{toolId}-init(frame)`

: 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.

`{toolId}-build(panel)`

: 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.

`{toolId}-ready(panel)`

: 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.

`{toolId}-selected(panel)`

: A tool has been selected. The parameter is a {ref}`ToolPanel <devtoolsapi-tool-panel>` object.

`{toolId}-destroy(panel)`

: A tool is about to be destroyed. The parameter is a {ref}`ToolPanel <devtoolsapi-tool-panel>` object.

`destroy`

: The `Toolbox` is about to be destroyed.

`destroyed`

: The `Toolbox` has been destroyed.

(devtoolsapi-tool-definition)=

### ToolDefinition

A `ToolDefinition` object contains all the required information for a tool to be shown in the toolbox.

#### Methods

`isToolSupported(toolbox)`

: A method that is called during toolbox construction to check if the tool supports debugging the given target of the given toolbox.

  **Parameters:**

- `toolbox {Toolbox}` - The toolbox where the tool is going to be displayed, if supported.

  **Return value:**
  A boolean indicating if the tool supports the given toolbox's target.

`build(window, toolbox)`

: A method that builds the {ref}`ToolPanel <devtoolsapi-tool-panel>` for this tool.

  **Parameters:**

- `window {Window}` - The [Window](https://developer.mozilla.org/en-US/docs/Web/API/Window) object for frame the tool is being built into.
- `toolbox {Toolbox}` - The {ref}`Toolbox <devtoolsapi-toolbox>` the tool is being built for.

  **Return value:**
  A {ref}`ToolPanel <devtoolsapi-tool-panel>` for the tool.

`onKey(panel, toolbox)`

: **Optional.** A method that is called when the keyboard shortcut for the tool is activated while the tool is the active tool.

  **Parameters:**

- `panel {ToolPanel}` - The {ref}`ToolPanel <devtoolsapi-tool-panel>` for the tool.
- `toolbox {Toolbox}` - The toolbox for the shortcut was triggered for.

  **Return value:**
  Undefined.

#### Properties

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.

`id`

: **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).

`url`

: **String, required.** An URL of the panel document.

`label`

: **String, optional.** The tool's name. If undefined the `icon` should be specified.

`tooltip`

: **String, optional.** The tooltip for the tool's tab.

`panelLabel`

: **String, optional.** An accessibility label for the panel.

`ordinal`

: **Integer, optional.** The position of the tool's tab within the toolbox. **Default:** 99

`visibilityswitch`

: **String, optional.** A preference name that controls the visibility of the tool. **Default:** `devtools.{id}.enabled`

`icon`

: **String, optional.** An URL for the icon to show in the toolbox tab. If undefined the label should be defined.

`highlightedicon`

: **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}`

`iconOnly`

: **Boolean, optional.** If true, the label won't be shown in the tool's tab. **Default:** false

`invertIconForLightTheme`

: **Boolean, optional.** If true the colors of the icon will be inverted for the light theme. **Default:** false

`key`

: **String, optional.** The key used for keyboard shortcut. Either `key` or `keycode` value.

`modifiers`

: **String, optional.** `modifiers` for the keyboard shortcut.

`preventClosingOnKey`

: **Boolean, optional.** If true the tool won't close if its keybinding is pressed while it is active. **Default:** false

`inMenu`

: **Boolean, optional.** If true the tool will be shown in the Developer Menu. **Default:** false

`menuLabel`

: **String, optional.** A label for the Developer Menu item. **Default:** `{label}`

`accesskey`

: **String, optional.** `accesskey` for the Developer Menu `xul:menuitem`.

#### Example

Here's a minimal definition for a tool.

```JavaScript
let def = {
  id: "my-tool",
  label: "My Tool",
  icon: "chrome://browser/skin/devtools/tool-webconsole.svg",
  url: "about:blank",
  isToolSupported: toolbox => true,
  build: (window, toolbox) => new MyToolPanel(window, toolbox)
};

// Register it.
gDevTools.registerTool(def);
```

(devtoolsapi-target-type)=

### TargetType

FIXME:

(devtoolsapi-host-type)=

### HostType

FIXME

(devtoolsapi-tool-panel)=

### ToolPanel

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.

#### Methods

`open()`

: **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.

  **Return value:**
  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.

`destroy()`

: 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.

  **Return value:**
  A [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) if the function performs asynchronous operations, otherwise `undefined`.

#### Example

Here's a basic template for a ToolPanel implementation.

```JavaScript
// In the ToolDefinition object, do
//   build: (window, target) => new MyPanel(window, target),

class MyPanel {
  constructor(window, target) {
    // The window object that has loaded the URL defined in the ToolDefinition
    this.window = window;
    // The Target this toolbox is debugging.
    this.target = target;

    // Do synchronous initialization here.
    window.document.body.addEventListener("click", this.handleClick);
  }

  open() {
    // Any asynchronous operations should be done here.
    return this.doSomethingAsynchronous()
      .then(() => this);
  }

  destroy() {
    // Synchronous destruction.
    this.window.document.body.removeEventListener("click", this.handleClick);

    // Async destruction.
    return this.destroySomethingAsynchronously()
      .then(() => console.log("destroyed"));
  }

  handleClick: function(event) {
    console.log("Clicked", event.originalTarget);
  }
}
```

(devtoolsapi-event-emitter)=

### EventEmitter

`EventEmitter` is an interface many Developer Tool classes and objects implement and use to notify others about changes in their internal state.

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.

:::{note}
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).
:::

#### Methods

The following methods are available on objects that have been decorated with the `EventEmitter` interface.

`emit(eventName, ...extraArguments)`

: Emits an event with the given name to this object.

  **Parameters:**

- `eventName {String}` - The name of the event.
- `extraArguments {...Any}` - Extra arguments that are passed to the listeners.

`on(eventName, listener)`

: Adds a listener for the given event.

`off(eventName, listener)`

: Removes the previously added listener from the event.

`once(eventName, listener)`

: Adds a listener for the event that is removed after it has been emitted once.

  **Return value:**
  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.

#### Examples

Here's a few examples using the `gDevTools` object.

```JavaScript
let onInit = (eventName, toolbox, netmonitor) => console.log("Netmonitor initialized!");

// Attach a listener.
gDevTools.on("netmonitor-init", onInit);

// Remove a listener.
gDevTools.off("netmonitor-init", onInit);

// Attach a one time listener.
gDevTools.once("netmonitor-init", (eventName, toolbox, netmonitor) => {
  console.log("Network Monitor initialized once!", toolbox, netmonitor);
});

// Use the Promise returned by the once method.
gDevTools.once("netmonitor-init").then(toolbox => {
  // Note that the second argument is not available here.
  console.log("Network Monitor initialized to toolbox", toolbox);
});
```

### ToolSidebar

To build a sidebar in your tool, first, add a xul:tabbox where you want the sidebar to live:

```xml
<splitter class="devtools-side-splitter"/>
<tabbox id="mytool-sidebar" class="devtools-sidebar-tabs" hidden="true">
  <tabs/>
  <tabpanels flex="1"/>
</tabbox>
```

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.

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.

If the loaded document exposes a `window.setPanel(ToolPanel)` function, the sidebar will call it once the document is loaded.

```{eval-rst}
.. list-table:: Methods
  :widths: 70 30
  :header-rows: 1

  * - Method
    - Description

  * - ``new ToolSidebar(xul:tabbox, ToolPanel, showTabstripe=true)``
    - ToolSidebar constructor

  * - ``void addTab(tabId, url, selected=false)``
    - Add a tab in the sidebar

  * - ``void select(tabId)``
    - Select a tab

  * - ``void hide()``
    - Hide the sidebar

  * - ``void show()``
    - Show the sidebar

  * - ``void toggle()``
    - Toggle the sidebar

  * - ``void getWindowForTab(tabId)``
    - Get the iframe containing the tab content

  * - ``tabId getCurrentTabID()``
    - Return the id of tabId of the current tab

  * - ``tabbox getTab(tabId)``
    - Return a tab given its id

  * - ``destroy()``
    - Destroy the ToolSidebar object
```

```{eval-rst}
.. list-table:: Events
  :widths: 70 30
  :header-rows: 1

  * - Events
    - Description

  * - ``new-tab-registered``
    - A new tab has been added

  * - ``{tabId}-ready``
    - Tab is loaded and can be used

  * - ``{tabId}-selected``
    - Tab has been selected and is visible

  * - ``show``
    - The sidebar has been opened.

  * - ``hide``
    - The sidebar has been closed.

```

### Examples

Register a tool

```JavaScript
gDevTools.registerTool({
  // FIXME: missing key related properties.
  id: "inspector",
  icon: "chrome://browser/skin/devtools/inspector-icon.png",
  url: "chrome://browser/content/devtools/inspector/inspector.xul",
  get label() {
    let strings = Services.strings.createBundle("chrome://browser/locale/devtools/inspector.properties");
    return strings.GetStringFromName("inspector.label");
  },

  isToolSupported: function(toolbox) {
    return toolbox.commands.descriptorFront.isLocalTab;
  },

  build: function(iframeWindow, toolbox, node) {
    return new InspectorPanel(iframeWindow, toolbox, node);
  }
});
```

Open a tool, or select it if the toolbox is already open:

```JavaScript
let target = TargetFactory.forTab(gBrowser.selectedTab);
let toolbox = gDevTools.openToolbox(target, null, "inspector");

toolbox.once("inspector-ready", function(event, panel) {
  let inspector = toolbox.getToolPanels().get("inspector");
  inspector.selection.setNode(target, "browser-context-menu");
});
```

Add a sidebar to an existing tool:

```JavaScript
let sidebar = new ToolSidebar(xulTabbox, toolPanel);
sidebar.addTab("tab1", "chrome://browser/content/.../tab1.xhtml", true);
sidebar.addTab("tab2", "chrome://browser/content/.../tab2.xhtml", false);
sidebar.show();
```

---

### Devtools Docs User Devtoolscolors Index (`devtools/docs/user/devtoolscolors/index.md`)

---
myst:
  substitutions:
    br: |-
      ```{raw} html
      <br/><br/>```
---

# DevToolsColors

:::{warning}
**Firefox developers**: Don't change any of these values without UX approval. If any of these values need to be changed, you will need to change some CSS code in `/browser/themes/*/devtools/`. File a DevTools bug accordingly.
:::

This chart lists colors and CSS variables as implemented in the dark theme and light theme for developer tools.

```
/* Detailed source-code truncated for AI context efficiency. */
```

:::{warning}
Not yet finalized. See [bug 916766](https://bugzilla.mozilla.org/show_bug.cgi?id=916766) for progress.
:::

---

### Devtools Docs User Dom Property Viewer Index (`devtools/docs/user/dom_property_viewer/index.md`)

# DOM Property Viewer

:::{container} block_quote
The DOM Property Viewer is disabled by default. Enable it in the {ref}`Developer Tools Settings <tool-toolbox-settings>`
:::

The DOM Property Viewer lets you inspect the properties of the [DOM](https://developer.mozilla.org/en-US/docs/Glossary/DOM) as an expandable tree structure, starting from the [window](https://developer.mozilla.org/en-US/docs/Web/API/Window) object of the current page or the {doc}`selected iframe <../working_with_iframes/index>`.

```{image} dom_inspector.png
:class: center
```

## Enabling the DOM Property Viewer

The DOM Property Viewer is not enabled by default. To enable it, open the {ref}`developer tools settings <tool-toolbox-settings>` and check the "DOM" box under "Default Firefox Developer Tools".

## Opening the DOM Property Viewer

Once enabled, you can select the *DOM* panel in the Web Developer Tools, accessible from the Browser Tools submenu

The {doc}`Toolbox <../tools_toolbox/index>` will appear at the bottom of the browser window, with the DOM Property Viewer activated. It's just called "DOM" in the Toolbox.

## DOM Property Viewer user interface

### DOM tree

The different properties of the DOM are displayed as an expandable tree. The left-hand side shows the property's name, and the right-hand side shows its value. Up to three properties of an object and items of an array are displayed. If a property has more elements than this, you'll see a "more..." annotation, and will need to click the property to see all elements. A lock icon indicates that a property is not writable.

### Refreshing the display

If the DOM changes you can hit the *Refresh* button to update the display:

```{image} dom_inspector_refresh_button.png
:alt: Button to update the DOM Inspector display
:class: center
```

### Filtering

There is a search box within the toolbar:

```{image} dom_inspector_search_box.png
:class: center
```

This filters the list to show only items which match the search term. Items match the search term if their name contains the search term. Matching is case-sensitive.

---

--- METRICS ---
- Files Extracted: 98
- Estimated Token Budget: ~120887 tokens
- Canonical Reference: https://codewiki.google/github.com/mozilla-firefox/firefox
