How to make HTML5 contenteditable div allowing only text in firefox?
Sadly, you can’t. As this answer points out the spec only specifies true
, false
and inherit
as valid parameters. The subject seems to have been discussed but if I’m not mistaken only Webkit implements support for plaintext-only
.
I ran into this problem myself. Here is my solution which I have tested in Firefox and Chrome:
Ensure the contenteditable
div has the css white-space: pre
, pre-line
or pre-wrap
so that it displays \n
as new lines.
Override the "enter" key so that when we are typing, it does not create any <div>
or <br>
tags
myDiv.addEventListener("keydown", e => {
//override pressing enter in contenteditable
if (e.keyCode == 13)
{
//don't automatically put in divs
e.preventDefault();
e.stopPropagation();
//insert newline
insertTextAtSelection(myDiv, "\n");
}
});
Secondly, override the paste event to only ever fetch the plaintext
//override paste
myDiv.addEventListener("paste", e => {
//cancel paste
e.preventDefault();
//get plaintext from clipboard
let text = (e.originalEvent || e).clipboardData.getData('text/plain');
//insert text manually
insertTextAtSelection(myDiv, text);
});
And here is the supporting function which inserts text into the textContent of a div, and returns the cursor to the proper position afterwards.
function insertTextAtSelection(div, txt) {
//get selection area so we can position insert
let sel = window.getSelection();
let text = div.textContent;
let before = Math.min(sel.focusOffset, sel.anchorOffset);
let after = Math.max(sel.focusOffset, sel.anchorOffset);
//ensure string ends with \n so it displays properly
let afterStr = text.substring(after);
if (afterStr == "") afterStr = "\n";
//insert content
div.textContent = text.substring(0, before) + txt + afterStr;
//restore cursor at correct position
sel.removeAllRanges();
let range = document.createRange();
//childNodes[0] should be all the text
range.setStart(div.childNodes[0], before + txt.length);
range.setEnd(div.childNodes[0], before + txt.length);
sel.addRange(range);
}
https://jsfiddle.net/1te5hwv0/