[mod] theme/simple: fmt/lint minor pass

*Safe* changes, no behaviour changes.

- Initial ES5 to ES2015+ conversion.
- Plenty of styling diff changes.
This commit is contained in:
Ivan Gabaldon
2025-06-28 10:19:15 +02:00
committed by Markus Heiser
parent a947d5b3cf
commit 95172213f6
13 changed files with 620 additions and 650 deletions
+219 -208
View File
@@ -1,14 +1,13 @@
/* SPDX-License-Identifier: AGPL-3.0-or-later */
/* global searxng */
searxng.ready(function () {
function isElementInDetail (el) {
searxng.ready(() => {
function isElementInDetail(el) {
while (el !== undefined) {
if (el.classList.contains('detail')) {
if (el.classList.contains("detail")) {
return true;
}
if (el.classList.contains('result')) {
if (el.classList.contains("result")) {
// we found a result, no need to go to the root of the document:
// el is not inside a <div class="detail"> element
return false;
@@ -18,9 +17,9 @@ searxng.ready(function () {
return false;
}
function getResultElement (el) {
function getResultElement(el) {
while (el !== undefined) {
if (el.classList.contains('result')) {
if (el.classList.contains("result")) {
return el;
}
el = el.parentNode;
@@ -28,14 +27,14 @@ searxng.ready(function () {
return undefined;
}
function isImageResult (resultElement) {
return resultElement && resultElement.classList.contains('result-images');
function isImageResult(resultElement) {
return resultElement && resultElement.classList.contains("result-images");
}
searxng.on('.result', 'click', function (e) {
searxng.on(".result", "click", function (e) {
if (!isElementInDetail(e.target)) {
highlightResult(this)(true, true);
let resultElement = getResultElement(e.target);
const resultElement = getResultElement(e.target);
if (isImageResult(resultElement)) {
e.preventDefault();
searxng.selectImage(resultElement);
@@ -43,166 +42,179 @@ searxng.ready(function () {
}
});
searxng.on('.result a', 'focus', function (e) {
if (!isElementInDetail(e.target)) {
let resultElement = getResultElement(e.target);
if (resultElement && resultElement.getAttribute("data-vim-selected") === null) {
highlightResult(resultElement)(true);
searxng.on(
".result a",
"focus",
(e) => {
if (!isElementInDetail(e.target)) {
const resultElement = getResultElement(e.target);
if (resultElement && resultElement.getAttribute("data-vim-selected") === null) {
highlightResult(resultElement)(true);
}
if (isImageResult(resultElement)) {
searxng.selectImage(resultElement);
}
}
if (isImageResult(resultElement)) {
searxng.selectImage(resultElement);
}
}
}, true);
},
true
);
/* common base for layouts */
var baseKeyBinding = {
'Escape': {
key: 'ESC',
Escape: {
key: "ESC",
fun: removeFocus,
des: 'remove focus from the focused input',
cat: 'Control'
des: "remove focus from the focused input",
cat: "Control"
},
'c': {
key: 'c',
c: {
key: "c",
fun: copyURLToClipboard,
des: 'copy url of the selected result to the clipboard',
cat: 'Results'
des: "copy url of the selected result to the clipboard",
cat: "Results"
},
'h': {
key: 'h',
h: {
key: "h",
fun: toggleHelp,
des: 'toggle help window',
cat: 'Other'
des: "toggle help window",
cat: "Other"
},
'i': {
key: 'i',
i: {
key: "i",
fun: searchInputFocus,
des: 'focus on the search input',
cat: 'Control'
des: "focus on the search input",
cat: "Control"
},
'n': {
key: 'n',
n: {
key: "n",
fun: GoToNextPage(),
des: 'go to next page',
cat: 'Results'
des: "go to next page",
cat: "Results"
},
'o': {
key: 'o',
o: {
key: "o",
fun: openResult(false),
des: 'open search result',
cat: 'Results'
des: "open search result",
cat: "Results"
},
'p': {
key: 'p',
p: {
key: "p",
fun: GoToPreviousPage(),
des: 'go to previous page',
cat: 'Results'
des: "go to previous page",
cat: "Results"
},
'r': {
key: 'r',
r: {
key: "r",
fun: reloadPage,
des: 'reload page from the server',
cat: 'Control'
des: "reload page from the server",
cat: "Control"
},
't': {
key: 't',
t: {
key: "t",
fun: openResult(true),
des: 'open the result in a new tab',
cat: 'Results'
},
des: "open the result in a new tab",
cat: "Results"
}
};
var keyBindingLayouts = {
"default": Object.assign(
{ /* SearXNG layout */
'ArrowLeft': {
key: '←',
fun: highlightResult('up'),
des: 'select previous search result',
cat: 'Results'
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),
ArrowRight: {
key: "→",
fun: highlightResult("down"),
des: "select next search result",
cat: "Results"
}
},
baseKeyBinding
),
'vim': Object.assign(
{ /* Vim-like Key Layout. */
'b': {
key: 'b',
vim: Object.assign(
{
/* Vim-like Key Layout. */
b: {
key: "b",
fun: scrollPage(-window.innerHeight),
des: 'scroll one page up',
cat: 'Navigation'
des: "scroll one page up",
cat: "Navigation"
},
'f': {
key: 'f',
f: {
key: "f",
fun: scrollPage(window.innerHeight),
des: 'scroll one page down',
cat: 'Navigation'
des: "scroll one page down",
cat: "Navigation"
},
'u': {
key: 'u',
u: {
key: "u",
fun: scrollPage(-window.innerHeight / 2),
des: 'scroll half a page up',
cat: 'Navigation'
des: "scroll half a page up",
cat: "Navigation"
},
'd': {
key: 'd',
d: {
key: "d",
fun: scrollPage(window.innerHeight / 2),
des: 'scroll half a page down',
cat: 'Navigation'
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'
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'
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'
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'
j: {
key: "j",
fun: highlightResult("down"),
des: "select next search result",
cat: "Results"
},
'y': {
key: 'y',
y: {
key: "y",
fun: copyURLToClipboard,
des: 'copy url of the selected result to the clipboard',
cat: 'Results'
},
}, baseKeyBinding)
}
des: "copy url of the selected result to the clipboard",
cat: "Results"
}
},
baseKeyBinding
)
};
var keyBindings = keyBindingLayouts[searxng.settings.hotkeys] || keyBindingLayouts.default;
searxng.on(document, "keydown", function (e) {
searxng.on(document, "keydown", (e) => {
// check for modifiers so we don't break browser's hotkeys
if (
Object.prototype.hasOwnProperty.call(keyBindings, e.key)
&& !e.ctrlKey && !e.altKey
&& !e.shiftKey && !e.metaKey
// biome-ignore lint/suspicious/noPrototypeBuiltins: FIXME: support for Chromium 93-87, Firefox 92-78, Safari 15.4-14
Object.prototype.hasOwnProperty.call(keyBindings, e.key) &&
!e.ctrlKey &&
!e.altKey &&
!e.shiftKey &&
!e.metaKey
) {
var tagName = e.target.tagName.toLowerCase();
if (e.key === 'Escape') {
if (e.key === "Escape") {
keyBindings[e.key].fun(e);
} else {
if (e.target === document.body || tagName === 'a' || tagName === 'button') {
if (e.target === document.body || tagName === "a" || tagName === "button") {
e.preventDefault();
keyBindings[e.key].fun();
}
@@ -210,13 +222,13 @@ searxng.ready(function () {
}
});
function highlightResult (which) {
return function (noScroll, keepFocus) {
var current = document.querySelector('.result[data-vim-selected]'),
function highlightResult(which) {
return (noScroll, keepFocus) => {
var current = document.querySelector(".result[data-vim-selected]"),
effectiveWhich = which;
if (current === null) {
// no selection : choose the first one
current = document.querySelector('.result');
current = document.querySelector(".result");
if (current === null) {
// no first one : there are no results
return;
@@ -227,48 +239,50 @@ searxng.ready(function () {
}
}
var next, results = document.querySelectorAll('.result');
results = Array.from(results); // convert NodeList to Array for further use
var next,
results = document.querySelectorAll(".result");
results = Array.from(results); // convert NodeList to Array for further use
if (typeof effectiveWhich !== 'string') {
if (typeof effectiveWhich !== "string") {
next = effectiveWhich;
} else {
switch (effectiveWhich) {
case 'visible':
var top = document.documentElement.scrollTop || document.body.scrollTop;
var bot = top + document.documentElement.clientHeight;
case "visible": {
var top = document.documentElement.scrollTop || document.body.scrollTop;
var bot = top + document.documentElement.clientHeight;
for (var i = 0; i < results.length; i++) {
next = results[i];
var etop = next.offsetTop;
var ebot = etop + next.clientHeight;
for (var i = 0; i < results.length; i++) {
next = results[i];
var etop = next.offsetTop;
var ebot = etop + next.clientHeight;
if ((ebot <= bot) && (etop > top)) {
break;
if (ebot <= bot && etop > top) {
break;
}
}
break;
}
break;
case 'down':
next = results[results.indexOf(current) + 1] || current;
break;
case 'up':
next = results[results.indexOf(current) - 1] || current;
break;
case 'bottom':
next = results[results.length - 1];
break;
case 'top':
case "down":
next = results[results.indexOf(current) + 1] || current;
break;
case "up":
next = results[results.indexOf(current) - 1] || current;
break;
case "bottom":
next = results[results.length - 1];
break;
case "top":
/* falls through */
default:
next = results[0];
default:
next = results[0];
}
}
if (next) {
current.removeAttribute('data-vim-selected');
next.setAttribute('data-vim-selected', 'true');
current.removeAttribute("data-vim-selected");
next.setAttribute("data-vim-selected", "true");
if (!keepFocus) {
var link = next.querySelector('h3 a') || next.querySelector('a');
var link = next.querySelector("h3 a") || next.querySelector("a");
if (link !== null) {
link.focus();
}
@@ -280,21 +294,21 @@ searxng.ready(function () {
};
}
function reloadPage () {
function reloadPage() {
document.location.reload(true);
}
function removeFocus (e) {
function removeFocus(e) {
const tagName = e.target.tagName.toLowerCase();
if (document.activeElement && (tagName === 'input' || tagName === 'select' || tagName === 'textarea')) {
if (document.activeElement && (tagName === "input" || tagName === "select" || tagName === "textarea")) {
document.activeElement.blur();
} else {
searxng.closeDetail();
}
}
function pageButtonClick (css_selector) {
return function () {
function pageButtonClick(css_selector) {
return () => {
var button = document.querySelector(css_selector);
if (button) {
button.click();
@@ -302,16 +316,16 @@ searxng.ready(function () {
};
}
function GoToNextPage () {
function GoToNextPage() {
return pageButtonClick('nav#pagination .next_page button[type="submit"]');
}
function GoToPreviousPage () {
function GoToPreviousPage() {
return pageButtonClick('nav#pagination .previous_page button[type="submit"]');
}
function scrollPageToSelected () {
var sel = document.querySelector('.result[data-vim-selected]');
function scrollPageToSelected() {
var sel = document.querySelector(".result[data-vim-selected]");
if (sel === null) {
return;
}
@@ -321,39 +335,39 @@ searxng.ready(function () {
ebot = etop + sel.clientHeight,
offset = 120;
// first element ?
if ((sel.previousElementSibling === null) && (ebot < wheight)) {
if (sel.previousElementSibling === null && ebot < wheight) {
// set to the top of page if the first element
// is fully included in the viewport
window.scroll(window.scrollX, 0);
return;
}
if (wtop > (etop - offset)) {
if (wtop > etop - offset) {
window.scroll(window.scrollX, etop - offset);
} else {
var wbot = wtop + wheight;
if (wbot < (ebot + offset)) {
if (wbot < ebot + offset) {
window.scroll(window.scrollX, ebot - wheight + offset);
}
}
}
function scrollPage (amount) {
return function () {
function scrollPage(amount) {
return () => {
window.scrollBy(0, amount);
highlightResult('visible')();
highlightResult("visible")();
};
}
function scrollPageTo (position, nav) {
return function () {
function scrollPageTo(position, nav) {
return () => {
window.scrollTo(0, position);
highlightResult(nav)();
};
}
function searchInputFocus () {
function searchInputFocus() {
window.scrollTo(0, 0);
var q = document.querySelector('#q');
var q = document.querySelector("#q");
q.focus();
if (q.setSelectionRange) {
var len = q.value.length;
@@ -361,14 +375,14 @@ searxng.ready(function () {
}
}
function openResult (newTab) {
return function () {
var link = document.querySelector('.result[data-vim-selected] h3 a');
function openResult(newTab) {
return () => {
var link = document.querySelector(".result[data-vim-selected] h3 a");
if (link === null) {
link = document.querySelector('.result[data-vim-selected] > a');
link = document.querySelector(".result[data-vim-selected] > a");
}
if (link !== null) {
var url = link.getAttribute('href');
var url = link.getAttribute("href");
if (newTab) {
window.open(url);
} else {
@@ -378,7 +392,7 @@ searxng.ready(function () {
};
}
function initHelpContent (divElement) {
function initHelpContent(divElement) {
var categories = {};
for (var k in keyBindings) {
@@ -387,75 +401,72 @@ searxng.ready(function () {
categories[key.cat].push(key);
}
var sorted = Object.keys(categories).sort(function (a, b) {
return categories[b].length - categories[a].length;
});
var sorted = Object.keys(categories).sort((a, b) => categories[b].length - categories[a].length);
if (sorted.length === 0) {
return;
}
var html = '<a href="#" class="close" aria-label="close" title="close">×</a>';
html += '<h3>How to navigate SearXNG with hotkeys</h3>';
html += '<table>';
html += "<h3>How to navigate SearXNG with hotkeys</h3>";
html += "<table>";
for (var i = 0; i < sorted.length; i++) {
var cat = categories[sorted[i]];
var lastCategory = i === (sorted.length - 1);
var lastCategory = i === sorted.length - 1;
var first = i % 2 === 0;
if (first) {
html += '<tr>';
html += "<tr>";
}
html += '<td>';
html += "<td>";
html += '<h4>' + cat[0].cat + '</h4>';
html += "<h4>" + cat[0].cat + "</h4>";
html += '<ul class="list-unstyled">';
for (var cj in cat) {
html += '<li><kbd>' + cat[cj].key + '</kbd> ' + cat[cj].des + '</li>';
html += "<li><kbd>" + cat[cj].key + "</kbd> " + cat[cj].des + "</li>";
}
html += '</ul>';
html += '</td>'; // col-sm-*
html += "</ul>";
html += "</td>"; // col-sm-*
if (!first || lastCategory) {
html += '</tr>'; // row
html += "</tr>"; // row
}
}
html += '</table>';
html += "</table>";
divElement.innerHTML = html;
}
function toggleHelp () {
var helpPanel = document.querySelector('#vim-hotkeys-help');
function toggleHelp() {
var helpPanel = document.querySelector("#vim-hotkeys-help");
if (helpPanel === undefined || helpPanel === null) {
// first call
helpPanel = document.createElement('div');
helpPanel.id = 'vim-hotkeys-help';
helpPanel.className = 'dialog-modal';
helpPanel = document.createElement("div");
helpPanel.id = "vim-hotkeys-help";
helpPanel.className = "dialog-modal";
initHelpContent(helpPanel);
var body = document.getElementsByTagName('body')[0];
var body = document.getElementsByTagName("body")[0];
body.appendChild(helpPanel);
} else {
// toggle hidden
helpPanel.classList.toggle('invisible');
return;
helpPanel.classList.toggle("invisible");
}
}
function copyURLToClipboard () {
var currentUrlElement = document.querySelector('.result[data-vim-selected] h3 a');
function copyURLToClipboard() {
var currentUrlElement = document.querySelector(".result[data-vim-selected] h3 a");
if (currentUrlElement === null) return;
const url = currentUrlElement.getAttribute('href');
const url = currentUrlElement.getAttribute("href");
navigator.clipboard.writeText(url);
}
searxng.scrollPageToSelected = scrollPageToSelected;
searxng.selectNext = highlightResult('down');
searxng.selectPrevious = highlightResult('up');
searxng.selectNext = highlightResult("down");
searxng.selectPrevious = highlightResult("up");
});