image emoji at caret

by electronixg

HTML

<div class="emoji-box">
<span>&#128578;</span>
<img src="https://upload.wikimedia.org/wikipedia/commons/0/02/Red_Circle%28small%29.svg" class="image-emoji">
</div>

<div class="input-field" placeholder="Tell me something..." contentEditable="true"></div>

CSS

html {  
  font-size: 62.5%; 
}

.image-emoji { 
  max-width: 1.8rem;
  max-height: 1.8rem;
  border-radius: 100%;
  padding: 0;
  margin: 0 0.15rem 0;  
}


.input-field {
  word-break: break-all;
  font-size:1.6rem;
  min-height: 3rem;
  max-height: 20rem;
  width: 60%; 
  margin: 0.5rem;
  padding: 1rem 6rem 1rem 4rem;
  border: 2px solid #e6e6e6;
  border-radius: 0.5rem;
  outline: none;
  overflow-y: auto;  
  line-height: 2.5rem;  
}

.input-field img {
  vertical-align: middle;
}


[contenteditable="true"]:empty:before {  
  content: attr(placeholder);
  pointer-events: none;
  display: block; /* For Firefox */
}


.emoji-box {
  display: flex;
  align-items: center;  
  font-size:1.6rem;
  background: white;
  border: 0.2rem solid #eee;
  border-radius: 0.5rem;
  height: 3rem;
  width: 60%;   
  padding: 1rem 6rem 1rem 4rem;
  margin: 0.5rem;
  color: #183153;
  cursor: pointer;
  overflow-y: auto;  
}

JavaScript

const emojiBox = document.querySelector(".emoji-box");
const inputField = document.querySelector(".input-field");
const matchHtmlTagsRegex = /<(\s|\/?)*([a-z]|!--|!doctype)+[^<>]*>/gi;

let pos;
let range;
let preCaretRange;
function getCaretIndex(element) {
  let position = 0;
  const isSupported = typeof document.getSelection() !== "undefined";
  if (isSupported) {
    const selection = document.getSelection();
    if (selection.rangeCount !== 0) {         
    
      const range = document.getSelection().getRangeAt(0);
      preCaretRange = range.cloneRange();      
      preCaretRange.selectNodeContents(element);
      preCaretRange.setEnd(range.endContainer, range.endOffset);
       preCaretRange.setStart(range.startContainer, range.startOffset);
      position = preCaretRange;
      //position = preCaretRange.toString().length;
      console.log("endContainer: " + preCaretRange.legth);
    }
  }
  return position;
}

inputField.addEventListener("click", () => {
  pos = getCaretIndex(inputField);
});
let flag=false;
inputField.addEventListener("keyup", () => {
  //requestAnimationFrame(() => {
    if (!matchHtmlTagsRegex.test(inputField.innerHTML) && flag === false) {
      inputField.innerHTML = "<div>" + inputField.innerText + "</div>"; 
      flag = true;
     
    }
  //});
});

emojiBox.addEventListener("click", (e) => {
  let emoji = null;
  let isImage = null;
  let emojiImage = null;
  let removeBR = null;
  let startPos = 0;
  let endPos = 0;
  
  if (pos){
    startPos = pos;  
    endPos = pos;   
  }
  
  console.log("target: " + e.target.outerHTML);
  let htmlLength;
  
  if (e.target != e.currentTarget) {    
    removeBR = inputField.querySelector("br");
    if (removeBR) {
      removeBR.outerHTML = "";
    }

    if (
      e.target.tagName.toLowerCase() === "img" &&
      e.target.classList.value.toLowerCase() === "image-emoji"
    )
      isImage = true;

    if (isImage) {
      emojiImage = e.target;
    } else {
      emoji = e.target;
...