From 04d8d49559efca96345005bc6ffffb3a1312c24f Mon Sep 17 00:00:00 2001 From: "Sean S. LeBlanc" Date: Wed, 29 May 2024 13:48:19 -0400 Subject: [PATCH 01/29] add test case covering non-void self-closing tag when self-closing is enforced --- .../tests/rules/require-closing-tags.test.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/packages/eslint-plugin/tests/rules/require-closing-tags.test.js b/packages/eslint-plugin/tests/rules/require-closing-tags.test.js index 10c7c9d2..4bfdc666 100644 --- a/packages/eslint-plugin/tests/rules/require-closing-tags.test.js +++ b/packages/eslint-plugin/tests/rules/require-closing-tags.test.js @@ -165,5 +165,19 @@ ruleTester.run("require-closing-tags", rule, { }, ], }, + { + code: `
`, + options: [ + { + selfClosing: "always", + }, + ], + output: null, + errors: [ + { + messageId: "unexpected", + }, + ], + }, ], }); From 1fbfe9a37f8775a2e34abb178e38fb0f7481e253 Mon Sep 17 00:00:00 2001 From: "Sean S. LeBlanc" Date: Wed, 29 May 2024 13:49:23 -0400 Subject: [PATCH 02/29] don't close non-void elements --- packages/eslint-plugin/lib/rules/require-closing-tags.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/eslint-plugin/lib/rules/require-closing-tags.js b/packages/eslint-plugin/lib/rules/require-closing-tags.js index 3a2191fd..a68ad4e6 100644 --- a/packages/eslint-plugin/lib/rules/require-closing-tags.js +++ b/packages/eslint-plugin/lib/rules/require-closing-tags.js @@ -122,7 +122,7 @@ module.exports = { ) { checkVoidElement(node, true, false); } else if (node.selfClosing || isVoidElement) { - checkVoidElement(node, shouldSelfClose, isVoidElement); + checkVoidElement(node, shouldSelfClose && isVoidElement, isVoidElement); } else if (node.openEnd.value !== "/>") { checkClosingTag(node); } From 2d3a51565189e32d58eaf2cf987490c60e9f9908 Mon Sep 17 00:00:00 2001 From: "Sean S. LeBlanc" Date: Wed, 29 May 2024 14:06:08 -0400 Subject: [PATCH 03/29] add test case covering math self close exception --- .../tests/rules/require-closing-tags.test.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/packages/eslint-plugin/tests/rules/require-closing-tags.test.js b/packages/eslint-plugin/tests/rules/require-closing-tags.test.js index 4bfdc666..067674b0 100644 --- a/packages/eslint-plugin/tests/rules/require-closing-tags.test.js +++ b/packages/eslint-plugin/tests/rules/require-closing-tags.test.js @@ -75,6 +75,20 @@ ruleTester.run("require-closing-tags", rule, { +`, + options: [ + { + selfClosing: "always", + }, + ], + }, + { + code: ` + + + 12 + + `, options: [ { From da729524aca1db5e3aa2e67edc2997e196d95b0d Mon Sep 17 00:00:00 2001 From: "Sean S. LeBlanc" Date: Wed, 29 May 2024 14:08:39 -0400 Subject: [PATCH 04/29] clarify names --- packages/eslint-plugin/lib/rules/require-closing-tags.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/eslint-plugin/lib/rules/require-closing-tags.js b/packages/eslint-plugin/lib/rules/require-closing-tags.js index a68ad4e6..93a2439e 100644 --- a/packages/eslint-plugin/lib/rules/require-closing-tags.js +++ b/packages/eslint-plugin/lib/rules/require-closing-tags.js @@ -49,7 +49,7 @@ module.exports = { }, create(context) { - const shouldSelfClose = + const preferSelfClose = context.options && context.options.length ? context.options[0].selfClosing === "always" : false; @@ -115,6 +115,7 @@ module.exports = { return { Tag(node) { const isVoidElement = VOID_ELEMENTS_SET.has(node.name); + const canSelfClose = isVoidElement; if ( node.selfClosing && allowSelfClosingCustom && @@ -122,7 +123,7 @@ module.exports = { ) { checkVoidElement(node, true, false); } else if (node.selfClosing || isVoidElement) { - checkVoidElement(node, shouldSelfClose && isVoidElement, isVoidElement); + checkVoidElement(node, preferSelfClose && canSelfClose, canSelfClose); } else if (node.openEnd.value !== "/>") { checkClosingTag(node); } From f3b10f8152b78d708312b3dab56221c618f8d18d Mon Sep 17 00:00:00 2001 From: "Sean S. LeBlanc" Date: Wed, 29 May 2024 14:15:31 -0400 Subject: [PATCH 05/29] re-implement foreign context check --- .../eslint-plugin/lib/rules/require-closing-tags.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/eslint-plugin/lib/rules/require-closing-tags.js b/packages/eslint-plugin/lib/rules/require-closing-tags.js index 93a2439e..b60c571a 100644 --- a/packages/eslint-plugin/lib/rules/require-closing-tags.js +++ b/packages/eslint-plugin/lib/rules/require-closing-tags.js @@ -49,6 +49,8 @@ module.exports = { }, create(context) { + /** @type {string[]} */ + const foreignContext = []; const preferSelfClose = context.options && context.options.length ? context.options[0].selfClosing === "always" @@ -114,8 +116,9 @@ module.exports = { return { Tag(node) { + if (['svg', 'math'].includes(node.name)) foreignContext.push(node.name); const isVoidElement = VOID_ELEMENTS_SET.has(node.name); - const canSelfClose = isVoidElement; + const canSelfClose = isVoidElement || foreignContext.length > 0; if ( node.selfClosing && allowSelfClosingCustom && @@ -128,6 +131,14 @@ module.exports = { checkClosingTag(node); } }, + /** + * @param {TagNode} node + */ + "Tag:exit"(node) { + if (node.name === foreignContext[foreignContext.length-1]) { + foreignContext.pop(); + } + }, }; }, }; From 26ff11b6201f240927a484553cee8116f9504849 Mon Sep 17 00:00:00 2001 From: "Sean S. LeBlanc" Date: Wed, 29 May 2024 14:23:18 -0400 Subject: [PATCH 06/29] foreign context doesn't include the opening node itself --- packages/eslint-plugin/lib/rules/require-closing-tags.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/eslint-plugin/lib/rules/require-closing-tags.js b/packages/eslint-plugin/lib/rules/require-closing-tags.js index b60c571a..948c4765 100644 --- a/packages/eslint-plugin/lib/rules/require-closing-tags.js +++ b/packages/eslint-plugin/lib/rules/require-closing-tags.js @@ -116,7 +116,6 @@ module.exports = { return { Tag(node) { - if (['svg', 'math'].includes(node.name)) foreignContext.push(node.name); const isVoidElement = VOID_ELEMENTS_SET.has(node.name); const canSelfClose = isVoidElement || foreignContext.length > 0; if ( @@ -130,6 +129,7 @@ module.exports = { } else if (node.openEnd.value !== "/>") { checkClosingTag(node); } + if (['svg', 'math'].includes(node.name)) foreignContext.push(node.name); }, /** * @param {TagNode} node From 6be6f3f863553794aec02e3c5a262e790dbd7c77 Mon Sep 17 00:00:00 2001 From: "Sean S. LeBlanc" Date: Wed, 29 May 2024 14:27:55 -0400 Subject: [PATCH 07/29] rewrite custom element checks to enforce the rule when possible --- .../eslint-plugin/lib/rules/require-closing-tags.js | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/packages/eslint-plugin/lib/rules/require-closing-tags.js b/packages/eslint-plugin/lib/rules/require-closing-tags.js index 948c4765..43324304 100644 --- a/packages/eslint-plugin/lib/rules/require-closing-tags.js +++ b/packages/eslint-plugin/lib/rules/require-closing-tags.js @@ -117,14 +117,9 @@ module.exports = { return { Tag(node) { const isVoidElement = VOID_ELEMENTS_SET.has(node.name); - const canSelfClose = isVoidElement || foreignContext.length > 0; - if ( - node.selfClosing && - allowSelfClosingCustom && - node.name.indexOf("-") !== -1 - ) { - checkVoidElement(node, true, false); - } else if (node.selfClosing || isVoidElement) { + const isCustomElement = node.name.indexOf("-") !== -1; + const canSelfClose = isVoidElement || foreignContext.length > 0 || (isCustomElement && allowSelfClosingCustom && !node.children.length); + if (node.selfClosing || canSelfClose) { checkVoidElement(node, preferSelfClose && canSelfClose, canSelfClose); } else if (node.openEnd.value !== "/>") { checkClosingTag(node); From 4e054dc01ac3e4de6c3ec739b64a8662fd6302ec Mon Sep 17 00:00:00 2001 From: "Sean S. LeBlanc" Date: Wed, 29 May 2024 14:28:13 -0400 Subject: [PATCH 08/29] update custom tag tests --- .../eslint-plugin/tests/rules/require-closing-tags.test.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/eslint-plugin/tests/rules/require-closing-tags.test.js b/packages/eslint-plugin/tests/rules/require-closing-tags.test.js index 067674b0..e0929778 100644 --- a/packages/eslint-plugin/tests/rules/require-closing-tags.test.js +++ b/packages/eslint-plugin/tests/rules/require-closing-tags.test.js @@ -31,6 +31,7 @@ ruleTester.run("require-closing-tags", rule, { code: ``, options: [ { + selfClosing: "always", allowSelfClosingCustom: true, }, ], @@ -39,6 +40,7 @@ ruleTester.run("require-closing-tags", rule, { code: ``, options: [ { + selfClosing: "always", allowSelfClosingCustom: true, }, ], @@ -55,6 +57,7 @@ ruleTester.run("require-closing-tags", rule, { code: ``, options: [ { + selfClosing: "always", allowSelfClosingCustom: true, }, ], From 28cb880cc5660a133fa198186c913b163ff22e28 Mon Sep 17 00:00:00 2001 From: "Sean S. LeBlanc" Date: Wed, 29 May 2024 14:28:20 -0400 Subject: [PATCH 09/29] add custom tag test for children --- .../tests/rules/require-closing-tags.test.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/eslint-plugin/tests/rules/require-closing-tags.test.js b/packages/eslint-plugin/tests/rules/require-closing-tags.test.js index e0929778..4890bd0a 100644 --- a/packages/eslint-plugin/tests/rules/require-closing-tags.test.js +++ b/packages/eslint-plugin/tests/rules/require-closing-tags.test.js @@ -62,6 +62,15 @@ ruleTester.run("require-closing-tags", rule, { }, ], }, + { + code: `children`, + options: [ + { + selfClosing: "always", + allowSelfClosingCustom: true, + }, + ], + }, { code: ` From 621cbbe349a33085d66ba7f76299a4ab1c9b1839 Mon Sep 17 00:00:00 2001 From: "Sean S. LeBlanc" Date: Wed, 29 May 2024 14:35:51 -0400 Subject: [PATCH 10/29] replace custom tag check with regex + custom pattern option --- packages/eslint-plugin/lib/rules/require-closing-tags.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/eslint-plugin/lib/rules/require-closing-tags.js b/packages/eslint-plugin/lib/rules/require-closing-tags.js index 43324304..9c62bfa6 100644 --- a/packages/eslint-plugin/lib/rules/require-closing-tags.js +++ b/packages/eslint-plugin/lib/rules/require-closing-tags.js @@ -37,6 +37,9 @@ module.exports = { allowSelfClosingCustom: { type: "boolean", }, + customPattern: { + type: "string", + }, }, additionalProperties: false, }, @@ -59,6 +62,8 @@ module.exports = { context.options && context.options.length ? context.options[0].allowSelfClosingCustom === true : false; + const customPattern = + new RegExp(context.options && context.options.length && context.options[0].customPattern || '-'); /** * @param {TagNode} node @@ -117,7 +122,7 @@ module.exports = { return { Tag(node) { const isVoidElement = VOID_ELEMENTS_SET.has(node.name); - const isCustomElement = node.name.indexOf("-") !== -1; + const isCustomElement = !!node.name.match(customPattern); const canSelfClose = isVoidElement || foreignContext.length > 0 || (isCustomElement && allowSelfClosingCustom && !node.children.length); if (node.selfClosing || canSelfClose) { checkVoidElement(node, preferSelfClose && canSelfClose, canSelfClose); From 604a3eea9ebba0507876861b45d7f84ffaca7561 Mon Sep 17 00:00:00 2001 From: "Sean S. LeBlanc" Date: Wed, 29 May 2024 14:35:59 -0400 Subject: [PATCH 11/29] add tests for custom pattern option --- .../tests/rules/require-closing-tags.test.js | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/packages/eslint-plugin/tests/rules/require-closing-tags.test.js b/packages/eslint-plugin/tests/rules/require-closing-tags.test.js index 4890bd0a..27d96ce6 100644 --- a/packages/eslint-plugin/tests/rules/require-closing-tags.test.js +++ b/packages/eslint-plugin/tests/rules/require-closing-tags.test.js @@ -71,6 +71,16 @@ ruleTester.run("require-closing-tags", rule, { }, ], }, + { + code: ``, + options: [ + { + selfClosing: "always", + allowSelfClosingCustom: true, + customPattern: ':', + }, + ], + }, { code: ` @@ -191,6 +201,22 @@ ruleTester.run("require-closing-tags", rule, { }, ], }, + { + code: ``, + options: [ + { + selfClosing: "always", + allowSelfClosingCustom: true, + customPattern: ':', + }, + ], + output: null, + errors: [ + { + messageId: "unexpected", + }, + ], + }, { code: `
`, options: [ From 21973f19b27fdec63d0ccd4801f62ee427445547 Mon Sep 17 00:00:00 2001 From: "Sean S. LeBlanc" Date: Wed, 29 May 2024 14:48:44 -0400 Subject: [PATCH 12/29] add test for preferred self closing custom tag with no children --- .../tests/rules/require-closing-tags.test.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/packages/eslint-plugin/tests/rules/require-closing-tags.test.js b/packages/eslint-plugin/tests/rules/require-closing-tags.test.js index 27d96ce6..d0372359 100644 --- a/packages/eslint-plugin/tests/rules/require-closing-tags.test.js +++ b/packages/eslint-plugin/tests/rules/require-closing-tags.test.js @@ -217,6 +217,21 @@ ruleTester.run("require-closing-tags", rule, { }, ], }, + { + code: ``, + options: [ + { + selfClosing: "always", + allowSelfClosingCustom: true, + }, + ], + output: '', + errors: [ + { + messageId: "missingSelf", + }, + ], + }, { code: `
`, options: [ From 18af2d5d4f8790052da12286c5d13b07071c1ece Mon Sep 17 00:00:00 2001 From: "Sean S. LeBlanc" Date: Wed, 29 May 2024 15:01:41 -0400 Subject: [PATCH 13/29] Update require-closing-tags.md --- docs/rules/require-closing-tags.md | 45 ++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/docs/rules/require-closing-tags.md b/docs/rules/require-closing-tags.md index e9650f2a..752fcce4 100644 --- a/docs/rules/require-closing-tags.md +++ b/docs/rules/require-closing-tags.md @@ -39,6 +39,7 @@ This rule has an object option for [Void Elements](https://html.spec.whatwg.org/ - `"allowSelfClosingCustom": false`: (default) disallow self-closing for the custom tags. - `"allowSelfClosingCustom": true`: allow self-closing for the custom tags. +- `"customPattern": "-"`: regex format for tags allowed by `"allowSelfClosingCustom"`. #### selfClosing : "never" @@ -94,16 +95,56 @@ Examples of **correct** code for the `{ "allowSelfClosingCustom": false }` optio #### "allowSelfClosingCustom": true +Examples of **incorrect** code for the `{ "allowSelfClosingCustom": false }` option: + + +```html,incorrect + +``` + Examples of **correct** code for the `{ "allowSelfClosingCustom": true }` option: ```html,correct - +children + +``` - +#### "customPattern" + +Examples of **incorrect** code for the options below: + +```js +{ + selfClosing: "always", + allowSelfClosingCustom: true, + customPattern: ":", +} +``` + + +```html,incorrect + ``` +Examples of **correct** code for the `options below: + +```js +{ + selfClosing: "always", + allowSelfClosingCustom: true, + customPattern: ":", +} +``` + + +```html,correct +children + + +``` + ## Further Reading - [Void Elements](https://html.spec.whatwg.org/multipage/syntax.html#void-elements) From f8102c8fae3140630c944809476c940b311e6476 Mon Sep 17 00:00:00 2001 From: "Sean S. LeBlanc" Date: Wed, 29 May 2024 15:38:07 -0400 Subject: [PATCH 14/29] add `mspace` to spellcheck https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mspace --- .cspell.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.cspell.json b/.cspell.json index 5b29a46c..7695b0b0 100644 --- a/.cspell.json +++ b/.cspell.json @@ -31,6 +31,7 @@ "noembed", "roletype", "nextid", - "screenreader" + "screenreader", + "mspace" ] } From c1b4fdb37db487916a1c8fd7008522cd82d458a0 Mon Sep 17 00:00:00 2001 From: "Sean S. LeBlanc" Date: Wed, 29 May 2024 15:44:40 -0400 Subject: [PATCH 15/29] prettier --- .../lib/rules/require-closing-tags.js | 17 ++++++++++++----- .../tests/rules/require-closing-tags.test.js | 6 +++--- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/packages/eslint-plugin/lib/rules/require-closing-tags.js b/packages/eslint-plugin/lib/rules/require-closing-tags.js index 9c62bfa6..6bf6fb34 100644 --- a/packages/eslint-plugin/lib/rules/require-closing-tags.js +++ b/packages/eslint-plugin/lib/rules/require-closing-tags.js @@ -62,8 +62,12 @@ module.exports = { context.options && context.options.length ? context.options[0].allowSelfClosingCustom === true : false; - const customPattern = - new RegExp(context.options && context.options.length && context.options[0].customPattern || '-'); + const customPattern = new RegExp( + (context.options && + context.options.length && + context.options[0].customPattern) || + "-" + ); /** * @param {TagNode} node @@ -123,19 +127,22 @@ module.exports = { Tag(node) { const isVoidElement = VOID_ELEMENTS_SET.has(node.name); const isCustomElement = !!node.name.match(customPattern); - const canSelfClose = isVoidElement || foreignContext.length > 0 || (isCustomElement && allowSelfClosingCustom && !node.children.length); + const canSelfClose = + isVoidElement || + foreignContext.length > 0 || + (isCustomElement && allowSelfClosingCustom && !node.children.length); if (node.selfClosing || canSelfClose) { checkVoidElement(node, preferSelfClose && canSelfClose, canSelfClose); } else if (node.openEnd.value !== "/>") { checkClosingTag(node); } - if (['svg', 'math'].includes(node.name)) foreignContext.push(node.name); + if (["svg", "math"].includes(node.name)) foreignContext.push(node.name); }, /** * @param {TagNode} node */ "Tag:exit"(node) { - if (node.name === foreignContext[foreignContext.length-1]) { + if (node.name === foreignContext[foreignContext.length - 1]) { foreignContext.pop(); } }, diff --git a/packages/eslint-plugin/tests/rules/require-closing-tags.test.js b/packages/eslint-plugin/tests/rules/require-closing-tags.test.js index d0372359..625d263c 100644 --- a/packages/eslint-plugin/tests/rules/require-closing-tags.test.js +++ b/packages/eslint-plugin/tests/rules/require-closing-tags.test.js @@ -77,7 +77,7 @@ ruleTester.run("require-closing-tags", rule, { { selfClosing: "always", allowSelfClosingCustom: true, - customPattern: ':', + customPattern: ":", }, ], }, @@ -207,7 +207,7 @@ ruleTester.run("require-closing-tags", rule, { { selfClosing: "always", allowSelfClosingCustom: true, - customPattern: ':', + customPattern: ":", }, ], output: null, @@ -225,7 +225,7 @@ ruleTester.run("require-closing-tags", rule, { allowSelfClosingCustom: true, }, ], - output: '', + output: "", errors: [ { messageId: "missingSelf", From 6b3a20febda3384bde2839bbcede1c35a351ef29 Mon Sep 17 00:00:00 2001 From: "Sean S. LeBlanc" Date: Sun, 2 Jun 2024 18:54:02 -0400 Subject: [PATCH 16/29] `customPattern` string -> `customPatterns` string array --- docs/rules/require-closing-tags.md | 8 ++++---- .../lib/rules/require-closing-tags.js | 19 +++++++++++-------- .../tests/rules/require-closing-tags.test.js | 4 ++-- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/docs/rules/require-closing-tags.md b/docs/rules/require-closing-tags.md index 752fcce4..672a831a 100644 --- a/docs/rules/require-closing-tags.md +++ b/docs/rules/require-closing-tags.md @@ -39,7 +39,7 @@ This rule has an object option for [Void Elements](https://html.spec.whatwg.org/ - `"allowSelfClosingCustom": false`: (default) disallow self-closing for the custom tags. - `"allowSelfClosingCustom": true`: allow self-closing for the custom tags. -- `"customPattern": "-"`: regex format for tags allowed by `"allowSelfClosingCustom"`. +- `"customPatterns": ["-"]`: an array of strings representing regular expression pattern, defines tags allowed by `"allowSelfClosingCustom"`. #### selfClosing : "never" @@ -110,7 +110,7 @@ Examples of **correct** code for the `{ "allowSelfClosingCustom": true }` option ``` -#### "customPattern" +#### "customPatterns" Examples of **incorrect** code for the options below: @@ -118,7 +118,7 @@ Examples of **incorrect** code for the options below: { selfClosing: "always", allowSelfClosingCustom: true, - customPattern: ":", + customPatterns: [":"], } ``` @@ -134,7 +134,7 @@ Examples of **correct** code for the `options below: { selfClosing: "always", allowSelfClosingCustom: true, - customPattern: ":", + customPatterns: [":"], } ``` diff --git a/packages/eslint-plugin/lib/rules/require-closing-tags.js b/packages/eslint-plugin/lib/rules/require-closing-tags.js index 6bf6fb34..9285167f 100644 --- a/packages/eslint-plugin/lib/rules/require-closing-tags.js +++ b/packages/eslint-plugin/lib/rules/require-closing-tags.js @@ -37,8 +37,11 @@ module.exports = { allowSelfClosingCustom: { type: "boolean", }, - customPattern: { - type: "string", + customPatterns: { + type: "array", + items: { + type: "string", + }, }, }, additionalProperties: false, @@ -62,12 +65,12 @@ module.exports = { context.options && context.options.length ? context.options[0].allowSelfClosingCustom === true : false; - const customPattern = new RegExp( - (context.options && + /** @type {RegExp[]} */ + const customPatterns = + ((context.options && context.options.length && - context.options[0].customPattern) || - "-" - ); + context.options[0].customPatterns) || + ["-"]).map(i => new RegExp(i)); /** * @param {TagNode} node @@ -126,7 +129,7 @@ module.exports = { return { Tag(node) { const isVoidElement = VOID_ELEMENTS_SET.has(node.name); - const isCustomElement = !!node.name.match(customPattern); + const isCustomElement = !!customPatterns.some(i => node.name.match(i)); const canSelfClose = isVoidElement || foreignContext.length > 0 || diff --git a/packages/eslint-plugin/tests/rules/require-closing-tags.test.js b/packages/eslint-plugin/tests/rules/require-closing-tags.test.js index 625d263c..cdc021af 100644 --- a/packages/eslint-plugin/tests/rules/require-closing-tags.test.js +++ b/packages/eslint-plugin/tests/rules/require-closing-tags.test.js @@ -77,7 +77,7 @@ ruleTester.run("require-closing-tags", rule, { { selfClosing: "always", allowSelfClosingCustom: true, - customPattern: ":", + customPatterns: [":"], }, ], }, @@ -207,7 +207,7 @@ ruleTester.run("require-closing-tags", rule, { { selfClosing: "always", allowSelfClosingCustom: true, - customPattern: ":", + customPatterns: [":"], }, ], output: null, From 48e51d3bcd7dd6f0a45b62a07e86e6cbcfeb481d Mon Sep 17 00:00:00 2001 From: "Sean S. LeBlanc" Date: Sun, 2 Jun 2024 18:55:01 -0400 Subject: [PATCH 17/29] format --- .../eslint-plugin/lib/rules/require-closing-tags.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/eslint-plugin/lib/rules/require-closing-tags.js b/packages/eslint-plugin/lib/rules/require-closing-tags.js index 9285167f..f01fa70e 100644 --- a/packages/eslint-plugin/lib/rules/require-closing-tags.js +++ b/packages/eslint-plugin/lib/rules/require-closing-tags.js @@ -66,11 +66,11 @@ module.exports = { ? context.options[0].allowSelfClosingCustom === true : false; /** @type {RegExp[]} */ - const customPatterns = - ((context.options && + const customPatterns = ( + (context.options && context.options.length && - context.options[0].customPatterns) || - ["-"]).map(i => new RegExp(i)); + context.options[0].customPatterns) || ["-"] + ).map((i) => new RegExp(i)); /** * @param {TagNode} node @@ -129,7 +129,9 @@ module.exports = { return { Tag(node) { const isVoidElement = VOID_ELEMENTS_SET.has(node.name); - const isCustomElement = !!customPatterns.some(i => node.name.match(i)); + const isCustomElement = !!customPatterns.some((i) => + node.name.match(i) + ); const canSelfClose = isVoidElement || foreignContext.length > 0 || From fc25c1c51e9cd1a74950661d8f0f70d829ecbcfb Mon Sep 17 00:00:00 2001 From: "Sean S. LeBlanc" Date: Sun, 2 Jun 2024 18:57:29 -0400 Subject: [PATCH 18/29] lint --- .../eslint-plugin/lib/rules/require-closing-tags.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/eslint-plugin/lib/rules/require-closing-tags.js b/packages/eslint-plugin/lib/rules/require-closing-tags.js index f01fa70e..5ee69f96 100644 --- a/packages/eslint-plugin/lib/rules/require-closing-tags.js +++ b/packages/eslint-plugin/lib/rules/require-closing-tags.js @@ -65,12 +65,11 @@ module.exports = { context.options && context.options.length ? context.options[0].allowSelfClosingCustom === true : false; - /** @type {RegExp[]} */ - const customPatterns = ( - (context.options && - context.options.length && - context.options[0].customPatterns) || ["-"] - ).map((i) => new RegExp(i)); + /** @type {string[]} */ + const customPatternsOption = (context.options && + context.options.length && + context.options[0].customPatterns) || ["-"]; + const customPatterns = customPatternsOption.map((i) => new RegExp(i)); /** * @param {TagNode} node From 88157f8788149696d12c2789960acdde2fa69efa Mon Sep 17 00:00:00 2001 From: "Sean S. LeBlanc" Date: Tue, 4 Jun 2024 11:19:16 -0400 Subject: [PATCH 19/29] Update docs/rules/require-closing-tags.md Co-authored-by: YeonJuan --- docs/rules/require-closing-tags.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rules/require-closing-tags.md b/docs/rules/require-closing-tags.md index 672a831a..31b7a7d8 100644 --- a/docs/rules/require-closing-tags.md +++ b/docs/rules/require-closing-tags.md @@ -128,7 +128,7 @@ Examples of **incorrect** code for the options below: ``` -Examples of **correct** code for the `options below: +Examples of **correct** code for the options below: ```js { From 94a5e731da649a82ce26fbebf79b033705a21a01 Mon Sep 17 00:00:00 2001 From: "Sean S. LeBlanc" Date: Tue, 4 Jun 2024 15:02:40 -0400 Subject: [PATCH 20/29] update test to expect removal of closing tag when fixing --- packages/eslint-plugin/tests/rules/require-closing-tags.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/eslint-plugin/tests/rules/require-closing-tags.test.js b/packages/eslint-plugin/tests/rules/require-closing-tags.test.js index cdc021af..8612519e 100644 --- a/packages/eslint-plugin/tests/rules/require-closing-tags.test.js +++ b/packages/eslint-plugin/tests/rules/require-closing-tags.test.js @@ -225,7 +225,7 @@ ruleTester.run("require-closing-tags", rule, { allowSelfClosingCustom: true, }, ], - output: "", + output: "", errors: [ { messageId: "missingSelf", From 3b10e93f183b903e88bbb93272080b8c400f3f3c Mon Sep 17 00:00:00 2001 From: "Sean S. LeBlanc" Date: Tue, 4 Jun 2024 15:11:32 -0400 Subject: [PATCH 21/29] remove closing tag in fixed output --- packages/eslint-plugin/lib/rules/require-closing-tags.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/eslint-plugin/lib/rules/require-closing-tags.js b/packages/eslint-plugin/lib/rules/require-closing-tags.js index 5ee69f96..214241bb 100644 --- a/packages/eslint-plugin/lib/rules/require-closing-tags.js +++ b/packages/eslint-plugin/lib/rules/require-closing-tags.js @@ -104,7 +104,10 @@ module.exports = { if (!fixable) { return null; } - return fixer.replaceText(node.openEnd, " />"); + return [ + fixer.replaceText(node.openEnd, " />"), + fixer.remove(node.close), + ]; }, }); } From e2db05fb5e80514ceb57cf0fae64703fff939b88 Mon Sep 17 00:00:00 2001 From: "Sean S. LeBlanc" Date: Tue, 4 Jun 2024 15:20:01 -0400 Subject: [PATCH 22/29] update fixes --- packages/eslint-plugin/lib/rules/require-closing-tags.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/eslint-plugin/lib/rules/require-closing-tags.js b/packages/eslint-plugin/lib/rules/require-closing-tags.js index 214241bb..faedf342 100644 --- a/packages/eslint-plugin/lib/rules/require-closing-tags.js +++ b/packages/eslint-plugin/lib/rules/require-closing-tags.js @@ -104,10 +104,10 @@ module.exports = { if (!fixable) { return null; } - return [ - fixer.replaceText(node.openEnd, " />"), - fixer.remove(node.close), - ]; + const fixes = []; + fixes.push(fixer.replaceText(node.openEnd, " />")); + if (node.close) fixes.push(fixer.remove(node.close)); + return fixes; }, }); } From 363b5f1b26954aa43b958d5db3b289fdad854d0d Mon Sep 17 00:00:00 2001 From: "Sean S. LeBlanc" Date: Thu, 6 Jun 2024 14:29:48 -0400 Subject: [PATCH 23/29] update tests to reflect new independent options spec --- .../tests/rules/require-closing-tags.test.js | 50 ++++--------------- 1 file changed, 9 insertions(+), 41 deletions(-) diff --git a/packages/eslint-plugin/tests/rules/require-closing-tags.test.js b/packages/eslint-plugin/tests/rules/require-closing-tags.test.js index 8612519e..3927979a 100644 --- a/packages/eslint-plugin/tests/rules/require-closing-tags.test.js +++ b/packages/eslint-plugin/tests/rules/require-closing-tags.test.js @@ -23,7 +23,7 @@ ruleTester.run("require-closing-tags", rule, { code: ` `, options: [ { - allowSelfClosingCustom: false, + selfClosingCustomPatterns: [], }, ], }, @@ -31,8 +31,7 @@ ruleTester.run("require-closing-tags", rule, { code: ``, options: [ { - selfClosing: "always", - allowSelfClosingCustom: true, + selfClosingCustomPatterns: ['-'], }, ], }, @@ -40,8 +39,7 @@ ruleTester.run("require-closing-tags", rule, { code: ``, options: [ { - selfClosing: "always", - allowSelfClosingCustom: true, + selfClosingCustomPatterns: ['-'], }, ], }, @@ -49,7 +47,7 @@ ruleTester.run("require-closing-tags", rule, { code: ` `, options: [ { - allowSelfClosingCustom: true, + selfClosingCustomPatterns: ['-'], }, ], }, @@ -57,8 +55,7 @@ ruleTester.run("require-closing-tags", rule, { code: ``, options: [ { - selfClosing: "always", - allowSelfClosingCustom: true, + selfClosingCustomPatterns: ['-'], }, ], }, @@ -66,18 +63,7 @@ ruleTester.run("require-closing-tags", rule, { code: `children`, options: [ { - selfClosing: "always", - allowSelfClosingCustom: true, - }, - ], - }, - { - code: ``, - options: [ - { - selfClosing: "always", - allowSelfClosingCustom: true, - customPatterns: [":"], + selfClosingCustomPatterns: ['-'], }, ], }, @@ -178,7 +164,7 @@ ruleTester.run("require-closing-tags", rule, { code: ``, options: [ { - allowSelfClosingCustom: false, + selfClosingCustomPatterns: [], }, ], errors: [ @@ -191,26 +177,9 @@ ruleTester.run("require-closing-tags", rule, { code: ``, options: [ { - allowSelfClosingCustom: false, + selfClosingCustomPatterns: [], }, ], - output: null, - errors: [ - { - messageId: "unexpected", - }, - ], - }, - { - code: ``, - options: [ - { - selfClosing: "always", - allowSelfClosingCustom: true, - customPatterns: [":"], - }, - ], - output: null, errors: [ { messageId: "unexpected", @@ -221,8 +190,7 @@ ruleTester.run("require-closing-tags", rule, { code: ``, options: [ { - selfClosing: "always", - allowSelfClosingCustom: true, + selfClosingCustomPatterns: ['-'], }, ], output: "", From 71c72dadb4efd384b7e7c38f69cc34009358e318 Mon Sep 17 00:00:00 2001 From: "Sean S. LeBlanc" Date: Thu, 6 Jun 2024 14:49:57 -0400 Subject: [PATCH 24/29] replace `allowSelfClosingCustom` + `customPatterns` with independent `selfClosingCustomPatterns` option and update foreign context handling to compensate --- .../lib/rules/require-closing-tags.js | 32 +++++++------------ 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/packages/eslint-plugin/lib/rules/require-closing-tags.js b/packages/eslint-plugin/lib/rules/require-closing-tags.js index faedf342..bf6807bd 100644 --- a/packages/eslint-plugin/lib/rules/require-closing-tags.js +++ b/packages/eslint-plugin/lib/rules/require-closing-tags.js @@ -34,10 +34,7 @@ module.exports = { selfClosing: { enum: ["always", "never"], }, - allowSelfClosingCustom: { - type: "boolean", - }, - customPatterns: { + selfClosingCustomPatterns: { type: "array", items: { type: "string", @@ -57,19 +54,15 @@ module.exports = { create(context) { /** @type {string[]} */ const foreignContext = []; - const preferSelfClose = + const shouldSelfCloseVoid = context.options && context.options.length ? context.options[0].selfClosing === "always" : false; - const allowSelfClosingCustom = - context.options && context.options.length - ? context.options[0].allowSelfClosingCustom === true - : false; /** @type {string[]} */ - const customPatternsOption = (context.options && + const selfClosingCustomPatternsOption = (context.options && context.options.length && - context.options[0].customPatterns) || ["-"]; - const customPatterns = customPatternsOption.map((i) => new RegExp(i)); + context.options[0].selfClosingCustomPatterns) || ["-"]; + const selfClosingCustomPatterns = selfClosingCustomPatternsOption.map((i) => new RegExp(i)); /** * @param {TagNode} node @@ -131,15 +124,14 @@ module.exports = { return { Tag(node) { const isVoidElement = VOID_ELEMENTS_SET.has(node.name); - const isCustomElement = !!customPatterns.some((i) => - node.name.match(i) - ); - const canSelfClose = - isVoidElement || - foreignContext.length > 0 || - (isCustomElement && allowSelfClosingCustom && !node.children.length); + const isSelfClosingCustomElement = !!selfClosingCustomPatterns.some((i) => node.name.match(i)); + const isForeign = foreignContext.length > 0; + const shouldSelfCloseCustom = isSelfClosingCustomElement && !node.children.length; + const shouldSelfCloseForeign = node.selfClosing; + const shouldSelfClose = (isVoidElement && shouldSelfCloseVoid) || (isSelfClosingCustomElement && shouldSelfCloseCustom) || (isForeign && shouldSelfCloseForeign); + const canSelfClose = isVoidElement || isSelfClosingCustomElement || isForeign; if (node.selfClosing || canSelfClose) { - checkVoidElement(node, preferSelfClose && canSelfClose, canSelfClose); + checkVoidElement(node, shouldSelfClose, canSelfClose); } else if (node.openEnd.value !== "/>") { checkClosingTag(node); } From 0ca6eeb348876425708ccf2993c7ae04e056eae3 Mon Sep 17 00:00:00 2001 From: "Sean S. LeBlanc" Date: Thu, 6 Jun 2024 14:55:39 -0400 Subject: [PATCH 25/29] Update require-closing-tags.md --- docs/rules/require-closing-tags.md | 56 ++++++------------------------ 1 file changed, 10 insertions(+), 46 deletions(-) diff --git a/docs/rules/require-closing-tags.md b/docs/rules/require-closing-tags.md index 31b7a7d8..8728f37a 100644 --- a/docs/rules/require-closing-tags.md +++ b/docs/rules/require-closing-tags.md @@ -30,16 +30,15 @@ Examples of **correct** code for this rule: ### Options -This rule has an object option for [Void Elements](https://html.spec.whatwg.org/multipage/syntax.html#void-elements). +This rule has an object option for [Void Elements](https://html.spec.whatwg.org/multipage/syntax.html#void-elements) and custom element patterns. - `"selfClosing": "never"`: (default) disallow using self closing tag on [Void Elements](https://html.spec.whatwg.org/multipage/syntax.html#void-elements). - `"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. +- `"selfClosingCustomPatterns": ["-"]`: (default) an array of strings representing regular expression pattern, enforce self-closing for tags including `-` in the name. -- `"allowSelfClosingCustom": true`: allow self-closing for the custom tags. -- `"customPatterns": ["-"]`: an array of strings representing regular expression pattern, defines tags allowed by `"allowSelfClosingCustom"`. +- `"selfClosingCustomPatterns": []`: disallow self-closing for custom tags. #### selfClosing : "never" @@ -77,32 +76,16 @@ Examples of **correct** code for the `{ "selfClosing": "always" }` option: ``` -#### "allowSelfClosingCustom": false +#### selfClosingCustomPatterns: ["-"] -Examples of **incorrect** code for the `{ "allowSelfClosingCustom": false }` option: - - -```html,incorrect - -``` - -Examples of **correct** code for the `{ "allowSelfClosingCustom": false }` option: - - -```html,correct - -``` - -#### "allowSelfClosingCustom": true - -Examples of **incorrect** code for the `{ "allowSelfClosingCustom": false }` option: +Examples of **incorrect** code for the `{ "selfClosingCustomPatterns": ["-"] }` option: ```html,incorrect ``` -Examples of **correct** code for the `{ "allowSelfClosingCustom": true }` option: +Examples of **correct** code for the `{ "selfClosingCustomPatterns": ["-"] }` option: ```html,correct @@ -110,39 +93,20 @@ Examples of **correct** code for the `{ "allowSelfClosingCustom": true }` option ``` -#### "customPatterns" +#### selfClosingCustomPatterns: [] -Examples of **incorrect** code for the options below: - -```js -{ - selfClosing: "always", - allowSelfClosingCustom: true, - customPatterns: [":"], -} -``` +Examples of **incorrect** code for the `{ "allowSelfClosingCustom": [] }` option: ```html,incorrect - ``` -Examples of **correct** code for the options below: - -```js -{ - selfClosing: "always", - allowSelfClosingCustom: true, - customPatterns: [":"], -} -``` +Examples of **correct** code for the `{ "allowSelfClosingCustom": [] }` option: ```html,correct -children - - + ``` ## Further Reading From 951289cb2a6ff8a48409794e9afb0e4a23d2694d Mon Sep 17 00:00:00 2001 From: "Sean S. LeBlanc" Date: Thu, 6 Jun 2024 14:56:19 -0400 Subject: [PATCH 26/29] format --- .../lib/rules/require-closing-tags.js | 19 ++++++++++++++----- .../tests/rules/require-closing-tags.test.js | 12 ++++++------ 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/packages/eslint-plugin/lib/rules/require-closing-tags.js b/packages/eslint-plugin/lib/rules/require-closing-tags.js index bf6807bd..7e64320f 100644 --- a/packages/eslint-plugin/lib/rules/require-closing-tags.js +++ b/packages/eslint-plugin/lib/rules/require-closing-tags.js @@ -62,7 +62,9 @@ module.exports = { const selfClosingCustomPatternsOption = (context.options && context.options.length && context.options[0].selfClosingCustomPatterns) || ["-"]; - const selfClosingCustomPatterns = selfClosingCustomPatternsOption.map((i) => new RegExp(i)); + const selfClosingCustomPatterns = selfClosingCustomPatternsOption.map( + (i) => new RegExp(i) + ); /** * @param {TagNode} node @@ -124,12 +126,19 @@ module.exports = { return { Tag(node) { const isVoidElement = VOID_ELEMENTS_SET.has(node.name); - const isSelfClosingCustomElement = !!selfClosingCustomPatterns.some((i) => node.name.match(i)); + const isSelfClosingCustomElement = !!selfClosingCustomPatterns.some( + (i) => node.name.match(i) + ); const isForeign = foreignContext.length > 0; - const shouldSelfCloseCustom = isSelfClosingCustomElement && !node.children.length; + const shouldSelfCloseCustom = + isSelfClosingCustomElement && !node.children.length; const shouldSelfCloseForeign = node.selfClosing; - const shouldSelfClose = (isVoidElement && shouldSelfCloseVoid) || (isSelfClosingCustomElement && shouldSelfCloseCustom) || (isForeign && shouldSelfCloseForeign); - const canSelfClose = isVoidElement || isSelfClosingCustomElement || isForeign; + const shouldSelfClose = + (isVoidElement && shouldSelfCloseVoid) || + (isSelfClosingCustomElement && shouldSelfCloseCustom) || + (isForeign && shouldSelfCloseForeign); + const canSelfClose = + isVoidElement || isSelfClosingCustomElement || isForeign; if (node.selfClosing || canSelfClose) { checkVoidElement(node, shouldSelfClose, canSelfClose); } else if (node.openEnd.value !== "/>") { diff --git a/packages/eslint-plugin/tests/rules/require-closing-tags.test.js b/packages/eslint-plugin/tests/rules/require-closing-tags.test.js index 3927979a..43cc256d 100644 --- a/packages/eslint-plugin/tests/rules/require-closing-tags.test.js +++ b/packages/eslint-plugin/tests/rules/require-closing-tags.test.js @@ -31,7 +31,7 @@ ruleTester.run("require-closing-tags", rule, { code: ``, options: [ { - selfClosingCustomPatterns: ['-'], + selfClosingCustomPatterns: ["-"], }, ], }, @@ -39,7 +39,7 @@ ruleTester.run("require-closing-tags", rule, { code: ``, options: [ { - selfClosingCustomPatterns: ['-'], + selfClosingCustomPatterns: ["-"], }, ], }, @@ -47,7 +47,7 @@ ruleTester.run("require-closing-tags", rule, { code: ` `, options: [ { - selfClosingCustomPatterns: ['-'], + selfClosingCustomPatterns: ["-"], }, ], }, @@ -55,7 +55,7 @@ ruleTester.run("require-closing-tags", rule, { code: ``, options: [ { - selfClosingCustomPatterns: ['-'], + selfClosingCustomPatterns: ["-"], }, ], }, @@ -63,7 +63,7 @@ ruleTester.run("require-closing-tags", rule, { code: `children`, options: [ { - selfClosingCustomPatterns: ['-'], + selfClosingCustomPatterns: ["-"], }, ], }, @@ -190,7 +190,7 @@ ruleTester.run("require-closing-tags", rule, { code: ``, options: [ { - selfClosingCustomPatterns: ['-'], + selfClosingCustomPatterns: ["-"], }, ], output: "", From 6df37ebce5a5cbd12437d95cd0a9166cb044991a Mon Sep 17 00:00:00 2001 From: "Sean S. LeBlanc" Date: Fri, 7 Jun 2024 07:46:29 -0400 Subject: [PATCH 27/29] update default to disallow self-closing custom tags --- packages/eslint-plugin/lib/rules/require-closing-tags.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/eslint-plugin/lib/rules/require-closing-tags.js b/packages/eslint-plugin/lib/rules/require-closing-tags.js index 7e64320f..0ed37fd1 100644 --- a/packages/eslint-plugin/lib/rules/require-closing-tags.js +++ b/packages/eslint-plugin/lib/rules/require-closing-tags.js @@ -61,7 +61,7 @@ module.exports = { /** @type {string[]} */ const selfClosingCustomPatternsOption = (context.options && context.options.length && - context.options[0].selfClosingCustomPatterns) || ["-"]; + context.options[0].selfClosingCustomPatterns) || []; const selfClosingCustomPatterns = selfClosingCustomPatternsOption.map( (i) => new RegExp(i) ); From 3ada9c87ea9066acc63acd6ccf7b2ccdcbff510b Mon Sep 17 00:00:00 2001 From: "Sean S. LeBlanc" Date: Fri, 7 Jun 2024 07:47:17 -0400 Subject: [PATCH 28/29] update docs --- docs/rules/require-closing-tags.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/rules/require-closing-tags.md b/docs/rules/require-closing-tags.md index 8728f37a..89cee20c 100644 --- a/docs/rules/require-closing-tags.md +++ b/docs/rules/require-closing-tags.md @@ -36,9 +36,9 @@ 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). -- `"selfClosingCustomPatterns": ["-"]`: (default) an array of strings representing regular expression pattern, enforce self-closing for tags including `-` in the name. +- `"selfClosingCustomPatterns": []`: (default) disallow self-closing for custom tags. -- `"selfClosingCustomPatterns": []`: disallow self-closing for custom tags. +- `"selfClosingCustomPatterns": ["-"]`: enforce self-closing for tags matching any of an array of strings representing regular expression pattern (e.g. tags including `-` in the name). #### selfClosing : "never" From 8665ff409f27ff103024aa5feb58cae5a55de144 Mon Sep 17 00:00:00 2001 From: "Sean S. LeBlanc" Date: Fri, 7 Jun 2024 07:55:52 -0400 Subject: [PATCH 29/29] format --- packages/eslint-plugin/lib/rules/require-closing-tags.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/eslint-plugin/lib/rules/require-closing-tags.js b/packages/eslint-plugin/lib/rules/require-closing-tags.js index 0ed37fd1..8685d5fb 100644 --- a/packages/eslint-plugin/lib/rules/require-closing-tags.js +++ b/packages/eslint-plugin/lib/rules/require-closing-tags.js @@ -59,9 +59,11 @@ module.exports = { ? context.options[0].selfClosing === "always" : false; /** @type {string[]} */ - const selfClosingCustomPatternsOption = (context.options && - context.options.length && - context.options[0].selfClosingCustomPatterns) || []; + const selfClosingCustomPatternsOption = + (context.options && + context.options.length && + context.options[0].selfClosingCustomPatterns) || + []; const selfClosingCustomPatterns = selfClosingCustomPatternsOption.map( (i) => new RegExp(i) );