JSFiddle - React, Tailwind, and code Playground
HTML
<div id="content">
<p>Text example</p>
<p>تجربة نص</p>
<p>Text example تجربة نص</p>
<p>تجربة نص Text example</p>
</div>
<div id="pointer">^</div>
CSS
div {
margin-bottom: 10px;
font-family: arial;
}
#pointer {
position: absolute;
display: none;
color: #f00;
font-weight: bold;
font-size: 20px;
}
JavaScript
function hilightEnd() {
// there is selction?
if(!window.getSelection().isCollapsed) {
// find direction of selection
var sel = window.getSelection();
var range = document.createRange();
range.setStart(sel.anchorNode, sel.anchorOffset);
range.setEnd(sel.focusNode, sel.focusOffset);
var backwards = range.collapsed;
range.detach();
// get selection rects
var rects = sel.getRangeAt(0).getClientRects();
var n = rects.length - 1;
// display end marker based on direction of selection
if (lastCharRTL(getSelectionHtml()))
$('#pointer').css({top: rects[n].top + 10, left: rects[n].left - 10}).show();
else if(backwards)
$('#pointer').css({top: rects[0].top + 10, left: rects[0].left - 10}).show();
else
$('#pointer').css({top: rects[n].top + 10, left: rects[n].right}).show();
}
else {
$('#pointer').hide();
}
}
// Return HTML from a user selection
// Posted by Tim Down (http://stackoverflow.com/a/4652824/2034234)
function getSelectionHtml() {
var html = "";
if (typeof window.getSelection != "undefined") {
var sel = window.getSelection();
if (sel.rangeCount) {
var container = document.createElement("div");
for (var i = 0, len = sel.rangeCount; i < len; ++i) {
container.appendChild(sel.getRangeAt(i).cloneContents());
}
html = container.innerHTML;
}
} else if (typeof document.selection != "undefined") {
if (document.selection.type == "Text") {
html = document.selection.createRange().htmlText;
}
}
return html;
}
function lastCharRTL(txt) {
return /[\u0591-\u07FF\uFB1D-\uFDFD\uFE70-\uFEFC]$/.test(txt);
}
$('#content').attr('contenteditable', true).on('mouseup mousedown keyup keydown', hilightEnd);