Browse Source

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

*Not so safe* changes, no behaviour changes.

- More ES5 to ES2015+ conversion.
- Make Biome not cry anymore applying remaining changes.
Ivan Gabaldon 1 week ago
parent
commit
879ac4e60f

+ 6 - 6
client/simple/src/js/head/00_init.js

@@ -1,12 +1,12 @@
 /* SPDX-License-Identifier: AGPL-3.0-or-later */
 ((w, d) => {
   // add data- properties
-  var script =
-    d.currentScript ||
-    (() => {
-      var scripts = d.getElementsByTagName("script");
-      return scripts[scripts.length - 1];
-    })();
+  const getLastScriptElement = () => {
+    const scripts = d.getElementsByTagName("script");
+    return scripts[scripts.length - 1];
+  };
+
+  const script = d.currentScript || getLastScriptElement();
 
   w.searxng = {
     settings: JSON.parse(atob(script.getAttribute("client_settings")))

+ 26 - 16
client/simple/src/js/main/00_toolkit.js

@@ -17,8 +17,8 @@ window.searxng = ((w, d) => {
         ElementPrototype.webkitMatchesSelector ||
         ElementPrototype.msMatchesSelector ||
         function (selector) {
-          var nodes = (this.parentNode || this.document).querySelectorAll(selector),
-            i = -1;
+          const nodes = (this.parentNode || this.document).querySelectorAll(selector);
+          let i = -1;
           while (nodes[++i] && nodes[i] !== this);
           return !!nodes[i];
         };
@@ -33,7 +33,7 @@ window.searxng = ((w, d) => {
     }
   }
 
-  var searxng = window.searxng || {};
+  const searxng = window.searxng || {};
 
   searxng.on = (obj, eventType, callback, useCapture) => {
     useCapture = useCapture || false;
@@ -45,10 +45,20 @@ window.searxng = ((w, d) => {
       d.addEventListener(
         eventType,
         (e) => {
-          var el = e.target || e.srcElement,
-            found = false;
-          while (el?.matches && el !== d && !(found = el.matches(obj))) el = el.parentElement;
-          if (found) callbackSafe(callback, el, e);
+          let el = e.target || e.srcElement;
+          let found = false;
+
+          while (el?.matches && el !== d) {
+            found = el.matches(obj);
+
+            if (found) break;
+
+            el = el.parentElement;
+          }
+
+          if (found) {
+            callbackSafe(callback, el, e);
+          }
         },
         useCapture
       );
@@ -66,7 +76,7 @@ window.searxng = ((w, d) => {
   searxng.http = (method, url, data = null) =>
     new Promise((resolve, reject) => {
       try {
-        var req = new XMLHttpRequest();
+        const req = new XMLHttpRequest();
         req.open(method, url, true);
         req.timeout = 20000;
 
@@ -104,9 +114,9 @@ window.searxng = ((w, d) => {
     });
 
   searxng.loadStyle = (src) => {
-    var path = searxng.settings.theme_static_path + "/" + src,
-      id = "style_" + src.replace(".", "_"),
-      s = d.getElementById(id);
+    const path = `${searxng.settings.theme_static_path}/${src}`;
+    const id = `style_${src.replace(".", "_")}`;
+    let s = d.getElementById(id);
     if (s === null) {
       s = d.createElement("link");
       s.setAttribute("id", id);
@@ -118,9 +128,9 @@ window.searxng = ((w, d) => {
   };
 
   searxng.loadScript = (src, callback) => {
-    var path = searxng.settings.theme_static_path + "/" + src,
-      id = "script_" + src.replace(".", "_"),
-      s = d.getElementById(id);
+    const path = `${searxng.settings.theme_static_path}/${src}`;
+    const id = `script_${src.replace(".", "_")}`;
+    let s = d.getElementById(id);
     if (s === null) {
       s = d.createElement("script");
       s.setAttribute("id", id);
@@ -137,7 +147,7 @@ window.searxng = ((w, d) => {
         console.log(exception);
       }
     } else {
-      console.log("callback not executed : script '" + path + "' not loaded.");
+      console.log(`callback not executed : script '${path}' not loaded.`);
     }
   };
 
@@ -154,7 +164,7 @@ window.searxng = ((w, d) => {
   });
 
   function getEndpoint() {
-    for (var className of d.getElementsByTagName("body")[0].classList.values()) {
+    for (const className of d.getElementsByTagName("body")[0].classList.values()) {
       if (className.endsWith("_endpoint")) {
         return className.split("_")[0];
       }

+ 8 - 8
client/simple/src/js/main/infinite_scroll.js

@@ -18,10 +18,10 @@ searxng.ready(() => {
   }
 
   const d = document;
-  var onlyImages = d.getElementById("results").classList.contains("only_template_images");
+  const onlyImages = d.getElementById("results").classList.contains("only_template_images");
 
   function newLoadSpinner() {
-    var loader = d.createElement("div");
+    const loader = d.createElement("div");
     loader.classList.add("loader");
     return loader;
   }
@@ -32,18 +32,18 @@ searxng.ready(() => {
   }
 
   function loadNextPage(callback) {
-    var form = d.querySelector("#pagination form.next_page");
+    const form = d.querySelector("#pagination form.next_page");
     if (!form) {
       return;
     }
     replaceChildrenWith(d.querySelector("#pagination"), [newLoadSpinner()]);
-    var formData = new FormData(form);
+    const formData = new FormData(form);
     searxng
       .http("POST", d.querySelector("#search").getAttribute("action"), formData)
       .then((response) => {
-        var nextPageDoc = new DOMParser().parseFromString(response, "text/html");
-        var articleList = nextPageDoc.querySelectorAll("#urls article");
-        var paginationElement = nextPageDoc.querySelector("#pagination");
+        const nextPageDoc = new DOMParser().parseFromString(response, "text/html");
+        const articleList = nextPageDoc.querySelectorAll("#urls article");
+        const paginationElement = nextPageDoc.querySelector("#pagination");
         d.querySelector("#pagination").remove();
         if (articleList.length > 0 && !onlyImages) {
           // do not add <hr> element when there are only images
@@ -59,7 +59,7 @@ searxng.ready(() => {
       })
       .catch((err) => {
         console.log(err);
-        var e = d.createElement("div");
+        const e = d.createElement("div");
         e.textContent = searxng.settings.translations.error_loading_next_page;
         e.classList.add("dialog-error");
         e.setAttribute("role", "alert");

+ 37 - 36
client/simple/src/js/main/keyboard.js

@@ -28,7 +28,7 @@ searxng.ready(() => {
   }
 
   function isImageResult(resultElement) {
-    return resultElement && resultElement.classList.contains("result-images");
+    return resultElement?.classList.contains("result-images");
   }
 
   searxng.on(".result", "click", function (e) {
@@ -60,7 +60,7 @@ searxng.ready(() => {
   );
 
   /* common base for layouts */
-  var baseKeyBinding = {
+  const baseKeyBinding = {
     Escape: {
       key: "ESC",
       fun: removeFocus,
@@ -116,7 +116,7 @@ searxng.ready(() => {
       cat: "Results"
     }
   };
-  var keyBindingLayouts = {
+  const keyBindingLayouts = {
     default: Object.assign(
       {
         /* SearXNG layout */
@@ -198,7 +198,7 @@ searxng.ready(() => {
     )
   };
 
-  var keyBindings = keyBindingLayouts[searxng.settings.hotkeys] || keyBindingLayouts.default;
+  const keyBindings = keyBindingLayouts[searxng.settings.hotkeys] || keyBindingLayouts.default;
 
   searxng.on(document, "keydown", (e) => {
     // check for modifiers so we don't break browser's hotkeys
@@ -210,7 +210,7 @@ searxng.ready(() => {
       !e.shiftKey &&
       !e.metaKey
     ) {
-      var tagName = e.target.tagName.toLowerCase();
+      const tagName = e.target.tagName.toLowerCase();
       if (e.key === "Escape") {
         keyBindings[e.key].fun(e);
       } else {
@@ -224,7 +224,7 @@ searxng.ready(() => {
 
   function highlightResult(which) {
     return (noScroll, keepFocus) => {
-      var current = document.querySelector(".result[data-vim-selected]"),
+      let current = document.querySelector(".result[data-vim-selected]"),
         effectiveWhich = which;
       if (current === null) {
         // no selection : choose the first one
@@ -239,7 +239,7 @@ searxng.ready(() => {
         }
       }
 
-      var next,
+      let next,
         results = document.querySelectorAll(".result");
       results = Array.from(results); // convert NodeList to Array for further use
 
@@ -248,13 +248,13 @@ searxng.ready(() => {
       } else {
         switch (effectiveWhich) {
           case "visible": {
-            var top = document.documentElement.scrollTop || document.body.scrollTop;
-            var bot = top + document.documentElement.clientHeight;
+            const top = document.documentElement.scrollTop || document.body.scrollTop;
+            const bot = top + document.documentElement.clientHeight;
 
-            for (var i = 0; i < results.length; i++) {
+            for (let i = 0; i < results.length; i++) {
               next = results[i];
-              var etop = next.offsetTop;
-              var ebot = etop + next.clientHeight;
+              const etop = next.offsetTop;
+              const ebot = etop + next.clientHeight;
 
               if (ebot <= bot && etop > top) {
                 break;
@@ -271,6 +271,7 @@ searxng.ready(() => {
           case "bottom":
             next = results[results.length - 1];
             break;
+          // biome-ignore lint/complexity/noUselessSwitchCase: fallthrough is intended
           case "top":
           /* falls through */
           default:
@@ -282,7 +283,7 @@ searxng.ready(() => {
         current.removeAttribute("data-vim-selected");
         next.setAttribute("data-vim-selected", "true");
         if (!keepFocus) {
-          var link = next.querySelector("h3 a") || next.querySelector("a");
+          const link = next.querySelector("h3 a") || next.querySelector("a");
           if (link !== null) {
             link.focus();
           }
@@ -309,7 +310,7 @@ searxng.ready(() => {
 
   function pageButtonClick(css_selector) {
     return () => {
-      var button = document.querySelector(css_selector);
+      const button = document.querySelector(css_selector);
       if (button) {
         button.click();
       }
@@ -325,11 +326,11 @@ searxng.ready(() => {
   }
 
   function scrollPageToSelected() {
-    var sel = document.querySelector(".result[data-vim-selected]");
+    const sel = document.querySelector(".result[data-vim-selected]");
     if (sel === null) {
       return;
     }
-    var wtop = document.documentElement.scrollTop || document.body.scrollTop,
+    const wtop = document.documentElement.scrollTop || document.body.scrollTop,
       wheight = document.documentElement.clientHeight,
       etop = sel.offsetTop,
       ebot = etop + sel.clientHeight,
@@ -344,7 +345,7 @@ searxng.ready(() => {
     if (wtop > etop - offset) {
       window.scroll(window.scrollX, etop - offset);
     } else {
-      var wbot = wtop + wheight;
+      const wbot = wtop + wheight;
       if (wbot < ebot + offset) {
         window.scroll(window.scrollX, ebot - wheight + offset);
       }
@@ -367,22 +368,22 @@ searxng.ready(() => {
 
   function searchInputFocus() {
     window.scrollTo(0, 0);
-    var q = document.querySelector("#q");
+    const q = document.querySelector("#q");
     q.focus();
     if (q.setSelectionRange) {
-      var len = q.value.length;
+      const len = q.value.length;
       q.setSelectionRange(len, len);
     }
   }
 
   function openResult(newTab) {
     return () => {
-      var link = document.querySelector(".result[data-vim-selected] h3 a");
+      let link = document.querySelector(".result[data-vim-selected] h3 a");
       if (link === null) {
         link = document.querySelector(".result[data-vim-selected] > a");
       }
       if (link !== null) {
-        var url = link.getAttribute("href");
+        const url = link.getAttribute("href");
         if (newTab) {
           window.open(url);
         } else {
@@ -393,40 +394,40 @@ searxng.ready(() => {
   }
 
   function initHelpContent(divElement) {
-    var categories = {};
+    const categories = {};
 
-    for (var k in keyBindings) {
-      var key = keyBindings[k];
+    for (const k in keyBindings) {
+      const key = keyBindings[k];
       categories[key.cat] = categories[key.cat] || [];
       categories[key.cat].push(key);
     }
 
-    var sorted = Object.keys(categories).sort((a, b) => categories[b].length - categories[a].length);
+    const 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>';
+    let html = '<a href="#" class="close" aria-label="close" title="close">×</a>';
     html += "<h3>How to navigate SearXNG with hotkeys</h3>";
     html += "<table>";
 
-    for (var i = 0; i < sorted.length; i++) {
-      var cat = categories[sorted[i]];
+    for (let i = 0; i < sorted.length; i++) {
+      const cat = categories[sorted[i]];
 
-      var lastCategory = i === sorted.length - 1;
-      var first = i % 2 === 0;
+      const lastCategory = i === sorted.length - 1;
+      const first = i % 2 === 0;
 
       if (first) {
         html += "<tr>";
       }
       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>";
+      for (const cj in cat) {
+        html += `<li><kbd>${cat[cj].key}</kbd> ${cat[cj].des}</li>`;
       }
 
       html += "</ul>";
@@ -443,14 +444,14 @@ searxng.ready(() => {
   }
 
   function toggleHelp() {
-    var helpPanel = document.querySelector("#vim-hotkeys-help");
+    let 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";
       initHelpContent(helpPanel);
-      var body = document.getElementsByTagName("body")[0];
+      const body = document.getElementsByTagName("body")[0];
       body.appendChild(helpPanel);
     } else {
       // toggle hidden
@@ -459,7 +460,7 @@ searxng.ready(() => {
   }
 
   function copyURLToClipboard() {
-    var currentUrlElement = document.querySelector(".result[data-vim-selected] h3 a");
+    const currentUrlElement = document.querySelector(".result[data-vim-selected] h3 a");
     if (currentUrlElement === null) return;
 
     const url = currentUrlElement.getAttribute("href");

+ 20 - 20
client/simple/src/js/main/mapresult.js

@@ -1,38 +1,38 @@
 /* SPDX-License-Identifier: AGPL-3.0-or-later */
 /* global L */
-((w, d, searxng) => {
+((_w, _d, searxng) => {
   searxng.ready(() => {
     searxng.on(".searxng_init_map", "click", function (event) {
       // no more request
       this.classList.remove("searxng_init_map");
 
       //
-      var leaflet_target = this.dataset.leafletTarget;
-      var map_lon = parseFloat(this.dataset.mapLon);
-      var map_lat = parseFloat(this.dataset.mapLat);
-      var map_zoom = parseFloat(this.dataset.mapZoom);
-      var map_boundingbox = JSON.parse(this.dataset.mapBoundingbox);
-      var map_geojson = JSON.parse(this.dataset.mapGeojson);
+      const leaflet_target = this.dataset.leafletTarget;
+      const map_lon = parseFloat(this.dataset.mapLon);
+      const map_lat = parseFloat(this.dataset.mapLat);
+      const map_zoom = parseFloat(this.dataset.mapZoom);
+      const map_boundingbox = JSON.parse(this.dataset.mapBoundingbox);
+      const map_geojson = JSON.parse(this.dataset.mapGeojson);
 
       searxng.loadStyle("css/leaflet.css");
       searxng.loadScript("js/leaflet.js", () => {
-        var map_bounds = null;
+        let map_bounds = null;
         if (map_boundingbox) {
-          var southWest = L.latLng(map_boundingbox[0], map_boundingbox[2]);
-          var northEast = L.latLng(map_boundingbox[1], map_boundingbox[3]);
+          const southWest = L.latLng(map_boundingbox[0], map_boundingbox[2]);
+          const northEast = L.latLng(map_boundingbox[1], map_boundingbox[3]);
           map_bounds = L.latLngBounds(southWest, northEast);
         }
 
         // init map
-        var map = L.map(leaflet_target);
+        const map = L.map(leaflet_target);
         // create the tile layer with correct attribution
-        var osmMapnikUrl = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png";
-        var osmMapnikAttrib = 'Map data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors';
-        var osmMapnik = new L.TileLayer(osmMapnikUrl, { minZoom: 1, maxZoom: 19, attribution: osmMapnikAttrib });
-        var osmWikimediaUrl = "https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}.png";
-        var osmWikimediaAttrib =
+        const osmMapnikUrl = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png";
+        const osmMapnikAttrib = 'Map data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors';
+        const osmMapnik = new L.TileLayer(osmMapnikUrl, { minZoom: 1, maxZoom: 19, attribution: osmMapnikAttrib });
+        const osmWikimediaUrl = "https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}.png";
+        const osmWikimediaAttrib =
           'Wikimedia maps | Maps data © <a href="https://openstreetmap.org">OpenStreetMap contributors</a>';
-        var osmWikimedia = new L.TileLayer(osmWikimediaUrl, {
+        const osmWikimedia = new L.TileLayer(osmWikimediaUrl, {
           minZoom: 1,
           maxZoom: 19,
           attribution: osmWikimediaAttrib
@@ -48,15 +48,15 @@
           }, 0);
         } else if (map_lon && map_lat) {
           if (map_zoom) {
-            map.setView(new L.latLng(map_lat, map_lon), map_zoom);
+            map.setView(new L.LatLng(map_lat, map_lon), map_zoom);
           } else {
-            map.setView(new L.latLng(map_lat, map_lon), 8);
+            map.setView(new L.LatLng(map_lat, map_lon), 8);
           }
         }
 
         map.addLayer(osmMapnik);
 
-        var baseLayers = {
+        const baseLayers = {
           "OSM Mapnik": osmMapnik,
           "OSM Wikimedia": osmWikimedia
         };

+ 3 - 3
client/simple/src/js/main/preferences.js

@@ -1,5 +1,5 @@
 /* SPDX-License-Identifier: AGPL-3.0-or-later */
-((w, d, searxng) => {
+((_w, d, searxng) => {
   if (searxng.endpoint !== "preferences") {
     return;
   }
@@ -12,9 +12,9 @@
         searxng.http("GET", "engine_descriptions.json").then((content) => {
           engine_descriptions = JSON.parse(content);
           for (const [engine_name, description] of Object.entries(engine_descriptions)) {
-            const elements = d.querySelectorAll('[data-engine-name="' + engine_name + '"] .engine-description');
+            const elements = d.querySelectorAll(`[data-engine-name="${engine_name}"] .engine-description`);
             for (const element of elements) {
-              const source = " (<i>" + searxng.settings.translations.Source + ":&nbsp;" + description[1] + "</i>)";
+              const source = ` (<i>${searxng.settings.translations.Source}:&nbsp;${description[1]}</i>)`;
               element.innerHTML = description[0] + source;
             }
           }

+ 11 - 11
client/simple/src/js/main/results.js

@@ -13,7 +13,7 @@ import "../../../node_modules/swiped-events/src/swiped-events.js";
         "error",
         () => {
           // console.log("ERROR can't load: " + img.src);
-          img.src = window.searxng.settings.theme_static_path + "/img/img_load_error.svg";
+          img.src = `${window.searxng.settings.theme_static_path}/img/img_load_error.svg`;
         },
         { once: true }
       )
@@ -24,11 +24,11 @@ import "../../../node_modules/swiped-events/src/swiped-events.js";
     }
 
     searxng.on(".btn-collapse", "click", function () {
-      var btnLabelCollapsed = this.getAttribute("data-btn-text-collapsed");
-      var btnLabelNotCollapsed = this.getAttribute("data-btn-text-not-collapsed");
-      var target = this.getAttribute("data-target");
-      var targetElement = d.querySelector(target);
-      var html = this.innerHTML;
+      const btnLabelCollapsed = this.getAttribute("data-btn-text-collapsed");
+      const btnLabelNotCollapsed = this.getAttribute("data-btn-text-not-collapsed");
+      const target = this.getAttribute("data-target");
+      const targetElement = d.querySelector(target);
+      let html = this.innerHTML;
       if (this.classList.contains("collapsed")) {
         html = html.replace(btnLabelCollapsed, btnLabelNotCollapsed);
       } else {
@@ -40,16 +40,16 @@ import "../../../node_modules/swiped-events/src/swiped-events.js";
     });
 
     searxng.on(".media-loader", "click", function () {
-      var target = this.getAttribute("data-target");
-      var iframe_load = d.querySelector(target + " > iframe");
-      var srctest = iframe_load.getAttribute("src");
+      const target = this.getAttribute("data-target");
+      const iframe_load = d.querySelector(`${target} > iframe`);
+      const srctest = iframe_load.getAttribute("src");
       if (srctest === null || srctest === undefined || srctest === false) {
         iframe_load.setAttribute("src", iframe_load.getAttribute("data-src"));
       }
     });
 
     searxng.on("#copy_url", "click", function () {
-      var target = this.parentElement.querySelector("pre");
+      const target = this.parentElement.querySelector("pre");
       navigator.clipboard.writeText(target.innerText);
       this.innerText = this.dataset.copiedText;
     });
@@ -165,7 +165,7 @@ import "../../../node_modules/swiped-events/src/swiped-events.js";
     w.addEventListener(
       "scroll",
       () => {
-        var e = d.getElementById("backToTop"),
+        const e = d.getElementById("backToTop"),
           scrollTop = document.documentElement.scrollTop || document.body.scrollTop,
           results = d.getElementById("results");
         if (e !== null) {

+ 7 - 7
client/simple/src/js/main/search.js

@@ -1,23 +1,23 @@
 /* SPDX-License-Identifier: AGPL-3.0-or-later */
 /* exported AutoComplete */
 
-((w, d, searxng) => {
-  var qinput_id = "q",
-    qinput;
+((_w, d, searxng) => {
+  const qinput_id = "q";
+  let qinput;
 
   const isMobile = window.matchMedia("only screen and (max-width: 50em)").matches;
   const isResultsPage = document.querySelector("main").id === "main_results";
 
   function submitIfQuery() {
     if (qinput.value.length > 0) {
-      var search = document.getElementById("search");
+      const search = document.getElementById("search");
       setTimeout(search.submit.bind(search), 0);
     }
   }
 
   function createClearButton(qinput) {
-    var cs = document.getElementById("clear_search");
-    var updateClearButton = () => {
+    const cs = document.getElementById("clear_search");
+    const updateClearButton = () => {
       if (qinput.value.length === 0) {
         cs.classList.add("empty");
       } else {
@@ -41,7 +41,7 @@
     if (searxng.settings.method === "GET") {
       const reqParams = new URLSearchParams();
       reqParams.append("q", query);
-      request = fetch("./autocompleter?" + reqParams.toString());
+      request = fetch(`./autocompleter?${reqParams.toString()}`);
     } else {
       const formData = new FormData();
       formData.append("q", query);

+ 4 - 2
client/simple/theme_icons.js

@@ -6,7 +6,7 @@ import { dirname, resolve } from "node:path";
 import { argv } from "node:process";
 import { jinja_svg_sets } from "./tools/jinja_svg_catalog.js";
 
-const HERE = dirname(argv[1]) + "/";
+const HERE = `${dirname(argv[1])}/`;
 const dest = resolve(HERE, "../../searx/templates/simple/icons.html");
 
 /** @type import("./tools/jinja_svg_catalog.js").JinjaMacro[] */
@@ -34,7 +34,9 @@ const sxng_icon_opts = {
   ]
 };
 
-/** @type import("./tools/jinja_svg_catalog.js").IconSet */
+/**
+ * @type import("./tools/jinja_svg_catalog.js").IconSet[]
+ */
 const simple_icons = [
   {
     base: resolve(HERE, "node_modules/ionicons/dist/svg"),

+ 8 - 10
client/simple/tools/img.js

@@ -1,5 +1,5 @@
-import fs from "fs";
-import path from "path";
+import fs from "node:fs";
+import path from "node:path";
 import sharp from "sharp";
 import { optimize as svgo } from "svgo";
 
@@ -14,9 +14,8 @@ import { optimize as svgo } from "svgo";
  *
  * @param {Src2Dest[]} items - Array of SVG files (src: SVG, dest:PNG) to convert.
  */
-
 async function svg2png(items) {
-  items.forEach(async (item) => {
+  for (const item of items) {
     try {
       fs.mkdir(path.dirname(item.dest), { recursive: true }, (err) => {
         if (err) throw err;
@@ -35,18 +34,17 @@ async function svg2png(items) {
       console.error(`ERROR: ${item.dest} -- ${err}`);
       throw err;
     }
-  });
+  }
 }
 
 /**
  * Optimize SVG images for WEB.
  *
- * @param {import('svgo').Config} svgo_opts - Options passed to svgo.
  * @param {Src2Dest[]} items - Array of SVG files (src:SVG, dest:SVG) to optimize.
+ * @param {import('svgo').Config} svgo_opts - Options passed to svgo.
  */
-
-async function svg2svg(svgo_opts, items) {
-  items.forEach(async (item) => {
+async function svg2svg(items, svgo_opts) {
+  for (const item of items) {
     try {
       fs.mkdir(path.dirname(item.dest), { recursive: true }, (err) => {
         if (err) throw err;
@@ -60,7 +58,7 @@ async function svg2svg(svgo_opts, items) {
       console.error(`ERROR: optimize src: ${item.src} -- ${err}`);
       throw err;
     }
-  });
+  }
 }
 
 export { svg2png, svg2svg };

+ 4 - 4
client/simple/tools/jinja_svg_catalog.js

@@ -1,8 +1,8 @@
+import fs from "node:fs";
+import { dirname, resolve } from "node:path";
+import { fileURLToPath } from "node:url";
 import { Edge } from "edge.js";
-import fs from "fs";
-import { dirname, resolve } from "path";
 import { optimize as svgo } from "svgo";
-import { fileURLToPath } from "url";
 
 const __dirname = dirname(fileURLToPath(import.meta.url));
 const __jinja_class_placeholder__ = "__jinja_class_placeholder__";
@@ -11,7 +11,7 @@ const __jinja_class_placeholder__ = "__jinja_class_placeholder__";
 
 /**
  * @typedef {object} IconSet - A set of icons
- * @property {object[]} set - Array of SVG icons, where property name is the
+ * @property {object} set - Object of SVG icons, where property name is the
  * name of the icon and value is the src of the SVG (relative to base).
  * @property {string} base - Folder in which the SVG src files are located.
  * @property {import("svgo").Config} svgo_opts - svgo options for this set.

+ 5 - 5
client/simple/tools/plg.js

@@ -13,14 +13,14 @@ import { svg2png, svg2svg } from "./img.js";
 /**
  * Vite plugin to convert a list of SVG files to PNG.
  *
- * @param {import('./img.js').Src2Dest} items - Array of SVG files (src: SVG, dest:PNG) to convert.
+ * @param {import('./img.js').Src2Dest[]} items - Array of SVG files (src: SVG, dest:PNG) to convert.
  */
 function plg_svg2png(items) {
   return {
     name: "searxng-simple-svg2png",
     apply: "build", // or 'serve'
     async writeBundle() {
-      svg2png(items);
+      await svg2png(items);
     }
   };
 }
@@ -28,15 +28,15 @@ function plg_svg2png(items) {
 /**
  * Vite plugin to optimize SVG images for WEB.
  *
+ * @param {import('./img.js').Src2Dest[]} items - Array of SVG files (src:SVG, dest:SVG) to optimize.
  * @param {import('svgo').Config} svgo_opts - Options passed to svgo.
- * @param {import('./img.js').Src2Dest} items - Array of SVG files (src:SVG, dest:SVG) to optimize.
  */
-function plg_svg2svg(svgo_opts, items) {
+function plg_svg2svg(items, svgo_opts) {
   return {
     name: "searxng-simple-svg2png",
     apply: "build", // or 'serve'
     async writeBundle() {
-      svg2svg(items, svgo_opts);
+      await svg2svg(items, svgo_opts);
     }
   };
 }

+ 26 - 20
client/simple/vite.config.js

@@ -21,10 +21,16 @@ const PATH = {
   templates: resolve(ROOT, "searx/templates/simple")
 };
 
+/**
+ * @type {import('svgo').Config}
+ */
 const svg2svg_opts = {
   plugins: [{ name: "preset-default" }, "sortAttrs", "convertStyleToAttrs"]
 };
 
+/**
+ * @type {import('svgo').Config}
+ */
 const svg2svg_favicon_opts = {
   plugins: [{ name: "preset-default" }, "sortAttrs"]
 };
@@ -52,7 +58,7 @@ export default defineConfig({
           outputSourceFiles: true,
           sourceMapURL: (name) => {
             const s = name.split("/");
-            return s[s.length - 1] + ".map";
+            return `${s[s.length - 1]}.map`;
           }
         }
         // env: 'development',
@@ -68,7 +74,7 @@ export default defineConfig({
   },
 
   build: {
-    target: "es2016",
+    target: "modules",
     manifest: "manifest.json",
     emptyOutDir: true,
     assetsDir: "",
@@ -85,13 +91,13 @@ export default defineConfig({
     rollupOptions: {
       input: {
         // build CSS files
-        "css/searxng.min.css": PATH.src + "/less/style-ltr.less",
-        "css/searxng-rtl.min.css": PATH.src + "/less/style-rtl.less",
-        "css/rss.min.css": PATH.src + "/less/rss.less",
+        "css/searxng.min.css": `${PATH.src}/less/style-ltr.less`,
+        "css/searxng-rtl.min.css": `${PATH.src}/less/style-rtl.less`,
+        "css/rss.min.css": `${PATH.src}/less/rss.less`,
 
         // build JS files
-        "js/searxng.head.min": PATH.src + "/js/searxng.head.js",
-        "js/searxng.min": PATH.src + "/js/searxng.js"
+        "js/searxng.head.min": `${PATH.src}/js/searxng.head.js`,
+        "js/searxng.min": `${PATH.src}/js/searxng.js`
       },
 
       // file naming conventions / pathnames are relative to outDir (PATH.dist)
@@ -111,10 +117,10 @@ export default defineConfig({
 
     viteStaticCopy({
       targets: [
-        { src: PATH.leaflet + "/leaflet.{js,js.map}", dest: PATH.dist + "/js" },
-        { src: PATH.leaflet + "/images/*.png", dest: PATH.dist + "/css/images/" },
-        { src: PATH.leaflet + "/*.{css,css.map}", dest: PATH.dist + "/css" },
-        { src: PATH.static + "/**/*", dest: PATH.dist }
+        { src: `${PATH.leaflet}/leaflet.{js,js.map}`, dest: `${PATH.dist}/js` },
+        { src: `${PATH.leaflet}/images/*.png`, dest: `${PATH.dist}/css/images/` },
+        { src: `${PATH.leaflet}/*.{css,css.map}`, dest: `${PATH.dist}/css` },
+        { src: `${PATH.static}/**/*`, dest: PATH.dist }
       ]
     }),
 
@@ -122,9 +128,9 @@ export default defineConfig({
 
     plg_svg2svg(
       [
-        { src: PATH.src + "/svg/empty_favicon.svg", dest: PATH.dist + "/img/empty_favicon.svg" },
-        { src: PATH.src + "/svg/select-dark.svg", dest: PATH.dist + "/img/select-dark.svg" },
-        { src: PATH.src + "/svg/select-light.svg", dest: PATH.dist + "/img/select-light.svg" }
+        { src: `${PATH.src}/svg/empty_favicon.svg`, dest: `${PATH.dist}/img/empty_favicon.svg` },
+        { src: `${PATH.src}/svg/select-dark.svg`, dest: `${PATH.dist}/img/select-dark.svg` },
+        { src: `${PATH.src}/svg/select-light.svg`, dest: `${PATH.dist}/img/select-light.svg` }
       ],
       svg2svg_opts
     ),
@@ -132,28 +138,28 @@ export default defineConfig({
     // SearXNG brand (static)
 
     plg_svg2png([
-      { src: PATH.brand + "/searxng-wordmark.svg", dest: PATH.dist + "/img/favicon.png" },
-      { src: PATH.brand + "/searxng.svg", dest: PATH.dist + "/img/searxng.png" }
+      { src: `${PATH.brand}/searxng-wordmark.svg`, dest: `${PATH.dist}/img/favicon.png` },
+      { src: `${PATH.brand}/searxng.svg`, dest: `${PATH.dist}/img/searxng.png` }
     ]),
 
     // -- svg
     plg_svg2svg(
       [
-        { src: PATH.brand + "/searxng.svg", dest: PATH.dist + "/img/searxng.svg" },
-        { src: PATH.brand + "/img_load_error.svg", dest: PATH.dist + "/img/img_load_error.svg" }
+        { src: `${PATH.brand}/searxng.svg`, dest: `${PATH.dist}/img/searxng.svg` },
+        { src: `${PATH.brand}/img_load_error.svg`, dest: `${PATH.dist}/img/img_load_error.svg` }
       ],
       svg2svg_opts
     ),
 
     // -- favicon
     plg_svg2svg(
-      [{ src: PATH.brand + "/searxng-wordmark.svg", dest: PATH.dist + "/img/favicon.svg" }],
+      [{ src: `${PATH.brand}/searxng-wordmark.svg`, dest: `${PATH.dist}/img/favicon.svg` }],
       svg2svg_favicon_opts
     ),
 
     // -- simple templates
     plg_svg2svg(
-      [{ src: PATH.brand + "/searxng-wordmark.svg", dest: PATH.templates + "/searxng-wordmark.min.svg" }],
+      [{ src: `${PATH.brand}/searxng-wordmark.svg`, dest: `${PATH.templates}/searxng-wordmark.min.svg` }],
       svg2svg_opts
     )
   ] // end: plugins

+ 1 - 1
searx/static/themes/simple/js/searxng.head.min.js.map

@@ -1 +1 @@
-{"version":3,"file":"searxng.head.min.js","sources":["../../../../../client/simple/src/js/head/00_init.js"],"sourcesContent":["/* SPDX-License-Identifier: AGPL-3.0-or-later */\n(function (w, d) {\n  'use strict';\n\n  // add data- properties\n  var script = d.currentScript  || (function () {\n    var scripts = d.getElementsByTagName('script');\n    return scripts[scripts.length - 1];\n  })();\n\n  w.searxng = {\n    settings: JSON.parse(atob(script.getAttribute('client_settings')))\n  };\n\n  // update the css\n  var htmlElement = d.getElementsByTagName(\"html\")[0];\n  htmlElement.classList.remove('no-js');\n  htmlElement.classList.add('js');\n\n})(window, document);\n"],"names":["w","d","script","scripts","htmlElement"],"mappings":"CACC,SAAUA,EAAGC,EAAG,CAIf,IAAIC,EAASD,EAAE,eAAmB,UAAY,CAC5C,IAAIE,EAAUF,EAAE,qBAAqB,QAAQ,EAC7C,OAAOE,EAAQA,EAAQ,OAAS,CAAC,CACrC,EAAM,EAEJH,EAAE,QAAU,CACV,SAAU,KAAK,MAAM,KAAKE,EAAO,aAAa,iBAAiB,CAAC,CAAC,CAClE,EAGD,IAAIE,EAAcH,EAAE,qBAAqB,MAAM,EAAE,CAAC,EAClDG,EAAY,UAAU,OAAO,OAAO,EACpCA,EAAY,UAAU,IAAI,IAAI,CAEhC,GAAG,OAAQ,QAAQ"}
+{"version":3,"file":"searxng.head.min.js","sources":["../../../../../client/simple/src/js/head/00_init.js"],"sourcesContent":["/* SPDX-License-Identifier: AGPL-3.0-or-later */\n(function (w, d) {\n  'use strict';\n\n  // add data- properties\n  var script = d.currentScript  || (function () {\n    var scripts = d.getElementsByTagName('script');\n    return scripts[scripts.length - 1];\n  })();\n\n  w.searxng = {\n    settings: JSON.parse(atob(script.getAttribute('client_settings')))\n  };\n\n  // update the css\n  var htmlElement = d.getElementsByTagName(\"html\")[0];\n  htmlElement.classList.remove('no-js');\n  htmlElement.classList.add('js');\n\n})(window, document);\n"],"names":["w","d","script","scripts","htmlElement"],"mappings":"CACC,SAAUA,EAAGC,EAAG,CAIf,IAAIC,EAASD,EAAE,eAAmB,UAAY,CAC5C,IAAIE,EAAUF,EAAE,qBAAqB,QAAQ,EAC7C,OAAOE,EAAQA,EAAQ,OAAS,CAAC,CACrC,EAAM,EAEJH,EAAE,QAAU,CACV,SAAU,KAAK,MAAM,KAAKE,EAAO,aAAa,iBAAiB,CAAC,CAAC,CAClE,EAGD,IAAIE,EAAcH,EAAE,qBAAqB,MAAM,EAAE,CAAC,EAClDG,EAAY,UAAU,OAAO,OAAO,EACpCA,EAAY,UAAU,IAAI,IAAI,CAEhC,GAAG,OAAQ,QAAQ"}

File diff suppressed because it is too large
+ 0 - 0
searx/static/themes/simple/js/searxng.min.js.map


Some files were not shown because too many files changed in this diff