diff --git a/src/pyj/read_book/create_annotation.pyj b/src/pyj/read_book/create_annotation.pyj index 9e0e34f95a..5702510faf 100644 --- a/src/pyj/read_book/create_annotation.pyj +++ b/src/pyj/read_book/create_annotation.pyj @@ -44,6 +44,7 @@ class CreateAnnotation: def __init__(self, view): self.view = view self.state = WAITING_FOR_CLICK + self.left_line_height = self.right_line_height = 8 container = self.container self.position_in_handle = {'x': 0, 'y': 0} @@ -64,7 +65,7 @@ class CreateAnnotation: ev.stopPropagation(), ev.preventDefault() if self.state is WAITING_FOR_CLICK: pt = map_to_iframe_coords({'x': ev.clientX, 'y': ev.clientY}) - self.send_message(type='position-handles-at-point', x=pt.x, y=pt.y) + self.send_message('position-handles-at-point', x=pt.x, y=pt.y) def mousedown_on_handle(self, ev): ev.stopPropagation(), ev.preventDefault() @@ -94,6 +95,10 @@ class CreateAnnotation: s = handle.style s.left = (ev.clientX - self.position_in_handle.x) + 'px' s.top = (ev.clientY - self.position_in_handle.y) + 'px' + pos = self.current_handle_position + pos.start = map_to_iframe_coords(pos.start) + pos.end = map_to_iframe_coords(pos.end) + self.send_message('set-selection', extents=pos) @property def container(self): @@ -111,14 +116,22 @@ class CreateAnnotation: def is_visible(self): return self.container.style.display is not 'none' + @property + def current_handle_position(self): + lh, rh = self.left_handle.getBoundingClientRect(), self.right_handle.getBoundingClientRect() + return { + 'start': {'x': Math.round(lh.right), 'y': Math.round(lh.bottom - self.left_line_height // 2)}, + 'end': {'x': Math.round(rh.left), 'y': Math.round(rh.bottom - self.right_line_height // 2)} + } + def show(self): self.container.style.display = 'block' def hide(self): self.container.style.display = 'none' - def send_message(self, **kw): - self.view.iframe_wrapper.send_message('annotations', **kw) + def send_message(self, type, **kw): + self.view.iframe_wrapper.send_message('annotations', type=type, **kw) def handle_message(self, msg): if msg.type is 'create-annotation': @@ -160,3 +173,5 @@ class CreateAnnotation: style, width = do_it(rh, extents.end) style.left = extents.end.x + 'px' self.state = WAITING_FOR_DRAG + self.left_line_height = extents.start.height + self.right_line_height = extents.end.height diff --git a/src/pyj/read_book/iframe.pyj b/src/pyj/read_book/iframe.pyj index 3541318d9e..e7ec0e0ca3 100644 --- a/src/pyj/read_book/iframe.pyj +++ b/src/pyj/read_book/iframe.pyj @@ -4,7 +4,9 @@ from __python__ import bound_methods, hash_literals import traceback from gettext import gettext as _ -from select import selection_extents, selection_extents_at_point +from select import ( + selection_extents, selection_extents_at_point, set_selections_extents_to +) from fs_images import fix_fullscreen_svg_images from iframe_comm import IframeClient @@ -611,7 +613,9 @@ class IframeBoss: ) def annotations_msg_received(self, data): - if data.type is 'position-handles-at-point': + if data.type is 'set-selection': + set_selections_extents_to(data.extents) + elif data.type is 'position-handles-at-point': self.send_message( 'annotations', type='position-handles', diff --git a/src/pyj/select.pyj b/src/pyj/select.pyj index 6e11b98c67..0ff69be331 100644 --- a/src/pyj/select.pyj +++ b/src/pyj/select.pyj @@ -90,3 +90,16 @@ def selection_extents_at_point(x, y): ans.start.x = x ans.end.x = x + ans.start.height * 3 return ans + + +def set_selections_extents_to(extents): + start = range_from_point(extents.start.x, extents.start.y) + if start: + end = range_from_point(extents.end.x, extents.end.y) + if end: + r = document.createRange() + r.setStart(start.startContainer, start.startOffset) + r.setEnd(end.startContainer, end.startOffset) + sel = window.getSelection() + sel.removeAllRanges() + sel.addRange(r)