diff --git a/src/pyj/range_utils.pyj b/src/pyj/range_utils.pyj index 50bfb0a933..4831b8c96a 100644 --- a/src/pyj/range_utils.pyj +++ b/src/pyj/range_utils.pyj @@ -53,6 +53,16 @@ def unwrap_crw(crw): unwrap(node) +def select_crw(crw): + nodes = document.querySelectorAll(f'span[data-calibre-range-wrapper="{crw}"]') + r = document.createRange() + r.setStart(nodes[0].firstChild, 0) + r.setEnd(nodes[-1].lastChild, nodes[-1].lastChild.nodeValue.length) + sel = window.getSelection() + sel.removeAllRanges() + sel.addRange(r) + + def create_wrapper_function(wrapper_elem, r, intersecting_wrappers): start_node = r.startContainer end_node = r.endContainer @@ -106,3 +116,18 @@ def wrap_text_in_range(style, r): def reset_highlight_counter(): nonlocal wrapper_counter wrapper_counter = 0 + + +def set_selection_to_highlight(): + sel = window.getSelection() + if not sel or not sel.getRangeAt(0): + return + r = sel.getRangeAt(0) + crw = None + for node in text_nodes_in_range(r): + crw = node.parentNode.dataset.calibreRangeWrapper + if crw: + break + if crw: + select_crw(crw) + return crw or None diff --git a/src/pyj/read_book/create_annotation.pyj b/src/pyj/read_book/create_annotation.pyj index 6e26c12141..c4fe9adf7a 100644 --- a/src/pyj/read_book/create_annotation.pyj +++ b/src/pyj/read_book/create_annotation.pyj @@ -137,6 +137,7 @@ class CreateAnnotation: def __init__(self, view): self.view = view + self.editing_annot_uuid = None self.annotations_manager = self.view.annotations_manager self.state = WAITING_FOR_CLICK self.left_line_height = self.right_line_height = 8 @@ -313,7 +314,7 @@ class CreateAnnotation: for k in Object.keys(self.current_highlight_style): style += f'{k}: {s[k]}; ' self.send_message( - 'apply-highlight', style=style, uuid=short_uuid() + 'apply-highlight', style=style, uuid=short_uuid(), existing=self.editing_annot_uuid ) self.hide() @@ -428,6 +429,7 @@ class CreateAnnotation: def handle_message(self, msg): if msg.type is 'create-annotation': + self.editing_annot_uuid = None if not self.is_visible: self.view.hide_overlays() self.state = WAITING_FOR_CLICK @@ -440,6 +442,7 @@ class CreateAnnotation: elif msg.type is 'position-handles': if self.state is WAITING_FOR_CLICK: self.place_handles(msg.extents) + self.editing_annot_uuid = msg.existing or None elif msg.type is 'update-handles': self.place_handles(msg.extents) if msg.from_scroll and not msg.selection_extended: diff --git a/src/pyj/read_book/iframe.pyj b/src/pyj/read_book/iframe.pyj index 45ceebc3ed..997665664f 100644 --- a/src/pyj/read_book/iframe.pyj +++ b/src/pyj/read_book/iframe.pyj @@ -11,7 +11,10 @@ from select import ( from fs_images import fix_fullscreen_svg_images from iframe_comm import IframeClient -from range_utils import reset_highlight_counter, unwrap_crw, wrap_text_in_range +from range_utils import ( + reset_highlight_counter, set_selection_to_highlight, unwrap_crw, + wrap_text_in_range +) from read_book.cfi import ( cfi_for_selection, range_from_cfi, scroll_to as scroll_to_cfi ) @@ -635,10 +638,12 @@ class IframeBoss: if data.type is 'set-selection': set_selections_extents_to(data.extents) elif data.type is 'position-handles-at-point': + extents = selection_extents_at_point(data.x, data.y, in_flow_mode) + annot_id = set_selection_to_highlight() + if annot_id: + extents = selection_extents(in_flow_mode) self.send_message( - 'annotations', - type='position-handles', - extents=selection_extents_at_point(data.x, data.y, in_flow_mode)) + 'annotations', type='position-handles', extents=extents, existing=self.annot_id_uuid_map[annot_id]) elif data.type is 'scroll': if self.scroll_to_extend_annotation(data.backwards): page_rect = {'width': current_page_width()} @@ -667,6 +672,9 @@ class IframeBoss: unwrap_crw(crw) removed_highlights[self.annot_id_uuid_map[crw]] = True v'delete self.annot_id_uuid_map[crw]' + if data.existing and removed_highlights[data.existing]: + data.uuid = data.existing + v'delete removed_highlights[data.existing]' removed_highlights = Object.keys(removed_highlights) if removed_highlights.length is 1: data.uuid = removed_highlights[0]