at main 2.5 kB view raw
1import * as aChecker from "accessibility-checker"; 2import "lume/types.ts"; 3import { rm } from "node:fs"; 4 5// HTML Accessibility Plugin, by dish 6// version 1.0.0 7// Based on IBM's accessibility-checker library 8 9export default function () { 10 return (site: Lume.Site) => { 11 site.process([".html"], checkPages); 12 13 async function checkPages(pages: Lume.Page[]) { 14 const barReport = site.debugBar?.collection("Accessibility Checker"); 15 if (barReport) { 16 barReport.icon = "wheelchair-motion"; 17 barReport.contexts = { 18 "violation": { 19 background: "error", 20 }, 21 "potentialviolation": { 22 background: "error", 23 }, 24 "recommendation": { 25 background: "info", 26 }, 27 "potentialrecommendation": { 28 background: "info", 29 }, 30 }; 31 } 32 console.info("[checkAccessibility] Starting..."); 33 rm(`${Deno.cwd()}/accessibility-results`, { recursive: true, force: true }, (err) => { 34 if (err) throw err; 35 }); 36 for (const page of pages) { 37 const label = page.outputPath.substring(0, page.outputPath.length - 5); 38 try { 39 let res = await aChecker.getCompliance( 40 page.content, 41 label, 42 ); 43 if (aChecker.assertCompliance(res.report) === 0) { 44 (() => {}); 45 } else { 46 barReport?.items.push({ 47 title: page.data.url, 48 details: `${res.report.results.length} errors`, 49 items: Array.from(res.report.results).map((rep) => ({ 50 title: `${rep.ruleId} - ${rep.reasonId}`, 51 context: rep.level, 52 text: rep.message, 53 actions: [ 54 { 55 text: "Highlight", 56 icon: "question", 57 onclick: `highlightElement("${rep.path.dom}", "${page.outputPath}")`, 58 }, 59 { 60 text: "Help", 61 icon: "question", 62 href: rep.help, 63 target: "_blank", 64 }, 65 ], 66 })), 67 }); 68 } 69 } catch (err) { 70 console.error(err); 71 } 72 } 73 await aChecker.close(); 74 } 75 }; 76} 77 78function lookupRule(rules: Object, ruleId: string, reasonId: string) { 79 const rule = rules[ruleId]; 80 const reason: string = rule[reasonId]; 81 return reason; 82}