Make extending the selection on scroll more robust

This commit is contained in:
Kovid Goyal 2020-04-08 20:16:52 +05:30
parent 73a08a9e15
commit 33fed39269
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
4 changed files with 62 additions and 29 deletions

View File

@ -378,6 +378,15 @@ class CreateAnnotation:
self.place_handles(msg.extents)
elif msg.type is 'update-handles':
self.place_handles(msg.extents)
if msg.from_scroll and not msg.selection_extended:
middle = map_from_iframe_coords({
'x': msg.page_rect.left + msg.page_rect.width // 2,
'y': msg.page_rect.top + msg.page_rect.height // 2
})
handle = self.left_handle if msg.backwards else self.right_handle
handle.style.display = 'block'
handle.style.left = f'{middle.x}px'
handle.style.top = f'{middle.y}px'
elif msg.type is 'highlight-applied':
if not msg.ok:
return error_dialog(

View File

@ -31,11 +31,11 @@ from read_book.mathjax import apply_mathjax
from read_book.paged_mode import (
anchor_funcs as paged_anchor_funcs,
auto_scroll_action as paged_auto_scroll_action, calc_columns_per_screen,
current_cfi, get_columns_per_screen_data, handle_gesture as paged_handle_gesture,
handle_shortcut as paged_handle_shortcut, jump_to_cfi as paged_jump_to_cfi,
layout as paged_layout, onwheel as paged_onwheel,
prepare_for_resize as paged_prepare_for_resize, progress_frac,
reset_paged_mode_globals, resize_done as paged_resize_done,
current_cfi, current_page_width, get_columns_per_screen_data,
handle_gesture as paged_handle_gesture, handle_shortcut as paged_handle_shortcut,
jump_to_cfi as paged_jump_to_cfi, layout as paged_layout,
onwheel as paged_onwheel, prepare_for_resize as paged_prepare_for_resize,
progress_frac, reset_paged_mode_globals, resize_done as paged_resize_done,
scroll_by_page as paged_scroll_by_page, scroll_to_elem,
scroll_to_extend_annotation as paged_annotation_scroll,
scroll_to_fraction as paged_scroll_to_fraction, snap_to_selection,
@ -634,8 +634,12 @@ class IframeBoss:
extents=selection_extents_at_point(data.x, data.y, in_flow_mode))
elif data.type is 'scroll':
if self.scroll_to_extend_annotation(data.backwards):
extend_selection_after_scroll(data.backwards, in_flow_mode)
self.send_message('annotations', type='update-handles', extents=selection_extents(in_flow_mode))
page_rect = {'width': current_page_width()}
extended = extend_selection_after_scroll(data.backwards, in_flow_mode, page_rect)
self.send_message(
'annotations', type='update-handles', extents=selection_extents(in_flow_mode),
backwards=data.backwards, from_scroll=True, selection_extended=extended, page_rect=page_rect
)
elif data.type is 'perp-scroll':
if in_flow_mode and flow_annotation_scroll(data.backwards, True):
self.send_message('annotations', type='update-handles', extents=selection_extents(in_flow_mode))

View File

@ -164,6 +164,10 @@ def will_columns_per_screen_change():
return calc_columns_per_screen() != cols_per_screen
def current_page_width():
return col_width
def layout(is_single_page, on_resize):
nonlocal _in_paged_mode, col_width, col_and_gap, screen_height, gap, screen_width, is_full_screen_layout, cols_per_screen, number_of_cols
body_style = window.getComputedStyle(document.body)

View File

@ -98,37 +98,53 @@ def selection_extents_at_point(x, y, in_flow_mode):
return ans
def extend_selection_after_scroll(backwards, in_flow_mode):
def extend_selection_after_scroll(backwards, in_flow_mode, page_rect):
page_rect.top = page_rect.left = 0
page_rect.bottom = window.innerHeight
page_rect.right = page_rect.width
if not in_flow_mode and not backwards:
page_rect.right = window.innerWidth
page_rect.left = window.innerWidth - page_rect.width
page_rect.width = page_rect.right - page_rect.left
page_rect.height = page_rect.bottom - page_rect.top
sel = window.getSelection()
if not sel.rangeCount:
return
return False
if in_flow_mode:
page_rect.width = window.innerWidth
r = sel.getRangeAt(0)
q = r.cloneRange()
q.collapse(backwards)
rects = r.getClientRects()
rects = q.getClientRects()
if not rects.length:
return
return False
rect = rects[0]
in_page_already = rect.left >= page_rect.left and rect.top >= page_rect.top and rect.bottom <= page_rect.bottom and rect.right <= page_rect.right
if in_page_already:
return True
dx = page_rect.width // 10
dy = page_rect.height // 10
middle_x = page_rect.left + page_rect.width // 2
for yi in range(1, 10):
if backwards:
if in_flow_mode and rect.bottom <= window.innerHeight:
return
if not in_flow_mode and rect.right <= window.innerWidth:
return
y = page_rect.bottom - dy * yi
else:
if in_flow_mode and rect.top >= 0:
return
if not in_flow_mode and rect.left >= 0:
return
x = window.innerWidth // 2
y = window.innerHeight // 3
if backwards:
y *= 2
y = page_rect.top + dy * yi
for xi in range(4):
xvals = v'[-1, 1]' if xi else v'[1]'
for xw in xvals:
x = middle_x + xw * dx
p = range_from_point(x, y)
if p:
if backwards:
r.setStart(p.startContainer, p.startOffset)
else:
r.setEnd(p.startContainer, p.startOffset)
return True
# could not find any content on page
return False
def set_selections_extents_to(extents):