diff --git a/searx/settings.yml b/searx/settings.yml index 6e5556d0c..5aaf154df 100644 --- a/searx/settings.yml +++ b/searx/settings.yml @@ -18,6 +18,8 @@ search: # "seznam", "startpage", "swisscows", "qwant", "wikipedia" - leave blank to turn it off # by default. autocomplete: "" + # minimun characters to type before autocompleter starts + autocomplete_min: 4 # Default search language - leave blank to detect from browser information or # use codes from 'languages.py' default_lang: "" diff --git a/searx/settings_defaults.py b/searx/settings_defaults.py index 7110fce93..938b9714d 100644 --- a/searx/settings_defaults.py +++ b/searx/settings_defaults.py @@ -153,6 +153,7 @@ SCHEMA = { 'search': { 'safe_search': SettingsValue((0, 1, 2), 0), 'autocomplete': SettingsValue(str, ''), + 'autocomplete_min': SettingsValue(int, 4), 'default_lang': SettingsValue(tuple(LANGUAGE_CODES + ['']), ''), 'languages': SettingSublistValue(LANGUAGE_CODES, LANGUAGE_CODES), 'ban_time_on_fail': SettingsValue(numbers.Real, 5), diff --git a/searx/static/themes/simple/js/searxng.head.min.js b/searx/static/themes/simple/js/searxng.head.min.js index 2885a301c..18ddcfd15 100644 Binary files a/searx/static/themes/simple/js/searxng.head.min.js and b/searx/static/themes/simple/js/searxng.head.min.js differ diff --git a/searx/static/themes/simple/js/searxng.head.min.js.map b/searx/static/themes/simple/js/searxng.head.min.js.map index 9fee90adb..7ebfb58f1 100644 Binary files a/searx/static/themes/simple/js/searxng.head.min.js.map and b/searx/static/themes/simple/js/searxng.head.min.js.map differ diff --git a/searx/static/themes/simple/js/searxng.min.js b/searx/static/themes/simple/js/searxng.min.js index a889e680b..b0cbe2918 100644 Binary files a/searx/static/themes/simple/js/searxng.min.js and b/searx/static/themes/simple/js/searxng.min.js differ diff --git a/searx/static/themes/simple/js/searxng.min.js.map b/searx/static/themes/simple/js/searxng.min.js.map index e325fba4c..75c5bc793 100644 Binary files a/searx/static/themes/simple/js/searxng.min.js.map and b/searx/static/themes/simple/js/searxng.min.js.map differ diff --git a/searx/static/themes/simple/src/js/head/00_init.js b/searx/static/themes/simple/src/js/head/00_init.js index acd437f39..4aeece8c2 100644 --- a/searx/static/themes/simple/src/js/head/00_init.js +++ b/searx/static/themes/simple/src/js/head/00_init.js @@ -1,9 +1,4 @@ -/** - * @license - * (C) Copyright Contributors to the SearXNG project. - * (C) Copyright Contributors to the searx project (2014 - 2021). - * SPDX-License-Identifier: AGPL-3.0-or-later - */ +/* SPDX-License-Identifier: AGPL-3.0-or-later */ (function (w, d) { 'use strict'; @@ -13,23 +8,13 @@ return scripts[scripts.length - 1]; })(); - // try to detect touch screen w.searxng = { - method: script.getAttribute('data-method'), - autocompleter: script.getAttribute('data-autocompleter') === 'true', - search_on_category_select: script.getAttribute('data-search-on-category-select') === 'true', - infinite_scroll: script.getAttribute('data-infinite-scroll') === 'true', - hotkeys: script.getAttribute('data-hotkeys') === 'true', - static_path: script.getAttribute('data-static-path'), - translations: JSON.parse(script.getAttribute('data-translations')), - theme: { - // image that is displayed if load of failed - img_load_error: 'img/img_load_error.svg' - } + settings: JSON.parse(atob(script.getAttribute('client_settings'))) }; // update the css var hmtlElement = d.getElementsByTagName("html")[0]; hmtlElement.classList.remove('no-js'); hmtlElement.classList.add('js'); -})(window, document); \ No newline at end of file + +})(window, document); diff --git a/searx/static/themes/simple/src/js/main/00_toolkit.js b/searx/static/themes/simple/src/js/main/00_toolkit.js index f53842d72..699731ee4 100644 --- a/searx/static/themes/simple/src/js/main/00_toolkit.js +++ b/searx/static/themes/simple/src/js/main/00_toolkit.js @@ -101,7 +101,7 @@ window.searxng = (function (w, d) { }; searxng.loadStyle = function (src) { - var path = searxng.static_path + src, + var path = searxng.settings.theme_static_path + src, id = "style_" + src.replace('.', '_'), s = d.getElementById(id); if (s === null) { @@ -115,7 +115,7 @@ window.searxng = (function (w, d) { }; searxng.loadScript = function (src, callback) { - var path = searxng.static_path + src, + var path = searxng.settings.theme_static_path + src, id = "script_" + src.replace('.', '_'), s = d.getElementById(id); if (s === null) { diff --git a/searx/static/themes/simple/src/js/main/infinite_scroll.js b/searx/static/themes/simple/src/js/main/infinite_scroll.js index b900e66e2..07db3305a 100644 --- a/searx/static/themes/simple/src/js/main/infinite_scroll.js +++ b/searx/static/themes/simple/src/js/main/infinite_scroll.js @@ -62,7 +62,7 @@ searxng.ready(function () { function (err) { console.log(err); var e = d.createElement('div'); - e.textContent = searxng.translations.error_loading_next_page; + e.textContent = searxng.settings.translations.error_loading_next_page; e.classList.add('dialog-error'); e.setAttribute('role', 'alert'); replaceChildrenWith(d.querySelector('#pagination'), [ e ]); @@ -70,7 +70,7 @@ searxng.ready(function () { ) } - if (searxng.infinite_scroll && searxng.infinite_scroll_supported) { + if (searxng.settings.infinite_scroll && searxng.infinite_scroll_supported) { const intersectionObserveOptions = { rootMargin: "20rem", }; diff --git a/searx/static/themes/simple/src/js/main/keyboard.js b/searx/static/themes/simple/src/js/main/keyboard.js index a8ab7222f..f29ed86f4 100644 --- a/searx/static/themes/simple/src/js/main/keyboard.js +++ b/searx/static/themes/simple/src/js/main/keyboard.js @@ -154,7 +154,7 @@ searxng.ready(function () { } }; - if (searxng.hotkeys) { + if (searxng.settings.hotkeys) { searxng.on(document, "keydown", function (e) { // check for modifiers so we don't break browser's hotkeys if (Object.prototype.hasOwnProperty.call(vimKeys, e.keyCode) && !e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey) { diff --git a/searx/static/themes/simple/src/js/main/preferences.js b/searx/static/themes/simple/src/js/main/preferences.js index 09f9cdde4..1e3ae5981 100644 --- a/searx/static/themes/simple/src/js/main/preferences.js +++ b/searx/static/themes/simple/src/js/main/preferences.js @@ -15,7 +15,7 @@ for (const [engine_name, description] of Object.entries(engine_descriptions)) { let elements = d.querySelectorAll('[data-engine-name="' + engine_name + '"] .engine-description'); for (const element of elements) { - let source = ' (' + searxng.translations['Source'] + ': ' + description[1] + ')'; + let source = ' (' + searxng.settings.translations.Source + ': ' + description[1] + ')'; element.innerHTML = description[0] + source; } } diff --git a/searx/static/themes/simple/src/js/main/search.js b/searx/static/themes/simple/src/js/main/search.js index 798c9b2d3..20e58e0fe 100644 --- a/searx/static/themes/simple/src/js/main/search.js +++ b/searx/static/themes/simple/src/js/main/search.js @@ -59,16 +59,16 @@ createClearButton(qinput); // autocompleter - if (searxng.autocompleter) { + if (searxng.settings.autocomplete_provider) { searxng.autocomplete = AutoComplete.call(w, { Url: "./autocompleter", - EmptyMessage: searxng.translations.no_item_found, - HttpMethod: searxng.method, + EmptyMessage: searxng.settings.translations.no_item_found, + HttpMethod: searxng.settings.http_method, HttpHeaders: { "Content-type": "application/x-www-form-urlencoded", "X-Requested-With": "XMLHttpRequest" }, - MinChars: 4, + MinChars: searxng.settings.autocomplete_min, Delay: 300, _Position: function () {}, _Open: function () { @@ -92,7 +92,7 @@ } // vanilla js version of search_on_category_select.js - if (qinput !== null && d.querySelector('.help') != null && searxng.search_on_category_select) { + if (qinput !== null && d.querySelector('.help') != null && searxng.settings.search_on_category_select) { d.querySelector('.help').className = 'invisible'; searxng.on('#categories input', 'change', function () { diff --git a/searx/templates/simple/base.html b/searx/templates/simple/base.html index a82c26a61..d8eaaa02b 100644 --- a/searx/templates/simple/base.html +++ b/searx/templates/simple/base.html @@ -19,14 +19,7 @@ {% endif %} {% block styles %}{% endblock %} - + {% block head %} diff --git a/searx/webapp.py b/searx/webapp.py index 3d3f736a5..178500df6 100755 --- a/searx/webapp.py +++ b/searx/webapp.py @@ -10,6 +10,7 @@ import hmac import json import os import sys +import base64 from datetime import datetime, timedelta from timeit import default_timer @@ -444,7 +445,37 @@ def get_pretty_url(parsed_url: urllib.parse.ParseResult): return [parsed_url.scheme + "://" + parsed_url.netloc, path] +def get_client_settings(): + req_pref = request.preferences + return { + 'autocomplete_provider': req_pref.get_value('autocomplete'), + 'autocomplete_min' : get_setting('search.autocomplete_min'), + 'http_method': req_pref.get_value('method'), + 'infinite_scroll': req_pref.get_value('infinite_scroll'), + 'translations': get_translations(), + 'search_on_category_select': req_pref.plugins.choices['searx.plugins.search_on_category_select'], + 'hotkeys': req_pref.plugins.choices['searx.plugins.vim_hotkeys'], + 'theme_static_path': custom_url_for('static', filename='themes/simple'), + } + + def render(template_name: str, override_theme: str = None, **kwargs): + + kwargs['client_settings'] = str( + base64.b64encode( + bytes( + json.dumps(get_client_settings()), + encoding='utf-8', + ) + ), encoding='utf-8', + ) + + # obsolete, only needed by oscar + kwargs['autocomplete'] = request.preferences.get_value('autocomplete') + kwargs['method'] = request.preferences.get_value('method') + kwargs['infinite_scroll'] = request.preferences.get_value('infinite_scroll') + kwargs['translations'] = json.dumps(get_translations(), separators=(',', ':')) + # values from the HTTP requests kwargs['endpoint'] = 'results' if 'q' in kwargs else request.endpoint kwargs['cookies'] = request.cookies @@ -452,9 +483,6 @@ def render(template_name: str, override_theme: str = None, **kwargs): # values from the preferences kwargs['preferences'] = request.preferences - kwargs['method'] = request.preferences.get_value('method') - kwargs['autocomplete'] = request.preferences.get_value('autocomplete') - kwargs['infinite_scroll'] = request.preferences.get_value('infinite_scroll') kwargs['results_on_new_tab'] = request.preferences.get_value('results_on_new_tab') kwargs['advanced_search'] = request.preferences.get_value('advanced_search') kwargs['query_in_title'] = request.preferences.get_value('query_in_title') @@ -466,7 +494,6 @@ def render(template_name: str, override_theme: str = None, **kwargs): # i18n kwargs['language_codes'] = [l for l in languages if l[0] in settings['search']['languages']] - kwargs['translations'] = json.dumps(get_translations(), separators=(',', ':')) locale = request.preferences.get_value('locale') kwargs['locale_rfc5646'] = _get_locale_rfc5646(locale)