Files
searxng/searx/static/themes/simple/chunk/Db5v-hxx.min.js
Ivan Gabaldon fb089ae297 [mod] client/simple: client plugins (#5406)
* [mod] client/simple: client plugins

Defines a new interface for client side *"plugins"* that coexist with server
side plugin system. Each plugin (e.g., `InfiniteScroll`) extends the base
`ts Plugin`. Client side plugins are independent and lazy‑loaded via `router.ts`
when their `load()` conditions are met. On each navigation request, all
applicable plugins are instanced.

Since these are client side plugins, we can only invoke them once DOM is fully
loaded. E.g. `Calculator` will not render a new `answer` block until fully
loaded and executed.

For some plugins, we might want to handle its availability in `settings.yml`
and toggle in UI, like we do for server side plugins. In that case, we extend
`py Plugin` instancing only the information and then checking client side if
[`settings.plugins`](1ad832b1dc/client/simple/src/js/toolkit.ts (L134))
array has the plugin id.

* [mod] client/simple: rebuild static
2025-12-02 10:18:00 +00:00

2 lines
5.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import{i as e,n as t,r as n}from"../sxng-core.min.js";import{t as r}from"./13gvpunf.min.js";var i={Escape:{key:`ESC`,fun:e=>f(e),des:`remove focus from the focused input`,cat:`Control`},c:{key:`c`,fun:()=>S(),des:`copy url of the selected result to the clipboard`,cat:`Results`},h:{key:`h`,fun:()=>x(o),des:`toggle help window`,cat:`Other`},i:{key:`i`,fun:()=>v(),des:`focus on the search input`,cat:`Control`},n:{key:`n`,fun:()=>m(),des:`go to next page`,cat:`Results`},o:{key:`o`,fun:()=>y(!1),des:`open search result`,cat:`Results`},p:{key:`p`,fun:()=>h(),des:`go to previous page`,cat:`Results`},r:{key:`r`,fun:()=>d(),des:`reload page from the server`,cat:`Control`},t:{key:`t`,fun:()=>y(!0),des:`open the result in a new tab`,cat:`Results`}},a={default:{ArrowLeft:{key:``,fun:()=>u(`up`)(),des:`select previous search result`,cat:`Results`},ArrowRight:{key:``,fun:()=>u(`down`)(),des:`select next search result`,cat:`Results`},...i},vim:{b:{key:`b`,fun:()=>g(-window.innerHeight),des:`scroll one page up`,cat:`Navigation`},d:{key:`d`,fun:()=>g(window.innerHeight/2),des:`scroll half a page down`,cat:`Navigation`},f:{key:`f`,fun:()=>g(window.innerHeight),des:`scroll one page down`,cat:`Navigation`},g:{key:`g`,fun:()=>_(-document.body.scrollHeight,`top`),des:`scroll to the top of the page`,cat:`Navigation`},j:{key:`j`,fun:()=>u(`down`)(),des:`select next search result`,cat:`Results`},k:{key:`k`,fun:()=>u(`up`)(),des:`select previous search result`,cat:`Results`},u:{key:`u`,fun:()=>g(-window.innerHeight/2),des:`scroll half a page up`,cat:`Navigation`},v:{key:`v`,fun:()=>_(document.body.scrollHeight,`bottom`),des:`scroll to the bottom of the page`,cat:`Navigation`},y:{key:`y`,fun:()=>S(),des:`copy url of the selected result to the clipboard`,cat:`Results`},...i}},o=e.hotkeys&&e.hotkeys in a?a[e.hotkeys]:a.default,s=e=>(e?.closest(`.detail, .result`))?.classList.contains(`detail`)??!1,c=e=>e?.closest(`.result`)??void 0,l=e=>e?.classList.contains(`result-images`)??!1,u=e=>(t,r)=>{let i=e,a=document.querySelector(`.result[data-vim-selected]`);if(!a){if(a=document.querySelector(`.result`),!a)return;(e===`down`||e===`up`)&&(i=a)}let o=Array.from(document.querySelectorAll(`.result`)),s;if(typeof i!=`string`)s=i;else switch(i){case`visible`:{let e=document.documentElement.scrollTop||document.body.scrollTop,t=e+document.documentElement.clientHeight;for(let n of o){let r=n.offsetTop;if(r+n.clientHeight<=t&&r>e){s=n;break}}break}case`down`:s=o[o.indexOf(a)+1]||a;break;case`up`:s=o[o.indexOf(a)-1]||a;break;case`bottom`:s=o.at(-1);break;case`top`:default:s=o[0]}s&&(a.removeAttribute(`data-vim-selected`),s.setAttribute(`data-vim-selected`,`true`),r||(s.querySelector(`h3 a`)||s.querySelector(`a`))?.focus(),t||n.scrollPageToSelected?.())},d=()=>{document.location.reload()},f=e=>{let t=e.target?.tagName?.toLowerCase();document.activeElement&&(t===`input`||t===`select`||t===`textarea`)?document.activeElement.blur():n.closeDetail?.()},p=e=>{let t=document.querySelector(e);t&&t.click()},m=()=>{p(`nav#pagination .next_page button[type="submit"]`)},h=()=>{p(`nav#pagination .previous_page button[type="submit"]`)};n.scrollPageToSelected=()=>{let e=document.querySelector(`.result[data-vim-selected]`);if(!e)return;let t=document.documentElement.scrollTop||document.body.scrollTop,n=document.documentElement.clientHeight,r=e.offsetTop,i=r+e.clientHeight;if(!e.previousElementSibling&&i<n){window.scroll(window.scrollX,0);return}t>r-120?window.scroll(window.scrollX,r-120):t+n<i+120&&window.scroll(window.scrollX,i-n+120)};var g=e=>{window.scrollBy(0,e),u(`visible`)()},_=(e,t)=>{window.scrollTo(0,e),u(t)()},v=()=>{window.scrollTo(0,0);let e=document.querySelector(`#q`);if(e&&(e.focus(),e.setSelectionRange)){let t=e.value.length;e.setSelectionRange(t,t)}},y=e=>{let t=document.querySelector(`.result[data-vim-selected] h3 a`);if(t||=document.querySelector(`.result[data-vim-selected] > a`),!t)return;let n=t.getAttribute(`href`);n&&(e?window.open(n):window.location.href=n)},b=(e,t)=>{let n={};for(let e of Object.values(t)){let t=e.cat;n[t]??=[],n[t].push(e)}let r=Object.keys(n).sort((e,t)=>(n[t]?.length??0)-(n[e]?.length??0)),i=`<a href="#" class="close" aria-label="close" title="close">×</a>`;i+=`<h3>How to navigate SearXNG with hotkeys</h3>`,i+=`<table>`;for(let[e,t]of r.entries()){let a=n[t];if(!a||a.length===0)continue;let o=e%2==0,s=e===r.length-1;o&&(i+=`<tr>`),i+=`<td>`,i+=`<h4>${t}</h4>`,i+=`<ul class="list-unstyled">`;for(let e of a)i+=`<li><kbd>${e.key}</kbd> ${e.des}</li>`;i+=`</ul>`,i+=`</td>`,(!o||s)&&(i+=`</tr>`)}i+=`</table>`,e.innerHTML=i},x=e=>{let t=document.querySelector(`#vim-hotkeys-help`);if(t)t.classList.toggle(`invisible`);else{t=Object.assign(document.createElement(`div`),{id:`vim-hotkeys-help`,className:`dialog-modal`}),b(t,e);let n=document.getElementsByTagName(`body`)[0];n&&n.appendChild(t)}},S=async()=>{let e=document.querySelector(`.result[data-vim-selected]`);if(!e)return;let t=e.querySelector(`a`);r(t);let n=t.getAttribute(`href`);if(n)if(window.isSecureContext)await navigator.clipboard.writeText(n);else{let e=window.getSelection();if(e){let r=document.createElement(`span`);r.textContent=n,t.appendChild(r);let i=document.createRange();i.selectNodeContents(r),e.removeAllRanges(),e.addRange(i),document.execCommand(`copy`),r.remove()}}};t(`click`,`.result`,function(e){if(!s(e.target)){u(this)(!0,!0);let t=c(e.target);t&&l(t)&&(e.preventDefault(),n.selectImage?.(t))}}),t(`focus`,`.result a`,e=>{if(!s(e.target)){let t=c(e.target);t&&!t.hasAttribute(`data-vim-selected`)&&u(t)(!0),t&&l(t)&&(e.preventDefault(),n.selectImage?.(t))}},{capture:!0}),t(`keydown`,document,e=>{if(Object.hasOwn(o,e.key)&&!e.ctrlKey&&!e.altKey&&!e.shiftKey&&!e.metaKey){let t=e.target?.tagName?.toLowerCase();e.key===`Escape`?o[e.key]?.fun(e):(e.target===document.body||t===`a`||t===`button`)&&(e.preventDefault(),o[e.key]?.fun(e))}}),n.selectNext=u(`down`),n.selectPrevious=u(`up`);
//# sourceMappingURL=Db5v-hxx.min.js.map