mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
More accurate detection of current ToC section when highlighting
This commit is contained in:
parent
28ef780d99
commit
c363d790ab
@ -57,7 +57,7 @@ from read_book.settings import (
|
|||||||
from read_book.shortcuts import (
|
from read_book.shortcuts import (
|
||||||
create_shortcut_map, keyevent_as_shortcut, shortcut_for_key_event
|
create_shortcut_map, keyevent_as_shortcut, shortcut_for_key_event
|
||||||
)
|
)
|
||||||
from read_book.toc import update_visible_toc_anchors
|
from read_book.toc import update_visible_toc_anchors, find_anchor_before_range
|
||||||
from read_book.touch import (
|
from read_book.touch import (
|
||||||
create_handlers as create_touch_handlers, reset_handlers as reset_touch_handlers
|
create_handlers as create_touch_handlers, reset_handlers as reset_touch_handlers
|
||||||
)
|
)
|
||||||
@ -793,9 +793,10 @@ class IframeBoss:
|
|||||||
sel.removeAllRanges()
|
sel.removeAllRanges()
|
||||||
elif dtype is 'apply-highlight':
|
elif dtype is 'apply-highlight':
|
||||||
sel = window.getSelection()
|
sel = window.getSelection()
|
||||||
text = sel.toString()
|
|
||||||
if not sel.rangeCount:
|
if not sel.rangeCount:
|
||||||
return
|
return
|
||||||
|
anchor_before = find_anchor_before_range(sel.getRangeAt(0), self.book.manifest.toc_anchor_map, self.anchor_funcs)
|
||||||
|
text = sel.toString()
|
||||||
bounds = cfi_for_selection()
|
bounds = cfi_for_selection()
|
||||||
style = highlight_style_as_css(data.style, opts.is_dark_theme, opts.color_scheme.foreground)
|
style = highlight_style_as_css(data.style, opts.is_dark_theme, opts.color_scheme.foreground)
|
||||||
cls = 'crw-has-dot' if data.has_notes else None
|
cls = 'crw-has-dot' if data.has_notes else None
|
||||||
@ -824,6 +825,7 @@ class IframeBoss:
|
|||||||
bounds=bounds,
|
bounds=bounds,
|
||||||
removed_highlights=removed_highlights,
|
removed_highlights=removed_highlights,
|
||||||
highlighted_text=text,
|
highlighted_text=text,
|
||||||
|
anchor_before=anchor_before
|
||||||
)
|
)
|
||||||
reset_find_caches()
|
reset_find_caches()
|
||||||
else:
|
else:
|
||||||
|
@ -15,6 +15,7 @@ from read_book.highlights import (
|
|||||||
ICON_SIZE, EditNotesAndColors, HighlightStyle, all_styles, render_notes
|
ICON_SIZE, EditNotesAndColors, HighlightStyle, all_styles, render_notes
|
||||||
)
|
)
|
||||||
from read_book.shortcuts import shortcut_for_key_event
|
from read_book.shortcuts import shortcut_for_key_event
|
||||||
|
from read_book.toc import get_toc_nodes_bordering_spine_item, family_for_toc_node
|
||||||
|
|
||||||
DRAG_SCROLL_ZONE_MIN_HEIGHT = 10
|
DRAG_SCROLL_ZONE_MIN_HEIGHT = 10
|
||||||
BUTTON_MARGIN = '0.5rem'
|
BUTTON_MARGIN = '0.5rem'
|
||||||
@ -965,8 +966,15 @@ class SelectionBar:
|
|||||||
_('Highlighting failed'),
|
_('Highlighting failed'),
|
||||||
_('Failed to apply highlighting, try adjusting extent of highlight')
|
_('Failed to apply highlighting, try adjusting extent of highlight')
|
||||||
)
|
)
|
||||||
|
toc_family = v'[]'
|
||||||
|
if msg.anchor_before:
|
||||||
|
toc_family = family_for_toc_node(msg.anchor_before.id)
|
||||||
|
else:
|
||||||
|
before = get_toc_nodes_bordering_spine_item()[0]
|
||||||
|
if before:
|
||||||
|
toc_family = family_for_toc_node(before.id)
|
||||||
self.annotations_manager.add_highlight(
|
self.annotations_manager.add_highlight(
|
||||||
msg, self.current_highlight_style.style, notes, self.view.current_toc_family)
|
msg, self.current_highlight_style.style, notes, toc_family)
|
||||||
elif msg.type is 'edit-highlight':
|
elif msg.type is 'edit-highlight':
|
||||||
if self.state is WAITING:
|
if self.state is WAITING:
|
||||||
self.create_highlight()
|
self.create_highlight()
|
||||||
|
@ -24,28 +24,20 @@ def iter_toc_descendants(node, callback):
|
|||||||
iter_toc_descendants(child, callback)
|
iter_toc_descendants(child, callback)
|
||||||
|
|
||||||
|
|
||||||
def get_border_nodes(toc, id_map):
|
def get_toc_nodes_bordering_spine_item(toc, csi):
|
||||||
data = update_visible_toc_nodes.data
|
|
||||||
before, after = data.before, data.after
|
|
||||||
if before:
|
|
||||||
before = id_map[before]
|
|
||||||
if after:
|
|
||||||
after = id_map[after]
|
|
||||||
if before and after:
|
|
||||||
# Both border nodes are in the current spine item
|
|
||||||
return before, after
|
|
||||||
# Find the ToC entries that point to the closest files on either side of the
|
# Find the ToC entries that point to the closest files on either side of the
|
||||||
# current spine item
|
# spine item
|
||||||
|
toc = toc or current_book().manifest.toc
|
||||||
|
csi = csi or current_spine_item()
|
||||||
spine = current_book().manifest.spine
|
spine = current_book().manifest.spine
|
||||||
spine_before, spine_after = {}, {}
|
spine_before, spine_after = {}, {}
|
||||||
which = spine_before
|
which = spine_before
|
||||||
csi = current_spine_item()
|
before = after = prev = None
|
||||||
for name in spine:
|
for name in spine:
|
||||||
if name is csi:
|
if name is csi:
|
||||||
which = spine_after
|
which = spine_after
|
||||||
else:
|
else:
|
||||||
which[name] = True
|
which[name] = True
|
||||||
prev = None
|
|
||||||
iter_toc_descendants(toc, def(node):
|
iter_toc_descendants(toc, def(node):
|
||||||
nonlocal prev, before, after
|
nonlocal prev, before, after
|
||||||
if node.dest:
|
if node.dest:
|
||||||
@ -63,6 +55,37 @@ def get_border_nodes(toc, id_map):
|
|||||||
return before, after
|
return before, after
|
||||||
|
|
||||||
|
|
||||||
|
def get_border_nodes(toc, id_map):
|
||||||
|
data = update_visible_toc_nodes.data
|
||||||
|
before, after = data.before, data.after
|
||||||
|
if before:
|
||||||
|
before = id_map[before]
|
||||||
|
if after:
|
||||||
|
after = id_map[after]
|
||||||
|
if before and after:
|
||||||
|
# Both border nodes are in the current spine item
|
||||||
|
return before, after
|
||||||
|
sb, sa = get_toc_nodes_bordering_spine_item(toc)
|
||||||
|
before = before or sb
|
||||||
|
after = after or sa
|
||||||
|
return before, after
|
||||||
|
|
||||||
|
|
||||||
|
def family_for_toc_node(toc_node_id, parent_map, id_map):
|
||||||
|
if not id_map or not parent_map:
|
||||||
|
toc = current_book().manifest.toc
|
||||||
|
parent_map, id_map = get_toc_maps(toc)
|
||||||
|
family = v'[]'
|
||||||
|
node = id_map[toc_node_id]
|
||||||
|
while node and node.title:
|
||||||
|
family.unshift(node)
|
||||||
|
parent = parent_map[node.id]
|
||||||
|
node = None
|
||||||
|
if parent:
|
||||||
|
node = id_map[parent.id]
|
||||||
|
return family
|
||||||
|
|
||||||
|
|
||||||
def get_current_toc_nodes():
|
def get_current_toc_nodes():
|
||||||
toc = current_book().manifest.toc
|
toc = current_book().manifest.toc
|
||||||
parent_map, id_map = get_toc_maps(toc)
|
parent_map, id_map = get_toc_maps(toc)
|
||||||
@ -78,16 +101,9 @@ def get_current_toc_nodes():
|
|||||||
if before:
|
if before:
|
||||||
ans[before.id] = True
|
ans[before.id] = True
|
||||||
ans = Object.keys(ans)
|
ans = Object.keys(ans)
|
||||||
family = v'[]'
|
|
||||||
if ans.length:
|
if ans.length:
|
||||||
node = id_map[ans[0]]
|
return family_for_toc_node(ans[0], parent_map, id_map)
|
||||||
while node and node.title:
|
return v'[]'
|
||||||
family.unshift(node)
|
|
||||||
parent = parent_map[node.id]
|
|
||||||
node = None
|
|
||||||
if parent:
|
|
||||||
node = id_map[parent.id]
|
|
||||||
return family
|
|
||||||
|
|
||||||
|
|
||||||
def get_highlighted_toc_nodes(toc, parent_map, id_map):
|
def get_highlighted_toc_nodes(toc, parent_map, id_map):
|
||||||
@ -207,3 +223,27 @@ def update_visible_toc_anchors(toc_anchor_map, anchor_funcs):
|
|||||||
break
|
break
|
||||||
|
|
||||||
return {'visible_anchors':visible_anchors, 'has_visible':has_visible, 'before':before, 'after':after, 'sorted_anchors':tam.sorted_anchors}
|
return {'visible_anchors':visible_anchors, 'has_visible':has_visible, 'before':before, 'after':after, 'sorted_anchors':tam.sorted_anchors}
|
||||||
|
|
||||||
|
|
||||||
|
def find_anchor_before_range(r, toc_anchor_map, anchor_funcs):
|
||||||
|
name = current_spine_item().name
|
||||||
|
prev_anchor = None
|
||||||
|
tam = current_toc_anchor_map(toc_anchor_map, anchor_funcs)
|
||||||
|
anchors = toc_anchor_map[name]
|
||||||
|
if anchors:
|
||||||
|
amap = {x.id: x for x in anchors}
|
||||||
|
for anchor_id in tam.sorted_anchors:
|
||||||
|
anchor = amap[anchor_id]
|
||||||
|
is_before = True
|
||||||
|
if anchor.frag:
|
||||||
|
elem = document.getElementById(anchor.frag)
|
||||||
|
if elem:
|
||||||
|
q = document.createRange()
|
||||||
|
q.selectNode(elem)
|
||||||
|
if q.compareBoundaryPoints(window.Range.START_TO_START, r) > 0:
|
||||||
|
is_before = False
|
||||||
|
if is_before:
|
||||||
|
prev_anchor = anchor
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
return prev_anchor
|
||||||
|
Loading…
x
Reference in New Issue
Block a user