summaryrefslogtreecommitdiff
path: root/searx/static/themes/simple/src/js/main/infinite_scroll.js
diff options
context:
space:
mode:
authorAlexandre Flament <alex@al-f.net>2022-01-23 11:37:57 +0100
committerAlexandre Flament <alex@al-f.net>2022-02-20 22:58:51 +0100
commit56e34947a6368e6154064c52fa23d21ecda7ab4c (patch)
treebad1463a0c3056896cfacb205039586b85a2c04d /searx/static/themes/simple/src/js/main/infinite_scroll.js
parent36aee70c247fe347c69abb17ec3bdc31781204c6 (diff)
[mod] infinite_scroll as preference
* oscar theme: code from searx/plugins/infinite_scroll.py * simple theme: new implementation Co-authored-by: Markus Heiser <markus.heiser@darmarIT.de>
Diffstat (limited to 'searx/static/themes/simple/src/js/main/infinite_scroll.js')
-rw-r--r--searx/static/themes/simple/src/js/main/infinite_scroll.js88
1 files changed, 88 insertions, 0 deletions
diff --git a/searx/static/themes/simple/src/js/main/infinite_scroll.js b/searx/static/themes/simple/src/js/main/infinite_scroll.js
new file mode 100644
index 000000000..b900e66e2
--- /dev/null
+++ b/searx/static/themes/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.translations.error_loading_next_page;
+ e.classList.add('dialog-error');
+ e.setAttribute('role', 'alert');
+ replaceChildrenWith(d.querySelector('#pagination'), [ e ]);
+ }
+ )
+ }
+
+ if (searxng.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);
+ }
+
+});