@ordojs/cli
Version:
Command-line interface for OrdoJS framework
249 lines โข 9.14 kB
JavaScript
/**
* @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>© 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