diff --git a/src/pyj/complete.pyj b/src/pyj/complete.pyj index 1fc0f7ffb9..b30c9bbaaa 100644 --- a/src/pyj/complete.pyj +++ b/src/pyj/complete.pyj @@ -2,7 +2,7 @@ # License: GPL v3 Copyright: 2016, Kovid Goyal from __python__ import hash_literals, bound_methods -from dom import ensure_id +from dom import ensure_id, unique_id, clear from elementmaker import E from session import local_storage from popups import CompletionPopup @@ -108,8 +108,74 @@ def create_search_bar(action, name, tooltip=None, placeholder=None, button=None, ewc.add_associated_widget(w) return parent + +def create_simple_input_with_history_native(name, tooltip=None, placeholder=None, history_size=100, input_type='text'): + # cannot use in standalone viewer because of: https://bugreports.qt.io/browse/QTBUG-54433 + dl_id = unique_id() + dl = document.createElement('datalist') + dl.id = dl_id + history_name = f'simple_input_history_{name}' + + def update_completion_items(x): + items = local_storage().get(history_name) + dl = x or document.getElementById(dl_id) + if dl: + clear(dl) + if items?.length: + for item in items: + dl.appendChild(E.option(value=item)) + + def save_completion_items(): + text = document.getElementById(dl_id).nextSibling.value + if text and text.strip(): + items = local_storage().get(history_name) or v'[]' + idx = items.indexOf(text) + if idx > -1: + items.splice(idx, 1) + items.unshift(text) + local_storage().set(history_name, uniq(items[:history_size])) + update_completion_items() + + update_completion_items(dl) + ans = E.span( + data_calibre_history_input='1', + dl, + E.input(type=input_type, name=name, list=dl_id, title=tooltip or '', placeholder=placeholder or ''), + ) + ans.addEventListener('save_history', save_completion_items) + return ans + + +def create_simple_input_with_history(name, tooltip=None, placeholder=None, history_size=100, input_type='text'): + # to use simply add the returned element to the DOM and when you want to + # save a new completion item, use dispatchEvent to send a 'save_history' + # event to it. + parent = E.span(data_calibre_history_input='1') + ewc = EditWithComplete(name, parent=parent, tooltip=tooltip, placeholder=placeholder, input_type=input_type) + history_name = f'simple_input_history_{name}' + + def update_completion_items(): + items = local_storage().get(history_name) + if items?.length: + ewc.set_all_items(items) + update_completion_items() + + def save_completion_items(): + text = ewc.text_input.value + if text and text.strip(): + items = local_storage().get(history_name) or v'[]' + idx = items.indexOf(text) + if idx > -1: + items.splice(idx, 1) + items.unshift(text) + local_storage().set(history_name, uniq(items[:history_size])) + update_completion_items() + + parent.addEventListener('save_history', save_completion_items) + return parent # }}} + def main(container): container.appendChild(create_search_bar(print, 'test-search-bar', placeholder='Testing search bar')) container.firstChild.lastChild.focus() diff --git a/src/pyj/read_book/prefs/selection.pyj b/src/pyj/read_book/prefs/selection.pyj index a99456c024..5b2bcb0b42 100644 --- a/src/pyj/read_book/prefs/selection.pyj +++ b/src/pyj/read_book/prefs/selection.pyj @@ -3,10 +3,11 @@ from __python__ import bound_methods, hash_literals from elementmaker import E -from gettext import gettext as _ from book_list.globals import get_session_data +from complete import create_simple_input_with_history from dom import clear, svgicon, unique_id +from gettext import gettext as _ from read_book.globals import is_dark_theme from read_book.highlights import all_styles from read_book.prefs.utils import create_button_box @@ -157,7 +158,11 @@ def create_selection_panel(container, apply_func, cancel_func): return E.div(style='margin-top:1ex', E.label(ans, '\xa0' + text)) def url(name, text, title): - ans = E.input(type='url', name=name, value=sd.get(name), size='50', title=title or '', style='margin-top: 1ex') + ans = create_simple_input_with_history(name, input_type='url') + inp = ans.querySelector(f'input[name={name}]') + inp.value = sd.get(name) or '' + inp.setAttribute('size', '50') + inp.style.marginTop = '1ex' return E.div(style='margin-top:1ex', E.label(text, E.br(), ans)) container.appendChild(cb( @@ -193,6 +198,9 @@ def commit_selection(onchange): sd = get_session_data() container = get_container() changed = False + save_ev = new Event('save_history') + for x in container.querySelectorAll('[data-calibre-history-input]'): + x.dispatchEvent(save_ev) for control in container.querySelectorAll('input[name]'): name = control.getAttribute('name') if control.type is 'checkbox':