I am trying to find >
sign in editable div
with REGEX
, replace it wrapping in span. The script(REGEX
) works, but it has a few bugs.
If I type >
sign 2 times dividing them by space like > >
, it creates the following.
<span>
<span>></span>
>
</span>
Instead I need this without nesting:
<span>></span>
<span>></span>
Also If I type >
2 times without space like >>
, REGEX
should take each >
sign and wrap it into a separate span
, like this:
<span>></span>
<span>></span>
Here is my code:
<div class="editable" contenteditable="true"></div>
.editable{
height: 20px;
border: 1px solid grey;
cursor: text;
white-space: pre-wrap;
}
span{
white-space: pre-wrap;
}
var createRange = function (node, chars, range) {
if (!range) {
range = document.createRange()
range.selectNode(node);
range.setStart(node, 0);
}
if (chars.count === 0) {
range.setEnd(node, chars.count);
} else if (node && chars.count >0) {
if (node.nodeType === Node.TEXT_NODE) {
if (node.textContent.length < chars.count) {
chars.count -= node.textContent.length;
} else {
range.setEnd(node, chars.count);
chars.count = 0;
}
} else {
for (var lp = 0; lp < node.childNodes.length; lp++) {
range = createRange(node.childNodes[lp], chars, range);
if (chars.count === 0) {
break;
}
}
}
}
return range;
};
var setCurrentCursorPosition = function (chars) {
if (chars >= 0) {
var selection = window.getSelection();
range = createRange(document.querySelector('.editable'), { count: chars });
if (range) {
range.collapse(false);
selection.removeAllRanges();
selection.addRange(range);
}
}
};
$('.editable').on('keydown', function() {
if( new RegExp(/(?!<span>)>(?!<\/span)/, 'g').test($(this).html()) ) {
$(this).html(
$(this).html().replace(/(?!<span>)>(?!<\/span)/g, '<span>></span>')
);
setCurrentCursorPosition( $(this).text().length );
}
});
You can ignore createRange
, setCurrentCursorPosition
functions. They just move the cursor when typing >
into the div
.