theme: remove __common__

This commit is contained in:
Alexandre Flament 2022-05-07 15:11:05 +02:00
parent 6db568bf69
commit 9b3efa6d8a
25 changed files with 141 additions and 588 deletions

View file

@ -22,5 +22,3 @@ description = gettext(
) )
default_on = True default_on = True
preference_section = 'ui' preference_section = 'ui'
js_dependencies = ('plugins/js/search_on_category_select.js',)

View file

@ -8,6 +8,3 @@ description = gettext(
) )
default_on = False default_on = False
preference_section = 'ui' preference_section = 'ui'
js_dependencies = ('plugins/js/vim_hotkeys.js',)
css_dependencies = ('plugins/css/vim_hotkeys.css',)

View file

@ -1,26 +0,0 @@
.vim-hotkeys-help {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 9999999;
overflow-y: auto;
max-height: 80%;
box-shadow: 0 0 1em;
}
.dflex {
display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */
display: -moz-box; /* OLD - Firefox 19- (buggy but mostly works) */
display: -ms-flexbox; /* TWEENER - IE 10 */
display: -webkit-flex; /* NEW - Chrome */
display: flex; /* NEW, Spec - Opera 12.1, Firefox 20+ */
}
.iflex {
-webkit-box-flex: 1; /* OLD - iOS 6-, Safari 3.1-6 */
-moz-box-flex: 1; /* OLD - Firefox 19- */
-webkit-flex: 1; /* Chrome */
-ms-flex: 1; /* IE 10 */
flex: 1; /* NEW, Spec - Opera 12.1, Firefox 20+ */
}

View file

@ -1,42 +0,0 @@
$(document).ready(function() {
if($('#q').length) {
$('#categories label').click(function(e) {
$('#categories input[type="checkbox"]').each(function(i, checkbox) {
$(checkbox).prop('checked', false);
});
$(document.getElementById($(this).attr("for"))).prop('checked', true);
if($('#q').val()) {
if (getHttpRequest() == "GET") {
$('#search_form').attr('action', $('#search_form').serialize());
}
$('#search_form').submit();
}
return false;
});
$('#time-range').change(function(e) {
if($('#q').val()) {
if (getHttpRequest() == "GET") {
$('#search_form').attr('action', $('#search_form').serialize());
}
$('#search_form').submit();
}
});
$('#language').change(function(e) {
if($('#q').val()) {
if (getHttpRequest() == "GET") {
$('#search_form').attr('action', $('#search_form').serialize());
}
$('#search_form').submit();
}
});
}
});
function getHttpRequest() {
httpRequest = "POST";
urlParams = new URLSearchParams(window.location.search);
if (urlParams.has('method')) {
httpRequest = urlParams.get('method');
}
return httpRequest;
}

View file

@ -1,345 +0,0 @@
$(document).ready(function() {
highlightResult('top')();
$('.result').on('click', function() {
highlightResult($(this))();
});
var vimKeys = {
27: {
key: 'Escape',
fun: removeFocus,
des: 'remove focus from the focused input',
cat: 'Control'
},
73: {
key: 'i',
fun: searchInputFocus,
des: 'focus on the search input',
cat: 'Control'
},
66: {
key: 'b',
fun: scrollPage(-window.innerHeight),
des: 'scroll one page up',
cat: 'Navigation'
},
70: {
key: 'f',
fun: scrollPage(window.innerHeight),
des: 'scroll one page down',
cat: 'Navigation'
},
85: {
key: 'u',
fun: scrollPage(-window.innerHeight / 2),
des: 'scroll half a page up',
cat: 'Navigation'
},
68: {
key: 'd',
fun: scrollPage(window.innerHeight / 2),
des: 'scroll half a page down',
cat: 'Navigation'
},
71: {
key: 'g',
fun: scrollPageTo(-document.body.scrollHeight, 'top'),
des: 'scroll to the top of the page',
cat: 'Navigation'
},
86: {
key: 'v',
fun: scrollPageTo(document.body.scrollHeight, 'bottom'),
des: 'scroll to the bottom of the page',
cat: 'Navigation'
},
75: {
key: 'k',
fun: highlightResult('up'),
des: 'select previous search result',
cat: 'Results'
},
74: {
key: 'j',
fun: highlightResult('down'),
des: 'select next search result',
cat: 'Results'
},
80: {
key: 'p',
fun: pageButtonClick(0),
des: 'go to previous page',
cat: 'Results'
},
78: {
key: 'n',
fun: pageButtonClick(1),
des: 'go to next page',
cat: 'Results'
},
79: {
key: 'o',
fun: openResult(false),
des: 'open search result',
cat: 'Results'
},
84: {
key: 't',
fun: openResult(true),
des: 'open the result in a new tab',
cat: 'Results'
},
82: {
key: 'r',
fun: reloadPage,
des: 'reload page from the server',
cat: 'Control'
},
72: {
key: 'h',
fun: toggleHelp,
des: 'toggle help window',
cat: 'Other'
}
};
$(document).keydown(function(e) {
// check for modifiers so we don't break browser's hotkeys
if (vimKeys.hasOwnProperty(e.keyCode)
&& !e.ctrlKey
&& !e.altKey
&& !e.shiftKey
&& !e.metaKey)
{
if (e.keyCode === 27) {
if (e.target.tagName.toLowerCase() === 'input') {
vimKeys[e.keyCode].fun();
}
} else {
if (e.target === document.body) {
e.preventDefault();
vimKeys[e.keyCode].fun();
}
}
}
});
function nextResult(current, direction) {
var next = current[direction]();
while (!next.is('.result') && next.length !== 0) {
next = next[direction]();
}
return next
}
function highlightResult(which) {
return function() {
var current = $('.result[data-vim-selected]');
if (current.length === 0) {
current = $('.result:first');
if (current.length === 0) {
return;
}
}
var next;
if (typeof which !== 'string') {
next = which;
} else {
switch (which) {
case 'visible':
var top = $(window).scrollTop();
var bot = top + $(window).height();
var results = $('.result');
for (var i = 0; i < results.length; i++) {
next = $(results[i]);
var etop = next.offset().top;
var ebot = etop + next.height();
if ((ebot <= bot) && (etop > top)) {
break;
}
}
break;
case 'down':
next = nextResult(current, 'next');
if (next.length === 0) {
next = $('.result:first');
}
break;
case 'up':
next = nextResult(current, 'prev');
if (next.length === 0) {
next = $('.result:last');
}
break;
case 'bottom':
next = $('.result:last');
break;
case 'top':
default:
next = $('.result:first');
}
}
if (next) {
current.removeAttr('data-vim-selected').removeClass('well well-sm');
next.attr('data-vim-selected', 'true').addClass('well well-sm');
scrollPageToSelected();
}
}
}
function reloadPage() {
document.location.reload(false);
}
function removeFocus() {
if (document.activeElement) {
document.activeElement.blur();
}
}
function pageButtonClick(num) {
return function() {
var buttons = $('div#pagination button[type="submit"]');
if (buttons.length !== 2) {
console.log('page navigation with this theme is not supported');
return;
}
if (num >= 0 && num < buttons.length) {
buttons[num].click();
} else {
console.log('pageButtonClick(): invalid argument');
}
}
}
function scrollPageToSelected() {
var sel = $('.result[data-vim-selected]');
if (sel.length !== 1) {
return;
}
var wnd = $(window);
var wtop = wnd.scrollTop();
var etop = sel.offset().top;
var offset = 30;
if (wtop > etop) {
wnd.scrollTop(etop - offset);
} else {
var ebot = etop + sel.height();
var wbot = wtop + wnd.height();
if (wbot < ebot) {
wnd.scrollTop(ebot - wnd.height() + offset);
}
}
}
function scrollPage(amount) {
return function() {
window.scrollBy(0, amount);
highlightResult('visible')();
}
}
function scrollPageTo(position, nav) {
return function() {
window.scrollTo(0, position);
highlightResult(nav)();
}
}
function searchInputFocus() {
$('input#q').focus();
}
function openResult(newTab) {
return function() {
var link = $('.result[data-vim-selected] .result_header a');
if (link.length) {
var url = link.attr('href');
if (newTab) {
window.open(url);
} else {
window.location.href = url;
}
}
};
}
function toggleHelp() {
var helpPanel = $('#vim-hotkeys-help');
if (helpPanel.length) {
helpPanel.toggleClass('hidden');
return;
}
var categories = {};
for (var k in vimKeys) {
var key = vimKeys[k];
categories[key.cat] = categories[key.cat] || [];
categories[key.cat].push(key);
}
var sorted = Object.keys(categories).sort(function(a, b) {
return categories[b].length - categories[a].length;
});
if (sorted.length === 0) {
return;
}
var html = '<div id="vim-hotkeys-help" class="well vim-hotkeys-help">';
html += '<div class="container-fluid">';
html += '<div class="row">';
html += '<div class="col-sm-12">';
html += '<h3>How to navigate searx with Vim-like hotkeys</h3>';
html += '</div>'; // col-sm-12
html += '</div>'; // row
for (var i = 0; i < sorted.length; i++) {
var cat = categories[sorted[i]];
var lastCategory = i === (sorted.length - 1);
var first = i % 2 === 0;
if (first) {
html += '<div class="row dflex">';
}
html += '<div class="col-sm-' + (first && lastCategory ? 12 : 6) + ' dflex">';
html += '<div class="panel panel-default iflex">';
html += '<div class="panel-heading">' + cat[0].cat + '</div>';
html += '<div class="panel-body">';
html += '<ul class="list-unstyled">';
for (var cj in cat) {
html += '<li><kbd>' + cat[cj].key + '</kbd> ' + cat[cj].des + '</li>';
}
html += '</ul>';
html += '</div>'; // panel-body
html += '</div>'; // panel
html += '</div>'; // col-sm-*
if (!first || lastCategory) {
html += '</div>'; // row
}
}
html += '</div>'; // container-fluid
html += '</div>'; // vim-hotkeys-help
$('body').append(html);
}
});

View file

@ -1,19 +0,0 @@
.github-issue-button {
display: block;
padding: 8px 16px;
font-family: sans-serif;
font-size: 16px;
color: white;
background-color: #238636 !important; /* important is needed cause to an !important in logicodev-dark */
border: #2ea043;
border-radius: 10px !important;
box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px;
}
.github-issue-button:hover {
background-color: #2ea043;
}
.issue-hide {
display: none;
}

View file

@ -1,5 +0,0 @@
.osm-map-box {
height:300px;
width:100%;
margin: 10px 0;
}

View file

@ -1,83 +0,0 @@
.engine-stats {
.engine-name {
width: 20rem;
}
.engine-score {
width: 7rem;
text-align: right;
}
.result-count {
}
.response-time {
}
.engine-reliability {
text-align: right;
}
table.engine-error {
max-width: 1280px;
margin: 1rem;
border: 1px solid gray;
}
table.engine-error th.engine-error-type,
table.engine-error td.engine-error-type,
failed-test {
width: 10rem;
}
table.engine-error span.log_parameters
{
border-right: 1px solid gray;
padding: 0 1rem 0 0;
margin: 0 0 0 0.5rem;
}
}
.bar-chart-value {
width: 3em;
display: inline-block;
text-align: right;
padding-right: 0.5rem;
}
.bar-chart-graph {
width: calc(100% - 5rem);
display: inline-block;
}
.bar-chart-bar {
border: 3px solid #5bc0de;
margin: 1px 0;
}
.bar-chart-serie1 {
border: 3px solid #5bc0de;
margin: 1px 0;
float: left;
}
.bar-chart-serie2 {
border: 3px solid #deb15b;
margin: 1px 0;
float: left;
}
.bar0{
width: 0;
border: 0;
}
.generate-bar(100);
.generate-bar(@n, @i: 1) when (@i =< @n) {
.bar@{i} {
width: (@i * 100% / @n);
}
.generate-bar(@n, (@i + 1));
}

View file

@ -44,7 +44,6 @@ module.exports = function (grunt) {
'svg4web.svgo.js', 'svg4web.svgo.js',
'src/js/main/*.js', 'src/js/main/*.js',
'src/js/head/*.js', 'src/js/head/*.js',
'../__common__/js/*.js'
], ],
}, },
stylelint: { stylelint: {
@ -146,7 +145,7 @@ module.exports = function (grunt) {
svgo: ['--config', 'svg4web.svgo.js'] svgo: ['--config', 'svg4web.svgo.js']
}, },
files: { files: {
'<%= _templates %>/__common__/searxng-wordmark.min.svg': '<%= _brand %>/searxng-wordmark.svg', '<%= _templates %>/simple/searxng-wordmark.min.svg': '<%= _brand %>/searxng-wordmark.svg',
'img/searxng.svg': '<%= _brand %>/searxng.svg', 'img/searxng.svg': '<%= _brand %>/searxng.svg',
'img/img_load_error.svg': '<%= _brand %>/img_load_error.svg' 'img/img_load_error.svg': '<%= _brand %>/img_load_error.svg'
} }

View file

@ -0,0 +1,21 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
.github-issue-button {
display: block;
padding: 8px 16px;
font-family: sans-serif;
font-size: 16px;
color: white;
background-color: #238636;
border: #2ea043;
border-radius: 10px !important;
box-shadow: rgba(0, 0, 0, 0) 0 0 0 0;
}
.github-issue-button:hover {
background-color: #2ea043;
}
.issue-hide {
display: none;
}

View file

@ -0,0 +1,7 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
.osm-map-box {
height: 300px;
width: 100%;
margin: 10px 0;
}

View file

@ -0,0 +1,77 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
.engine-stats {
.engine-name {
width: 20rem;
}
.engine-score {
width: 7rem;
text-align: right;
}
.engine-reliability {
text-align: right;
}
table.engine-error {
max-width: 1280px;
margin: 1rem;
border: 1px solid gray;
}
table.engine-error th.engine-error-type,
table.engine-error td.engine-error-type,
failed-test {
width: 10rem;
}
table.engine-error span.log_parameters {
border-right: 1px solid gray;
padding: 0 1rem 0 0;
margin: 0 0 0 0.5rem;
}
}
.bar-chart-value {
width: 3em;
display: inline-block;
text-align: right;
padding-right: 0.5rem;
}
.bar-chart-graph {
width: calc(100% - 5rem);
display: inline-block;
}
.bar-chart-bar {
border: 3px solid #5bc0de;
margin: 1px 0;
}
.bar-chart-serie1 {
border: 3px solid #5bc0de;
margin: 1px 0;
float: left;
}
.bar-chart-serie2 {
border: 3px solid #deb15b;
margin: 1px 0;
float: left;
}
.bar0 {
width: 0;
border: 0;
}
.generate-bar(100);
.generate-bar(@n, @i: 1) when (@i =< @n) {
.bar@{i} {
width: (@i * 100% / @n);
}
.generate-bar(@n, (@i + 1));
}

View file

@ -124,7 +124,7 @@
background-position-x: 100%; background-position-x: 100%;
} }
// patch of searx/static/themes/__common__/less/stats.less // patch of stats.less
.bar-chart-serie1, .bar-chart-serie1,
.bar-chart-serie2 { .bar-chart-serie2 {
float: right; float: right;

View file

@ -6,9 +6,6 @@
// stylelint-disable no-descending-specificity // stylelint-disable no-descending-specificity
@import "../../__common__/less/new_issue.less";
@import "../../__common__/less/stats.less";
@import "../../__common__/less/result_templates.less";
@import (inline) "../../node_modules/normalize.css/normalize.css"; @import (inline) "../../node_modules/normalize.css/normalize.css";
@import "definitions.less"; @import "definitions.less";
@import "mixins.less"; @import "mixins.less";
@ -19,6 +16,9 @@
@import "animations.less"; @import "animations.less";
@import "embedded.less"; @import "embedded.less";
@import "info.less"; @import "info.less";
@import "new_issue.less";
@import "stats.less";
@import "result_templates.less";
// for index.html template // for index.html template
@import "index.less"; @import "index.less";

View file

@ -2,7 +2,7 @@
<div id="search_header"> <div id="search_header">
<a id="search_logo" href="{{ url_for('index') }}" tabindex="0" title="{{ _('Display the front page') }}"> <a id="search_logo" href="{{ url_for('index') }}" tabindex="0" title="{{ _('Display the front page') }}">
<span hidden>SearXNG</span> <span hidden>SearXNG</span>
{% include '__common__/searxng-wordmark.min.svg' without context %} {% include 'simple/searxng-wordmark.min.svg' without context %}
</a> </a>
<div id="search_view"> <div id="search_view">
<div class="search_box"> <div class="search_box">

View file

Before

Width:  |  Height:  |  Size: 711 B

After

Width:  |  Height:  |  Size: 711 B

View file

@ -1,5 +1,5 @@
{% from 'simple/icons.html' import icon_big %} {% from 'simple/icons.html' import icon_big %}
{% from '__common__/new_issue.html' import new_issue with context %} {% from 'simple/new_issue.html' import new_issue with context %}
{% extends "simple/page_with_header.html" %} {% extends "simple/page_with_header.html" %}

View file

@ -17,7 +17,7 @@ from timeit import default_timer
from html import escape from html import escape
from io import StringIO from io import StringIO
import typing import typing
from typing import List, Dict, Iterable, Optional from typing import List, Dict, Iterable
import urllib import urllib
import urllib.parse import urllib.parse
@ -140,12 +140,6 @@ default_theme = settings['ui']['default_theme']
templates_path = settings['ui']['templates_path'] templates_path = settings['ui']['templates_path']
themes = get_themes(templates_path) themes = get_themes(templates_path)
result_templates = get_result_templates(templates_path) result_templates = get_result_templates(templates_path)
global_favicons = []
for indice, theme in enumerate(themes):
global_favicons.append([])
theme_img_path = os.path.join(settings['ui']['static_path'], 'themes', theme, 'img', 'icons')
for (dirpath, dirnames, filenames) in os.walk(theme_img_path):
global_favicons[indice].extend(filenames)
STATS_SORT_PARAMETERS = { STATS_SORT_PARAMETERS = {
'name': (False, 'name', ''), 'name': (False, 'name', ''),
@ -327,24 +321,6 @@ def code_highlighter(codelines, language=None):
return html_code return html_code
def get_current_theme_name(override: Optional[str] = None) -> str:
"""Returns theme name.
Checks in this order:
1. override
2. cookies
3. settings"""
if override and (override in themes or override == '__common__'):
return override
theme_name = request.args.get('theme', request.preferences.get_value('theme'))
if theme_name and theme_name in themes:
return theme_name
return default_theme
def get_result_template(theme_name: str, template_name: str): def get_result_template(theme_name: str, template_name: str):
themed_path = theme_name + '/result_templates/' + template_name themed_path = theme_name + '/result_templates/' + template_name
if themed_path in result_templates: if themed_path in result_templates:
@ -352,13 +328,13 @@ def get_result_template(theme_name: str, template_name: str):
return 'result_templates/' + template_name return 'result_templates/' + template_name
def custom_url_for(endpoint: str, override_theme: Optional[str] = None, **values): def custom_url_for(endpoint: str, **values):
suffix = "" suffix = ""
if endpoint == 'static' and values.get('filename'): if endpoint == 'static' and values.get('filename'):
file_hash = static_files.get(values['filename']) file_hash = static_files.get(values['filename'])
if not file_hash: if not file_hash:
# try file in the current theme # try file in the current theme
theme_name = get_current_theme_name(override=override_theme) theme_name = request.preferences.get_value('theme')
filename_with_theme = "themes/{}/{}".format(theme_name, values['filename']) filename_with_theme = "themes/{}/{}".format(theme_name, values['filename'])
file_hash = static_files.get(filename_with_theme) file_hash = static_files.get(filename_with_theme)
if file_hash: if file_hash:
@ -459,7 +435,7 @@ def get_client_settings():
} }
def render(template_name: str, override_theme: str = None, **kwargs): def render(template_name: str, **kwargs):
kwargs['client_settings'] = str( kwargs['client_settings'] = str(
base64.b64encode( base64.b64encode(
@ -471,12 +447,6 @@ def render(template_name: str, override_theme: str = None, **kwargs):
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 # values from the HTTP requests
kwargs['endpoint'] = 'results' if 'q' in kwargs else request.endpoint kwargs['endpoint'] = 'results' if 'q' in kwargs else request.endpoint
kwargs['cookies'] = request.cookies kwargs['cookies'] = request.cookies
@ -488,7 +458,7 @@ def render(template_name: str, override_theme: str = None, **kwargs):
kwargs['advanced_search'] = request.preferences.get_value('advanced_search') kwargs['advanced_search'] = request.preferences.get_value('advanced_search')
kwargs['query_in_title'] = request.preferences.get_value('query_in_title') kwargs['query_in_title'] = request.preferences.get_value('query_in_title')
kwargs['safesearch'] = str(request.preferences.get_value('safesearch')) kwargs['safesearch'] = str(request.preferences.get_value('safesearch'))
kwargs['theme'] = get_current_theme_name(override=override_theme) kwargs['theme'] = request.preferences.get_value('theme')
kwargs['categories_as_tabs'] = list(settings['categories_as_tabs'].keys()) kwargs['categories_as_tabs'] = list(settings['categories_as_tabs'].keys())
kwargs['categories'] = _get_enable_categories(categories.keys()) kwargs['categories'] = _get_enable_categories(categories.keys())
kwargs['OTHER_CATEGORY'] = OTHER_CATEGORY kwargs['OTHER_CATEGORY'] = OTHER_CATEGORY
@ -521,7 +491,14 @@ def render(template_name: str, override_theme: str = None, **kwargs):
kwargs['proxify_results'] = settings.get('result_proxy', {}).get('proxify_results', True) kwargs['proxify_results'] = settings.get('result_proxy', {}).get('proxify_results', True)
kwargs['get_result_template'] = get_result_template kwargs['get_result_template'] = get_result_template
kwargs['opensearch_url'] = ( kwargs['opensearch_url'] = (
url_for('opensearch') + '?' + urlencode({'method': kwargs['method'], 'autocomplete': kwargs['autocomplete']}) url_for('opensearch')
+ '?'
+ urlencode(
{
'method': request.preferences.get_value('method'),
'autocomplete': request.preferences.get_value('autocomplete'),
}
)
) )
# scripts from plugins # scripts from plugins
@ -648,7 +625,6 @@ def index_error(output_format: str, error_message: str):
q=request.form['q'] if 'q' in request.form else '', q=request.form['q'] if 'q' in request.form else '',
number_of_results=0, number_of_results=0,
error_message=error_message, error_message=error_message,
override_theme='__common__',
) )
return Response(response_rss, mimetype='text/xml') return Response(response_rss, mimetype='text/xml')
@ -841,7 +817,6 @@ def search():
suggestions=result_container.suggestions, suggestions=result_container.suggestions,
q=request.form['q'], q=request.form['q'],
number_of_results=number_of_results, number_of_results=number_of_results,
override_theme='__common__',
) )
return Response(response_rss, mimetype='text/xml') return Response(response_rss, mimetype='text/xml')
@ -886,8 +861,6 @@ def search():
settings['search']['languages'], settings['search']['languages'],
fallback=request.preferences.get_value("language") fallback=request.preferences.get_value("language")
), ),
theme = get_current_theme_name(),
favicons = global_favicons[themes.index(get_current_theme_name())],
timeout_limit = request.form.get('timeout_limit', None) timeout_limit = request.form.get('timeout_limit', None)
# fmt: on # fmt: on
) )
@ -984,8 +957,7 @@ def autocompleter():
suggestions = json.dumps([sug_prefix, results]) suggestions = json.dumps([sug_prefix, results])
mimetype = 'application/x-suggestions+json' mimetype = 'application/x-suggestions+json'
if get_current_theme_name() == 'simple': suggestions = escape(suggestions, False)
suggestions = escape(suggestions, False)
return Response(suggestions, mimetype=mimetype) return Response(suggestions, mimetype=mimetype)
@ -1132,7 +1104,6 @@ def preferences():
doi_resolvers = settings['doi_resolvers'], doi_resolvers = settings['doi_resolvers'],
current_doi_resolver = get_doi_resolver(request.preferences), current_doi_resolver = get_doi_resolver(request.preferences),
allowed_plugins = allowed_plugins, allowed_plugins = allowed_plugins,
theme = get_current_theme_name(),
preferences_url_params = request.preferences.get_as_url_params(), preferences_url_params = request.preferences.get_as_url_params(),
locked_preferences = settings['preferences']['lock'], locked_preferences = settings['preferences']['lock'],
preferences = True preferences = True
@ -1334,7 +1305,9 @@ def opensearch():
if request.headers.get('User-Agent', '').lower().find('webkit') >= 0: if request.headers.get('User-Agent', '').lower().find('webkit') >= 0:
method = 'get' method = 'get'
ret = render('opensearch.xml', opensearch_method=method, override_theme='__common__') autocomplete = request.preferences.get_value('autocomplete')
ret = render('opensearch.xml', opensearch_method=method, autocomplete=autocomplete)
resp = Response(response=ret, status=200, mimetype="application/opensearchdescription+xml") resp = Response(response=ret, status=200, mimetype="application/opensearchdescription+xml")
return resp return resp
@ -1342,8 +1315,9 @@ def opensearch():
@app.route('/favicon.ico') @app.route('/favicon.ico')
def favicon(): def favicon():
theme = request.preferences.get_value("theme")
return send_from_directory( return send_from_directory(
os.path.join(app.root_path, settings['ui']['static_path'], 'themes', get_current_theme_name(), 'img'), os.path.join(app.root_path, settings['ui']['static_path'], 'themes', theme, 'img'),
'favicon.png', 'favicon.png',
mimetype='image/vnd.microsoft.icon', mimetype='image/vnd.microsoft.icon',
) )

View file

@ -53,10 +53,7 @@ class UnicodeWriter:
def get_themes(templates_path): def get_themes(templates_path):
"""Returns available themes list.""" """Returns available themes list."""
themes = os.listdir(templates_path) return os.listdir(templates_path)
if '__common__' in themes:
themes.remove('__common__')
return themes
def get_hash_for_file(file: pathlib.Path) -> str: def get_hash_for_file(file: pathlib.Path) -> str:

View file

@ -7,6 +7,7 @@ from searx.results import Timing
import searx.search.processors import searx.search.processors
from searx.search import Search from searx.search import Search
from searx.preferences import Preferences
from tests import SearxTestCase from tests import SearxTestCase
@ -77,12 +78,14 @@ class ViewsTestCase(SearxTestCase):
self.setattr4test(Search, 'search', search_mock) self.setattr4test(Search, 'search', search_mock)
def get_current_theme_name_mock(override=None): original_preferences_get_value = Preferences.get_value
if override:
return override
return 'simple'
self.setattr4test(webapp, 'get_current_theme_name', get_current_theme_name_mock) def preferences_get_value(preferences_self, user_setting_name: str):
if user_setting_name == 'theme':
return 'simple'
return original_preferences_get_value(preferences_self, user_setting_name)
self.setattr4test(Preferences, 'get_value', preferences_get_value)
self.maxDiff = None # to see full diffs self.maxDiff = None # to see full diffs

View file

@ -8,7 +8,7 @@ STATIC_BUILT_PATHS=(
'searx/static/themes/simple/js' 'searx/static/themes/simple/js'
'searx/static/themes/simple/src/generated/pygments.less' 'searx/static/themes/simple/src/generated/pygments.less'
'searx/static/themes/simple/img' 'searx/static/themes/simple/img'
'searx/templates/__common__/searxng-wordmark.min.svg' 'searx/templates/simple/searxng-wordmark.min.svg'
'searx/templates/simple/icons.html' 'searx/templates/simple/icons.html'
) )