mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Fix incorrect CFI when selecting text in a range wrapper that is the first child
This commit is contained in:
parent
d5521f96a6
commit
ad490e9cd6
@ -150,6 +150,7 @@ def text_length_in_range_wrapper(node):
|
|||||||
|
|
||||||
def adjust_node_for_text_offset(node):
|
def adjust_node_for_text_offset(node):
|
||||||
offset = 0
|
offset = 0
|
||||||
|
adjusted = False
|
||||||
while True:
|
while True:
|
||||||
p = node.previousSibling
|
p = node.previousSibling
|
||||||
if not p or p.nodeType > Node.COMMENT_NODE:
|
if not p or p.nodeType > Node.COMMENT_NODE:
|
||||||
@ -159,7 +160,8 @@ def adjust_node_for_text_offset(node):
|
|||||||
elif p.nodeType is Node.ELEMENT_NODE and p.dataset.calibreRangeWrapper:
|
elif p.nodeType is Node.ELEMENT_NODE and p.dataset.calibreRangeWrapper:
|
||||||
offset += text_length_in_range_wrapper(p)
|
offset += text_length_in_range_wrapper(p)
|
||||||
node = p
|
node = p
|
||||||
return node, offset
|
adjusted = True
|
||||||
|
return node, offset, adjusted
|
||||||
|
|
||||||
|
|
||||||
def unwrapped_nodes(range_wrapper):
|
def unwrapped_nodes(range_wrapper):
|
||||||
@ -219,10 +221,13 @@ def encode(doc, node, offset, tail):
|
|||||||
node = node.firstChild
|
node = node.firstChild
|
||||||
if is_text_node(node):
|
if is_text_node(node):
|
||||||
offset = offset or 0
|
offset = offset or 0
|
||||||
|
adjust_node = node
|
||||||
if node.parentNode and node.parentNode.dataset.calibreRangeWrapper:
|
if node.parentNode and node.parentNode.dataset.calibreRangeWrapper:
|
||||||
node = node.parentNode
|
adjust_node = node.parentNode
|
||||||
node, additional_offset = adjust_node_for_text_offset(node)
|
adjusted_node, additional_offset, adjusted = adjust_node_for_text_offset(adjust_node)
|
||||||
offset += additional_offset
|
if adjusted:
|
||||||
|
node = adjusted_node
|
||||||
|
offset += additional_offset
|
||||||
cfi = ":" + offset + cfi
|
cfi = ":" + offset + cfi
|
||||||
elif node.nodeType is not Node.ELEMENT_NODE: # Not handled
|
elif node.nodeType is not Node.ELEMENT_NODE: # Not handled
|
||||||
print(f"Offsets for nodes of type {node.nodeType} are not handled")
|
print(f"Offsets for nodes of type {node.nodeType} are not handled")
|
||||||
@ -255,7 +260,6 @@ def encode(doc, node, offset, tail):
|
|||||||
return cfi
|
return cfi
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
|
||||||
# def decode(cfi, doc): {{{
|
# def decode(cfi, doc): {{{
|
||||||
|
|
||||||
def node_at_index(nodes, target, index, iter_text_nodes):
|
def node_at_index(nodes, target, index, iter_text_nodes):
|
||||||
|
@ -85,3 +85,13 @@ def cfi_with_range_wrappers():
|
|||||||
p.appendChild(document.createTextNode('def'))
|
p.appendChild(document.createTextNode('def'))
|
||||||
assert_equal(decode(f'{path_to_p}/1:2'), {'node': p.firstChild, 'offset': 2})
|
assert_equal(decode(f'{path_to_p}/1:2'), {'node': p.firstChild, 'offset': 2})
|
||||||
assert_equal(decode(f'{path_to_p}/3:2'), {'node': p.lastChild, 'offset': 2})
|
assert_equal(decode(f'{path_to_p}/3:2'), {'node': p.lastChild, 'offset': 2})
|
||||||
|
|
||||||
|
document.body.appendChild(E.p('abc'))
|
||||||
|
p = document.body.lastChild
|
||||||
|
path_to_p = encode(document, p)
|
||||||
|
without_wrapper = encode(document, p.firstChild, 0)
|
||||||
|
assert_equal(without_wrapper, f'{path_to_p}/1:0')
|
||||||
|
p.removeChild(p.firstChild)
|
||||||
|
p.appendChild(E.span('abc', data_calibre_range_wrapper='7'))
|
||||||
|
with_wrapper = encode(document, p.firstChild.firstChild, 0)
|
||||||
|
assert_equal(without_wrapper, with_wrapper)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user