Skip to content

Commit 0d2607f

Browse files
authored
Allow restricting classes by regexp in vue/no-restricted-class (#2013)
1 parent 2479d2f commit 0d2607f

File tree

3 files changed

+45
-5
lines changed

3 files changed

+45
-5
lines changed

docs/rules/no-restricted-class.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ in the rule configuration.
2020

2121
```json
2222
{
23-
"vue/no-restricted-class": ["error", "forbidden", "forbidden-two", "forbidden-three"]
23+
"vue/no-restricted-class": ["error", "forbidden", "forbidden-two", "forbidden-three", "/^for(bidden|gotten)/"]
2424
}
2525
```
2626

lib/rules/no-restricted-class.js

+30-4
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,27 @@
55
'use strict'
66

77
const utils = require('../utils')
8+
const regexp = require('../utils/regexp')
89

910
/**
1011
* Report a forbidden class
1112
* @param {string} className
1213
* @param {*} node
1314
* @param {RuleContext} context
1415
* @param {Set<string>} forbiddenClasses
16+
* @param {Array<RegExp>} forbiddenClassesRegexps
1517
*/
16-
const reportForbiddenClass = (className, node, context, forbiddenClasses) => {
17-
if (forbiddenClasses.has(className)) {
18+
const reportForbiddenClass = (
19+
className,
20+
node,
21+
context,
22+
forbiddenClasses,
23+
forbiddenClassesRegexps
24+
) => {
25+
if (
26+
forbiddenClasses.has(className) ||
27+
forbiddenClassesRegexps.some((re) => re.test(className))
28+
) {
1829
const loc = node.value ? node.value.loc : node.loc
1930
context.report({
2031
node,
@@ -113,14 +124,23 @@ module.exports = {
113124
/** @param {RuleContext} context */
114125
create(context) {
115126
const forbiddenClasses = new Set(context.options || [])
127+
const forbiddenClassesRegexps = (context.options || [])
128+
.filter((cl) => regexp.isRegExp(cl))
129+
.map((cl) => regexp.toRegExp(cl))
116130

117131
return utils.defineTemplateBodyVisitor(context, {
118132
/**
119133
* @param {VAttribute & { value: VLiteral } } node
120134
*/
121135
'VAttribute[directive=false][key.name="class"]'(node) {
122136
for (const className of node.value.value.split(/\s+/)) {
123-
reportForbiddenClass(className, node, context, forbiddenClasses)
137+
reportForbiddenClass(
138+
className,
139+
node,
140+
context,
141+
forbiddenClasses,
142+
forbiddenClassesRegexps
143+
)
124144
}
125145
},
126146

@@ -135,7 +155,13 @@ module.exports = {
135155
for (const { className, reportNode } of extractClassNames(
136156
/** @type {Expression} */ (node.expression)
137157
)) {
138-
reportForbiddenClass(className, reportNode, context, forbiddenClasses)
158+
reportForbiddenClass(
159+
className,
160+
reportNode,
161+
context,
162+
forbiddenClasses,
163+
forbiddenClassesRegexps
164+
)
139165
}
140166
}
141167
})

tests/lib/rules/no-restricted-class.js

+14
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ ruleTester.run('no-restricted-class', rule, {
3030
{
3131
code: `<template><div :class="'' + {forbidden: true}">Content</div></template>`,
3232
options: ['forbidden']
33+
},
34+
{
35+
code: `<template><div class="allowed">Content</div></template>`,
36+
options: ['/^for(bidden|gotten)/']
3337
}
3438
],
3539

@@ -113,6 +117,16 @@ ruleTester.run('no-restricted-class', rule, {
113117
}
114118
],
115119
options: ['forbidden']
120+
},
121+
{
122+
code: `<template><div class="forbidden allowed" /></template>`,
123+
errors: [
124+
{
125+
message: "'forbidden' class is not allowed.",
126+
type: 'VAttribute'
127+
}
128+
],
129+
options: ['/^for(bidden|gotten)/']
116130
}
117131
]
118132
})

0 commit comments

Comments
 (0)