upskill-event-manager/fix-focus-management.js
bengizmo 993a820a84 feat: Add comprehensive development artifacts to repository
- Add 26 documentation files including test reports, deployment guides, and troubleshooting documentation
- Include 3 CSV data files for trainer imports and user registration tracking
- Add 43 JavaScript test files covering mobile optimization, Safari compatibility, and E2E testing
- Include 18 PHP utility files for debugging, geocoding, and data analysis
- Add 12 shell scripts for deployment verification, user management, and database operations
- Update .gitignore with whitelist patterns for development files, documentation, and CSV data

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-11 12:26:11 -03:00

301 lines
No EOL
9 KiB
JavaScript

#!/usr/bin/env node
/**
* HVAC Community Events CSS Focus Management Fixes
*
* This script adds proper focus management styles to ensure WCAG 2.1 compliance
* and keyboard accessibility across all CSS files.
*/
const fs = require('fs');
const path = require('path');
const CSS_DIR = './assets/css';
const focusRules = [];
// Focus styles to add for different element types
const FOCUS_PATTERNS = {
// Interactive elements that need focus indicators
buttons: [
'.hvac-button:focus',
'.hvac-content .button:focus',
'.hvac-content button:focus',
'.hvac-content input[type="submit"]:focus',
'.hvac-email-submit:focus',
'.hvac-filter-submit:focus',
'.hvac-certificate-actions button:focus',
'.hvac-certificate-actions a:focus'
],
// Form inputs
inputs: [
'.hvac-form-input:focus',
'.hvac-content input[type="text"]:focus',
'.hvac-content input[type="email"]:focus',
'.hvac-content input[type="password"]:focus',
'.hvac-content input[type="url"]:focus',
'.hvac-content textarea:focus',
'.hvac-content select:focus',
'.hvac-email-form-row input:focus',
'.hvac-email-form-row textarea:focus',
'.hvac-filter-group input:focus',
'.hvac-filter-group select:focus'
],
// Links and navigation
links: [
'.hvac-content a:focus',
'.hvac-event-link:focus',
'.hvac-certificate-link:focus',
'.hvac-attendee-profile-icon:focus',
'.hvac-dashboard-nav a:focus',
'.hvac-email-navigation a:focus'
],
// Interactive elements
interactive: [
'.hvac-attendee-checkbox:focus',
'.hvac-select-all-container input[type="checkbox"]:focus',
'.hvac-modal-close:focus',
'.hvac-certificate-table tr:focus'
]
};
// Focus styles definitions
const FOCUS_STYLES = {
buttons: `
outline: 2px solid #005fcc;
outline-offset: 2px;
box-shadow: 0 0 0 3px rgba(0, 95, 204, 0.2);
border-radius: 4px;`,
inputs: `
outline: 2px solid #005fcc;
outline-offset: 2px;
border-color: #005fcc;
box-shadow: 0 0 0 3px rgba(0, 95, 204, 0.2);`,
links: `
outline: 2px solid #005fcc;
outline-offset: 2px;
text-decoration: underline;
background-color: rgba(0, 95, 204, 0.1);
border-radius: 2px;`,
interactive: `
outline: 2px solid #005fcc;
outline-offset: 2px;
box-shadow: 0 0 0 3px rgba(0, 95, 204, 0.2);`
};
// Skip focus outline for mouse users (but keep for keyboard)
const MOUSE_FOCUS_RESET = `
/* Reset focus for mouse users while preserving keyboard accessibility */
.js-focus-visible :focus:not(.focus-visible) {
outline: none;
box-shadow: none;
}
/* Ensure focus is visible for keyboard users */
.js-focus-visible .focus-visible {
outline: 2px solid #005fcc;
outline-offset: 2px;
}`;
function addFocusStylesToFile(filePath) {
try {
let content = fs.readFileSync(filePath, 'utf8');
let modifications = 0;
console.log(`\nProcessing: ${path.basename(filePath)}`);
// Check if focus styles already exist
if (content.includes('/* Focus Management Styles */')) {
console.log(' ✓ Focus styles already exist, skipping');
return 0;
}
// Add focus styles section
const focusSection = `
/* Focus Management Styles - WCAG 2.1 Compliance */
/* Added for keyboard accessibility and screen reader support */
/* Button Focus Styles */
${FOCUS_PATTERNS.buttons.join(',\n')} {${FOCUS_STYLES.buttons}
}
/* Input Focus Styles */
${FOCUS_PATTERNS.inputs.join(',\n')} {${FOCUS_STYLES.inputs}
}
/* Link Focus Styles */
${FOCUS_PATTERNS.links.join(',\n')} {${FOCUS_STYLES.links}
}
/* Interactive Element Focus Styles */
${FOCUS_PATTERNS.interactive.join(',\n')} {${FOCUS_STYLES.interactive}
}
/* High Contrast Mode Support */
@media (prefers-contrast: high) {
.hvac-content *:focus {
outline: 3px solid #000000;
outline-offset: 2px;
background-color: #ffff00;
color: #000000;
}
}
/* Focus-visible polyfill support */
${MOUSE_FOCUS_RESET}
`;
// Add the focus section before the last closing brace or at the end
if (content.includes('@media print')) {
// Insert before print styles
content = content.replace('@media print', focusSection + '\n@media print');
} else {
// Add at the end
content += focusSection;
}
modifications++;
// Write the updated content
fs.writeFileSync(filePath, content, 'utf8');
console.log(` ✓ Added ${modifications} focus management sections`);
focusRules.push({
file: path.basename(filePath),
modifications: modifications
});
return modifications;
} catch (error) {
console.error(`Error processing ${filePath}:`, error.message);
return 0;
}
}
function addFocusIndicatorsToAnimations() {
const animationsPath = path.join(CSS_DIR, 'hvac-animations.css');
try {
let content = fs.readFileSync(animationsPath, 'utf8');
// Check if focus-specific animations already exist
if (content.includes('/* Focus Animation Styles */')) {
console.log(' ✓ Animations file already has focus styles');
return 0;
}
const focusAnimations = `
/* Focus Animation Styles */
/* Smooth transitions for focus indicators */
.hvac-content *:focus {
transition: outline 0.2s ease-out,
box-shadow 0.2s ease-out,
background-color 0.2s ease-out;
}
/* Focus indicator animation for better visibility */
@keyframes focus-pulse {
0% { box-shadow: 0 0 0 3px rgba(0, 95, 204, 0.3); }
50% { box-shadow: 0 0 0 5px rgba(0, 95, 204, 0.2); }
100% { box-shadow: 0 0 0 3px rgba(0, 95, 204, 0.3); }
}
/* Apply focus pulse to critical interactive elements */
.hvac-button:focus,
.hvac-email-submit:focus,
.hvac-content button[type="submit"]:focus {
animation: focus-pulse 2s ease-in-out infinite;
}
/* Disable focus animations for reduced motion users */
@media (prefers-reduced-motion: reduce) {
.hvac-content *:focus {
transition: none;
animation: none;
}
}`;
// Add before the reduced motion section
content = content.replace(
'/* Disable animations for users who prefer reduced motion */',
focusAnimations + '\n\n/* Disable animations for users who prefer reduced motion */'
);
fs.writeFileSync(animationsPath, content, 'utf8');
console.log(' ✓ Added focus animations to hvac-animations.css');
return 1;
} catch (error) {
console.error(`Error updating animations file:`, error.message);
return 0;
}
}
function main() {
console.log('HVAC Community Events - CSS Focus Management Fixes');
console.log('='.repeat(60));
if (!fs.existsSync(CSS_DIR)) {
console.error(`CSS directory not found: ${CSS_DIR}`);
process.exit(1);
}
const cssFiles = fs.readdirSync(CSS_DIR)
.filter(file => file.endsWith('.css'))
.map(file => path.join(CSS_DIR, file));
let totalModifications = 0;
// Process each CSS file
cssFiles.forEach(filePath => {
totalModifications += addFocusStylesToFile(filePath);
});
// Add focus-specific animations
totalModifications += addFocusIndicatorsToAnimations();
console.log('\n' + '='.repeat(60));
console.log('FOCUS MANAGEMENT FIX SUMMARY');
console.log('='.repeat(60));
focusRules.forEach(rule => {
console.log(`${rule.file}: ${rule.modifications} focus sections added`);
});
console.log(`\nTotal files processed: ${cssFiles.length}`);
console.log(`Total focus modifications: ${totalModifications}`);
if (totalModifications > 0) {
console.log('\n✅ Focus management fixes applied successfully!');
console.log('\nKey improvements:');
console.log('• Added WCAG 2.1 compliant focus indicators');
console.log('• Implemented keyboard navigation support');
console.log('• Added high contrast mode compatibility');
console.log('• Included focus-visible polyfill support');
console.log('• Added smooth focus transitions');
console.log('• Respect user motion preferences');
console.log('\n📋 Next Steps:');
console.log('• Test keyboard navigation across all pages');
console.log('• Verify screen reader compatibility');
console.log('• Check high contrast mode display');
console.log('• Add focus-visible.js polyfill to pages');
} else {
console.log('\n✅ All CSS files already have focus management styles');
}
}
if (require.main === module) {
main();
}
module.exports = { addFocusStylesToFile, FOCUS_PATTERNS, FOCUS_STYLES };