summaryrefslogtreecommitdiff
path: root/client/simple/src/js/main/infinite_scroll.js
diff options
context:
space:
mode:
authorMarkus Heiser <markus.heiser@darmarit.de>2025-01-23 11:10:40 +0100
committerMarkus Heiser <markus.heiser@darmarIT.de>2025-02-28 12:27:41 +0100
commita1132deaa4618f228e82252397247a150081a5f3 (patch)
tree0445fbe04c8932acdfbe5362db40ea1782f38539 /client/simple/src/js/main/infinite_scroll.js
parentb6487b70aaa199aba6ae999a9c99b340b5e98884 (diff)
[web-client] simple theme: move sources to client/simple/src
Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
Diffstat (limited to 'client/simple/src/js/main/infinite_scroll.js')
-rw-r--r--client/simple/src/js/main/infinite_scroll.js88
1 files changed, 88 insertions, 0 deletions
diff --git a/client/simple/src/js/main/infinite_scroll.js b/client/simple/src/js/main/infinite_scroll.js
new file mode 100644
index 000000000..07db3305a
--- /dev/null
+++ b/client/simple/src/js/main/infinite_scroll.js
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: AGPL-3.0-or-later
+
+/* global searxng */
+
+searxng.ready(function () {
+ 'use strict';
+
+ searxng.infinite_scroll_supported = (
+ 'IntersectionObserver' in window &&
+ 'IntersectionObserverEntry' in window &&
+ 'intersectionRatio' in window.IntersectionObserverEntry.prototype);
+
+ if (searxng.endpoint !== 'results') {
+ return;
+ }
+
+ if (!searxng.infinite_scroll_supported) {
+ console.log('IntersectionObserver not supported');
+ return;
+ }
+
+ let d = document;
+ var onlyImages = d.getElementById('results').classList.contains('only_template_images');
+
+ function newLoadSpinner () {
+ var loader = d.createElement('div');
+ loader.classList.add('loader');
+ return loader;
+ }
+
+ function replaceChildrenWith (element, children) {
+ element.textContent = '';
+ children.forEach(child => element.appendChild(child));
+ }
+
+ function loadNextPage (callback) {
+ var form = d.querySelector('#pagination form.next_page');
+ if (!form) {
+ return
+ }
+ replaceChildrenWith(d.querySelector('#pagination'), [ newLoadSpinner() ]);
+ var formData = new FormData(form);
+ searxng.http('POST', d.querySelector('#search').getAttribute('action'), formData).then(
+ function (response) {
+ var nextPageDoc = new DOMParser().parseFromString(response, 'text/html');
+ var articleList = nextPageDoc.querySelectorAll('#urls article');
+ var paginationElement = nextPageDoc.querySelector('#pagination');
+ d.querySelector('#pagination').remove();
+ if (articleList.length > 0 && !onlyImages) {
+ // do not add <hr> element when there are only images
+ d.querySelector('#urls').appendChild(d.createElement('hr'));
+ }
+ articleList.forEach(articleElement => {
+ d.querySelector('#urls').appendChild(articleElement);
+ });
+ if (paginationElement) {
+ d.querySelector('#results').appendChild(paginationElement);
+ callback();
+ }
+ }
+ ).catch(
+ function (err) {
+ console.log(err);
+ var e = d.createElement('div');
+ e.textContent = searxng.settings.translations.error_loading_next_page;
+ e.classList.add('dialog-error');
+ e.setAttribute('role', 'alert');
+ replaceChildrenWith(d.querySelector('#pagination'), [ e ]);
+ }
+ )
+ }
+
+ if (searxng.settings.infinite_scroll && searxng.infinite_scroll_supported) {
+ const intersectionObserveOptions = {
+ rootMargin: "20rem",
+ };
+ const observedSelector = 'article.result:last-child';
+ const observer = new IntersectionObserver(entries => {
+ const paginationEntry = entries[0];
+ if (paginationEntry.isIntersecting) {
+ observer.unobserve(paginationEntry.target);
+ loadNextPage(() => observer.observe(d.querySelector(observedSelector), intersectionObserveOptions));
+ }
+ });
+ observer.observe(d.querySelector(observedSelector), intersectionObserveOptions);
+ }
+
+});