I have this function to get the cursor position, when you click on the text, it only works for monospaced characters, but it obviously does not work with characters that are wider than Chinese or Japanese.
function get_char_pos(point) { var prompt_len = self.find('.prompt').text().length; var size = get_char_size(); var width = size.width; var height = size.height; var offset = self.offset(); var col = Math.floor((point.x - offset.left) / width); var row = Math.floor((point.y - offset.top) / height); var lines = get_splited_command_line(command); var try_pos; if (row > 0 && lines.length > 1) { try_pos = col + lines.slice(0, row).reduce(function(sum, line) { return sum + line.length; }, 0); } else { try_pos = col - prompt_len; }
I tried to create a function using the wcwidth library (which returns 2 for wider characters and 1 for regular letters), but this does not work completely correctly, here is the code with a demo:
var self = $('pre'); var offset = self.offset(); var command = 'γγγ·γΏγγ€γγγγ·γ€γΉγγγ·γΏγγ€γγγγ·γ€γΉγγγ·γΏγγ€γγγγ·γ€γΉ\nfoo bar baz\nfoo bar baz\nγγγ·γΏγγ€γγγγ·γ€'; self.html(command); function get_char_size() { var span = $('<span> </span>').appendTo(self); var rect = span[0].getBoundingClientRect(); span.remove(); return rect; } var length = wcwidth;
span { color: red; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://rawgit.com/jcubic/leash/master/lib/wcwidth.js"></script> <pre></pre>
I cannot use intervals for each letter, because I have text divided into 3 spans before, cursor, and after cursor. and I also have gaps for styling, which may or may not be in the container.
Any help on how to fix this feature is appreciated.
Decision
Here is my @Will based code that I used in my code that works with multiple elements (for some reason, chrome has problems when you click on an element that has only one character, and just in case the focus is no more text length):
function get_focus_offset() { var sel; if ((sel = window.getSelection()) && (sel.focusNode !== null)) { return sel.focusOffset; } } function get_char_pos(e) { var focus = get_focus_offset(); if ($.isNumeric(focus)) { var node = $(e.target);
UPDATE : there is a click problem if you click on the first half of the character that he selected correctly, but when you click on the other half, he selects the next character so that I end up with one character on the element approach.
source share