4 Commits

Author SHA1 Message Date
Markus Heiser
06f6ee4e36 [build] /static 2025-01-26 13:34:52 +01:00
Markus Heiser
9beff8212b [refactor] results.js: wait one second before loading full high-res image
Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
2025-01-26 13:34:52 +01:00
Bnyro
cf4e183790 [refactor] results.js: cancel image loading after next one selected 2025-01-26 13:34:52 +01:00
Bnyro
c1fcee9d9f [docs] settings_search.rst: add missing autocompletion providers 2025-01-26 08:38:29 +01:00
5 changed files with 87 additions and 45 deletions

View File

@@ -33,14 +33,19 @@
``autocomplete``:
Existing autocomplete backends, leave blank to turn it off.
- ``dbpedia``
- ``duckduckgo``
- ``google``
- ``mwmbl``
- ``startpage``
- ``swisscows``
- ``qwant``
- ``wikipedia``
- ``baidu```
- ``brave```
- ``dbpedia```
- ``duckduckgo```
- ``google```
- ``mwmbl```
- ``qwant```
- ``seznam```
- ``startpage```
- ``stract```
- ``swisscows```
- ``wikipedia```
- ``yandex```
``favicon_resolver``:
To activate favicons in SearXNG's result list select a default

View File

@@ -33,9 +33,9 @@ brand:
search:
# Filter results. 0: None, 1: Moderate, 2: Strict
safe_search: 0
# Existing autocomplete backends: "dbpedia", "duckduckgo", "google", "yandex", "mwmbl",
# "seznam", "startpage", "stract", "swisscows", "qwant", "wikipedia" - leave blank to turn it off
# by default.
# Existing autocomplete backends: "baidu", "brave", "dbpedia", "duckduckgo", "google", "yandex",
# "mwmbl", "seznam", "startpage", "stract", "swisscows", "qwant", "wikipedia" -
# leave blank to turn it off by default.
autocomplete: ""
# minimun characters to type before autocompleter starts
autocomplete_min: 4

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -52,43 +52,80 @@
this.innerText = this.dataset.copiedText;
});
const isMobile = screen.orientation.type.startsWith('portrait');
searxng.selectImage = function (resultElement) {
/* eslint no-unused-vars: 0 */
if (resultElement) {
// load full size image in background
const imgElement = resultElement.querySelector('.result-images-source img');
const thumbnailElement = resultElement.querySelector('.image_thumbnail');
const detailElement = resultElement.querySelector('.detail');
if (imgElement) {
const imgSrc = imgElement.getAttribute('data-src');
if (imgSrc) {
const loader = d.createElement('div');
const imgLoader = new Image();
// searxng.selectImage (gallery)
// -----------------------------
loader.classList.add('loader');
detailElement.appendChild(loader);
// setTimeout() ID, needed to cancel *last* loadImage
let imgTimeoutID;
imgLoader.onload = e => {
imgElement.src = imgSrc;
loader.remove();
};
imgLoader.onerror = e => {
loader.remove();
};
imgLoader.src = imgSrc;
imgElement.src = thumbnailElement.src;
imgElement.removeAttribute('data-src');
}
}
}
// progress spinner, while an image is loading
const imgLoaderSpinner = d.createElement('div');
imgLoaderSpinner.classList.add('loader');
// singleton image object, which is used for all loading processes of a
// detailed image
const imgLoader = new Image();
const loadImage = (imgSrc, onSuccess) => {
// if defered image load exists, stop defered task.
if (imgTimeoutID) clearTimeout(imgTimeoutID);
// defer load of the detail image for 1 sec
imgTimeoutID = setTimeout(() => {
imgLoader.src = imgSrc;
}, 1000);
// set handlers in the on-properties
imgLoader.onload = () => {
onSuccess();
imgLoaderSpinner.remove();
};
imgLoader.onerror = () => {
imgLoaderSpinner.remove();
};
};
searxng.selectImage = (resultElement) => {
// add a class that can be evaluated in the CSS and indicates that the
// detail view is open
d.getElementById('results').classList.add('image-detail-open');
// add a hash to the browser history so that pressing back doesn't return to the previous page
// this allows us to dismiss the image details on pressing the back button on mobile devices
// add a hash to the browser history so that pressing back doesn't return
// to the previous page this allows us to dismiss the image details on
// pressing the back button on mobile devices
window.location.hash = '#image-viewer';
searxng.scrollPageToSelected();
// if there is none element given by the caller, stop here
if (!resultElement) return;
// find <img> object in the element, if there is none, stop here.
const img = resultElement.querySelector('.result-images-source img');
if (!img) return;
// <img src="" data-src="http://example.org/image.jpg">
const src = img.getAttribute('data-src');
// already loaded high-res image or no high-res image available
if (!src) return;
// use the image thumbnail until the image is fully loaded
const thumbnail = resultElement.querySelector('.image_thumbnail');
img.src = thumbnail.src;
// show a progress spinner
const detailElement = resultElement.querySelector('.detail');
detailElement.appendChild(imgLoaderSpinner);
// load full size image in background
loadImage(src, () => {
// after the singelton loadImage has loaded the detail image into the
// cache, it can be used in the origin <img> as src property.
img.src = src;
img.removeAttribute('data-src');
});
};
searxng.closeDetail = function () {
@@ -117,10 +154,10 @@
d.querySelectorAll('.swipe-horizontal').forEach(
obj => {
obj.addEventListener('swiped-left', function (e) {
obj.addEventListener('swiped-left', function () {
searxng.selectNext(false);
});
obj.addEventListener('swiped-right', function (e) {
obj.addEventListener('swiped-right', function () {
searxng.selectPrevious(false);
});
}