4

I have been trying to add text highlighting to python code in a writable div using spans since spans do not work inside textarea, but for some reason the div reverses any text, here's a simplified version of the code:

<div id="code-editor" spellcheck="false" contenteditable="true"></div>

<script>

    const writableDiv = document.getElementById("code-editor");

    const pythonKeyWords = [ /* has all python keywords */ ]

    const keywordRegex = new RegExp('\\b(' + pythonKeywords.join('|') + ')\\b', 'g');

    writableDiv.addEventListener('input', () => {
        let text = writableDiv.innerText;
        text = text.replace(keywordRegex, '<span style="color: #f200ff;">$&</span>');
        writableDiv.innerHTML = text;
    });

</script>

Here, if I enter def from the keyword, it comes out as fed in the the div, and vice versa.

I would like to know what's wrong with what I am doing, because I have tried to use highlights.js and to customize it a bit but it got the same issue as this one.

Jam
  • 65
  • 7
  • 1
    The problem is, that changing the content of a contenteditable div resets the cursor. After every letter you type, the cursor moves to the start of the line, because you updated the innerHTML. That's why you're effectively writing in reverse. I've found some solutions here https://stackoverflow.com/questions/24845254/modify-text-in-a-contenteditable-div-without-resetting-the-caret-cursor-positi and here https://stackoverflow.com/questions/43533971/contenteditable-div-set-cursor-position-after-updating-inner-html – FireFuro99 May 07 '23 at 23:26
  • 1
    @FireFuro99 That actually makes sense because it was updating the cursor's position even without replacing the `text` - just by using the innerHTML. Thanks! – Jam May 08 '23 at 05:32

2 Answers2

0

Please try using textContent instead of innerHTML like this:

writableDiv.addEventListener('input', () => {
  let text = writableDiv.innerText;
  text = text.replace(keywordRegex, '<span style="color: #f200ff;">$&</span>');
  writableDiv.innerHTML = text;
}
its-me-mahmud
  • 690
  • 1
  • 7
  • 14
Prerak Patel
  • 84
  • 13
0

I think this is a problem of design

If you are trying to create a code editor, you can create it via differents technics, like put an invisible input and then on space key, or enter key, add the word to the editor, like chips elements https://material.angular.io/components/chips/examples

Anyways, I woudl recommend and input element, than a div editor element, those elements are for different purposes. Input type text is the way.

Another one is to create a input like WYSIWYG but those are ver difficult to create, here are some examples:

https://onlinehtmleditor.dev/

Or in your case, search for some library with all this work aready done.

If you look at the HTML at the time of edit, there are a lot of tricks of constanting generate new html code and printing and hiding inputs elements.

This is an expensive work, I would recommend an editor that already exists and use it. It is a lot of work. Good Luckk!

  • Thanks! I'll check codemirror and hopefully it would be fixed. – Jam May 08 '23 at 05:27
  • 1
    Glad to help, ths code mirror looks "simply" and also use div with content editor Here is the source code of view element https://github.com/codemirror/view Maybe you can use that same librarye which is in NPM and it has https://github.com/codemirror/lang-python for python support I'm sure that is a lop of work to do with this and using something that already exists will help on your proyect (Y) – Cristóbal Díaz Álvarez May 08 '23 at 05:52