What is the reason for elements such as "if" and "else" not being visually

I am currently developing a browser-based code editor with a unique feature. Task: The objective is to highlight specific keywords like if, else, for... when they are entered into the editor.


      textarea.addEventListener("input", function() {
        // Get the text inside the textarea
        const text = this.textContent;
    
        // Loop through each keyword and apply highlighting
        for (let keyword of keywords) {
          const pattern = new RegExp("\\b" + keyword + "\\b", "g");
          const replacement = "<span class='highlight'>" + keyword + "</span>";
          const highlightedText = text.replace(pattern, replacement);
          this.innerHTML = highlightedText;
        }
      });
      
      <div name="code-space" id="code__space" contenteditable="true"></div>
    

I might need to revise my approach. Any suggestions would be greatly appreciated.

Answer №1

Is this the desired outcome? Instead of using a textarea in your HTML, you opted for a contenteditable div, so I implemented my modifications based on the input event triggered by the editable text:

var editor = document.querySelector('#code__space');

const keywords = ['if', 'else', 'for'];
let timeoutId;

editor.addEventListener('input', function() {
  clearTimeout(timeoutId);
  timeoutId = setTimeout(function() {
    var text = editor.textContent;

    for (let keyword of keywords) {
      const pattern = new RegExp('\\b' + keyword + '\\b', 'g');
      const replacement = '<span class="highlight">' + keyword + '</span>';
      text = text.replace(pattern, replacement);
    }
    
    const sel = window.getSelection();
    const node = sel.focusNode;
    const offset = sel.focusOffset;
    const pos = getCursorPosition(editor, node, offset, { pos: 0, done: false });
    if (offset === 0) pos.pos += 0.5;

    editor.innerHTML = text;
    
    // restore the position
    sel.removeAllRanges();
    const range = setCursorPosition(editor, document.createRange(), {
      pos: pos.pos,
      done: false,
    });
    range.collapse(true);
    sel.addRange(range);
    
  }, 1000);
});

// get the cursor position from .editor start
function getCursorPosition(parent, node, offset, stat) {
  if (stat.done) return stat;

  let currentNode = null;
  if (parent.childNodes.length == 0) {
    stat.pos += parent.textContent.length;
  } else {
    for (let i = 0; i < parent.childNodes.length && !stat.done; i++) {
      currentNode = parent.childNodes[i];
      if (currentNode === node) {
        stat.pos += offset;
        stat.done = true;
        return stat;
      } else getCursorPosition(currentNode, node, offset, stat);
    }
  }
  return stat;
}

//find the child node and relative position and set it on range
function setCursorPosition(parent, range, stat) {
  if (stat.done) return range;

  if (parent.childNodes.length == 0) {
    if (parent.textContent.length >= stat.pos) {
      range.setStart(parent, stat.pos);
      stat.done = true;
    } else {
      stat.pos = stat.pos - parent.textContent.length;
    }
  } else {
    for (let i = 0; i < parent.childNodes.length && !stat.done; i++) {
      currentNode = parent.childNodes[i];
      setCursorPosition(currentNode, range, stat);
    }
  }
  return range;
}
.highlight {
  color: #bf0808;
  background: #b6b6b9;
  font-weight: bold;
}

#code__space {
  border: 1px solid #ccc;
  min-height: 100px;
  padding: 10px;
  direction: ltr;
}
<div name="code-space" id="code__space" contenteditable="true" style="border: 1px solid blue; min-height: 2em"></div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is the <a data-method='something' href ... requesting a POST method?

Yes, it does. Has this behavior been documented anywhere? Situation: I made an error with my RoR Helper and created Links with data-method='GET'. Everything still functioned correctly, but I received a "Resend Data Warning" when refreshing the ...

Unable to change Gutters to 0 in the .container-fluid class in Bootstrap 5.2

I have gone through all the answers related to my question, but I couldn't find a solution for it. Below is the HTML code with Bootstrap 5.2 that I am working on: <section id="title"> <div class="container-fluid"> ...

Looking to add multiple instances of a jQuery effect on a single page?

Currently, I am utilizing a jQuery background scroller and aiming to display multiple instances on the same page with varying speeds. However, I am encountering difficulties in achieving this customization. var scrollSpeed = 70; // Speed in millis ...

Using the toggle method or IF statements in JavaScript to implement show and hide functionality upon clicking

I’ve been struggling with this issue for days now. It seems like I may have overcomplicated a simple piece of code. I'm trying to show some divs when a button is clicked, but I’m having trouble getting it to work properly. Initially, I used VAR.st ...

Tips for handling uncaught exceptions in Internet Explorer

In both Chrome and Firefox, it is possible to suppress exceptions, but unfortunately, this is not the case with Internet Explorer (IE). window.addEventListener("error", function errorHandler(event) { console.log("exception should be suppressed and not ...

Minor Chrome compatibility problems with CSS alignment

As someone who is new to stackoverflow, I've always found it to be a valuable resource for answers. I've had success building HTML 5 banner ads using GSAP (Greensock Animation Platform) in the past, but now I'm facing a CSS alignment issue t ...

What causes my CSS to be disrupted by a line break in one instance but not in another? (view demonstrations)

https://i.stack.imgur.com/bitod.png In comparing this particular fiddle with another version of the same fiddle, the only variance is that in the second one, there is </label><label for="address_zip" class="zip"> without a line break following ...

Conceal a div containing a specific class during the page's loading process, then reveal it once the

Is there a way to hide a specific div class while a page is loading? Here is the structure I am working with: <div id ="container"> <div class="project-item tv"></div> <div class="project-item radio"></div> <div class="pro ...

Stripe: Either a source or customer must be provided

I've been working on incorporating Stripe into my online shopping cart project, but I've hit a roadblock. Whenever I try to submit the checkout form, I keep encountering the error message: "Must provide source or customer." I suspect there might ...

Is create-react-native-app experiencing functionality issues?

As someone who is new to expo and create-react-native-app, I recently encountered a strange issue while learning react-native. Normally, I use create-react-native-app without any problems. However, one day when I tried to create a new project, I was presen ...

The border color of the text input is not changing as expected when in focus

Is there a way to change the border color of a text input field to blue when it is not selected and then change it to orange when the field is selected? input[type="text"]{ border: 1px solid blue; } input[type="text"]:focus{ border: 1px solid ora ...

Retrieving the output from a nested function within a function in a Node.js application connected to a

I'm currently working on a basic web application that interacts with a database by performing INSERT and SELECT operations on a single table. While I have utilized a function from various tutorials, I am struggling to retrieve the results from the SEL ...

What is the proper way to incorporate the "pdf" package into a TypeScript project?

I recently installed pdf and its types using the following command: npm install --save pdf @types/pdf However, I am struggling to find any documentation on how to actually use this package. When I try the following code: import {PDFJS} from 'pdf&ap ...

Troubleshooting: Issue with Angular 2 bidirectional data binding on two input fields

Hi there, I am encountering an issue with the following code snippet: <input type="radio" value="{{commencementDate.value}}" id="bankCommencementDateSelect" formControlName="bankCommencementDate"> <input #commencementDate id="bankCommencementDat ...

Tips on managing URL in jQuery Mobile that appears in the navigation bar

I am currently working on a jQuery Mobile application that is designed to function on a single static URL, also known as a single page application. Using $.mobile.changePage.defaults.changeHash = false within the mobileinit event has been successful in ma ...

Transferring information from the service layer to the controller

My goal is to transfer data from a service to a controller using AngularJS. Below is the code I am using: .controller('lista',function($scope,cetrams){ $scope.hola="This is it"; var test; var testfn = function(){ test = &apo ...

Modify the values of an object by utilizing the setter function

How can I utilize the setter method to update existing values of an object and perform mathematical operations? var obj = { set model(object) { //method's logic } }; obj = {x:10, y: 20, p: 15}; obj = { x:10, y: 20, p: 15 set mod ...

When the page is scrolled to 50 pixels, a modal pop-up will appear

I attempted to use cookies to store a value when the user clicks on a popup to close it, ensuring that the popup does not show again once closed. However, I am encountering an issue where the popup continues to open whenever I scroll, even after closing it ...

Switching the mouse cursor when the mousedown event occurs

I'm trying to implement a feature where holding down the mouse will change the cursor to an image, and when releasing the mouse it should revert back to its default. However, the code I have isn't working properly - you have to right click then l ...

Discover how to capture a clicked word within the Ionic Framework

I've been working on an app using the Ionic Framework. I am trying to figure out how to detect when a word is pressed in my application. One solution I tried involved splitting the string into words and generating a span with a click event for each on ...