fix(architecture): interactive diagram SVG click handler timing issues
Fixed non-responsive service node clicks on architecture.html interactive diagram. Root cause: SVG loaded via <object> tag had contentDocument timing issues - event listeners attached before SVG fully accessible. Solution: - Added retry mechanism for contentDocument access (100ms intervals) - Implemented multiple loading strategies (immediate, load event, timeout) - Enabled event capturing phase (addEventListener 3rd param: true) - Enhanced logging for debugging click event flow - Auto-display overview panel on initialization - CSP-compliant cursor styling via JavaScript Deployed to production: https://agenticgovernance.digital/architecture.html 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
0b853c537d
commit
f347d0a34e
1 changed files with 34 additions and 7 deletions
|
|
@ -133,11 +133,13 @@ class InteractiveDiagram {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for object to load
|
// Wait for object to load with retry mechanism
|
||||||
const initializeSVG = () => {
|
const initializeSVG = () => {
|
||||||
const svgDoc = objectElement.contentDocument;
|
const svgDoc = objectElement.contentDocument;
|
||||||
if (!svgDoc) {
|
if (!svgDoc) {
|
||||||
console.warn('[InteractiveDiagram] Could not access SVG contentDocument');
|
console.warn('[InteractiveDiagram] Could not access SVG contentDocument, retrying...');
|
||||||
|
// Retry after a short delay
|
||||||
|
setTimeout(initializeSVG, 100);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -168,13 +170,22 @@ class InteractiveDiagram {
|
||||||
const nodes = svg.querySelectorAll('.service-node');
|
const nodes = svg.querySelectorAll('.service-node');
|
||||||
console.log(`[InteractiveDiagram] Found ${nodes.length} service nodes`);
|
console.log(`[InteractiveDiagram] Found ${nodes.length} service nodes`);
|
||||||
|
|
||||||
|
if (nodes.length === 0) {
|
||||||
|
console.warn('[InteractiveDiagram] No service nodes found in SVG');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
nodes.forEach(node => {
|
nodes.forEach(node => {
|
||||||
const serviceId = node.getAttribute('data-service');
|
const serviceId = node.getAttribute('data-service');
|
||||||
|
console.log(`[InteractiveDiagram] Attaching listeners to service: ${serviceId}`);
|
||||||
|
|
||||||
|
// Use event capturing to ensure events are caught
|
||||||
node.addEventListener('click', (e) => {
|
node.addEventListener('click', (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
console.log(`[InteractiveDiagram] Clicked service: ${serviceId}`);
|
||||||
this.showServiceDetails(serviceId);
|
this.showServiceDetails(serviceId);
|
||||||
});
|
}, true);
|
||||||
|
|
||||||
node.addEventListener('mouseenter', () => {
|
node.addEventListener('mouseenter', () => {
|
||||||
this.highlightService(serviceId);
|
this.highlightService(serviceId);
|
||||||
|
|
@ -183,17 +194,33 @@ class InteractiveDiagram {
|
||||||
node.addEventListener('mouseleave', () => {
|
node.addEventListener('mouseleave', () => {
|
||||||
this.unhighlightService(serviceId);
|
this.unhighlightService(serviceId);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Add pointer cursor via JavaScript (CSP-compliant)
|
||||||
|
node.style.cursor = 'pointer';
|
||||||
});
|
});
|
||||||
|
|
||||||
this.addKeyboardNavigation(nodes);
|
this.addKeyboardNavigation(nodes);
|
||||||
|
|
||||||
|
// Show initial state (overview)
|
||||||
|
this.showServiceDetails('overview');
|
||||||
|
console.log('[InteractiveDiagram] Setup complete, showing overview');
|
||||||
};
|
};
|
||||||
|
|
||||||
// If object already loaded, initialize immediately
|
// Try multiple approaches to ensure SVG loads
|
||||||
if (objectElement.contentDocument) {
|
if (objectElement.contentDocument && objectElement.contentDocument.readyState === 'complete') {
|
||||||
|
// Object already loaded and ready
|
||||||
|
console.log('[InteractiveDiagram] Object already loaded, initializing immediately');
|
||||||
initializeSVG();
|
initializeSVG();
|
||||||
} else {
|
} else {
|
||||||
// Otherwise wait for load event
|
// Wait for load event
|
||||||
objectElement.addEventListener('load', initializeSVG);
|
console.log('[InteractiveDiagram] Waiting for object to load...');
|
||||||
|
objectElement.addEventListener('load', () => {
|
||||||
|
console.log('[InteractiveDiagram] Object loaded event fired');
|
||||||
|
initializeSVG();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Also try after a short delay as fallback
|
||||||
|
setTimeout(initializeSVG, 500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue