forked from zaclys/searxng
		
	Merge pull request #1091 from return42/client-settings
[mod] client_settings: pass settings from server to JS client
This commit is contained in:
		
						commit
						30756d5cfc
					
				
					 14 changed files with 55 additions and 53 deletions
				
			
		| 
						 | 
				
			
			@ -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: ""
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,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
 | 
			
		||||
| 
						 | 
				
			
			@ -1 +1 @@
 | 
			
		|||
{"version":3,"file":"searxng.head.min.js","sources":["../src/js/head/00_init.js"],"sourcesContent":["/**\n * @license\n * (C) Copyright Contributors to the SearXNG project.\n * (C) Copyright Contributors to the searx project (2014 - 2021).\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n(function (w, d) {\n  'use strict';\n\n  // add data- properties\n  var script = d.currentScript  || (function () {\n    var scripts = d.getElementsByTagName('script');\n    return scripts[scripts.length - 1];\n  })();\n\n  // try to detect touch screen\n  w.searxng = {\n    method: script.getAttribute('data-method'),\n    autocompleter: script.getAttribute('data-autocompleter') === 'true',\n    search_on_category_select: script.getAttribute('data-search-on-category-select') === 'true',\n    infinite_scroll: script.getAttribute('data-infinite-scroll') === 'true',\n    hotkeys: script.getAttribute('data-hotkeys') === 'true',\n    static_path: script.getAttribute('data-static-path'),\n    translations: JSON.parse(script.getAttribute('data-translations')),\n    theme: {\n      // image that is displayed if load of <img src='...'> failed\n      img_load_error: 'img/img_load_error.svg'\n    }\n  };\n\n  // update the css\n  var hmtlElement = d.getElementsByTagName(\"html\")[0];\n  hmtlElement.classList.remove('no-js');\n  hmtlElement.classList.add('js');\n})(window, document);"],"names":["w","d","script","currentScript","scripts","getElementsByTagName","length","searxng","method","getAttribute","autocompleter","search_on_category_select","infinite_scroll","hotkeys","static_path","translations","JSON","parse","theme","img_load_error","hmtlElement","classList","remove","add","window","document"],"mappings":";;;;;;CAMA,SAAWA,EAAGC,gBAIZ,IAAIC,EAASD,EAAEE,eAAkB,WAC/B,IAAIC,EAAUH,EAAEI,qBAAqB,UACrC,OAAOD,EAAQA,EAAQE,OAAS,GAFD,GAMjCN,EAAEO,QAAU,CACVC,OAAQN,EAAOO,aAAa,eAC5BC,cAAeR,EAAOO,aAAa,wBAA0B,OAC7DE,0BAA2BT,EAAOO,aAAa,oCAAsC,OACrFG,gBAAiBV,EAAOO,aAAa,0BAA4B,OACjEI,QAASX,EAAOO,aAAa,kBAAoB,OACjDK,YAAaZ,EAAOO,aAAa,oBACjCM,aAAcC,KAAKC,MAAMf,EAAOO,aAAa,sBAC7CS,MAAO,CAELC,eAAgB,2BAKpB,IAAIC,EAAcnB,EAAEI,qBAAqB,QAAQ,GACjDe,EAAYC,UAAUC,OAAO,SAC7BF,EAAYC,UAAUE,IAAI,OA3B5B,CA4BGC,OAAQC"}
 | 
			
		||||
{"version":3,"file":"searxng.head.min.js","sources":["../src/js/head/00_init.js"],"sourcesContent":["/* SPDX-License-Identifier: AGPL-3.0-or-later */\n(function (w, d) {\n  'use strict';\n\n  // add data- properties\n  var script = d.currentScript  || (function () {\n    var scripts = d.getElementsByTagName('script');\n    return scripts[scripts.length - 1];\n  })();\n\n  w.searxng = {\n    settings: JSON.parse(atob(script.getAttribute('client_settings')))\n  };\n\n  // update the css\n  var hmtlElement = d.getElementsByTagName(\"html\")[0];\n  hmtlElement.classList.remove('no-js');\n  hmtlElement.classList.add('js');\n\n})(window, document);\n"],"names":["w","d","script","currentScript","scripts","getElementsByTagName","length","searxng","settings","JSON","parse","atob","getAttribute","hmtlElement","classList","remove","add","window","document"],"mappings":"CACA,SAAWA,EAAGC,gBAIZ,IAAIC,EAASD,EAAEE,eAAkB,WAC/B,IAAIC,EAAUH,EAAEI,qBAAqB,UACrC,OAAOD,EAAQA,EAAQE,OAAS,GAFD,GAKjCN,EAAEO,QAAU,CACVC,SAAUC,KAAKC,MAAMC,KAAKT,EAAOU,aAAa,sBAIhD,IAAIC,EAAcZ,EAAEI,qBAAqB,QAAQ,GACjDQ,EAAYC,UAAUC,OAAO,SAC7BF,EAAYC,UAAUE,IAAI,OAhB5B,CAkBGC,OAAQC"}
 | 
			
		||||
							
								
								
									
										4
									
								
								searx/static/themes/simple/js/searxng.min.js
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								searx/static/themes/simple/js/searxng.min.js
									
										
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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",
 | 
			
		||||
    };
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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'] + ': ' + description[1] + '</i>)';
 | 
			
		||||
              let source = ' (<i>' + searxng.settings.translations.Source + ': ' + description[1] + '</i>)';
 | 
			
		||||
              element.innerHTML = description[0] + source;
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 () {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 }}"/>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue