diff --git a/src/rules/no-html.js b/src/rules/no-html.js
index 167c32b6..2d25932b 100644
--- a/src/rules/no-html.js
+++ b/src/rules/no-html.js
@@ -3,12 +3,6 @@
* @author Nicholas C. Zakas
*/
-//-----------------------------------------------------------------------------
-// Imports
-//-----------------------------------------------------------------------------
-
-import { findOffsets } from "../util.js";
-
//-----------------------------------------------------------------------------
// Type Definitions
//-----------------------------------------------------------------------------
@@ -25,7 +19,7 @@ import { findOffsets } from "../util.js";
//-----------------------------------------------------------------------------
const htmlTagPattern =
- /<([a-z0-9]+(?:-[a-z0-9]+)*)(?:\s(?:[^>"']|"[^"]*"|'[^']*')*)?>/giu;
+ /<(?[a-z0-9]+(?:-[a-z0-9]+)*)(?:\s(?:[^>"']|"[^"]*"|'[^']*')*)?>/giu;
const lineEndingPattern = /\r\n?|\n/u;
//-----------------------------------------------------------------------------
@@ -74,48 +68,45 @@ export default {
},
create(context) {
+ const { sourceCode } = context;
const [{ allowed, allowedIgnoreCase }] = context.options;
- const allowedElements = new Set(
- allowedIgnoreCase ? allowed.map(tag => tag.toLowerCase()) : allowed,
- );
+
+ /**
+ * Normalize a tag name based on the `allowedIgnoreCase` option.
+ * @param {string} tagName The tag name to normalize.
+ * @returns {string} The normalized tag name.
+ */
+ function normalizeTagName(tagName) {
+ return allowedIgnoreCase ? tagName.toLowerCase() : tagName;
+ }
+
+ const allowedElements = new Set(allowed.map(normalizeTagName));
return {
html(node) {
+ /** @type {RegExpExecArray} */
let match;
while ((match = htmlTagPattern.exec(node.value)) !== null) {
const fullMatch = match[0];
- const tagName = match[1];
- const { lineOffset, columnOffset } = findOffsets(
- node.value,
- match.index,
- );
- const start = {
- line: node.position.start.line + lineOffset,
- column: node.position.start.column + columnOffset,
- };
-
+ const { tagName } = match.groups;
const firstNewlineIndex =
fullMatch.search(lineEndingPattern);
- const endColumn =
- firstNewlineIndex === -1
- ? start.column + fullMatch.length
- : start.column + firstNewlineIndex;
-
- const end = {
- line: start.line,
- column: endColumn,
- };
-
- const tagToCheck = allowedIgnoreCase
- ? tagName.toLowerCase()
- : tagName;
- if (
- allowedElements.size === 0 ||
- !allowedElements.has(tagToCheck)
- ) {
+
+ const startOffset = // Adjust `htmlTagPattern` match index to the full source code.
+ match.index + node.position.start.offset;
+ const endOffset =
+ startOffset +
+ (firstNewlineIndex === -1
+ ? fullMatch.length
+ : firstNewlineIndex);
+
+ if (!allowedElements.has(normalizeTagName(tagName))) {
context.report({
- loc: { start, end },
+ loc: {
+ start: sourceCode.getLocFromIndex(startOffset),
+ end: sourceCode.getLocFromIndex(endOffset),
+ },
messageId: "disallowedElement",
data: {
name: tagName,