diff --git a/src/pyj/range_utils.pyj b/src/pyj/range_utils.pyj index 1f6c697fd6..51d0d7782d 100644 --- a/src/pyj/range_utils.pyj +++ b/src/pyj/range_utils.pyj @@ -151,6 +151,13 @@ def create_wrapper_function(wrapper_elem, r, intersecting_wrappers, process_wrap current_range.setEnd(node, end_offset) end_node = current_wrapper end_offset = 1 + if current_range.collapsed: + # Dont wrap empty ranges. This is needed otherwise two adjacent + # selections of text will incorrectly be detected as overlapping. + # For example: highlight abc then def in the word abcdef here the + # second highlight's first range is the collapsed range at the end + # of abc + return crw = node.parentNode?.dataset?.calibreRangeWrapper if crw: intersecting_wrappers[crw] = True @@ -158,7 +165,6 @@ def create_wrapper_function(wrapper_elem, r, intersecting_wrappers, process_wrap if process_wrapper: process_wrapper(current_wrapper) all_wrappers.push(current_wrapper) - return current_wrapper return wrap_node @@ -184,10 +190,13 @@ def wrap_text_in_range(styler, r, class_to_add_to_last, process_wrapper): all_wrappers = v'[]' wrap_node = create_wrapper_function(wrapper_elem, r, intersecting_wrappers, process_wrapper, all_wrappers) text_nodes_in_range(r).map(wrap_node) + ancestor = r.commonAncestorContainer + if ancestor.nodeType is Node.TEXT_NODE: + ancestor = ancestor.parentNode # remove any empty text nodes created by surroundContents() on either # side of the wrapper. This happens for instance on Chrome when # wrapping all text inside some text - r.commonAncestorContainer.normalize() + ancestor.normalize() crw = wrapper_elem.dataset.calibreRangeWrapper v'delete intersecting_wrappers[crw]' if class_to_add_to_last and all_wrappers.length: