mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 02:34:06 -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
|
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
|
parent = r.commonAncestorContainer
|
||||||
doc = parent.ownerDocument or document
|
doc = parent.ownerDocument or document
|
||||||
iterator = doc.createNodeIterator(parent)
|
iterator = doc.createNodeIterator(parent)
|
||||||
@ -21,13 +39,35 @@ def text_nodes_in_range(r):
|
|||||||
if not in_range and node.isSameNode(r.startContainer):
|
if not in_range and node.isSameNode(r.startContainer):
|
||||||
in_range = True
|
in_range = True
|
||||||
if in_range:
|
if in_range:
|
||||||
if is_non_empty_text_node(node):
|
if predicate(node):
|
||||||
ans.push(node)
|
ans.push(node)
|
||||||
if node.isSameNode(r.endContainer):
|
if node.isSameNode(r.endContainer):
|
||||||
break
|
break
|
||||||
return ans
|
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):
|
def all_annots_in_range(r, annot_id_uuid_map, ans):
|
||||||
parent = r.commonAncestorContainer
|
parent = r.commonAncestorContainer
|
||||||
doc = parent.ownerDocument or document
|
doc = parent.ownerDocument or document
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
# License: GPL v3 Copyright: 2020, Kovid Goyal <kovid at kovidgoyal.net>
|
# License: GPL v3 Copyright: 2020, Kovid Goyal <kovid at kovidgoyal.net>
|
||||||
from __python__ import bound_methods, hash_literals
|
from __python__ import bound_methods, hash_literals
|
||||||
|
|
||||||
|
from range_utils import select_first_node_from_range, is_node_visible
|
||||||
|
|
||||||
def build_text_map():
|
def build_text_map():
|
||||||
node_list = v'[]'
|
node_list = v'[]'
|
||||||
@ -27,9 +28,6 @@ def build_text_map():
|
|||||||
tag = node.tagName.toLowerCase()
|
tag = node.tagName.toLowerCase()
|
||||||
if ignored_tags[tag]:
|
if ignored_tags[tag]:
|
||||||
return
|
return
|
||||||
style = window.getComputedStyle(node)
|
|
||||||
if style.display is 'none' or style.visibility is 'hidden':
|
|
||||||
return
|
|
||||||
children = node.childNodes
|
children = node.childNodes
|
||||||
for i in range(children.length):
|
for i in range(children.length):
|
||||||
process_node(v'children[i]')
|
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)
|
sel.setBaseAndExtent(match.start_node, match.start_offset, match.end_node, match.end_offset)
|
||||||
except: # if offset is outside node
|
except: # if offset is outside node
|
||||||
return False
|
return False
|
||||||
|
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 True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def select_search_result(sr):
|
def select_search_result(sr):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user