Files
WRNexusJS/packages/dev-toolbar/src/rules/html.ts
T
2026-07-21 12:30:46 +05:30

75 lines
2.6 KiB
TypeScript

import type { DevToolbarRule } from "./types.ts";
import { createIssue } from "./helpers.ts";
export const htmlRules: DevToolbarRule[] = [
{
id: "html/structure",
category: "html",
defaultSeverity: "warning",
description: "Checks document structure and DOM complexity.",
run: ({ document, root }) => {
const issues = [];
const nodeCount = root.querySelectorAll("*").length;
if (nodeCount > 3000)
issues.push(
createIssue({
ruleId: "html/dom-size",
category: "html",
severity: "error",
title: "DOM is extremely large",
message: `The page contains ${nodeCount} elements.`,
recommendation:
"Reduce wrappers, paginate long lists, and render hidden content on demand.",
}),
);
else if (nodeCount > 1500)
issues.push(
createIssue({
ruleId: "html/dom-size",
category: "html",
severity: "warning",
title: "DOM is large",
message: `The page contains ${nodeCount} elements.`,
recommendation: "Review repeated wrappers and off-screen content.",
}),
);
if (!document.querySelector("main"))
issues.push(
createIssue({
ruleId: "html/main-missing",
category: "html",
severity: "warning",
title: "Main landmark is missing",
message: "The document has no main element.",
recommendation: "Wrap the primary page content in a main element.",
}),
);
if (document.querySelectorAll("main").length > 1)
issues.push(
createIssue({
ruleId: "html/multiple-main",
category: "html",
severity: "error",
title: "Multiple main landmarks",
message: "The document contains more than one main element.",
recommendation: "Use one visible main landmark per document.",
}),
);
for (const element of root.querySelectorAll("button button, button a, a a, a button"))
issues.push(
createIssue({
ruleId: "html/nested-interactive",
category: "html",
severity: "error",
title: "Interactive elements are nested",
message: "Nested buttons and links create invalid and confusing interaction behavior.",
element,
recommendation:
"Use one interactive element and style its inner non-interactive content.",
}),
);
return issues;
},
},
];