diff options
| author | Alexandre Flament <alex@al-f.net> | 2022-02-21 12:49:04 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-02-21 12:49:04 +0100 |
| commit | 8230603f4834003c79938b472d1f6328b1af2ae8 (patch) | |
| tree | 39ec6d65a8e04ba56fb1ba6f91cd8df068a85129 /searx/static/themes/simple/src/js/main/infinite_scroll.js | |
| parent | 6c38bb599447db8cbe3436e4c3596ca0f4574080 (diff) | |
| parent | 1832ec742a378f0fd2162e3c07b7c279544c86f8 (diff) | |
Merge pull request #916 from dalf/pref_infinite_scroll2
Convert the infinite_scroll plugin as a preference (second version)
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.js | 88 |
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); + } + +}); |