Complete the cleanup by moving the final 6 JavaScript development files (4 debug tools + 2 demo HTML pages) to history archive. Additional Files Moved: - debug_buttons.js: Button functionality debugging tool - debug_floating_menu.js: Floating menu structure inspection - e2e_tests.js: End-to-end test runner with custom framework - final_functionality_verification.js: Final verification script - demo_clean_editor.html: Clean section editor demonstration - test_dom_integration.html: DOM integration testing page Documentation Updates: - Updated history/javascript-dev-tests/README.md to document all 59 archived files - Added categorization for debug tools and demo pages - Complete project root directory cleanup achieved Project Status: - ✅ Main directory now clean of all development artifacts - ✅ All 59 JavaScript development files properly archived - ✅ Comprehensive documentation of archived functionality - ✅ 79 automated tests providing equivalent coverage 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
206 lines
7.5 KiB
JavaScript
Executable File
206 lines
7.5 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
||
|
||
/**
|
||
* Button Functionality Debug Tool
|
||
*
|
||
* Specifically tests button creation and event binding
|
||
*/
|
||
|
||
const fs = require('fs');
|
||
const { JSDOM } = require('jsdom');
|
||
|
||
function analyzeButtonCode(htmlFile) {
|
||
const html = fs.readFileSync(htmlFile, 'utf8');
|
||
|
||
console.log('🔧 Button Functionality Analysis');
|
||
console.log('━'.repeat(50));
|
||
|
||
// Extract the showImageEditor method
|
||
const showImageEditorMatch = html.match(/showImageEditor\([\s\S]*?\n \}/);
|
||
if (showImageEditorMatch) {
|
||
const method = showImageEditorMatch[0];
|
||
|
||
console.log('\n📋 showImageEditor Method Analysis:');
|
||
|
||
// Check button creation pattern
|
||
const buttonCreationPattern = /buttons\.forEach\([\s\S]*?\}\);/;
|
||
const hasForEach = buttonCreationPattern.test(method);
|
||
console.log(` Button forEach loop: ${hasForEach ? '✅' : '❌'}`);
|
||
|
||
// Check arrow function binding
|
||
const arrowFunctionPattern = /action: \(\) => this\.\w+\(sectionId\)/;
|
||
const hasArrowBinding = arrowFunctionPattern.test(method);
|
||
console.log(` Arrow function binding: ${hasArrowBinding ? '✅' : '❌'}`);
|
||
|
||
// Check createButton calls
|
||
const createButtonPattern = /this\.createButton\(/;
|
||
const hasCreateButton = createButtonPattern.test(method);
|
||
console.log(` createButton calls: ${hasCreateButton ? '✅' : '❌'}`);
|
||
|
||
// Check if sectionId is in scope
|
||
const sectionIdPattern = /sectionId/g;
|
||
const sectionIdCount = (method.match(sectionIdPattern) || []).length;
|
||
console.log(` sectionId references: ${sectionIdCount} times`);
|
||
|
||
console.log('\n🔍 Potential Issues:');
|
||
|
||
if (!hasArrowBinding) {
|
||
console.log(' ❌ Arrow function binding missing - buttons may not work');
|
||
}
|
||
|
||
if (sectionIdCount < 4) {
|
||
console.log(' ⚠️ Low sectionId usage - may not be passed to all handlers');
|
||
}
|
||
|
||
// Extract button definitions
|
||
const buttonDefsMatch = method.match(/const buttons = \[[\s\S]*?\];/);
|
||
if (buttonDefsMatch) {
|
||
console.log('\n📋 Button Definitions Found:');
|
||
const buttonDefs = buttonDefsMatch[0];
|
||
const buttonNames = buttonDefs.match(/'([^']+)'/g) || [];
|
||
buttonNames.forEach(name => {
|
||
console.log(` • ${name.replace(/'/g, '')}`);
|
||
});
|
||
}
|
||
} else {
|
||
console.log('❌ showImageEditor method not found');
|
||
}
|
||
|
||
// Check createButton method
|
||
const createButtonMatch = html.match(/createButton\([\s\S]*?\n \}/);
|
||
if (createButtonMatch) {
|
||
const method = createButtonMatch[0];
|
||
console.log('\n📋 createButton Method Analysis:');
|
||
|
||
const hasEventListener = method.includes('addEventListener');
|
||
console.log(` Event listener attachment: ${hasEventListener ? '✅' : '❌'}`);
|
||
|
||
const hasHandlerParam = method.includes('handler');
|
||
console.log(` Handler parameter: ${hasHandlerParam ? '✅' : '❌'}`);
|
||
|
||
if (!hasEventListener || !hasHandlerParam) {
|
||
console.log(' ❌ createButton method may be broken');
|
||
}
|
||
}
|
||
}
|
||
|
||
async function testButtonCreation(htmlFile) {
|
||
console.log('\n🧪 Testing Button Creation in DOM Environment');
|
||
console.log('━'.repeat(50));
|
||
|
||
try {
|
||
const html = fs.readFileSync(htmlFile, 'utf8');
|
||
|
||
const dom = new JSDOM(html, {
|
||
runScripts: "dangerously",
|
||
resources: "usable",
|
||
pretendToBeVisual: true
|
||
});
|
||
|
||
const { window } = dom;
|
||
const { document } = window;
|
||
|
||
// Wait for load
|
||
await new Promise(resolve => {
|
||
if (document.readyState === 'complete') {
|
||
resolve();
|
||
} else {
|
||
window.addEventListener('load', resolve);
|
||
}
|
||
});
|
||
|
||
// Wait a bit more for initialization
|
||
await new Promise(resolve => setTimeout(resolve, 500));
|
||
|
||
console.log('\n📊 DOM State after initialization:');
|
||
|
||
// Check if MarkitectEditor is available
|
||
const editorAvailable = window.MarkitectEditor !== undefined;
|
||
console.log(` MarkitectEditor global: ${editorAvailable ? '✅' : '❌'}`);
|
||
|
||
if (editorAvailable) {
|
||
const editorClasses = Object.keys(window.MarkitectEditor);
|
||
console.log(` Available classes: ${editorClasses.join(', ')}`);
|
||
}
|
||
|
||
// Check if container has sections
|
||
const container = document.getElementById('markdown-content');
|
||
if (container) {
|
||
const sections = container.querySelectorAll('[data-section-id]');
|
||
console.log(` Sections created: ${sections.length}`);
|
||
|
||
// Look for image sections
|
||
let imageCount = 0;
|
||
sections.forEach(section => {
|
||
if (section.innerHTML.includes('<img') || section.innerHTML.includes('![')) {
|
||
imageCount++;
|
||
}
|
||
});
|
||
console.log(` Image sections: ${imageCount}`);
|
||
|
||
// Try to simulate click on an image section
|
||
if (imageCount > 0) {
|
||
console.log('\n🖱️ Simulating click on image section...');
|
||
|
||
for (const section of sections) {
|
||
if (section.innerHTML.includes('<img') || section.innerHTML.includes('![')) {
|
||
console.log(` Clicking section: ${section.getAttribute('data-section-id')}`);
|
||
|
||
// Simulate click
|
||
const clickEvent = new window.MouseEvent('click', {
|
||
bubbles: true,
|
||
cancelable: true,
|
||
view: window
|
||
});
|
||
|
||
section.dispatchEvent(clickEvent);
|
||
|
||
// Check if image editor was created
|
||
setTimeout(() => {
|
||
const imageEditor = document.querySelector('.ui-edit-image-editor-container');
|
||
console.log(` Image editor created: ${imageEditor ? '✅' : '❌'}`);
|
||
|
||
if (imageEditor) {
|
||
const buttons = imageEditor.querySelectorAll('button');
|
||
console.log(` Buttons in editor: ${buttons.length}`);
|
||
|
||
buttons.forEach((btn, i) => {
|
||
console.log(` Button ${i + 1}: "${btn.textContent}"`);
|
||
|
||
// Check if button has click handler
|
||
const hasHandler = btn.onclick || btn.addEventListener;
|
||
console.log(` Has handler: ${hasHandler ? '✅' : '❌'}`);
|
||
});
|
||
}
|
||
}, 100);
|
||
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
} catch (error) {
|
||
console.log(`❌ DOM testing failed: ${error.message}`);
|
||
}
|
||
}
|
||
|
||
// Main execution
|
||
if (require.main === module) {
|
||
const htmlFile = process.argv[2] || '/tmp/test_complete_functionality.html';
|
||
|
||
if (!fs.existsSync(htmlFile)) {
|
||
console.error(`❌ File not found: ${htmlFile}`);
|
||
process.exit(1);
|
||
}
|
||
|
||
// Analyze the code first
|
||
analyzeButtonCode(htmlFile);
|
||
|
||
// Test in DOM environment
|
||
testButtonCreation(htmlFile).then(() => {
|
||
console.log('\n✅ Analysis complete');
|
||
}).catch(error => {
|
||
console.error('❌ Testing failed:', error);
|
||
});
|
||
} |