#!/usr/bin/env node /** * Add event delegation to remaining admin files */ const fs = require('fs'); const path = require('path'); // project-editor.js const projectEditorFile = path.join(__dirname, '../public/js/admin/project-editor.js'); let projectEditorContent = fs.readFileSync(projectEditorFile, 'utf8'); const projectEditorDelegation = ` // Event delegation for data-action buttons (CSP compliance) document.addEventListener('click', (e) => { const button = e.target.closest('[data-action]'); if (!button) return; const action = button.dataset.action; const arg0 = button.dataset.arg0; if (action === 'editVariable') { window.projectEditor.editVariable(arg0); } else if (action === 'deleteVariable') { window.projectEditor.deleteVariable(arg0); } }); `; if (!projectEditorContent.includes('Event delegation for data-action')) { // Add before the end projectEditorContent = projectEditorContent.trim() + '\n' + projectEditorDelegation; fs.writeFileSync(projectEditorFile, projectEditorContent); console.log('✓ Added event delegation to project-editor.js'); } // rule-editor.js const ruleEditorFile = path.join(__dirname, '../public/js/admin/rule-editor.js'); let ruleEditorContent = fs.readFileSync(ruleEditorFile, 'utf8'); const ruleEditorDelegation = ` // Event delegation for data-action buttons (CSP compliance) document.addEventListener('click', (e) => { const button = e.target.closest('[data-action]'); if (!button) return; const action = button.dataset.action; const arg0 = button.dataset.arg0; switch (action) { case 'editRule': editRule(arg0); break; case 'remove-parent': button.parentElement.remove(); break; } }); `; if (!ruleEditorContent.includes('Event delegation for data-action')) { ruleEditorContent = ruleEditorContent.trim() + '\n' + ruleEditorDelegation; fs.writeFileSync(ruleEditorFile, ruleEditorContent); console.log('✓ Added event delegation to rule-editor.js'); } // audit-analytics.js const auditFile = path.join(__dirname, '../public/js/admin/audit-analytics.js'); let auditContent = fs.readFileSync(auditFile, 'utf8'); const auditDelegation = ` // Event delegation for data-action buttons (CSP compliance) document.addEventListener('click', (e) => { const button = e.target.closest('[data-action]'); if (!button) return; const action = button.dataset.action; const arg0 = button.dataset.arg0; if (action === 'showDecisionDetails') { showDecisionDetails(arg0); } }); `; if (!auditContent.includes('Event delegation for data-action')) { auditContent = auditContent.trim() + '\n' + auditDelegation; fs.writeFileSync(auditFile, auditContent); console.log('✓ Added event delegation to audit-analytics.js'); } // claude-md-migrator.js const migratorFile = path.join(__dirname, '../public/js/admin/claude-md-migrator.js'); let migratorContent = fs.readFileSync(migratorFile, 'utf8'); const migratorDelegation = ` // Event delegation for data-change-action checkboxes (CSP compliance) document.addEventListener('change', (e) => { const checkbox = e.target.closest('[data-change-action]'); if (!checkbox) return; const action = checkbox.dataset.changeAction; const index = parseInt(checkbox.dataset.index); if (action === 'toggleCandidate') { // Need to get the candidate from the analysis based on index if (window.currentAnalysis && window.currentAnalysis.candidates[index]) { toggleCandidate(window.currentAnalysis.candidates[index], checkbox.checked); } } }); `; if (!migratorContent.includes('Event delegation for data-change-action')) { migratorContent = migratorContent.trim() + '\n' + migratorDelegation; fs.writeFileSync(migratorFile, migratorContent); console.log('✓ Added event delegation to claude-md-migrator.js'); } console.log('\n✅ Event delegation added to all remaining admin files\n');