Browse Source

Merge pull request #1091 from return42/client-settings

[mod] client_settings: pass settings from server to JS client
Alexandre Flament 3 years ago
parent
commit
30756d5cfc

+ 2 - 0
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: ""

+ 1 - 0
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),

+ 1 - 7
searx/static/themes/simple/js/searxng.head.min.js

@@ -1,8 +1,2 @@
-/**
- * @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
- */
-(function(t,e){"use strict";var a=e.currentScript||function(){var t=e.getElementsByTagName("script");return t[t.length-1]}();t.searxng={method:a.getAttribute("data-method"),autocompleter:a.getAttribute("data-autocompleter")==="true",search_on_category_select:a.getAttribute("data-search-on-category-select")==="true",infinite_scroll:a.getAttribute("data-infinite-scroll")==="true",hotkeys:a.getAttribute("data-hotkeys")==="true",static_path:a.getAttribute("data-static-path"),translations:JSON.parse(a.getAttribute("data-translations")),theme:{img_load_error:"img/img_load_error.svg"}};var r=e.getElementsByTagName("html")[0];r.classList.remove("no-js");r.classList.add("js")})(window,document);
+(function(t,e){"use strict";var s=e.currentScript||function(){var t=e.getElementsByTagName("script");return t[t.length-1]}();t.searxng={settings:JSON.parse(atob(s.getAttribute("client_settings")))};var n=e.getElementsByTagName("html")[0];n.classList.remove("no-js");n.classList.add("js")})(window,document);
 //# sourceMappingURL=searxng.head.min.js.map

File diff suppressed because it is too large
+ 0 - 0
searx/static/themes/simple/js/searxng.head.min.js.map


File diff suppressed because it is too large
+ 0 - 0
searx/static/themes/simple/js/searxng.min.js


File diff suppressed because it is too large
+ 0 - 0
searx/static/themes/simple/js/searxng.min.js.map


+ 4 - 19
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 <img src='...'> 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);
+
+})(window, document);

+ 2 - 2
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) {

+ 2 - 2
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",
     };

+ 1 - 1
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) {

+ 1 - 1
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 = ' (<i>' + searxng.translations['Source'] + ':&nbsp;' + description[1] + '</i>)';
+              let source = ' (<i>' + searxng.settings.translations.Source + ':&nbsp;' + description[1] + '</i>)';
               element.innerHTML = description[0] + source;
             }
           }

+ 5 - 5
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 () {

+ 1 - 8
searx/templates/simple/base.html

@@ -19,14 +19,7 @@
   {% endif %}
   {% block styles %}{% endblock %}
   <!--[if gte IE 9]>-->
-  <script src="{{ url_for('static', filename='js/searxng.head.min.js') }}"
-          data-method="{{ method or 'POST' }}"
-          data-autocompleter="{% if autocomplete %}true{% else %}false{% endif %}"
-          data-search-on-category-select="{{ 'true' if 'plugins/js/search_on_category_select.js' in scripts else 'false'}}"
-          data-infinite-scroll="{% if infinite_scroll %}true{% else %}false{% endif %}"
-          data-hotkeys="{{ 'true' if 'plugins/js/vim_hotkeys.js' in scripts else 'false' }}"
-          data-static-path="{{ url_for('static', filename='themes/simple') }}/"
-          data-translations="{{ translations }}"></script>
+  <script src="{{ url_for('static', filename='js/searxng.head.min.js') }}" client_settings="{{ client_settings }}"></script>
   <!--<![endif]-->
   {% block head %}
   <link title="{{ instance_name }}" type="application/opensearchdescription+xml" rel="search" href="{{ opensearch_url }}"/>

+ 31 - 4
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)

Some files were not shown because too many files changed in this diff