mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Remove overlapping highlights when applying a new one
This commit is contained in:
parent
5af73fee86
commit
37a60e366a
@ -60,6 +60,11 @@ def unwrap(node):
|
|||||||
p.normalize()
|
p.normalize()
|
||||||
|
|
||||||
|
|
||||||
|
def unwrap_crw(crw):
|
||||||
|
for node in document.querySelectorAll(f'span[data-calibre-range-wrapper="{crw}"]'):
|
||||||
|
unwrap(node)
|
||||||
|
|
||||||
|
|
||||||
def create_wrapper_function(wrapper_elem, r):
|
def create_wrapper_function(wrapper_elem, r):
|
||||||
start_node = r.startContainer
|
start_node = r.startContainer
|
||||||
end_node = r.endContainer
|
end_node = r.endContainer
|
||||||
@ -109,3 +114,33 @@ def wrap_text_in_range(style, r):
|
|||||||
def reset_highlight_counter():
|
def reset_highlight_counter():
|
||||||
nonlocal wrapper_counter
|
nonlocal wrapper_counter
|
||||||
wrapper_counter = 0
|
wrapper_counter = 0
|
||||||
|
|
||||||
|
|
||||||
|
def is_text_node(node):
|
||||||
|
return node.nodeType is Node.TEXT_NODE or node.nodeType is Node.CDATA_SECTION_NODE
|
||||||
|
|
||||||
|
|
||||||
|
def range_wrappers_intersecting_selection(sel):
|
||||||
|
ans = {}
|
||||||
|
sel = sel or window.getSelection()
|
||||||
|
if not sel:
|
||||||
|
return ans
|
||||||
|
r = sel.getRangeAt(0)
|
||||||
|
if not r:
|
||||||
|
return ans
|
||||||
|
walker = document.createTreeWalker(r.commonAncestorContainer, NodeFilter.SHOW_ALL, None, False)
|
||||||
|
in_selection = False
|
||||||
|
while True:
|
||||||
|
node = walker.nextNode()
|
||||||
|
if not node:
|
||||||
|
break
|
||||||
|
if not in_selection and node is not r.startContainer:
|
||||||
|
continue
|
||||||
|
in_selection = True
|
||||||
|
if node.nodeType is Node.ELEMENT_NODE and node.dataset.calibreRangeWrapper:
|
||||||
|
ans[node.dataset.calibreRangeWrapper] = True
|
||||||
|
elif is_text_node(node) and node.parentNode.dataset.calibreRangeWrapper:
|
||||||
|
ans[node.parentNode.dataset.calibreRangeWrapper] = True
|
||||||
|
if node is r.endContainer:
|
||||||
|
break
|
||||||
|
return Object.keys(ans)
|
||||||
|
@ -11,7 +11,10 @@ from select import (
|
|||||||
|
|
||||||
from fs_images import fix_fullscreen_svg_images
|
from fs_images import fix_fullscreen_svg_images
|
||||||
from iframe_comm import IframeClient
|
from iframe_comm import IframeClient
|
||||||
from range_utils import reset_highlight_counter, wrap_text_in_range
|
from range_utils import (
|
||||||
|
range_wrappers_intersecting_selection, reset_highlight_counter, unwrap_crw,
|
||||||
|
wrap_text_in_range
|
||||||
|
)
|
||||||
from read_book.cfi import cfi_for_selection, scroll_to as scroll_to_cfi
|
from read_book.cfi import cfi_for_selection, scroll_to as scroll_to_cfi
|
||||||
from read_book.extract import get_elements
|
from read_book.extract import get_elements
|
||||||
from read_book.find import reset_find_caches, select_search_result
|
from read_book.find import reset_find_caches, select_search_result
|
||||||
@ -646,12 +649,28 @@ class IframeBoss:
|
|||||||
elif data.type is 'set-highlight-style':
|
elif data.type is 'set-highlight-style':
|
||||||
set_selection_style(data.style)
|
set_selection_style(data.style)
|
||||||
elif data.type is 'apply-highlight':
|
elif data.type is 'apply-highlight':
|
||||||
|
sel = window.getSelection()
|
||||||
|
text = ''
|
||||||
|
if sel:
|
||||||
|
text = sel.toString()
|
||||||
bounds = cfi_for_selection()
|
bounds = cfi_for_selection()
|
||||||
|
intersecting_wrappers = range_wrappers_intersecting_selection()
|
||||||
annot_id = wrap_text_in_range(data.style)
|
annot_id = wrap_text_in_range(data.style)
|
||||||
|
removed_highlights = {}
|
||||||
if annot_id is not None:
|
if annot_id is not None:
|
||||||
window.getSelection().removeAllRanges()
|
sel.removeAllRanges()
|
||||||
self.annot_id_uuid_map[annot_id] = data.uuid
|
self.annot_id_uuid_map[annot_id] = data.uuid
|
||||||
self.send_message('annotations', type='highlight-applied', uuid=data.uuid, ok=annot_id is not None, bounds=bounds)
|
for crw in intersecting_wrappers:
|
||||||
|
unwrap_crw(crw)
|
||||||
|
removed_highlights[self.annot_id_uuid_map[crw]] = True
|
||||||
|
self.send_message(
|
||||||
|
'annotations',
|
||||||
|
type='highlight-applied',
|
||||||
|
uuid=data.uuid, ok=annot_id is not None,
|
||||||
|
bounds=bounds,
|
||||||
|
removed_highlights=Object.keys(removed_highlights),
|
||||||
|
highlighted_text=text,
|
||||||
|
)
|
||||||
reset_find_caches()
|
reset_find_caches()
|
||||||
else:
|
else:
|
||||||
console.log('Ignoring annotations message to iframe with unknown type: ' + data.type)
|
console.log('Ignoring annotations message to iframe with unknown type: ' + data.type)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user