Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new rule: no-restricted-html-elements #1820

Merged
merged 21 commits into from Mar 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
555b64b
Add new rule: html-forbid-elements
doug-wade Mar 18, 2022
994bbe9
PR Feedback
doug-wade Mar 20, 2022
40c20cd
Update lib/rules/no-restricted-html-elements.js
doug-wade Mar 23, 2022
2f837ba
Update docs/rules/no-restricted-html-elements.md
doug-wade Mar 23, 2022
d32eac1
Update lib/rules/no-restricted-html-elements.js
doug-wade Mar 23, 2022
59d1c5d
Update tests/lib/rules/no-restricted-html-elements.js
doug-wade Mar 23, 2022
409f48a
Update tests/lib/rules/no-restricted-html-elements.js
doug-wade Mar 23, 2022
b7ca92b
Update tests/lib/rules/no-restricted-html-elements.js
doug-wade Mar 23, 2022
4a62c15
Update tests/lib/rules/no-restricted-html-elements.js
doug-wade Mar 23, 2022
51c0f9b
Update tests/lib/rules/no-restricted-html-elements.js
doug-wade Mar 23, 2022
28b7883
Update tests/lib/rules/no-restricted-html-elements.js
doug-wade Mar 23, 2022
6800118
Update docs/rules/no-restricted-html-elements.md
doug-wade Mar 23, 2022
0202bce
Update tests/lib/rules/no-restricted-html-elements.js
doug-wade Mar 23, 2022
d87c63b
Update docs/rules/no-restricted-html-elements.md
doug-wade Mar 23, 2022
55fd543
Update docs/rules/no-restricted-html-elements.md
doug-wade Mar 23, 2022
b989b15
Update docs/rules/no-restricted-html-elements.md
doug-wade Mar 23, 2022
3812f9f
run npm update
doug-wade Mar 23, 2022
07cc3a8
Remove messages block
doug-wade Mar 23, 2022
33a4d90
Update docs/rules/no-restricted-html-elements.md
ota-meshi Mar 23, 2022
cdb4636
Update docs/rules/no-restricted-html-elements.md
ota-meshi Mar 23, 2022
daa01ec
Fix demo site
ota-meshi Mar 23, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/rules/README.md
Expand Up @@ -335,6 +335,7 @@ For example:
| [vue/no-restricted-class](./no-restricted-class.md) | disallow specific classes in Vue components | |
| [vue/no-restricted-component-options](./no-restricted-component-options.md) | disallow specific component option | |
| [vue/no-restricted-custom-event](./no-restricted-custom-event.md) | disallow specific custom event | :bulb: |
| [vue/no-restricted-html-elements](./no-restricted-html-elements.md) | disallow specific HTML elements | |
| [vue/no-restricted-props](./no-restricted-props.md) | disallow specific props | :bulb: |
| [vue/no-restricted-static-attribute](./no-restricted-static-attribute.md) | disallow specific attribute | |
| [vue/no-restricted-v-bind](./no-restricted-v-bind.md) | disallow specific argument in `v-bind` | |
Expand Down
96 changes: 96 additions & 0 deletions docs/rules/no-restricted-html-elements.md
@@ -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)
1 change: 1 addition & 0 deletions lib/index.js
Expand Up @@ -113,6 +113,7 @@ module.exports = {
'no-restricted-class': require('./rules/no-restricted-class'),
'no-restricted-component-options': require('./rules/no-restricted-component-options'),
'no-restricted-custom-event': require('./rules/no-restricted-custom-event'),
'no-restricted-html-elements': require('./rules/no-restricted-html-elements'),
'no-restricted-props': require('./rules/no-restricted-props'),
'no-restricted-static-attribute': require('./rules/no-restricted-static-attribute'),
'no-restricted-syntax': require('./rules/no-restricted-syntax'),
Expand Down
68 changes: 68 additions & 0 deletions lib/rules/no-restricted-html-elements.js
@@ -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
})
}
})
}
})
}
}
75 changes: 75 additions & 0 deletions tests/lib/rules/no-restricted-html-elements.js
@@ -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' }]
}
]
})