eslint-plugin-chrome-extensions 2.6.0 → 2.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +648 -33
  2. package/package.json +11 -9
  3. package/src/data/apis.js +74 -88
  4. package/src/data/manifest.js +3 -1
  5. package/src/data/regex.js +3 -1
  6. package/src/index.d.ts +42 -0
  7. package/src/index.js +0 -4
  8. package/src/rules/css-spacing.js +375 -0
  9. package/src/rules/manifest-key-order.js +1 -2
  10. package/src/rules/manifest-spacing.js +1 -2
  11. package/src/rules/no-content-style-leak.js +12 -11
  12. package/src/rules/no-deprecated-apis.js +2 -2
  13. package/src/rules/no-duplicate-manifest-keys.js +0 -1
  14. package/src/rules/no-global-keyframes.js +84 -0
  15. package/src/rules/no-host-page-selectors.js +105 -0
  16. package/src/rules/no-inline-event-handlers.js +116 -0
  17. package/src/rules/no-inline-scripts.js +65 -0
  18. package/src/rules/no-insecure-fetch.js +7 -6
  19. package/src/rules/no-insecure-messaging.js +4 -4
  20. package/src/rules/no-invalid-locales.js +3 -5
  21. package/src/rules/no-missing-default-locale.js +1 -1
  22. package/src/rules/no-missing-permissions.js +2 -3
  23. package/src/rules/no-missing-web-accessible-resources.js +2 -2
  24. package/src/rules/no-remote-code.js +77 -28
  25. package/src/rules/no-remote-objects.js +55 -0
  26. package/src/rules/no-remote-urls.js +102 -0
  27. package/src/rules/no-scrollbar-styling.js +71 -0
  28. package/src/rules/no-unrestricted-host-permissions.js +1 -1
  29. package/src/rules/no-unused-i18n-keys.js +0 -1
  30. package/src/rules/no-unused-permissions.js +5 -4
  31. package/src/rules/require-license-file.js +1 -2
  32. package/src/rules/require-mv3.js +3 -2
  33. package/src/rules/require-short-name-when-useful.js +0 -1
  34. package/src/rules/valid-filenames.js +3 -3
  35. package/src/rules/valid-license-file.js +2 -4
  36. package/src/rules/valid-manifest-icons.js +2 -2
  37. package/src/rules/valid-mv3-schema.js +5 -5
  38. package/src/rules/valid-url-fields.js +2 -2
  39. package/src/rules/valid-version-field.js +2 -2
  40. package/src/utils/api.js +20 -0
  41. package/src/utils/array.js +1 -0
  42. package/src/utils/extension.js +1 -3
  43. package/src/utils/html.js +29 -0
  44. package/src/utils/i18n.js +2 -2
  45. package/src/utils/init.js +21 -9
  46. package/src/utils/license.js +1 -1
  47. package/src/utils/node.js +3 -1
  48. package/src/utils/pkg.js +19 -2
  49. package/src/utils/rules.js +1 -1
  50. package/src/data/deprecations.js +0 -8
package/README.md CHANGED
@@ -8,8 +8,8 @@
8
8
  <img alt="[License: MIT]" src="https://img.shields.io/badge/License-MIT-f1f20a.svg?logo=internetarchive&logoColor=white&labelColor=464646&style=for-the-badge"></a>
9
9
  <a target="_blank" href="https://getnpmstats.com/?package=eslint-plugin-chrome-extensions&range=last-year&interval=monthly">
10
10
  <img src="https://img.shields.io/npm/dm/eslint-plugin-chrome-extensions?style=for-the-badge&logo=npm&color=black"></a>
11
- <a target="_blank" href="https://eslint.org/">
12
- <img alt="[Requires ESLint >=9.6.0]" src="https://img.shields.io/badge/Requires-ESLint_%3E%3D9.6.0-4B32C3?style=for-the-badge&logo=eslint"></a>
11
+ <a href="#usage">
12
+ <img alt="[Supports ESLint >=9.6.0 / Oxlint >=1.65.0]" src="https://img.shields.io/badge/Supports-ESLint_%3E%3D9.6.0_%2F_Oxlint_%3E%3D1.65.0-4B32C3?style=for-the-badge&logo=eslint"></a>
13
13
  <br><br>
14
14
 
15
15
  ESLint rules for Chrome extensions.
@@ -33,6 +33,8 @@ npm i -D eslint-plugin-chrome-extensions
33
33
  Usage
34
34
  </h2>
35
35
 
36
+ ### ESLint
37
+
36
38
  Add bundled configs to your `eslint.config.*js` for each file type you need:
37
39
 
38
40
  ```js
@@ -46,36 +48,136 @@ export default [
46
48
  plugins: { 'chrome-extensions': chromeExtensions },
47
49
  rules: {
48
50
  ...chromeExtensions.configs.recommended.rules,
49
- 'chrome-extensions/no-deprecated-apis': 'off' // selectively disable rule
50
- }
51
- },
52
- {
53
- files: ['**/manifest.json'], ...chromeExtensions.configs.manifest,
54
- rules: {
55
- ...chromeExtensions.configs.manifest.rules,
56
- 'chrome-extensions/manifest-spacing': ['warn', { spaces: 4 }] // selectively tweak rule
51
+ 'chrome-extensions/no-deprecated-apis': 'off', // selectively disable rule
52
+ 'chrome-extensions/valid-version-field': ['error', { versionType: 'date' }] // selectively tweak rule
57
53
  }
58
54
  },
59
- { files: ['**/*LICENSE*'], ...chromeExtensions.configs.license },
60
- { files: ['**/extension/**/*.css'], ...chromeExtensions.configs.css },
61
- { files: ['**/extension/**/*.html'], ...chromeExtensions.configs.html },
62
- { files: ['**/extension/**/*.json'], ...chromeExtensions.configs.json },
63
- { files: ['**/extension/**/*.json5'], ...chromeExtensions.configs.json5 },
64
- { files: ['**/extension/**/*.jsonc'], ...chromeExtensions.configs.jsonc }
55
+ { files: ['**/*LICENSE*'], ...chromeExtensions.configs.license },
56
+ { files: ['**/manifest.json'], ...chromeExtensions.configs.manifest },
57
+ { files: ['**/extension/**/*.css'], ...chromeExtensions.configs.css },
58
+ { files: ['**/extension/**/*.html'], ...chromeExtensions.configs.html },
59
+ { files: ['**/extension/**/*.json'], ...chromeExtensions.configs.json },
60
+ { files: ['**/extension/**/*.json5'], ...chromeExtensions.configs.json5 },
61
+ { files: ['**/extension/**/*.jsonc'], ...chromeExtensions.configs.jsonc }
65
62
  ]
66
63
  ```
67
64
 
68
- Available bundles: `recommended`, `strict` (everything), `problem` (deterministic bugs only), `security`, `manifest`, `license`, `css`, `html`, `json`, `json5`, `jsonc`
65
+ ### Oxlint
66
+
67
+ Add a JS bundle to your `oxlint.config.ts` (non-JS parsing unsupported by Oxlint):
68
+
69
+ ```ts
70
+ ...
71
+ import chromeExtensions from 'eslint-plugin-chrome-extensions'
72
+
73
+ export default defineConfig({
74
+ // main config
75
+ overrides: [
76
+ // other overrides
77
+ {
78
+ files: ['**/extension/**/*.{cjs,js,jsx,mjs,ts,tsx}'],
79
+ jsPlugins: ['eslint-plugin-chrome-extensions'],
80
+ rules: {
81
+ ...chromeExtensions.configs.recommended.rules,
82
+ 'chrome-extensions/no-deprecated-apis': 'off', // selectively disable rule
83
+ 'chrome-extensions/no-insecure-messaging': ['error', { disallowWildcardTarget: false }] // selectively tweak rule
84
+ }
85
+ }
86
+ ]
87
+ })
88
+ ```
69
89
 
70
90
  **Note:** Rule config is either a severity string (`'off'`, `'warn'`, `'error'`) or an array `[severity, options]` when the rule accepts options.
71
91
 
72
92
  ---
73
93
 
94
+ *Available JS bundles:* `recommended`, `strict` (everything), `problem` (deterministic bugs only), `security`
95
+
96
+ *Available filetype bundles (ESLint only):* `manifest`, `license`, `css`, `html`, `json`, `json5`, `jsonc`
97
+
98
+ ---
99
+
74
100
  <h2 id="supported-rules">
75
101
  <img height=30 width=27 align="top" src="https://api.iconify.design/mdi/format-list-checks.svg?color=%232b2b2a">
76
102
  Supported rules
77
103
  </h2>
78
104
 
105
+ <h3 id="css-spacing">
106
+ <code>css-spacing</code>
107
+ <a title="Only works in 'css/css' config block" href="#usage">
108
+ <img height=18 alt="[CSS only]" src="https://img.shields.io/badge/CSS_only-dcd6f7?style=flat-square" align="middle"></a>
109
+ <a title="Accepts eslint --fix" target="_blank" href="https://eslint.org/docs/latest/use/command-line-interface#--fix">
110
+ <img height=18 alt="[Auto-fixable]" src="https://img.shields.io/badge/Auto--fixable-3b5bdb?style=flat-square" align="middle"></a>
111
+ <a title="Doesn't prevent bugs" href="#css-spacing">
112
+ <img height=18 alt="[Stylistic]" src="https://img.shields.io/badge/Stylistic-af68ff?style=flat-square" align="middle"></a>
113
+ <a title="Accepts array w/ options" href="#usage">
114
+ <img height=18 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
115
+ <a title="Copy rule URL" target="_blank"
116
+ href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23css-spacing">
117
+ <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
118
+ </h3>
119
+
120
+ <details>
121
+
122
+ <summary>Enforces consistent indentation and spacing in CSS.</summary>
123
+
124
+ <h4 id="css-spacing-options">Options</h4>
125
+
126
+ - `spaces` (default `2`) – number of spaces per indent level <a title="Introduced in v2.7.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.7.0"><img height=14 alt="[Since v2.7.0]" src="https://img.shields.io/badge/since-v2.7.0-8a9199?style=flat-square" align="middle"></a>
127
+ - `checkBraces` (default `true`) – enforce 1 space after `{` and before `}` in single-line rules <a title="Introduced in v2.7.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.7.0"><img height=14 alt="[Since v2.7.0]" src="https://img.shields.io/badge/since-v2.7.0-8a9199?style=flat-square" align="middle"></a>
128
+ - `checkBrackets` (default `true`) – enforce 0 spaces after `[` and before `]` in attribute selectors <a title="Introduced in v2.7.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.7.0"><img height=14 alt="[Since v2.7.0]" src="https://img.shields.io/badge/since-v2.7.0-8a9199?style=flat-square" align="middle"></a>
129
+ - `checkColons` (default `true`) – enforce 0 spaces before and 1 space after `:` in declarations, and 1 space between value tokens <a title="Introduced in v2.7.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.7.0"><img height=14 alt="[Since v2.7.0]" src="https://img.shields.io/badge/since-v2.7.0-8a9199?style=flat-square" align="middle"></a>
130
+ - `checkCombinators` (default `true`) – enforce 1 space on each side of `>`, `+`, `~` in selectors <a title="Introduced in v2.7.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.7.0"><img height=14 alt="[Since v2.7.0]" src="https://img.shields.io/badge/since-v2.7.0-8a9199?style=flat-square" align="middle"></a>
131
+ - `checkCommas` (default `true`) – enforce 0 spaces before and 1 space after `,` in selector lists <a title="Introduced in v2.7.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.7.0"><img height=14 alt="[Since v2.7.0]" src="https://img.shields.io/badge/since-v2.7.0-8a9199?style=flat-square" align="middle"></a>
132
+ - `checkParentheses` (default `true`) – enforce 0 spaces after `(` and before `)` in functions and pseudo-classes <a title="Introduced in v2.7.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.7.0"><img height=14 alt="[Since v2.7.0]" src="https://img.shields.io/badge/since-v2.7.0-8a9199?style=flat-square" align="middle"></a>
133
+ - `checkSemicolons` (default `true`) – enforce 1 space after `;` in single-line declaration blocks <a title="Introduced in v2.7.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.7.0"><img height=14 alt="[Since v2.7.0]" src="https://img.shields.io/badge/since-v2.7.0-8a9199?style=flat-square" align="middle"></a>
134
+
135
+ #### <img width=13 height=13 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-greasemonkey/99f14247b2/assets/images/icons/square/with-symbol/gray.svg" align="bottom"> Incorrect code
136
+
137
+ ```diff
138
+ ! .panel { background : blue }
139
+ ! .panel+em { font-style: italic }
140
+ ! :not( .bar ) { color: red }
141
+ ```
142
+
143
+ #### <img width=13 height=13 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-greasemonkey/99f14247b2/assets/images/icons/square/with-symbol/green.svg" align="bottom"> Correct code
144
+
145
+ ```diff
146
+ - .panel { background : blue }
147
+ + .panel { background: blue }
148
+ - .panel+em { font-style: italic }
149
+ + .panel + em { font-style: italic }
150
+ - :not( .bar ) { color: red }
151
+ + :not(.bar) { color: red }
152
+ ```
153
+
154
+ #### When not to use it
155
+
156
+ If you don't care about visual consistency in your CSS, or you already use Stylelint to format CSS.
157
+
158
+ #### Introduced in
159
+
160
+ <a target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.7.0">v2.7.0</a> (October 17, 2026)
161
+
162
+ #### See also
163
+
164
+ - [`manifest-spacing`](#manifest-spacing)
165
+ <a title="Only works in 'json/json' config block" href="#usage"><img height=14 alt="[Manifest only]" src="https://img.shields.io/badge/Manifest_only-999999?style=flat-square" align="middle"></a>
166
+ <a title="Accepts eslint --fix" target="_blank" href="https://eslint.org/docs/latest/use/command-line-interface#--fix"><img height=14 alt="[Auto-fixable]" src="https://img.shields.io/badge/Auto--fixable-3b5bdb?style=flat-square" align="middle"></a>
167
+ <a title="Doesn't prevent bugs" href="#manifest-spacing"><img height=14 alt="[Stylistic]" src="https://img.shields.io/badge/Stylistic-af68ff?style=flat-square" align="middle"></a>
168
+ <a title="Accepts array w/ options" href="#manifest-spacing-options"><img height=14 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
169
+ - <img height=12 src="https://www.google.com/s2/favicons?domain=developer.mozilla.org&sz=64">&ensp;<a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/Syntax">MDN — CSS syntax</a>
170
+
171
+ <div align="center">
172
+
173
+ [Back to index ↑][epce-rules]
174
+
175
+ </div>
176
+
177
+ ---
178
+
179
+ </details>
180
+
79
181
  <h3 id="manifest-key-order">
80
182
  <code>manifest-key-order</code>
81
183
  <a title="Only works in 'json/json' config block" href="#usage">
@@ -240,6 +342,8 @@ If you don't care about visual consistency in your manifest.
240
342
 
241
343
  <h3 id="no-content-style-leak">
242
344
  <code>no-content-style-leak</code>
345
+ <a title="Introduced in v1.0.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v1.0.0">
346
+ <img height=18 align="middle" src="https://api.iconify.design/ph/flag-banner-fold-fill.svg?color=%234a4a4a"></a>
243
347
  <a title="Only included in strict config" href="#usage">
244
348
  <img height=18 alt="[Strict only]" src="https://img.shields.io/badge/Strict_only-ff8c42?style=flat-square" align="middle"></a>
245
349
  <a title="Copy rule URL" target="_blank"
@@ -292,6 +396,8 @@ If you intentionally interact w/ host page styles.
292
396
 
293
397
  <h3 id="no-deprecated-apis">
294
398
  <code>no-deprecated-apis</code>
399
+ <a title="Introduced in v1.0.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v1.0.0">
400
+ <img height=18 align="middle" src="https://api.iconify.design/ph/flag-banner-fold-fill.svg?color=%234a4a4a"></a>
295
401
  <a title="Included in recommended config" href="#usage">
296
402
  <img height=18 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
297
403
  <a title="Accepts array w/ options" href="#usage">
@@ -307,8 +413,8 @@ If you intentionally interact w/ host page styles.
307
413
 
308
414
  <h4 id="no-deprecated-apis-options">Options</h4>
309
415
 
310
- - `target` (default `'mv3'`) – Chrome extension manifest version whose deprecations to validate against (`'mv3'`, `'mv2'`) <a title="Introduced in v1.0.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v1.0.0"><img height=14 alt="[Since v1.0.0]" src="https://img.shields.io/badge/since-v1.0.0-6b8e6b?style=flat-square&labelColor=464646" align="middle"></a>
311
- - `allowedAPIs` (default `[]`) – additional deprecated API namespaces to allow, as a single string or array <a title="Introduced in v1.0.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v1.0.0"><img height=14 alt="[Since v1.0.0]" src="https://img.shields.io/badge/since-v1.0.0-6b8e6b?style=flat-square&labelColor=464646" align="middle"></a>
416
+ - `target` (default `'mv3'`) – Chrome extension manifest version whose deprecations to validate against (`'mv3'`, `'mv2'`) <a title="Introduced in v1.0.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v1.0.0"><img height=14 alt="[Since v1.0.0]" src="https://img.shields.io/badge/since-v1.0.0-8a9199?style=flat-square&labelColor=464646" align="middle"></a>
417
+ - `allowedAPIs` (default `[]`) – additional deprecated API namespaces to allow, as a single string or array <a title="Introduced in v1.0.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v1.0.0"><img height=14 alt="[Since v1.0.0]" src="https://img.shields.io/badge/since-v1.0.0-8a9199?style=flat-square&labelColor=464646" align="middle"></a>
312
418
 
313
419
  #### <img width=13 height=13 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-greasemonkey/99f14247b2/assets/images/icons/square/with-symbol/gray.svg" align="bottom"> Incorrect code
314
420
 
@@ -422,6 +528,285 @@ If you rely on a Chromium fork resolving duplicate keys in a specific order.
422
528
 
423
529
  </details>
424
530
 
531
+ <h3 id="no-global-keyframes">
532
+ <code>no-global-keyframes</code>
533
+ <a title="Only works in 'css/css' config block" href="#usage">
534
+ <img height=18 alt="[CSS only]" src="https://img.shields.io/badge/CSS_only-dcd6f7?style=flat-square" align="middle"></a>
535
+ <a title="Accepts array w/ options" href="#usage">
536
+ <img height=18 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
537
+ <a title="Copy rule URL" target="_blank"
538
+ href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23no-global-keyframes">
539
+ <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
540
+ </h3>
541
+
542
+ <details>
543
+
544
+ <summary>Disallows <code>@keyframes</code> in content-script CSS to prevent collisions w/ host animations.</summary>
545
+
546
+ <h4 id="no-global-keyframes-options">Options</h4>
547
+
548
+ - `flagCommonNames` (default `true`) – flag well-known animation names (`spin`, `fade-in`, `slide-in-right`, etc.) that are most likely to collide w/ host pages <a title="Introduced in v2.7.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.7.0"><img height=14 alt="[Since v2.7.0]" src="https://img.shields.io/badge/since-v2.7.0-8a9199?style=flat-square" align="middle"></a>
549
+ - `requiredPrefix` (default `undefined`) – flag names not starting w/ this prefix <a title="Introduced in v2.7.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.7.0"><img height=14 alt="[Since v2.7.0]" src="https://img.shields.io/badge/since-v2.7.0-8a9199?style=flat-square" align="middle"></a>
550
+
551
+ #### <img width=13 height=13 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-greasemonkey/99f14247b2/assets/images/icons/square/with-symbol/gray.svg" align="bottom"> Incorrect code
552
+
553
+ ```diff
554
+ ! @keyframes spin { from { transform: rotate(0) } to { transform: rotate(360deg) } }
555
+ ! @keyframes fade-in { from { opacity: 0 } to { opacity: 1 } }
556
+ ```
557
+
558
+ #### <img width=13 height=13 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-greasemonkey/99f14247b2/assets/images/icons/square/with-symbol/green.svg" align="bottom"> Correct code
559
+
560
+ ```diff
561
+ - @keyframes spin { from { transform: rotate(0) } to { transform: rotate(360deg) } }
562
+ + @keyframes myext-spin { from { transform: rotate(0) } to { transform: rotate(360deg) } }
563
+ - @keyframes fade-in { from { opacity: 0 } to { opacity: 1 } }
564
+ + @keyframes myext-fade-in { from { opacity: 0 } to { opacity: 1 } }
565
+ ```
566
+
567
+ #### When not to use it
568
+
569
+ If your CSS is scoped inside a Shadow DOM root.
570
+
571
+ #### Introduced in
572
+
573
+ <a target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.7.0">v2.7.0</a> (October 17, 2026)
574
+
575
+ #### See also
576
+
577
+ - [`no-host-page-selectors`](#no-host-page-selectors)
578
+ <a title="Only works in 'css/css' config block" href="#usage"><img height=14 alt="[CSS only]" src="https://img.shields.io/badge/CSS_only-dcd6f7?style=flat-square" align="middle"></a>
579
+ <a title="Accepts array w/ options" href="#no-host-page-selectors-options"><img height=14 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
580
+ - <img height=12 src="https://www.google.com/s2/favicons?domain=developer.mozilla.org&sz=64">&ensp;<a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/@keyframes">MDN — `@keyframes`</a>
581
+ - <img height=12 src="https://www.google.com/s2/favicons?domain=developer.mozilla.org&sz=64">&ensp;<a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_shadow_DOM">MDN — Using shadow DOM</a>
582
+
583
+ <div align="center">
584
+
585
+ [Back to index ↑][epce-rules]
586
+
587
+ </div>
588
+
589
+ ---
590
+
591
+ </details>
592
+
593
+ <h3 id="no-inline-event-handlers">
594
+ <code>no-inline-event-handlers</code>
595
+ <a title="Introduced in latest minor release" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.8.0">
596
+ <img height=16 align="middle" src="https://api.iconify.design/mdi/sprout.svg?color=%234a4a4a"></a>
597
+ <a title="Only works in 'html/html' config block" href="#usage">
598
+ <img height=18 alt="[HTML only]" src="https://img.shields.io/badge/HTML_only-a8d8ea?style=flat-square" align="middle"></a>
599
+ <a title="Accepts array w/ options" href="#usage">
600
+ <img height=18 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
601
+ <a title="Copy rule URL" target="_blank"
602
+ href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23no-inline-event-handlers">
603
+ <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
604
+ </h3>
605
+
606
+ <details>
607
+
608
+ <summary>Disallows inline event handlers (e.g. <code>onclick</code>, <code>onload</code>) in HTML (blocked by MV3's <code>script-src 'self'</code> at runtime).</summary>
609
+
610
+ <h4 id="no-inline-event-handlers-options">Options</h4>
611
+
612
+ - `allowedAttributes` (default `[]`) – inline event handler attributes to permit (e.g. `['onafterprint']`), as a single string or array <a title="Introduced in v2.8.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.8.0"><img height=14 alt="[Since v2.8.0]" src="https://img.shields.io/badge/since-v2.8.0-8a9199?style=flat-square" align="middle"></a>
613
+
614
+ #### <img width=13 height=13 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-greasemonkey/99f14247b2/assets/images/icons/square/with-symbol/gray.svg" align="bottom"> Incorrect code
615
+
616
+ ```diff
617
+ ! <button onclick="alert('hi')">Click</button>
618
+ ! <body onload="init()">
619
+ ! <img src="logo.png" onerror="this.hidden = true">
620
+ ```
621
+
622
+ #### <img width=13 height=13 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-greasemonkey/99f14247b2/assets/images/icons/square/with-symbol/green.svg" align="bottom"> Correct code
623
+
624
+ ```diff
625
+ - <button onclick="alert('hi')">Click</button>
626
+ + <button id="myButton">Click</button>
627
+ - <body onload="init()">
628
+ + <body>
629
+ - <img src="logo.png" onerror="this.hidden = true">
630
+ + <img src="logo.png" id="logo">
631
+
632
+ // popup.js
633
+ + document.getElementById('myButton').addEventListener('click', () => alert('hi'))
634
+ + document.addEventListener('DOMContentLoaded', init)
635
+ + document.getElementById('logo').addEventListener('error', event => event.target.hidden = true)
636
+ ```
637
+
638
+ #### When not to use it
639
+
640
+ If your HTML is a <a target="_blank" href="https://developer.chrome.com/docs/extensions/reference/manifest/sandbox">sandbox page</a> (where the CSP is intentionally relaxed). For individual handlers you still need, prefer `allowedAttributes` over disabling the rule.
641
+
642
+ #### Introduced in
643
+
644
+ <a target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.8.0">v2.8.0</a> (October 20, 2026)
645
+
646
+ #### See also
647
+
648
+ - [`no-inline-scripts`](#no-inline-scripts)
649
+ <a title="Only works in 'html/html' config block" href="#usage"><img height=14 alt="[HTML only]" src="https://img.shields.io/badge/HTML_only-a8d8ea?style=flat-square" align="middle"></a>
650
+ <a title="Accepts array w/ options" href="#no-inline-scripts-options"><img height=14 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
651
+ - [`no-remote-code`](#no-remote-code)
652
+ <a title="Included in recommended config" href="#usage"><img height=14 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
653
+ <a title="Included in security config" href="#usage"><img height=14 alt="[Security]" src="https://img.shields.io/badge/Security-e8357a?style=flat-square" align="middle"></a>
654
+ <a title="Accepts array w/ options" href="#no-remote-code-options"><img height=14 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
655
+ - <img height=12 src="https://www.google.com/s2/favicons?domain=developer.chrome.com&sz=64">&ensp;<a target="_blank" href="https://developer.chrome.com/docs/extensions/reference/manifest/content-security-policy">Chrome for Developers — `content_security_policy`</a>
656
+ - <img height=12 src="https://www.google.com/s2/favicons?domain=developer.mozilla.org&sz=64">&ensp;<a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy/script-src">MDN — CSP `script-src`</a>
657
+ - <img height=12 src="https://www.google.com/s2/favicons?domain=developer.mozilla.org&sz=64">&ensp;<a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener">MDN — `addEventListener()`</a>
658
+
659
+ <div align="center">
660
+
661
+ [Back to index ↑][epce-rules]
662
+
663
+ </div>
664
+
665
+ ---
666
+
667
+ </details>
668
+
669
+ <h3 id="no-inline-scripts">
670
+ <code>no-inline-scripts</code>
671
+ <a title="Introduced in latest minor release" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.8.0">
672
+ <img height=16 align="middle" src="https://api.iconify.design/mdi/sprout.svg?color=%234a4a4a"></a>
673
+ <a title="Only works in 'html/html' config block" href="#usage">
674
+ <img height=18 alt="[HTML only]" src="https://img.shields.io/badge/HTML_only-a8d8ea?style=flat-square" align="middle"></a>
675
+ <a title="Accepts array w/ options" href="#usage">
676
+ <img height=18 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
677
+ <a title="Copy rule URL" target="_blank"
678
+ href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23no-inline-scripts">
679
+ <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
680
+ </h3>
681
+
682
+ <details>
683
+
684
+ <summary>Disallows inline <code>&lt;script&gt;</code> bodies and remote <code>&lt;script src&gt;</code> in HTML (blocked by MV3's <code>script-src 'self'</code> at runtime).</summary>
685
+
686
+ <h4 id="no-inline-scripts-options">Options</h4>
687
+
688
+ - `allowedSrcPrefixes` (default `['chrome-extension://']`) – additional `src` prefixes to permit, as a single string or array <a title="Introduced in v2.8.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.8.0"><img height=14 alt="[Since v2.8.0]" src="https://img.shields.io/badge/since-v2.8.0-8a9199?style=flat-square" align="middle"></a>
689
+
690
+ #### <img width=13 height=13 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-greasemonkey/99f14247b2/assets/images/icons/square/with-symbol/gray.svg" align="bottom"> Incorrect code
691
+
692
+ ```diff
693
+ ! <script>alert('hi')</script>
694
+ ! <script src="https://cdn.example.com/lib.js"></script>
695
+ ! <script src="//cdn.example.com/lib.js"></script>
696
+ ! <script src="data:text/javascript;base64,YWxlcnQoMSk="></script>
697
+ ```
698
+
699
+ #### <img width=13 height=13 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-greasemonkey/99f14247b2/assets/images/icons/square/with-symbol/green.svg" align="bottom"> Correct code
700
+
701
+ ```diff
702
+ - <script>alert('hi')</script>
703
+ + <script src="popup.js"></script>
704
+ - <script src="https://cdn.example.com/lib.js"></script>
705
+ + <script src="./vendor/lib.js"></script>
706
+ - <script src="//cdn.example.com/lib.js"></script>
707
+ + <script type="module" src="popup.js"></script>
708
+ - <script src="data:text/javascript;base64,YWxlcnQoMSk="></script>
709
+ + <script src="chrome-extension://abc123/popup.js"></script>
710
+ ```
711
+
712
+ #### When not to use it
713
+
714
+ If your HTML is a <a target="_blank" href="https://developer.chrome.com/docs/extensions/reference/manifest/sandbox">sandbox page</a> (where the CSP is intentionally relaxed).
715
+
716
+ #### Introduced in
717
+
718
+ <a target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.8.0">v2.8.0</a> (October 20, 2026)
719
+
720
+ #### See also
721
+
722
+ - [`no-remote-code`](#no-remote-code)
723
+ <a title="Included in recommended config" href="#usage"><img height=14 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
724
+ <a title="Included in security config" href="#usage"><img height=14 alt="[Security]" src="https://img.shields.io/badge/Security-e8357a?style=flat-square" align="middle"></a>
725
+ <a title="Accepts array w/ options" href="#no-remote-code-options"><img height=14 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
726
+ - <img height=12 src="https://www.google.com/s2/favicons?domain=developer.chrome.com&sz=64">&ensp;<a target="_blank" href="https://developer.chrome.com/docs/extensions/reference/manifest/content-security-policy">Chrome for Developers — `content_security_policy`</a>
727
+ - <img height=12 src="https://www.google.com/s2/favicons?domain=developer.mozilla.org&sz=64">&ensp;<a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy/script-src">MDN — CSP `script-src`</a>
728
+ - <img height=12 src="https://www.google.com/s2/favicons?domain=developer.mozilla.org&sz=64">&ensp;<a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/script">MDN — `<script>` element</a>
729
+
730
+ <div align="center">
731
+
732
+ [Back to index ↑][epce-rules]
733
+
734
+ </div>
735
+
736
+ ---
737
+
738
+ </details>
739
+
740
+ <h3 id="no-host-page-selectors">
741
+ <code>no-host-page-selectors</code>
742
+ <a title="Only works in 'css/css' config block" href="#usage">
743
+ <img height=18 alt="[CSS only]" src="https://img.shields.io/badge/CSS_only-dcd6f7?style=flat-square" align="middle"></a>
744
+ <a title="Accepts array w/ options" href="#usage">
745
+ <img height=18 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
746
+ <a title="Copy rule URL" target="_blank"
747
+ href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23no-host-page-selectors">
748
+ <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
749
+ </h3>
750
+
751
+ <details>
752
+
753
+ <summary>Disallows host-page selectors (<code>html</code>, <code>body</code>, <code>:root</code>, <code>*</code>, bare elem types) in content-script CSS.</summary>
754
+
755
+ <h4 id="no-host-page-selectors-options">Options</h4>
756
+
757
+ - `allowedSelectors` (default `[]`) – selectors to explicitly allow (e.g. `['body.dark']`), as a single string or array <a title="Introduced in v2.7.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.7.0"><img height=14 alt="[Since v2.7.0]" src="https://img.shields.io/badge/since-v2.7.0-8a9199?style=flat-square" align="middle"></a>
758
+ - `disallowUniversal` (default `true`) – flag `*` <a title="Introduced in v2.7.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.7.0"><img height=14 alt="[Since v2.7.0]" src="https://img.shields.io/badge/since-v2.7.0-8a9199?style=flat-square" align="middle"></a>
759
+ - `disallowStructural` (default `true`) – flag `html`, `body`, `:root` <a title="Introduced in v2.7.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.7.0"><img height=14 alt="[Since v2.7.0]" src="https://img.shields.io/badge/since-v2.7.0-8a9199?style=flat-square" align="middle"></a>
760
+ - `disallowBareElements` (default `true`) – flag elem types (e.g. `div`, `a`) that lack `class`/`id`/`attribute` <a title="Introduced in v2.7.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.7.0"><img height=14 alt="[Since v2.7.0]" src="https://img.shields.io/badge/since-v2.7.0-8a9199?style=flat-square" align="middle"></a>
761
+
762
+ #### <img width=13 height=13 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-greasemonkey/99f14247b2/assets/images/icons/square/with-symbol/gray.svg" align="bottom"> Incorrect code
763
+
764
+ ```diff
765
+ ! * { box-sizing: border-box }
766
+
767
+ ! body { margin: 0 }
768
+ ! html { font-family: sans-serif }
769
+ ! button:hover { opacity: 0.8 }
770
+ ```
771
+
772
+ #### <img width=13 height=13 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-greasemonkey/99f14247b2/assets/images/icons/square/with-symbol/green.svg" align="bottom"> Correct code
773
+
774
+ ```diff
775
+ - * { box-sizing: border-box }
776
+ + :host { box-sizing: border-box }
777
+
778
+ - body { margin: 0 }
779
+ + :host { margin: 0 }
780
+ - html { font-family: sans-serif }
781
+ + :host { font-family: sans-serif }
782
+ - button:hover { opacity: 0.8 }
783
+ + .myext-button:hover { opacity: 0.8 }
784
+ ```
785
+
786
+ #### When not to use it
787
+
788
+ If you intentionally style the host page. For individual selectors you still need, prefer `allowedSelectors` over disabling the rule.
789
+
790
+ #### Introduced in
791
+
792
+ <a target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.7.0">v2.7.0</a> (October 17, 2026)
793
+
794
+ #### See also
795
+
796
+ - [`no-content-style-leak`](#no-content-style-leak)
797
+ <a title="Only included in strict config" href="#usage"><img height=14 alt="[Strict only]" src="https://img.shields.io/badge/Strict_only-ff8c42?style=flat-square" align="middle"></a>
798
+ - <img height=12 src="https://www.google.com/s2/favicons?domain=developer.mozilla.org&sz=64">&ensp;<a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/:host">MDN — `:host`</a>
799
+
800
+ <div align="center">
801
+
802
+ [Back to index ↑][epce-rules]
803
+
804
+ </div>
805
+
806
+ ---
807
+
808
+ </details>
809
+
425
810
  <h3 id="no-insecure-fetch">
426
811
  <code>no-insecure-fetch</code>
427
812
  <a title="Included in recommended config" href="#usage">
@@ -463,7 +848,10 @@ If you intentionally target HTTP endpoints.
463
848
 
464
849
  #### See also
465
850
 
851
+ - <img height=12 src="https://www.google.com/s2/favicons?domain=rfc-editor.org&sz=64">&ensp;<a target="_blank" href="https://www.rfc-editor.org/info/rfc9110/">RFC 9110 — HTTP Semantics</a>
466
852
  - <img height=12 src="https://www.google.com/s2/favicons?domain=developer.chrome.com&sz=64">&ensp;<a target="_blank" href="https://developer.chrome.com/docs/extensions/develop/concepts/network-requests">Chrome for Developers — Cross-origin network requests</a>
853
+ - <img height=12 src="https://www.google.com/s2/favicons?domain=developer.mozilla.org&sz=64">&ensp;<a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/open">MDN — `XMLHttpRequest.open()`</a>
854
+ - <img height=12 src="https://www.google.com/s2/favicons?domain=developer.mozilla.org&sz=64">&ensp;<a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Window/fetch">MDN — `fetch()`</a>
467
855
 
468
856
  <div align="center">
469
857
 
@@ -477,6 +865,8 @@ If you intentionally target HTTP endpoints.
477
865
 
478
866
  <h3 id="no-insecure-messaging">
479
867
  <code>no-insecure-messaging</code>
868
+ <a title="Introduced in v1.0.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v1.0.0">
869
+ <img height=18 align="middle" src="https://api.iconify.design/ph/flag-banner-fold-fill.svg?color=%234a4a4a"></a>
480
870
  <a title="Included in recommended config" href="#usage">
481
871
  <img height=18 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
482
872
  <a title="Included in security config" href="#usage">
@@ -635,6 +1025,8 @@ If your `_locales/` is externally populated at build time. If you target a Chrom
635
1025
 
636
1026
  <h3 id="no-invalid-permissions">
637
1027
  <code>no-invalid-permissions</code>
1028
+ <a title="Introduced in v1.0.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v1.0.0">
1029
+ <img height=18 align="middle" src="https://api.iconify.design/ph/flag-banner-fold-fill.svg?color=%234a4a4a"></a>
638
1030
  <a title="Included in recommended config" href="#usage">
639
1031
  <img height=18 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
640
1032
  <a title="Works in 'json/json' config block" href="#usage">
@@ -652,8 +1044,8 @@ If your `_locales/` is externally populated at build time. If you target a Chrom
652
1044
 
653
1045
  <h4 id="no-invalid-permissions-options">Options</h4>
654
1046
 
655
- - `target` (default `'mv3'`) – Chrome manifest version whose permissions to validate against (`'mv3'`, `'mv2'`) <a title="Introduced in v1.0.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v1.0.0"><img height=14 alt="[Since v1.0.0]" src="https://img.shields.io/badge/since-v1.0.0-6b8e6b?style=flat-square&labelColor=464646" align="middle"></a>
656
- - `allowedPermissions` (default `[]`) – additional permission names to allow beyond the built-in list, as a single string or array <a title="Introduced in v1.0.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v1.0.0"><img height=14 alt="[Since v1.0.0]" src="https://img.shields.io/badge/since-v1.0.0-6b8e6b?style=flat-square&labelColor=464646" align="middle"></a>
1047
+ - `target` (default `'mv3'`) – Chrome manifest version whose permissions to validate against (`'mv3'`, `'mv2'`) <a title="Introduced in v1.0.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v1.0.0"><img height=14 alt="[Since v1.0.0]" src="https://img.shields.io/badge/since-v1.0.0-8a9199?style=flat-square&labelColor=464646" align="middle"></a>
1048
+ - `allowedPermissions` (default `[]`) – additional permission names to allow beyond the built-in list, as a single string or array <a title="Introduced in v1.0.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v1.0.0"><img height=14 alt="[Since v1.0.0]" src="https://img.shields.io/badge/since-v1.0.0-8a9199?style=flat-square&labelColor=464646" align="middle"></a>
657
1049
 
658
1050
  #### <img width=13 height=13 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-greasemonkey/99f14247b2/assets/images/icons/square/with-symbol/gray.svg" align="bottom"> Incorrect code
659
1051
 
@@ -881,6 +1273,8 @@ If your `_locales/` is externally populated at build time.
881
1273
 
882
1274
  <h3 id="no-missing-permissions">
883
1275
  <code>no-missing-permissions</code>
1276
+ <a title="Introduced in v1.0.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v1.0.0">
1277
+ <img height=18 align="middle" src="https://api.iconify.design/ph/flag-banner-fold-fill.svg?color=%234a4a4a"></a>
884
1278
  <a title="Included in recommended config" href="#usage">
885
1279
  <img height=18 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
886
1280
  <a title="Copy rule URL" target="_blank"
@@ -1012,6 +1406,8 @@ If your paths are built at runtime.
1012
1406
 
1013
1407
  <h3 id="no-remote-code">
1014
1408
  <code>no-remote-code</code>
1409
+ <a title="Introduced in v1.0.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v1.0.0">
1410
+ <img height=18 align="middle" src="https://api.iconify.design/ph/flag-banner-fold-fill.svg?color=%234a4a4a"></a>
1015
1411
  <a title="Included in recommended config" href="#usage">
1016
1412
  <img height=18 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
1017
1413
  <a title="Included in security config" href="#usage">
@@ -1029,8 +1425,8 @@ If your paths are built at runtime.
1029
1425
 
1030
1426
  <h4 id="no-remote-code-options">Options</h4>
1031
1427
 
1032
- - `patterns` (default `['eval', 'new-function', 'string-timer', 'dynamic-import', 'remote-script-src', 'execute-script-url']`) – detection paths to enable, as a single string or array <a title="Introduced in v1.0.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v1.0.0"><img height=14 alt="[Since v1.0.0]" src="https://img.shields.io/badge/since-v1.0.0-6b8e6b?style=flat-square&labelColor=464646" align="middle"></a>
1033
- - `checkExecuteScriptClosures` (default `true`) – additionally flag <code>chrome.scripting.executeScript({ func })</code> bodies that capture outer-scope variables <a title="Introduced in v1.0.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v1.0.0"><img height=14 alt="[Since v1.0.0]" src="https://img.shields.io/badge/since-v1.0.0-6b8e6b?style=flat-square&labelColor=464646" align="middle"></a>
1428
+ - `patterns` (default `['dynamic-import', 'eval', 'execute-script-url', 'inline-event-handler', 'inline-script-body', 'new-function', 'remote-script-src', 'string-timer']`) – detection paths to enable, as a single string or array <a title="Introduced in v1.0.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v1.0.0"><img height=14 alt="[Since v1.0.0]" src="https://img.shields.io/badge/since-v1.0.0-8a9199?style=flat-square&labelColor=464646" align="middle"></a>
1429
+ - `checkExecuteScriptClosures` (default `true`) – additionally flag <code>chrome.scripting.executeScript({ func })</code> bodies that capture outer-scope variables <a title="Introduced in v1.0.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v1.0.0"><img height=14 alt="[Since v1.0.0]" src="https://img.shields.io/badge/since-v1.0.0-8a9199?style=flat-square&labelColor=464646" align="middle"></a>
1034
1430
 
1035
1431
  #### <img width=13 height=13 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-greasemonkey/99f14247b2/assets/images/icons/square/with-symbol/gray.svg" align="bottom"> Incorrect code
1036
1432
 
@@ -1064,12 +1460,224 @@ If you intentionally target forks w/ relaxed CSPs. For individual patterns you s
1064
1460
 
1065
1461
  #### See also
1066
1462
 
1067
- - [`require-mv3`](#require-mv3)
1068
- <a title="Included in recommended config" href="#usage"><img height=14 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
1069
- <a title="Works in 'json/json' config block" href="#usage"><img height=14 alt="[Manifest]" src="https://img.shields.io/badge/Manifest-999999?style=flat-square" align="middle"></a>
1070
- - [`valid-mv3-schema`](#valid-mv3-schema)
1463
+ - [`no-remote-urls`](#no-remote-urls)
1464
+ <a title="Only works in 'css/css' config block" href="#usage"><img height=14 alt="[CSS only]" src="https://img.shields.io/badge/CSS_only-dcd6f7?style=flat-square" align="middle"></a>
1465
+ <a title="Accepts array w/ options" href="#no-remote-urls-options"><img height=14 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
1466
+
1467
+ <div align="center">
1468
+
1469
+ [Back to index ↑][epce-rules]
1470
+
1471
+ </div>
1472
+
1473
+ ---
1474
+
1475
+ </details>
1476
+
1477
+ <h3 id="no-remote-objects">
1478
+ <code>no-remote-objects</code>
1479
+ <a title="Introduced in latest minor release" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.8.0">
1480
+ <img height=16 align="middle" src="https://api.iconify.design/mdi/sprout.svg?color=%234a4a4a"></a>
1481
+ <a title="Only works in 'html/html' config block" href="#usage">
1482
+ <img height=18 alt="[HTML only]" src="https://img.shields.io/badge/HTML_only-a8d8ea?style=flat-square" align="middle"></a>
1483
+ <a title="Accepts array w/ options" href="#usage">
1484
+ <img height=18 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
1485
+ <a title="Copy rule URL" target="_blank"
1486
+ href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23no-remote-objects">
1487
+ <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
1488
+ </h3>
1489
+
1490
+ <details>
1491
+
1492
+ <summary>Disallows remote <code>&lt;object data&gt;</code> and <code>&lt;embed src&gt;</code> in HTML (blocked by MV3's <code>object-src 'self'</code> at runtime).</summary>
1493
+
1494
+ <h4 id="no-remote-objects-options">Options</h4>
1495
+
1496
+ - `allowedPrefixes` (default `['chrome-extension://']`) – additional URL prefixes to permit, as a single string or array <a title="Introduced in v2.8.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.8.0"><img height=14 alt="[Since v2.8.0]" src="https://img.shields.io/badge/since-v2.8.0-8a9199?style=flat-square" align="middle"></a>
1497
+
1498
+ #### <img width=13 height=13 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-greasemonkey/99f14247b2/assets/images/icons/square/with-symbol/gray.svg" align="bottom"> Incorrect code
1499
+
1500
+ ```diff
1501
+ ! <object data="https://cdn.example.com/report.pdf"></object>
1502
+ ! <embed src="http://cdn.example.com/game.swf">
1503
+ ! <object data="//cdn.example.com/chart.svg"></object>
1504
+ ```
1505
+
1506
+ #### <img width=13 height=13 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-greasemonkey/99f14247b2/assets/images/icons/square/with-symbol/green.svg" align="bottom"> Correct code
1507
+
1508
+ ```diff
1509
+ - <object data="https://cdn.example.com/report.pdf"></object>
1510
+ + <object data="report.pdf"></object>
1511
+ - <embed src="http://cdn.example.com/game.swf">
1512
+ + <embed src="./vendor/game.swf">
1513
+ - <object data="//cdn.example.com/chart.svg"></object>
1514
+ + <object data="chrome-extension://abc123/chart.svg"></object>
1515
+ ```
1516
+
1517
+ #### When not to use it
1518
+
1519
+ If your HTML is a <a target="_blank" href="https://developer.chrome.com/docs/extensions/reference/manifest/sandbox">sandbox page</a> (where the CSP is intentionally relaxed).
1520
+
1521
+ #### Introduced in
1522
+
1523
+ <a target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.8.0">v2.8.0</a> (October 20, 2026)
1524
+
1525
+ #### See also
1526
+
1527
+ - [`no-inline-scripts`](#no-inline-scripts)
1528
+ <a title="Only works in 'html/html' config block" href="#usage"><img height=14 alt="[HTML only]" src="https://img.shields.io/badge/HTML_only-a8d8ea?style=flat-square" align="middle"></a>
1529
+ <a title="Accepts array w/ options" href="#no-inline-scripts-options"><img height=14 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
1530
+ - <img height=12 src="https://www.google.com/s2/favicons?domain=developer.chrome.com&sz=64">&ensp;<a target="_blank" href="https://developer.chrome.com/docs/extensions/reference/manifest/content-security-policy">Chrome for Developers — `content_security_policy`</a>
1531
+ - <img height=12 src="https://www.google.com/s2/favicons?domain=developer.mozilla.org&sz=64">&ensp;<a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy/object-src">MDN — CSP `object-src`</a>
1532
+ - <img height=12 src="https://www.google.com/s2/favicons?domain=developer.mozilla.org&sz=64">&ensp;<a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/object">MDN — `<object>` element</a>
1533
+ - <img height=12 src="https://www.google.com/s2/favicons?domain=developer.mozilla.org&sz=64">&ensp;<a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/embed">MDN — `<embed>` element</a>
1534
+
1535
+ <div align="center">
1536
+
1537
+ [Back to index ↑][epce-rules]
1538
+
1539
+ </div>
1540
+
1541
+ ---
1542
+
1543
+ </details>
1544
+
1545
+ <h3 id="no-remote-urls">
1546
+ <code>no-remote-urls</code>
1547
+ <a title="Only works in 'css/css' config block" href="#usage">
1548
+ <img height=18 alt="[CSS only]" src="https://img.shields.io/badge/CSS_only-dcd6f7?style=flat-square" align="middle"></a>
1549
+ <a title="Accepts array w/ options" href="#usage">
1550
+ <img height=18 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
1551
+ <a title="Copy rule URL" target="_blank"
1552
+ href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23no-remote-urls">
1553
+ <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
1554
+ </h3>
1555
+
1556
+ <details>
1557
+
1558
+ <summary>Disallows remote resources (<code>@import</code>, <code>@namespace</code>, <code>url()</code>) in extension CSS.</summary>
1559
+
1560
+ <h4 id="no-remote-urls-options">Options</h4>
1561
+
1562
+ - `allowedSchemes` (default `['blob', 'chrome-extension', 'data']`) – URL schemes to allow (beyond relative paths, which are always permitted), as a single string or array <a title="Introduced in v2.7.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.7.0"><img height=14 alt="[Since v2.7.0]" src="https://img.shields.io/badge/since-v2.7.0-8a9199?style=flat-square" align="middle"></a>
1563
+ - `patterns` (default `['at-import', 'url']`) – detection paths to enable, as a single string or array (`'at-import'`, `'url'`, `'namespace'`) <a title="Introduced in v2.7.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.7.0"><img height=14 alt="[Since v2.7.0]" src="https://img.shields.io/badge/since-v2.7.0-8a9199?style=flat-square" align="middle"></a>
1564
+
1565
+ #### <img width=13 height=13 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-greasemonkey/99f14247b2/assets/images/icons/square/with-symbol/gray.svg" align="bottom"> Incorrect code
1566
+
1567
+ ```diff
1568
+ ! @import url("https://cdn.jsdelivr.net/npm/normalize.css@8.0.1/normalize.css");
1569
+ ! @import "https://cdn.example.com/style.css";
1570
+
1571
+ ! .panel { background: url("https://cdn.example.com/bg.png") }
1572
+ ! .cursor-area { cursor: url("//cdn.example.com/c.cur"), auto }
1573
+
1574
+ ! @font-face { font-family: Lato; src: url("https://fonts.gstatic.com/s/lato/v24/S6uyw4BMUTPHjx4wXiWtFCc.woff2") }
1575
+ ```
1576
+
1577
+ #### <img width=13 height=13 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-greasemonkey/99f14247b2/assets/images/icons/square/with-symbol/green.svg" align="bottom"> Correct code
1578
+
1579
+ ```diff
1580
+ - @import url("https://cdn.jsdelivr.net/npm/normalize.css@8.0.1/normalize.css");
1581
+ + @import url("./normalize.css");
1582
+ - @import "https://cdn.example.com/style.css";
1583
+ + @import "./reset.css";
1584
+
1585
+ - .panel { background: url("https://cdn.example.com/bg.png") }
1586
+ + .panel { background: url("/bg.png") }
1587
+ - .cursor-area { cursor: url("//cdn.example.com/c.cur"), auto }
1588
+ + .cursor-area { cursor: url("cursors/pointer.cur"), auto }
1589
+
1590
+ - @font-face { font-family: Lato; src: url("https://fonts.gstatic.com/s/lato/v24/S6uyw4BMUTPHjx4wXiWtFCc.woff2") }
1591
+ + @font-face { font-family: Lato; src: url("fonts/lato-v24.woff2") }
1592
+ ```
1593
+
1594
+ #### When not to use it
1595
+
1596
+ If you intentionally reference remote stylesheets, fonts, or images (e.g. Google Fonts, CDN assets). For individual schemes you still need, prefer `allowedSchemes` over disabling the rule.
1597
+
1598
+ #### Introduced in
1599
+
1600
+ <a target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.7.0">v2.7.0</a> (October 17, 2026)
1601
+
1602
+ #### See also
1603
+
1604
+ - [`no-remote-code`](#no-remote-code)
1071
1605
  <a title="Included in recommended config" href="#usage"><img height=14 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
1072
- <a title="Works in 'json/json' config block" href="#usage"><img height=14 alt="[Manifest]" src="https://img.shields.io/badge/Manifest-999999?style=flat-square" align="middle"></a>
1606
+ <a title="Included in security config" href="#usage"><img height=14 alt="[Security]" src="https://img.shields.io/badge/Security-e8357a?style=flat-square" align="middle"></a>
1607
+ <a title="Accepts array w/ options" href="#no-remote-code-options"><img height=14 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
1608
+ - <img height=12 src="https://www.google.com/s2/favicons?domain=developer.chrome.com&sz=64">&ensp;<a target="_blank" href="https://developer.chrome.com/docs/extensions/reference/manifest/content-security-policy">Chrome for Developers — `content_security_policy`</a>
1609
+ - <img height=12 src="https://www.google.com/s2/favicons?domain=developer.chrome.com&sz=64">&ensp;<a target="_blank" href="https://developer.chrome.com/docs/extensions/reference/manifest/web-accessible-resources">Chrome for Developers — `web_accessible_resources`</a>
1610
+
1611
+ <div align="center">
1612
+
1613
+ [Back to index ↑][epce-rules]
1614
+
1615
+ </div>
1616
+
1617
+ ---
1618
+
1619
+ </details>
1620
+
1621
+ <h3 id="no-scrollbar-styling">
1622
+ <code>no-scrollbar-styling</code>
1623
+ <a title="Only works in 'css/css' config block" href="#usage">
1624
+ <img height=18 alt="[CSS only]" src="https://img.shields.io/badge/CSS_only-dcd6f7?style=flat-square" align="middle"></a>
1625
+ <a title="Accepts array w/ options" href="#usage">
1626
+ <img height=18 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
1627
+ <a title="Copy rule URL" target="_blank"
1628
+ href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23no-scrollbar-styling">
1629
+ <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
1630
+ </h3>
1631
+
1632
+ <details>
1633
+
1634
+ <summary>Disallows scrollbar pseudo-elements (e.g. <code>::-webkit-scrollbar</code>) on unscoped selectors in content-script CSS.</summary>
1635
+
1636
+ <h4 id="no-scrollbar-styling-options">Options</h4>
1637
+
1638
+ - `allowedSelectors` (default `[]`) – selectors to explicitly allow (e.g. `['body::-webkit-scrollbar']`), as a single string or array <a title="Introduced in v2.7.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.7.0"><img height=14 alt="[Since v2.7.0]" src="https://img.shields.io/badge/since-v2.7.0-8a9199?style=flat-square" align="middle"></a>
1639
+
1640
+ #### <img width=13 height=13 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-greasemonkey/99f14247b2/assets/images/icons/square/with-symbol/gray.svg" align="bottom"> Incorrect code
1641
+
1642
+ ```diff
1643
+ ! ::-webkit-scrollbar { width: 8px }
1644
+ ! ::-webkit-scrollbar-thumb { background: #888 }
1645
+
1646
+ ! *::-webkit-scrollbar { width: 8px }
1647
+ ! body::-webkit-scrollbar { width: 8px }
1648
+ ! html::-webkit-scrollbar { width: 8px }
1649
+ ```
1650
+
1651
+ #### <img width=13 height=13 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-greasemonkey/99f14247b2/assets/images/icons/square/with-symbol/green.svg" align="bottom"> Correct code
1652
+
1653
+ ```diff
1654
+ - ::-webkit-scrollbar { width: 8px }
1655
+ + .myext-panel::-webkit-scrollbar { width: 8px }
1656
+ - ::-webkit-scrollbar-thumb { background: #888 }
1657
+ + .myext-panel::-webkit-scrollbar-thumb { background: #888 }
1658
+
1659
+ - *::-webkit-scrollbar { width: 8px }
1660
+ + .myext-root::-webkit-scrollbar { width: 8px }
1661
+ - body::-webkit-scrollbar { width: 8px }
1662
+ + .myext-panel::-webkit-scrollbar { width: 8px }
1663
+ - html::-webkit-scrollbar { width: 8px }
1664
+ + .myext-panel::-webkit-scrollbar { width: 8px }
1665
+ ```
1666
+
1667
+ #### When not to use it
1668
+
1669
+ If you intentionally theme the host page's scrollbar. For individual selectors you still need, prefer `allowedSelectors` over disabling the rule.
1670
+
1671
+ #### Introduced in
1672
+
1673
+ <a target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.7.0">v2.7.0</a> (October 17, 2026)
1674
+
1675
+ #### See also
1676
+
1677
+ - [`no-host-page-selectors`](#no-host-page-selectors)
1678
+ <a title="Only works in 'css/css' config block" href="#usage"><img height=14 alt="[CSS only]" src="https://img.shields.io/badge/CSS_only-dcd6f7?style=flat-square" align="middle"></a>
1679
+ <a title="Accepts array w/ options" href="#no-host-page-selectors-options"><img height=14 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
1680
+ - <img height=12 src="https://www.google.com/s2/favicons?domain=developer.mozilla.org&sz=64">&ensp;<a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/::-webkit-scrollbar">MDN — `::-webkit-scrollbar`</a>
1073
1681
 
1074
1682
  <div align="center">
1075
1683
 
@@ -1295,6 +1903,8 @@ If your i18n keys are referenced dynamically.
1295
1903
 
1296
1904
  <h3 id="no-unused-permissions">
1297
1905
  <code>no-unused-permissions</code>
1906
+ <a title="Introduced in v1.0.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v1.0.0">
1907
+ <img height=18 align="middle" src="https://api.iconify.design/ph/flag-banner-fold-fill.svg?color=%234a4a4a"></a>
1298
1908
  <a title="Included in recommended config" href="#usage">
1299
1909
  <img height=18 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
1300
1910
  <a title="Works in 'json/json' config block" href="#usage">
@@ -1373,14 +1983,13 @@ If you access the granted API through an alias or computed property rather than
1373
1983
 
1374
1984
  <summary>Requires a license file.</summary>
1375
1985
 
1376
- #### <img width=13 height=13 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-greasemonkey/99f14247b2/assets/images/icons/square/with-symbol/gray.svg" align="bottom"> Incorrect directory structure
1986
+ #### <img width=13 height=13 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-greasemonkey/99f14247b2/assets/images/icons/square/with-symbol/gray.svg" align="bottom"> Incorrect dir structure
1377
1987
 
1378
1988
  ```diff
1379
1989
  /extension/manifest.json
1380
- !
1381
1990
  ```
1382
1991
 
1383
- #### <img width=13 height=13 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-greasemonkey/99f14247b2/assets/images/icons/square/with-symbol/green.svg" align="bottom"> Correct directory structure
1992
+ #### <img width=13 height=13 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-greasemonkey/99f14247b2/assets/images/icons/square/with-symbol/green.svg" align="bottom"> Correct dir structure
1384
1993
 
1385
1994
  ```diff
1386
1995
  /extension/manifest.json
@@ -1414,6 +2023,8 @@ If you intentionally omit a license, or it's injected at build time.
1414
2023
 
1415
2024
  <h3 id="require-mv3">
1416
2025
  <code>require-mv3</code>
2026
+ <a title="Introduced in v1.0.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v1.0.0">
2027
+ <img height=18 align="middle" src="https://api.iconify.design/ph/flag-banner-fold-fill.svg?color=%234a4a4a"></a>
1417
2028
  <a title="Included in recommended config" href="#usage">
1418
2029
  <img height=18 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
1419
2030
  <a title="Works in 'json/json' config block" href="#usage">
@@ -1770,6 +2381,8 @@ If your icons are injected at build time, or you target browsers that support SV
1770
2381
 
1771
2382
  <h3 id="valid-mv3-schema">
1772
2383
  <code>valid-mv3-schema</code>
2384
+ <a title="Introduced in v1.0.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v1.0.0">
2385
+ <img height=18 align="middle" src="https://api.iconify.design/ph/flag-banner-fold-fill.svg?color=%234a4a4a"></a>
1773
2386
  <a title="Included in recommended config" href="#usage">
1774
2387
  <img height=18 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
1775
2388
  <a title="Works in 'json/json' config block" href="#usage">
@@ -1839,6 +2452,8 @@ If you intentionally target MV2 for a browser that still supports it (e.g. Firef
1839
2452
 
1840
2453
  <h3 id="valid-service-worker">
1841
2454
  <code>valid-service-worker</code>
2455
+ <a title="Introduced in v1.0.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v1.0.0">
2456
+ <img height=18 align="middle" src="https://api.iconify.design/ph/flag-banner-fold-fill.svg?color=%234a4a4a"></a>
1842
2457
  <a title="Included in recommended config" href="#usage">
1843
2458
  <img height=18 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
1844
2459
  <a title="Accepts array w/ options" href="#usage">
@@ -2075,8 +2690,8 @@ If you don't care about version format consistency, or your version is injected
2075
2690
 
2076
2691
  ## <img height=30 width=27 align="top" src="https://api.iconify.design/ic/baseline-account-balance.svg?color=%232b2b2a"> License
2077
2692
 
2078
- <a target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/src/branch/main/docs/LICENSE.md">
2079
- <img height=80 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-greasemonkey/9e820e5d51/assets/images/logos/mit-license/red-pixelated.png"></a>
2693
+ <a href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/src/branch/main/docs/LICENSE.md">
2694
+ <img height=88 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-chrome-extensions/d79e1db7e2/assets/images/banners/mit-license/banner.png"></a>
2080
2695
  <br><br>
2081
2696
 
2082
2697
  <details>