- 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>
421 lines
No EOL
13 KiB
JavaScript
421 lines
No EOL
13 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
/**
|
|
* HVAC Community Events CSS Vendor Prefix Fixes
|
|
*
|
|
* This script adds vendor prefixes for cross-browser compatibility
|
|
* using Autoprefixer patterns to ensure support across all modern browsers.
|
|
*/
|
|
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
const CSS_DIR = './assets/css';
|
|
const prefixRules = [];
|
|
|
|
// Vendor prefix patterns - following Autoprefixer standards
|
|
const VENDOR_PREFIXES = {
|
|
// Flexbox properties
|
|
flexbox: {
|
|
'display: flex': [
|
|
'display: -webkit-box',
|
|
'display: -ms-flexbox',
|
|
'display: flex'
|
|
],
|
|
'flex-direction: column': [
|
|
'-webkit-box-orient: vertical',
|
|
'-webkit-box-direction: normal',
|
|
'-ms-flex-direction: column',
|
|
'flex-direction: column'
|
|
],
|
|
'flex-direction: row': [
|
|
'-webkit-box-orient: horizontal',
|
|
'-webkit-box-direction: normal',
|
|
'-ms-flex-direction: row',
|
|
'flex-direction: row'
|
|
],
|
|
'justify-content: space-between': [
|
|
'-webkit-box-pack: justify',
|
|
'-ms-flex-pack: justify',
|
|
'justify-content: space-between'
|
|
],
|
|
'justify-content: center': [
|
|
'-webkit-box-pack: center',
|
|
'-ms-flex-pack: center',
|
|
'justify-content: center'
|
|
],
|
|
'justify-content: flex-start': [
|
|
'-webkit-box-pack: start',
|
|
'-ms-flex-pack: start',
|
|
'justify-content: flex-start'
|
|
],
|
|
'justify-content: flex-end': [
|
|
'-webkit-box-pack: end',
|
|
'-ms-flex-pack: end',
|
|
'justify-content: flex-end'
|
|
],
|
|
'align-items: center': [
|
|
'-webkit-box-align: center',
|
|
'-ms-flex-align: center',
|
|
'align-items: center'
|
|
],
|
|
'align-items: flex-start': [
|
|
'-webkit-box-align: start',
|
|
'-ms-flex-align: start',
|
|
'align-items: flex-start'
|
|
],
|
|
'align-items: flex-end': [
|
|
'-webkit-box-align: end',
|
|
'-ms-flex-align: end',
|
|
'align-items: flex-end'
|
|
],
|
|
'align-items: stretch': [
|
|
'-webkit-box-align: stretch',
|
|
'-ms-flex-align: stretch',
|
|
'align-items: stretch'
|
|
],
|
|
'flex: 1': [
|
|
'-webkit-box-flex: 1',
|
|
'-ms-flex: 1',
|
|
'flex: 1'
|
|
],
|
|
'flex-wrap: wrap': [
|
|
'-ms-flex-wrap: wrap',
|
|
'flex-wrap: wrap'
|
|
]
|
|
},
|
|
|
|
// CSS Grid properties
|
|
grid: {
|
|
'display: grid': [
|
|
'display: -ms-grid',
|
|
'display: grid'
|
|
],
|
|
'grid-template-columns': {
|
|
pattern: /grid-template-columns:\s*([^;]+)/g,
|
|
replacement: (match, value) => [
|
|
`-ms-grid-columns: ${value}`,
|
|
`grid-template-columns: ${value}`
|
|
]
|
|
},
|
|
'grid-template-rows': {
|
|
pattern: /grid-template-rows:\s*([^;]+)/g,
|
|
replacement: (match, value) => [
|
|
`-ms-grid-rows: ${value}`,
|
|
`grid-template-rows: ${value}`
|
|
]
|
|
},
|
|
'gap': {
|
|
pattern: /gap:\s*([^;]+)/g,
|
|
replacement: (match, value) => [
|
|
`grid-gap: ${value}`,
|
|
`gap: ${value}`
|
|
]
|
|
}
|
|
},
|
|
|
|
// Transform properties
|
|
transform: {
|
|
pattern: /transform:\s*([^;]+)/g,
|
|
replacement: (match, value) => [
|
|
`-webkit-transform: ${value}`,
|
|
`-ms-transform: ${value}`,
|
|
`transform: ${value}`
|
|
]
|
|
},
|
|
|
|
// Transition properties
|
|
transition: {
|
|
pattern: /transition:\s*([^;]+)/g,
|
|
replacement: (match, value) => [
|
|
`-webkit-transition: ${value}`,
|
|
`transition: ${value}`
|
|
]
|
|
},
|
|
|
|
// Animation properties
|
|
animation: {
|
|
pattern: /animation:\s*([^;]+)/g,
|
|
replacement: (match, value) => [
|
|
`-webkit-animation: ${value}`,
|
|
`animation: ${value}`
|
|
]
|
|
},
|
|
|
|
// Box-shadow property
|
|
boxShadow: {
|
|
pattern: /box-shadow:\s*([^;]+)/g,
|
|
replacement: (match, value) => [
|
|
`-webkit-box-shadow: ${value}`,
|
|
`box-shadow: ${value}`
|
|
]
|
|
},
|
|
|
|
// Border-radius property
|
|
borderRadius: {
|
|
pattern: /border-radius:\s*([^;]+)/g,
|
|
replacement: (match, value) => [
|
|
`-webkit-border-radius: ${value}`,
|
|
`border-radius: ${value}`
|
|
]
|
|
},
|
|
|
|
// Appearance property
|
|
appearance: {
|
|
pattern: /appearance:\s*([^;]+)/g,
|
|
replacement: (match, value) => [
|
|
`-webkit-appearance: ${value}`,
|
|
`-moz-appearance: ${value}`,
|
|
`appearance: ${value}`
|
|
]
|
|
},
|
|
|
|
// User-select property
|
|
userSelect: {
|
|
pattern: /user-select:\s*([^;]+)/g,
|
|
replacement: (match, value) => [
|
|
`-webkit-user-select: ${value}`,
|
|
`-moz-user-select: ${value}`,
|
|
`-ms-user-select: ${value}`,
|
|
`user-select: ${value}`
|
|
]
|
|
},
|
|
|
|
// Background-size property
|
|
backgroundSize: {
|
|
pattern: /background-size:\s*([^;]+)/g,
|
|
replacement: (match, value) => [
|
|
`-webkit-background-size: ${value}`,
|
|
`background-size: ${value}`
|
|
]
|
|
}
|
|
};
|
|
|
|
function addVendorPrefixesToFile(filePath) {
|
|
try {
|
|
let content = fs.readFileSync(filePath, 'utf8');
|
|
let modifications = 0;
|
|
const fileName = path.basename(filePath);
|
|
|
|
console.log(`\nProcessing: ${fileName}`);
|
|
|
|
// Skip files that already have vendor prefixes
|
|
if (content.includes('/* Vendor Prefixes Added */')) {
|
|
console.log(' ✓ Vendor prefixes already exist, skipping');
|
|
return 0;
|
|
}
|
|
|
|
// Process flexbox properties
|
|
Object.entries(VENDOR_PREFIXES.flexbox).forEach(([property, prefixes]) => {
|
|
const regex = new RegExp(`${property.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&')}(?=\\s*;)`, 'g');
|
|
const matches = content.match(regex);
|
|
|
|
if (matches && matches.length > 0) {
|
|
content = content.replace(regex, prefixes.join(';\n ') + ';');
|
|
modifications += matches.length;
|
|
console.log(` ✓ Added ${matches.length} flexbox prefixes for: ${property}`);
|
|
}
|
|
});
|
|
|
|
// Process other properties with regex patterns
|
|
Object.entries(VENDOR_PREFIXES).forEach(([category, config]) => {
|
|
if (category === 'flexbox') return; // Already processed above
|
|
|
|
if (config.pattern && config.replacement) {
|
|
const matches = [...content.matchAll(config.pattern)];
|
|
|
|
if (matches.length > 0) {
|
|
matches.forEach(match => {
|
|
const replacements = typeof config.replacement === 'function'
|
|
? config.replacement(match[0], match[1])
|
|
: config.replacement;
|
|
|
|
content = content.replace(match[0], replacements.join(';\n ') + ';');
|
|
});
|
|
|
|
modifications += matches.length;
|
|
console.log(` ✓ Added ${matches.length} ${category} prefixes`);
|
|
}
|
|
}
|
|
});
|
|
|
|
// Add special handling for CSS Grid fallbacks
|
|
if (content.includes('display: grid')) {
|
|
const gridFallbacks = `
|
|
/* CSS Grid Fallbacks for IE */
|
|
.hvac-stats-row,
|
|
.hvac-dashboard-stats,
|
|
.hvac-certificate-stats {
|
|
display: -ms-grid;
|
|
-ms-grid-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
}
|
|
|
|
/* Progressive enhancement for modern browsers */
|
|
@supports (display: grid) {
|
|
.hvac-stats-row,
|
|
.hvac-dashboard-stats,
|
|
.hvac-certificate-stats {
|
|
display: grid;
|
|
}
|
|
}`;
|
|
|
|
if (!content.includes('/* CSS Grid Fallbacks for IE */')) {
|
|
content += gridFallbacks;
|
|
modifications += 3;
|
|
console.log(' ✓ Added CSS Grid IE fallbacks');
|
|
}
|
|
}
|
|
|
|
// Add feature detection support
|
|
const featureDetection = `
|
|
/* Feature Detection Support */
|
|
@supports not (display: flex) {
|
|
.hvac-content [class*="flex"] {
|
|
display: table-cell;
|
|
vertical-align: middle;
|
|
}
|
|
}
|
|
|
|
@supports not (display: grid) {
|
|
.hvac-content [class*="grid"] {
|
|
display: block;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.hvac-content [class*="grid"] > * {
|
|
float: left;
|
|
width: 50%;
|
|
}
|
|
}`;
|
|
|
|
if (!content.includes('/* Feature Detection Support */') && modifications > 0) {
|
|
content += featureDetection;
|
|
modifications += 2;
|
|
console.log(' ✓ Added feature detection fallbacks');
|
|
}
|
|
|
|
// Add vendor prefix marker
|
|
if (modifications > 0) {
|
|
content = `/* Vendor Prefixes Added - ${new Date().toISOString().split('T')[0]} */\n${content}`;
|
|
}
|
|
|
|
// Write the updated content
|
|
fs.writeFileSync(filePath, content, 'utf8');
|
|
|
|
if (modifications > 0) {
|
|
console.log(` ✅ Added ${modifications} vendor prefixes total`);
|
|
prefixRules.push({
|
|
file: fileName,
|
|
modifications: modifications
|
|
});
|
|
} else {
|
|
console.log(' • No vendor prefixes needed');
|
|
}
|
|
|
|
return modifications;
|
|
|
|
} catch (error) {
|
|
console.error(`Error processing ${filePath}:`, error.message);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
function createAutoprefixerConfig() {
|
|
const configPath = './autoprefixer.config.js';
|
|
const configContent = `module.exports = {
|
|
browsers: [
|
|
'> 1%',
|
|
'last 2 versions',
|
|
'Firefox ESR',
|
|
'not dead',
|
|
'IE 11'
|
|
],
|
|
grid: 'autoplace',
|
|
flexbox: 'no-2009'
|
|
};`;
|
|
|
|
if (!fs.existsSync(configPath)) {
|
|
fs.writeFileSync(configPath, configContent, 'utf8');
|
|
console.log('✓ Created autoprefixer.config.js for future builds');
|
|
}
|
|
}
|
|
|
|
function main() {
|
|
console.log('HVAC Community Events - CSS Vendor Prefix Fixes');
|
|
console.log('='.repeat(60));
|
|
|
|
if (!fs.existsSync(CSS_DIR)) {
|
|
console.error(`CSS directory not found: ${CSS_DIR}`);
|
|
process.exit(1);
|
|
}
|
|
|
|
// Focus on the main HVAC plugin CSS files
|
|
const hvacFiles = [
|
|
'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 = hvacFiles.filter(filePath => fs.existsSync(filePath));
|
|
|
|
let totalModifications = 0;
|
|
|
|
// Process each CSS file
|
|
existingFiles.forEach(filePath => {
|
|
totalModifications += addVendorPrefixesToFile(filePath);
|
|
});
|
|
|
|
// Create autoprefixer config for future builds
|
|
createAutoprefixerConfig();
|
|
|
|
console.log('\n' + '='.repeat(60));
|
|
console.log('VENDOR PREFIX FIX SUMMARY');
|
|
console.log('='.repeat(60));
|
|
|
|
if (prefixRules.length > 0) {
|
|
prefixRules.forEach(rule => {
|
|
console.log(`${rule.file}: ${rule.modifications} prefixes added`);
|
|
});
|
|
}
|
|
|
|
console.log(`\nTotal files processed: ${existingFiles.length}`);
|
|
console.log(`Total vendor prefixes added: ${totalModifications}`);
|
|
|
|
if (totalModifications > 0) {
|
|
console.log('\n✅ Vendor prefix fixes applied successfully!');
|
|
console.log('\nKey improvements:');
|
|
console.log('• Added -webkit- prefixes for Safari/Chrome');
|
|
console.log('• Added -ms- prefixes for IE/Edge');
|
|
console.log('• Added -moz- prefixes for Firefox');
|
|
console.log('• Added CSS Grid IE fallbacks');
|
|
console.log('• Added @supports feature detection');
|
|
console.log('• Created autoprefixer.config.js for builds');
|
|
|
|
console.log('\n📋 Browser Support:');
|
|
console.log('• Chrome/Safari: All modern features');
|
|
console.log('• Firefox: All modern features');
|
|
console.log('• Edge: All modern features');
|
|
console.log('• IE 11: Graceful fallbacks provided');
|
|
|
|
console.log('\n💡 Next Steps:');
|
|
console.log('• Test in IE 11 to verify fallbacks');
|
|
console.log('• Consider adding PostCSS/Autoprefixer to build process');
|
|
console.log('• Validate with BrowserStack or similar tools');
|
|
} else {
|
|
console.log('\n✅ All CSS files already have vendor prefixes');
|
|
}
|
|
}
|
|
|
|
if (require.main === module) {
|
|
main();
|
|
}
|
|
|
|
module.exports = { addVendorPrefixesToFile, VENDOR_PREFIXES }; |