tor-browser

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

.stylelintrc.js (15008B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 /* eslint-env node */
      6 
      7 "use strict";
      8 
      9 const fs = require("fs");
     10 const path = require("path");
     11 const rollouts = require("./stylelint-rollouts.config");
     12 
     13 function readFile(filePath) {
     14  return fs
     15    .readFileSync(filePath, { encoding: "utf-8" })
     16    .split("\n")
     17    .filter(p => p && !p.startsWith("#"));
     18 }
     19 
     20 const ignoreFiles = [
     21  ...readFile(
     22    path.join(__dirname, "tools", "rewriting", "ThirdPartyPaths.txt")
     23  ),
     24  ...readFile(path.join(__dirname, "tools", "rewriting", "Generated.txt")),
     25 ];
     26 
     27 module.exports = {
     28  extends: ["stylelint-config-recommended"],
     29  plugins: [
     30    "./tools/lint/stylelint/stylelint-plugin-mozilla/index.mjs",
     31    "@stylistic/stylelint-plugin",
     32    "stylelint-use-logical",
     33  ],
     34  ignoreFiles,
     35  rules: {
     36    /* Disabled because of `-moz-element(#foo)` which gets misparsed. */
     37    "color-no-invalid-hex": null,
     38    "font-family-no-missing-generic-family-keyword": [
     39      true,
     40      {
     41        ignoreFontFamilies: [
     42          "-moz-button",
     43          "-moz-field",
     44          "-moz-fixed",
     45          "-moz-list",
     46          "caption",
     47        ],
     48      },
     49    ],
     50 
     51    "function-no-unknown": [
     52      true,
     53      {
     54        ignoreFunctions: [
     55          "light-dark" /* Used for color-scheme dependent colors */,
     56          "add" /* Used in mathml.css */,
     57          "-moz-symbolic-icon" /* Used for GTK icons */,
     58        ],
     59      },
     60    ],
     61 
     62    "length-zero-no-unit": [
     63      true,
     64      {
     65        ignore: ["custom-properties"],
     66      },
     67    ],
     68 
     69    "max-nesting-depth": [
     70      3,
     71      {
     72        ignore: ["blockless-at-rules"],
     73      },
     74    ],
     75 
     76    "no-descending-specificity": null,
     77    "no-duplicate-selectors": null,
     78 
     79    "property-no-unknown": [
     80      true,
     81      {
     82        ignoreProperties: [
     83          // overflow-clip-box is Gecko-specific and not exposed to web
     84          // content. Might be replaced with overflow-clip-margin, see:
     85          // https://github.com/w3c/csswg-drafts/issues/10745
     86          "overflow-clip-box",
     87          "overflow-clip-box-block",
     88          "overflow-clip-box-inline",
     89        ],
     90      },
     91    ],
     92 
     93    /*
     94     * XXXgijs: we would like to enable this, but we can't right now.
     95     * This is because Gecko uses a number of custom pseudoclasses,
     96     * and stylelint assumes that for `:unknown-pseudoclass(foo)`,
     97     * `foo` should be a known type.
     98     * This is tedious but workable for things like `-moz-locale-dir` where
     99     * the set of acceptable values (ltr/rtl) is small.
    100     * However, for tree cells, the set of values is unlimited (ie
    101     * user-defined, based on atoms sent by the JS tree view APIs).
    102     * There does not appear to be a way to exempt the contents of these
    103     * unknown pseudoclasses, and as a result, this rule is not
    104     * usable for us. The 'type' only includes the contents of the
    105     * pseudoclass, not the pseudo itself, so we can't filter based on the
    106     * pseudoclass either.
    107     * Ideally, we would either create an option to the builtin rule
    108     * in stylelint itself, or mimic the rule but exempt these, or
    109     * add parser support for our custom pseudoclasses.
    110     *
    111     * For now, we just disable this rule.
    112     */
    113    "selector-type-no-unknown": null,
    114    /*
    115     * See above - if we enabled this rule, we'd have to allow for a number
    116     * of custom elements we use, which are listed here:
    117    "selector-type-no-unknown": [
    118      true,
    119      {
    120        ignore: ["custom-elements"],
    121        ignoreTypes: [
    122          // Modern custom element / storybooked components:
    123          /^moz-/,
    124          // moz-locale-dir trips this rule for some reason:
    125          "rtl",
    126          "ltr",
    127          // Migrated XBL elements not part of core XUL that we use at the moment:
    128          "findbar",
    129          "panelmultiview",
    130          "panelview",
    131          "popupnotification",
    132          "popupnotificationcontent",
    133          // Legacy XUL elements:
    134          // (the commented out ones used to be a thing and aren't used in-tree anymore)
    135          "arrowscrollbox",
    136          "box",
    137          // "broadcaster",
    138          // "broadcasterset",
    139          "button",
    140          "browser",
    141          "checkbox",
    142          "caption",
    143          // clicktoscroll
    144          // colorpicker
    145          // column
    146          // columns
    147          "commandset",
    148          "command",
    149          // conditions
    150          // content
    151          // datepicker
    152          "deck",
    153          "description",
    154          "dialog",
    155          // dialogheader
    156          "dropmarker",
    157          "editor",
    158          // grid
    159          // grippy
    160          "groupbox",
    161          "hbox",
    162          // iframe
    163          // image
    164          "key",
    165          "keyset",
    166          // label
    167          "listbox",
    168          // listcell
    169          // listcol
    170          // listcols
    171          // listhead
    172          // listheader
    173          "listitem",
    174          // member
    175          "menu",
    176          "menubar",
    177          "menucaption",
    178          "menuitem",
    179          "menulist",
    180          "menupopup",
    181          "menuseparator",
    182          "notification",
    183          "notificationbox",
    184          "observes",
    185          // overlay
    186          // page
    187          "panel",
    188          // param
    189          "popupset",
    190          // preference
    191          // preferences
    192          // prefpane
    193          // prefwindow
    194          // progressmeter
    195          // query
    196          // queryset
    197          "radio",
    198          "radiogroup",
    199          // resizer
    200          "richlistbox",
    201          "richlistitem",
    202          // row
    203          // rows
    204          // rule
    205          // scale
    206          // script
    207          "scrollbar",
    208          "scrollbox",
    209          "scrollcorner",
    210          "separator",
    211          "spacer",
    212          // spinbuttons
    213          "splitter",
    214          "stack",
    215          // statusbar
    216          // statusbarpanel
    217          "stringbundle",
    218          "stringbundleset",
    219          "tab",
    220          "tabbox",
    221          "tabpanel",
    222          "tabpanels",
    223          "tabs",
    224          // template
    225          // textnode
    226          "textbox",
    227          // timepicker
    228          "titlebar",
    229          "toolbar",
    230          "toolbarbutton",
    231          // toolbargrippy
    232          "toolbaritem",
    233          "toolbarpalette",
    234          "toolbarpaletteitem",
    235          "toolbarseparator",
    236          "toolbarset",
    237          "toolbarspacer",
    238          "toolbarspring",
    239          "toolbartabstop",
    240          "toolbox",
    241          "tooltip",
    242          "tree",
    243          "treecell",
    244          "treechildren",
    245          "treecol",
    246          "treecols",
    247          "treeitem",
    248          "treerow",
    249          "treeseparator",
    250          // triple
    251          "vbox",
    252          // where
    253          "window",
    254          "wizard",
    255          "wizardpage",
    256        ],
    257      },
    258    ],
    259    */
    260 
    261    "selector-pseudo-class-no-unknown": [
    262      true,
    263      {
    264        ignorePseudoClasses: ["popover-open"],
    265      },
    266    ],
    267    "selector-pseudo-element-no-unknown": [
    268      true,
    269      {
    270        ignorePseudoElements: ["slider-track", "slider-fill", "slider-thumb"],
    271      },
    272    ],
    273    // stylelint fixes for the use-logical rule will be addressed in Bug 1996168
    274    // Remove this line setting `csscontrols/use-logical` to null after implementing fixes
    275    "csstools/use-logical": null,
    276    "stylelint-plugin-mozilla/no-base-design-tokens": true,
    277    "stylelint-plugin-mozilla/use-design-tokens": true,
    278    "stylelint-plugin-mozilla/no-non-semantic-token-usage": true,
    279    "stylelint-plugin-mozilla/use-size-tokens": true,
    280  },
    281 
    282  overrides: [
    283    {
    284      files: "*.scss",
    285      customSyntax: "postcss-scss",
    286      extends: "stylelint-config-recommended-scss",
    287    },
    288    {
    289      files: [
    290        "browser/components/aboutwelcome/**",
    291        "browser/components/asrouter/**",
    292        "browser/extensions/newtab/**",
    293      ],
    294      customSyntax: "postcss-scss",
    295      extends: "stylelint-config-standard-scss",
    296      rules: {
    297        "@stylistic/color-hex-case": "upper",
    298        "@stylistic/indentation": 2,
    299        "@stylistic/no-eol-whitespace": true,
    300        "@stylistic/no-missing-end-of-source-newline": true,
    301        "@stylistic/number-leading-zero": "always",
    302        "@stylistic/number-no-trailing-zeros": true,
    303        "@stylistic/string-quotes": [
    304          "single",
    305          {
    306            avoidEscape: true,
    307          },
    308        ],
    309        "at-rule-disallowed-list": [
    310          ["debug", "warn", "error"],
    311          {
    312            message: "Clean up %s directives before committing",
    313          },
    314        ],
    315        "at-rule-no-vendor-prefix": null,
    316        "color-function-notation": null,
    317        "comment-empty-line-before": [
    318          "always",
    319          {
    320            except: ["first-nested"],
    321            ignore: ["after-comment", "stylelint-commands"],
    322          },
    323        ],
    324        "custom-property-empty-line-before": null,
    325        "custom-property-pattern": null,
    326        "declaration-block-no-duplicate-properties": true,
    327        "declaration-block-no-redundant-longhand-properties": null,
    328        "declaration-no-important": true,
    329        "function-no-unknown": [
    330          true,
    331          {
    332            ignoreFunctions: ["div"],
    333          },
    334        ],
    335        "function-url-no-scheme-relative": true,
    336        "keyframes-name-pattern": null,
    337        "media-feature-name-no-vendor-prefix": null,
    338        "no-descending-specificity": null,
    339        "property-disallowed-list": [
    340          ["margin-left", "margin-right"],
    341          {
    342            message: "Use margin-inline instead of %s",
    343          },
    344        ],
    345        "property-no-unknown": true,
    346        "property-no-vendor-prefix": null,
    347        "scss/dollar-variable-empty-line-before": null,
    348        "scss/double-slash-comment-empty-line-before": [
    349          "always",
    350          {
    351            except: ["first-nested"],
    352            ignore: ["between-comments", "stylelint-commands", "inside-block"],
    353          },
    354        ],
    355        "selector-class-pattern": null,
    356        "selector-no-vendor-prefix": null,
    357        "value-keyword-case": null,
    358        "value-no-vendor-prefix": null,
    359      },
    360    },
    361    {
    362      files: ["browser/extensions/newtab/**"],
    363      rules: {
    364        "declaration-property-value-disallowed-list": [
    365          {
    366            "font-size": [
    367              "/^[0-9.]+(px|em|rem|%)$/",
    368              "/^[0-9.]+$/",
    369              "/^(small|medium|large|x-large|xx-large)$/",
    370            ],
    371            "border-radius": [
    372              "/^[0-9.]+(px|em|rem|%)$/",
    373              "/^(small|medium|large|x-large|xx-large)$/",
    374            ],
    375            // Validate to only allow variables and global values
    376            "font-weight": [
    377              "/^(?!var\\(|inherit$|initial$|unset$|revert$|revert-layer$).+$/",
    378            ],
    379            [/^(margin|padding|inset|gap|row-gap|column-gap|grid-row-gap|grid-column-gap|top|right|bottom|left)($|-)/]:
    380              ["/[0-9.]+(px|em|rem)|\\$/"],
    381          },
    382          {
    383            message:
    384              "Avoid literal values. Use variables (e.g. var(--font-size-small)) or inherit/unset/etc.",
    385          },
    386        ],
    387        "csstools/use-logical": [
    388          "always",
    389          {
    390            // Bug 2003301: Do not enforce logical properties for any height/width properties
    391            except: [/^(min-|max-)?width/i, /^(min-|max-)?height/i],
    392            severity: "error",
    393          },
    394        ],
    395      },
    396    },
    397    {
    398      name: "design-token-rules-off",
    399      files: [
    400        // CSS files under browser/branding do not use design tokens
    401        "browser/branding/**",
    402        // CSS files under browser/components/extensions are not using design tokens
    403        "browser/components/extensions/**",
    404        // Webcompat interventions are not expected to use design tokens
    405        // They are intended to override existing styles for specific extension
    406        "browser/extensions/webcompat/injections/css/**",
    407        // Most of devtools does not use design tokens, so turn the appropriate rules off for devtools.
    408        // Stylelint does not support negating the file glob within an overrides section,
    409        // so these rules get re-enabled for some devtools files in the section below
    410        "devtools/**",
    411        // FXR is no longer maintained and is not expected to use design tokens
    412        "browser/fxr/**",
    413        // Android does not use design tokens
    414        "mobile/android/**",
    415        // Docs do not use design tokens
    416        "docs/**",
    417        // DOM does not use design tokens
    418        "dom/**",
    419        // Layouts do not use design tokens
    420        "layout/**",
    421        // Testing does not use design tokens
    422        "testing/**",
    423        // UA Widgets should not use design tokens
    424        "toolkit/themes/shared/colorpicker-common.css",
    425        "toolkit/themes/shared/colorpicker.css",
    426        "toolkit/themes/shared/media/pipToggle.css",
    427        "toolkit/themes/shared/media/videocontrols.css",
    428        "toolkit/content/widgets/datetimebox.css",
    429        "toolkit/content/widgets/marquee.css",
    430        "toolkit/themes/shared/media/textrecognition.css",
    431        // The contents of backup/content/archive.css are injected as inline CSS
    432        // into the HTML backup archive files that exist on a user's file system
    433        // and can be opened in any browser.
    434        "browser/components/backup/content/archive.css",
    435        // Bug 2003877 - this is a centralization of a bunch of rules that had
    436        // been spread across about:newtab and about:privatebrowsing. We'll
    437        // fix these design tokens issues in a follow-up (presuming the
    438        // replacement of the handoff bar doesn't land and remove this first).
    439        "browser/components/search/content/contentSearchHandoffUI.css",
    440      ],
    441      rules: {
    442        "stylelint-plugin-mozilla/use-design-tokens": null,
    443        "stylelint-plugin-mozilla/no-non-semantic-token-usage": null,
    444        "stylelint-plugin-mozilla/use-size-tokens": null,
    445      },
    446    },
    447    {
    448      name: "design-token-rules-on",
    449      files: [
    450        // Enable design token related rules only on the parts of devtools that can use them
    451        "devtools/client/aboutdebugging/src/**",
    452      ],
    453      rules: {
    454        "stylelint-plugin-mozilla/use-design-tokens": true,
    455        "stylelint-plugin-mozilla/no-non-semantic-token-usage": true,
    456        "stylelint-plugin-mozilla/use-size-tokens": true,
    457      },
    458    },
    459    {
    460      files: ["toolkit/**/*.css", "toolkit/**/*.scss"],
    461      rules: {
    462        "stylelint-plugin-mozilla/no-browser-refs-in-toolkit": true,
    463      },
    464    },
    465    {
    466      // non-logical properties make sense in devtools/ where physical positioning always makes sense
    467      name: "logical-properties-rule-off",
    468      files: ["devtools/**"],
    469      rules: {
    470        "csstools/use-logical": null,
    471      },
    472    },
    473    // Rollouts should always be applied last in the overrides section
    474    // to ensure that they take precedence over other overrides.
    475    ...rollouts,
    476  ],
    477 };