Skip to content

Commit 06ac53d

Browse files
authored
feat: add allowedIgnoreCase option to no-html (#500)
* feat: add allowedIgnoreCase option to no-html * indent options
1 parent 737501b commit 06ac53d

File tree

3 files changed

+144
-15
lines changed

3 files changed

+144
-15
lines changed

docs/rules/no-html.md

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,25 +26,49 @@ The following options are available on this rule:
2626

2727
* `allowed: Array<string>` - when specified, HTML tags are allowed only if they match one of the tags in this array. (default: `[]`)
2828

29-
Examples of **incorrect** code when configured as `"no-html": ["error", { allowed: ["b"] }]`:
29+
Examples of **incorrect** code when configured as `"no-html": ["error", { allowed: ["b"] }]`:
3030

31-
```markdown
32-
<!-- eslint markdown/no-html: ["error", { allowed: ["b"] }] -->
31+
```markdown
32+
<!-- eslint markdown/no-html: ["error", { allowed: ["b"] }] -->
3333

34-
# Heading 1
34+
# Heading 1
3535

36-
Hello <em>world!</em>
37-
```
36+
Hello <em>world!</em>
37+
```
3838

39-
Examples of **correct** code when configured as `"no-html": ["error", { allowed: ["b"] }]`:
39+
Examples of **correct** code when configured as `"no-html": ["error", { allowed: ["b"] }]`:
4040

41-
```markdown
42-
<!-- eslint markdown/no-html: ["error", { allowed: ["b"] }] -->
41+
```markdown
42+
<!-- eslint markdown/no-html: ["error", { allowed: ["b"] }] -->
4343

44-
# Heading 1
44+
# Heading 1
4545

46-
Hello <b>world!</b>
47-
```
46+
Hello <b>world!</b>
47+
```
48+
49+
* `allowedIgnoreCase: boolean` - when `true`, enables case-insensitive matching of HTML tag names against the `allowed` array described above. (default: `false`)
50+
51+
Examples of **incorrect** code when configured as `"no-html": ["error", { allowed: ["DIV"], allowedIgnoreCase: false }]`:
52+
53+
```markdown
54+
<!-- eslint markdown/no-html: ["error", { allowed: ["DIV"], allowedIgnoreCase: false }] -->
55+
56+
# Heading 1
57+
58+
<div>Hello world!</div>
59+
```
60+
61+
Examples of **correct** code when configured as `"no-html": ["error", { allowed: ["DIV"], allowedIgnoreCase: true }]`:
62+
63+
```markdown
64+
<!-- eslint markdown/no-html: ["error", { allowed: ["DIV"], allowedIgnoreCase: true }] -->
65+
66+
# Heading 1
67+
68+
<div>Hello world!</div>
69+
<DIV>Hello world!</DIV>
70+
<DiV>Hello world!</DiV>
71+
```
4872

4973
## When Not to Use It
5074

src/rules/no-html.js

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { findOffsets } from "../util.js";
1616
/**
1717
* @import { MarkdownRuleDefinition } from "../types.js";
1818
* @typedef {"disallowedElement"} NoHtmlMessageIds
19-
* @typedef {[{ allowed?: string[] }]} NoHtmlOptions
19+
* @typedef {[{ allowed?: string[], allowedIgnoreCase?: boolean }]} NoHtmlOptions
2020
* @typedef {MarkdownRuleDefinition<{ RuleOptions: NoHtmlOptions, MessageIds: NoHtmlMessageIds }>} NoHtmlRuleDefinition
2121
*/
2222

@@ -55,6 +55,9 @@ export default {
5555
},
5656
uniqueItems: true,
5757
},
58+
allowedIgnoreCase: {
59+
type: "boolean",
60+
},
5861
},
5962
additionalProperties: false,
6063
},
@@ -63,12 +66,16 @@ export default {
6366
defaultOptions: [
6467
{
6568
allowed: [],
69+
allowedIgnoreCase: false,
6670
},
6771
],
6872
},
6973

7074
create(context) {
71-
const allowed = new Set(context.options[0]?.allowed);
75+
const [{ allowed, allowedIgnoreCase }] = context.options;
76+
const allowedElements = new Set(
77+
allowedIgnoreCase ? allowed.map(tag => tag.toLowerCase()) : allowed,
78+
);
7279

7380
return {
7481
html(node) {
@@ -89,7 +96,13 @@ export default {
8996
column: start.column + match[0].length + 1,
9097
};
9198

92-
if (allowed.size === 0 || !allowed.has(tagName)) {
99+
const tagToCheck = allowedIgnoreCase
100+
? tagName.toLowerCase()
101+
: tagName;
102+
if (
103+
allowedElements.size === 0 ||
104+
!allowedElements.has(tagToCheck)
105+
) {
93106
context.report({
94107
loc: { start, end },
95108
messageId: "disallowedElement",

tests/rules/no-html.test.js

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,34 @@ ruleTester.run("no-html", rule, {
3939
code: "<custom-element>Hello world!</custom-element>",
4040
options: [{ allowed: ["custom-element"] }],
4141
},
42+
{
43+
code: "<div>Hello world!</div>",
44+
options: [{ allowed: ["div"] }],
45+
},
46+
{
47+
code: "<DIV>Hello world!</DIV>",
48+
options: [{ allowed: ["DIV"] }],
49+
},
50+
{
51+
code: "<div>Hello world!</div>",
52+
options: [{ allowed: ["DIV"], allowedIgnoreCase: true }],
53+
},
54+
{
55+
code: "<DIV>Hello world!</DIV>",
56+
options: [{ allowed: ["div"], allowedIgnoreCase: true }],
57+
},
58+
{
59+
code: "<DiV>Hello world!</DiV>",
60+
options: [{ allowed: ["div"], allowedIgnoreCase: true }],
61+
},
62+
{
63+
code: "<custom-element>Hello world!</custom-element>",
64+
options: [{ allowed: ["CUSTOM-ELEMENT"], allowedIgnoreCase: true }],
65+
},
66+
{
67+
code: "<CUSTOM-ELEMENT>Hello world!</CUSTOM-ELEMENT>",
68+
options: [{ allowed: ["custom-element"], allowedIgnoreCase: true }],
69+
},
4270
],
4371
invalid: [
4472
{
@@ -130,5 +158,69 @@ ruleTester.run("no-html", rule, {
130158
},
131159
],
132160
},
161+
{
162+
code: "<div>Hello world!</div>",
163+
options: [{ allowed: ["DIV"] }],
164+
errors: [
165+
{
166+
messageId: "disallowedElement",
167+
line: 1,
168+
column: 1,
169+
endLine: 1,
170+
endColumn: 6,
171+
data: {
172+
name: "div",
173+
},
174+
},
175+
],
176+
},
177+
{
178+
code: "<DIV>Hello world!</DIV>",
179+
options: [{ allowed: ["div"] }],
180+
errors: [
181+
{
182+
messageId: "disallowedElement",
183+
line: 1,
184+
column: 1,
185+
endLine: 1,
186+
endColumn: 6,
187+
data: {
188+
name: "DIV",
189+
},
190+
},
191+
],
192+
},
193+
{
194+
code: "<div>Hello world!</div>",
195+
options: [{ allowed: ["span"], allowedIgnoreCase: true }],
196+
errors: [
197+
{
198+
messageId: "disallowedElement",
199+
line: 1,
200+
column: 1,
201+
endLine: 1,
202+
endColumn: 6,
203+
data: {
204+
name: "div",
205+
},
206+
},
207+
],
208+
},
209+
{
210+
code: "<DIV>Hello world!</DIV>",
211+
options: [{ allowed: ["span"], allowedIgnoreCase: true }],
212+
errors: [
213+
{
214+
messageId: "disallowedElement",
215+
line: 1,
216+
column: 1,
217+
endLine: 1,
218+
endColumn: 6,
219+
data: {
220+
name: "DIV",
221+
},
222+
},
223+
],
224+
},
133225
],
134226
});

0 commit comments

Comments
 (0)