-1

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>&gt;</span>
 &gt;
</span>

Instead I need this without nesting:

<span>&gt;</span>
<span>&gt;</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>&gt;</span>
<span>&gt;</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>)&gt;(?!<\/span)/, 'g').test($(this).html()) ) {
    $(this).html(
      $(this).html().replace(/(?!<span>)&gt;(?!<\/span)/g, '<span>&gt;</span>')
    );

    setCurrentCursorPosition( $(this).text().length );
  }
});

Codepen demo

You can ignore createRange, setCurrentCursorPosition functions. They just move the cursor when typing > into the div.

david
  • 1
  • 2

1 Answers1

-1

Use html entities

<span>&gt;</span>

Documentation: https://www.w3schools.com/html/html_entities.asp

Wimanicesir
  • 4,606
  • 2
  • 11
  • 30