Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add new rule: no-restricted-html-elements (#1820)
* Add new rule: html-forbid-elements * PR Feedback * Update lib/rules/no-restricted-html-elements.js Co-authored-by: Flo Edelmann <florian-edelmann@online.de> * Update docs/rules/no-restricted-html-elements.md Co-authored-by: Flo Edelmann <florian-edelmann@online.de> * Update lib/rules/no-restricted-html-elements.js Co-authored-by: Flo Edelmann <florian-edelmann@online.de> * Update tests/lib/rules/no-restricted-html-elements.js Co-authored-by: Yosuke Ota <otameshiyo23@gmail.com> * Update tests/lib/rules/no-restricted-html-elements.js Co-authored-by: Yosuke Ota <otameshiyo23@gmail.com> * Update tests/lib/rules/no-restricted-html-elements.js Co-authored-by: Yosuke Ota <otameshiyo23@gmail.com> * Update tests/lib/rules/no-restricted-html-elements.js Co-authored-by: Yosuke Ota <otameshiyo23@gmail.com> * Update tests/lib/rules/no-restricted-html-elements.js Co-authored-by: Yosuke Ota <otameshiyo23@gmail.com> * Update tests/lib/rules/no-restricted-html-elements.js Co-authored-by: Yosuke Ota <otameshiyo23@gmail.com> * Update docs/rules/no-restricted-html-elements.md Co-authored-by: Yosuke Ota <otameshiyo23@gmail.com> * Update tests/lib/rules/no-restricted-html-elements.js Co-authored-by: Yosuke Ota <otameshiyo23@gmail.com> * Update docs/rules/no-restricted-html-elements.md Co-authored-by: Flo Edelmann <florian-edelmann@online.de> * Update docs/rules/no-restricted-html-elements.md Co-authored-by: Flo Edelmann <florian-edelmann@online.de> * Update docs/rules/no-restricted-html-elements.md Co-authored-by: Flo Edelmann <florian-edelmann@online.de> * run npm update * Remove messages block * Update docs/rules/no-restricted-html-elements.md * Update docs/rules/no-restricted-html-elements.md * Fix demo site Co-authored-by: Flo Edelmann <florian-edelmann@online.de> Co-authored-by: Yosuke Ota <otameshiyo23@gmail.com>
- Loading branch information
1 parent
f5f4f97
commit 1ce68fa
Showing
5 changed files
with
241 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
--- | ||
pageClass: rule-details | ||
sidebarDepth: 0 | ||
title: vue/no-restricted-html-elements | ||
description: disallow specific HTML elements | ||
--- | ||
# vue/no-restricted-html-elements | ||
|
||
> disallow specific HTML elements | ||
- :exclamation: <badge text="This rule has not been released yet." vertical="middle" type="error"> ***This rule has not been released yet.*** </badge> | ||
|
||
## :book: Rule Details | ||
|
||
This rule allows you to specify HTML elements that you don't want to use in your application. | ||
|
||
<eslint-code-block :rules="{'vue/no-restricted-html-elements': ['error', 'marquee', 'button'] }"> | ||
|
||
```vue | ||
<template> | ||
<!-- ✓ GOOD --> | ||
<p></p> | ||
<input /> | ||
<br /> | ||
<!-- ✗ BAD --> | ||
<button></button> | ||
<marquee></marquee> | ||
</template> | ||
``` | ||
|
||
</eslint-code-block> | ||
|
||
## :wrench: Options | ||
|
||
This rule takes a list of strings, where each string is an HTML element name to be restricted: | ||
|
||
```json | ||
{ | ||
"vue/no-restricted-html-elements": ["error", "button", "marquee"] | ||
} | ||
``` | ||
|
||
<eslint-code-block :rules="{'vue/no-restricted-html-elements': ['error', 'button', 'marquee']}"> | ||
|
||
```vue | ||
<template> | ||
<!-- ✗ BAD --> | ||
<button></button> | ||
<marquee></marquee> | ||
</template> | ||
``` | ||
|
||
</eslint-code-block> | ||
|
||
Alternatively, the rule also accepts objects. | ||
|
||
```json | ||
{ | ||
"vue/no-restricted-html-elements": [ | ||
"error", | ||
{ | ||
"element": "button", | ||
"message": "Prefer use of our custom <AppButton /> component" | ||
}, | ||
{ | ||
"element": "marquee", | ||
"message": "Do not use deprecated HTML tags" | ||
} | ||
] | ||
} | ||
``` | ||
|
||
The following properties can be specified for the object. | ||
|
||
- `element` ... Specify the html element. | ||
- `message` ... Specify an optional custom message. | ||
|
||
### `{ "element": "marquee" }, { "element": "button" }` | ||
|
||
<eslint-code-block :rules="{'vue/no-restricted-html-elements': ['error', { element: 'marquee' }, { element: 'button' }]}"> | ||
|
||
```vue | ||
<template> | ||
<!-- ✗ BAD --> | ||
<marquee></marquee> | ||
<button></button> | ||
</template> | ||
``` | ||
|
||
</eslint-code-block> | ||
|
||
## :mag: Implementation | ||
|
||
- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/no-restricted-html-elements.js) | ||
- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/no-restricted-html-elements.js) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
/** | ||
* @author Doug Wade <douglas.b.wade@gmail.com> | ||
*/ | ||
|
||
'use strict' | ||
|
||
const utils = require('../utils') | ||
|
||
module.exports = { | ||
meta: { | ||
type: 'suggestion', | ||
docs: { | ||
description: 'disallow specific HTML elements', | ||
categories: undefined, | ||
url: 'https://eslint.vuejs.org/rules/no-restricted-html-elements.html' | ||
}, | ||
fixable: null, | ||
schema: { | ||
type: 'array', | ||
items: { | ||
oneOf: [ | ||
{ type: 'string' }, | ||
{ | ||
type: 'object', | ||
properties: { | ||
element: { type: 'string' }, | ||
message: { type: 'string', minLength: 1 } | ||
}, | ||
required: ['element'], | ||
additionalProperties: false | ||
} | ||
] | ||
}, | ||
uniqueItems: true, | ||
minItems: 0 | ||
} | ||
}, | ||
/** | ||
* @param {RuleContext} context - The rule context. | ||
* @returns {RuleListener} AST event handlers. | ||
*/ | ||
create(context) { | ||
return utils.defineTemplateBodyVisitor(context, { | ||
/** | ||
* @param {VElement} node | ||
*/ | ||
VElement(node) { | ||
if (!utils.isHtmlElementNode(node)) { | ||
return | ||
} | ||
|
||
context.options.forEach((option) => { | ||
const message = | ||
option.message || | ||
`Unexpected use of forbidden HTML element ${node.rawName}.` | ||
const element = option.element || option | ||
|
||
if (element === node.rawName) { | ||
context.report({ | ||
message, | ||
node: node.startTag | ||
}) | ||
} | ||
}) | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
/** | ||
* @author Doug Wade | ||
*/ | ||
'use strict' | ||
|
||
const RuleTester = require('eslint').RuleTester | ||
const rule = require('../../../lib/rules/no-restricted-html-elements') | ||
|
||
const tester = new RuleTester({ | ||
parser: require.resolve('vue-eslint-parser'), | ||
parserOptions: { ecmaVersion: 2015 } | ||
}) | ||
|
||
tester.run('no-restricted-html-elements', rule, { | ||
valid: [ | ||
{ | ||
filename: 'test.vue', | ||
code: '', | ||
options: ['button'] | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: '<template><div class="foo"></div></template>', | ||
options: ['button'] | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: '<template><button type="button"></button></template>', | ||
options: ['div'] | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: '<template><div class="foo"><Button type="button"></Button></div></template>', | ||
options: ['button'] | ||
} | ||
], | ||
invalid: [ | ||
{ | ||
filename: 'test.vue', | ||
code: '<template><div><button type="button"></button><div></template>', | ||
errors: [ | ||
{ | ||
message: 'Unexpected use of forbidden HTML element button.', | ||
line: 1, | ||
column: 16 | ||
} | ||
], | ||
options: ['button'] | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: '<template><div class="foo"><button type="button"></button></div></template>', | ||
errors: [ | ||
{ | ||
message: 'Unexpected use of forbidden HTML element div.', | ||
line: 1, | ||
column: 11 | ||
} | ||
], | ||
options: ['div'] | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: '<template><marquee>foo</marquee></template>', | ||
errors: [ | ||
{ | ||
message: 'Custom error', | ||
line: 1, | ||
column: 11 | ||
} | ||
], | ||
options: [{ element: 'marquee', message: 'Custom error' }] | ||
} | ||
] | ||
}) |