I have this contentEditable code:
function uuid() { // to generate uuid
return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
)
}
// ---------------------------------
// observing any div addition to conentEditable div in order to assign new uuid for added div
function subscriber(mutations) {
mutations.forEach(mutation => {
mutation.addedNodes.forEach(node => node.id = uuid());
console.clear();
console.log([...mutation.target.children].map(x => x.id));
});
}
const observer = new MutationObserver(subscriber);
observer.observe(document.querySelector('div[contenteditable]'), { childList: true });
// ---------------------------------
// Assigning tab key shortcut
document.querySelector('div[contenteditable]').onkeydown = function(e){
if (e.keyCode === 9) {
e.preventDefault(); // this will prevent us from tabbing out of the editor
document.execCommand('styleWithCSS',true,null);
document.execCommand('indent',true,null);
}
};
<div contenteditable>
<div id="48b62163-9f3b-4b20-8dad-dc99e27e1243">Edit text content here.<div>
</div>
The code sets new uuid for every newly created element within the contentEditable on line break. The MutationObserver code was originally mentioned in a previous question.
To illustrate what I want to do, I'll explain this example:
Let's say I typed:
Edit text content here.
New line 1.
New line 2.
New line 3.
Then, I will have the original html code like this:
<div contenteditable>
<div id="48b62163-9f3b-4b20-8dad-dc99e27e1243">Edit text content here.</div>
<div id="0b0e3518-1fb2-43e4-9160-6563ac0f82be">New line 1.</div>
<div id="57d399c6-afa0-42ae-83c2-d6d7937f22d3">New line 2.</div>
<div id="1fe51cac-bb79-47e2-bd95-e813b33e29aa">New line 3.</div>
</div>
Now when cursor being on New line 2
, and I press the tab key, the line will be indented and the view of the contentEditable will be like this:
Edit text content here.
New line 1.
. . . New line 2.
New line 3.
and the original html code will be like this:
<div contenteditable>
<div id="48b62163-9f3b-4b20-8dad-dc99e27e1243">Edit text content here.</div>
<div id="0b0e3518-1fb2-43e4-9160-6563ac0f82be">New line 1.</div>
<blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" id="a1badbcd-be93-4193-b73f-807d619393b5">
<div id="57d399c6-afa0-42ae-83c2-d6d7937f22d3">New line 2.</div>
</blockquote>
<div id="1fe51cac-bb79-47e2-bd95-e813b33e29aa">New line 3.</div>
</div>
I don't want to make indentation like this, with creating blockquote
.
Instead, I want it to move the active div
to be a child of the preceding one like this:
<div contenteditable>
<div id="48b62163-9f3b-4b20-8dad-dc99e27e1243">Edit text content here.</div>
<div id="0b0e3518-1fb2-43e4-9160-6563ac0f82be">New line 1.
<div id="57d399c6-afa0-42ae-83c2-d6d7937f22d3" style="margin: 0 0 0 40px;>New line 2.</div>
</div>
<div id="1fe51cac-bb79-47e2-bd95-e813b33e29aa">New line 3.</div>
</div>
And I want it when I intend more like this:
Edit text content here.
New line 1.
. . . . . . . . . New line 2.
New line 3.
, the html code becomes:
<div contenteditable>
<div id="48b62163-9f3b-4b20-8dad-dc99e27e1243">Edit text content here.</div>
<div id="0b0e3518-1fb2-43e4-9160-6563ac0f82be">New line 1.
<div id="57d399c6-afa0-42ae-83c2-d6d7937f22d3" style="margin: 0 0 0 120px;>New line 2.</div>
</div>
<div id="1fe51cac-bb79-47e2-bd95-e813b33e29aa">New line 3.</div>
</div>
I've thoughts to approach this to make the code check if there's a preceding div
element, if so, it should make the active div
element to be its child. Also the indentation styling will be added to the active div
element.
I'll play with window.getSelection().focusNode.parentNode
a little and post my solution once I finish writing it. However, I hope there's some more efficient way.