mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-07 18:24:30 -04:00
E-book viewer: Fix searching for text next to hidden text not scrolling to the match
This commit is contained in:
parent
5e2dd561b6
commit
e0dee4fdef
@ -8,7 +8,25 @@ def is_non_empty_text_node(node):
|
||||
return (node.nodeType is Node.TEXT_NODE or node.nodeType is Node.CDATA_SECTION_NODE) and node.nodeValue.length > 0
|
||||
|
||||
|
||||
def text_nodes_in_range(r):
|
||||
def is_element_visible(elem):
|
||||
s = window.getComputedStyle(elem)
|
||||
return s.display is not 'none' and s.visibility is not 'hidden'
|
||||
|
||||
|
||||
def is_node_visible(node):
|
||||
if node.nodeType is not Node.ELEMENT_NODE:
|
||||
node = node.parentElement
|
||||
if not node:
|
||||
return False
|
||||
current = node
|
||||
while current:
|
||||
if not is_element_visible(current):
|
||||
return False
|
||||
current = current.parentElement
|
||||
return True
|
||||
|
||||
|
||||
def select_nodes_from_range(r, predicate):
|
||||
parent = r.commonAncestorContainer
|
||||
doc = parent.ownerDocument or document
|
||||
iterator = doc.createNodeIterator(parent)
|
||||
@ -21,13 +39,35 @@ def text_nodes_in_range(r):
|
||||
if not in_range and node.isSameNode(r.startContainer):
|
||||
in_range = True
|
||||
if in_range:
|
||||
if is_non_empty_text_node(node):
|
||||
if predicate(node):
|
||||
ans.push(node)
|
||||
if node.isSameNode(r.endContainer):
|
||||
break
|
||||
return ans
|
||||
|
||||
|
||||
def select_first_node_from_range(r, predicate):
|
||||
parent = r.commonAncestorContainer
|
||||
doc = parent.ownerDocument or document
|
||||
iterator = doc.createNodeIterator(parent)
|
||||
in_range = False
|
||||
while True:
|
||||
node = iterator.nextNode()
|
||||
if not node:
|
||||
break
|
||||
if not in_range and node.isSameNode(r.startContainer):
|
||||
in_range = True
|
||||
if in_range:
|
||||
if predicate(node):
|
||||
return node
|
||||
if node.isSameNode(r.endContainer):
|
||||
break
|
||||
|
||||
|
||||
def text_nodes_in_range(r):
|
||||
return select_nodes_from_range(r, is_non_empty_text_node)
|
||||
|
||||
|
||||
def all_annots_in_range(r, annot_id_uuid_map, ans):
|
||||
parent = r.commonAncestorContainer
|
||||
doc = parent.ownerDocument or document
|
||||
|
@ -2,6 +2,7 @@
|
||||
# License: GPL v3 Copyright: 2020, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
from __python__ import bound_methods, hash_literals
|
||||
|
||||
from range_utils import select_first_node_from_range, is_node_visible
|
||||
|
||||
def build_text_map():
|
||||
node_list = v'[]'
|
||||
@ -27,9 +28,6 @@ def build_text_map():
|
||||
tag = node.tagName.toLowerCase()
|
||||
if ignored_tags[tag]:
|
||||
return
|
||||
style = window.getComputedStyle(node)
|
||||
if style.display is 'none' or style.visibility is 'hidden':
|
||||
return
|
||||
children = node.childNodes
|
||||
for i in range(children.length):
|
||||
process_node(v'children[i]')
|
||||
@ -143,7 +141,12 @@ def select_find_result(match):
|
||||
sel.setBaseAndExtent(match.start_node, match.start_offset, match.end_node, match.end_offset)
|
||||
except: # if offset is outside node
|
||||
return False
|
||||
return True
|
||||
if not sel.rangeCount:
|
||||
return False
|
||||
for i in range(sel.rangeCount):
|
||||
if select_first_node_from_range(sel.getRangeAt(i), is_node_visible):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def select_search_result(sr):
|
||||
|
Loading…
x
Reference in New Issue
Block a user