mirror of
				https://github.com/searxng/searxng.git
				synced 2025-11-03 19:17:07 -05:00 
			
		
		
		
	theme: remove __common__
This commit is contained in:
		
							parent
							
								
									6db568bf69
								
							
						
					
					
						commit
						9b3efa6d8a
					
				@ -22,5 +22,3 @@ description = gettext(
 | 
			
		||||
)
 | 
			
		||||
default_on = True
 | 
			
		||||
preference_section = 'ui'
 | 
			
		||||
 | 
			
		||||
js_dependencies = ('plugins/js/search_on_category_select.js',)
 | 
			
		||||
 | 
			
		||||
@ -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',)
 | 
			
		||||
 | 
			
		||||
@ -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',
 | 
			
		||||
        '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'
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										21
									
								
								searx/static/themes/simple/src/less/new_issue.less
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								searx/static/themes/simple/src/less/new_issue.less
									
									
									
									
									
										Normal 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;
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,7 @@
 | 
			
		||||
// SPDX-License-Identifier: AGPL-3.0-or-later
 | 
			
		||||
 | 
			
		||||
.osm-map-box {
 | 
			
		||||
  height: 300px;
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  margin: 10px 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										77
									
								
								searx/static/themes/simple/src/less/stats.less
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								searx/static/themes/simple/src/less/stats.less
									
									
									
									
									
										Normal 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));
 | 
			
		||||
}
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
@ -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";
 | 
			
		||||
 | 
			
		||||
@ -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">
 | 
			
		||||
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 711 B After Width: | Height: | Size: 711 B  | 
@ -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" %}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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,7 +957,6 @@ def autocompleter():
 | 
			
		||||
        suggestions = json.dumps([sug_prefix, results])
 | 
			
		||||
        mimetype = 'application/x-suggestions+json'
 | 
			
		||||
 | 
			
		||||
    if get_current_theme_name() == 'simple':
 | 
			
		||||
    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',
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
@ -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:
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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'
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user