Merge pull request 'Fix error with searx language + update to latest searx static and template files' (#11) from meazdev into main

Reviewed-on: #11
This commit is contained in:
meaz 2023-11-15 09:10:59 +00:00
commit a90c65ad27
23 changed files with 299 additions and 144 deletions

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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -55,26 +55,14 @@ searxng.ready(function () {
}
}, true);
// these bindings are always on
var keyBindings = {
/* common base for layouts */
var baseKeyBinding = {
'Escape': {
key: 'ESC',
fun: removeFocus,
des: 'remove focus from the focused input',
cat: 'Control'
},
'ArrowLeft': {
key: '⬅',
fun: highlightResult('up'),
des: 'Use left arrow to select previous search result',
cat: 'Results'
},
'ArrowRight': {
key: '➡',
fun: highlightResult('down'),
des: 'Use right arrow to select next search result',
cat: 'Results'
},
'h': {
key: 'h',
fun: toggleHelp,
@ -117,65 +105,80 @@ searxng.ready(function () {
des: 'open the result in a new tab',
cat: 'Results'
},
}
// these bindings are enabled by user preferences
var vimKeys = {
'b': {
key: 'b',
fun: scrollPage(-window.innerHeight),
des: 'scroll one page up',
cat: 'Navigation'
},
'f': {
key: 'f',
fun: scrollPage(window.innerHeight),
des: 'scroll one page down',
cat: 'Navigation'
},
'u': {
key: 'u',
fun: scrollPage(-window.innerHeight / 2),
des: 'scroll half a page up',
cat: 'Navigation'
},
'd': {
key: 'd',
fun: scrollPage(window.innerHeight / 2),
des: 'scroll half a page down',
cat: 'Navigation'
},
'g': {
key: 'g',
fun: scrollPageTo(-document.body.scrollHeight, 'top'),
des: 'scroll to the top of the page',
cat: 'Navigation'
},
'v': {
key: 'v',
fun: scrollPageTo(document.body.scrollHeight, 'bottom'),
des: 'scroll to the bottom of the page',
cat: 'Navigation'
},
'k': {
key: 'k',
fun: highlightResult('up'),
des: 'select previous search result',
cat: 'Results'
},
'j': {
key: 'j',
fun: highlightResult('down'),
des: 'select next search result',
cat: 'Results'
},
};
var keyBindingLayouts = {
if (searxng.settings.hotkeys) {
// To add Vim-like key bindings, merge the 'vimKeys' into 'keyBindings'.
Object.assign(keyBindings, vimKeys);
"default": Object.assign(
{ /* SearXNG layout */
'ArrowLeft': {
key: '←',
fun: highlightResult('up'),
des: 'select previous search result',
cat: 'Results'
},
'ArrowRight': {
key: '→',
fun: highlightResult('down'),
des: 'select next search result',
cat: 'Results'
},
}, baseKeyBinding),
'vim': Object.assign(
{ /* Vim-like Key Layout. */
'b': {
key: 'b',
fun: scrollPage(-window.innerHeight),
des: 'scroll one page up',
cat: 'Navigation'
},
'f': {
key: 'f',
fun: scrollPage(window.innerHeight),
des: 'scroll one page down',
cat: 'Navigation'
},
'u': {
key: 'u',
fun: scrollPage(-window.innerHeight / 2),
des: 'scroll half a page up',
cat: 'Navigation'
},
'd': {
key: 'd',
fun: scrollPage(window.innerHeight / 2),
des: 'scroll half a page down',
cat: 'Navigation'
},
'g': {
key: 'g',
fun: scrollPageTo(-document.body.scrollHeight, 'top'),
des: 'scroll to the top of the page',
cat: 'Navigation'
},
'v': {
key: 'v',
fun: scrollPageTo(document.body.scrollHeight, 'bottom'),
des: 'scroll to the bottom of the page',
cat: 'Navigation'
},
'k': {
key: 'k',
fun: highlightResult('up'),
des: 'select previous search result',
cat: 'Results'
},
'j': {
key: 'j',
fun: highlightResult('down'),
des: 'select next search result',
cat: 'Results'
},
}, baseKeyBinding)
}
var keyBindings = keyBindingLayouts[searxng.settings.hotkeys] || keyBindingLayouts.default;
searxng.on(document, "keydown", function (e) {
// check for modifiers so we don't break browser's hotkeys
if (

View file

@ -16,6 +16,10 @@
}
));
if (d.querySelector('#search_url button#copy_url')) {
d.querySelector('#search_url button#copy_url').style.display = "block";
}
searxng.on('.btn-collapse', 'click', function () {
var btnLabelCollapsed = this.getAttribute('data-btn-text-collapsed');
var btnLabelNotCollapsed = this.getAttribute('data-btn-text-not-collapsed');
@ -41,6 +45,12 @@
}
});
searxng.on('#copy_url', 'click', function () {
var target = this.parentElement.querySelector('pre');
navigator.clipboard.writeText(target.innerText);
this.innerText = this.dataset.copiedText;
});
searxng.selectImage = function (resultElement) {
/* eslint no-unused-vars: 0 */
if (resultElement) {

View file

@ -150,29 +150,37 @@
}
}
// vanilla js version of search_on_category_select.js
if (qinput !== null && d.querySelector('.help') != null && searxng.settings.search_on_category_select) {
d.querySelector('.help').className = 'invisible';
searxng.on('#categories input', 'change', function () {
var i, categories = d.querySelectorAll('#categories input[type="checkbox"]');
for (i = 0; i < categories.length; i++) {
if (categories[i] !== this && categories[i].checked) {
categories[i].click();
}
}
if (! this.checked) {
this.click();
}
submitIfQuery();
return false;
});
// Additionally to searching when selecting a new category, we also
// automatically start a new search request when the user changes a search
// filter (safesearch, time range or language) (this requires JavaScript
// though)
if (
qinput !== null
&& searxng.settings.search_on_category_select
// If .search_filters is undefined (invisible) we are on the homepage and
// hence don't have to set any listeners
&& d.querySelector(".search_filters") != null
) {
searxng.on(d.getElementById('safesearch'), 'change', submitIfQuery);
searxng.on(d.getElementById('time_range'), 'change', submitIfQuery);
searxng.on(d.getElementById('language'), 'change', submitIfQuery);
}
// most common browsers at the time of writing this support :has, except for Firefox
// can be removed when Firefox / Firefox ESL starts supporting it as well
try {
// this fails when the browser does not support :has
d.querySelector("html:has(body)");
} catch (_) {
// manually deselect the old selection when a new category is selected
for (let button of d.querySelectorAll("button.category_button")) {
searxng.on(button, 'click', () => {
const selected = d.querySelector("button.category_button.selected");
console.log(selected);
selected.classList.remove("selected");
})
}
}
});
})(window, document, window.searxng);

View file

@ -5,12 +5,14 @@
:root {
--disroot-white: #ddd;
--color-btn-font: #ddd;
/* background colors */
--disroot-lightmode: #ddd;
--disroot-darkmode: hsl(225, 16%, 15%); //#1f222b;
--disroot-darkmode-light: hsl(225, 15%, 20%); //#2b2f3b //#2a2e3a;
--disroot-darkmode-lighter: hsl(227, 14%, 25%); //#383c4a;
/* primary color light theme*/
/* primary color light theme */
//--primary-l-h: 336;
//--primary-l-s: 57%;
//--primary-l-l: 20%;
@ -20,17 +22,18 @@
//--disroot-red-even-lighter: hsl(var(--primary-l-h), calc(var(--primary-l-s) - 29%), calc(var(--primary-l-l) + 43%));
--disroot-red: hsl(336, 57%, 20%); //#50162d;
--disroot-red-light: hsl(336, 43%, 27%); //#61273e;
--disroot-red-lighter: hsl(336, 34%, 33%); //#72384f;
--disroot-red-even-lighter: hsl(336, 28%, 64%); //#bd899e;
/* primary color dark theme*/
--disroot-red-lighter: hsl(336, 34%, 33%); //#72384f;
--disroot-red-even-lighter: hsl(336, 28%, 64%); //#bd899e;
/* primary color dark theme */
--disroot-green: hsl(77, 66%, 43%); //#8eb726;
--disroot-green-lighter: hsl(77, 54%, 59%); //#afcf60;
--disroot-green-even-lighter: hsl(77, 45%, 73%); //#c8d99b;
--disroot-green-darker: hsl(77, 66%, 34%); //#71911e;
/* secondary color */
--disroot-blueish: hsl(184, 51%, 25%); //#1f5c60;
--disroot-blueish-lighter: hsl(184, 30%, 44%); //#4f8f93;
--color-url-font: var(--disroot-green);
--color-url-visited-font: var(--disroot-blueish);
--color-header-background: var(--disroot-red-light);
@ -69,11 +72,17 @@
--color-search-background-hover: var(--disroot-red-lighter);
}
@results-margin: 0.325rem;
// Category color
.category label {
// Category color
//.category label {
// color: var(--color-btn-font);
//}
button.category_button {
color: var(--color-btn-font);
}
// Navbar links in right corner only on results page
// (needed when using disroot color as navbar background)
.results_endpoint #links_on_top a,
@ -83,6 +92,7 @@
.results_endpoint #links_on_top a:visited * {
color: #fff !important;
}
.result {
background-color: var(--color-result-background);
border-radius: 2px;
@ -99,9 +109,9 @@
fill: var(--disroot-red-even-lighter);
}
#categories_container {
//background-color: var(--disroot-red);
}
// #categories_container {
// background-color: var(--disroot-red);
// }
//Search box
.search_box {
@ -110,9 +120,9 @@
}
//Cache link
.cache_link:visited {
//.cache_link:visited {
// color: var(--disroot-red);
}
//}
//Logo
.index {
@ -180,4 +190,4 @@
&:hover {
filter: grayscale(1);
}
}
}

View file

@ -23,12 +23,15 @@
"spacer categories";
}
.category {
.category_checkbox,
.category_button {
display: inline-block;
position: relative;
.ltr-margin-right(1rem);
padding: 0;
}
.category_checkbox {
input {
display: none;
}
@ -57,7 +60,37 @@
}
}
button.category_button {
background-color: inherit;
color: var(--color-base-font);
cursor: pointer;
padding: 0.2rem 0;
display: inline-flex;
align-items: center;
text-transform: capitalize;
font-size: 0.9em;
border: none;
border-bottom: 2px solid transparent;
svg {
padding-right: 0.2rem;
}
&.selected,
&:active,
&:focus-within {
color: var(--color-categories-item-selected-font);
border-bottom: 2px solid var(--color-categories-item-border-selected);
}
}
#categories_container:has(button.category_button:focus-within) button.category_button.selected {
color: var(--color-base-font);
border-bottom: none;
}
#search_logo {
padding: 0.5rem 10px 0 10px;
grid-area: logo;
display: flex;
align-items: center;
@ -90,7 +123,12 @@
}
#search_view {
padding: 0.5rem 0.3rem 0 0.5rem;
grid-area: search;
body.results_endpoint & {
padding: 0.5rem 2.8rem 0 0;
}
}
.search_box {
@ -205,11 +243,6 @@ html.no-js #clear_search.hide_if_nojs {
#categories {
font-size: 90%;
clear: both;
.checkbox_container {
margin: auto;
margin-top: 2px;
}
}
}
@ -219,7 +252,7 @@ html.no-js #clear_search.hide_if_nojs {
#categories_container {
width: max-content;
.category {
.category_checkbox {
display: inline-block;
width: auto;
}
@ -254,7 +287,6 @@ html.no-js #clear_search.hide_if_nojs {
.search_box {
width: 98%;
display: flex;
margin: 0 auto;
}
#q {
@ -263,7 +295,8 @@ html.no-js #clear_search.hide_if_nojs {
}
.search_filters {
margin: 0;
margin: 0 10px;
padding: 0.5rem 0;
}
.category {
@ -271,16 +304,23 @@ html.no-js #clear_search.hide_if_nojs {
width: auto;
margin: 0;
svg {
display: none;
}
}
.category_checkbox {
label {
padding: 1rem !important;
margin: 0 !important;
svg {
display: none;
}
}
}
.category_button {
padding: 1rem !important;
margin: 0 !important;
}
#search_view:focus-within {
display: block;
background-color: var(--color-search-background);

View file

@ -522,8 +522,7 @@ article[data-vim-selected].category-social {
"pagination sidebar";
}
#results #sidebar *:first-child,
#results #urls *:first-child {
#results #sidebar *:first-child {
margin-top: 0;
}
@ -731,16 +730,25 @@ summary.title {
#search_url {
div.selectable_url {
pre {
float: left;
width: 200em;
}
}
button#copy_url {
float: right;
padding: 0.4rem;
margin-left: 0.5rem;
border-radius: 0.3rem;
display: none; // will be shown by JS.
}
}
#links_on_top {
position: absolute;
.ltr-right(1.8rem);
.ltr-right(1rem);
.ltr-text-align-right();
top: 2.2rem;
top: 2.7rem;
padding: 0;
border: 0;
display: flex;
@ -920,7 +928,7 @@ summary.title {
}
#main_results div#results {
margin: 1rem auto 0 auto;
margin: 0 auto;
justify-content: center;
display: grid;
grid-template-columns: @results-width;
@ -1017,12 +1025,12 @@ summary.title {
#main_results div#results {
grid-template-columns: 100%;
margin: 1rem 0 0 0;
margin: 0 auto;
}
#links_on_top {
top: 0.8rem;
.ltr-right(0.7rem);
top: 1.4rem;
.ltr-right(10px);
}
#main_index #links_on_top {
@ -1046,7 +1054,9 @@ summary.title {
.result {
background: var(--color-result-background);
margin: 1rem 0;
border: 1px solid var(--color-result-background);
margin: 1rem 10px;
.rounded-corners;
}
.result-images {

View file

@ -176,6 +176,15 @@ div.selectable_url {
border-color: var(--color-error);
}
.dialog-error-block {
.dialog();
display: block;
color: var(--color-error);
background: var(--color-error-background);
border-color: var(--color-error);
}
.dialog-warning {
.dialog();

View file

@ -17,7 +17,7 @@
{% else %}
<link rel="stylesheet" href="{{ url_for('static', filename='css/searxng.min.css') }}" type="text/css" media="screen" />
{% endif %}
{% if get_setting('server.limiter') %}
{% if get_setting('server.limiter') or get_setting('server.public_instance') %}
<link rel="stylesheet" href="{{ url_for('client_token', token=link_token) }}" type="text/css" />
{% endif %}
{% block styles %}{% endblock %}

View file

@ -13,14 +13,25 @@
} -%}
<div id="categories" class="search_categories">{{- '' -}}
<div id="categories_container">
{%- for category in categories -%}
<div class="category"><input type="checkbox" id="checkbox_{{ category|replace(' ', '_') }}" name="category_{{ category }}"{% if category in selected_categories %} checked="checked"{% endif %}/>
<label for="checkbox_{{ category|replace(' ', '_') }}" class="tooltips">
{{- icon_big(category_icons[category]) if category in category_icons else icon_big('globe-outline') -}}
<div class="category_name">{{- _(category) -}}</div>
</label>
</div>
{%- endfor -%}
{%- if display_tooltip %}<div class="help">{{ _('Click on the magnifier to perform search') }}</div>{% endif -%}
{%- if not search_on_category_select or not display_tooltip -%}
{%- for category in categories_as_tabs -%}
<div class="category category_checkbox">{{- '' -}}
<input type="checkbox" id="checkbox_{{ category|replace(' ', '_') }}" name="category_{{ category }}"{% if category in selected_categories %} checked="checked"{% endif %}/>
<label for="checkbox_{{ category|replace(' ', '_') }}" class="tooltips">
{{- icon_big(category_icons[category]) if category in category_icons else icon_big('globe-outline') -}}
<div class="category_name">{{- _(category) -}}</div>
</label>
</div>
{%- endfor -%}
{%- if display_tooltip %}<div class="help">{{ _('Click on the magnifier to perform search') }}</div>{% endif -%}
{%- else -%}
{%- for category in categories_as_tabs -%}{{- '\n' -}}
<button type="submit" name="category_{{ category }}" class="category category_button {% if category in selected_categories %}selected{% endif %}">
{{- icon_big(category_icons[category]) if category in category_icons else icon_big('globe-outline') -}}
<div class="category_name">{{- _(category) -}}</div>{{- '' -}}
</button>{{- '' -}}
{%- endfor -%}
{{- '\n' -}}
{%- endif -%}
</div>{{- '' -}}
</div>

View file

@ -1,5 +1,9 @@
<div id="engines_msg">
{% if not results and not answers %}
<details class="sidebar-collapsable" open>
{% else %}
<details class="sidebar-collapsable">
{% endif %}
<summary class="title" id="engines_msg-title">{{ _('Messages from the search engines') }}</summary>
<div class="dialog-error" role="alert">
{{ icon_big('warning') }}

View file

@ -1,6 +1,7 @@
<div id="search_url" role="complementary" aria-labelledby="search_url-title">
<details class="sidebar-collapsable">
<summary class="title" id="search_url-title">{{ _('Search URL') }}</summary>
<button id="copy_url" type="submit" data-copied-text="{{ _('Copied') }}">{{ _('Copy') }}</button>
<div class="selectable_url">
<pre>{{ url_for('search', _external=True) }}?q={{ q|urlencode }}&amp;language={{ current_language }}&amp;time_range={{ time_range }}&amp;safesearch={{ safesearch }}
{%- if pageno > 1 -%}

View file

@ -1,5 +1,11 @@
{% from 'beetroot/icons.html' import icon_big %}
<div class="dialog-error" role="alert">
<div class="dialog-error-block" role="alert">
<p><strong>{{ _('Sorry!') }}</strong></p>
<p>{{ _("we didn't find any results. Please use another query or search in more categories.") }}</p>
<p>{{ _("No results were found. You can try to:") }}</p>
<ul>
<li>{{ _("Refresh the page.") }}</li>
<li>{{ _("Search for another query or select another category (above).") }}</li>
<li>{{ _("Change the search engine used in the preferences:") }} <a href="/preferences">/preferences</a></li>
<li>{{ _("Switch to another instance:") }} <a href="https://searx.space">https://searx.space</a></li>
</ul>
</div>

View file

@ -108,7 +108,7 @@
{%- endmacro -%}
{%- macro engine_reliability(engine_name) -%}
{%- set r = reliabilities.get(engine_name, {}).get('reliablity', None) -%}
{%- set r = reliabilities.get(engine_name, {}).get('reliability', None) -%}
{%- set checker_result = reliabilities.get(engine_name, {}).get('checker', []) -%}
{%- set errors = reliabilities.get(engine_name, {}).get('errors', []) -%}
{%- if r != None -%}
@ -197,6 +197,10 @@
{%- if 'infinite_scroll' not in locked_preferences -%}
{%- include 'beetroot/preferences/infinite_scroll.html' -%}
{%- endif -%}
{%- if 'search_on_category_select' not in locked_preferences -%}
{%- include 'beetroot/preferences/search_on_category_select.html' -%}
{%- endif -%}
{%- include 'beetroot/preferences/hotkeys.html' -%}
{{- plugin_preferences('ui') -}}
{{- tab_footer() -}}

View file

@ -0,0 +1,23 @@
<fieldset>{{- '' -}}
<legend id="pref_hotkeys">{{- _('Hotkeys') -}}</legend>{{- '' -}}
<div class="value">{{- '' -}}
<select name="hotkeys" aria-labelledby="pref_hotkeys">{{- '' -}}
<option value="default"
{%- if hotkeys == 'default' %} selected="selected"
{%- endif -%}>
SearXNG{{- '' -}}
</option>{{- '' -}}
<option value="vim"
{%- if hotkeys == 'vim' %} selected="selected"
{%- endif -%}>
{{- _('Vim-like') -}}
</option>{{- '' -}}
</select>{{- '' -}}
</div>{{- '' -}}
<div class="description">
{{- _(
'Navigate search results with hotkeys (JavaScript required). '
'Press "h" key on main or result page to get help.'
) -}}
</div>{{- '' -}}
</fieldset>{{- '' -}}

View file

@ -0,0 +1,16 @@
<fieldset>{{- '' -}}
<legend>{{ _('Search on category select') }}</legend>{{- '' -}}
<p class="value">{{- '' -}}
<input type="checkbox" {{- ' ' -}}
name="search_on_category_select" {{- ' ' -}}
aria-labelledby="pref_search_on_category_select" {{- ' ' -}}
class="checkbox-onoff" {{- ' ' -}}
{%- if preferences.get_value('search_on_category_select') -%}
checked
{%- endif -%}{{- ' ' -}}
/>{{- '' -}}
</p>{{- '' -}}
<div class="description">
{{- _('Perform search immediately if a category selected. Disable to select multiple categories') -}}
</div>{{- '' -}}
</fieldset>{{- '' -}}

View file

@ -8,7 +8,7 @@
<div class="search_box">
<input id="q" name="q" type="text" placeholder="{{ _('Search for...') }}" tabindex="1" autocomplete="off" autocapitalize="none" spellcheck="false" autocorrect="off" dir="auto" value="{{ q or '' }}">
<button id="clear_search" type="reset" aria-label="{{ _('clear') }}" class="hide_if_nojs"><span>{{ icon_big('close') }}</span><span class="show_if_nojs">{{ _('clear') }}</span></button>
<button id="send_search" type="submit" aria-label="{{ _('search') }}"><span class="hide_if_nojs">{{ icon_big('search-outline') }}</span><span class="show_if_nojs">{{ _('search') }}</span></button>
<button id="send_search" type="submit" {%- if search_on_category_select -%}name="category_{{ selected_categories[0]|replace(' ', '_') }}"{%- endif -%} aria-label="{{ _('search') }}"><span class="hide_if_nojs">{{ icon_big('search-outline') }}</span><span class="show_if_nojs">{{ _('search') }}</span></button>
</div>
</div>
{% set display_tooltip = true %}

View file

@ -82,7 +82,7 @@
</div>
{%- endif -%}
</td>
<td class="engine-reliability"> {{ engine_reliabilities.get(engine_stat.name, {}).get('reliablity') }}</td>
<td class="engine-reliability"> {{ engine_reliabilities.get(engine_stat.name, {}).get('reliability') }}</td>
</tr>
{% endfor %}
</table>