@@ -0,0 +1,238 @@
1+$(document).ready(function() {
6+ des: 'remove focus from the focused input',
11+ fun: searchInputFocus,
12+ des: 'focus on the search input',
17+ fun: scrollPage(-window.innerHeight),
18+ des: 'scroll one page up',
23+ fun: scrollPage(window.innerHeight),
24+ des: 'scroll one page down',
29+ fun: scrollPage(-window.innerHeight / 2),
30+ des: 'scroll half a page up',
35+ fun: scrollPage(window.innerHeight / 2),
36+ des: 'scroll half a page down',
41+ fun: scrollPageTo(-document.body.scrollHeight),
42+ des: 'scroll to the top of the page',
47+ fun: scrollPageTo(document.body.scrollHeight),
48+ des: 'scroll to the bottom of the page',
54+ des: 'select previous search result',
60+ des: 'select next search result',
65+ fun: pageButtonClick(0),
66+ des: 'go to previous page',
71+ fun: pageButtonClick(1),
72+ des: 'go to next page',
77+ fun: openResult(false),
78+ des: 'open search result',
83+ fun: openResult(true),
84+ des: 'open the result in a new tab',
90+ des: 'reload page from the server',
96+ des: 'toggle help window',
101+ $(document).keyup(function(e) {
102+ // check for modifiers so we don't break browser's hotkeys
103+ if (vimKeys.hasOwnProperty(e.keyCode)
109+ if (e.keyCode === 27) {
110+ if (e.target.tagName.toLowerCase() === 'input') {
111+ vimKeys[e.keyCode].fun();
114+ if (e.target === document.body) {
115+ vimKeys[e.keyCode].fun();
121+ function reloadPage() {
122+ document.location.reload(false);
125+ function removeFocus() {
126+ if (document.activeElement) {
127+ document.activeElement.blur();
131+ function pageButtonClick(num) {
133+ var buttons = $('div#pagination button[type="submit"]');
134+ if (buttons.length !== 2) {
135+ console.log('page navigation with this theme is not supported');
138+ if (num >= 0 && num < buttons.length) {
139+ buttons[num].click();
141+ console.log('pageButtonClick(): invalid argument');
146+ function scrollPage(amount) {
148+ window.scrollBy(0, amount);
152+ function scrollPageTo(position) {
154+ window.scrollTo(0, position);
158+ function searchInputFocus() {
159+ $('input#q').focus();
162+ function previousResult() {
165+ function nextResult() {
168+ function openResult(newTab) {
171+ function toggleHelp() {
172+ var helpPanel = $('#vim-hotkeys-help');
173+ if (helpPanel.length) {
174+ helpPanel.toggleClass('hidden');
178+ var categories = {};
180+ for (var k in vimKeys) {
181+ var key = vimKeys[k];
182+ categories[key.cat] = categories[key.cat] || [];
183+ categories[key.cat].push(key);
186+ var sorted = Object.keys(categories).sort(function(a, b) {
187+ return categories[b].length - categories[a].length;
190+ if (sorted.length === 0) {
194+ var html = '<div id="vim-hotkeys-help" class="well vim-hotkeys-help">';
195+ html += '<div class="container-fluid">';
197+ html += '<div class="row">';
198+ html += '<div class="col-sm-12">';
199+ html += '<h3>How to navigate searx with Vim-like hotkeys</h3>';
200+ html += '</div>'; // col-sm-12
201+ html += '</div>'; // row
203+ for (var i = 0; i < sorted.length; i++) {
204+ var cat = categories[sorted[i]];
206+ var lastCategory = i === (sorted.length - 1);
207+ var first = i % 2 === 0;
210+ html += '<div class="row">';
212+ html += '<div class="col-sm-' + (first && lastCategory ? 12 : 6) + '">';
214+ html += '<div class="panel panel-default">';
215+ html += '<div class="panel-heading">' + cat[0].cat + '</div>';
216+ html += '<div class="panel-body">';
217+ html += '<ul class="list-unstyled">';
219+ for (var cj in cat) {
220+ html += '<li><kbd>' + cat[cj].key + '</kbd> ' + cat[cj].des + '</li>';
224+ html += '</div>'; // panel-body
225+ html += '</div>'; // panel
226+ html += '</div>'; // col-sm-*
228+ if (!first || lastCategory) {
229+ html += '</div>'; // row
233+ html += '</div>'; // container-fluid
234+ html += '</div>'; // vim-hotkeys-help
236+ $('body').append(html);