Fix incorrect CFI when selecting text in a range wrapper that is the first child

This commit is contained in:
Kovid Goyal 2020-07-20 14:44:49 +05:30
parent d5521f96a6
commit ad490e9cd6
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 19 additions and 5 deletions

View File

@ -150,6 +150,7 @@ def text_length_in_range_wrapper(node):
def adjust_node_for_text_offset(node):
offset = 0
adjusted = False
while True:
p = node.previousSibling
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:
offset += text_length_in_range_wrapper(p)
node = p
return node, offset
adjusted = True
return node, offset, adjusted
def unwrapped_nodes(range_wrapper):
@ -219,10 +221,13 @@ def encode(doc, node, offset, tail):
node = node.firstChild
if is_text_node(node):
offset = offset or 0
adjust_node = node
if node.parentNode and node.parentNode.dataset.calibreRangeWrapper:
node = node.parentNode
node, additional_offset = adjust_node_for_text_offset(node)
offset += additional_offset
adjust_node = node.parentNode
adjusted_node, additional_offset, adjusted = adjust_node_for_text_offset(adjust_node)
if adjusted:
node = adjusted_node
offset += additional_offset
cfi = ":" + offset + cfi
elif node.nodeType is not Node.ELEMENT_NODE: # 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
# }}}
# def decode(cfi, doc): {{{
def node_at_index(nodes, target, index, iter_text_nodes):

View File

@ -85,3 +85,13 @@ def cfi_with_range_wrappers():
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}/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)