image emoji at caret
by electronixg
HTML
<div class="emoji-box">
<span>🙂</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;
...