- 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>
208 lines
No EOL
7.7 KiB
JavaScript
208 lines
No EOL
7.7 KiB
JavaScript
#!/usr/bin/env node
|
||
|
||
/**
|
||
* CSS Cleanup Script - Fix malformed vendor prefixes and syntax errors
|
||
*
|
||
* This script cleans up issues caused by the automated vendor prefix script
|
||
*/
|
||
|
||
const fs = require('fs');
|
||
const path = require('path');
|
||
|
||
const CSS_DIR = './assets/css';
|
||
const cleanupRules = [];
|
||
|
||
function cleanupCSSFile(filePath) {
|
||
try {
|
||
let content = fs.readFileSync(filePath, 'utf8');
|
||
let modifications = 0;
|
||
const fileName = path.basename(filePath);
|
||
|
||
console.log(`\nCleaning: ${fileName}`);
|
||
|
||
const originalSize = content.length;
|
||
|
||
// Fix 1: Remove duplicate webkit prefixes
|
||
const webkitDuplicates = content.match(/-webkit--webkit-/g);
|
||
if (webkitDuplicates) {
|
||
content = content.replace(/-webkit--webkit(-webkit)?(-webkit)?(-webkit)?(-webkit)?(-webkit)?(-webkit)?(-webkit)?(-webkit)?(-webkit)?(-webkit)?(-webkit)?/g, '-webkit-');
|
||
console.log(` ✓ Fixed ${webkitDuplicates.length} duplicate webkit prefixes`);
|
||
modifications++;
|
||
}
|
||
|
||
// Fix 2: Remove double semicolons
|
||
const doubleSemicolons = content.match(/;;/g);
|
||
if (doubleSemicolons) {
|
||
content = content.replace(/;;+/g, ';');
|
||
console.log(` ✓ Fixed ${doubleSemicolons.length} double semicolons`);
|
||
modifications++;
|
||
}
|
||
|
||
// Fix 3: Fix malformed border-radius declarations
|
||
const malformedBorderRadius = content.match(/border-radius:\s*[^;]*;\s*border-radius:\s*[^;]*;\s*border-radius:/g);
|
||
if (malformedBorderRadius) {
|
||
// Find and fix multi-line border-radius duplicates
|
||
content = content.replace(/(-webkit-)?border-radius:\s*([^;]+);\s*(\n\s*border-radius:\s*[^;]+;\s*)+/g, (match, webkit, value) => {
|
||
return webkit ? `-webkit-border-radius: ${value};\n border-radius: ${value};` : `border-radius: ${value};`;
|
||
});
|
||
console.log(` ✓ Fixed malformed border-radius declarations`);
|
||
modifications++;
|
||
}
|
||
|
||
// Fix 4: Remove excessive duplicate properties
|
||
content = content.replace(/(\s*([a-z-]+):\s*([^;]+);)\s*(\n\s*\2:\s*\3;\s*)+/g, '$1');
|
||
|
||
// Fix 5: Clean up malformed transform properties
|
||
content = content.replace(/transform:\s*([^;]+);\s*transform:\s*([^;]+);\s*transform:\s*([^;]+);/g,
|
||
'-webkit-transform: $1;\n -ms-transform: $1;\n transform: $1;');
|
||
|
||
// Fix 6: Clean up malformed transition properties
|
||
content = content.replace(/transition:\s*([^;]+);\s*transition:\s*([^;]+);/g,
|
||
'-webkit-transition: $1;\n transition: $1;');
|
||
|
||
// Fix 7: Fix malformed box-shadow properties
|
||
content = content.replace(/box-shadow:\s*([^;]+);\s*box-shadow:\s*([^;]+);\s*box-shadow:\s*([^;]+);/g,
|
||
'-webkit-box-shadow: $1;\n box-shadow: $1;');
|
||
|
||
// Fix 8: Remove any remaining triple prefixes
|
||
content = content.replace(/-webkit--webkit--webkit-/g, '-webkit-');
|
||
content = content.replace(/-ms--ms-/g, '-ms-');
|
||
content = content.replace(/-moz--moz-/g, '-moz-');
|
||
|
||
// Fix 9: Clean up transform uppercase issues
|
||
content = content.replace(/text--webkit-transform:\s*uppercase;\s*-ms-transform:\s*uppercase;\s*transform:\s*uppercase;/g, 'text-transform: uppercase;');
|
||
|
||
// Fix 10: Remove empty lines and normalize spacing
|
||
content = content.replace(/\n\s*\n\s*\n/g, '\n\n');
|
||
|
||
const newSize = content.length;
|
||
const sizeReduction = originalSize - newSize;
|
||
|
||
if (modifications > 0 || sizeReduction > 100) {
|
||
fs.writeFileSync(filePath, content, 'utf8');
|
||
console.log(` ✅ Cleaned ${modifications} issues, reduced size by ${sizeReduction} chars`);
|
||
|
||
cleanupRules.push({
|
||
file: fileName,
|
||
modifications: modifications,
|
||
sizeReduction: sizeReduction
|
||
});
|
||
|
||
return modifications;
|
||
} else {
|
||
console.log(' • No issues found');
|
||
return 0;
|
||
}
|
||
|
||
} catch (error) {
|
||
console.error(`Error cleaning ${filePath}:`, error.message);
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
function validateCSSFile(filePath) {
|
||
try {
|
||
const content = fs.readFileSync(filePath, 'utf8');
|
||
const fileName = path.basename(filePath);
|
||
|
||
console.log(`\nValidating: ${fileName}`);
|
||
|
||
const issues = [];
|
||
|
||
// Check for remaining syntax issues
|
||
if (content.includes(';;')) issues.push('Double semicolons found');
|
||
if (content.includes('-webkit--webkit-')) issues.push('Duplicate webkit prefixes found');
|
||
if (content.match(/border-radius:\s*[^;]*;\s*border-radius:\s*[^;]*;\s*border-radius:/)) issues.push('Malformed border-radius');
|
||
if (content.includes('transform: uppercase')) issues.push('Malformed transform property');
|
||
|
||
// Check for valid CSS structure
|
||
const openBraces = (content.match(/\{/g) || []).length;
|
||
const closeBraces = (content.match(/\}/g) || []).length;
|
||
if (openBraces !== closeBraces) issues.push('Mismatched braces');
|
||
|
||
if (issues.length === 0) {
|
||
console.log(' ✅ CSS validates successfully');
|
||
return true;
|
||
} else {
|
||
console.log(` ❌ Issues found: ${issues.join(', ')}`);
|
||
return false;
|
||
}
|
||
|
||
} catch (error) {
|
||
console.error(`Error validating ${filePath}:`, error.message);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
function main() {
|
||
console.log('HVAC Community Events - CSS Cleanup');
|
||
console.log('='.repeat(50));
|
||
|
||
if (!fs.existsSync(CSS_DIR)) {
|
||
console.error(`CSS directory not found: ${CSS_DIR}`);
|
||
process.exit(1);
|
||
}
|
||
|
||
// Focus on HVAC CSS files that were modified
|
||
const targetFiles = [
|
||
'hvac-common.css',
|
||
'hvac-dashboard.css',
|
||
'hvac-registration.css',
|
||
'hvac-event-summary.css',
|
||
'hvac-email-attendees.css',
|
||
'hvac-mobile-nav.css',
|
||
'hvac-animations.css',
|
||
'hvac-certificates.css',
|
||
'hvac-attendee-profile.css',
|
||
'hvac-print.css'
|
||
].map(file => path.join(CSS_DIR, file));
|
||
|
||
// Filter to only existing files
|
||
const existingFiles = targetFiles.filter(filePath => fs.existsSync(filePath));
|
||
|
||
let totalModifications = 0;
|
||
|
||
// Cleanup phase
|
||
console.log('\n🧹 CLEANUP PHASE');
|
||
console.log('-'.repeat(30));
|
||
existingFiles.forEach(filePath => {
|
||
totalModifications += cleanupCSSFile(filePath);
|
||
});
|
||
|
||
// Validation phase
|
||
console.log('\n✅ VALIDATION PHASE');
|
||
console.log('-'.repeat(30));
|
||
let validFiles = 0;
|
||
existingFiles.forEach(filePath => {
|
||
if (validateCSSFile(filePath)) {
|
||
validFiles++;
|
||
}
|
||
});
|
||
|
||
// Summary
|
||
console.log('\n' + '='.repeat(50));
|
||
console.log('CLEANUP SUMMARY');
|
||
console.log('='.repeat(50));
|
||
|
||
if (cleanupRules.length > 0) {
|
||
cleanupRules.forEach(rule => {
|
||
console.log(`${rule.file}: ${rule.modifications} fixes, ${rule.sizeReduction} chars reduced`);
|
||
});
|
||
}
|
||
|
||
console.log(`\nTotal files processed: ${existingFiles.length}`);
|
||
console.log(`Total files cleaned: ${cleanupRules.length}`);
|
||
console.log(`Total files validated: ${validFiles}/${existingFiles.length}`);
|
||
|
||
if (validFiles === existingFiles.length) {
|
||
console.log('\n✅ All CSS files are now clean and valid!');
|
||
} else {
|
||
console.log('\n⚠️ Some CSS files still have issues - manual review needed');
|
||
}
|
||
}
|
||
|
||
if (require.main === module) {
|
||
main();
|
||
}
|
||
|
||
module.exports = { cleanupCSSFile, validateCSSFile }; |