mirror of https://github.com/searxng/searxng.git
theme: remove __common__
This commit is contained in:
parent
6db568bf69
commit
9b3efa6d8a
|
@ -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',)
|
|
||||||
|
|
|
@ -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',)
|
|
||||||
|
|
|
@ -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+ */
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
.osm-map-box {
|
|
||||||
height:300px;
|
|
||||||
width:100%;
|
|
||||||
margin: 10px 0;
|
|
||||||
}
|
|
|
@ -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));
|
|
||||||
}
|
|
|
@ -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'
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
.osm-map-box {
|
||||||
|
height: 300px;
|
||||||
|
width: 100%;
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
|
@ -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));
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
|
@ -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";
|
||||||
|
|
|
@ -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">
|
||||||
|
|
Before Width: | Height: | Size: 711 B After Width: | Height: | Size: 711 B |
|
@ -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" %}
|
||||||
|
|
||||||
|
|
|
@ -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',
|
||||||
)
|
)
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue