UNPKG

@ordojs/cli

Version:

Command-line interface for OrdoJS framework

249 lines โ€ข 9.14 kB
/** * @fileoverview CLI command for accessibility features */ import { AccessibilityManager } from '@ordojs/core'; import { Command } from 'commander'; import { existsSync, readFileSync, writeFileSync } from 'fs'; /** * Accessibility command for generating ARIA attributes and running accessibility tests */ export function createAccessibilityCommand() { const command = new Command('accessibility') .description('Generate ARIA attributes and run accessibility tests') .option('-i, --input <file>', 'Input HTML file or directory', './src') .option('-o, --output <file>', 'Output file for generated ARIA attributes') .option('-c, --config <file>', 'Accessibility configuration file') .option('-t, --test', 'Run accessibility tests', false) .option('-r, --report', 'Generate accessibility report', false) .option('-f, --fix', 'Automatically fix accessibility issues', false) .option('-v, --verbose', 'Verbose output', false) .action(async (options) => { try { await runAccessibilityCommand(options); } catch (error) { console.error('Accessibility command failed:', error); process.exit(1); } }); return command; } /** * Run the accessibility command */ async function runAccessibilityCommand(options) { console.log('๐Ÿ” Running OrdoJS Accessibility Analysis...\n'); // Load configuration const config = loadAccessibilityConfig(options.config); const accessibilityManager = new AccessibilityManager(config); if (options.test) { await runAccessibilityTests(accessibilityManager, options); } if (options.report) { await generateAccessibilityReport(accessibilityManager, options); } if (options.fix) { await fixAccessibilityIssues(accessibilityManager, options); } console.log('โœ… Accessibility analysis completed successfully!'); } /** * Load accessibility configuration */ function loadAccessibilityConfig(configPath) { if (!configPath) { return { enableAriaGeneration: true, enableKeyboardNavigation: true, enableFocusManagement: true, enableScreenReaderSupport: true, enableSemanticHTML: true, enableAccessibilityTesting: true }; } if (!existsSync(configPath)) { throw new Error(`Configuration file not found: ${configPath}`); } try { const configContent = readFileSync(configPath, 'utf-8'); return JSON.parse(configContent); } catch (error) { throw new Error(`Failed to parse configuration file: ${error}`); } } /** * Run accessibility tests */ async function runAccessibilityTests(accessibilityManager, options) { console.log('๐Ÿงช Running accessibility tests...\n'); // Create a mock DOM environment for testing const mockHTML = ` <!DOCTYPE html> <html lang="en"> <head> <title>Test Page</title> </head> <body> <header> <nav> <a href="#home">Home</a> <a href="#about">About</a> </nav> </header> <main> <h1>Welcome</h1> <form> <label for="name">Name:</label> <input type="text" id="name" name="name" required> <button type="submit">Submit</button> </form> <div class="modal" role="dialog"> <h2>Modal Title</h2> <p>Modal content</p> <button aria-label="Close">ร—</button> </div> </main> <footer> <p>&copy; 2024</p> </footer> </body> </html> `; // Parse HTML and create DOM elements const parser = new DOMParser(); const doc = parser.parseFromString(mockHTML, 'text/html'); // Run accessibility checks const ariaIssues = accessibilityManager['checkAriaAttributes'](); const keyboardIssues = accessibilityManager['checkKeyboardNavigation'](); const focusIssues = accessibilityManager['checkFocusManagement'](); const screenReaderIssues = accessibilityManager['checkScreenReaderSupport'](); // Display results console.log('๐Ÿ“Š Accessibility Test Results:\n'); if (ariaIssues.length > 0) { console.log('โŒ ARIA Issues:'); ariaIssues.forEach((issue) => { console.log(` - ${issue.issue} (${issue.severity})`); }); console.log(''); } else { console.log('โœ… No ARIA issues found\n'); } if (keyboardIssues.length > 0) { console.log('โŒ Keyboard Navigation Issues:'); keyboardIssues.forEach((issue) => { console.log(` - ${issue.issue} (${issue.severity})`); }); console.log(''); } else { console.log('โœ… No keyboard navigation issues found\n'); } if (focusIssues.length > 0) { console.log('โŒ Focus Management Issues:'); focusIssues.forEach((issue) => { console.log(` - ${issue.issue} (${issue.severity})`); }); console.log(''); } else { console.log('โœ… No focus management issues found\n'); } if (screenReaderIssues.length > 0) { console.log('โŒ Screen Reader Issues:'); screenReaderIssues.forEach((issue) => { console.log(` - ${issue.issue} (${issue.severity})`); }); console.log(''); } else { console.log('โœ… No screen reader issues found\n'); } const totalIssues = ariaIssues.length + keyboardIssues.length + focusIssues.length + screenReaderIssues.length; console.log(`๐Ÿ“ˆ Total Issues: ${totalIssues}`); } /** * Generate accessibility report */ async function generateAccessibilityReport(accessibilityManager, options) { console.log('๐Ÿ“‹ Generating accessibility report...\n'); const report = accessibilityManager['generateAccessibilityReport'](); const reportContent = { timestamp: new Date().toISOString(), summary: report.summary, issues: { aria: report.ariaIssues, keyboard: report.keyboardIssues, focus: report.focusIssues, screenReader: report.screenReaderIssues }, recommendations: generateRecommendations(report) }; if (options.output) { writeFileSync(options.output, JSON.stringify(reportContent, null, 2)); console.log(`๐Ÿ“„ Report saved to: ${options.output}`); } else { console.log('๐Ÿ“„ Accessibility Report:'); console.log(JSON.stringify(reportContent, null, 2)); } } /** * Generate recommendations based on accessibility issues */ function generateRecommendations(report) { const recommendations = []; if (report.ariaIssues.length > 0) { recommendations.push('Add missing ARIA attributes to improve screen reader support'); recommendations.push('Ensure all interactive elements have appropriate roles'); } if (report.keyboardIssues.length > 0) { recommendations.push('Ensure all interactive elements are keyboard accessible'); recommendations.push('Add proper tabindex values for custom interactive elements'); } if (report.focusIssues.length > 0) { recommendations.push('Implement proper focus management for modals and dialogs'); recommendations.push('Add focus indicators for better visual feedback'); } if (report.screenReaderIssues.length > 0) { recommendations.push('Add alt text to all images'); recommendations.push('Ensure form controls have associated labels'); } if (recommendations.length === 0) { recommendations.push('Great job! Your application meets accessibility standards'); } return recommendations; } /** * Fix accessibility issues automatically */ async function fixAccessibilityIssues(accessibilityManager, options) { console.log('๐Ÿ”ง Fixing accessibility issues...\n'); // This would involve parsing HTML files and automatically adding ARIA attributes // For now, we'll provide guidance on manual fixes console.log('๐Ÿ“ Manual Fixes Required:'); console.log('1. Add missing ARIA attributes to interactive elements'); console.log('2. Ensure proper heading hierarchy (h1, h2, h3, etc.)'); console.log('3. Add alt text to images'); console.log('4. Ensure form controls have labels'); console.log('5. Test keyboard navigation'); console.log('6. Test with screen readers'); console.log('7. Ensure sufficient color contrast'); console.log('8. Add focus indicators'); console.log('9. Implement skip links for navigation'); console.log('10. Test with different assistive technologies\n'); console.log('๐Ÿ’ก Use the --test flag to identify specific issues'); console.log('๐Ÿ’ก Use the --report flag to generate detailed reports'); } /** * Mock DOMParser for testing */ class DOMParser { parseFromString(html, mimeType) { // This is a simplified mock - in a real implementation, // you would use a proper HTML parser like jsdom return document; } } //# sourceMappingURL=accessibility.js.map