In a contenteditable element in which a list has been inserted with document.execCommand, is it possible to create next paragraph at the root of the editable element and not within the container of the list?
I tried to hijack "enter" keydown and play with the selection / range but did not manage to achieve such goal. The browser seems to always add the next paragraph within the container of the list.
For example:
<div contenteditable="true">
<div>
<ol>
<li>1</li>
<li>focus -> user click enter here twice</li>
results in
<div contenteditable="true">
<div>
<ol>
<li>1</li>
<li></li>
</ol>
<div>after clicking twice enter, focus is here and newly created div is a sibling of ol</div>
but I would like to get
<div contenteditable="true">
<div>
<ol>
<li>1</li>
<li></li>
</ol>
</div>
<div>after clicking twice enter, focus is here and newly created div finds place at the root</div>
note that I aim to use document.execCommand because my feature needs to support undo / redo (and I am not that motived to implement once again my own custom undo / redo stack).
Use appendChild.
const mainDiv = document.querySelector('[contenteditable]');
const newDiv = document.createElement('div');
newDiv.textContent = 'foo';
mainDiv.appendChild(newDiv);
<div contenteditable="true">
<div>
<ol>
<li>1</li>
<li>focus -> user click enter here twice</li>
</ol>
</div>
</div>
My answer was based on a solution found here: How to set the caret (cursor) position in a contenteditable element (div)?
Not sure if this exactly what you're looking for. Pressing enter twice in a row will place the cursor at the end of "focus here" text and put you outside of the OL element.
var lastKey = null;
document.querySelector('[contenteditable="true"]').addEventListener('keyup', e => {
e.target.children[1];
if (e.key === 'Enter' && e.key === lastKey){
var range = document.createRange();
var sel = window.getSelection();
var el = e.target.children[1];
range.setStart(el.childNodes[0],el.childNodes[0].textContent.length);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
}
lastKey = e.key;
});
<div contenteditable="true">
<div>
<ol>
<li>1</li>
<li></li>
</ol>
</div>
<div>focus here</div>
</div>