mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Wire up search result discovery
Also make only the results portion of the view scrollable
This commit is contained in:
parent
b94e0dbe4d
commit
83cbd28323
@ -49,7 +49,7 @@ def get_toc_data(book):
|
||||
|
||||
class SearchOverlay:
|
||||
|
||||
display_type = 'block'
|
||||
display_type = 'flex'
|
||||
CONTAINER_ID = 'book-search-overlay'
|
||||
|
||||
def __init__(self, view):
|
||||
@ -60,8 +60,11 @@ class SearchOverlay:
|
||||
self.result_map = {}
|
||||
c = self.container
|
||||
c.style.backgroundColor = get_color('window-background')
|
||||
c.style.maxHeight = '100%'
|
||||
c.style.overflow = 'auto'
|
||||
c.style.maxHeight = '100vh'
|
||||
c.style.minHeight = '100vh'
|
||||
c.style.flexDirection = 'column'
|
||||
c.style.alignItems = 'stretch'
|
||||
c.style.overflow = 'hidden'
|
||||
c.addEventListener('keydown', self.onkeydown)
|
||||
|
||||
create_top_bar(c, title=_('Search in book'), action=self.hide, icon='close')
|
||||
@ -110,15 +113,17 @@ class SearchOverlay:
|
||||
|
||||
c.appendChild(E.hr())
|
||||
c.appendChild(E.div(
|
||||
style='display: none',
|
||||
style='display: none; overflow: auto',
|
||||
E.div(
|
||||
style='text-align: center',
|
||||
E.div(create_spinner('4em', '4em')),
|
||||
E.div(_('Searching, please wait…'), style='margin-top: 1ex'),
|
||||
),
|
||||
E.div(
|
||||
),
|
||||
E.div(),
|
||||
))
|
||||
for child in c.childNodes:
|
||||
if child is not c.lastChild:
|
||||
child.style.flexShrink = '0'
|
||||
|
||||
@property
|
||||
def current_query(self):
|
||||
@ -129,6 +134,13 @@ class SearchOverlay:
|
||||
'text': c.querySelector('input[type=search]').value
|
||||
}
|
||||
|
||||
@current_query.setter
|
||||
def current_query(self, q):
|
||||
c = self.container
|
||||
c.querySelector('select[name=mode]').value = q.mode or 'contains'
|
||||
c.querySelector('input[name=case_sensitive]').checked = bool(q.case_sensitive)
|
||||
c.querySelector('input[type=search]').value = q.text or ''
|
||||
|
||||
@property
|
||||
def bottom_container(self):
|
||||
return self.container.lastChild
|
||||
@ -194,6 +206,8 @@ class SearchOverlay:
|
||||
def result_received(self, result):
|
||||
self.show_results()
|
||||
self.result_map[result.result_num] = result
|
||||
sr = Object.assign({}, result)
|
||||
self.view.discover_search_result(sr)
|
||||
toc_node_id = result.toc_nodes[0] if result.toc_nodes.length else -1
|
||||
toc_node = self.toc_data.toc_id_map[toc_node_id]
|
||||
c = self.results_container
|
||||
@ -228,15 +242,44 @@ class SearchOverlay:
|
||||
lines.push('\xa0\xa0' * i + '➤ ' + (self.toc_data.toc_id_map[node_id]?.title or _('Unknown')))
|
||||
tt = ngettext('Table of Contents section:', 'Table of Contents sections:', lines.length)
|
||||
tt += '\n' + lines.join('\n')
|
||||
entry = E.li(title=tt)
|
||||
rnum = result.result_num
|
||||
entry = E.li(title=tt, data_result_num=rnum + '', onclick=self.result_clicked.bind(None, rnum))
|
||||
|
||||
if result.before:
|
||||
entry.appendChild(E.span('…' + result.before + ' '))
|
||||
entry.appendChild(E.span('…' + result.before))
|
||||
entry.appendChild(E.strong(result.text))
|
||||
if result.after:
|
||||
entry.appendChild(E.span(' ' + result.after + '…'))
|
||||
entry.appendChild(E.span(result.after + '…'))
|
||||
ul.appendChild(entry)
|
||||
|
||||
def make_query_programmatically(self, text, mode, case_sensitive):
|
||||
self.current_query = {'text': text, 'mode': mode, 'case_sensitive': case_sensitive}
|
||||
self.show()
|
||||
self.run_search()
|
||||
|
||||
@property
|
||||
def current_result_container(self):
|
||||
return self.container.querySelector('.current')
|
||||
|
||||
def make_result_current(self, result_num):
|
||||
q = result_num + ''
|
||||
for li in self.container.querySelectorAll('[data-result-num]'):
|
||||
if li.dataset.resultNum is q:
|
||||
li.classList.add('current')
|
||||
li.scrollIntoView()
|
||||
else:
|
||||
li.classList.remove('current')
|
||||
|
||||
def search_result_discovered(self, sr):
|
||||
self.make_result_current(sr.result_num)
|
||||
|
||||
def result_clicked(self, rnum):
|
||||
sr = Object.assign({}, self.result_map[rnum])
|
||||
sr.on_discovery = 0
|
||||
self.make_result_current(rnum)
|
||||
self.view.show_search_result(sr)
|
||||
self.hide()
|
||||
|
||||
def clear_caches(self, book):
|
||||
self.clear_results()
|
||||
self.bottom_container.style.display = 'none'
|
||||
@ -303,6 +346,7 @@ add_extra_css(def():
|
||||
css += build_rule(sel + '.collapsed > ul', display='none')
|
||||
css += build_rule(sel + ' > div', font_style='italic', font_weight='bold', cursor='pointer')
|
||||
css += build_rule(sel + ' li', list_style_type='none', margin='1rem', margin_right='0', cursor='pointer')
|
||||
css += build_rule(sel + ' li.current', border_left='solid 2px ' + get_color('link-foreground'), padding_left='2px')
|
||||
css += build_rule(sel + ' li strong', color=get_color('link-foreground'), font_style='italic')
|
||||
return css
|
||||
)
|
||||
|
@ -87,6 +87,7 @@ class ReadUI:
|
||||
ui_operations.view_image = self.view_image.bind(self)
|
||||
ui_operations.speak_simple_text = self.speak_simple_text.bind(self)
|
||||
ui_operations.tts = self.tts.bind(self)
|
||||
ui_operations.search_result_discovered = self.view.search_overlay.search_result_discovered
|
||||
ui_operations.open_url = def(url):
|
||||
window.open(url, '_blank')
|
||||
ui_operations.copy_selection = def(text, html):
|
||||
|
@ -1392,8 +1392,9 @@ class View:
|
||||
if self.search_result_discovery?.on_discovery is sr.on_discovery:
|
||||
self.search_result_discovery.in_flight = None
|
||||
if discovered:
|
||||
self.search_result_discovery.discovered = True
|
||||
ui_operations.search_result_discovered(sr)
|
||||
if not self.search_result_discovery.discovered:
|
||||
self.search_result_discovery.discovered = True
|
||||
ui_operations.search_result_discovered(sr)
|
||||
elif not self.search_result_discovery.discovered and self.search_result_discovery.queue.length:
|
||||
self.show_search_result(self.search_result_discovery.queue.shift())
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user