From ff06cbbae50b0cec6da9fb1ec9e6473eacd1aef8 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 26 Oct 2020 09:09:42 +0530 Subject: [PATCH] Viewer: Fix jumping to search result not always working in flow mode. Fixes #1900868 [Private bug](https://bugs.launchpad.net/calibre/+bug/1900868) --- src/pyj/read_book/flow_mode.pyj | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/pyj/read_book/flow_mode.pyj b/src/pyj/read_book/flow_mode.pyj index 45642e5357..a898f2888b 100644 --- a/src/pyj/read_book/flow_mode.pyj +++ b/src/pyj/read_book/flow_mode.pyj @@ -21,6 +21,7 @@ from __python__ import bound_methods, hash_literals # things scroll in the positive block direction. from dom import set_css +from range_utils import wrap_range, unwrap from read_book.cfi import scroll_to as cfi_scroll_to from read_book.globals import current_spine_item, get_boss, rtl_page_progression, ltr_page_progression from read_book.settings import opts @@ -598,16 +599,32 @@ def auto_scroll_action(action): return is_auto_scroll_active() +def closest_preceding_element(p): + while p and not p.scrollIntoView: + p = p.previousSibling or p.parentNode + return p + + def ensure_selection_visible(): s = window.getSelection() - if not s.anchorNode: - return p = s.anchorNode - while p: - if p.scrollIntoView: - p.scrollIntoView() - return - p = p.parentNode + if not p: + return + p = closest_preceding_element(p) + if p?.scrollIntoView: + p.scrollIntoView() + r = s.getRangeAt(0) + if not r: + return + rect = r.getBoundingClientRect() + if not rect: + return + if rect.top < 0 or rect.top >= window.innerHeight or rect.left < 0 or rect.left >= window.innerWidth: + wrapper = document.createElement('span') + wrap_range(r, wrapper) + wrapper.scrollIntoView() + unwrap(wrapper) + def jump_to_cfi(cfi): # Jump to the position indicated by the specified conformal fragment