7
I have a div
with contenteditable=true
in my document and I intend to do Highlight in certain parts of the text while the user type (add spans). For this I first need to extract the text typed by the user in the form of a simple string, without tags, and preserving line breaks. Thus <p>aa</p><p>bb</p>
would generate "aa\nbb"
and <div>aaa</div><div><br></div>
would generate "aaa\n"
. For this I created a function that is called in the oninput
of the div and that should return an array with each line of text (["aa", "bb"]
and ["aaa", ""]
for the above examples).
Initially I did focusing only on Chrome. It creates the content of the div as the user types producing internal Ivs for each line. In some cases Divs can be generated inside each other. Ex: (identation has been added for readability)
<div contenteditable=true>
primeira linha
<div>segunda linha</div>
<div><br></div>
<div>
quarta linha
<div>quinta linha</div>
</div>
</div>
I made the following code to get the resulting array:
function extractLines(elem) {
var nodes = elem.childNodes;
var lines = [];
for (i = 0; i < nodes.length; ++i) {
var node = nodes[i];
if (node.nodeName == "#text") {
lines.push(node.nodeValue);
}
else if (node.nodeName == "BR") {
lines.push("");
}
else { // DIV ou P
lines.push.apply(lines, extractLines(node));
}
}
return lines;
}
The idea is quite simple:
For each subnode of the div:
- If it is a text node, it is a line. Include in the array.
- If it is a
<br>
, is a blank line. Include""
in the array. - If it is a
<div>
or<p>
, recursively execute this algorithm and insert the result at the end of the array.
But this same code generates an endless loop in some of my tests, I don’t understand why.
<div>aa<div><br></div></div>
=>["aa", ""]
<div>aa<div><br></div><div><br></div></div>
=> infinite loop
Why this infinite loop happens? Is there something wrong with my code? How to implement this same algorithm without this problem?
+1 for a brilliant solution... ;)
– utluiz