mirror of https://github.com/searxng/searxng.git
[mod] improve handling of the hotkeys
- KeyboardEvent: keyCode property is depricated, replaced by key property [2] - the check for ifDetailOpened is not necessary, because the hotkeys are not only applicable to image-results, by example: `!goi !go !scc hello` - Key bindings like h for help are to be used in general (not only in vim-mode) [1] https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode [2] https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
This commit is contained in:
parent
e6b160da62
commit
a987672340
|
@ -57,118 +57,118 @@ searxng.ready(function () {
|
||||||
|
|
||||||
// these bindings are always on
|
// these bindings are always on
|
||||||
var keyBindings = {
|
var keyBindings = {
|
||||||
27: {
|
'Escape': {
|
||||||
key: 'Escape',
|
key: 'ESC',
|
||||||
fun: removeFocus,
|
fun: removeFocus,
|
||||||
des: 'remove focus from the focused input',
|
des: 'remove focus from the focused input',
|
||||||
cat: 'Control'
|
cat: 'Control'
|
||||||
},
|
},
|
||||||
37: {
|
'ArrowLeft': {
|
||||||
key: 'Left',
|
key: '⬅',
|
||||||
fun: ifDetailOpened(highlightResult('up')),
|
fun: highlightResult('up'),
|
||||||
des: 'select previous search result',
|
des: 'Use left arrow to select previous search result',
|
||||||
cat: 'Results'
|
cat: 'Results'
|
||||||
},
|
},
|
||||||
39: {
|
'ArrowRight': {
|
||||||
key: 'Right',
|
key: '➡',
|
||||||
fun: ifDetailOpened(highlightResult('down')),
|
fun: highlightResult('down'),
|
||||||
des: 'select next search result',
|
des: 'Use right arrow to select next search result',
|
||||||
cat: 'Results'
|
cat: 'Results'
|
||||||
}
|
},
|
||||||
}
|
'h': {
|
||||||
|
key: 'h',
|
||||||
// these bindings are enabled by user preferences
|
fun: toggleHelp,
|
||||||
var vimKeys = {
|
des: 'toggle help window',
|
||||||
73: {
|
cat: 'Other'
|
||||||
|
},
|
||||||
|
'i': {
|
||||||
key: 'i',
|
key: 'i',
|
||||||
fun: searchInputFocus,
|
fun: searchInputFocus,
|
||||||
des: 'focus on the search input',
|
des: 'focus on the search input',
|
||||||
cat: 'Control'
|
cat: 'Control'
|
||||||
},
|
},
|
||||||
66: {
|
'n': {
|
||||||
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: GoToPreviousPage(),
|
|
||||||
des: 'go to previous page',
|
|
||||||
cat: 'Results'
|
|
||||||
},
|
|
||||||
78: {
|
|
||||||
key: 'n',
|
key: 'n',
|
||||||
fun: GoToNextPage(),
|
fun: GoToNextPage(),
|
||||||
des: 'go to next page',
|
des: 'go to next page',
|
||||||
cat: 'Results'
|
cat: 'Results'
|
||||||
},
|
},
|
||||||
79: {
|
'o': {
|
||||||
key: 'o',
|
key: 'o',
|
||||||
fun: openResult(false),
|
fun: openResult(false),
|
||||||
des: 'open search result',
|
des: 'open search result',
|
||||||
cat: 'Results'
|
cat: 'Results'
|
||||||
},
|
},
|
||||||
84: {
|
'p': {
|
||||||
key: 't',
|
key: 'p',
|
||||||
fun: openResult(true),
|
fun: GoToPreviousPage(),
|
||||||
des: 'open the result in a new tab',
|
des: 'go to previous page',
|
||||||
cat: 'Results'
|
cat: 'Results'
|
||||||
},
|
},
|
||||||
82: {
|
'r': {
|
||||||
key: 'r',
|
key: 'r',
|
||||||
fun: reloadPage,
|
fun: reloadPage,
|
||||||
des: 'reload page from the server',
|
des: 'reload page from the server',
|
||||||
cat: 'Control'
|
cat: 'Control'
|
||||||
},
|
},
|
||||||
72: {
|
't': {
|
||||||
key: 'h',
|
key: 't',
|
||||||
fun: toggleHelp,
|
fun: openResult(true),
|
||||||
des: 'toggle help window',
|
des: 'open the result in a new tab',
|
||||||
cat: 'Other'
|
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'
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (searxng.settings.hotkeys) {
|
if (searxng.settings.hotkeys) {
|
||||||
|
@ -178,27 +178,23 @@ searxng.ready(function () {
|
||||||
|
|
||||||
searxng.on(document, "keydown", function (e) {
|
searxng.on(document, "keydown", function (e) {
|
||||||
// check for modifiers so we don't break browser's hotkeys
|
// check for modifiers so we don't break browser's hotkeys
|
||||||
if (Object.prototype.hasOwnProperty.call(keyBindings, e.keyCode) && !e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey) {
|
if (
|
||||||
|
Object.prototype.hasOwnProperty.call(keyBindings, e.key)
|
||||||
|
&& !e.ctrlKey && !e.altKey
|
||||||
|
&& !e.shiftKey && !e.metaKey
|
||||||
|
) {
|
||||||
var tagName = e.target.tagName.toLowerCase();
|
var tagName = e.target.tagName.toLowerCase();
|
||||||
if (e.keyCode === 27) {
|
if (e.key === 'Escape') {
|
||||||
keyBindings[e.keyCode].fun(e);
|
keyBindings[e.key].fun(e);
|
||||||
} else {
|
} else {
|
||||||
if (e.target === document.body || tagName === 'a' || tagName === 'button') {
|
if (e.target === document.body || tagName === 'a' || tagName === 'button') {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
keyBindings[e.keyCode].fun();
|
keyBindings[e.key].fun();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function ifDetailOpened (f) {
|
|
||||||
return function () {
|
|
||||||
if (searxng.isDetailOpened()) {
|
|
||||||
f();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function highlightResult (which) {
|
function highlightResult (which) {
|
||||||
return function (noScroll, keepFocus) {
|
return function (noScroll, keepFocus) {
|
||||||
var current = document.querySelector('.result[data-vim-selected]'),
|
var current = document.querySelector('.result[data-vim-selected]'),
|
||||||
|
@ -390,7 +386,7 @@ searxng.ready(function () {
|
||||||
}
|
}
|
||||||
|
|
||||||
var html = '<a href="#" class="close" aria-label="close" title="close">×</a>';
|
var html = '<a href="#" class="close" aria-label="close" title="close">×</a>';
|
||||||
html += '<h3>How to navigate searx with Vim-like hotkeys</h3>';
|
html += '<h3>How to navigate SearXNG with hotkeys</h3>';
|
||||||
html += '<table>';
|
html += '<table>';
|
||||||
|
|
||||||
for (var i = 0; i < sorted.length; i++) {
|
for (var i = 0; i < sorted.length; i++) {
|
||||||
|
@ -432,8 +428,6 @@ searxng.ready(function () {
|
||||||
helpPanel.id = 'vim-hotkeys-help';
|
helpPanel.id = 'vim-hotkeys-help';
|
||||||
helpPanel.className = 'dialog-modal';
|
helpPanel.className = 'dialog-modal';
|
||||||
initHelpContent(helpPanel);
|
initHelpContent(helpPanel);
|
||||||
initHelpContent(helpPanel);
|
|
||||||
initHelpContent(helpPanel);
|
|
||||||
var body = document.getElementsByTagName('body')[0];
|
var body = document.getElementsByTagName('body')[0];
|
||||||
body.appendChild(helpPanel);
|
body.appendChild(helpPanel);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -74,10 +74,6 @@
|
||||||
searxng.scrollPageToSelected();
|
searxng.scrollPageToSelected();
|
||||||
}
|
}
|
||||||
|
|
||||||
searxng.isDetailOpened = function () {
|
|
||||||
return d.getElementById('results').classList.contains('image-detail-open');
|
|
||||||
}
|
|
||||||
|
|
||||||
searxng.closeDetail = function (e) {
|
searxng.closeDetail = function (e) {
|
||||||
d.getElementById('results').classList.remove('image-detail-open');
|
d.getElementById('results').classList.remove('image-detail-open');
|
||||||
searxng.scrollPageToSelected();
|
searxng.scrollPageToSelected();
|
||||||
|
|
Loading…
Reference in New Issue