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; }, }, ];