diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 000000000..c47f9a1ab --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,35 @@ +# Agents + + + +## Markdown Code Guide + +- Markdown should be formatted with Prettier. +- There should be a line break before the first list item. +- There should be a line break after headings. + +## YAML Code Guide + +- YML files should begin with --- on the first line. +- YML should be formatted with Prettier. + +## Communication (MANDATORY) + +- No apologies - State facts and solutions directly. +- Concise style - Professional, avoid repetition and filler. +- Single chunk edits - All file edits in one operation. +- Real file links only - No placeholder files. +- No unnecessary confirmations - Use available context. + +## Quality & Validation (MANDATORY) + +- Never assume commands worked without verification. +- 98%+ confidence threshold for definitive claims. +- Immediate re-investigation when findings don't match expectations. +- Cross-tool validation when tools fail. + +## Code Standards (MANDATORY) + +- No emojis in code or documentation. +- Only implement what's requested. +- Preserve existing structures - Don't remove unrelated code. diff --git a/dist/core/core.js b/dist/core/core.js index 293b1ccbd..19f238fbf 100644 --- a/dist/core/core.js +++ b/dist/core/core.js @@ -38,8 +38,9 @@ class HTMLHintCore { }); return ''; }); + const disabledRulesMap = this.parseDisableComments(html); const parser = new htmlparser_1.default(); - const reporter = new reporter_1.default(html, ruleset); + const reporter = new reporter_1.default(html, ruleset, disabledRulesMap); const rules = this.rules; let rule; for (const id in ruleset) { @@ -51,6 +52,90 @@ class HTMLHintCore { parser.parse(html); return reporter.messages; } + parseDisableComments(html) { + var _a; + const disabledRulesMap = {}; + const lines = html.split(/\r?\n/); + const regComment = //gi; + const comments = []; + let match; + while ((match = regComment.exec(html)) !== null) { + const beforeMatch = html.substring(0, match.index); + const lineNumber = beforeMatch.split(/\r?\n/).length; + const command = match[1].toLowerCase(); + const isNextLine = match[0].includes('-next-line'); + const rulesStr = (_a = match[2]) === null || _a === void 0 ? void 0 : _a.trim(); + comments.push({ + line: lineNumber, + command, + isNextLine, + rulesStr, + }); + } + let currentDisabledRules = null; + let isAllDisabled = false; + for (let i = 0; i < lines.length; i++) { + const line = i + 1; + const commentOnLine = comments.find((c) => c.line === line); + if (commentOnLine) { + if (commentOnLine.command === 'disable') { + if (commentOnLine.isNextLine) { + const nextLine = line + 1; + if (commentOnLine.rulesStr) { + const rules = commentOnLine.rulesStr + .split(/\s+/) + .filter((r) => r.length > 0); + if (!disabledRulesMap[nextLine]) { + disabledRulesMap[nextLine] = {}; + } + if (!disabledRulesMap[nextLine].rules) { + disabledRulesMap[nextLine].rules = new Set(); + } + rules.forEach((r) => disabledRulesMap[nextLine].rules.add(r)); + } + else { + if (!disabledRulesMap[nextLine]) { + disabledRulesMap[nextLine] = {}; + } + disabledRulesMap[nextLine].all = true; + } + } + else { + if (commentOnLine.rulesStr) { + const rules = commentOnLine.rulesStr + .split(/\s+/) + .filter((r) => r.length > 0); + currentDisabledRules = new Set(rules); + isAllDisabled = false; + } + else { + currentDisabledRules = null; + isAllDisabled = true; + } + } + } + else if (commentOnLine.command === 'enable') { + currentDisabledRules = null; + isAllDisabled = false; + } + } + if (currentDisabledRules !== null || isAllDisabled) { + if (!disabledRulesMap[line]) { + disabledRulesMap[line] = {}; + } + if (isAllDisabled && disabledRulesMap[line].all !== true) { + disabledRulesMap[line].all = true; + } + else if (currentDisabledRules) { + if (!disabledRulesMap[line].rules) { + disabledRulesMap[line].rules = new Set(); + } + currentDisabledRules.forEach((r) => disabledRulesMap[line].rules.add(r)); + } + } + } + return disabledRulesMap; + } format(arrMessages, options = {}) { const arrLogs = []; const colors = { @@ -106,4 +191,4 @@ exports.HTMLHint = new HTMLHintCore(); Object.values(HTMLRules).forEach((rule) => { exports.HTMLHint.addRule(rule); }); -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29yZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb3JlL2NvcmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsNkNBQXFDO0FBa0tQLHFCQWxLdkIsb0JBQVUsQ0FrS3VCO0FBakt4Qyx5Q0FBaUM7QUFpS2IsbUJBaktiLGtCQUFRLENBaUthO0FBaEs1QixxQ0FBb0M7QUFnSzNCLDhCQUFTO0FBeEpsQixNQUFNLFlBQVk7SUFBbEI7UUFDUyxVQUFLLEdBQTJCLEVBQUUsQ0FBQTtRQUN6QixtQkFBYyxHQUFZO1lBQ3hDLG1CQUFtQixFQUFFLElBQUk7WUFDekIsZ0JBQWdCLEVBQUUsSUFBSTtZQUN0QiwwQkFBMEIsRUFBRSxJQUFJO1lBQ2hDLGVBQWUsRUFBRSxJQUFJO1lBQ3JCLFVBQVUsRUFBRSxJQUFJO1lBQ2hCLGtCQUFrQixFQUFFLElBQUk7WUFDeEIsV0FBVyxFQUFFLElBQUk7WUFDakIsZUFBZSxFQUFFLElBQUk7WUFDckIscUJBQXFCLEVBQUUsSUFBSTtZQUMzQixlQUFlLEVBQUUsSUFBSTtTQUN0QixDQUFBO0lBOEhILENBQUM7SUE1SFEsT0FBTyxDQUFDLElBQVU7UUFDdkIsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFBO0lBQzVCLENBQUM7SUFFTSxNQUFNLENBQUMsSUFBWSxFQUFFLFVBQW1CLElBQUksQ0FBQyxjQUFjO1FBQ2hFLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDdEMsT0FBTyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUE7UUFDL0IsQ0FBQztRQUdELElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUNqQiwwQ0FBMEMsRUFDMUMsQ0FBQyxHQUFHLEVBQUUsVUFBa0IsRUFBRSxFQUFFO1lBSTFCLFVBQVUsQ0FBQyxPQUFPLENBQ2hCLDJDQUEyQyxFQUMzQyxD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 \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29yZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb3JlL2NvcmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsNkNBQXFDO0FBaVJQLHFCQWpSdkIsb0JBQVUsQ0FpUnVCO0FBaFJ4Qyx5Q0FBaUM7QUFnUmIsbUJBaFJiLGtCQUFRLENBZ1JhO0FBL1E1QixxQ0FBb0M7QUErUTNCLDhCQUFTO0FBdlFsQixNQUFNLFlBQVk7SUFBbEI7UUFDUyxVQUFLLEdBQTJCLEVBQUUsQ0FBQTtRQUN6QixtQkFBYyxHQUFZO1lBQ3hDLG1CQUFtQixFQUFFLElBQUk7WUFDekIsZ0JBQWdCLEVBQUUsSUFBSTtZQUN0QiwwQkFBMEIsRUFBRSxJQUFJO1lBQ2hDLGVBQWUsRUFBRSxJQUFJO1lBQ3JCLFVBQVUsRUFBRSxJQUFJO1lBQ2hCLGtCQUFrQixFQUFFLElBQUk7WUFDeEIsV0FBVyxFQUFFLElBQUk7WUFDakIsZUFBZSxFQUFFLElBQUk7WUFDckIscUJBQXFCLEVBQUUsSUFBSTtZQUMzQixlQUFlLEVBQUUsSUFBSTtTQUN0QixDQUFBO0lBNk9ILENBQUM7SUEzT1EsT0FBTyxDQUFDLElBQVU7UUFDdkIsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFBO0lBQzVCLENBQUM7SUFFTSxNQUFNLENBQUMsSUFBWSxFQUFFLFVBQW1CLElBQUksQ0FBQyxjQUFjO1FBQ2hFLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDdEMsT0FBTyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUE7UUFDL0IsQ0FBQztRQUdELElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUNqQiwwQ0FBMEMsRUFDMUMsQ0FBQyxHQUFHLEVBQUUsVUFBa0IsRUFBRSxFQUFFO1lBSTFCLFVBQVUsQ0FBQyxPQUFPLENBQ2hCLDJDQUEyQyxFQUMzQyxD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 \ No newline at end of file diff --git a/dist/core/reporter.js b/dist/core/reporter.js index 5326e2abb..896f280e7 100644 --- a/dist/core/reporter.js +++ b/dist/core/reporter.js @@ -1,13 +1,14 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); class Reporter { - constructor(html, ruleset) { + constructor(html, ruleset, disabledRulesMap = {}) { this.html = html; this.lines = html.split(/\r?\n/); const match = /\r?\n/.exec(html); this.brLen = match !== null ? match[0].length : 0; this.ruleset = ruleset; this.messages = []; + this.disabledRulesMap = disabledRulesMap; } info(message, line, col, rule, raw) { this.report("info", message, line, col, rule, raw); @@ -19,6 +20,15 @@ class Reporter { this.report("error", message, line, col, rule, raw); } report(type, message, line, col, rule, raw) { + const lineDisabled = this.disabledRulesMap[line]; + if (lineDisabled) { + if (lineDisabled.all === true) { + return; + } + if (lineDisabled.rules && lineDisabled.rules.has(rule.id)) { + return; + } + } const lines = this.lines; const brLen = this.brLen; let evidence = ''; @@ -53,4 +63,4 @@ class Reporter { } } exports.default = Reporter; -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29yZS9yZXBvcnRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUVBLE1BQXFCLFFBQVE7SUFPM0IsWUFBbUIsSUFBWSxFQUFFLE9BQWdCO1FBQy9DLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFBO1FBQ2hCLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQTtRQUNoQyxNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFBO1FBRWhDLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFBO1FBQ2pELElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFBO1FBQ3RCLElBQUksQ0FBQyxRQUFRLEdBQUcsRUFBRSxDQUFBO0lBQ3BCLENBQUM7SUFFTSxJQUFJLENBQ1QsT0FBZSxFQUNmLElBQVksRUFDWixHQUFXLEVBQ1gsSUFBVSxFQUNWLEdBQVc7UUFFWCxJQUFJLENBQUMsTUFBTSxTQUFrQixPQUFPLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUE7SUFDN0QsQ0FBQztJQUVNLElBQUksQ0FDVCxPQUFlLEVBQ2YsSUFBWSxFQUNaLEdBQVcsRUFDWCxJQUFVLEVBQ1YsR0FBVztRQUVYLElBQUksQ0FBQyxNQUFNLFlBQXFCLE9BQU8sRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQTtJQUNoRSxDQUFDO0lBRU0sS0FBSyxDQUNWLE9BQWUsRUFDZixJQUFZLEVBQ1osR0FBVyxFQUNYLElBQVUsRUFDVixHQUFXO1FBRVgsSUFBSSxDQUFDLE1BQU0sVUFBbUIsT0FBTyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFBO0lBQzlELENBQUM7SUFFTyxNQUFNLENBQ1osSUFBZ0IsRUFDaEIsT0FBZSxFQUNmLElBQVksRUFDWixHQUFXLEVBQ1gsSUFBVSxFQUNWLEdBQVc7UUFFWCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFBO1FBQ3hCLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUE7UUFDeEIsSUFBSSxRQUFRLEdBQUcsRUFBRSxDQUFBO1FBQ2pCLElBQUksV0FBVyxHQUFHLENBQUMsQ0FBQTtRQUVuQixLQUFLLElBQUksQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLEVBQUUsU0FBUyxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLFNBQVMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQ3BFLFFBQVEsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUE7WUFDbkIsV0FBVyxHQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUE7WUFDN0IsSUFBSSxHQUFHLEdBQUcsV0FBVyxJQUFJLElBQUksR0FBRyxTQUFTLEVBQUUsQ0FBQztnQkFDMUMsSUFBSSxFQUFFLENBQUE7Z0JBQ04sR0FBRyxJQUFJLFdBQVcsQ0FBQTtnQkFDbEIsSUFBSSxHQUFHLEtBQUssQ0FBQyxFQUFFLENBQUM7b0JBQ2QsR0FBRyxJQUFJLEtBQUssQ0FBQTtnQkFDZCxDQUFDO1lBQ0gsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLE1BQUs7WUFDUCxDQUFDO1FBQ0gsQ0FBQztRQUVELElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDO1lBQ2pCLElBQUksRUFBRSxJQUFJO1lBQ1YsT0FBTyxFQUFFLE9BQU87WUFDaEIsR0FBRyxFQUFFLEdBQUc7WUFDUixRQUFRLEVBQUUsUUFBUTtZQUNsQixJQUFJLEVBQUUsSUFBSTtZQUNWLEdBQUcsRUFBRSxHQUFHO1lBQ1IsSUFBSSxFQUFFO2dCQUNKLEVBQUUsRUFBRSxJQUFJLENBQUMsRUFBRTtnQkFDWCxXQUFXLEVBQUUsSUFBSSxDQUFDLFdBQVc7Z0JBQzdCLElBQUksRUFBRSw4QkFBOEIsSUFBSSxDQUFDLEVBQUUsRUFBRTthQUN0QztTQUNWLENBQUMsQ0FBQTtJQUNKLENBQUM7Q0FDRjtBQXhGRCwyQkF3RkMifQ== \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29yZS9yZXBvcnRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUVBLE1BQXFCLFFBQVE7SUFRM0IsWUFDRSxJQUFZLEVBQ1osT0FBZ0IsRUFDaEIsbUJBQXFDLEVBQUU7UUFFdkMsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUE7UUFDaEIsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFBO1FBQ2hDLE1BQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUE7UUFFaEMsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUE7UUFDakQsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUE7UUFDdEIsSUFBSSxDQUFDLFFBQVEsR0FBRyxFQUFFLENBQUE7UUFDbEIsSUFBSSxDQUFDLGdCQUFnQixHQUFHLGdCQUFnQixDQUFBO0lBQzFDLENBQUM7SUFFTSxJQUFJLENBQ1QsT0FBZSxFQUNmLElBQVksRUFDWixHQUFXLEVBQ1gsSUFBVSxFQUNWLEdBQVc7UUFFWCxJQUFJLENBQUMsTUFBTSxTQUFrQixPQUFPLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUE7SUFDN0QsQ0FBQztJQUVNLElBQUksQ0FDVCxPQUFlLEVBQ2YsSUFBWSxFQUNaLEdBQVcsRUFDWCxJQUFVLEVBQ1YsR0FBVztRQUVYLElBQUksQ0FBQyxNQUFNLFlBQXFCLE9BQU8sRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQTtJQUNoRSxDQUFDO0lBRU0sS0FBSyxDQUNWLE9BQWUsRUFDZixJQUFZLEVBQ1osR0FBVyxFQUNYLElBQVUsRUFDVixHQUFXO1FBRVgsSUFBSSxDQUFDLE1BQU0sVUFBbUIsT0FBTyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFBO0lBQzlELENBQUM7SUFFTyxNQUFNLENBQ1osSUFBZ0IsRUFDaEIsT0FBZSxFQUNmLElBQVksRUFDWixHQUFXLEVBQ1gsSUFBVSxFQUNWLEdBQVc7UUFHWCxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDaEQsSUFBSSxZQUFZLEVBQUUsQ0FBQztZQUNqQixJQUFJLFlBQVksQ0FBQyxHQUFHLEtBQUssSUFBSSxFQUFFLENBQUM7Z0JBRTlCLE9BQU07WUFDUixDQUFDO1lBQ0QsSUFBSSxZQUFZLENBQUMsS0FBSyxJQUFJLFlBQVksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO2dCQUUxRCxPQUFNO1lBQ1IsQ0FBQztRQUNILENBQUM7UUFFRCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFBO1FBQ3hCLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUE7UUFDeEIsSUFBSSxRQUFRLEdBQUcsRUFBRSxDQUFBO1FBQ2pCLElBQUksV0FBVyxHQUFHLENBQUMsQ0FBQTtRQUVuQixLQUFLLElBQUksQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLEVBQUUsU0FBUyxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLFNBQVMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQ3BFLFFBQVEsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUE7WUFDbkIsV0FBVyxHQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUE7WUFDN0IsSUFBSSxHQUFHLEdBQUcsV0FBVyxJQUFJLElBQUksR0FBRyxTQUFTLEVBQUUsQ0FBQztnQkFDMUMsSUFBSSxFQUFFLENBQUE7Z0JBQ04sR0FBRyxJQUFJLFdBQVcsQ0FBQTtnQkFDbEIsSUFBSSxHQUFHLEtBQUssQ0FBQyxFQUFFLENBQUM7b0JBQ2QsR0FBRyxJQUFJLEtBQUssQ0FBQTtnQkFDZCxDQUFDO1lBQ0gsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLE1BQUs7WUFDUCxDQUFDO1FBQ0gsQ0FBQztRQUVELElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDO1lBQ2pCLElBQUksRUFBRSxJQUFJO1lBQ1YsT0FBTyxFQUFFLE9BQU87WUFDaEIsR0FBRyxFQUFFLEdBQUc7WUFDUixRQUFRLEVBQUUsUUFBUTtZQUNsQixJQUFJLEVBQUUsSUFBSTtZQUNWLEdBQUcsRUFBRSxHQUFHO1lBQ1IsSUFBSSxFQUFFO2dCQUNKLEVBQUUsRUFBRSxJQUFJLENBQUMsRUFBRTtnQkFDWCxXQUFXLEVBQUUsSUFBSSxDQUFDLFdBQVc7Z0JBQzdCLElBQUksRUFBRSw4QkFBOEIsSUFBSSxDQUFDLEVBQUUsRUFBRTthQUN0QztTQUNWLENBQUMsQ0FBQTtJQUNKLENBQUM7Q0FDRjtBQTNHRCwyQkEyR0MifQ== \ No newline at end of file diff --git a/src/core/core.ts b/src/core/core.ts index f6c720404..39e0d7f80 100644 --- a/src/core/core.ts +++ b/src/core/core.ts @@ -1,7 +1,7 @@ import HTMLParser from './htmlparser' import Reporter from './reporter' import * as HTMLRules from './rules' -import { Hint, Rule, Ruleset } from './types' +import { Hint, Rule, Ruleset, DisabledRulesMap } from './types' export interface FormatOptions { colors?: boolean @@ -58,8 +58,11 @@ class HTMLHintCore { } ) + // Parse disable/enable comments + const disabledRulesMap = this.parseDisableComments(html) + const parser = new HTMLParser() - const reporter = new Reporter(html, ruleset) + const reporter = new Reporter(html, ruleset, disabledRulesMap) const rules = this.rules let rule: Rule @@ -76,6 +79,114 @@ class HTMLHintCore { return reporter.messages } + private parseDisableComments(html: string): DisabledRulesMap { + const disabledRulesMap: DisabledRulesMap = {} + const lines = html.split(/\r?\n/) + const regComment = + //gi + + // Find all disable/enable comments and their positions + const comments: Array<{ + line: number + command: string + isNextLine: boolean + rulesStr?: string + }> = [] + + let match: RegExpExecArray | null + while ((match = regComment.exec(html)) !== null) { + // Calculate line number from match position + const beforeMatch = html.substring(0, match.index) + const lineNumber = beforeMatch.split(/\r?\n/).length + const command = match[1].toLowerCase() + const isNextLine = match[0].includes('-next-line') + const rulesStr = match[2]?.trim() + + comments.push({ + line: lineNumber, + command, + isNextLine, + rulesStr, + }) + } + + // Process comments in order + let currentDisabledRules: Set | null = null + let isAllDisabled = false + + for (let i = 0; i < lines.length; i++) { + const line = i + 1 + + // Check if there's a comment on this line + const commentOnLine = comments.find((c) => c.line === line) + if (commentOnLine) { + if (commentOnLine.command === 'disable') { + if (commentOnLine.isNextLine) { + // htmlhint-disable-next-line + const nextLine = line + 1 + if (commentOnLine.rulesStr) { + // Specific rules disabled + const rules = commentOnLine.rulesStr + .split(/\s+/) + .filter((r) => r.length > 0) + if (!disabledRulesMap[nextLine]) { + disabledRulesMap[nextLine] = {} + } + if (!disabledRulesMap[nextLine].rules) { + disabledRulesMap[nextLine].rules = new Set() + } + rules.forEach((r) => disabledRulesMap[nextLine].rules!.add(r)) + } else { + // All rules disabled + if (!disabledRulesMap[nextLine]) { + disabledRulesMap[nextLine] = {} + } + disabledRulesMap[nextLine].all = true + } + } else { + // htmlhint-disable + if (commentOnLine.rulesStr) { + // Specific rules disabled + const rules = commentOnLine.rulesStr + .split(/\s+/) + .filter((r) => r.length > 0) + currentDisabledRules = new Set(rules) + isAllDisabled = false + } else { + // All rules disabled + currentDisabledRules = null + isAllDisabled = true + } + } + } else if (commentOnLine.command === 'enable') { + // htmlhint-enable + currentDisabledRules = null + isAllDisabled = false + } + } + + // Apply current disable state to this line (if not already set by next-line) + if (currentDisabledRules !== null || isAllDisabled) { + if (!disabledRulesMap[line]) { + disabledRulesMap[line] = {} + } + // Don't override if already set by next-line comment + if (isAllDisabled && disabledRulesMap[line].all !== true) { + disabledRulesMap[line].all = true + } else if (currentDisabledRules) { + if (!disabledRulesMap[line].rules) { + disabledRulesMap[line].rules = new Set() + } + currentDisabledRules.forEach((r) => + disabledRulesMap[line].rules!.add(r) + ) + } + } + } + + return disabledRulesMap + } + public format(arrMessages: Hint[], options: FormatOptions = {}) { const arrLogs: string[] = [] const colors = { diff --git a/src/core/reporter.ts b/src/core/reporter.ts index 024a82caf..eaa73b308 100644 --- a/src/core/reporter.ts +++ b/src/core/reporter.ts @@ -1,4 +1,4 @@ -import { Hint, ReportType, Rule, Ruleset } from './types' +import { Hint, ReportType, Rule, Ruleset, DisabledRulesMap } from './types' export default class Reporter { public html: string @@ -6,8 +6,13 @@ export default class Reporter { public brLen: number public ruleset: Ruleset public messages: Hint[] + private disabledRulesMap: DisabledRulesMap - public constructor(html: string, ruleset: Ruleset) { + public constructor( + html: string, + ruleset: Ruleset, + disabledRulesMap: DisabledRulesMap = {} + ) { this.html = html this.lines = html.split(/\r?\n/) const match = /\r?\n/.exec(html) @@ -15,6 +20,7 @@ export default class Reporter { this.brLen = match !== null ? match[0].length : 0 this.ruleset = ruleset this.messages = [] + this.disabledRulesMap = disabledRulesMap } public info( @@ -55,6 +61,19 @@ export default class Reporter { rule: Rule, raw: string ) { + // Check if rule is disabled for this line + const lineDisabled = this.disabledRulesMap[line] + if (lineDisabled) { + if (lineDisabled.all === true) { + // All rules disabled for this line + return + } + if (lineDisabled.rules && lineDisabled.rules.has(rule.id)) { + // This specific rule is disabled for this line + return + } + } + const lines = this.lines const brLen = this.brLen let evidence = '' diff --git a/src/core/types.ts b/src/core/types.ts index f93bdc6e2..003476994 100644 --- a/src/core/types.ts +++ b/src/core/types.ts @@ -79,3 +79,10 @@ export interface Hint { col: number rule: Rule } + +export interface DisabledRulesMap { + [line: number]: { + all?: boolean + rules?: Set + } +} diff --git a/test/core.spec.js b/test/core.spec.js index 114ad81e5..f12634549 100644 --- a/test/core.spec.js +++ b/test/core.spec.js @@ -80,4 +80,130 @@ describe('Core', () => { expect(/|\.\.\./.test(log)).toBe(true) expect(/t\.\.\./.test(log)).toBe(true) }) + + describe('Disable/enable comments', () => { + it('htmlhint-disable should disable all rules for following lines', () => { + const code = ` +
Lorem
+
Ipsum
` + const messages = HTMLHint.verify(code, { + 'attr-lowercase': true, + }) + expect(messages.length).toBe(0) + }) + + it('htmlhint-disable-next-line should disable all rules for next line', () => { + const code = ` +
Lorem
+
Ipsum
` + const messages = HTMLHint.verify(code, { + 'attr-lowercase': true, + }) + // Line 2 should be disabled (no errors), line 3 is valid (no errors) + expect(messages.length).toBe(0) + }) + + it('htmlhint-disable with specific rule should disable only that rule', () => { + const code = ` +
Lorem
+
Ipsum
` + const messages = HTMLHint.verify(code, { + 'attr-lowercase': true, + 'tag-pair': true, + }) + // attr-lowercase should be disabled, but tag-pair should still work + expect(messages.length).toBe(0) + }) + + it('htmlhint-disable-next-line with specific rule should disable only that rule for next line', () => { + const code = ` +
Lorem
+
Ipsum
` + const messages = HTMLHint.verify(code, { + 'attr-lowercase': true, + }) + // Line 2 should not have errors (disabled), line 3 should have errors + expect(messages.length).toBe(1) + expect(messages[0].line).toBe(3) + expect(messages[0].rule.id).toBe('attr-lowercase') + }) + + it('htmlhint-enable should re-enable rules', () => { + const code = ` +
Lorem
+
Lorem
+ +
Ipsum
` + const messages = HTMLHint.verify(code, { + 'attr-lowercase': true, + }) + // Lines 2-3 should be disabled, line 5 should have errors + expect(messages.length).toBe(1) + expect(messages[0].line).toBe(5) + expect(messages[0].rule.id).toBe('attr-lowercase') + }) + + it('htmlhint-disable should work with multiple rules', () => { + const code = ` +
Lorem
+
Ipsum
` + const messages = HTMLHint.verify(code, { + 'attr-lowercase': true, + 'tagname-lowercase': true, + }) + expect(messages.length).toBe(0) + }) + + it('htmlhint-disable-next-line should work with multiple rules', () => { + const code = ` +
Lorem
+
Ipsum
` + const messages = HTMLHint.verify(code, { + 'attr-lowercase': true, + 'tagname-lowercase': true, + }) + // Line 2 should be disabled, line 3 should have errors + // Filter to only check the rules we care about + const relevantMessages = messages.filter( + (m) => + m.rule.id === 'attr-lowercase' || m.rule.id === 'tagname-lowercase' + ) + // Line 2 should have no errors (disabled) + const line2Messages = relevantMessages.filter((m) => m.line === 2) + expect(line2Messages.length).toBe(0) + // Line 3 should have errors + const line3Messages = relevantMessages.filter((m) => m.line === 3) + expect(line3Messages.length).toBeGreaterThan(0) + expect(line3Messages.some((m) => m.rule.id === 'attr-lowercase')).toBe( + true + ) + expect(line3Messages.some((m) => m.rule.id === 'tagname-lowercase')).toBe( + true + ) + }) + + it('should still report errors when rules are not disabled', () => { + const code = `
Lorem
+
Ipsum
` + const messages = HTMLHint.verify(code, { + 'attr-lowercase': true, + }) + // Line 1 should have an error + expect(messages.length).toBe(1) + expect(messages[0].line).toBe(1) + expect(messages[0].rule.id).toBe('attr-lowercase') + }) + + it('should handle disable comments on same line as code', () => { + const code = `
Lorem
+
Ipsum
` + const messages = HTMLHint.verify(code, { + 'attr-lowercase': true, + }) + // Line 1 should have error, line 2 should be disabled + expect(messages.length).toBe(1) + expect(messages[0].line).toBe(1) + expect(messages[0].rule.id).toBe('attr-lowercase') + }) + }) }) diff --git a/website/src/content/docs/configuration.md b/website/src/content/docs/configuration.md index dff5782a0..6511869c3 100644 --- a/website/src/content/docs/configuration.md +++ b/website/src/content/docs/configuration.md @@ -33,6 +33,69 @@ Finally, rules can be specified inline directly in the HTML document: ``` +## Disabling Rules Inline + +You can disable specific rules or all rules for specific lines in your HTML using HTML comments. This is useful when you need to temporarily disable linting for a particular section of code. + +### Disable All Rules + +To disable all HTMLHint rules for the following lines until re-enabled: + + +```html + +
Lorem
+
Ipsum
+ +
Dolor
+``` + +### Disable for Next Line + +To disable all rules for just the next line: + + +```html + +
Lorem
+
Ipsum
+``` + +### Disable Specific Rules + +To disable specific rules for the following lines: + + +```html + +
Lorem
+
Ipsum
+ +
Dolor
+``` + +### Disable Specific Rules for Next Line + +To disable specific rules for just the next line: + + +```html + +
Lorem
+
Ipsum
+``` + +### Disable Multiple Rules + +You can disable multiple rules by listing them separated by spaces: + + +```html + +
Lorem
+
Ipsum
+``` + ## Example configuration file An example configuration file (with all rules disabled): diff --git a/website/src/content/docs/getting-started.mdx b/website/src/content/docs/getting-started.mdx index cbecb74ff..4c9046238 100644 --- a/website/src/content/docs/getting-started.mdx +++ b/website/src/content/docs/getting-started.mdx @@ -24,6 +24,7 @@ import { Tabs, TabItem } from '@astrojs/starlight/components'; "attr-lowercase": true, "attr-no-duplication": true, "attr-value-double-quotes": true, + "attr-value-no-duplication": true, "button-type-require": true, "doctype-first": true, "doctype-html5": true, @@ -31,6 +32,7 @@ import { Tabs, TabItem } from '@astrojs/starlight/components'; "h1-require": true, "html-lang-require": true, "id-unique": true, + "input-requires-label": true, "main-require": true, "meta-charset-require": true, "meta-description-require": true,