summaryrefslogtreecommitdiffstats
path: root/docs/code-quality/lint/linters
diff options
context:
space:
mode:
Diffstat (limited to 'docs/code-quality/lint/linters')
-rw-r--r--docs/code-quality/lint/linters/android-format.rst31
-rw-r--r--docs/code-quality/lint/linters/black.rst36
-rw-r--r--docs/code-quality/lint/linters/clang-format.rst35
-rw-r--r--docs/code-quality/lint/linters/clippy.rst36
-rw-r--r--docs/code-quality/lint/linters/codespell.rst36
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla.rst114
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/avoid-Date-timing.rst30
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/avoid-removeChild.rst20
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/balanced-listeners.rst20
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/balanced-observers.rst20
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/consistent-if-bracing.rst23
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/environment.rst76
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/import-browser-window-globals.rst8
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/import-content-task-globals.rst14
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/import-globals-from.rst18
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/import-globals.rst5
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/import-headjs-globals.rst28
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/lazy-getter-object-name.rst25
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/mark-exported-symbols-as-used.rst23
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/mark-test-function-used.rst8
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/no-aArgs.rst22
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/no-addtask-setup.rst27
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/no-arbitrary-setTimeout.rst23
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/no-compare-against-boolean-literals.rst23
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/no-cu-reportError.rst23
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/no-define-cc-etc.rst23
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/no-redeclare-with-import-autofix.rst21
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/no-throw-cr-literal.rst38
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/no-useless-parameters.rst26
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/no-useless-removeEventListener.rst20
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/no-useless-run-test.rst6
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/prefer-boolean-length-check.rst24
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/prefer-formatValues.rst23
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-addtask-only.rst6
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-chromeutils-import-params.rst22
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-eager-module-in-lazy-getter.rst35
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-global-this.rst29
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-globalThis-modification.rst19
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-import-system-module-from-non-system.rst36
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-importGlobalProperties.rst45
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-lazy-imports-into-globals.rst36
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-mixing-eager-and-lazy.rst22
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-multiple-getters-calls.rst27
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-relative-requires.rst22
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-requires-await.rst20
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-scriptableunicodeconverter.rst13
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-some-requires.rst6
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-top-level-await.rst26
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/use-cc-etc.rst26
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/use-chromeutils-generateqi.rst33
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/use-chromeutils-import.rst24
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/use-default-preference-values.rst19
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/use-includes-instead-of-indexOf.rst21
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/use-isInstance.rst42
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/use-ownerGlobal.rst20
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/use-returnValue.rst20
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/use-services.rst21
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/use-static-import.rst21
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/valid-ci-uses.rst42
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/valid-lazy.rst55
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/valid-services-property.rst30
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/valid-services.rst24
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-mozilla/var-only-at-top-level.rst21
-rw-r--r--docs/code-quality/lint/linters/eslint-plugin-spidermonkey-js.rst18
-rw-r--r--docs/code-quality/lint/linters/eslint.rst211
-rw-r--r--docs/code-quality/lint/linters/file-perm.rst42
-rw-r--r--docs/code-quality/lint/linters/file-whitespace.rst38
-rw-r--r--docs/code-quality/lint/linters/fluent-lint.rst47
-rw-r--r--docs/code-quality/lint/linters/l10n.rst45
-rw-r--r--docs/code-quality/lint/linters/license.rst39
-rw-r--r--docs/code-quality/lint/linters/lintpref.rst32
-rw-r--r--docs/code-quality/lint/linters/mingw-capitalization.rst28
-rw-r--r--docs/code-quality/lint/linters/perfdocs.rst84
-rw-r--r--docs/code-quality/lint/linters/rejected-words.rst28
-rw-r--r--docs/code-quality/lint/linters/rstlinter.rst32
-rw-r--r--docs/code-quality/lint/linters/ruff.rst44
-rw-r--r--docs/code-quality/lint/linters/rustfmt.rst33
-rw-r--r--docs/code-quality/lint/linters/stylelint.rst77
-rw-r--r--docs/code-quality/lint/linters/trojan-source.rst34
-rw-r--r--docs/code-quality/lint/linters/yamllint.rst31
80 files changed, 2551 insertions, 0 deletions
diff --git a/docs/code-quality/lint/linters/android-format.rst b/docs/code-quality/lint/linters/android-format.rst
new file mode 100644
index 0000000000..ed23ac64de
--- /dev/null
+++ b/docs/code-quality/lint/linters/android-format.rst
@@ -0,0 +1,31 @@
+Spotless
+========
+
+`Spotless <https://github.com/diffplug/spotless>`__ is a pluggable formatter
+for Gradle and Android.
+
+In our current configuration, Spotless includes the
+`Google Java Format plug-in <https://github.com/google/google-java-format>`__
+which formats all our Java code using the Google Java coding style guidelines,
+and `ktlint <https://ktlint.github.io/>`__ which formats all
+our Kotlin code using the official Kotlin coding convention and Android Kotlin
+Style Guide.
+
+
+Run Locally
+-----------
+
+The mozlint integration of spotless can be run using mach:
+
+.. parsed-literal::
+
+ $ mach lint --linter android-format
+
+Alternatively, omit the ``--linter android-format`` and run all configured linters, which will include
+spotless.
+
+
+Autofix
+-------
+
+The spotless linter provides a ``--fix`` option.
diff --git a/docs/code-quality/lint/linters/black.rst b/docs/code-quality/lint/linters/black.rst
new file mode 100644
index 0000000000..60a06ce95b
--- /dev/null
+++ b/docs/code-quality/lint/linters/black.rst
@@ -0,0 +1,36 @@
+Black
+=====
+
+`Black <https://black.readthedocs.io/en/stable/>`__ is a opinionated python code formatter.
+
+
+Run Locally
+-----------
+
+The mozlint integration of black can be run using mach:
+
+.. parsed-literal::
+
+ $ mach lint --linter black <file paths>
+
+Alternatively, omit the ``--linter black`` and run all configured linters, which will include
+black.
+
+
+Configuration
+-------------
+
+To enable black on new directory, add the path to the include
+section in the :searchfox:`black.yml <tools/lint/black.yml>` file.
+
+Autofix
+-------
+
+The black linter provides a ``--fix`` option.
+
+
+Sources
+-------
+
+* :searchfox:`Configuration (YAML) <tools/lint/black.yml>`
+* :searchfox:`Source <tools/lint/python/black.py>`
diff --git a/docs/code-quality/lint/linters/clang-format.rst b/docs/code-quality/lint/linters/clang-format.rst
new file mode 100644
index 0000000000..a528af4358
--- /dev/null
+++ b/docs/code-quality/lint/linters/clang-format.rst
@@ -0,0 +1,35 @@
+clang-format
+============
+
+`clang-format <https://clang.llvm.org/docs/ClangFormat.html>`__ is a tool to reformat C/C++ to the right coding style.
+
+Run Locally
+-----------
+
+The mozlint integration of clang-format can be run using mach:
+
+.. parsed-literal::
+
+ $ mach lint --linter clang-format <file paths>
+
+
+Configuration
+-------------
+
+To enable clang-format on new directory, add the path to the include
+section in the :searchfox:`clang-format.yml <tools/lint/clang-format.yml>` file.
+
+While excludes: will work, this linter will read the ignore list from :searchfox:`.clang-format-ignore file <.clang-format-ignore>`
+at the root directory. This because it is also used by the ./mach clang-format -p command.
+
+Autofix
+-------
+
+clang-format can reformat the code with the option `--fix` (based on the upstream option `-i`).
+To highlight the results, we are using the ``--dry-run`` option (from clang-format 10).
+
+Sources
+-------
+
+* :searchfox:`Configuration (YAML) <tools/lint/clang-format.yml>`
+* :searchfox:`Source <tools/lint/clang-format/__init__.py>`
diff --git a/docs/code-quality/lint/linters/clippy.rst b/docs/code-quality/lint/linters/clippy.rst
new file mode 100644
index 0000000000..40db532b88
--- /dev/null
+++ b/docs/code-quality/lint/linters/clippy.rst
@@ -0,0 +1,36 @@
+clippy
+======
+
+`clippy`_ is the tool for Rust static analysis.
+
+Run Locally
+-----------
+
+The mozlint integration of clippy can be run using mach:
+
+.. parsed-literal::
+
+ $ mach lint --linter clippy <file paths>
+
+.. note::
+
+ clippy expects a path or a .rs file. It doesn't accept Cargo.toml
+ as it would break the mozlint workflow.
+
+Configuration
+-------------
+
+To enable clippy on new directory, add the path to the include
+section in the `clippy.yml <https://searchfox.org/mozilla-central/source/tools/lint/clippy.yml>`_ file.
+
+Autofix
+-------
+
+This linter provides a ``--fix`` option.
+Please note that this option does not fix all detected issues.
+
+Sources
+-------
+
+* `Configuration (YAML) <https://searchfox.org/mozilla-central/source/tools/lint/clippy.yml>`_
+* `Source <https://searchfox.org/mozilla-central/source/tools/lint/clippy/__init__.py>`_
diff --git a/docs/code-quality/lint/linters/codespell.rst b/docs/code-quality/lint/linters/codespell.rst
new file mode 100644
index 0000000000..9299a81b6e
--- /dev/null
+++ b/docs/code-quality/lint/linters/codespell.rst
@@ -0,0 +1,36 @@
+Codespell
+=========
+
+`codespell <https://github.com/codespell-project/codespell/>`__ is a popular tool to look for typical typos in the source code.
+
+It is enabled mostly for the documentation and English locale files.
+
+Run Locally
+-----------
+
+The mozlint integration of codespell can be run using mach:
+
+.. parsed-literal::
+
+ $ mach lint --linter codespell <file paths>
+
+
+Configuration
+-------------
+
+To enable codespell on new directory, add the path to the include
+section in the :searchfox:`codespell.yml <tools/lint/codespell.yml>` file.
+
+This job is configured as `tier 2 <https://wiki.mozilla.org/Sheriffing/Job_Visibility_Policy#Overview_of_the_Job_Visibility_Tiers>`_.
+
+Autofix
+-------
+
+Codespell provides a ``--fix`` option. It is based on the ``-w`` option provided by upstream.
+
+
+Sources
+-------
+
+* :searchfox:`Configuration (YAML) <tools/lint/codespell.yml>`
+* :searchfox:`Source <tools/lint/spell/__init__.py>`
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla.rst
new file mode 100644
index 0000000000..d1d60c963c
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla.rst
@@ -0,0 +1,114 @@
+=====================
+Mozilla ESLint Plugin
+=====================
+
+This is the documentation of Mozilla ESLint PLugin.
+
+Environments
+============
+
+The plugin implements the following environments:
+
+
+.. toctree::
+ :maxdepth: 2
+
+ eslint-plugin-mozilla/environment
+
+Rules
+=====
+
+The plugin implements the following rules:
+
+.. toctree::
+ :maxdepth: 1
+
+ eslint-plugin-mozilla/avoid-Date-timing
+ eslint-plugin-mozilla/avoid-removeChild
+ eslint-plugin-mozilla/balanced-listeners
+ eslint-plugin-mozilla/balanced-observers
+ eslint-plugin-mozilla/consistent-if-bracing
+ eslint-plugin-mozilla/import-browser-window-globals
+ eslint-plugin-mozilla/import-content-task-globals
+ eslint-plugin-mozilla/import-globals
+ eslint-plugin-mozilla/import-globals-from
+ eslint-plugin-mozilla/import-headjs-globals
+ eslint-plugin-mozilla/lazy-getter-object-name
+ eslint-plugin-mozilla/mark-exported-symbols-as-used
+ eslint-plugin-mozilla/mark-test-function-used
+ eslint-plugin-mozilla/no-aArgs
+ eslint-plugin-mozilla/no-addtask-setup
+ eslint-plugin-mozilla/no-arbitrary-setTimeout
+ eslint-plugin-mozilla/no-compare-against-boolean-literals
+ eslint-plugin-mozilla/no-cu-reportError
+ eslint-plugin-mozilla/no-define-cc-etc
+ eslint-plugin-mozilla/no-redeclare-with-import-autofix
+ eslint-plugin-mozilla/no-throw-cr-literal
+ eslint-plugin-mozilla/no-useless-parameters
+ eslint-plugin-mozilla/no-useless-removeEventListener
+ eslint-plugin-mozilla/no-useless-run-test
+ eslint-plugin-mozilla/prefer-boolean-length-check
+ eslint-plugin-mozilla/prefer-formatValues
+ eslint-plugin-mozilla/reject-addtask-only
+ eslint-plugin-mozilla/reject-chromeutils-import-params
+ eslint-plugin-mozilla/reject-eager-module-in-lazy-getter
+ eslint-plugin-mozilla/reject-global-this
+ eslint-plugin-mozilla/reject-globalThis-modification
+ eslint-plugin-mozilla/reject-importGlobalProperties
+ eslint-plugin-mozilla/reject-lazy-imports-into-globals
+ eslint-plugin-mozilla/reject-mixing-eager-and-lazy
+ eslint-plugin-mozilla/reject-multiple-getters-calls
+ eslint-plugin-mozilla/reject-relative-requires
+ eslint-plugin-mozilla/reject-requires-await
+ eslint-plugin-mozilla/reject-scriptableunicodeconverter
+ eslint-plugin-mozilla/reject-some-requires
+ eslint-plugin-mozilla/reject-top-level-await
+ eslint-plugin-mozilla/reject-import-system-module-from-non-system
+ eslint-plugin-mozilla/use-cc-etc
+ eslint-plugin-mozilla/use-chromeutils-generateqi
+ eslint-plugin-mozilla/use-chromeutils-import
+ eslint-plugin-mozilla/use-default-preference-values
+ eslint-plugin-mozilla/use-includes-instead-of-indexOf
+ eslint-plugin-mozilla/use-isInstance
+ eslint-plugin-mozilla/use-ownerGlobal
+ eslint-plugin-mozilla/use-returnValue
+ eslint-plugin-mozilla/use-services
+ eslint-plugin-mozilla/use-static-import
+ eslint-plugin-mozilla/valid-ci-uses
+ eslint-plugin-mozilla/valid-lazy
+ eslint-plugin-mozilla/valid-services
+ eslint-plugin-mozilla/valid-services-property
+ eslint-plugin-mozilla/var-only-at-top-level
+
+Tests
+=====
+
+The tests for eslint-plugin-mozilla are run via `mochajs`_ on top of node. Most
+of the tests use the `ESLint Rule Unit Test framework`_.
+
+.. _mochajs: https://mochajs.org/
+.. _ESLint Rule Unit Test Framework: http://eslint.org/docs/developer-guide/working-with-rules#rule-unit-tests
+
+Running Tests
+-------------
+
+The tests for eslint-plugin-mozilla are run via `mochajs`_ on top of node. Most
+of the tests use the `ESLint Rule Unit Test framework`_.
+
+The rules have some self tests, these can be run via:
+
+.. code-block:: shell
+
+ $ cd tools/lint/eslint/eslint-plugin-mozilla
+ $ npm install
+ $ npm run test
+
+Disabling tests
+---------------
+
+In the unlikely event of needing to disable a test, currently the only way is
+by commenting-out. Please file a bug if you have to do this. Bugs should be filed
+in the *Testing* product under *Lint*.
+
+.. _mochajs: https://mochajs.org/
+.. _ESLint Rule Unit Test Framework: http://eslint.org/docs/developer-guide/working-with-rules#rule-unit-tests
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/avoid-Date-timing.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/avoid-Date-timing.rst
new file mode 100644
index 0000000000..b01b568a28
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/avoid-Date-timing.rst
@@ -0,0 +1,30 @@
+avoid-Date-timing
+=================
+
+Rejects grabbing the current time via Date.now() or new Date() for timing
+purposes when the less problematic performance.now() can be used instead.
+
+The performance.now() function returns milliseconds since page load. To
+convert that to milliseconds since the epoch, use:
+
+.. code-block:: js
+
+ performance.timing.navigationStart + performance.now()
+
+Often timing relative to the page load is adequate and that conversion may not
+be necessary.
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+.. code-block:: js
+
+ Date.now()
+
+Examples of correct code for this rule:
+---------------------------------------
+
+.. code-block:: js
+
+ new Date('2017-07-11');
+ performance.now()
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/avoid-removeChild.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/avoid-removeChild.rst
new file mode 100644
index 0000000000..15ece94d0d
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/avoid-removeChild.rst
@@ -0,0 +1,20 @@
+avoid-removeChild
+=================
+
+Rejects using ``element.parentNode.removeChild(element)`` when ``element.remove()``
+can be used instead.
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+.. code-block:: js
+
+ elt.parentNode.removeChild(elt);
+
+Examples of correct code for this rule:
+---------------------------------------
+
+.. code-block:: js
+
+ elt.remove();
+ elt.parentNode.removeChild(elt2);
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/balanced-listeners.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/balanced-listeners.rst
new file mode 100644
index 0000000000..f53c11e7aa
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/balanced-listeners.rst
@@ -0,0 +1,20 @@
+balanced-listeners
+==================
+
+Checks that for every occurrence of 'addEventListener' or 'on' there is an
+occurrence of 'removeEventListener' or 'off' with the same event name.
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+.. code-block:: js
+
+ elt.addEventListener('click', handler, false);
+
+Examples of correct code for this rule:
+---------------------------------------
+
+.. code-block:: js
+
+ elt.addEventListener('event', handler);
+ elt.removeEventListener('event', handler);
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/balanced-observers.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/balanced-observers.rst
new file mode 100644
index 0000000000..b169a520a3
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/balanced-observers.rst
@@ -0,0 +1,20 @@
+balanced-observers
+==================
+
+Checks that for every occurrence of ``addObserver`` there is an
+occurrence of ``removeObserver`` with the same topic.
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+.. code-block:: js
+
+ Services.obs.addObserver(observer, 'observable');
+
+Examples of correct code for this rule:
+---------------------------------------
+
+.. code-block:: js
+
+ Services.obs.addObserver(observer, 'observable');
+ Services.obs.removeObserver(observer, 'observable');
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/consistent-if-bracing.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/consistent-if-bracing.rst
new file mode 100644
index 0000000000..7bf6b796ef
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/consistent-if-bracing.rst
@@ -0,0 +1,23 @@
+consistent-if-bracing
+=====================
+
+Checks that if/elseif/else bodies are braced consistently, so either all bodies
+are braced or unbraced. Doesn't enforce either of those styles though.
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+.. code-block:: js
+
+ if (true) {1} else 0
+ if (true) 1; else {0}
+ if (true) {1} else if (true) 2; else {0}
+
+Examples of correct code for this rule:
+---------------------------------------
+
+.. code-block:: js
+
+ if (true) {1} else {0}
+ if (false) 1; else 0
+ if (true) {1} else if (true) {2} else {0}
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/environment.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/environment.rst
new file mode 100644
index 0000000000..2c779410d6
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/environment.rst
@@ -0,0 +1,76 @@
+Environment
+===========
+
+These environments are available by specifying a comment at the top of the file,
+e.g.
+
+.. code-block:: js
+
+ /* eslint-env mozilla/chrome-worker */
+
+There are also built-in ESLint environments available as well. Find them here: http://eslint.org/docs/user-guide/configuring#specifying-environments
+
+browser-window
+--------------
+
+Defines the environment for scripts that are in the main browser.xhtml scope.
+
+chrome-script
+-------------
+
+Defines the environment for scripts loaded by
+``SpecialPowers.loadChromeScript``.
+
+chrome-worker
+-------------
+
+Defines the environment for chrome workers. This differs from normal workers by
+the fact that `ctypes` can be accessed as well.
+
+frame-script
+------------
+
+Defines the environment for scripts loaded by ``Services.mm.loadFrameScript``.
+
+jsm
+---
+
+Defines the environment for jsm files (javascript modules).
+
+privileged
+----------
+
+Defines the environment for privileged JS files.
+
+process-script
+--------------
+
+Defines the environment for scripts loaded by
+``Services.ppmm.loadProcessScript``.
+
+remote-page
+-----------
+
+Defines the environment for scripts loaded with ``<script src="...">`` in
+``about:`` pages.
+
+simpletest
+----------
+
+Defines the environment for scripts that use the SimpleTest mochitest harness.
+
+sjs
+---
+
+Defines the environment for sjs files.
+
+special-powers-sandbox
+----------------------
+
+Defines the environment for scripts evaluated inside ``SpecialPowers`` sandbox
+with the default options.
+
+xpcshell
+--------
+
+Defines the environment for xpcshell test files.
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/import-browser-window-globals.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/import-browser-window-globals.rst
new file mode 100644
index 0000000000..35c09cc8fd
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/import-browser-window-globals.rst
@@ -0,0 +1,8 @@
+import-browser-window-globals
+=============================
+
+For scripts included in browser-window, this will automatically inject the
+browser-window global scopes into the file.
+
+This is a rule rather than an environment, as it allowed us to automatically
+select the files to include.
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/import-content-task-globals.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/import-content-task-globals.rst
new file mode 100644
index 0000000000..f2550a1412
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/import-content-task-globals.rst
@@ -0,0 +1,14 @@
+import-content-task-globals
+===========================
+
+For files containing ContentTask.spawn calls, this will automatically declare
+the frame script variables in the global scope. ContentTask is only available
+to test files, so by default the configs only specify it for the mochitest based
+configurations.
+
+This saves setting the file as a mozilla/frame-script environment.
+
+Note: due to the way ESLint works, it appears it is only easy to declare these
+variables on a file global scope, rather than function global. This may mean that
+they are incorrectly allowed, but given they are test files, this should be
+detected during testing.
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/import-globals-from.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/import-globals-from.rst
new file mode 100644
index 0000000000..c2956ba05a
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/import-globals-from.rst
@@ -0,0 +1,18 @@
+import-globals-from
+===================
+
+Parses a file for globals defined in various unique Mozilla ways.
+
+When a ``/* import-globals-from <path> */`` comment is found in a file, then all
+globals from the file at <path> will be imported in the current scope. This will
+also operate recursively.
+
+This is useful for scripts that are loaded as <script> tag in a window and rely
+on each other's globals.
+
+If <path> is a relative path, then it must be relative to the file being
+checked by the rule.
+
+Note: ``import-globals-from`` does not support loading globals from ES modules.
+These should be imported as variable definitions directly, or the file where
+they are imported should be referenced.
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/import-globals.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/import-globals.rst
new file mode 100644
index 0000000000..2c47a5210f
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/import-globals.rst
@@ -0,0 +1,5 @@
+import-globals
+==============
+
+Checks ``XPCOMUtils.defineLazyGetter`` etc and adds the name to the global
+scope.
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/import-headjs-globals.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/import-headjs-globals.rst
new file mode 100644
index 0000000000..a754bd7985
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/import-headjs-globals.rst
@@ -0,0 +1,28 @@
+import-headjs-globals
+=====================
+
+Import globals from head.js and from any files that were imported by
+head.js (as far as we can correctly resolve the path).
+
+This rule is included in the test configurations.
+
+The following file import patterns are supported:
+
+- ``Services.scriptloader.loadSubScript(path)``
+- ``loader.loadSubScript(path)``
+- ``loadSubScript(path)``
+- ``loadHelperScript(path)``
+- ``import-globals-from path``
+
+If path does not exist because it is generated e.g.
+``testdir + "/somefile.js"`` we do our best to resolve it.
+
+The following patterns are supported:
+
+- ``Cu.import("resource://devtools/client/shared/widgets/ViewHelpers.jsm");``
+- ``loader.lazyRequireGetter(this, "name2"``
+- ``loader.lazyServiceGetter(this, "name3"``
+- ``XPCOMUtils.defineLazyModuleGetter(this, "setNamedTimeout", ...)``
+- ``loader.lazyGetter(this, "toolboxStrings"``
+- ``XPCOMUtils.defineLazyGetter(this, "clipboardHelper"``
+- ``ChromeUtils.defineLazyGetter(this, "clipboardHelper"``
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/lazy-getter-object-name.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/lazy-getter-object-name.rst
new file mode 100644
index 0000000000..090f445b69
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/lazy-getter-object-name.rst
@@ -0,0 +1,25 @@
+lazy-getter-object-name
+=============================
+
+Enforce the standard object variable name ``lazy`` for
+``ChromeUtils.defineESModuleGetters``
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+.. code-block:: js
+
+ const obj = {};
+ ChromeUtils.defineESModuleGetters(obj, {
+ AppConstants: “resource://gre/modules/AppConstants.sys.mjs”,
+ });
+
+Examples of correct code for this rule:
+---------------------------------------
+
+.. code-block:: js
+
+ const lazy = {};
+ ChromeUtils.defineESModuleGetters(lazy, {
+ AppConstants: “resource://gre/modules/AppConstants.sys.mjs”,
+ });
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/mark-exported-symbols-as-used.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/mark-exported-symbols-as-used.rst
new file mode 100644
index 0000000000..92e315a249
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/mark-exported-symbols-as-used.rst
@@ -0,0 +1,23 @@
+mark-exported-symbols-as-used
+=============================
+
+Marks variables listed in ``EXPORTED_SYMBOLS`` as used so that ``no-unused-vars``
+does not complain about them.
+
+This rule also checks that ``EXPORTED_SYMBOLS`` is not defined using ``let`` as
+``let`` isn't allowed as the lexical scope may die after the script executes.
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+.. code-block:: js
+
+ let EXPORTED_SYMBOLS = ["foo"];
+
+Examples of correct code for this rule:
+---------------------------------------
+
+.. code-block:: js
+
+ var EXPORTED_SYMBOLS = ["foo"];
+ const EXPORTED_SYMBOLS = ["foo"];
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/mark-test-function-used.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/mark-test-function-used.rst
new file mode 100644
index 0000000000..a518d7415b
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/mark-test-function-used.rst
@@ -0,0 +1,8 @@
+mark-test-function-used
+=======================
+
+Simply marks ``test`` (the test method) or ``run_test`` as used when in mochitests
+or xpcshell tests respectively. This avoids ESLint telling us that the function
+is never called.
+
+This rule is included in the test configurations.
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/no-aArgs.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/no-aArgs.rst
new file mode 100644
index 0000000000..7e398bcbbe
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/no-aArgs.rst
@@ -0,0 +1,22 @@
+no-aArgs
+========
+
+Checks that function argument names don't start with lowercase 'a' followed by
+a capital letter. This is to prevent the use of Hungarian notation whereby the
+first letter is a prefix that indicates the type or intended use of a variable.
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+.. code-block:: js
+
+ function(aFoo, aBar) {}
+ (aFoo, aBar) => {}
+
+Examples of correct code for this rule:
+---------------------------------------
+
+.. code-block:: js
+
+ function(foo, bar) {}
+ (foo, bar) => {})
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/no-addtask-setup.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/no-addtask-setup.rst
new file mode 100644
index 0000000000..f26a869371
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/no-addtask-setup.rst
@@ -0,0 +1,27 @@
+no-addtask-setup
+================
+
+Reject using ``add_task(async function setup() { ... })`` in favour of
+``add_setup(async function() { ... })``.
+
+Using semantically separate setup functions makes ``.only`` work correctly
+and will allow for future improvements to setup/cleanup abstractions.
+
+This option can be autofixed (``--fix``).
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+.. code-block:: js
+
+ add_task(async function setup() { ... });
+ add_task(function setup() { ... });
+ add_task(function init() { ... });
+
+Examples of correct code for this rule:
+---------------------------------------
+
+.. code-block:: js
+
+ add_setup(async function() { ... });
+ add_setup(function() { ... });
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/no-arbitrary-setTimeout.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/no-arbitrary-setTimeout.rst
new file mode 100644
index 0000000000..a7d62e74ba
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/no-arbitrary-setTimeout.rst
@@ -0,0 +1,23 @@
+no-arbitrary-setTimeout
+=======================
+
+Disallows setTimeout with non-zero values in tests. Using arbitrary times for
+setTimeout may cause intermittent failures in tests. A value of zero is allowed
+as this is letting the event stack unwind, however also consider the use
+of ``TestUtils.waitForTick``.
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+.. code-block:: js
+
+ function(aFoo, aBar) {}
+ (aFoo, aBar) => {}
+
+Examples of correct code for this rule:
+---------------------------------------
+
+.. code-block:: js
+
+ function(foo, bar) {}
+ (foo, bar) => {})
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/no-compare-against-boolean-literals.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/no-compare-against-boolean-literals.rst
new file mode 100644
index 0000000000..b7785f2fc2
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/no-compare-against-boolean-literals.rst
@@ -0,0 +1,23 @@
+no-compare-against-boolean-literals
+===================================
+
+Checks that boolean expressions do not compare against literal values
+of ``true`` or ``false``. This is to prevent overly verbose code such as
+``if (isEnabled == true)`` when ``if (isEnabled)`` would suffice.
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+.. code-block:: js
+
+ if (foo == true) {}
+ if (foo != false) {}
+ if (false == foo) {}
+
+Examples of correct code for this rule:
+---------------------------------------
+
+.. code-block:: js
+
+ if (!foo) {}
+ if (!!foo) {}
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/no-cu-reportError.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/no-cu-reportError.rst
new file mode 100644
index 0000000000..9f5a0def27
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/no-cu-reportError.rst
@@ -0,0 +1,23 @@
+no-cu-reportError
+=================
+
+Disallows Cu.reportError. This has been deprecated and should be replaced by
+console.error.
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+.. code-block:: js
+
+ Cu.reportError("message");
+ Cu.reportError("message", stack);
+
+Examples of correct code for this rule:
+---------------------------------------
+
+.. code-block:: js
+
+ console.error("message");
+ let error = new Error("message");
+ error.stack = stack;
+ console.error(error);
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/no-define-cc-etc.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/no-define-cc-etc.rst
new file mode 100644
index 0000000000..4421f4dd54
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/no-define-cc-etc.rst
@@ -0,0 +1,23 @@
+no-define-cc-etc
+================
+
+Disallows old-style definitions for ``Cc``/``Ci``/``Cu``/``Cr``. These are now
+defined globally for all chrome contexts.
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+.. code-block:: js
+
+ var Cc = Components.classes;
+ var Ci = Components.interfaces;
+ var {Ci: interfaces, Cc: classes, Cu: utils} = Components;
+ var Cr = Components.results;
+
+
+Examples of correct code for this rule:
+---------------------------------------
+
+.. code-block:: js
+
+ const CC = Components.Constructor;
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/no-redeclare-with-import-autofix.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/no-redeclare-with-import-autofix.rst
new file mode 100644
index 0000000000..d7d4edab50
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/no-redeclare-with-import-autofix.rst
@@ -0,0 +1,21 @@
+no-redeclare-with-import-autofix
+================================
+
+This is the
+`builtin eslint rule no-redeclare <https://eslint.org/docs/latest/rules/no-redeclare>`_,
+but with an additional fixer that can automatically remove superfluous
+(duplicate) imports.
+
+For redeclarations that are not imports, there is no automatic fix, as
+the author will likely have to rename variables so that they do not
+redeclare existing variables or conflict with the name of a builtin
+property or global variable.
+
+Typical duplicate imports happen when a `head.js` file, imports
+a module and a test then subsequently also attempts to import the same
+module.
+
+In browser mochitests, an additional typical scenario is importing
+modules that are already imported in the main browser window. Because
+these tests run in a scope that inherits from the main browser window
+one, there is no need to re-import such modules.
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/no-throw-cr-literal.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/no-throw-cr-literal.rst
new file mode 100644
index 0000000000..0f9222de30
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/no-throw-cr-literal.rst
@@ -0,0 +1,38 @@
+no-throw-cr-literal
+===================
+
+This is similar to the ESLint built-in rule no-throw-literal. It disallows
+throwing Components.results code directly.
+
+Throwing bare literals is inferior to throwing Exception objects, which provide
+stack information. Cr.ERRORs should be be passed as the second argument to
+``Components.Exception()`` to create an Exception object with stack info, and
+the correct result property corresponding to the NS_ERROR that other code
+expects.
+Using a regular ``new Error()`` to wrap just turns it into a string and doesn't
+set the result property, so the errors can't be recognised.
+
+This option can be autofixed (``--fix``).
+
+.. code-block:: js
+
+ performance.timing.navigationStart + performance.now()
+
+Often timing relative to the page load is adequate and that conversion may not
+be necessary.
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+.. code-block:: js
+
+ throw Cr.NS_ERROR_UNEXPECTED;
+ throw Components.results.NS_ERROR_ABORT;
+ throw new Error(Cr.NS_ERROR_NO_INTERFACE);
+
+Examples of correct code for this rule:
+---------------------------------------
+
+.. code-block:: js
+
+ throw Components.Exception("Not implemented", Cr.NS_ERROR_NOT_IMPLEMENTED);
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/no-useless-parameters.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/no-useless-parameters.rst
new file mode 100644
index 0000000000..485caf6522
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/no-useless-parameters.rst
@@ -0,0 +1,26 @@
+no-useless-parameters
+=====================
+
+Reject common XPCOM methods called with useless optional parameters (eg.
+``Services.io.newURI(url, null, null)``, or non-existent parameters (eg.
+``Services.obs.removeObserver(name, observer, false)``).
+
+This option can be autofixed (``--fix``).
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+.. code-block:: js
+
+ elt.addEventListener('click', handler, false);
+ Services.io.newURI('http://example.com', null, null);
+ Services.obs.notifyObservers(obj, 'topic', null);
+
+Examples of correct code for this rule:
+---------------------------------------
+
+.. code-block:: js
+
+ elt.addEventListener('click', handler);
+ Services.io.newURI('http://example.com');
+ Services.obs.notifyObservers(obj, 'topic');
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/no-useless-removeEventListener.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/no-useless-removeEventListener.rst
new file mode 100644
index 0000000000..ce314ab58d
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/no-useless-removeEventListener.rst
@@ -0,0 +1,20 @@
+no-useless-removeEventListener
+==============================
+
+Reject calls to removeEventListener where ``{once: true}`` could be used instead.
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+.. code-block:: js
+
+ elt.addEventListener('click', function listener() {
+ elt.removeEventListener('click', listener);
+ });
+
+Examples of correct code for this rule:
+---------------------------------------
+
+.. code-block:: js
+
+ elt.addEventListener('click', handler, {once: true});
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/no-useless-run-test.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/no-useless-run-test.rst
new file mode 100644
index 0000000000..a079405696
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/no-useless-run-test.rst
@@ -0,0 +1,6 @@
+no-useless-run-test
+===================
+
+Designed for xpcshell-tests. Rejects definitions of ``run_test()`` where the
+function only contains a single call to ``run_next_test()``. xpcshell's head.js
+already defines a utility function so there is no need for duplication.
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/prefer-boolean-length-check.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/prefer-boolean-length-check.rst
new file mode 100644
index 0000000000..cd6ee4e544
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/prefer-boolean-length-check.rst
@@ -0,0 +1,24 @@
+prefer-boolean-length-check
+===========================
+
+Prefers using a boolean length check rather than comparing against zero.
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+.. code-block:: js
+
+ if (foo.length == 0) {}
+ if (foo.length > 0) {}
+ if (foo && foo.length == 0) {}
+ function bar() { return foo.length > 0 }
+
+Examples of correct code for this rule:
+---------------------------------------
+
+.. code-block:: js
+
+ if (foo.length && foo.length) {}
+ if (!foo.length) {}
+ var a = foo.length > 0
+ function bar() { return !!foo.length }
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/prefer-formatValues.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/prefer-formatValues.rst
new file mode 100644
index 0000000000..88eedee792
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/prefer-formatValues.rst
@@ -0,0 +1,23 @@
+prefer-formatValues
+===================
+
+Rejects multiple calls to document.l10n.formatValue in the same code block, to
+reduce localization overheads.
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+.. code-block:: js
+
+ {
+ document.l10n.formatValue('foobar');
+ document.l10n.formatValue('foobaz');
+ }
+
+Examples of correct code for this rule:
+---------------------------------------
+
+.. code-block:: js
+
+ document.l10n.formatValue('foobar');
+ document.l10n.formatValues(['foobar', 'foobaz']);
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-addtask-only.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-addtask-only.rst
new file mode 100644
index 0000000000..e540b24416
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-addtask-only.rst
@@ -0,0 +1,6 @@
+reject-addtask-only
+===================
+
+Designed for JavaScript tests using the add_task pattern. Rejects chaining
+.only() to an add_task() call, which is useful for local testing to run a
+single task in isolation but is easy to land into the tree by accident.
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-chromeutils-import-params.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-chromeutils-import-params.rst
new file mode 100644
index 0000000000..4710878f8d
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-chromeutils-import-params.rst
@@ -0,0 +1,22 @@
+reject-chromeutils-import-params
+================================
+
+``ChromeUtils.import`` used to be able to be called with two arguments, however
+the second argument is no longer supported. Exports from modules should now be
+explicit, and the imported symbols being accessed from the returned object.
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+.. code-block:: js
+
+ ChromeUtils.import("resource://gre/modules/AppConstants.jsm", this);
+ ChromeUtils.import("resource://gre/modules/AppConstants.jsm", null);
+ ChromeUtils.import("resource://gre/modules/AppConstants.jsm", {});
+
+Examples of correct code for this rule:
+---------------------------------------
+
+.. code-block:: js
+
+ const { AppConstants } = ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-eager-module-in-lazy-getter.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-eager-module-in-lazy-getter.rst
new file mode 100644
index 0000000000..fd81793690
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-eager-module-in-lazy-getter.rst
@@ -0,0 +1,35 @@
+reject-eager-module-in-lazy-getter
+==================================
+
+Rejects defining a lazy getter for module that's known to be loaded early in the
+startup process and it is not necessary to lazy load it.
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+.. code-block:: js
+
+ ChromeUtils.defineESModuleGetters(lazy, {
+ AppConstants: "resource://gre/modules/AppConstants.sys.mjs",
+ });
+ XPCOMUtils.defineLazyModuleGetters(lazy, {
+ XPCOMUtils: "resource://gre/modules/XPCOMUtils.jsm",
+ });
+ XPCOMUtils.defineLazyModuleGetter(
+ lazy,
+ "AppConstants",
+ "resource://gre/modules/AppConstants.jsm",
+ });
+
+Examples of correct code for this rule:
+---------------------------------------
+
+.. code-block:: js
+
+ import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs";
+ const { XPCOMUtils } = ChromeUtils.import(
+ "resource://gre/modules/XPCOMUtils.jsm"
+ );
+ const { AppConstants } = ChromeUtils.import(
+ "resource://gre/modules/AppConstants.jsm"
+ );
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-global-this.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-global-this.rst
new file mode 100644
index 0000000000..b3d94321f5
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-global-this.rst
@@ -0,0 +1,29 @@
+reject-global-this
+======================
+
+Rejects global ``this`` usage in JSM files. The global ``this`` is not
+available in ESM, and this is a preparation for the migration.
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+.. code-block:: js
+
+ this.EXPORTED_SYMBOLS = ["foo"];
+
+ XPCOMUtils.defineLazyModuleGetters(this, {
+ AddonManager: "resource://gre/modules/AddonManager.jsm",
+ });
+
+
+Examples of correct code for this rule:
+---------------------------------------
+
+.. code-block:: js
+
+ const EXPORTED_SYMBOLS = ["foo"];
+
+ const lazy = {};
+ XPCOMUtils.defineLazyModuleGetters(lazy, {
+ AddonManager: "resource://gre/modules/AddonManager.jsm",
+ });
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-globalThis-modification.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-globalThis-modification.rst
new file mode 100644
index 0000000000..dd4fc4b2af
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-globalThis-modification.rst
@@ -0,0 +1,19 @@
+reject-globalThis-modification
+==============================
+
+Reject any modification to ``globalThis`` inside the system modules.
+
+``globalThis`` is the shared global inside the system modules, and modification
+on it is visible from all modules, and it shouldn't be done unless it's really
+necessary.
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+.. code-block:: js
+
+ globalThis.foo = 10;
+ Object.defineProperty(globalThis, "bar", { value: 20});
+ ChromeUtils.defineESModuleGetters(globalThis, {
+ AppConstants: "resource://gre/modules/AppConstants.sys.mjs",
+ });
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-import-system-module-from-non-system.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-import-system-module-from-non-system.rst
new file mode 100644
index 0000000000..d168676745
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-import-system-module-from-non-system.rst
@@ -0,0 +1,36 @@
+reject-import-system-module-from-non-system
+===========================================
+
+Rejects static import declaration for system modules (``.sys.mjs``) from non-system
+modules.
+
+Using static import for a system module into a non-system module would create a separate instance of the imported object(s) that is not shared with the other system modules and would break the per-process singleton expectation.
+
+The reason for this is that inside system modules, a static import will load the module into the shared global. Inside non-system modules, the static import will load into a different global (e.g. window). This will cause the module to be loaded into different scopes, and hence create separate instances. The fix is to use ``ChromeUtils.importESModule`` which will import the object via the system module shared global scope.
+
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+Inside a non-system module:
+
+.. code-block:: js
+
+ import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs";
+
+Examples of correct code for this rule:
+---------------------------------------
+
+Inside a non-system module:
+
+.. code-block:: js
+
+ const { AppConstants } = ChromeUtils.importESModule(
+ "resource://gre/modules/AppConstants.sys.mjs"
+ );
+
+Inside a system module:
+
+.. code-block:: js
+
+ import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs";
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-importGlobalProperties.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-importGlobalProperties.rst
new file mode 100644
index 0000000000..68b2e46928
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-importGlobalProperties.rst
@@ -0,0 +1,45 @@
+reject-importGlobalProperties
+=============================
+
+Rejects calls to ``Cu.importGlobalProperties`` or
+``XPCOMUtils.defineLazyGlobalGetters``.
+
+In system modules all the required properties should already be available. In
+non-module code or non-system modules, webidl defined interfaces should already
+be available and hence do not need importing.
+
+Options
+-------
+
+* "everything": Disallows using the import/getters completely.
+* "allownonwebidl": Disallows using the import functions for webidl symbols. Allows
+ other symbols.
+
+everything
+----------
+
+Incorrect code for this option:
+
+.. code-block:: js
+
+ Cu.importGlobalProperties(['TextEncoder']);
+ XPCOMUtils.defineLazyGlobalGetters(this, ['TextEncoder']);
+
+allownonwebidl
+--------------
+
+Incorrect code for this option:
+
+.. code-block:: js
+
+ // AnimationEffect is a webidl property.
+ Cu.importGlobalProperties(['AnimationEffect']);
+ XPCOMUtils.defineLazyGlobalGetters(this, ['AnimationEffect']);
+
+Correct code for this option:
+
+.. code-block:: js
+
+ // TextEncoder is not defined by webidl.
+ Cu.importGlobalProperties(['TextEncoder']);
+ XPCOMUtils.defineLazyGlobalGetters(this, ['TextEncoder']);
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-lazy-imports-into-globals.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-lazy-imports-into-globals.rst
new file mode 100644
index 0000000000..64230ab6f1
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-lazy-imports-into-globals.rst
@@ -0,0 +1,36 @@
+reject-lazy-imports-into-globals
+================================
+
+Rejects importing lazy items into ``window`` or ``globalThis`` when in a
+non-system module scope.
+
+Importing into the ``window`` scope (or ``globalThis``) will share the imported
+global with everything else in the same window. In modules, this is generally
+unnecessary and undesirable because each module imports what it requires.
+Additionally, sharing items via the global scope makes it more difficult for
+linters to determine the available globals.
+
+Instead, the globals should either be imported directly, or into a lazy object.
+If there is a good reason for sharing the globals via the ``window`` scope, then
+this rule may be disabled as long as a comment is added explaining the reasons.
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+.. code-block:: js
+
+ XPCOMUtils.defineLazyModuleGetter(globalThis, "foo", "foo.jsm");
+ XPCOMUtils.defineLazyModuleGetter(window, "foo", "foo.jsm");
+ XPCOMUtils.defineLazyGetter(globalThis, "foo", () => {});
+ XPCOMUtils.defineLazyGetter(window, "foo", () => {});
+ ChromeUtils.defineLazyGetter(globalThis, "foo", () => {});
+ ChromeUtils.defineLazyGetter(window, "foo", () => {});
+
+Examples of correct code for this rule:
+---------------------------------------
+
+.. code-block:: js
+
+ const lazy = {};
+ XPCOMUtils.defineLazyGetter(lazy, "foo", () => {});
+ ChromeUtils.defineLazyGetter(lazy, "bar", () => {});
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-mixing-eager-and-lazy.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-mixing-eager-and-lazy.rst
new file mode 100644
index 0000000000..1bf5100901
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-mixing-eager-and-lazy.rst
@@ -0,0 +1,22 @@
+reject-mixing-eager-and-lazy
+==================================
+
+Rejects defining a lazy getter for a module that's eagerly imported at
+top-level script unconditionally.
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+.. code-block:: js
+
+ const { SomeProp } = ChromeUtils.import("resource://gre/modules/Foo.jsm");
+ XPCOMUtils.defineLazyModuleGetter(lazy, {
+ OtherProp: "resource://gre/modules/Foo.jsm",
+ });
+
+Examples of correct code for this rule:
+---------------------------------------
+
+.. code-block:: js
+
+ const { SomeProp, OtherProp } = ChromeUtils.import("resource://gre/modules/Foo.jsm");
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-multiple-getters-calls.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-multiple-getters-calls.rst
new file mode 100644
index 0000000000..7ea048402b
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-multiple-getters-calls.rst
@@ -0,0 +1,27 @@
+reject-multiple-getters-calls
+=============================
+
+Rejects multiple calls on ``ChromeUtils.defineESModuleGetters`` for the same
+target in the same context.
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+.. code-block:: js
+
+ ChromeUtils.defineESModuleGetters(lazy, {
+ AppConstants: "resource://gre/modules/AppConstants.sys.mjs",
+ });
+ ChromeUtils.defineESModuleGetters(lazy, {
+ PlacesUtils: "resource://gre/modules/PlacesUtils.sys.mjs",
+ });
+
+Examples of correct code for this rule:
+---------------------------------------
+
+.. code-block:: js
+
+ ChromeUtils.defineESModuleGetters(lazy, {
+ AppConstants: "resource://gre/modules/AppConstants.sys.mjs",
+ PlacesUtils: "resource://gre/modules/PlacesUtils.sys.mjs",
+ });
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-relative-requires.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-relative-requires.rst
new file mode 100644
index 0000000000..4387041b26
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-relative-requires.rst
@@ -0,0 +1,22 @@
+reject-relative-requires
+========================
+
+Rejects calls to require which use relative directories.
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+.. code-block:: js
+
+ require("./relative/path")
+ require("../parent/folder/path")
+ loader.lazyRequireGetter(this, "path", "../parent/folder/path", true)
+
+Examples of correct code for this rule:
+---------------------------------------
+
+.. code-block:: js
+
+ require("devtools/absolute/path")
+ require("resource://gre/modules/SomeModule.jsm")
+ loader.lazyRequireGetter(this, "path", "devtools/absolute/path", true)
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-requires-await.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-requires-await.rst
new file mode 100644
index 0000000000..2a8618939f
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-requires-await.rst
@@ -0,0 +1,20 @@
+reject-requires-await
+=====================
+
+`Assert.rejects` must be preceded by an `await`, otherwise the assertion
+may not be completed before the test finishes, might not be caught
+and might cause intermittent issues in other tests.
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+.. code-block:: js
+
+ Assert.rejects(myfunc(), /startup failed/, "Should reject");
+
+Examples of correct code for this rule:
+---------------------------------------
+
+.. code-block:: js
+
+ await Assert.rejects(myfunc(), /startup failed/, "Should reject");
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-scriptableunicodeconverter.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-scriptableunicodeconverter.rst
new file mode 100644
index 0000000000..8f6ae39060
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-scriptableunicodeconverter.rst
@@ -0,0 +1,13 @@
+reject-scriptableunicodeconverter
+================================================
+
+Rejects calls into ``Ci.nsIScriptableUnicodeConverter``. This is configured as a warning.
+You should use |TextEncoder|_ or |TextDecoder|_ for new code.
+If modifying old code, please consider swapping it in if possible; if this is tricky please ensure
+a bug is on file.
+
+.. |TextEncoder| replace:: ``TextEncoder``
+.. _TextEncoder: https://searchfox.org/mozilla-central/source/dom/webidl/TextEncoder.webidl
+
+.. |TextDecoder| replace:: ``TextDecoder``
+.. _TextDecoder: https://searchfox.org/mozilla-central/source/dom/webidl/TextDecoder.webidl
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-some-requires.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-some-requires.rst
new file mode 100644
index 0000000000..476dcbcb94
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-some-requires.rst
@@ -0,0 +1,6 @@
+reject-some-requires
+====================
+
+This takes an option, a regular expression. Invocations of
+``require`` with a string literal argument are matched against this
+regexp; and if it matches, the ``require`` use is flagged.
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-top-level-await.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-top-level-await.rst
new file mode 100644
index 0000000000..38be0b2d22
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-top-level-await.rst
@@ -0,0 +1,26 @@
+reject-top-level-await
+======================
+
+Rejects ``await`` at the top-level of code in modules. Top-level ``await`` is
+not currently support in Gecko's component modules, so this is rejected.
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+.. code-block:: js
+
+ await foo;
+
+ if (expr) {
+ await foo;
+ }
+
+ for await (let x of [1, 2, 3]) { }
+
+Examples of correct code for this rule:
+---------------------------------------
+
+.. code-block:: js
+
+ async function() { await foo; }
+ async function() { for await (let x of [1, 2, 3]) { } }
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/use-cc-etc.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/use-cc-etc.rst
new file mode 100644
index 0000000000..902b4a630c
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/use-cc-etc.rst
@@ -0,0 +1,26 @@
+use-cc-etc
+======================
+
+This requires using ``Cc`` rather than ``Components.classes``, and the same for
+``Components.interfaces``, ``Components.results`` and ``Components.utils``.
+This has a slight performance advantage by avoiding the use of the dot.
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+.. code-block:: js
+
+ let foo = Components.classes['bar'];
+ let bar = Components.interfaces.bar;
+ Components.results.NS_ERROR_ILLEGAL_INPUT;
+ Components.utils.reportError('fake');
+
+Examples of correct code for this rule:
+---------------------------------------
+
+.. code-block:: js
+
+ let foo = Cc['bar'];
+ let bar = Ci.bar;
+ Cr.NS_ERROR_ILLEGAL_INPUT;
+ Cu.reportError('fake');
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/use-chromeutils-generateqi.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/use-chromeutils-generateqi.rst
new file mode 100644
index 0000000000..3da22e139a
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/use-chromeutils-generateqi.rst
@@ -0,0 +1,33 @@
+use-chromeutils-generateqi
+==========================
+
+Reject use of ``XPCOMUtils.generateQI`` and JS-implemented QueryInterface
+methods in favor of ``ChromeUtils``.
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+.. code-block:: js
+
+ X.prototype.QueryInterface = XPCOMUtils.generateQI(["nsIMeh"]);
+ X.prototype = { QueryInterface: XPCOMUtils.generateQI(["nsIMeh"]) };
+ X.prototype = { QueryInterface: function QueryInterface(iid) {
+ if (
+ iid.equals(Ci.nsISupports) ||
+ iid.equals(Ci.nsIMeh) ||
+ iid.equals(nsIFlug) ||
+ iid.equals(Ci.amIFoo)
+ ) {
+ return this;
+ }
+ throw Components.Exception("", Cr.NS_ERROR_NO_INTERFACE);
+ } };
+
+
+Examples of correct code for this rule:
+---------------------------------------
+
+.. code-block:: js
+
+ X.prototype.QueryInterface = ChromeUtils.generateQI(["nsIMeh"]);
+ X.prototype = { QueryInterface: ChromeUtils.generateQI(["nsIMeh"]) }
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/use-chromeutils-import.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/use-chromeutils-import.rst
new file mode 100644
index 0000000000..c38304193a
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/use-chromeutils-import.rst
@@ -0,0 +1,24 @@
+use-chromeutils-import
+======================
+
+Require use of ``ChromeUtils.import`` and ``ChromeUtils.defineModuleGetter``
+rather than ``Components.utils.import`` and
+``XPCOMUtils.defineLazyModuleGetter``.
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+.. code-block:: js
+
+ Components.utils.import("resource://gre/modules/AppConstants.jsm", this);
+ XPCOMUtils.defineLazyModuleGetter(this, "AppConstants", "resource://gre/modules/AppConstants.jsm");
+
+Examples of correct code for this rule:
+---------------------------------------
+
+.. code-block:: js
+
+ ChromeUtils.import("resource://gre/modules/AppConstants.jsm", this);
+ ChromeUtils.defineModuleGetter(this, "AppConstants", "resource://gre/modules/AppConstants.jsm");
+ // 4 argument version of defineLazyModuleGetter is allowed.
+ XPCOMUtils.defineLazyModuleGetter(this, "AppConstants","resource://gre/modules/AppConstants.jsm","Foo");
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/use-default-preference-values.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/use-default-preference-values.rst
new file mode 100644
index 0000000000..2392709e89
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/use-default-preference-values.rst
@@ -0,0 +1,19 @@
+use-default-preference-values
+=============================
+
+Require providing a second parameter to ``get*Pref`` methods instead of
+using a try/catch block.
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+.. code-block:: js
+
+ try { blah = branch.getCharPref('blah'); } catch(e) {}
+
+Examples of correct code for this rule:
+---------------------------------------
+
+.. code-block:: js
+
+ blah = branch.getCharPref('blah', true);
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/use-includes-instead-of-indexOf.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/use-includes-instead-of-indexOf.rst
new file mode 100644
index 0000000000..bb65ebea2c
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/use-includes-instead-of-indexOf.rst
@@ -0,0 +1,21 @@
+use-includes-instead-of-indexOf
+===============================
+
+Use ``.includes`` instead of ``.indexOf`` to check if something is in an array
+or string.
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+.. code-block:: js
+
+ let a = foo.indexOf(bar) >= 0;
+ let a = foo.indexOf(bar) == -1;
+
+Examples of correct code for this rule:
+---------------------------------------
+
+.. code-block:: js
+
+ let a = foo.includes(bar);
+ let a = foo.indexOf(bar) > 0;
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/use-isInstance.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/use-isInstance.rst
new file mode 100644
index 0000000000..dca1e51c82
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/use-isInstance.rst
@@ -0,0 +1,42 @@
+use-isInstance
+==============
+
+Prefer ``.isInstance()`` in chrome scripts over the standard ``instanceof``
+operator for DOM interfaces, since the latter will return false when the object
+is created from a different context.
+
+These files are covered:
+
+- ``*.sys.mjs``
+- ``*.jsm``
+- ``*.jsm.js``
+- ``*.xhtml`` with ``there.is.only.xul``
+- ``*.js`` with a heuristic
+
+Since there is no straightforward way to detect chrome scripts, currently the
+linter assumes that any script including the following words are chrome
+privileged. This of course may not be sufficient and is open for change:
+
+- ``ChromeUtils``, but not ``SpecialPowers.ChromeUtils``
+- ``BrowserTestUtils``, ``PlacesUtils``
+- ``document.createXULElement``
+- ``loader.lazyRequireGetter``
+- ``Services.foo``, but not ``SpecialPowers.Services.foo``
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+.. code-block:: js
+
+ node instanceof Node
+ text instanceof win.Text
+ target instanceof this.contentWindow.HTMLAudioElement
+
+Examples of correct code for this rule:
+---------------------------------------
+
+.. code-block:: js
+
+ Node.isInstance(node)
+ win.Text.isInstance(text)
+ this.contentWindow.HTMLAudioElement.isInstance(target)
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/use-ownerGlobal.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/use-ownerGlobal.rst
new file mode 100644
index 0000000000..5d9905fc9f
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/use-ownerGlobal.rst
@@ -0,0 +1,20 @@
+use-ownerGlobal
+===============
+
+Require ``.ownerGlobal`` instead of ``.ownerDocument.defaultView``.
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+.. code-block:: js
+
+ aEvent.target.ownerDocument.defaultView;
+ this.DOMPointNode.ownerDocument.defaultView.getSelection();
+
+Examples of correct code for this rule:
+---------------------------------------
+
+.. code-block:: js
+
+ aEvent.target.ownerGlobal;
+ this.DOMPointNode.ownerGlobal.getSelection();
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/use-returnValue.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/use-returnValue.rst
new file mode 100644
index 0000000000..1280703747
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/use-returnValue.rst
@@ -0,0 +1,20 @@
+use-returnValue
+===============
+
+Warn when idempotent methods are called and their return value is unused.
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+.. code-block:: js
+
+ foo.concat(bar)
+ baz.concat()
+
+Examples of correct code for this rule:
+---------------------------------------
+
+.. code-block:: js
+
+ a = foo.concat(bar)
+ b = baz.concat()
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/use-services.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/use-services.rst
new file mode 100644
index 0000000000..1a57e3da10
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/use-services.rst
@@ -0,0 +1,21 @@
+use-services
+============
+
+Requires the use of ``Services`` rather than ``Cc[].getService()`` where a
+service is already defined in ``Services``.
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+.. code-block:: js
+
+ Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
+ Components.classes["@mozilla.org/toolkit/app-startup;1"].getService(Components.interfaces.nsIAppStartup);
+
+Examples of correct code for this rule:
+---------------------------------------
+
+.. code-block:: js
+
+ Services.wm.addListener()
+ Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator)
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/use-static-import.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/use-static-import.rst
new file mode 100644
index 0000000000..9090dd80b7
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/use-static-import.rst
@@ -0,0 +1,21 @@
+use-static-import
+=================
+
+Requires the use of static imports in system ES module files (``.sys.mjs``)
+where possible.
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+.. code-block:: js
+
+ const { XPCOMUtils } = ChromeUtils.importESModule("resource://gre/modules/XPCOMUtils.sys.mjs");
+ const { XPCOMUtils: foo } = ChromeUtils.importESModule("resource://gre/modules/XPCOMUtils.sys.mjs");
+
+Examples of correct code for this rule:
+---------------------------------------
+
+.. code-block:: js
+
+ import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
+ import { XPCOMUtils as foo } from "resource://gre/modules/XPCOMUtils.sys.mjs";
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/valid-ci-uses.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/valid-ci-uses.rst
new file mode 100644
index 0000000000..440d730e05
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/valid-ci-uses.rst
@@ -0,0 +1,42 @@
+valid-ci-uses
+=============
+
+Ensures that interface accesses on ``Ci`` are valid, and property accesses on
+``Ci.<interface>`` are also valid.
+
+This rule requires a full build to run, and is not turned on by default. To run
+this rule manually, use:
+
+.. code-block:: console
+
+ MOZ_OBJDIR=objdir-ff-opt ./mach eslint --rule="mozilla/valid-ci-uses: error" *
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+``nsIFoo`` does not exist.
+
+.. code-block:: js
+
+ Ci.nsIFoo
+
+``UNKNOWN_CONSTANT`` does not exist on nsIURIFixup.
+
+.. code-block:: js
+
+ Ci.nsIURIFixup.UNKNOWN_CONSTANT
+
+Examples of correct code for this rule:
+---------------------------------------
+
+``nsIFile`` does exist.
+
+.. code-block:: js
+
+ Ci.nsIFile
+
+``FIXUP_FLAG_NONE`` does exist on nsIURIFixup.
+
+.. code-block:: js
+
+ Ci.nsIURIFixup.FIXUP_FLAG_NONE
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/valid-lazy.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/valid-lazy.rst
new file mode 100644
index 0000000000..fcbe5d064e
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/valid-lazy.rst
@@ -0,0 +1,55 @@
+valid-lazy
+==========
+
+Ensures that definitions and uses of properties on the ``lazy`` object are valid.
+This rule checks for using unknown properties, duplicated symbols, unused
+symbols, and also lazy getter used at top-level unconditionally.
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+.. code-block:: js
+
+ const lazy = {};
+ if (x) {
+ // Unknown lazy member property {{name}}
+ lazy.bar.foo();
+ }
+
+.. code-block:: js
+
+ const lazy = {};
+ XPCOMUtils.defineLazyGetter(lazy, "foo", "foo.jsm");
+
+ // Duplicate symbol foo being added to lazy.
+ XPCOMUtils.defineLazyGetter(lazy, "foo", "foo1.jsm");
+ if (x) {
+ lazy.foo3.bar();
+ }
+
+.. code-block:: js
+
+ const lazy = {};
+ // Unused lazy property foo
+ XPCOMUtils.defineLazyGetter(lazy, "foo", "foo.jsm");
+
+.. code-block:: js
+
+ const lazy = {};
+ XPCOMUtils.defineLazyGetter(lazy, "foo", "foo.jsm");
+ // Used at top-level unconditionally.
+ lazy.foo.bar();
+
+Examples of correct code for this rule:
+---------------------------------------
+
+.. code-block:: js
+
+ const lazy = {};
+ XPCOMUtils.defineLazyGetter(lazy, "foo1", () => {});
+ XPCOMUtils.defineLazyModuleGetters(lazy, { foo2: "foo2.jsm" });
+
+ if (x) {
+ lazy.foo1.bar();
+ lazy.foo2.bar();
+ }
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/valid-services-property.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/valid-services-property.rst
new file mode 100644
index 0000000000..c6c61abac2
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/valid-services-property.rst
@@ -0,0 +1,30 @@
+valid-services-property
+=======================
+
+Ensures that accesses of properties of items accessed via the ``Services``
+object are valid.
+
+This rule requires a full build to run, and is not turned on by default. To run
+this rule manually, use:
+
+.. code-block:: console
+
+ MOZ_OBJDIR=objdir-ff-opt ./mach eslint --rule="mozilla/valid-services-property: error" *
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+Assuming ``foo`` is not defined within ``Ci.nsISearchService``.
+
+.. code-block:: js
+
+ Services.search.foo();
+
+Examples of correct code for this rule:
+---------------------------------------
+
+Assuming ``bar`` is defined within ``Ci.nsISearchService``.
+
+.. code-block:: js
+
+ Services.search.bar();
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/valid-services.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/valid-services.rst
new file mode 100644
index 0000000000..bd76cb52ac
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/valid-services.rst
@@ -0,0 +1,24 @@
+valid-services
+==============
+
+Ensures that accesses of the ``Services`` object are valid.
+``Services`` are defined in ``tools/lint/eslint/eslint-plugin-mozilla/lib/services.json`` and can be added by copying from
+``<objdir>/xpcom/components/services.json`` after a build.
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+Assuming ``foo`` is not defined within Services.
+
+.. code-block:: js
+
+ Services.foo.fn();
+
+Examples of correct code for this rule:
+---------------------------------------
+
+Assuming ``bar`` is defined within Services.
+
+.. code-block:: js
+
+ Services.bar.fn();
diff --git a/docs/code-quality/lint/linters/eslint-plugin-mozilla/var-only-at-top-level.rst b/docs/code-quality/lint/linters/eslint-plugin-mozilla/var-only-at-top-level.rst
new file mode 100644
index 0000000000..d21fc1b299
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla/var-only-at-top-level.rst
@@ -0,0 +1,21 @@
+var-only-at-top-level
+=====================
+
+Marks all var declarations that are not at the top level invalid.
+
+Examples of incorrect code for this rule:
+-----------------------------------------
+
+.. code-block:: js
+
+ { var foo; }
+ function() { var bar; }
+
+Examples of correct code for this rule:
+---------------------------------------
+
+.. code-block:: js
+
+ var foo;
+ { let foo; }
+ function () { let bar; }
diff --git a/docs/code-quality/lint/linters/eslint-plugin-spidermonkey-js.rst b/docs/code-quality/lint/linters/eslint-plugin-spidermonkey-js.rst
new file mode 100644
index 0000000000..e20c8562b6
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint-plugin-spidermonkey-js.rst
@@ -0,0 +1,18 @@
+==============================
+Mozilla ESLint SpiderMonkey JS
+==============================
+
+This plugin adds a processor and an environment for the SpiderMonkey JS code.
+
+Processors
+==========
+
+The processor is used to pre-process all `*.js` files and deals with the macros
+that SpiderMonkey uses.
+
+Environments
+============
+
+The plugin provides a custom environment for SpiderMonkey's self-hosted code. It
+adds all self-hosting functions, error message numbers, and other self-hosting
+definitions as global, read-only identifiers.
diff --git a/docs/code-quality/lint/linters/eslint.rst b/docs/code-quality/lint/linters/eslint.rst
new file mode 100644
index 0000000000..3f3e33467b
--- /dev/null
+++ b/docs/code-quality/lint/linters/eslint.rst
@@ -0,0 +1,211 @@
+ESLint
+======
+
+`ESLint`__ is a popular linter for JavaScript. The ESLint integration also uses
+`Prettier`_ to enforce code formatting.
+
+Run Locally
+-----------
+
+The mozlint integration of ESLint can be run using mach:
+
+.. parsed-literal::
+
+ $ mach lint --linter eslint <file paths>
+
+Alternatively, omit the ``--linter eslint`` and run all configured linters, which will include
+ESLint.
+
+ESLint also supports the ``--fix`` option to autofix most errors raised from most of the rules.
+
+See the `Usage guide`_ for more options.
+
+Understanding Rules and Errors
+------------------------------
+
+* Only some files are linted, see the :searchfox:`configuration <tools/lint/eslint.yml>` for details.
+
+ * By design we do not lint/format reftests not crashtests as these are specially crafted tests.
+
+* If you don't understand a rule, you can look it in `eslint.org's rule list`_ for more
+ information about it.
+* For Mozilla specific rules (with the mozilla/ prefix), see these for more details:
+
+ * `eslint-plugin-mozilla`_
+ * `eslint-plugin-spidermonkey-js`_
+
+Common Issues and How To Solve Them
+-----------------------------------
+
+My editor says that ``mozilla/whatever`` is unknown
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Run ``./mach eslint --setup``, and restart your editor.
+
+My editor doesn't understand a new global I've just added (e.g. to a content file or head.js file)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* This is a limitation which is a mixture of our ESLint setup and how we share globals across files.
+* Restarting your editor should pick up the new globals.
+* You can always double check via ``./mach lint --linter eslint <file path>`` on the command line.
+
+I am getting a linter error "Unknown Services member property"
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Make sure to add any new Services to ``tools/lint/eslint/eslint-plugin-mozilla/lib/services.json``. For example by copying from
+``<objdir>/xpcom/components/services.json`` after a build.
+
+.. _adding-tests:
+
+I'm adding tests, how do I set up the right configuration?
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Please note we prefer the tests to be in named directories as this makes it
+easier to identify the types of tests developers are working with. Additionally,
+it is not possible to scope ESLint rules to individual files based on .ini
+files without a build step that would break editors, or an expensive loading
+cycle.
+
+* If the directory path of the tests is one of the `known ones`_, then ESLint will
+ do the right thing for that test type. This is the preferred option.
+
+ * For example placing xpcshell-tests in ``browser/components/foo/test/unit/``
+ will set up ESLint correctly.
+
+* If you really can't match the directory name, e.g. like the
+ ``browser/base/content/tests/*``, then you'll need to add a new entry in
+ :searchfox:`.eslintrc-test-paths.js <.eslintrc-test-paths.js>`.
+
+Please do not add new cases of multiple types of tests within a single directory,
+this is `difficult for ESLint to handle`_. Currently this may cause:
+
+* Rules to be incorrectly applied to the wrong types of test file.
+* Extra definitions for globals in tests which means that the no undefined variables
+ rule does not get triggered in some cases.
+
+I'm using an ES module
+^^^^^^^^^^^^^^^^^^^^^^
+
+* Use a ``.mjs`` extension for the file. ESLint will pick this up and automatically
+ treat it as a module.
+* If it is a system module (e.g. component definition or other non-frontend code),
+ use a ``.sys.mjs`` extension.
+
+This code should neither be linted nor formatted
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* If it is a third-party piece of code, please add it to :searchfox:`ThirdPartyPaths.txt <tools/rewriting/ThirdPartyPaths.txt>`.
+* If it is a generated file, please add it to :searchfox:`Generated.txt <tools/rewriting/Generated.txt>`.
+* If intentionally invalid, please add it to :searchfox:`.eslintignore <.eslintignore>`.
+
+This code shouldn't be formatted
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The vast majority of code should be formatted, however we allow some limited
+cases where it makes sense, for example:
+
+* A table in an array where laying it out in a table fashion makes it more readable.
+* Other structures or function calls where layout is more readable in a particular format.
+
+To disable prettier for code like this, ``// prettier-ignore`` may be used on
+the line previous to where you want it disabled.
+See the `prettier ignore docs`_ for more information.
+
+I have valid code that is failing the ``no-undef`` rule or can't be parsed
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Please do not add this to :searchfox:`.eslintignore <.eslintignore>`. Generally
+ this can be fixed, if the following tips don't help, please `seek help`_.
+* If you are adding a new test directory, see the :ref:`section above <adding-tests>`
+
+* If you are writing a script loaded into special environment (e.g. frame script) you may need to tell ESLint to use the `environment definitions`_ for each case:
+
+ * ``/* eslint-env mozilla/frame-script */``
+
+* If you are writing a worker, then you may need to use the worker or chrome-worker environment:
+
+ * ``/* eslint-env worker */``
+ * ``/* eslint-env mozilla/chrome-worker */``
+
+* I use ``Services.scriptloader.loadSubScript``:
+
+ * ``/* import-globals-from relative/path/to/file.js``
+
+Configuration
+-------------
+
+The global configuration file lives in ``topsrcdir/.eslintrc``. This global configuration can be
+overridden by including an ``.eslintrc`` in the appropriate subdirectory. For an overview of the
+supported configuration, see `ESLint's documentation`_.
+
+Please keep differences in rules across the tree to a minimum. We want to be consistent to
+make it easier for developers.
+
+Sources
+-------
+
+* :searchfox:`Configuration (YAML) <tools/lint/eslint.yml>`
+* :searchfox:`Source <tools/lint/eslint/__init__.py>`
+
+Builders
+--------
+
+`Mark Banner (standard8) <https://people.mozilla.org/s?query=standard8>`__ owns
+the builders. Questions can also be asked on #lint:mozilla.org on Matrix.
+
+ESLint (ES)
+^^^^^^^^^^^
+
+This is a tier-1 task. For test failures the patch causing the
+issue should be backed out or the issue fixed.
+
+Some failures can be fixed with ``./mach eslint --fix path/to/file``.
+
+For test harness issues, file bugs in Developer Infrastructure :: Lint and Formatting.
+
+ESLint-build (ES-B)
+^^^^^^^^^^^^^^^^^^^
+
+This is a tier-2 task that is run once a day at midnight UTC via a cron job.
+
+It currently runs the ESLint rules plus two additional rules:
+
+* `valid-ci-uses <eslint-plugin-mozilla/valid-ci-uses.html>`__
+* `valid-services-property <eslint-plugin-mozilla/valid-services-property.html>`__
+
+These are two rules that both require build artifacts.
+
+To run them manually, you can run:
+
+``MOZ_OBJDIR=objdir-ff-opt ./mach eslint --rule "mozilla/valid-ci-uses: error" --rule "mozilla/valid-services-property: error" *``
+
+For test failures, the regression causing bug may be able to be found by:
+
+ * Determining if the file where the error is reported has been changed recently.
+ * Seeing if an associated ``.idl`` file has been changed.
+
+If no regressing bug can easily be found, file a bug in the relevant
+product/component for the file where the failure is and cc :standard8.
+
+For test harness issues, file bugs in Developer Infrastructure :: Lint and Formatting.
+
+.. toctree::
+ :hidden:
+
+ eslint-plugin-mozilla
+ eslint-plugin-spidermonkey-js
+
+.. __: https://eslint.org/
+.. _Prettier: https://prettier.io/
+.. _Usage guide: ../usage.html
+.. _ESLint's documentation: https://eslint.org/docs/user-guide/configuring
+.. _eslint.org's rule list: https://eslint.org/docs/rules/
+.. _eslint-plugin-mozilla: eslint-plugin-mozilla.html
+.. _eslint-plugin-spidermonkey-js: eslint-plugin-spidermonkey-js.html
+.. _informed that it is a module: https://searchfox.org/mozilla-central/rev/9399e5832979755cd340383f4ca4069dd5fc7774/browser/base/content/.eslintrc.js
+.. _seek help: ../index.html#getting-help
+.. _patterns in .eslintrc.js: https://searchfox.org/mozilla-central/rev/9399e5832979755cd340383f4ca4069dd5fc7774/.eslintrc.js#24-38
+.. _environment definitions: ./eslint-plugin-mozilla/environment.html
+.. _known ones: https://searchfox.org/mozilla-central/rev/287583a4a605eee8cd2d41381ffaea7a93d7b987/.eslintrc.js#24-40
+.. _difficult for ESLint to handle: https://bugzilla.mozilla.org/show_bug.cgi?id=1379669
+.. _prettier ignore docs: https://prettier.io/docs/en/ignore.html
diff --git a/docs/code-quality/lint/linters/file-perm.rst b/docs/code-quality/lint/linters/file-perm.rst
new file mode 100644
index 0000000000..5c3a02fa1b
--- /dev/null
+++ b/docs/code-quality/lint/linters/file-perm.rst
@@ -0,0 +1,42 @@
+File permission
+===============
+
+This linter verifies if a file has unnecessary permissions.
+If a file has execution permissions (+x), file-perm will
+generate a warning.
+
+It will ignore files starting with ``#!`` for types of files
+that typically have shebang lines (such as python, node or
+shell scripts).
+
+This linter does not have any affect on Windows.
+
+
+Run Locally
+-----------
+
+This mozlint linter can be run using mach:
+
+.. parsed-literal::
+
+ $ mach lint --linter file-perm <file paths>
+
+
+Configuration
+-------------
+
+This linter is enabled on the whole code base.
+
+This job is configured as `tier 2 <https://wiki.mozilla.org/Sheriffing/Job_Visibility_Policy#Overview_of_the_Job_Visibility_Tiers>`_.
+
+Autofix
+-------
+
+This linter provides a ``--fix`` option. The python script is doing the change itself.
+
+
+Sources
+-------
+
+* `Configuration (YAML) <https://searchfox.org/mozilla-central/source/tools/lint/file-perm.yml>`_
+* `Source <https://searchfox.org/mozilla-central/source/tools/lint/file-perm/__init__.py>`_
diff --git a/docs/code-quality/lint/linters/file-whitespace.rst b/docs/code-quality/lint/linters/file-whitespace.rst
new file mode 100644
index 0000000000..201f10d123
--- /dev/null
+++ b/docs/code-quality/lint/linters/file-whitespace.rst
@@ -0,0 +1,38 @@
+Trailing whitespaces
+====================
+
+This linter verifies if a file has:
+
+* unnecessary trailing whitespaces,
+* Windows carriage return,
+* empty lines at the end of file,
+* if file ends with a newline or not
+
+
+Run Locally
+-----------
+
+This mozlint linter can be run using mach:
+
+.. parsed-literal::
+
+ $ mach lint --linter file-whitespace <file paths>
+
+
+Configuration
+-------------
+
+This linter is enabled on most of the code base.
+
+This job is configured as `tier 2 <https://wiki.mozilla.org/Sheriffing/Job_Visibility_Policy#Overview_of_the_Job_Visibility_Tiers>`_.
+
+Autofix
+-------
+
+This linter provides a ``--fix`` option. The python script is doing the change itself.
+
+Sources
+-------
+
+* :searchfox:`Configuration (YAML) <tools/lint/file-whitespace.yml>`
+* :searchfox:`Source <tools/lint/file-whitespace/__init__.py>`
diff --git a/docs/code-quality/lint/linters/fluent-lint.rst b/docs/code-quality/lint/linters/fluent-lint.rst
new file mode 100644
index 0000000000..809adb4a5e
--- /dev/null
+++ b/docs/code-quality/lint/linters/fluent-lint.rst
@@ -0,0 +1,47 @@
+Fluent Lint
+===========
+
+Fluent lint is a linter for Fluent files (.ftl). Currently, it includes:
+
+* Checks for invalid typography in messages (e.g. straight single or double quotes).
+* Checks for comments layout.
+* Checks for identifiers (minimum length, allowed characters).
+* Hard-coded brand names.
+
+
+Run Locally
+-----------
+
+The mozlint integration of fluent-lint can be run using mach:
+
+.. parsed-literal::
+
+ $ mach lint --linter fluent-lint <file paths>
+
+Alternatively, omit the ``--linter fluent-lint`` and run all configured linters, which will include
+fluent-lint.
+
+
+Run on Taskcluster
+------------------
+
+The fluent-lint job shows up as text(fluent) in the linting job. It should run automatically if
+changes are made to fluent (ftl) files.
+
+
+Configuration
+-------------
+
+The main configuration file is found in :searchfox:`tools/lint/fluent-lint/exclusions.yml`. This provides
+a way of excluding identifiers or files from checking. In general, exclusions are only to be
+used for identifiers that are generated programmatically, but unfortunately, there are other
+exclusions that are required for historical reasons. In almost all cases, it should *not* be
+necessary to add new exclusions to this file.
+
+
+Sources
+-------
+
+* :searchfox:`Configuration (YAML) <tools/lint/fluent-lint.yml>`
+* :searchfox:`Source <tools/lint/fluent-lint/__init__.py>`
+* :searchfox:`Test <tools/lint/test/test_fluent_lint.py>`
diff --git a/docs/code-quality/lint/linters/l10n.rst b/docs/code-quality/lint/linters/l10n.rst
new file mode 100644
index 0000000000..de4ce990c8
--- /dev/null
+++ b/docs/code-quality/lint/linters/l10n.rst
@@ -0,0 +1,45 @@
+L10n
+====
+
+The l10n linter checks for mistakes and problems in the localizable files.
+Most of the code lives inside the
+`compare-locales <https://pypi.org/project/compare-locales/>`_
+package, and is shipping as the ``moz-l10n-lint`` command.
+
+The linter checks for fundamental issues like parsing errors, but it also
+finds more subtle mistakes like duplicated messages. It also warns if you're
+trying to change a string without changing the ID, or to add a string that's
+still in use in a stable channel with a different value.
+
+The warnings on string ID changes get reported on phabricator, but they're
+not making the build fail. To find out when to change IDs and when not to,
+read the :ref:`Lifecycle & Workflow <Localization>` section in the
+localization documentation.
+
+Run Locally
+-----------
+
+The can be run using mach:
+
+.. parsed-literal::
+
+ $ mach lint --linter l10n <file paths>
+
+Alternatively, omit the ``--linter l10n`` and run all configured linters, which
+will include the l10n linter.
+
+
+Updating the Reference
+----------------------
+
+The linter checks out the cross-channel localization files into your
+``.mozbuild`` state directory. By default this is updated automatically after
+48 hours. There might be new strings anyway, if you want to ensure an
+updated clone, remove the marker file in
+``~/.mozbuild/gecko-strings/.hg/l10n_pull_marker``.
+
+Sources
+-------
+
+* :searchfox:`Configuration (YAML) <tools/lint/l10n.yml>`
+* :searchfox:`Source <tools/lint/python/l10n_lint.py>`
diff --git a/docs/code-quality/lint/linters/license.rst b/docs/code-quality/lint/linters/license.rst
new file mode 100644
index 0000000000..0533333218
--- /dev/null
+++ b/docs/code-quality/lint/linters/license.rst
@@ -0,0 +1,39 @@
+License
+=======
+
+This linter verifies if a file has a known license header.
+
+By default, Firefox uses MPL-2 license with the `appropriate headers <https://www.mozilla.org/en-US/MPL/headers/>`_.
+In some cases (thirdpardy code), a file might have a different header file.
+If this is the case, one of the significant line of the header should be listed in the list `of valid licenses
+<https://searchfox.org/mozilla-central/source/tools/lint/license/valid-licenses.txt>`_.
+
+Run Locally
+-----------
+
+This mozlint linter can be run using mach:
+
+.. parsed-literal::
+
+ $ mach lint --linter license <file paths>
+
+
+Configuration
+-------------
+
+This linter is enabled on most of the whole code base.
+
+Autofix
+-------
+
+This linter provides a ``--fix`` option. The python script is doing the change itself
+and will use the right header MPL-2 header depending on the language.
+It will add the license at the right place in case the file is a script (ie starting with ``!#``
+or a XML file ``<?xml>``).
+
+
+Sources
+-------
+
+* `Configuration (YAML) <https://searchfox.org/mozilla-central/source/tools/lint/license.yml>`_
+* `Source <https://searchfox.org/mozilla-central/source/tools/lint/license/__init__.py>`_
diff --git a/docs/code-quality/lint/linters/lintpref.rst b/docs/code-quality/lint/linters/lintpref.rst
new file mode 100644
index 0000000000..ca19089172
--- /dev/null
+++ b/docs/code-quality/lint/linters/lintpref.rst
@@ -0,0 +1,32 @@
+Lintpref
+========
+
+The lintpref linter is a simple linter for libpref files to check for duplicate
+entries between :searchfox:`modules/libpref/init/all.js` and
+:searchfox:`modules/libpref/init/StaticPrefList.yaml`. If a duplicate is found,
+lintpref will raise an error and emit the ``all.js`` line where you can find
+the duplicate entry.
+
+
+Running Locally
+---------------
+
+The linter can be run using mach:
+
+ .. parsed-literal::
+
+ $ mach lint --linter lintpref
+
+
+Fixing Lintpref Errors
+----------------------
+
+In most cases, duplicate entries should be avoided and the duplicate removed
+from ``all.js``. If for any reason a pref should exist in both files, the pref
+should be added to ``IGNORE_PREFS`` in :searchfox:`tools/lint/libpref/__init__.py`.
+
+Sources
+-------
+
+* :searchfox:`Configuration (YAML) <tools/lint/lintpref.yml>`
+* :searchfox:`Source <tools/lint/libpref/__init__.py>`
diff --git a/docs/code-quality/lint/linters/mingw-capitalization.rst b/docs/code-quality/lint/linters/mingw-capitalization.rst
new file mode 100644
index 0000000000..e6c51a4d14
--- /dev/null
+++ b/docs/code-quality/lint/linters/mingw-capitalization.rst
@@ -0,0 +1,28 @@
+MinGW capitalization
+====================
+
+This linter verifies that Windows include file are lowercase.
+It might break the mingw build otherwise.
+
+
+Run Locally
+-----------
+
+This mozlint linter can be run using mach:
+
+.. parsed-literal::
+
+ $ mach lint --linter mingw-capitalization <file paths>
+
+
+Configuration
+-------------
+
+This linter is enabled on the whole code base except WebRTC
+
+
+Sources
+-------
+
+* :searchfox:`Configuration (YAML) <tools/lint/mingw-capitalization.yml>`
+* :searchfox:`Source <tools/lint/cpp/mingw-capitalization.py>`
diff --git a/docs/code-quality/lint/linters/perfdocs.rst b/docs/code-quality/lint/linters/perfdocs.rst
new file mode 100644
index 0000000000..3169ee553f
--- /dev/null
+++ b/docs/code-quality/lint/linters/perfdocs.rst
@@ -0,0 +1,84 @@
+PerfDocs
+========
+
+`PerfDocs`_ is a tool that checks to make sure all performance tests are documented in tree.
+
+At the moment, it is only used for this documentation verification, but in the future it will also auto-generate documentation from these descriptions that will be displayed in the source-docs documentation page (rather than the wiki, which is where they currently reside).
+
+Run Locally
+-----------
+
+The mozlint integration of PerfDocs can be run using mach:
+
+.. parsed-literal::
+
+ $ mach lint --linter perfdocs .
+
+
+Configuration
+-------------
+
+There are no configuration options available for this linter. It scans the full source tree under ``testing``, looking for folders named ``perfdocs`` and then validates their content. This has only been implemented for Raptor so far, but Talos will be added in the future. We also hope to expand this to search outside the ``testing`` directory.
+
+The ``perfdocs`` folders, there needs to be an ``index.rst`` file and it needs to contain the string ``{documentation}`` in some location in the file which is where the test documentation will be placed. The folders must also have a ``config.yml`` file following this schema:
+
+.. code-block:: python
+
+ CONFIG_SCHEMA = {
+ "type": "object",
+ "properties": {
+ "name": {"type": "string"},
+ "manifest": {"type": "string"},
+ "suites": {
+ "type": "object",
+ "properties": {
+ "suite_name": {
+ "type": "object",
+ "properties": {
+ "tests": {
+ "type": "object",
+ "properties": {
+ "test_name": {"type": "string"},
+ }
+ },
+ "description": {"type": "string"},
+ },
+ "required": [
+ "description"
+ ]
+ }
+ }
+ }
+ },
+ "required": [
+ "name",
+ "manifest",
+ "suites"
+ ]
+ }
+
+Here is an example of a configuration file for the Raptor framework:
+
+.. parsed-literal::
+
+ name: raptor
+ manifest: testing/raptor/raptor/raptor.ini
+ suites:
+ desktop:
+ description: "Desktop tests."
+ tests:
+ raptor-tp6: "Raptor TP6 tests."
+ mobile:
+ description: "Mobile tests"
+ benchmarks:
+ description: "Benchmark tests."
+ tests:
+ wasm: "All wasm tests."
+
+Note that there needs to be a FrameworkGatherer implemented for the framework being documented since each of them may have different ways of parsing test manifests for the tests. See `RaptorGatherer <https://searchfox.org/mozilla-central/source/tools/lint/perfdocs/framework_gatherers.py>`_ for an example gatherer that was implemented for Raptor.
+
+Sources
+-------
+
+* `Configuration <https://searchfox.org/mozilla-central/source/tools/lint/perfdocs.yml>`__
+* `Source <https://searchfox.org/mozilla-central/source/tools/lint/perfdocs>`__
diff --git a/docs/code-quality/lint/linters/rejected-words.rst b/docs/code-quality/lint/linters/rejected-words.rst
new file mode 100644
index 0000000000..9afe7df27e
--- /dev/null
+++ b/docs/code-quality/lint/linters/rejected-words.rst
@@ -0,0 +1,28 @@
+Rejected words
+==============
+
+Reject some words we don't want to use in the code base for various reasons.
+
+Run Locally
+-----------
+
+The mozlint integration of codespell can be run using mach:
+
+.. parsed-literal::
+
+ $ mach lint --linter rejected-words <file paths>
+
+
+Configuration
+-------------
+
+This linter is enabled on the whole code base. Issues existing in the code base
+are listed in the exclude list in the :searchfox:`rejected-words.yml
+<tools/lint/rejected-words.yml>` file.
+
+New words can be added in the `payload` section.
+
+Sources
+-------
+
+* :searchfox:`Configuration (YAML) <tools/lint/rejected-words.yml>`
diff --git a/docs/code-quality/lint/linters/rstlinter.rst b/docs/code-quality/lint/linters/rstlinter.rst
new file mode 100644
index 0000000000..46a68d5849
--- /dev/null
+++ b/docs/code-quality/lint/linters/rstlinter.rst
@@ -0,0 +1,32 @@
+RST Linter
+==========
+
+`rstcheck`_ is a popular linter for restructuredtext.
+
+
+Run Locally
+-----------
+
+The mozlint integration of rst linter can be run using mach:
+
+.. parsed-literal::
+
+ $ mach lint --linter rst <file paths>
+
+
+Configuration
+-------------
+
+All directories will have rst linter run against them.
+If you wish to exclude a subdirectory of an included one, you can add it to the ``exclude``
+directive.
+
+
+.. _rstcheck: https://github.com/myint/rstcheck
+
+
+Sources
+-------
+
+* :searchfox:`Configuration (YAML) <tools/lint/rst.yml>`
+* :searchfox:`Source <tools/lint/rst/__init__.py>`
diff --git a/docs/code-quality/lint/linters/ruff.rst b/docs/code-quality/lint/linters/ruff.rst
new file mode 100644
index 0000000000..359e8dcbf6
--- /dev/null
+++ b/docs/code-quality/lint/linters/ruff.rst
@@ -0,0 +1,44 @@
+Ruff
+====
+
+`Ruff <https://github.com/charliermarsh/ruff>`_ is an extremely fast Python
+linter and formatter, written in Rust. It can process all of mozilla-central in
+under a second, and implements rule sets from a large array of Python linters
+and formatters, including:
+
+* flake8 (pycodestyle, pyflakes and mccabe)
+* isort
+* pylint
+* pyupgrade
+* and many many more!
+
+Run Locally
+-----------
+
+The mozlint integration of ruff can be run using mach:
+
+.. parsed-literal::
+
+ $ mach lint --linter ruff <file paths>
+
+
+Configuration
+-------------
+
+Ruff is configured in the root `pyproject.toml`_ file. Additionally, ruff will
+pick up any ``pyproject.toml`` or ``ruff.toml`` files in subdirectories. The
+settings in these files will only apply to files contained within these
+subdirs. For more details on configuration discovery, see the `configuration
+documentation`_.
+
+For a list of options, see the `settings documentation`_.
+
+Sources
+-------
+
+* `Configuration (YAML) <https://searchfox.org/mozilla-central/source/tools/lint/ruff.yml>`_
+* `Source <https://searchfox.org/mozilla-central/source/tools/lint/python/ruff.py>`_
+
+.. _pyproject.toml: https://searchfox.org/mozilla-central/source/pyproject.toml
+.. _configuration documentation: https://beta.ruff.rs/docs/configuration/
+.. _settings documentation: https://beta.ruff.rs/docs/settings/
diff --git a/docs/code-quality/lint/linters/rustfmt.rst b/docs/code-quality/lint/linters/rustfmt.rst
new file mode 100644
index 0000000000..eb7e75fa6b
--- /dev/null
+++ b/docs/code-quality/lint/linters/rustfmt.rst
@@ -0,0 +1,33 @@
+Rustfmt
+=======
+
+`rustfmt <https://github.com/rust-lang/rustfmt>`__ is the tool for Rust coding style.
+
+Run Locally
+-----------
+
+The mozlint integration of rustfmt can be run using mach:
+
+.. parsed-literal::
+
+ $ mach lint --linter rustfmt <file paths>
+
+
+Configuration
+-------------
+
+To enable rustfmt on new directory, add the path to the include
+section in the :searchfox:`rustfmt.yml <tools/lint/rustfmt.yml>` file.
+
+
+Autofix
+-------
+
+Rustfmt is reformatting the code by default. To highlight the results, we are using
+the ``--check`` option.
+
+Sources
+-------
+
+* :searchfox:`Configuration (YAML) <tools/lint/rustfmt.yml>`
+* :searchfox:`Source <tools/lint/rust/__init__.py>`
diff --git a/docs/code-quality/lint/linters/stylelint.rst b/docs/code-quality/lint/linters/stylelint.rst
new file mode 100644
index 0000000000..1e8b6c7ff9
--- /dev/null
+++ b/docs/code-quality/lint/linters/stylelint.rst
@@ -0,0 +1,77 @@
+Stylelint
+=========
+
+`Stylelint`__ is a popular linter for CSS.
+
+Run Locally
+-----------
+
+The mozlint integration of Stylelint can be run using mach:
+
+.. parsed-literal::
+
+ $ mach lint --linter stylelint <file paths>
+
+Alternatively, omit the ``--linter stylelint`` and run all configured linters, which will include
+Stylelint.
+
+Stylelint also supports the ``--fix`` option to autofix most errors raised from most of the rules.
+
+See the `Usage guide`_ for more options.
+
+Understanding Rules and Errors
+------------------------------
+
+* Only some files are linted, see the :searchfox:`configuration <tools/lint/stylelint.yml>` for details.
+
+ * By design we do not lint/format reftests not crashtests as these are specially crafted tests.
+
+* If you don't understand a rule, you can look it in `stylelint.io's rule list`_ for more
+ information about it.
+
+Common Issues and How To Solve Them
+-----------------------------------
+
+This code should neither be linted nor formatted
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* If it is a third-party piece of code, please add it to :searchfox:`ThirdPartyPaths.txt <tools/rewriting/ThirdPartyPaths.txt>`.
+* If it is a generated file, please add it to :searchfox:`Generated.txt <tools/rewriting/Generated.txt>`.
+* If intentionally invalid, please add it to :searchfox:`.stylelintignore <.stylelintignore>`.
+
+Configuration
+-------------
+
+The global configuration file lives in ``topsrcdir/.stylelintrc.js``.
+For an overview of the supported configuration, see `Stylelint's documentation`_.
+
+Please keep differences in rules across the tree to a minimum. We want to be consistent to
+make it easier for developers.
+
+Sources
+-------
+
+* :searchfox:`Configuration (YAML) <tools/lint/stylelint.yml>`
+* :searchfox:`Source <tools/lint/stylelint/__init__.py>`
+
+Builders
+--------
+
+`Gijs Kruitbosch (gijs) <https://people.mozilla.org/s?query=gijs>`__ owns
+the builders. Questions can also be asked on #lint:mozilla.org on Matrix.
+
+Stylelint task
+^^^^^^^^^^^^^^
+
+This is a tier-1 task. For test failures the patch causing the
+issue should be backed out or the issue fixed.
+
+Some failures can be fixed with ``./mach lint -l stylelint --fix path/to/file``.
+
+For test harness issues, file bugs in Developer Infrastructure :: Lint and Formatting.
+
+
+.. __: https://stylelint.io/
+.. _Usage guide: ../usage.html
+.. _Stylelint's documentation: https://stylelint.io/user-guide/configure/
+.. _stylelint.io's rule list: https://stylelint.io/user-guide/rules/
diff --git a/docs/code-quality/lint/linters/trojan-source.rst b/docs/code-quality/lint/linters/trojan-source.rst
new file mode 100644
index 0000000000..250bdd9afe
--- /dev/null
+++ b/docs/code-quality/lint/linters/trojan-source.rst
@@ -0,0 +1,34 @@
+Trojan Source
+=============
+
+This linter verifies if a change is using some invalid unicode.
+
+The goal of this linter is to identify some potential usage of this
+technique:
+
+https://trojansource.codes/
+
+The code is inspired by the Red Hat script published:
+
+https://access.redhat.com/security/vulnerabilities/RHSB-2021-007#diagnostic-tools
+
+Run Locally
+-----------
+
+This mozlint linter can be run using mach:
+
+.. parsed-literal::
+
+ $ mach lint --linter trojan-source <file paths>
+
+
+Configuration
+-------------
+
+This linter is enabled on most of the code base on C/C++, Python and Rust.
+
+Sources
+-------
+
+* `Configuration (YAML) <https://searchfox.org/mozilla-central/source/tools/lint/trojan-source.yml>`_
+* `Source <https://searchfox.org/mozilla-central/source/tools/lint/trojan-source/__init__.py>`_
diff --git a/docs/code-quality/lint/linters/yamllint.rst b/docs/code-quality/lint/linters/yamllint.rst
new file mode 100644
index 0000000000..e148a6aace
--- /dev/null
+++ b/docs/code-quality/lint/linters/yamllint.rst
@@ -0,0 +1,31 @@
+yamllint
+========
+
+`yamllint <https://github.com/adrienverge/yamllint>`__ is a linter for YAML files.
+
+
+Run Locally
+-----------
+
+The mozlint integration of yamllint can be run using mach:
+
+.. parsed-literal::
+
+ $ mach lint --linter yaml <file paths>
+
+Alternatively, omit ``--linter yaml`` to run all configured linters, including
+yamllint.
+
+
+Configuration
+-------------
+
+To enable yamllint on a new directory, add the path to the include section in
+the :searchfox:`yaml.yml <tools/lint/yaml.yml>` file.
+
+
+Sources
+-------
+
+* :searchfox:`Configuration (YAML) <tools/lint/yaml.yml>`
+* :searchfox:`Source <tools/lint/yamllint_/__init__.py>`