I have a div contentEditable=true where multi-line text is entered. Whenever the user press enter, I would like to inspect the line in which the user was to see what is the context of that line (preferably, of all lines).
Is it possible to have something like window.getSelection().lineContent
?
I can use window.getSelection().anchorNode.textContent
, but it will only work for the current node (not the line). I'm assuming the user will press enter to go to next line and I'd like to know if next line should or not be indented (my main goal is to know whether there is a "tab" in the beginning of the line, so far).
EDIT: Current code:
document.getElementById('sampleeditor').addEventListener("keydown", fSubsTab );
function fSubsTab () {
e = window.event
if ( false ) {
} else if ( e.keyCode == 13 ) {
e.preventDefault();
if (!window.getSelection) return;
sel = window.getSelection();
node_offset = sel.anchorOffset
node_text = sel.anchorNode.textContent
// The problem is how would I get the content of the
// current line between last line break and next one,
// or until the end
}
}
EDIT 2: SOLVED. See answer below.
I've solved it by using a custom function to generate a uuid, add it to the text and then remove it back. The code is a little messy because of the quantity of functions used, but it goes something like this
// function for replacing characters without case sensitivity
String.prototype.replaces = function(str, replace, incaseSensitive) {
if(!incaseSensitive){
return this.split(str).join(replace);
} else {
// Replace this part with regex for more performance
var strLower = this.toLowerCase();
var findLower = String(str).toLowerCase();
var strTemp = this.toString();
var pos = strLower.length;
while((pos = strLower.lastIndexOf(findLower, pos)) != -1){
tcounter++
strTemp = strTemp.substr(0, pos) + replace + strTemp.substr(pos + findLower.length);
pos--;
if (pos<0) {
break
}
}
return strTemp;
}
};
// function for generating uuid to be used after
function uuidv4() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
// function for dealing with linebreaks from innerhtml and returning as text with line breaks
function innerHTMLtoText ( inner ) {
text = inner
prelb = uuidv4() + uuidv4() + uuidv4() + uuidv4()
prelb_list = [];
lb = prelb + "ddd" + prelb; prelb_list.push(lb);
tag_ = "<div>"; text = text.replaces ( tag_, lb + tag_, true );
tag_ = "</div>"; text = text.replaces ( tag_, lb + tag_, true );
tag_ = "<div "; text = text.replaces ( tag_, lb + tag_, true );
lb = prelb + "ppp" + prelb; prelb_list.push(lb);
tag_ = "<p>"; text = text.replaces ( tag_, lb + tag_, true );
tag_ = "</p>"; text = text.replaces ( tag_, lb + tag_, true );
tag_ = "<p "; text = text.replaces ( tag_, lb + tag_, true );
lb = prelb + "bbb" + prelb; prelb_list.push(lb);
tag_ = "<br>"; text = text.replaces ( tag_, lb + tag_, true );
tag_ = "<br "; text = text.replaces ( tag_, lb + tag_, true );
// tag_ = "<br />"; text = text.replaces ( tag_, lb + tag_, true );
tag_ = "<br/>"; text = text.replaces ( tag_, lb + tag_, true );
tag_ = "</br>"; text = text.replaces ( tag_, lb + tag_, true );
var temporalDivElement = document.createElement("div");
temporalDivElement.innerHTML = text;
text = temporalDivElement.textContent
list_ = prelb_list
for ( let i = 0 ; i<list_.length ; i++ ) {
this_ = list_[i]
text = text.replaces ( this_, "\n", true );
}
return text
}
// main function, that generates a uuid, inserts at caret position, checks text of line, and removes the uuid
document.getElementById('sampleeditor').addEventListener("keyup", function(e) {
if(e.keyCode == 13) {
texteditor = document.getElementById('sampleeditor')
e.preventDefault();
if (!window.getSelection) return;
sel = window.getSelection();
if (!sel.rangeCount) return;
range = sel.getRangeAt(0);
range.collapse(true);
span = document.createElement('span');
span.appendChild(document.createTextNode(' '));
theSpanId = "span_" + uuidv4() + uuidv4() + uuidv4() + uuidv4()
span.id = theSpanId
outerInclude = span.outerHTML
changeText = document.createElement('span');
idToRemove = uuidv4() + uuidv4() + uuidv4() + uuidv4()
changeText.innerHTML = idToRemove
outerRemove = changeText.outerHTML
range.insertNode(changeText);
theinner = texteditor.innerHTML
plainText = innerHTMLtoText ( theinner )
posLineBreak = plainText.indexOf (idToRemove)
textBefore = plainText.substring(0, posLineBreak)
textBefore = textBefore.split ("\n")
linePart1 = textBefore[textBefore.length-1]
textAfter = plainText.substring(posLineBreak)
textAfter = textAfter.split ("\n")
linePart2 = textAfter[0]
fullLine = linePart1 + linePart2
fullLine = fullLine.split ( idToRemove ).join ("")
texteditor.innerHTML = texteditor.innerHTML.split(outerRemove).join("<br>" + outerInclude)
range = sel.getRangeAt(0);
range.collapse(true);
span = document.getElementById(theSpanId)
range.setStartAfter(span);
range.collapse(true);
var startNode = span.firstChild;
var endNode = span.firstChild;
var range = document.createRange();
range.setStart(startNode, 0);
range.setEnd(endNode, 0+1);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
});