HTML Flatten
by Imabot
HTML
<button id="flat">Flat HTML</button>
<div contenteditable="true" id="editor-container"><h3>HTML flattener</h3><hr><p>Each row of the output array is an object composed of:</p><ul><li><b>index:</b> index from the root node</li><li><b>length:</b> length of the leaf</li><li><b>parents:</b> list of parents to the root node</li></ul><br><p>⬆ a <br> tag.</p></div>
<small>More info on <a href="https://lucidar.me/en/rich-content-editor/flatten-html/">my blog</a></small>
CSS
#editor-container {
white-space: pre-wrap;
border:1px solid;
}
JavaScript
let editor = document.getElementById('editor-container');
// When the page is ready
document.addEventListener("DOMContentLoaded", () => {
editor.focus();
console.log (flattenHtml(editor));
console.log (editor.innerText);
})
document.getElementById('flat').onclick = () => { console.log (flattenHtml(editor)); }
// Convert nested HTML info flatten array
function flattenHtml (node, flat=[], tagsList = [])
{
// Add the current tag
tagsList.push(node)
// Check if it is a leaf or not
if (!node.childNodes.length)
{
// Calculate the node index
let index = (flat[flat.length -1] === undefined) ? 0 : flat[flat.length -1].index + flat[flat.length -1].length;
// Push the node in the array
flat.push( { index: index, length: node.length ?? 1, text: node.wholeText ?? '', parents: [...tagsList] });
}
else
{
// Call the function recursively on each child
node.childNodes.forEach((child) => { flat = flattenHtml(child, flat, tagsList); })
}
// Remove the current tag
tagsList.splice(tagsList.indexOf(node),1);
return flat;
}