Skip to content

Commit

Permalink
feat: [require-closing-tags] Add allowSelfClosingCustom options (fix #99
Browse files Browse the repository at this point in the history
) (#109)
  • Loading branch information
yeonjuan authored Sep 29, 2022
1 parent 8b670a2 commit c4368e1
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 13 deletions.
44 changes: 44 additions & 0 deletions docs/rules/require-closing-tags.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ This rule has an object option for [Void Elements](https://html.spec.whatwg.org

- `"selfClosing": "always"`: enforce using self closing tag on [Void Elements](https://html.spec.whatwg.org/multipage/syntax.html#void-elements).

- `"allowSelfClosingCustom": false`: (default) disallow self-closing for the custom tags.

- `"allowSelfClosingCustom": true`: allow self-closing for the custom tags.


#### selfClosing : "never"

Expand Down Expand Up @@ -88,6 +92,46 @@ This rule has an object option for [Void Elements](https://html.spec.whatwg.org

<!-- prettier-ignore-end -->


#### "allowSelfClosingCustom": false

👎 Examples of **incorrect** code for the `{ "allowSelfClosingCustom": false }` option:

<!-- prettier-ignore-start -->

```html
<custom-tag />
```

<!-- prettier-ignore-end -->

👍 Examples of **correct** code for the `{ "allowSelfClosingCustom": false }` option:

<!-- prettier-ignore-start -->

```html
<custom-tag> </custom-tag>
```

<!-- prettier-ignore-end -->


#### "allowSelfClosingCustom": true


👍 Examples of **correct** code for the `{ "allowSelfClosingCustom": true }` option:

<!-- prettier-ignore-start -->

```html
<!-- both allowed -->

<custom-tag> </custom-tag>
<custom-tag />
```

<!-- prettier-ignore-end -->

### Further reading

- [Void Elements](https://html.spec.whatwg.org/multipage/syntax.html#void-elements)
36 changes: 23 additions & 13 deletions packages/eslint-plugin/lib/rules/require-closing-tags.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ module.exports = {
selfClosing: {
enum: ["always", "never"],
},
allowSelfClosingCustom: {
type: "boolean",
},
},
additionalProperties: false,
},
Expand All @@ -46,12 +49,14 @@ module.exports = {
},

create(context) {
let svgStacks = [];

const shouldSelfClose =
context.options && context.options.length
? context.options[0].selfClosing === "always"
: false;
const allowSelfClosingCustom =
context.options && context.options.length
? context.options[0].allowSelfClosingCustom === true
: false;

function checkClosingTag(node) {
if (!node.close) {
Expand All @@ -65,7 +70,7 @@ module.exports = {
}
}

function checkVoidElement(node) {
function checkVoidElement(node, shouldSelfClose, fixable) {
const hasSelfClose = node.openEnd.value === "/>";
if (shouldSelfClose && !hasSelfClose) {
context.report({
Expand All @@ -75,6 +80,9 @@ module.exports = {
},
messageId: MESSAGE_IDS.MISSING_SELF,
fix(fixer) {
if (!fixable) {
return null;
}
return fixer.replaceText(node.openEnd, " />");
},
});
Expand All @@ -87,6 +95,9 @@ module.exports = {
},
messageId: MESSAGE_IDS.UNEXPECTED,
fix(fixer) {
if (!fixable) {
return null;
}
return fixer.replaceText(node.openEnd, ">");
},
});
Expand All @@ -95,20 +106,19 @@ module.exports = {

return {
Tag(node) {
if (node.name === "svg") {
svgStacks.push(node);
}
if (node.selfClosing || VOID_ELEMENTS_SET.has(node.name)) {
checkVoidElement(node);
const isVoidElement = VOID_ELEMENTS_SET.has(node.name);
if (
node.selfClosing &&
allowSelfClosingCustom &&
node.name.indexOf("-") !== -1
) {
checkVoidElement(node, true, false);
} else if (node.selfClosing || isVoidElement) {
checkVoidElement(node, shouldSelfClose, isVoidElement);
} else if (node.openEnd.value !== "/>") {
checkClosingTag(node);
}
},
"Tag:exit"(node) {
if (node.name === "svg") {
svgStacks.push(node);
}
},
};
},
};
67 changes: 67 additions & 0 deletions packages/eslint-plugin/tests/rules/require-closing-tags.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,46 @@ ruleTester.run("require-closing-tags", rule, {
},
],
},
{
code: `<custom-tag> </custom-tag>`,
options: [
{
allowSelfClosingCustom: false,
},
],
},
{
code: `<custom-tag/>`,
options: [
{
allowSelfClosingCustom: true,
},
],
},
{
code: `<custom-tag />`,
options: [
{
allowSelfClosingCustom: true,
},
],
},
{
code: `<custom-tag> </custom-tag>`,
options: [
{
allowSelfClosingCustom: true,
},
],
},
{
code: `<custom-tag id="foo" />`,
options: [
{
allowSelfClosingCustom: true,
},
],
},
{
code: `
<body>
Expand Down Expand Up @@ -98,5 +138,32 @@ ruleTester.run("require-closing-tags", rule, {
},
],
},
{
code: `<custom-tag />`,
options: [
{
allowSelfClosingCustom: false,
},
],
errors: [
{
messageId: "unexpected",
},
],
},
{
code: `<custom-tag id="foo" />`,
options: [
{
allowSelfClosingCustom: false,
},
],
output: null,
errors: [
{
messageId: "unexpected",
},
],
},
],
});

0 comments on commit c4368e1

Please sign in to comment.