From ebbb60764c1620be2547d29303ece8a0320d3968 Mon Sep 17 00:00:00 2001 From: TKDev7 Date: Thu, 31 Jul 2025 15:21:52 +0300 Subject: [PATCH 1/5] fix: improve no-html rule's tag location reporting --- src/rules/no-html.js | 12 +++- tests/rules/no-html.test.js | 107 ++++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+), 2 deletions(-) diff --git a/src/rules/no-html.js b/src/rules/no-html.js index 0c463b18..45fcdca8 100644 --- a/src/rules/no-html.js +++ b/src/rules/no-html.js @@ -24,7 +24,7 @@ import { findOffsets } from "../util.js"; // Helpers //----------------------------------------------------------------------------- -const htmlTagPattern = /<([a-z0-9]+(?:-[a-z0-9]+)*)/giu; +const htmlTagPattern = /<([a-z0-9]+(?:-[a-z0-9]+)*)[^>]*>/giu; //----------------------------------------------------------------------------- // Rule Definition @@ -75,6 +75,7 @@ export default { let match; while ((match = htmlTagPattern.exec(node.value)) !== null) { + const fullMatch = match[0]; const tagName = match[1]; const { lineOffset, columnOffset } = findOffsets( node.value, @@ -84,9 +85,16 @@ export default { line: node.position.start.line + lineOffset, column: node.position.start.column + columnOffset, }; + + const firstLineEnd = fullMatch.indexOf("\n"); + const endColumn = + firstLineEnd === -1 + ? start.column + fullMatch.length + : start.column + firstLineEnd; + const end = { line: start.line, - column: start.column + match[0].length + 1, + column: endColumn, }; if (allowed.size === 0 || !allowed.has(tagName)) { diff --git a/tests/rules/no-html.test.js b/tests/rules/no-html.test.js index 8f396c80..5d86cdeb 100644 --- a/tests/rules/no-html.test.js +++ b/tests/rules/no-html.test.js @@ -130,5 +130,112 @@ ruleTester.run("no-html", rule, { }, ], }, + { + code: "Content", + errors: [ + { + messageId: "disallowedElement", + line: 1, + column: 1, + endLine: 1, + endColumn: 8, + data: { name: "span" }, + }, + ], + }, + { + code: '
Some content
', + errors: [ + { + messageId: "disallowedElement", + line: 1, + column: 1, + endLine: 1, + endColumn: 15, + data: { + name: "div", + }, + }, + ], + }, + { + code: '

Content

', + errors: [ + { + messageId: "disallowedElement", + line: 1, + column: 1, + endLine: 1, + endColumn: 42, + data: { + name: "p", + }, + }, + ], + }, + { + code: 'Text', + errors: [ + { + messageId: "disallowedElement", + line: 1, + column: 1, + endLine: 1, + endColumn: 6, + data: { + name: "span", + }, + }, + ], + }, + { + code: '
Content
', + errors: [ + { + messageId: "disallowedElement", + line: 1, + column: 1, + endLine: 1, + endColumn: 24, + data: { name: "div" }, + }, + ], + }, + { + code: '', + errors: [ + { + messageId: "disallowedElement", + line: 1, + column: 1, + endLine: 1, + endColumn: 47, + data: { + name: "input", + }, + }, + ], + }, + { + code: 'Link', + errors: [ + { + messageId: "disallowedElement", + line: 1, + column: 1, + endLine: 1, + endColumn: 13, + data: { name: "a" }, + }, + { + messageId: "disallowedElement", + line: 1, + column: 13, + endLine: 1, + endColumn: 37, + data: { name: "span" }, + }, + ], + }, ], }); From 669dd45832bb2545bcd9d2e485e4781ef9c84a78 Mon Sep 17 00:00:00 2001 From: TKDev7 Date: Tue, 5 Aug 2025 12:31:02 +0300 Subject: [PATCH 2/5] use regex pattern instead of indexOf --- src/rules/no-html.js | 10 ++++++---- tests/rules/no-html.test.js | 30 ++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/rules/no-html.js b/src/rules/no-html.js index 45fcdca8..f0922980 100644 --- a/src/rules/no-html.js +++ b/src/rules/no-html.js @@ -25,6 +25,7 @@ import { findOffsets } from "../util.js"; //----------------------------------------------------------------------------- const htmlTagPattern = /<([a-z0-9]+(?:-[a-z0-9]+)*)[^>]*>/giu; +const nextLinesPattern = /[\r\n][\s\S]*$/u; //----------------------------------------------------------------------------- // Rule Definition @@ -68,7 +69,7 @@ export default { }, create(context) { - const allowed = new Set(context.options[0]?.allowed); + const allowed = new Set(context.options[0].allowed); return { html(node) { @@ -86,11 +87,12 @@ export default { column: node.position.start.column + columnOffset, }; - const firstLineEnd = fullMatch.indexOf("\n"); + const firstNewlineIndex = + fullMatch.search(nextLinesPattern); const endColumn = - firstLineEnd === -1 + firstNewlineIndex === -1 ? start.column + fullMatch.length - : start.column + firstLineEnd; + : start.column + firstNewlineIndex; const end = { line: start.line, diff --git a/tests/rules/no-html.test.js b/tests/rules/no-html.test.js index 5d86cdeb..031a8e14 100644 --- a/tests/rules/no-html.test.js +++ b/tests/rules/no-html.test.js @@ -188,6 +188,36 @@ ruleTester.run("no-html", rule, { }, ], }, + { + code: 'Text', + errors: [ + { + messageId: "disallowedElement", + line: 1, + column: 1, + endLine: 1, + endColumn: 6, + data: { + name: "span", + }, + }, + ], + }, + { + code: 'Text', + errors: [ + { + messageId: "disallowedElement", + line: 1, + column: 1, + endLine: 1, + endColumn: 6, + data: { + name: "span", + }, + }, + ], + }, { code: '
Content
', errors: [ From 5dea7a47f5cf43dc0a82d94d5e9eb3e5af7a437e Mon Sep 17 00:00:00 2001 From: TKDev7 Date: Wed, 6 Aug 2025 23:36:16 +0300 Subject: [PATCH 3/5] correctly handle > in HTML attribute values --- src/rules/no-html.js | 3 ++- tests/rules/no-html.test.js | 45 +++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/rules/no-html.js b/src/rules/no-html.js index f0922980..fbc10494 100644 --- a/src/rules/no-html.js +++ b/src/rules/no-html.js @@ -24,7 +24,8 @@ import { findOffsets } from "../util.js"; // Helpers //----------------------------------------------------------------------------- -const htmlTagPattern = /<([a-z0-9]+(?:-[a-z0-9]+)*)[^>]*>/giu; +const htmlTagPattern = + /<([a-z0-9]+(?:-[a-z0-9]+)*)(?:\s+(?:[^>"']|"[^"]*"|'[^']*')*)?>/giu; const nextLinesPattern = /[\r\n][\s\S]*$/u; //----------------------------------------------------------------------------- diff --git a/tests/rules/no-html.test.js b/tests/rules/no-html.test.js index 031a8e14..3e3ec645 100644 --- a/tests/rules/no-html.test.js +++ b/tests/rules/no-html.test.js @@ -267,5 +267,50 @@ ruleTester.run("no-html", rule, { }, ], }, + { + code: '', + errors: [ + { + messageId: "disallowedElement", + line: 1, + column: 1, + endLine: 1, + endColumn: 26, + data: { + name: "input", + }, + }, + ], + }, + { + code: "", + errors: [ + { + messageId: "disallowedElement", + line: 1, + column: 1, + endLine: 1, + endColumn: 24, + data: { + name: "input", + }, + }, + ], + }, + { + code: '" />', + errors: [ + { + messageId: "disallowedElement", + line: 1, + column: 1, + endLine: 1, + endColumn: 7, + data: { + name: "input", + }, + }, + ], + }, ], }); From c88961df3b9cb4b697736fdb9804ac4b33cdfbf4 Mon Sep 17 00:00:00 2001 From: TKDev7 Date: Sun, 10 Aug 2025 01:12:26 +0300 Subject: [PATCH 4/5] add test --- tests/rules/no-html.test.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/rules/no-html.test.js b/tests/rules/no-html.test.js index 3e3ec645..438f41d5 100644 --- a/tests/rules/no-html.test.js +++ b/tests/rules/no-html.test.js @@ -312,5 +312,25 @@ ruleTester.run("no-html", rule, { }, ], }, + { + code: dedent` + + `, + errors: [ + { + messageId: "disallowedElement", + line: 2, + column: 1, + endLine: 2, + endColumn: 7, + data: { + name: "input", + }, + }, + ], + }, ], }); From 843a4b36d8a02a3b450f4d28eed2c9526793a2cc Mon Sep 17 00:00:00 2001 From: TKDev7 Date: Sat, 16 Aug 2025 17:28:58 +0300 Subject: [PATCH 5/5] simplify regex for detecting line endings --- src/rules/no-html.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rules/no-html.js b/src/rules/no-html.js index fbc10494..a06d14c0 100644 --- a/src/rules/no-html.js +++ b/src/rules/no-html.js @@ -26,7 +26,7 @@ import { findOffsets } from "../util.js"; const htmlTagPattern = /<([a-z0-9]+(?:-[a-z0-9]+)*)(?:\s+(?:[^>"']|"[^"]*"|'[^']*')*)?>/giu; -const nextLinesPattern = /[\r\n][\s\S]*$/u; +const lineEndingPattern = /\r\n?|\n/u; //----------------------------------------------------------------------------- // Rule Definition @@ -89,7 +89,7 @@ export default { }; const firstNewlineIndex = - fullMatch.search(nextLinesPattern); + fullMatch.search(lineEndingPattern); const endColumn = firstNewlineIndex === -1 ? start.column + fullMatch.length