lab_work3
This commit is contained in:
261
node_modules/eslint-plugin-html/CHANGELOG.md
generated
vendored
Normal file
261
node_modules/eslint-plugin-html/CHANGELOG.md
generated
vendored
Normal file
@@ -0,0 +1,261 @@
|
||||
2024-09-21 v8.1.2
|
||||
|
||||
- Fix sourceType config for ESLint 9
|
||||
- Don't require espree directly #271
|
||||
|
||||
2024-04-22 v8.1.1
|
||||
|
||||
- Fix compatibility with @eslint/config-inspector #267
|
||||
- Drop Jest #266
|
||||
- Update dependencies
|
||||
|
||||
2024-04-10 v8.1.0
|
||||
|
||||
- Introduce the `html/ignore-tags-without-type` setting #249
|
||||
- Fix files with unknown extensions being considered as XML #257
|
||||
- Fix plugin applied even if it's not in the configuration #263
|
||||
- Update dependencies
|
||||
|
||||
2024-02-09 v8.0.0
|
||||
|
||||
- **Breaking: drop Node 12 and 14 support**
|
||||
- ESLint 9 support (flat config)
|
||||
|
||||
2022-07-25 v7.1.0
|
||||
|
||||
- Add support for @html-eslint and @angular-eslint/template plugins #176
|
||||
|
||||
2022-07-18 v7.0.0
|
||||
|
||||
- **Breaking: drop Node 10 support**
|
||||
- Allow temporarily disabling ESLint with HTML comments
|
||||
- Allow configuring which script tag names should be considered as JavaScript #137
|
||||
|
||||
2021-09-20 v6.2.0
|
||||
|
||||
- Update dependencies
|
||||
- Fix support for ESLint v8.0.0-beta.2
|
||||
- Add .riot extension #146
|
||||
|
||||
2021-03-08 v6.1.2
|
||||
|
||||
- Update htmlparser2 #141
|
||||
- Update dependencies
|
||||
|
||||
2020-11-11 v6.1.1
|
||||
|
||||
- Update dependencies
|
||||
- Move from travis to github actions
|
||||
|
||||
2020-09-06 v6.1.0
|
||||
|
||||
- Allow dots in extensions #127
|
||||
|
||||
2020-08-08 v6.0.3
|
||||
|
||||
- Update dependencies
|
||||
|
||||
2020-04-15 v6.0.2
|
||||
|
||||
- Remove npm-shrinkwrap.json from the npm package #125
|
||||
|
||||
2020-04-05 v6.0.1 (the 5th anniversary release)
|
||||
|
||||
- Update dependencies
|
||||
- Run CI against eslint@next
|
||||
- Add eslint-plugin-php-markup reference to the README
|
||||
|
||||
2019-06-26 v6.0.0 (the 666 release)
|
||||
|
||||
- **Breaking: drop Node 6 support**
|
||||
- Fix support for ESLint v6
|
||||
|
||||
2019-05-13 v5.0.5
|
||||
|
||||
- Fix support for ESLint v6.0.0-alpha.1 (again)
|
||||
- Improved integration tests
|
||||
|
||||
2019-05-12 v5.0.4
|
||||
|
||||
- Fix support for ESLint v6.0.0-alpha.1 #117
|
||||
|
||||
2019-02-02 v5.0.3
|
||||
|
||||
- Fix support for `parserOptions.ecmaFeatures.globalReturn: true` while sharing scope between multiple script tags
|
||||
|
||||
2019-02-02 v5.0.2
|
||||
|
||||
- Fix support for the --report-unused-disabled-directives option #111
|
||||
|
||||
2019-02-02 v5.0.1
|
||||
|
||||
- Fix compatibility with ESLint 5.13.0
|
||||
- Update dependencies
|
||||
|
||||
2018-11-11 v5.0.0
|
||||
|
||||
- **Breaking: drop Node 4 support**
|
||||
- **Breaking: don't lint .vue files by default**
|
||||
- Update dependencies
|
||||
|
||||
2018-09-22 v4.0.6
|
||||
|
||||
- Ignore script tags with a `src` attribute #102
|
||||
- More detailed error reporting
|
||||
|
||||
2018-06-20 v4.0.5
|
||||
|
||||
- Fix typo regression from v4.0.4
|
||||
|
||||
2018-06-20 v4.0.4
|
||||
|
||||
- Request detailed informations when ESLint is not found
|
||||
|
||||
2018-04-11 v4.0.3
|
||||
|
||||
- Prevent patching ESLint multiple times #89
|
||||
|
||||
2018-01-24 v4.0.2
|
||||
|
||||
- Fix compatibility with tslint #85
|
||||
|
||||
2017-11-22 v4.0.1
|
||||
|
||||
- Fix processing files after processing a HTML file without script tag #82
|
||||
|
||||
2017-11-12 v4.0.0
|
||||
|
||||
- **Breaking: drop ESLint < 4.7 support**
|
||||
- **Breaking: Non-module script tags are sharing the global scope** #66
|
||||
- Lint script tags with `type="module"` by default
|
||||
|
||||
2017-09-16 v3.2.2
|
||||
|
||||
- Fix ESLint 4.7 support
|
||||
|
||||
2017-09-03 v3.2.1
|
||||
|
||||
- Fix ESLint 4.6 support #77
|
||||
|
||||
2017-08-12 v3.2.0
|
||||
|
||||
- improve compatibility with the `prettier` plugin by ignoring the first empty script line #76
|
||||
- fix compatibility with the `eslint-comments` plugin #70
|
||||
- add some _Troubleshooting_ documentation about linting template markup and Vue files
|
||||
|
||||
2017-07-18 v3.1.1
|
||||
|
||||
- Fix node 4 support #71 #72
|
||||
|
||||
2017-07-11 v3.1.0
|
||||
|
||||
- Remap messages "source" property to fix custom formatters support #69
|
||||
|
||||
2017-06-12 v3.0.0 [migration guide](MIGRATION_TO_V3.md)
|
||||
|
||||
- **Breaking: lint script tags separately** #49 #55 #56
|
||||
- ESLint 4 support #57
|
||||
- Support nested settings in a "html" object #58
|
||||
|
||||
2017-05-06 v2.0.3
|
||||
|
||||
- No change, new version to work around a publish issue
|
||||
|
||||
2017-05-06 v2.0.2
|
||||
|
||||
- Support self-closing script tags in XHTML #52
|
||||
- Fix tests for ESLint 4.0.0-alpha.{0-2}
|
||||
|
||||
2017-02-16 v2.0.1
|
||||
|
||||
- Support for empty filenames #48
|
||||
- Support for empty files #46
|
||||
|
||||
2017-01-25 v2.0.0
|
||||
|
||||
- **Breaking: drop `html/xml-mode` setting**
|
||||
- `eslint --fix` support #23
|
||||
- Allow configuring HTML and XML extensions via ESLint config
|
||||
- Allow configuring JS MIME types via ESLint config
|
||||
- Report correct end locations of error messages
|
||||
- Report correct fix ranges of error messages
|
||||
|
||||
2016-11-18 v1.7.0
|
||||
|
||||
- Ignore all warnings for non-script lines #37
|
||||
|
||||
2016-11-05 v1.6.0
|
||||
|
||||
- Patch all loaded eslint packages #28
|
||||
|
||||
2016-10-23 v1.5.5
|
||||
|
||||
- Fix typo in handlebars extension #36
|
||||
|
||||
2016-10-22 v1.5.4
|
||||
|
||||
- Support `.nunjucks` files #35
|
||||
|
||||
2016-09-24 v1.5.3
|
||||
|
||||
- Fix tests for ESLint 3.6.0 #32
|
||||
- Support `.we` files #30
|
||||
|
||||
2016-08-06 v1.5.2
|
||||
|
||||
- Laxer way to retrieve the eslint package #27
|
||||
- Support `.erb` files #26
|
||||
- Support `.tag` files #25
|
||||
|
||||
2016-05-22 v1.5.1
|
||||
|
||||
- Republish v1.5.0 on NPM, files were missing because of npm/npm#5082
|
||||
|
||||
2016-05-22 v1.5.0
|
||||
|
||||
- Support `.handlebars` files
|
||||
- Introduce the `html/xml-mode` setting and parse XML files as XML #20
|
||||
- Support `.twig` files #21
|
||||
- Support the `text/ecmascript-6` mime type #17
|
||||
|
||||
2016-02-16 v1.4.0
|
||||
|
||||
- Support `.php` files
|
||||
|
||||
2016-01-27 v1.3.0
|
||||
|
||||
- Fix crlf newlines support #16
|
||||
- Introduce the `html/report-bad-indent` setting
|
||||
- Introduce the `html/indent` setting
|
||||
- Support more standard JS MIME types #15
|
||||
|
||||
2016-01-15 v1.2.0
|
||||
|
||||
- Support the `text/babel` mime type
|
||||
- Support `.mustache` files #11
|
||||
|
||||
2015-11-02 v1.1.0
|
||||
|
||||
- Stop non-JS lines breaking `no-multiple-empty-lines` #8
|
||||
|
||||
2015-08-22 v1.0.4
|
||||
|
||||
- Check if there is some lines before striping the last line spaces #7
|
||||
|
||||
2015-08-17 v1.0.3
|
||||
|
||||
- Support `.hbs` files
|
||||
|
||||
2015-06-30 v1.0.2
|
||||
|
||||
- Support `.vue` files #4
|
||||
|
||||
2015-04-18 v1.0.1
|
||||
|
||||
- Fix space eating issue
|
||||
- Introduce unit tests
|
||||
|
||||
2015-04-05 v1.0.0
|
||||
|
||||
- Add README
|
||||
- Initial commit
|
||||
13
node_modules/eslint-plugin-html/LICENSE
generated
vendored
Normal file
13
node_modules/eslint-plugin-html/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
Copyright (c) 2016, Benoît Zugmeyer
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
511
node_modules/eslint-plugin-html/README.md
generated
vendored
Normal file
511
node_modules/eslint-plugin-html/README.md
generated
vendored
Normal file
@@ -0,0 +1,511 @@
|
||||
<div align="center">
|
||||
<img src="media/logo.svg" width="150" height="150">
|
||||
<h1>eslint-plugin-html</h1>
|
||||
<a href="https://www.npmjs.com/package/eslint-plugin-html"><img alt="NPM version" src="https://img.shields.io/npm/v/eslint-plugin-html"></a>
|
||||
<a href="https://github.com/BenoitZugmeyer/eslint-plugin-html/actions/workflows/tests.yml"><img alt="Tests Status" src="https://img.shields.io/github/actions/workflow/status/BenoitZugmeyer/eslint-plugin-html/tests.yml"></a>
|
||||
<p>A <a href="http://eslint.org">ESLint</a> plugin to lint and fix inline scripts contained in HTML files.</p>
|
||||
</div>
|
||||
|
||||
- [Usage](#usage)
|
||||
- [Disabling ESLint](#disabling-eslint)
|
||||
- [Linting HTML](#linting-html)
|
||||
- [Multiple scripts tags in a HTML file](#multiple-scripts-tags-in-a-html-file)
|
||||
- [History](#history)
|
||||
- [XML support](#xml-support)
|
||||
- [Settings](#settings)
|
||||
- [`html/html-extensions`](#htmlhtml-extensions)
|
||||
- [`html/xml-extensions`](#htmlxml-extensions)
|
||||
- [`html/indent`](#htmlindent)
|
||||
- [`html/report-bad-indent`](#htmlreport-bad-indent)
|
||||
- [`html/javascript-tag-names`](#htmljavascript-tag-names)
|
||||
- [`html/javascript-mime-types`](#htmljavascript-mime-types)
|
||||
- [`html/ignore-tags-without-type`](#htmlignore-tags-without-type)
|
||||
- [Troubleshooting](#troubleshooting)
|
||||
- [No file linted when running `eslint` on a directory](#no-file-linted-when-running-eslint-on-a-directory)
|
||||
- [Linting templates (or PHP)](#linting-templates-or-php)
|
||||
- [Linting VUE files](#linting-vue-files)
|
||||
- [Migration from older versions](#migration-from-older-versions)
|
||||
- [To v4](#to-v4)
|
||||
- [To v3](#to-v3)
|
||||
- [Credits](#credits)
|
||||
|
||||
## Usage
|
||||
|
||||
Simply install via `npm install --save-dev eslint-plugin-html` and add the plugin to your ESLint
|
||||
configuration. See
|
||||
[ESLint documentation](http://eslint.org/docs/user-guide/configuring#configuring-plugins).
|
||||
|
||||
<details open>
|
||||
<summary>Example with ESLint 9 and above (flat config)</summary>
|
||||
|
||||
```javascript
|
||||
import html from "eslint-plugin-html"
|
||||
|
||||
export default [
|
||||
{
|
||||
files: ["**/*.html"],
|
||||
plugins: { html },
|
||||
},
|
||||
]
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Example with ESLint 8 and below</summary>
|
||||
|
||||
```json
|
||||
{
|
||||
"plugins": ["html"]
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## Disabling ESLint
|
||||
|
||||
To temporarily disable ESLint, use the `<!-- eslint-disable -->` HTML comment. Re-enable it with
|
||||
`<!-- eslint enable -->`. Example:
|
||||
|
||||
```html
|
||||
<!-- eslint-disable -->
|
||||
<script>
|
||||
var foo = 1
|
||||
</script>
|
||||
<!-- eslint-enable -->
|
||||
```
|
||||
|
||||
To disable ESLint for the next script tag only, use the `<!-- eslint-disable-next-script -->` HTML
|
||||
comment. Example:
|
||||
|
||||
```html
|
||||
<!-- eslint-disable-next-script -->
|
||||
<script>
|
||||
var foo = 1
|
||||
</script>
|
||||
```
|
||||
|
||||
Disabled script tags are completely ignored: their content will not be parsed as JavaScript. You can
|
||||
use this to disable script tags containing template syntax.
|
||||
|
||||
## Linting HTML
|
||||
|
||||
This plugin focuses on applying ESLint rules on inline scripts contained in HTML. It does not
|
||||
provide any rule related to HTML. For that, you can use other plugins like
|
||||
[`@eslint-html`](https://yeonjuan.github.io/html-eslint/) or
|
||||
[@angular-eslint](https://github.com/angular-eslint/angular-eslint). `eslint-plugin-html` is
|
||||
compatible with those plugins and can be used along them.
|
||||
|
||||
## Multiple scripts tags in a HTML file
|
||||
|
||||
When linting a HTML with multiple script tags, this plugin tries to emulate the browser behavior by
|
||||
sharing the global scope between scripts by default. This behavior doesn't apply to "module"
|
||||
scripts (ie: `<script type="module">` and most transpiled code), where [each script tag gets its own
|
||||
top-level scope](http://exploringjs.com/es6/ch_modules.html#_modules).
|
||||
|
||||
ESLint has already [an
|
||||
option](https://eslint.org/docs/user-guide/configuring#specifying-parser-options) to tell the parser
|
||||
if the script are modules. `eslint-plugin-html` will use this option as well to know if the scopes
|
||||
should be shared (the default) or not. To change this, just set it in your ESLint configuration:
|
||||
|
||||
<details open>
|
||||
<summary>ESLint 9 and above (flat config)</summary>
|
||||
|
||||
```javascript
|
||||
export default [
|
||||
{
|
||||
// ...
|
||||
languageOptions: {
|
||||
sourceType: "module",
|
||||
},
|
||||
},
|
||||
]
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>ESLint 8 and below</summary>
|
||||
|
||||
```json
|
||||
{
|
||||
"parserOptions": {
|
||||
"sourceType": "module"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
To illustrate this behavior, consider this HTML extract:
|
||||
|
||||
```html
|
||||
<script>
|
||||
var foo = 1
|
||||
</script>
|
||||
|
||||
<script>
|
||||
alert(foo)
|
||||
</script>
|
||||
```
|
||||
|
||||
This is perfectly valid by default, and the ESLint rules `no-unused-vars` and `no-undef` shouldn't
|
||||
complain. But if those scripts are considerated as ES modules, `no-unused-vars` should report an
|
||||
error in the first script, and `no-undef` should report an error in the second script.
|
||||
|
||||
### History
|
||||
|
||||
In `eslint-plugin-html` v1 and v2, script code were concatenated and linted in a single pass, so
|
||||
the scope were always shared. This caused [some issues](MIGRATION_TO_V3.md), so in v3 all scripts
|
||||
were linted separately, and scopes were never shared. In v4, the plugin still lint scripts
|
||||
separately, but makes sure global variables are declared and used correctly in the non-module case.
|
||||
|
||||
## XML support
|
||||
|
||||
This plugin parses HTML and XML markup slightly differently, mainly when considering `CDATA`
|
||||
sections:
|
||||
|
||||
- in XML, any data inside a `CDATA` section will be considered as raw text (not XML) and the `CDATA`
|
||||
delimiter will be droped ;
|
||||
- in HTML, there is no such thing for `<script>` tags: the `CDATA` delimiter is considered as normal
|
||||
text and thus, part of the script.
|
||||
|
||||
## Settings
|
||||
|
||||
> Note: all settings can be written either as `"html/key": value` or in a nested object `"html": { "key": value }`
|
||||
|
||||
### `html/html-extensions`
|
||||
|
||||
By default, this plugin will only consider files ending with those extensions as HTML: `.erb`,
|
||||
`.handlebars`, `.hbs`, `.htm`, `.html`, `.mustache`, `.nunjucks`, `.php`, `.tag`, `.twig`, `.we`.
|
||||
You can set your own list of HTML extensions by using this setting. Example:
|
||||
|
||||
<details open>
|
||||
<summary>ESLint 9 and above (flat config)</summary>
|
||||
|
||||
```javascript
|
||||
export default [
|
||||
{
|
||||
files: ["**/*.html", "**/*.we"],
|
||||
plugins: { html },
|
||||
settings: {
|
||||
"html/html-extensions": [".html", ".we"], // consider .html and .we files as HTML
|
||||
},
|
||||
},
|
||||
]
|
||||
```
|
||||
|
||||
Note: you need to specify extensions twice, which is not ideal. This should be imporved in the
|
||||
future.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>ESLint 8 and below</summary>
|
||||
|
||||
```json
|
||||
{
|
||||
"plugins": ["html"],
|
||||
"settings": {
|
||||
"html/html-extensions": [".html", ".we"] // consider .html and .we files as HTML
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### `html/xml-extensions`
|
||||
|
||||
By default, this plugin will only consider files ending with those extensions as XML: `.xhtml`,
|
||||
`.xml`. You can set your own list of XML extensions by using this setting. Example:
|
||||
|
||||
<details open>
|
||||
<summary>ESLint 9 and above (flat config)</summary>
|
||||
|
||||
```javascript
|
||||
export default [
|
||||
{
|
||||
files: ["**/*.html"],
|
||||
plugins: { html },
|
||||
settings: {
|
||||
"html/xtml-extensions": [".html"], // consider .html files as XML
|
||||
},
|
||||
},
|
||||
]
|
||||
```
|
||||
|
||||
Note: you need to specify extensions twice, which is not ideal. This should be imporved in the
|
||||
future.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>ESLint 8 and below</summary>
|
||||
|
||||
```json
|
||||
{
|
||||
"plugins": ["html"],
|
||||
"settings": {
|
||||
"html/xml-extensions": [".html"] // consider .html files as XML
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### `html/indent`
|
||||
|
||||
By default, the code between `<script>` tags is dedented according to the first non-empty line. The
|
||||
setting `html/indent` allows to ensure that every script tags follow an uniform indentation. Like
|
||||
the `indent` rule, you can pass a number of spaces, or `"tab"` to indent with one tab. Prefix this
|
||||
value with a `+` to be relative to the `<script>` tag indentation. Example:
|
||||
|
||||
<details open>
|
||||
<summary>ESLint 9 and above (flat config)</summary>
|
||||
|
||||
```javascript
|
||||
export default [
|
||||
{
|
||||
files: ["**/*.html"],
|
||||
plugins: { html },
|
||||
settings: {
|
||||
"html/indent": "0", // code should start at the beginning of the line (no initial indentation).
|
||||
"html/indent": "+2", // indentation is the <script> indentation plus two spaces.
|
||||
"html/indent": "tab", // indentation is one tab at the beginning of the line.
|
||||
},
|
||||
},
|
||||
]
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>ESLint 8 and below</summary>
|
||||
|
||||
```json
|
||||
{
|
||||
"plugins": ["html"],
|
||||
"settings": {
|
||||
"html/indent": "0", // code should start at the beginning of the line (no initial indentation).
|
||||
"html/indent": "+2", // indentation is the <script> indentation plus two spaces.
|
||||
"html/indent": "tab" // indentation is one tab at the beginning of the line.
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### `html/report-bad-indent`
|
||||
|
||||
By default, this plugin won't warn if it encounters a problematic indentation (ex: a line is under
|
||||
indented). If you want to make sure the indentation is correct, use the `html/report-bad-indent` in
|
||||
conjunction with the `indent` rule. Pass `"warn"` or `1` to display warnings, `"error"` or `2` to
|
||||
display errors. Example:
|
||||
|
||||
<details open>
|
||||
<summary>ESLint 9 and above (flat config)</summary>
|
||||
|
||||
```javascript
|
||||
export default [
|
||||
{
|
||||
files: ["**/*.html"],
|
||||
plugins: { html },
|
||||
settings: {
|
||||
"html/report-bad-indent": "error",
|
||||
},
|
||||
},
|
||||
]
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>ESLint 8 and below</summary>
|
||||
|
||||
```json
|
||||
{
|
||||
"plugins": ["html"],
|
||||
"settings": {
|
||||
"html/report-bad-indent": "error"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### `html/javascript-tag-names`
|
||||
|
||||
By default, the code between `<script>` tags is considered as JavaScript. You can customize which
|
||||
tags should be considered JavaScript by providing one or multiple tag names.
|
||||
|
||||
Example:
|
||||
|
||||
<details open>
|
||||
<summary>ESLint 9 and above (flat config)</summary>
|
||||
|
||||
```javascript
|
||||
export default [
|
||||
{
|
||||
files: ["**/*.html"],
|
||||
plugins: { html },
|
||||
settings: {
|
||||
"html/javascript-tag-names": ["script", "customscript"],
|
||||
},
|
||||
},
|
||||
]
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>ESLint 8 and below</summary>
|
||||
|
||||
```json
|
||||
{
|
||||
"plugins": ["html"],
|
||||
"settings": {
|
||||
"html/javascript-tag-names": ["script", "customscript"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### `html/javascript-mime-types`
|
||||
|
||||
By default, the code between `<script>` tags is considered as JavaScript code only if there is no
|
||||
`type` attribute or if its value matches the pattern
|
||||
`(application|text)/(x-)?(javascript|babel|ecmascript-6)` or `module` (case insensitive). You can
|
||||
customize the types that should be considered as JavaScript by providing one or multiple MIME types.
|
||||
If a MIME type starts with a `/`, it will be considered as a regular expression. Example:
|
||||
|
||||
<details open>
|
||||
<summary>ESLint 9 and above (flat config)</summary>
|
||||
|
||||
```javascript
|
||||
export default [
|
||||
{
|
||||
files: ["**/*.html"],
|
||||
plugins: { html },
|
||||
settings: {
|
||||
"html/javascript-mime-types": ["text/javascript", "text/jsx"], // also use script tags with a "text/jsx" type attribute
|
||||
"html/javascript-mime-types": "/^text\\/(javascript|jsx)$/", // same thing
|
||||
},
|
||||
},
|
||||
]
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>ESLint 8 and below</summary>
|
||||
|
||||
```json
|
||||
{
|
||||
"plugins": ["html"],
|
||||
"settings": {
|
||||
"html/javascript-mime-types": ["text/javascript", "text/jsx"], // also use script tags with a "text/jsx" type attribute
|
||||
"html/javascript-mime-types": "/^text\\/(javascript|jsx)$/" // same thing
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### `html/ignore-tags-without-type`
|
||||
|
||||
By default, the code between `<script>` tags is considered JavaScript if there is no `type`
|
||||
attribute. You can set this setting to `true` to ignore script tags without a `type` attribute.
|
||||
Example:
|
||||
|
||||
<details open>
|
||||
<summary>ESLint 9 and above (flat config)</summary>
|
||||
|
||||
```javascript
|
||||
export default [
|
||||
{
|
||||
files: ["**/*.html"],
|
||||
plugins: { html },
|
||||
settings: {
|
||||
"html/ignore-tags-without-type": true,
|
||||
},
|
||||
},
|
||||
]
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>ESLint 8 and below</summary>
|
||||
|
||||
```json
|
||||
{
|
||||
"plugins": ["html"],
|
||||
"settings": {
|
||||
"html/ignore-tags-without-type": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### No file linted when running `eslint` on a directory
|
||||
|
||||
By default, when executing the `eslint` command on a directory, only `.js` files will be linted. You
|
||||
will have to specify extra extensions with the `--ext` option. Example: `eslint --ext .html,.js src`
|
||||
will lint both `.html` and `.js` files in the `src` directory. See [ESLint
|
||||
documentation](http://eslint.org/docs/user-guide/command-line-interface#ext).
|
||||
|
||||
### Linting templates (or PHP)
|
||||
|
||||
`eslint-plugin-html` won't evaluate or remove your template markup. If you have template markup in
|
||||
your script tags, the resulting script may not be valid JavaScript, so `ESLint` will fail to parse
|
||||
it. Here are some workarounds:
|
||||
|
||||
- You can use [HTML comments to disable ESLint](#disabling-eslint) for specific script tags.
|
||||
|
||||
- For PHP, you can use
|
||||
[`eslint-plugin-php-markup`](https://github.com/tengattack/eslint-plugin-php-markup) to lint php
|
||||
files, it use a same way to process php markup like `eslint-plugin-html`.
|
||||
|
||||
- Another possible hacky workaround to make sure the code is valid JavaScript is to put your
|
||||
template markup inside a comment. When the template is rendered, the generated JS code must start
|
||||
with a new line, so it will be written below the comment. PHP example:
|
||||
|
||||
```html
|
||||
<script>
|
||||
var mydata
|
||||
// <?= "\n mydata = " . json_encode($var) . ";" ?>
|
||||
console.log(mydata)
|
||||
</script>
|
||||
```
|
||||
|
||||
### Linting VUE files
|
||||
|
||||
Initially, [`eslint-plugin-vue`](https://github.com/vuejs/eslint-plugin-vue) was using
|
||||
`eslint-plugin-html` to lint code inside script tags. Since v3, `eslint-plugin-vue` is using its
|
||||
own parser, so it is _incompatible_ with `eslint-plugin-html`. You should use `eslint-plugin-vue`
|
||||
exclusively and remove `eslint-plugin-html` from your dependencies if you still have it.
|
||||
|
||||
## Migration from older versions
|
||||
|
||||
### To v4
|
||||
|
||||
`eslint-plugin-html` v4 requires at least ESLint v4.7. This is because a lot of internal changes
|
||||
occured in ESLint v4.7, including a [new API to support autofixing in
|
||||
preprocessors](https://eslint.org/docs/developer-guide/working-with-plugins#processors-in-plugins).
|
||||
If you are still using an older version of ESLint, please consider upgrading, or keep using
|
||||
`eslint-plugin-html` v3.
|
||||
|
||||
The big feature (and breaking change) in `eslint-plugin-html` v4 is the ability to choose how [scopes
|
||||
are shared between script tags in the same HTML file](#multiple-scripts-tags-in-a-html-file).
|
||||
|
||||
### To v3
|
||||
|
||||
If you are considering upgrading to v3, please read [this guide](MIGRATION_TO_V3.md).
|
||||
|
||||
## Credits
|
||||
|
||||
A big thank you to [@kuceb](https://github.com/kuceb) for the logo image!
|
||||
40
node_modules/eslint-plugin-html/package.json
generated
vendored
Normal file
40
node_modules/eslint-plugin-html/package.json
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"name": "eslint-plugin-html",
|
||||
"version": "8.1.2",
|
||||
"description": "A ESLint plugin to lint and fix inline scripts contained in HTML files.",
|
||||
"license": "ISC",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/BenoitZugmeyer/eslint-plugin-html"
|
||||
},
|
||||
"homepage": "https://github.com/BenoitZugmeyer/eslint-plugin-html",
|
||||
"bugs": "https://github.com/BenoitZugmeyer/eslint-plugin-html/issues",
|
||||
"keywords": [
|
||||
"eslint-plugin",
|
||||
"eslintplugin",
|
||||
"eslint",
|
||||
"html"
|
||||
],
|
||||
"main": "src/index.js",
|
||||
"engines": {
|
||||
"node": ">=16.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"htmlparser2": "^9.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@html-eslint/eslint-plugin": "^0.27.0",
|
||||
"@html-eslint/parser": "^0.27.0",
|
||||
"eslint": "^9.0.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"markdown-link-check": "^3.10.2",
|
||||
"prettier": "^3.2.4",
|
||||
"semver": "^7.3.2"
|
||||
},
|
||||
"scripts": {
|
||||
"validate": "npm run lint && npm run test",
|
||||
"test": "node --test",
|
||||
"lint": "eslint .",
|
||||
"format": "prettier --check ."
|
||||
}
|
||||
}
|
||||
127
node_modules/eslint-plugin-html/src/TransformableString.js
generated
vendored
Normal file
127
node_modules/eslint-plugin-html/src/TransformableString.js
generated
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
"use strict"
|
||||
|
||||
const lineEndingsRe = /\r\n|\r|\n/g
|
||||
function lineStarts(str) {
|
||||
const result = [0]
|
||||
lineEndingsRe.lastIndex = 0
|
||||
while (true) {
|
||||
const match = lineEndingsRe.exec(str)
|
||||
if (!match) break
|
||||
result.push(lineEndingsRe.lastIndex)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
function locationToIndex(location, lineStarts) {
|
||||
if (
|
||||
!location.line ||
|
||||
location.line < 0 ||
|
||||
!location.column ||
|
||||
location.column < 0
|
||||
) {
|
||||
throw new Error("Invalid location")
|
||||
}
|
||||
return lineStarts[location.line - 1] + location.column - 1
|
||||
}
|
||||
|
||||
function indexToLocation(index, lineStarts) {
|
||||
if (index < 0) throw new Error("Invalid index")
|
||||
|
||||
let line = 0
|
||||
while (line + 1 < lineStarts.length && lineStarts[line + 1] <= index) {
|
||||
line += 1
|
||||
}
|
||||
|
||||
return {
|
||||
line: line + 1,
|
||||
column: index - lineStarts[line] + 1,
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = class TransformableString {
|
||||
constructor(original) {
|
||||
this._original = original
|
||||
this._blocks = []
|
||||
this._lineStarts = lineStarts(original)
|
||||
this._cache = null
|
||||
}
|
||||
|
||||
_compute() {
|
||||
if (!this._cache) {
|
||||
let result = ""
|
||||
let index = 0
|
||||
for (const block of this._blocks) {
|
||||
result += this._original.slice(index, block.from) + block.str
|
||||
index = block.to
|
||||
}
|
||||
result += this._original.slice(index)
|
||||
this._cache = {
|
||||
lineStarts: lineStarts(result),
|
||||
result,
|
||||
}
|
||||
}
|
||||
return this._cache
|
||||
}
|
||||
|
||||
getOriginalLine(n) {
|
||||
if (n < 1 || n > this._lineStarts.length) {
|
||||
throw new Error("Invalid line number")
|
||||
}
|
||||
return this._original
|
||||
.slice(this._lineStarts[n - 1], this._lineStarts[n])
|
||||
.replace(lineEndingsRe, "")
|
||||
}
|
||||
|
||||
toString() {
|
||||
return this._compute().result
|
||||
}
|
||||
|
||||
replace(from, to, str) {
|
||||
this._cache = null
|
||||
if (from > to || from < 0 || to > this._original.length) {
|
||||
throw new Error("Invalid slice indexes")
|
||||
}
|
||||
const newBlock = { from, to, str }
|
||||
if (
|
||||
!this._blocks.length ||
|
||||
this._blocks[this._blocks.length - 1].to <= from
|
||||
) {
|
||||
this._blocks.push(newBlock)
|
||||
} else {
|
||||
const index = this._blocks.findIndex((other) => other.to > from)
|
||||
if (this._blocks[index].from < to) throw new Error("Can't replace slice")
|
||||
this._blocks.splice(index, 0, newBlock)
|
||||
}
|
||||
}
|
||||
|
||||
originalIndex(index) {
|
||||
let block
|
||||
for (block of this._blocks) {
|
||||
if (index < block.from) break
|
||||
|
||||
if (index < block.from + block.str.length) {
|
||||
return
|
||||
} else {
|
||||
index += block.to - block.from - block.str.length
|
||||
}
|
||||
}
|
||||
if (index < 0 || index > this._original.length) {
|
||||
throw new Error("Invalid index")
|
||||
}
|
||||
if (index == this._original.length) {
|
||||
if (block.to && block.to === this._original.length) {
|
||||
return block.from + block.str.length
|
||||
}
|
||||
return this._original.length
|
||||
}
|
||||
return index
|
||||
}
|
||||
|
||||
originalLocation(location) {
|
||||
const index = locationToIndex(location, this._compute().lineStarts)
|
||||
const originalIndex = this.originalIndex(index)
|
||||
if (originalIndex !== undefined) {
|
||||
return indexToLocation(originalIndex, this._lineStarts)
|
||||
}
|
||||
}
|
||||
}
|
||||
261
node_modules/eslint-plugin-html/src/extract.js
generated
vendored
Normal file
261
node_modules/eslint-plugin-html/src/extract.js
generated
vendored
Normal file
@@ -0,0 +1,261 @@
|
||||
"use strict"
|
||||
|
||||
const htmlparser = require("htmlparser2")
|
||||
const TransformableString = require("./TransformableString")
|
||||
|
||||
const NO_IGNORE = 0
|
||||
const IGNORE_NEXT = 1
|
||||
const IGNORE_UNTIL_ENABLE = 2
|
||||
|
||||
function iterateScripts(code, xmlMode, options, onChunk) {
|
||||
if (!code) return
|
||||
|
||||
const isJavaScriptMIMEType = options.isJavaScriptMIMEType || (() => true)
|
||||
const javaScriptTagNames = options.javaScriptTagNames || ["script"]
|
||||
const ignoreTagsWithoutType = options.ignoreTagsWithoutType || false
|
||||
let index = 0
|
||||
let inScript = false
|
||||
let cdata = []
|
||||
let ignoreState = NO_IGNORE
|
||||
|
||||
const chunks = []
|
||||
function pushChunk(type, end) {
|
||||
chunks.push({ type, start: index, end, cdata })
|
||||
cdata = []
|
||||
index = end
|
||||
}
|
||||
|
||||
const parser = new htmlparser.Parser(
|
||||
{
|
||||
onopentag(name, attrs) {
|
||||
// Test if current tag is a valid <script> tag.
|
||||
if (!javaScriptTagNames.includes(name)) {
|
||||
return
|
||||
}
|
||||
|
||||
if (attrs.type) {
|
||||
if (!isJavaScriptMIMEType(attrs.type)) {
|
||||
return
|
||||
}
|
||||
} else if (ignoreTagsWithoutType) {
|
||||
return
|
||||
}
|
||||
|
||||
if (attrs.src) {
|
||||
return
|
||||
}
|
||||
|
||||
if (ignoreState === IGNORE_NEXT) {
|
||||
ignoreState = NO_IGNORE
|
||||
return
|
||||
}
|
||||
|
||||
if (ignoreState === IGNORE_UNTIL_ENABLE) {
|
||||
return
|
||||
}
|
||||
|
||||
inScript = true
|
||||
pushChunk("html", parser.endIndex + 1)
|
||||
},
|
||||
|
||||
oncdatastart() {
|
||||
cdata.push(
|
||||
{
|
||||
start: parser.startIndex,
|
||||
end: parser.startIndex + 9,
|
||||
},
|
||||
{
|
||||
start: parser.endIndex - 2,
|
||||
end: parser.endIndex + 1,
|
||||
}
|
||||
)
|
||||
},
|
||||
|
||||
onclosetag(name) {
|
||||
if (!javaScriptTagNames.includes(name) || !inScript) {
|
||||
return
|
||||
}
|
||||
|
||||
inScript = false
|
||||
|
||||
if (parser.startIndex < chunks[chunks.length - 1].end) {
|
||||
// The parser didn't move its index after the previous chunk emited. It occurs on
|
||||
// self-closing tags (xml mode). Just ignore this script.
|
||||
return
|
||||
}
|
||||
|
||||
pushChunk("script", parser.startIndex)
|
||||
},
|
||||
|
||||
ontext() {
|
||||
if (!inScript) {
|
||||
return
|
||||
}
|
||||
|
||||
pushChunk("script", parser.endIndex + 1)
|
||||
},
|
||||
|
||||
oncomment(comment) {
|
||||
comment = comment.trim()
|
||||
if (comment === "eslint-disable") {
|
||||
ignoreState = IGNORE_UNTIL_ENABLE
|
||||
} else if (comment === "eslint-enable") {
|
||||
ignoreState = NO_IGNORE
|
||||
} else if (comment === "eslint-disable-next-script") {
|
||||
ignoreState = IGNORE_NEXT
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
xmlMode: xmlMode === true,
|
||||
}
|
||||
)
|
||||
|
||||
parser.parseComplete(code)
|
||||
|
||||
pushChunk("html", parser.endIndex + 1)
|
||||
|
||||
{
|
||||
const emitChunk = () => {
|
||||
const cdata = []
|
||||
for (let i = startChunkIndex; i < index; i += 1) {
|
||||
cdata.push.apply(cdata, chunks[i].cdata)
|
||||
}
|
||||
onChunk({
|
||||
type: chunks[startChunkIndex].type,
|
||||
start: chunks[startChunkIndex].start,
|
||||
end: chunks[index - 1].end,
|
||||
cdata,
|
||||
})
|
||||
}
|
||||
let startChunkIndex = 0
|
||||
let index
|
||||
for (index = 1; index < chunks.length; index += 1) {
|
||||
if (chunks[startChunkIndex].type === chunks[index].type) continue
|
||||
emitChunk()
|
||||
startChunkIndex = index
|
||||
}
|
||||
|
||||
emitChunk()
|
||||
}
|
||||
}
|
||||
|
||||
function computeIndent(descriptor, previousHTML, slice) {
|
||||
if (!descriptor) {
|
||||
const indentMatch = /[\n\r]+([ \t]*)/.exec(slice)
|
||||
return indentMatch ? indentMatch[1] : ""
|
||||
}
|
||||
|
||||
if (descriptor.relative) {
|
||||
return previousHTML.match(/([^\n\r]*)<[^<]*$/)[1] + descriptor.spaces
|
||||
}
|
||||
|
||||
return descriptor.spaces
|
||||
}
|
||||
|
||||
function* dedent(indent, slice) {
|
||||
let hadNonEmptyLine = false
|
||||
const re = /(\r\n|\n|\r)([ \t]*)(.*)/g
|
||||
let lastIndex = 0
|
||||
|
||||
while (true) {
|
||||
const match = re.exec(slice)
|
||||
if (!match) break
|
||||
|
||||
const newLine = match[1]
|
||||
const lineIndent = match[2]
|
||||
const lineText = match[3]
|
||||
|
||||
const isEmptyLine = !lineText
|
||||
const isFirstNonEmptyLine = !isEmptyLine && !hadNonEmptyLine
|
||||
|
||||
const badIndentation =
|
||||
// Be stricter on the first line
|
||||
isFirstNonEmptyLine
|
||||
? indent !== lineIndent
|
||||
: lineIndent.indexOf(indent) !== 0
|
||||
|
||||
if (!badIndentation) {
|
||||
lastIndex = match.index + newLine.length + indent.length
|
||||
// Remove the first line if it is empty
|
||||
const fromIndex = match.index === 0 ? 0 : match.index + newLine.length
|
||||
yield {
|
||||
type: "dedent",
|
||||
from: fromIndex,
|
||||
to: lastIndex,
|
||||
}
|
||||
} else if (isEmptyLine) {
|
||||
yield {
|
||||
type: "empty",
|
||||
}
|
||||
} else {
|
||||
yield {
|
||||
type: "bad-indent",
|
||||
}
|
||||
}
|
||||
|
||||
if (!isEmptyLine) {
|
||||
hadNonEmptyLine = true
|
||||
}
|
||||
}
|
||||
|
||||
const endSpaces = slice.slice(lastIndex).match(/[ \t]*$/)[0].length
|
||||
if (endSpaces) {
|
||||
yield {
|
||||
type: "dedent",
|
||||
from: slice.length - endSpaces,
|
||||
to: slice.length,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function extract(code, xmlMode, options) {
|
||||
const badIndentationLines = []
|
||||
const codeParts = []
|
||||
let lineNumber = 1
|
||||
let previousHTML = ""
|
||||
|
||||
iterateScripts(code, xmlMode, options, (chunk) => {
|
||||
const slice = code.slice(chunk.start, chunk.end)
|
||||
if (chunk.type === "html") {
|
||||
const match = slice.match(/\r\n|\n|\r/g)
|
||||
if (match) lineNumber += match.length
|
||||
previousHTML = slice
|
||||
} else if (chunk.type === "script") {
|
||||
const transformedCode = new TransformableString(code)
|
||||
let indentSlice = slice
|
||||
for (const cdata of chunk.cdata) {
|
||||
transformedCode.replace(cdata.start, cdata.end, "")
|
||||
if (cdata.end === chunk.end) {
|
||||
indentSlice = code.slice(chunk.start, cdata.start)
|
||||
}
|
||||
}
|
||||
transformedCode.replace(0, chunk.start, "")
|
||||
transformedCode.replace(chunk.end, code.length, "")
|
||||
for (const action of dedent(
|
||||
computeIndent(options.indent, previousHTML, indentSlice),
|
||||
indentSlice
|
||||
)) {
|
||||
lineNumber += 1
|
||||
if (action.type === "dedent") {
|
||||
transformedCode.replace(
|
||||
chunk.start + action.from,
|
||||
chunk.start + action.to,
|
||||
""
|
||||
)
|
||||
} else if (action.type === "bad-indent") {
|
||||
badIndentationLines.push(lineNumber)
|
||||
}
|
||||
}
|
||||
codeParts.push(transformedCode)
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
code: codeParts,
|
||||
badIndentationLines,
|
||||
hasBOM: code.startsWith("\uFEFF"),
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = extract
|
||||
25
node_modules/eslint-plugin-html/src/getFileMode.js
generated
vendored
Normal file
25
node_modules/eslint-plugin-html/src/getFileMode.js
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
"use strict"
|
||||
|
||||
module.exports = function getMode(pluginSettings, filenameOrOptions) {
|
||||
const filename =
|
||||
typeof filenameOrOptions === "object"
|
||||
? filenameOrOptions.filename
|
||||
: filenameOrOptions
|
||||
|
||||
if (!filename) {
|
||||
return
|
||||
}
|
||||
if (pluginSettings.htmlExtensions.some(hasExtension)) {
|
||||
return "html"
|
||||
}
|
||||
if (pluginSettings.xmlExtensions.some(hasExtension)) {
|
||||
return "xml"
|
||||
}
|
||||
|
||||
function hasExtension(extension) {
|
||||
if (!extension.startsWith(".")) {
|
||||
extension = `.${extension}`
|
||||
}
|
||||
return filename.endsWith(extension)
|
||||
}
|
||||
}
|
||||
82
node_modules/eslint-plugin-html/src/index.js
generated
vendored
Normal file
82
node_modules/eslint-plugin-html/src/index.js
generated
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
"use strict"
|
||||
|
||||
const path = require("path")
|
||||
const { createVerifyPatch } = require("./verifyPatch")
|
||||
const {
|
||||
createVerifyWithFlatConfigPatch,
|
||||
} = require("./verifyWithFlatConfigPatch")
|
||||
const pluginReference = require("./pluginReference")
|
||||
|
||||
module.exports = pluginReference
|
||||
|
||||
const LINTER_ISPATCHED_PROPERTY_NAME =
|
||||
"__eslint-plugin-html-verify-function-is-patched"
|
||||
|
||||
// Disclaimer:
|
||||
//
|
||||
// This is not a long term viable solution. ESLint needs to improve its processor API to
|
||||
// provide access to the configuration before actually preprocess files, but it's not
|
||||
// planed yet. This solution is quite ugly but shouldn't alter eslint process.
|
||||
//
|
||||
// Related github issues:
|
||||
// https://github.com/eslint/eslint/issues/3422
|
||||
// https://github.com/eslint/eslint/issues/4153
|
||||
|
||||
const needles = [
|
||||
path.join("lib", "linter", "linter.js"), // ESLint 6+
|
||||
path.join("lib", "linter.js"), // ESLint 5-
|
||||
]
|
||||
|
||||
iterateESLintModules(patch)
|
||||
|
||||
function iterateESLintModules(fn) {
|
||||
let found = false
|
||||
|
||||
for (const key in require.cache) {
|
||||
if (!needles.some((needle) => key.endsWith(needle))) continue
|
||||
|
||||
const module = require.cache[key]
|
||||
if (module && module.exports) {
|
||||
fn(module)
|
||||
found = true
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
console.warn(
|
||||
`⚠ eslint-plugin-html warning: ESLint is not loaded, HTML files will fail to lint. If you don't intend to lint HTML files, you can safely ignore this warning. If you think this is a bug, please file a report at https://github.com/BenoitZugmeyer/eslint-plugin-html/issues`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function patch(module) {
|
||||
const Linter = getLinterFromModule(module)
|
||||
// ignore if verify function is already been patched sometime before
|
||||
if (Linter[LINTER_ISPATCHED_PROPERTY_NAME] === true) {
|
||||
return
|
||||
}
|
||||
Linter[LINTER_ISPATCHED_PROPERTY_NAME] = true
|
||||
|
||||
const verifyMethodName = Linter.prototype._verifyWithoutProcessors
|
||||
? "_verifyWithoutProcessors" // ESLint 6+
|
||||
: "verify" // ESLint 5-
|
||||
const verify = Linter.prototype[verifyMethodName]
|
||||
Linter.prototype[verifyMethodName] = createVerifyPatch(verify)
|
||||
|
||||
const verifyWithFlatConfig =
|
||||
Linter.prototype._verifyWithFlatConfigArrayAndWithoutProcessors
|
||||
Linter.prototype._verifyWithFlatConfigArrayAndWithoutProcessors =
|
||||
createVerifyWithFlatConfigPatch(module, verifyWithFlatConfig)
|
||||
}
|
||||
|
||||
function getLinterFromModule(module) {
|
||||
const Linter = module.exports.Linter
|
||||
? module.exports.Linter // ESLint 6+
|
||||
: module.exports // ESLint 5-
|
||||
if (
|
||||
typeof Linter === "function" &&
|
||||
typeof Linter.prototype.verify === "function"
|
||||
) {
|
||||
return Linter
|
||||
}
|
||||
}
|
||||
1
node_modules/eslint-plugin-html/src/pluginReference.js
generated
vendored
Normal file
1
node_modules/eslint-plugin-html/src/pluginReference.js
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = {}
|
||||
63
node_modules/eslint-plugin-html/src/remapMessages.js
generated
vendored
Normal file
63
node_modules/eslint-plugin-html/src/remapMessages.js
generated
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
module.exports = { remapMessages }
|
||||
|
||||
function remapMessages(messages, hasBOM, codePart) {
|
||||
const newMessages = []
|
||||
|
||||
for (const message of messages) {
|
||||
if (remapMessage(message, hasBOM, codePart)) {
|
||||
newMessages.push(message)
|
||||
}
|
||||
}
|
||||
|
||||
return newMessages
|
||||
}
|
||||
|
||||
function remapMessage(message, hasBOM, codePart) {
|
||||
if (!message.line || !message.column) {
|
||||
// Some messages apply to the whole file instead of a particular code location. In particular:
|
||||
// * @typescript-eslint/parser may send messages with no line/column
|
||||
// * eslint-plugin-eslint-comments send messages with column=0 to bypass ESLint ignore comments.
|
||||
// See https://github.com/BenoitZugmeyer/eslint-plugin-html/issues/70
|
||||
// For now, just include them in the output. In the future, we should make sure those messages
|
||||
// are not print twice.
|
||||
return true
|
||||
}
|
||||
|
||||
const location = codePart.originalLocation({
|
||||
line: message.line,
|
||||
column: message.column,
|
||||
})
|
||||
|
||||
// Ignore messages if they were in transformed code
|
||||
if (!location) {
|
||||
return false
|
||||
}
|
||||
|
||||
Object.assign(message, location)
|
||||
message.source = codePart.getOriginalLine(location.line)
|
||||
|
||||
// Map fix range
|
||||
if (message.fix && message.fix.range) {
|
||||
const bomOffset = hasBOM ? -1 : 0
|
||||
message.fix.range = [
|
||||
codePart.originalIndex(message.fix.range[0]) + bomOffset,
|
||||
// The range end is exclusive, meaning it should replace all characters with indexes from
|
||||
// start to end - 1. We have to get the original index of the last targeted character.
|
||||
codePart.originalIndex(message.fix.range[1] - 1) + 1 + bomOffset,
|
||||
]
|
||||
}
|
||||
|
||||
// Map end location
|
||||
if (message.endLine && message.endColumn) {
|
||||
const endLocation = codePart.originalLocation({
|
||||
line: message.endLine,
|
||||
column: message.endColumn,
|
||||
})
|
||||
if (endLocation) {
|
||||
message.endLine = endLocation.line
|
||||
message.endColumn = endLocation.column
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
122
node_modules/eslint-plugin-html/src/settings.js
generated
vendored
Normal file
122
node_modules/eslint-plugin-html/src/settings.js
generated
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
"use strict"
|
||||
|
||||
const oneLine = require("./utils").oneLine
|
||||
|
||||
const defaultHTMLExtensions = [
|
||||
".erb",
|
||||
".handlebars",
|
||||
".hbs",
|
||||
".htm",
|
||||
".html",
|
||||
".mustache",
|
||||
".nunjucks",
|
||||
".php",
|
||||
".tag",
|
||||
".riot",
|
||||
".twig",
|
||||
".we",
|
||||
]
|
||||
|
||||
const defaultXMLExtensions = [".xhtml", ".xml"]
|
||||
|
||||
function filterOut(array, excludeArray) {
|
||||
if (!excludeArray) return array
|
||||
return array.filter((item) => excludeArray.indexOf(item) < 0)
|
||||
}
|
||||
|
||||
function compileRegExp(re) {
|
||||
const tokens = re.split("/")
|
||||
if (tokens.shift()) {
|
||||
// Ignore first token
|
||||
throw new Error(`Invalid regexp: ${re}`)
|
||||
}
|
||||
const flags = tokens.pop()
|
||||
return new RegExp(tokens.join("/"), flags)
|
||||
}
|
||||
|
||||
function getSetting(settings, name) {
|
||||
if (typeof settings.html === "object" && name in settings.html) {
|
||||
return settings.html[name]
|
||||
}
|
||||
return settings[`html/${name}`]
|
||||
}
|
||||
|
||||
function getSettings(settings) {
|
||||
const htmlExtensions =
|
||||
getSetting(settings, "html-extensions") ||
|
||||
filterOut(defaultHTMLExtensions, getSetting(settings, "xml-extensions"))
|
||||
|
||||
const xmlExtensions =
|
||||
getSetting(settings, "xml-extensions") ||
|
||||
filterOut(defaultXMLExtensions, getSetting(settings, "html-extensions"))
|
||||
|
||||
const javaScriptTagNames = getSetting(settings, "javascript-tag-names") || [
|
||||
"script",
|
||||
]
|
||||
|
||||
const ignoreTagsWithoutType =
|
||||
getSetting(settings, "ignore-tags-without-type") || false
|
||||
|
||||
let reportBadIndent
|
||||
switch (getSetting(settings, "report-bad-indent")) {
|
||||
case undefined:
|
||||
case false:
|
||||
case 0:
|
||||
case "off":
|
||||
reportBadIndent = 0
|
||||
break
|
||||
case true:
|
||||
case 1:
|
||||
case "warn":
|
||||
reportBadIndent = 1
|
||||
break
|
||||
case 2:
|
||||
case "error":
|
||||
reportBadIndent = 2
|
||||
break
|
||||
default:
|
||||
throw new Error(
|
||||
oneLine`
|
||||
Invalid value for html/report-bad-indent,
|
||||
expected one of 0, 1, 2, "off", "warn" or "error"
|
||||
`
|
||||
)
|
||||
}
|
||||
|
||||
const parsedIndent = /^(\+)?(tab|\d+)$/.exec(getSetting(settings, "indent"))
|
||||
const indent = parsedIndent && {
|
||||
relative: parsedIndent[1] === "+",
|
||||
spaces: parsedIndent[2] === "tab" ? "\t" : " ".repeat(parsedIndent[2]),
|
||||
}
|
||||
|
||||
const rawJavaScriptMIMETypes = getSetting(settings, "javascript-mime-types")
|
||||
const javaScriptMIMETypes = rawJavaScriptMIMETypes
|
||||
? (Array.isArray(rawJavaScriptMIMETypes)
|
||||
? rawJavaScriptMIMETypes
|
||||
: [rawJavaScriptMIMETypes]
|
||||
).map((s) => (s.startsWith("/") ? compileRegExp(s) : s))
|
||||
: [
|
||||
/^(application|text)\/(x-)?(javascript|babel|ecmascript-6)$/i,
|
||||
/^module$/i,
|
||||
]
|
||||
|
||||
function isJavaScriptMIMEType(type) {
|
||||
return javaScriptMIMETypes.some((o) =>
|
||||
typeof o === "string" ? type === o : o.test(type)
|
||||
)
|
||||
}
|
||||
|
||||
return {
|
||||
htmlExtensions,
|
||||
xmlExtensions,
|
||||
javaScriptTagNames,
|
||||
indent,
|
||||
reportBadIndent,
|
||||
isJavaScriptMIMEType,
|
||||
ignoreTagsWithoutType,
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getSettings,
|
||||
}
|
||||
32
node_modules/eslint-plugin-html/src/utils.js
generated
vendored
Normal file
32
node_modules/eslint-plugin-html/src/utils.js
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
"use strict"
|
||||
|
||||
function oneLine(parts) {
|
||||
return parts
|
||||
.map((part, index) => {
|
||||
return index > 0 ? arguments[index - 1] + part : part
|
||||
})
|
||||
.join("")
|
||||
.trim()
|
||||
.split("\n")
|
||||
.map((line) => line.trim())
|
||||
.join(" ")
|
||||
}
|
||||
|
||||
function splatSet(items) {
|
||||
const set = new Set()
|
||||
splatSetRec(items, set)
|
||||
return set
|
||||
}
|
||||
|
||||
function splatSetRec(items, set) {
|
||||
if (items instanceof Array || items instanceof Set) {
|
||||
for (const item of items) splatSetRec(item, set)
|
||||
} else {
|
||||
set.add(items)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
oneLine,
|
||||
splatSet,
|
||||
}
|
||||
162
node_modules/eslint-plugin-html/src/verifyPatch.js
generated
vendored
Normal file
162
node_modules/eslint-plugin-html/src/verifyPatch.js
generated
vendored
Normal file
@@ -0,0 +1,162 @@
|
||||
const getSettings = require("./settings").getSettings
|
||||
const getFileMode = require("./getFileMode")
|
||||
const extract = require("./extract")
|
||||
const { remapMessages } = require("./remapMessages")
|
||||
const { verifyWithSharedScopes } = require("./verifyWithSharedScopes")
|
||||
|
||||
const PREPARE_RULE_NAME = "__eslint-plugin-html-prepare"
|
||||
|
||||
module.exports = { createVerifyPatch }
|
||||
|
||||
function createVerifyPatch(verify) {
|
||||
return function (textOrSourceCode, config, filenameOrOptions, saveState) {
|
||||
const callOriginalVerify = () =>
|
||||
verify.call(this, textOrSourceCode, config, filenameOrOptions, saveState)
|
||||
|
||||
if (typeof config.extractConfig === "function") {
|
||||
return callOriginalVerify()
|
||||
}
|
||||
|
||||
const pluginSettings = getSettings(config.settings || {})
|
||||
const mode = getFileMode(pluginSettings, filenameOrOptions)
|
||||
|
||||
if (!mode || typeof textOrSourceCode !== "string") {
|
||||
return callOriginalVerify()
|
||||
}
|
||||
|
||||
let messages
|
||||
;[messages, config] = verifyExternalHtmlPlugin(config, callOriginalVerify)
|
||||
|
||||
if (config.parser && config.parser.id === "@html-eslint/parser") {
|
||||
messages.push(...callOriginalVerify())
|
||||
const rules = {}
|
||||
for (const name in config.rules) {
|
||||
if (!name.startsWith("@html-eslint/")) {
|
||||
rules[name] = config.rules[name]
|
||||
}
|
||||
}
|
||||
config = editConfig(config, {
|
||||
parser: null,
|
||||
rules,
|
||||
})
|
||||
}
|
||||
|
||||
const extractResult = extract(
|
||||
textOrSourceCode,
|
||||
mode === "xml",
|
||||
pluginSettings
|
||||
)
|
||||
|
||||
if (pluginSettings.reportBadIndent) {
|
||||
messages.push(
|
||||
...extractResult.badIndentationLines.map((line) => ({
|
||||
message: "Bad line indentation.",
|
||||
line,
|
||||
column: 1,
|
||||
ruleId: "(html plugin)",
|
||||
severity: pluginSettings.reportBadIndent,
|
||||
}))
|
||||
)
|
||||
}
|
||||
|
||||
// Save code parts parsed source code so we don't have to parse it twice
|
||||
const sourceCodes = new WeakMap()
|
||||
const verifyCodePart = (codePart, { prepare, ignoreRules } = {}) => {
|
||||
this.defineRule(PREPARE_RULE_NAME, (context) => {
|
||||
sourceCodes.set(codePart, context.getSourceCode())
|
||||
return {
|
||||
Program(program) {
|
||||
if (prepare) {
|
||||
prepare(context, program)
|
||||
}
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
const localMessages = verify.call(
|
||||
this,
|
||||
sourceCodes.get(codePart) || String(codePart),
|
||||
editConfig(config, {
|
||||
rules: Object.assign(
|
||||
{ [PREPARE_RULE_NAME]: "error" },
|
||||
!ignoreRules && config.rules
|
||||
),
|
||||
}),
|
||||
ignoreRules && typeof filenameOrOptions === "object"
|
||||
? Object.assign({}, filenameOrOptions, {
|
||||
reportUnusedDisableDirectives: false,
|
||||
})
|
||||
: filenameOrOptions,
|
||||
saveState
|
||||
)
|
||||
|
||||
messages.push(
|
||||
...remapMessages(localMessages, extractResult.hasBOM, codePart)
|
||||
)
|
||||
}
|
||||
|
||||
const parserOptions = config.parserOptions || {}
|
||||
if (parserOptions.sourceType === "module") {
|
||||
for (const codePart of extractResult.code) {
|
||||
verifyCodePart(codePart)
|
||||
}
|
||||
} else {
|
||||
verifyWithSharedScopes(extractResult.code, verifyCodePart, parserOptions)
|
||||
}
|
||||
|
||||
messages.sort((ma, mb) => ma.line - mb.line || ma.column - mb.column)
|
||||
|
||||
return messages
|
||||
}
|
||||
}
|
||||
|
||||
function editConfig(config, { parser = config.parser, rules = config.rules }) {
|
||||
return {
|
||||
...config,
|
||||
parser,
|
||||
rules,
|
||||
}
|
||||
}
|
||||
|
||||
const externalHtmlPluginPrefixes = [
|
||||
"@html-eslint/",
|
||||
"@angular-eslint/template-",
|
||||
]
|
||||
|
||||
function getParserId(config) {
|
||||
if (!config.parser) {
|
||||
return
|
||||
}
|
||||
|
||||
if (typeof config.parser === "string") {
|
||||
// old versions of ESLint (ex: 4.7)
|
||||
return config.parser
|
||||
}
|
||||
|
||||
return config.parser.id
|
||||
}
|
||||
|
||||
function verifyExternalHtmlPlugin(config, callOriginalVerify) {
|
||||
const parserId = getParserId(config)
|
||||
const externalHtmlPluginPrefix =
|
||||
parserId &&
|
||||
externalHtmlPluginPrefixes.find((prefix) => parserId.startsWith(prefix))
|
||||
if (!externalHtmlPluginPrefix) {
|
||||
return [[], config]
|
||||
}
|
||||
|
||||
const rules = {}
|
||||
for (const name in config.rules) {
|
||||
if (!name.startsWith(externalHtmlPluginPrefix)) {
|
||||
rules[name] = config.rules[name]
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
callOriginalVerify(),
|
||||
editConfig(config, {
|
||||
parser: null,
|
||||
rules,
|
||||
}),
|
||||
]
|
||||
}
|
||||
172
node_modules/eslint-plugin-html/src/verifyWithFlatConfigPatch.js
generated
vendored
Normal file
172
node_modules/eslint-plugin-html/src/verifyWithFlatConfigPatch.js
generated
vendored
Normal file
@@ -0,0 +1,172 @@
|
||||
const getSettings = require("./settings").getSettings
|
||||
const getFileMode = require("./getFileMode")
|
||||
const extract = require("./extract")
|
||||
const { verifyWithSharedScopes } = require("./verifyWithSharedScopes")
|
||||
const { remapMessages } = require("./remapMessages")
|
||||
const pluginReference = require("./pluginReference")
|
||||
|
||||
const PREPARE_RULE_NAME = "__eslint-plugin-html-prepare"
|
||||
const PREPARE_PLUGIN_NAME = "__eslint-plugin-html-prepare"
|
||||
|
||||
module.exports = { createVerifyWithFlatConfigPatch }
|
||||
|
||||
function createVerifyWithFlatConfigPatch(eslintModule, verifyWithFlatConfig) {
|
||||
return function (textOrSourceCode, providedConfig, providedOptions) {
|
||||
const callOriginalVerify = () =>
|
||||
verifyWithFlatConfig.call(
|
||||
this,
|
||||
textOrSourceCode,
|
||||
providedConfig,
|
||||
providedOptions
|
||||
)
|
||||
|
||||
if (!Object.values(providedConfig.plugins).includes(pluginReference)) {
|
||||
return callOriginalVerify()
|
||||
}
|
||||
|
||||
const pluginSettings = getSettings(providedConfig.settings || {})
|
||||
const mode = getFileMode(pluginSettings, providedOptions.filename)
|
||||
|
||||
if (!mode) {
|
||||
return callOriginalVerify()
|
||||
}
|
||||
|
||||
let messages
|
||||
;[messages, providedConfig] = verifyExternalHtmlPlugin(
|
||||
eslintModule,
|
||||
providedConfig,
|
||||
callOriginalVerify
|
||||
)
|
||||
|
||||
const extractResult = extract(
|
||||
textOrSourceCode,
|
||||
mode === "xml",
|
||||
pluginSettings
|
||||
)
|
||||
|
||||
if (pluginSettings.reportBadIndent) {
|
||||
messages.push(
|
||||
...extractResult.badIndentationLines.map((line) => ({
|
||||
message: "Bad line indentation.",
|
||||
line,
|
||||
column: 1,
|
||||
ruleId: "(html plugin)",
|
||||
severity: pluginSettings.reportBadIndent,
|
||||
}))
|
||||
)
|
||||
}
|
||||
|
||||
// Save code parts parsed source code so we don't have to parse it twice
|
||||
const sourceCodes = new WeakMap()
|
||||
const verifyCodePart = (codePart, { prepare, ignoreRules } = {}) => {
|
||||
providedConfig.plugins[PREPARE_PLUGIN_NAME] = {
|
||||
rules: {
|
||||
[PREPARE_RULE_NAME]: {
|
||||
create(context) {
|
||||
sourceCodes.set(codePart, context.getSourceCode())
|
||||
return {
|
||||
Program(program) {
|
||||
if (prepare) {
|
||||
prepare(context, program)
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
const localMessages = verifyWithFlatConfig.call(
|
||||
this,
|
||||
sourceCodes.get(codePart) || String(codePart),
|
||||
{
|
||||
...providedConfig,
|
||||
rules: Object.assign(
|
||||
{ [`${PREPARE_PLUGIN_NAME}/${PREPARE_RULE_NAME}`]: "error" },
|
||||
!ignoreRules && providedConfig.rules
|
||||
),
|
||||
},
|
||||
ignoreRules
|
||||
? {
|
||||
...providedOptions,
|
||||
reportUnusedDisableDirectives: false,
|
||||
}
|
||||
: providedOptions
|
||||
)
|
||||
|
||||
messages.push(
|
||||
...remapMessages(localMessages, extractResult.hasBOM, codePart)
|
||||
)
|
||||
}
|
||||
|
||||
const languageOptions = providedConfig.languageOptions || {}
|
||||
const parserOptions = languageOptions.parserOptions || {}
|
||||
const sourceType = languageOptions.sourceType || parserOptions.sourceType
|
||||
if (sourceType === "module") {
|
||||
for (const codePart of extractResult.code) {
|
||||
verifyCodePart(codePart)
|
||||
}
|
||||
} else {
|
||||
verifyWithSharedScopes(extractResult.code, verifyCodePart, parserOptions)
|
||||
}
|
||||
|
||||
messages.sort((ma, mb) => ma.line - mb.line || ma.column - mb.column)
|
||||
|
||||
return messages
|
||||
}
|
||||
}
|
||||
|
||||
const externalHtmlPlugins = [
|
||||
{ parser: "@html-eslint/parser", plugin: "@html-eslint/eslint-plugin" },
|
||||
]
|
||||
|
||||
function tryRequire(name) {
|
||||
try {
|
||||
return require(name)
|
||||
} catch {
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
function findExternalHtmlPluginName(config) {
|
||||
if (!config.languageOptions || !config.languageOptions.parser) {
|
||||
return
|
||||
}
|
||||
for (const { parser, plugin } of externalHtmlPlugins) {
|
||||
let parserModule = tryRequire(parser)
|
||||
if (config.languageOptions.parser === parserModule) {
|
||||
const pluginModule = tryRequire(plugin)
|
||||
for (const [name, plugin] of Object.entries(config.plugins)) {
|
||||
if (plugin === pluginModule) {
|
||||
return name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function verifyExternalHtmlPlugin(eslintModule, config, callOriginalVerify) {
|
||||
const htmlPluginName = findExternalHtmlPluginName(config)
|
||||
if (!htmlPluginName) {
|
||||
return [[], config]
|
||||
}
|
||||
|
||||
const rules = {}
|
||||
for (const name in config.rules) {
|
||||
if (!name.startsWith(htmlPluginName + "/")) {
|
||||
rules[name] = config.rules[name]
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
callOriginalVerify(),
|
||||
{
|
||||
...config,
|
||||
languageOptions: {
|
||||
...config.languageOptions,
|
||||
parser: eslintModule.require("espree"),
|
||||
},
|
||||
rules,
|
||||
},
|
||||
]
|
||||
}
|
||||
81
node_modules/eslint-plugin-html/src/verifyWithSharedScopes.js
generated
vendored
Normal file
81
node_modules/eslint-plugin-html/src/verifyWithSharedScopes.js
generated
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
const { splatSet } = require("./utils")
|
||||
|
||||
module.exports = { verifyWithSharedScopes }
|
||||
|
||||
function verifyWithSharedScopes(codeParts, verifyCodePart, parserOptions) {
|
||||
// First pass: collect needed globals and declared globals for each script tags.
|
||||
const firstPassValues = []
|
||||
|
||||
for (const codePart of codeParts) {
|
||||
verifyCodePart(codePart, {
|
||||
prepare(context, program) {
|
||||
const globalScope = getGlobalScope(context, program)
|
||||
// See https://github.com/eslint/eslint/blob/4b267a5c8a42477bb2384f33b20083ff17ad578c/lib/rules/no-redeclare.js#L67-L78
|
||||
let scopeForDeclaredGlobals
|
||||
if (
|
||||
parserOptions.ecmaFeatures &&
|
||||
parserOptions.ecmaFeatures.globalReturn
|
||||
) {
|
||||
scopeForDeclaredGlobals = globalScope.childScopes[0]
|
||||
} else {
|
||||
scopeForDeclaredGlobals = globalScope
|
||||
}
|
||||
|
||||
firstPassValues.push({
|
||||
codePart,
|
||||
exportedGlobals: globalScope.through.map(
|
||||
(node) => node.identifier.name
|
||||
),
|
||||
declaredGlobals: scopeForDeclaredGlobals.variables.map(
|
||||
(variable) => variable.name
|
||||
),
|
||||
})
|
||||
},
|
||||
ignoreRules: true,
|
||||
})
|
||||
}
|
||||
|
||||
// Second pass: declare variables for each script scope, then run eslint.
|
||||
for (let i = 0; i < firstPassValues.length; i += 1) {
|
||||
verifyCodePart(firstPassValues[i].codePart, {
|
||||
prepare(context, program) {
|
||||
const exportedGlobals = splatSet(
|
||||
firstPassValues
|
||||
.slice(i + 1)
|
||||
.map((nextValues) => nextValues.exportedGlobals)
|
||||
)
|
||||
for (const name of exportedGlobals)
|
||||
markGlobalVariableAsUsed(context, program, name)
|
||||
|
||||
const declaredGlobals = splatSet(
|
||||
firstPassValues
|
||||
.slice(0, i)
|
||||
.map((previousValues) => previousValues.declaredGlobals)
|
||||
)
|
||||
const scope = getGlobalScope(context, program)
|
||||
scope.through = scope.through.filter((variable) => {
|
||||
return !declaredGlobals.has(variable.identifier.name)
|
||||
})
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function markGlobalVariableAsUsed(context, program, name) {
|
||||
const sourceCode = context.getSourceCode()
|
||||
|
||||
if (sourceCode.markVariableAsUsed) {
|
||||
sourceCode.markVariableAsUsed(name, program)
|
||||
} else {
|
||||
context.markVariableAsUsed(name)
|
||||
}
|
||||
}
|
||||
|
||||
function getGlobalScope(context, program) {
|
||||
const sourceCode = context.getSourceCode()
|
||||
if (sourceCode.getScope) {
|
||||
// eslint 9+
|
||||
return sourceCode.getScope(program)
|
||||
}
|
||||
return context.getScope()
|
||||
}
|
||||
Reference in New Issue
Block a user