1
0
mirror of https://github.com/searxng/searxng.git synced 2024-11-04 20:30:11 +01:00

Merge pull request #1186 from dalf/theme_remove_common

Theme: remove __common__ directories
This commit is contained in:
Alexandre Flament 2022-05-08 10:45:45 +02:00 committed by GitHub
commit 85c1c14fd7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 145 additions and 592 deletions

View File

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

View File

@ -8,6 +8,3 @@ description = gettext(
)
default_on = False
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));
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -44,7 +44,6 @@ module.exports = function (grunt) {
'svg4web.svgo.js',
'src/js/main/*.js',
'src/js/head/*.js',
'../__common__/js/*.js'
],
},
stylelint: {
@ -146,7 +145,7 @@ module.exports = function (grunt) {
svgo: ['--config', 'svg4web.svgo.js']
},
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/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%;
}
// patch of searx/static/themes/__common__/less/stats.less
// patch of stats.less
.bar-chart-serie1,
.bar-chart-serie2 {
float: right;

View File

@ -6,9 +6,6 @@
// 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 "definitions.less";
@import "mixins.less";
@ -19,6 +16,9 @@
@import "animations.less";
@import "embedded.less";
@import "info.less";
@import "new_issue.less";
@import "stats.less";
@import "result_templates.less";
// for index.html template
@import "index.less";

View File

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

View File

@ -17,7 +17,7 @@ from timeit import default_timer
from html import escape
from io import StringIO
import typing
from typing import List, Dict, Iterable, Optional
from typing import List, Dict, Iterable
import urllib
import urllib.parse
@ -140,12 +140,6 @@ default_theme = settings['ui']['default_theme']
templates_path = settings['ui']['templates_path']
themes = get_themes(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 = {
'name': (False, 'name', ''),
@ -327,24 +321,6 @@ def code_highlighter(codelines, language=None):
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):
themed_path = theme_name + '/result_templates/' + template_name
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
def custom_url_for(endpoint: str, override_theme: Optional[str] = None, **values):
def custom_url_for(endpoint: str, **values):
suffix = ""
if endpoint == 'static' and values.get('filename'):
file_hash = static_files.get(values['filename'])
if not file_hash:
# 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'])
file_hash = static_files.get(filename_with_theme)
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(
base64.b64encode(
@ -471,12 +447,6 @@ def render(template_name: str, override_theme: str = None, **kwargs):
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
@ -488,7 +458,7 @@ def render(template_name: str, override_theme: str = None, **kwargs):
kwargs['advanced_search'] = request.preferences.get_value('advanced_search')
kwargs['query_in_title'] = request.preferences.get_value('query_in_title')
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'] = _get_enable_categories(categories.keys())
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['get_result_template'] = get_result_template
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
@ -648,7 +625,6 @@ def index_error(output_format: str, error_message: str):
q=request.form['q'] if 'q' in request.form else '',
number_of_results=0,
error_message=error_message,
override_theme='__common__',
)
return Response(response_rss, mimetype='text/xml')
@ -841,7 +817,6 @@ def search():
suggestions=result_container.suggestions,
q=request.form['q'],
number_of_results=number_of_results,
override_theme='__common__',
)
return Response(response_rss, mimetype='text/xml')
@ -886,8 +861,6 @@ def search():
settings['search']['languages'],
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)
# fmt: on
)
@ -984,8 +957,7 @@ def autocompleter():
suggestions = json.dumps([sug_prefix, results])
mimetype = 'application/x-suggestions+json'
if get_current_theme_name() == 'simple':
suggestions = escape(suggestions, False)
suggestions = escape(suggestions, False)
return Response(suggestions, mimetype=mimetype)
@ -1132,7 +1104,6 @@ def preferences():
doi_resolvers = settings['doi_resolvers'],
current_doi_resolver = get_doi_resolver(request.preferences),
allowed_plugins = allowed_plugins,
theme = get_current_theme_name(),
preferences_url_params = request.preferences.get_as_url_params(),
locked_preferences = settings['preferences']['lock'],
preferences = True
@ -1334,7 +1305,9 @@ def opensearch():
if request.headers.get('User-Agent', '').lower().find('webkit') >= 0:
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")
return resp
@ -1342,8 +1315,9 @@ def opensearch():
@app.route('/favicon.ico')
def favicon():
theme = request.preferences.get_value("theme")
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',
mimetype='image/vnd.microsoft.icon',
)

View File

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

View File

@ -7,6 +7,7 @@ from searx.results import Timing
import searx.search.processors
from searx.search import Search
from searx.preferences import Preferences
from tests import SearxTestCase
@ -77,12 +78,14 @@ class ViewsTestCase(SearxTestCase):
self.setattr4test(Search, 'search', search_mock)
def get_current_theme_name_mock(override=None):
if override:
return override
return 'simple'
original_preferences_get_value = Preferences.get_value
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

View File

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