import { registerClearHandler } from './devtools.js';
function renderNode(node, depth, maxExpand) {
if (node.type === 'text') {
const text = node.text.trim();
if (!text) return '';
return `
${escapeHtml(text)}
`;
}
const hasChildren = node.children && node.children.length > 0;
const expanded = depth < maxExpand;
let attrs = '';
if (node.attrs) {
for (const a of node.attrs) {
attrs += ` ${escapeHtml(a.name)}="${escapeHtml(a.value)}"`;
}
}
let html = '';
html += `
';
return html;
}
html += '';
if (hasChildren) {
html += ``;
for (const child of node.children) {
html += renderNode(child, depth + 1, maxExpand);
}
html += `
</${escapeHtml(node.tag)}>
`;
html += '
';
}
html += '';
return html;
}
function escapeHtml(str) {
return str.replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"');
}
function bindToggleHandlers(container) {
container.querySelectorAll('.el-node-header[data-has-children="true"]').forEach(header => {
header.addEventListener('click', () => {
const children = header.nextElementSibling;
if (!children || !children.classList.contains('el-children')) return;
const toggle = header.querySelector('.el-toggle');
const isExpanded = children.classList.contains('expanded');
children.classList.toggle('expanded');
toggle.textContent = isExpanded ? '▶' : '▼';
});
});
}
let lastTree = null;
function render(tree) {
lastTree = tree;
const out = document.getElementById('elements-output');
if (!tree) {
out.innerHTML = 'No elements captured. Run your code to see the DOM tree.
';
return;
}
out.innerHTML = renderNode(tree, 0, 2);
bindToggleHandlers(out);
}
export function clearElements() {
lastTree = null;
document.getElementById('elements-output').innerHTML = '';
}
export function initElements() {
registerClearHandler('elements', clearElements);
window.addEventListener('message', (e) => {
if (!e.data || e.data.type !== 'devtools' || e.data.tab !== 'elements') return;
if (e.data.tree) render(e.data.tree);
});
}