mirror of https://github.com/searxng/searxng.git
Merge pull request #916 from dalf/pref_infinite_scroll2
Convert the infinite_scroll plugin as a preference (second version)
This commit is contained in:
commit
8230603f48
|
@ -1,9 +0,0 @@
|
||||||
from flask_babel import gettext
|
|
||||||
|
|
||||||
name = gettext('Infinite scroll')
|
|
||||||
description = gettext('Automatically load next page when scrolling to bottom of current page')
|
|
||||||
default_on = False
|
|
||||||
preference_section = 'ui'
|
|
||||||
|
|
||||||
js_dependencies = ('plugins/js/infinite_scroll.js',)
|
|
||||||
css_dependencies = ('plugins/css/infinite_scroll.css',)
|
|
|
@ -394,6 +394,17 @@ class Preferences:
|
||||||
'False': False
|
'False': False
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
'infinite_scroll': MapSetting(
|
||||||
|
settings['ui']['infinite_scroll'],
|
||||||
|
locked=is_locked('infinite_scroll'),
|
||||||
|
map={
|
||||||
|
'': settings['ui']['infinite_scroll'],
|
||||||
|
'0': False,
|
||||||
|
'1': True,
|
||||||
|
'True': True,
|
||||||
|
'False': False
|
||||||
|
}
|
||||||
|
),
|
||||||
# fmt: on
|
# fmt: on
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -169,7 +169,6 @@ outgoing:
|
||||||
# - 'Ahmia blacklist' # activation depends on outgoing.using_tor_proxy
|
# - 'Ahmia blacklist' # activation depends on outgoing.using_tor_proxy
|
||||||
# # these plugins are disabled if nothing is configured ..
|
# # these plugins are disabled if nothing is configured ..
|
||||||
# - 'Hostname replace' # see hostname_replace configuration below
|
# - 'Hostname replace' # see hostname_replace configuration below
|
||||||
# - 'Infinite scroll'
|
|
||||||
# - 'Open Access DOI rewrite'
|
# - 'Open Access DOI rewrite'
|
||||||
# - 'Vim-like hotkeys'
|
# - 'Vim-like hotkeys'
|
||||||
|
|
||||||
|
|
|
@ -186,6 +186,7 @@ SCHEMA = {
|
||||||
'results_on_new_tab': SettingsValue(bool, False),
|
'results_on_new_tab': SettingsValue(bool, False),
|
||||||
'advanced_search': SettingsValue(bool, False),
|
'advanced_search': SettingsValue(bool, False),
|
||||||
'query_in_title': SettingsValue(bool, False),
|
'query_in_title': SettingsValue(bool, False),
|
||||||
|
'infinite_scroll': SettingsValue(bool, False),
|
||||||
},
|
},
|
||||||
'preferences': {
|
'preferences': {
|
||||||
'lock': SettingsValue(list, []),
|
'lock': SettingsValue(list, []),
|
||||||
|
|
|
@ -1,40 +0,0 @@
|
||||||
function hasScrollbar() {
|
|
||||||
var root = document.compatMode=='BackCompat'? document.body : document.documentElement;
|
|
||||||
return root.scrollHeight>root.clientHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadNextPage() {
|
|
||||||
var formData = $('#pagination form:last').serialize();
|
|
||||||
if (formData) {
|
|
||||||
$('#pagination').html('<div class="loading-spinner"></div>');
|
|
||||||
$.ajax({
|
|
||||||
type: "POST",
|
|
||||||
url: $('#search_form').prop('action'),
|
|
||||||
data: formData,
|
|
||||||
dataType: 'html',
|
|
||||||
success: function(data) {
|
|
||||||
var body = $(data);
|
|
||||||
$('#pagination').remove();
|
|
||||||
$('#main_results').append('<hr/>');
|
|
||||||
$('#main_results').append(body.find('.result'));
|
|
||||||
$('#main_results').append(body.find('#pagination'));
|
|
||||||
if(!hasScrollbar()) {
|
|
||||||
loadNextPage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$(document).ready(function() {
|
|
||||||
var win = $(window);
|
|
||||||
if(!hasScrollbar()) {
|
|
||||||
loadNextPage();
|
|
||||||
}
|
|
||||||
win.scroll(function() {
|
|
||||||
$("#pagination button").css("visibility", "hidden");
|
|
||||||
if ($(document).height() - win.height() - win.scrollTop() < 150) {
|
|
||||||
loadNextPage();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -29,7 +29,8 @@
|
||||||
this.verticalMargin = verticalMargin;
|
this.verticalMargin = verticalMargin;
|
||||||
this.horizontalMargin = horizontalMargin;
|
this.horizontalMargin = horizontalMargin;
|
||||||
this.maxHeight = maxHeight;
|
this.maxHeight = maxHeight;
|
||||||
this.isAlignDone = true;
|
this.trottleCallToAlign = null;
|
||||||
|
this.alignAfterThrotteling = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -72,12 +73,12 @@
|
||||||
// not loaded image : make it square as _getHeigth said it
|
// not loaded image : make it square as _getHeigth said it
|
||||||
imgWidth = height;
|
imgWidth = height;
|
||||||
}
|
}
|
||||||
img.style.width = imgWidth + 'px';
|
img.setAttribute('width', Math.round(imgWidth));
|
||||||
img.style.height = height + 'px';
|
img.setAttribute('height', Math.round(height));
|
||||||
img.style.marginLeft = this.horizontalMargin + 'px';
|
img.style.marginLeft = Math.round(this.horizontalMargin) + 'px';
|
||||||
img.style.marginTop = this.horizontalMargin + 'px';
|
img.style.marginTop = Math.round(this.horizontalMargin) + 'px';
|
||||||
img.style.marginRight = this.verticalMargin - 7 + 'px'; // -4 is the negative margin of the inline element
|
img.style.marginRight = Math.round(this.verticalMargin - 7) + 'px'; // -4 is the negative margin of the inline element
|
||||||
img.style.marginBottom = this.verticalMargin - 7 + 'px';
|
img.style.marginBottom = Math.round(this.verticalMargin - 7) + 'px';
|
||||||
resultNode = img.parentNode.parentNode;
|
resultNode = img.parentNode.parentNode;
|
||||||
if (!resultNode.classList.contains('js')) {
|
if (!resultNode.classList.contains('js')) {
|
||||||
resultNode.classList.add('js');
|
resultNode.classList.add('js');
|
||||||
|
@ -112,6 +113,23 @@
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ImageLayout.prototype.throttleAlign = function () {
|
||||||
|
var obj = this;
|
||||||
|
if (obj.trottleCallToAlign) {
|
||||||
|
obj.alignAfterThrotteling = true;
|
||||||
|
} else {
|
||||||
|
obj.alignAfterThrotteling = false;
|
||||||
|
obj.align();
|
||||||
|
obj.trottleCallToAlign = setTimeout(function () {
|
||||||
|
if (obj.alignAfterThrotteling) {
|
||||||
|
obj.align();
|
||||||
|
}
|
||||||
|
obj.alignAfterThrotteling = false;
|
||||||
|
obj.trottleCallToAlign = null;
|
||||||
|
}, 20);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ImageLayout.prototype.align = function () {
|
ImageLayout.prototype.align = function () {
|
||||||
var i;
|
var i;
|
||||||
var results_selectorNode = d.querySelectorAll(this.results_selector);
|
var results_selectorNode = d.querySelectorAll(this.results_selector);
|
||||||
|
@ -141,9 +159,9 @@
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ImageLayout.prototype.watch = function () {
|
ImageLayout.prototype._monitorImages = function () {
|
||||||
var i, img;
|
var i, img;
|
||||||
var obj = this;
|
var objthrottleAlign = this.throttleAlign.bind(this);
|
||||||
var results_nodes = d.querySelectorAll(this.results_selector);
|
var results_nodes = d.querySelectorAll(this.results_selector);
|
||||||
var results_length = results_nodes.length;
|
var results_length = results_nodes.length;
|
||||||
|
|
||||||
|
@ -152,34 +170,53 @@
|
||||||
event.originalTarget.src = w.searxng.static_path + w.searxng.theme.img_load_error;
|
event.originalTarget.src = w.searxng.static_path + w.searxng.theme.img_load_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
function throttleAlign () {
|
|
||||||
if (obj.isAlignDone) {
|
|
||||||
obj.isAlignDone = false;
|
|
||||||
setTimeout(function () {
|
|
||||||
obj.align();
|
|
||||||
obj.isAlignDone = true;
|
|
||||||
}, 100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/Window/pageshow_event
|
|
||||||
w.addEventListener('pageshow', throttleAlign);
|
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/FileReader/load_event
|
|
||||||
w.addEventListener('load', throttleAlign);
|
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/Window/resize_event
|
|
||||||
w.addEventListener('resize', throttleAlign);
|
|
||||||
|
|
||||||
for (i = 0; i < results_length; i++) {
|
for (i = 0; i < results_length; i++) {
|
||||||
img = results_nodes[i].querySelector(this.img_selector);
|
img = results_nodes[i].querySelector(this.img_selector);
|
||||||
if (img !== null && img !== undefined) {
|
if (img !== null && img !== undefined && !img.classList.contains('aligned')) {
|
||||||
img.addEventListener('load', throttleAlign);
|
img.addEventListener('load', objthrottleAlign);
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onerror
|
// https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onerror
|
||||||
img.addEventListener('error', throttleAlign);
|
img.addEventListener('error', objthrottleAlign);
|
||||||
|
img.addEventListener('timeout', objthrottleAlign);
|
||||||
if (w.searxng.theme.img_load_error) {
|
if (w.searxng.theme.img_load_error) {
|
||||||
img.addEventListener('error', img_load_error, {once: true});
|
img.addEventListener('error', img_load_error, {once: true});
|
||||||
}
|
}
|
||||||
|
img.classList.add('aligned');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageLayout.prototype.watch = function () {
|
||||||
|
var objthrottleAlign = this.throttleAlign.bind(this);
|
||||||
|
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/API/Window/pageshow_event
|
||||||
|
w.addEventListener('pageshow', objthrottleAlign);
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/API/FileReader/load_event
|
||||||
|
w.addEventListener('load', objthrottleAlign);
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/API/Window/resize_event
|
||||||
|
w.addEventListener('resize', objthrottleAlign);
|
||||||
|
|
||||||
|
this._monitorImages();
|
||||||
|
|
||||||
|
var obj = this;
|
||||||
|
|
||||||
|
let observer = new MutationObserver(entries => {
|
||||||
|
let newElement = false;
|
||||||
|
for (let i = 0; i < entries.length; i++) {
|
||||||
|
if (entries[i].addedNodes.length > 0 && entries[i].addedNodes[0].classList.contains('result')) {
|
||||||
|
newElement = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (newElement) {
|
||||||
|
obj._monitorImages();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
observer.observe(d.querySelector(this.container_selector), {
|
||||||
|
childList: true,
|
||||||
|
subtree: true,
|
||||||
|
attributes: false,
|
||||||
|
characterData: false,
|
||||||
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
w.searxng.ImageLayout = ImageLayout;
|
w.searxng.ImageLayout = ImageLayout;
|
||||||
|
|
|
@ -382,6 +382,29 @@
|
||||||
.col-stat {
|
.col-stat {
|
||||||
width: 10rem;
|
width: 10rem;
|
||||||
}
|
}
|
||||||
|
@keyframes rotate-forever {
|
||||||
|
0% {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.loading-spinner {
|
||||||
|
animation-duration: 0.75s;
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
animation-name: rotate-forever;
|
||||||
|
animation-timing-function: linear;
|
||||||
|
height: 30px;
|
||||||
|
width: 30px;
|
||||||
|
border: 8px solid #666;
|
||||||
|
border-right-color: transparent;
|
||||||
|
border-radius: 50% !important;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
html.infinite_scroll #pagination button {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
this file is generated automatically by searxng_extra/update/update_pygments.py
|
this file is generated automatically by searxng_extra/update/update_pygments.py
|
||||||
using pygments version 2.11.2
|
using pygments version 2.11.2
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -382,6 +382,29 @@
|
||||||
.col-stat {
|
.col-stat {
|
||||||
width: 10rem;
|
width: 10rem;
|
||||||
}
|
}
|
||||||
|
@keyframes rotate-forever {
|
||||||
|
0% {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.loading-spinner {
|
||||||
|
animation-duration: 0.75s;
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
animation-name: rotate-forever;
|
||||||
|
animation-timing-function: linear;
|
||||||
|
height: 30px;
|
||||||
|
width: 30px;
|
||||||
|
border: 8px solid #666;
|
||||||
|
border-right-color: transparent;
|
||||||
|
border-radius: 50% !important;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
html.infinite_scroll #pagination button {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
this file is generated automatically by searxng_extra/update/update_pygments.py
|
this file is generated automatically by searxng_extra/update/update_pygments.py
|
||||||
using pygments version 2.11.2
|
using pygments version 2.11.2
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -382,6 +382,29 @@
|
||||||
.col-stat {
|
.col-stat {
|
||||||
width: 10rem;
|
width: 10rem;
|
||||||
}
|
}
|
||||||
|
@keyframes rotate-forever {
|
||||||
|
0% {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.loading-spinner {
|
||||||
|
animation-duration: 0.75s;
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
animation-name: rotate-forever;
|
||||||
|
animation-timing-function: linear;
|
||||||
|
height: 30px;
|
||||||
|
width: 30px;
|
||||||
|
border: 8px solid #666;
|
||||||
|
border-right-color: transparent;
|
||||||
|
border-radius: 50% !important;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
html.infinite_scroll #pagination button {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
this file is generated automatically by searxng_extra/update/update_pygments.py
|
this file is generated automatically by searxng_extra/update/update_pygments.py
|
||||||
using pygments version 2.11.2
|
using pygments version 2.11.2
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -78,7 +78,7 @@ module.exports = function(grunt) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
jshint: {
|
jshint: {
|
||||||
files: ['gruntfile.js', 'src/js/*.js', '../__common__/js/image_layout.js'],
|
files: ['gruntfile.js', 'src/js/*.js'], // files in __common__ are linted by es lint in simple theme
|
||||||
options: {
|
options: {
|
||||||
reporterOutput: "",
|
reporterOutput: "",
|
||||||
esversion: 6,
|
esversion: 6,
|
||||||
|
|
|
@ -19,6 +19,7 @@ window.searxng = (function(d) {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
autocompleter: script.getAttribute('data-autocompleter') === 'true',
|
autocompleter: script.getAttribute('data-autocompleter') === 'true',
|
||||||
|
infinite_scroll: script.getAttribute('data-infinite-scroll') === 'true',
|
||||||
method: script.getAttribute('data-method'),
|
method: script.getAttribute('data-method'),
|
||||||
translations: JSON.parse(script.getAttribute('data-translations'))
|
translations: JSON.parse(script.getAttribute('data-translations'))
|
||||||
};
|
};
|
||||||
|
@ -189,6 +190,56 @@ $(document).ready(function(){
|
||||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
$(document).ready(function() {
|
||||||
|
function hasScrollbar() {
|
||||||
|
var root = document.compatMode=='BackCompat'? document.body : document.documentElement;
|
||||||
|
return root.scrollHeight>root.clientHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadNextPage() {
|
||||||
|
var formData = $('#pagination form:last').serialize();
|
||||||
|
if (formData) {
|
||||||
|
$('#pagination').html('<div class="loading-spinner"></div>');
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: $('#search_form').prop('action'),
|
||||||
|
data: formData,
|
||||||
|
dataType: 'html',
|
||||||
|
success: function(data) {
|
||||||
|
var body = $(data);
|
||||||
|
$('#pagination').remove();
|
||||||
|
$('#main_results').append('<hr/>');
|
||||||
|
$('#main_results').append(body.find('.result'));
|
||||||
|
$('#main_results').append(body.find('#pagination'));
|
||||||
|
if(!hasScrollbar()) {
|
||||||
|
loadNextPage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (searxng.infinite_scroll) {
|
||||||
|
var win = $(window);
|
||||||
|
$("html").addClass('infinite_scroll');
|
||||||
|
if(!hasScrollbar()) {
|
||||||
|
loadNextPage();
|
||||||
|
}
|
||||||
|
win.on('scroll', function() {
|
||||||
|
if ($(document).height() - win.height() - win.scrollTop() < 150) {
|
||||||
|
loadNextPage();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
;/**
|
||||||
|
* @license
|
||||||
|
* (C) Copyright Contributors to the SearXNG project.
|
||||||
|
* (C) Copyright Contributors to the searx project (2014 - 2021).
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
window.addEventListener('load', function() {
|
window.addEventListener('load', function() {
|
||||||
// Hide infobox toggle if shrunk size already fits all content.
|
// Hide infobox toggle if shrunk size already fits all content.
|
||||||
$('.infobox').each(function() {
|
$('.infobox').each(function() {
|
||||||
|
@ -348,7 +399,8 @@ $(document).ready(function(){
|
||||||
this.verticalMargin = verticalMargin;
|
this.verticalMargin = verticalMargin;
|
||||||
this.horizontalMargin = horizontalMargin;
|
this.horizontalMargin = horizontalMargin;
|
||||||
this.maxHeight = maxHeight;
|
this.maxHeight = maxHeight;
|
||||||
this.isAlignDone = true;
|
this.trottleCallToAlign = null;
|
||||||
|
this.alignAfterThrotteling = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -391,12 +443,12 @@ $(document).ready(function(){
|
||||||
// not loaded image : make it square as _getHeigth said it
|
// not loaded image : make it square as _getHeigth said it
|
||||||
imgWidth = height;
|
imgWidth = height;
|
||||||
}
|
}
|
||||||
img.style.width = imgWidth + 'px';
|
img.setAttribute('width', Math.round(imgWidth));
|
||||||
img.style.height = height + 'px';
|
img.setAttribute('height', Math.round(height));
|
||||||
img.style.marginLeft = this.horizontalMargin + 'px';
|
img.style.marginLeft = Math.round(this.horizontalMargin) + 'px';
|
||||||
img.style.marginTop = this.horizontalMargin + 'px';
|
img.style.marginTop = Math.round(this.horizontalMargin) + 'px';
|
||||||
img.style.marginRight = this.verticalMargin - 7 + 'px'; // -4 is the negative margin of the inline element
|
img.style.marginRight = Math.round(this.verticalMargin - 7) + 'px'; // -4 is the negative margin of the inline element
|
||||||
img.style.marginBottom = this.verticalMargin - 7 + 'px';
|
img.style.marginBottom = Math.round(this.verticalMargin - 7) + 'px';
|
||||||
resultNode = img.parentNode.parentNode;
|
resultNode = img.parentNode.parentNode;
|
||||||
if (!resultNode.classList.contains('js')) {
|
if (!resultNode.classList.contains('js')) {
|
||||||
resultNode.classList.add('js');
|
resultNode.classList.add('js');
|
||||||
|
@ -431,6 +483,23 @@ $(document).ready(function(){
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ImageLayout.prototype.throttleAlign = function () {
|
||||||
|
var obj = this;
|
||||||
|
if (obj.trottleCallToAlign) {
|
||||||
|
obj.alignAfterThrotteling = true;
|
||||||
|
} else {
|
||||||
|
obj.alignAfterThrotteling = false;
|
||||||
|
obj.align();
|
||||||
|
obj.trottleCallToAlign = setTimeout(function () {
|
||||||
|
if (obj.alignAfterThrotteling) {
|
||||||
|
obj.align();
|
||||||
|
}
|
||||||
|
obj.alignAfterThrotteling = false;
|
||||||
|
obj.trottleCallToAlign = null;
|
||||||
|
}, 20);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ImageLayout.prototype.align = function () {
|
ImageLayout.prototype.align = function () {
|
||||||
var i;
|
var i;
|
||||||
var results_selectorNode = d.querySelectorAll(this.results_selector);
|
var results_selectorNode = d.querySelectorAll(this.results_selector);
|
||||||
|
@ -460,9 +529,9 @@ $(document).ready(function(){
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ImageLayout.prototype.watch = function () {
|
ImageLayout.prototype._monitorImages = function () {
|
||||||
var i, img;
|
var i, img;
|
||||||
var obj = this;
|
var objthrottleAlign = this.throttleAlign.bind(this);
|
||||||
var results_nodes = d.querySelectorAll(this.results_selector);
|
var results_nodes = d.querySelectorAll(this.results_selector);
|
||||||
var results_length = results_nodes.length;
|
var results_length = results_nodes.length;
|
||||||
|
|
||||||
|
@ -471,34 +540,53 @@ $(document).ready(function(){
|
||||||
event.originalTarget.src = w.searxng.static_path + w.searxng.theme.img_load_error;
|
event.originalTarget.src = w.searxng.static_path + w.searxng.theme.img_load_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
function throttleAlign () {
|
|
||||||
if (obj.isAlignDone) {
|
|
||||||
obj.isAlignDone = false;
|
|
||||||
setTimeout(function () {
|
|
||||||
obj.align();
|
|
||||||
obj.isAlignDone = true;
|
|
||||||
}, 100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/Window/pageshow_event
|
|
||||||
w.addEventListener('pageshow', throttleAlign);
|
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/FileReader/load_event
|
|
||||||
w.addEventListener('load', throttleAlign);
|
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/Window/resize_event
|
|
||||||
w.addEventListener('resize', throttleAlign);
|
|
||||||
|
|
||||||
for (i = 0; i < results_length; i++) {
|
for (i = 0; i < results_length; i++) {
|
||||||
img = results_nodes[i].querySelector(this.img_selector);
|
img = results_nodes[i].querySelector(this.img_selector);
|
||||||
if (img !== null && img !== undefined) {
|
if (img !== null && img !== undefined && !img.classList.contains('aligned')) {
|
||||||
img.addEventListener('load', throttleAlign);
|
img.addEventListener('load', objthrottleAlign);
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onerror
|
// https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onerror
|
||||||
img.addEventListener('error', throttleAlign);
|
img.addEventListener('error', objthrottleAlign);
|
||||||
|
img.addEventListener('timeout', objthrottleAlign);
|
||||||
if (w.searxng.theme.img_load_error) {
|
if (w.searxng.theme.img_load_error) {
|
||||||
img.addEventListener('error', img_load_error, {once: true});
|
img.addEventListener('error', img_load_error, {once: true});
|
||||||
}
|
}
|
||||||
|
img.classList.add('aligned');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageLayout.prototype.watch = function () {
|
||||||
|
var objthrottleAlign = this.throttleAlign.bind(this);
|
||||||
|
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/API/Window/pageshow_event
|
||||||
|
w.addEventListener('pageshow', objthrottleAlign);
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/API/FileReader/load_event
|
||||||
|
w.addEventListener('load', objthrottleAlign);
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/API/Window/resize_event
|
||||||
|
w.addEventListener('resize', objthrottleAlign);
|
||||||
|
|
||||||
|
this._monitorImages();
|
||||||
|
|
||||||
|
var obj = this;
|
||||||
|
|
||||||
|
let observer = new MutationObserver(entries => {
|
||||||
|
let newElement = false;
|
||||||
|
for (let i = 0; i < entries.length; i++) {
|
||||||
|
if (entries[i].addedNodes.length > 0 && entries[i].addedNodes[0].classList.contains('result')) {
|
||||||
|
newElement = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (newElement) {
|
||||||
|
obj._monitorImages();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
observer.observe(d.querySelector(this.container_selector), {
|
||||||
|
childList: true,
|
||||||
|
subtree: true,
|
||||||
|
attributes: false,
|
||||||
|
characterData: false,
|
||||||
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
w.searxng.ImageLayout = ImageLayout;
|
w.searxng.ImageLayout = ImageLayout;
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* (C) Copyright Contributors to the searx project (2014 - 2021).
|
* (C) Copyright Contributors to the searx project (2014 - 2021).
|
||||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
window.searxng=function(t){"use strict";t.getElementsByTagName("html")[0].className="js";t=t.currentScript||(t=t.getElementsByTagName("script"))[t.length-1];return{autocompleter:"true"===t.getAttribute("data-autocompleter"),method:t.getAttribute("data-method"),translations:JSON.parse(t.getAttribute("data-translations"))}}(document),
|
window.searxng=function(t){"use strict";t.getElementsByTagName("html")[0].className="js";t=t.currentScript||(t=t.getElementsByTagName("script"))[t.length-1];return{autocompleter:"true"===t.getAttribute("data-autocompleter"),infinite_scroll:"true"===t.getAttribute("data-infinite-scroll"),method:t.getAttribute("data-method"),translations:JSON.parse(t.getAttribute("data-translations"))}}(document),
|
||||||
/**
|
/**
|
||||||
* @license
|
* @license
|
||||||
* (C) Copyright Contributors to the SearXNG project.
|
* (C) Copyright Contributors to the SearXNG project.
|
||||||
|
@ -12,7 +12,7 @@ window.searxng=function(t){"use strict";t.getElementsByTagName("html")[0].classN
|
||||||
* (C) 2014 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>
|
* (C) 2014 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>
|
||||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
$(document).ready(function(){var t,a="";searxng.autocompleter&&((t=new Bloodhound({datumTokenizer:Bloodhound.tokenizers.obj.whitespace("value"),queryTokenizer:Bloodhound.tokenizers.whitespace,remote:{url:"./autocompleter?q=%QUERY",wildcard:"%QUERY"}})).initialize(),$("#q").on("keydown",function(t){13==t.which&&(a=$("#q").val())}),$("#q").typeahead({name:"search-results",highlight:!1,hint:!0,displayKey:function(t){return t},classNames:{input:"tt-input",hint:"tt-hint",menu:"tt-dropdown-menu",dataset:"tt-dataset-search-results"}},{name:"autocomplete",source:t}),$("#q").bind("typeahead:select",function(t,e){a&&$("#q").val(a),$("#search_form").submit()}))}),
|
$(document).ready(function(){var t,n="";searxng.autocompleter&&((t=new Bloodhound({datumTokenizer:Bloodhound.tokenizers.obj.whitespace("value"),queryTokenizer:Bloodhound.tokenizers.whitespace,remote:{url:"./autocompleter?q=%QUERY",wildcard:"%QUERY"}})).initialize(),$("#q").on("keydown",function(t){13==t.which&&(n=$("#q").val())}),$("#q").typeahead({name:"search-results",highlight:!1,hint:!0,displayKey:function(t){return t},classNames:{input:"tt-input",hint:"tt-hint",menu:"tt-dropdown-menu",dataset:"tt-dataset-search-results"}},{name:"autocomplete",source:t}),$("#q").bind("typeahead:select",function(t,e){n&&$("#q").val(n),$("#search_form").submit()}))}),
|
||||||
/**
|
/**
|
||||||
* @license
|
* @license
|
||||||
* (C) Copyright Contributors to the SearXNG project.
|
* (C) Copyright Contributors to the SearXNG project.
|
||||||
|
@ -20,7 +20,14 @@ $(document).ready(function(){var t,a="";searxng.autocompleter&&((t=new Bloodhoun
|
||||||
* (C) 2014 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>
|
* (C) 2014 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>
|
||||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
$(document).ready(function(){$("#q.autofocus").focus(),$("#clear_search").click(function(){document.getElementById("q").value=""}),$(".select-all-on-click").click(function(){$(this).select()}),$(".btn-collapse").click(function(){var t=$(this).data("btn-text-collapsed"),e=$(this).data("btn-text-not-collapsed");""!==t&&""!==e&&(new_html=$(this).hasClass("collapsed")?$(this).html().replace(t,e):$(this).html().replace(e,t),$(this).html(new_html))}),$(".btn-toggle .btn").click(function(){var t="btn-"+$(this).data("btn-class"),e=$(this).data("btn-label-default"),a=$(this).data("btn-label-toggled");""!==a&&(new_html=$(this).hasClass("btn-default")?$(this).html().replace(e,a):$(this).html().replace(a,e),$(this).html(new_html)),$(this).toggleClass(t),$(this).toggleClass("btn-default")}),$(".media-loader").click(function(){var t=$(this).data("target"),t=$(t+" > iframe"),e=t.attr("src");void 0!==e&&!1!==e||t.attr("src",t.data("src"))}),$(".btn-sm").dblclick(function(){var t="btn-"+$(this).data("btn-class");$(this).hasClass("btn-default")?($(".btn-sm > input").attr("checked","checked"),$(".btn-sm > input").prop("checked",!0),$(".btn-sm").addClass(t),$(".btn-sm").addClass("active"),$(".btn-sm").removeClass("btn-default")):($(".btn-sm > input").attr("checked",""),$(".btn-sm > input").removeAttr("checked"),$(".btn-sm > input").checked=!1,$(".btn-sm").removeClass(t),$(".btn-sm").removeClass("active"),$(".btn-sm").addClass("btn-default"))}),$(".nav-tabs").click(function(t){$(t.target).parents("ul").children().attr("aria-selected","false"),$(t.target).parent().attr("aria-selected","true")}),searxng.image_thumbnail_layout=new searxng.ImageLayout("#main_results","#main_results .result-images","img.img-thumbnail",15,3,200),searxng.image_thumbnail_layout.watch()}),
|
$(document).ready(function(){$("#q.autofocus").focus(),$("#clear_search").click(function(){document.getElementById("q").value=""}),$(".select-all-on-click").click(function(){$(this).select()}),$(".btn-collapse").click(function(){var t=$(this).data("btn-text-collapsed"),e=$(this).data("btn-text-not-collapsed");""!==t&&""!==e&&(new_html=$(this).hasClass("collapsed")?$(this).html().replace(t,e):$(this).html().replace(e,t),$(this).html(new_html))}),$(".btn-toggle .btn").click(function(){var t="btn-"+$(this).data("btn-class"),e=$(this).data("btn-label-default"),n=$(this).data("btn-label-toggled");""!==n&&(new_html=$(this).hasClass("btn-default")?$(this).html().replace(e,n):$(this).html().replace(n,e),$(this).html(new_html)),$(this).toggleClass(t),$(this).toggleClass("btn-default")}),$(".media-loader").click(function(){var t=$(this).data("target"),t=$(t+" > iframe"),e=t.attr("src");void 0!==e&&!1!==e||t.attr("src",t.data("src"))}),$(".btn-sm").dblclick(function(){var t="btn-"+$(this).data("btn-class");$(this).hasClass("btn-default")?($(".btn-sm > input").attr("checked","checked"),$(".btn-sm > input").prop("checked",!0),$(".btn-sm").addClass(t),$(".btn-sm").addClass("active"),$(".btn-sm").removeClass("btn-default")):($(".btn-sm > input").attr("checked",""),$(".btn-sm > input").removeAttr("checked"),$(".btn-sm > input").checked=!1,$(".btn-sm").removeClass(t),$(".btn-sm").removeClass("active"),$(".btn-sm").addClass("btn-default"))}),$(".nav-tabs").click(function(t){$(t.target).parents("ul").children().attr("aria-selected","false"),$(t.target).parent().attr("aria-selected","true")}),searxng.image_thumbnail_layout=new searxng.ImageLayout("#main_results","#main_results .result-images","img.img-thumbnail",15,3,200),searxng.image_thumbnail_layout.watch()}),
|
||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* (C) Copyright Contributors to the SearXNG project.
|
||||||
|
* (C) Copyright Contributors to the searx project (2014 - 2021).
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
$(document).ready(function(){function e(){var t="BackCompat"==document.compatMode?document.body:document.documentElement;return t.scrollHeight>t.clientHeight}function n(){var t=$("#pagination form:last").serialize();t&&($("#pagination").html('<div class="loading-spinner"></div>'),$.ajax({type:"POST",url:$("#search_form").prop("action"),data:t,dataType:"html",success:function(t){t=$(t);$("#pagination").remove(),$("#main_results").append("<hr/>"),$("#main_results").append(t.find(".result")),$("#main_results").append(t.find("#pagination")),e()||n()}}))}var t;searxng.infinite_scroll&&(t=$(window),$("html").addClass("infinite_scroll"),e()||n(),t.on("scroll",function(){$(document).height()-t.height()-t.scrollTop()<150&&n()}))}),
|
||||||
/**
|
/**
|
||||||
* @license
|
* @license
|
||||||
* (C) Copyright Contributors to the SearXNG project.
|
* (C) Copyright Contributors to the SearXNG project.
|
||||||
|
@ -35,14 +42,14 @@ window.addEventListener("load",function(){$(".infobox").each(function(){var t=$(
|
||||||
* (C) 2014 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>
|
* (C) 2014 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>
|
||||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
$(document).ready(function(){$(".searxng_init_map").on("click",function(t){var e=$(this).data("leaflet-target"),a=$(this).data("map-lon"),n=$(this).data("map-lat"),i=$(this).data("map-zoom"),s=$(this).data("map-boundingbox"),o=$(this).data("map-geojson"),r=(s&&(southWest=L.latLng(s[0],s[2]),northEast=L.latLng(s[1],s[3]),map_bounds=L.latLngBounds(southWest,northEast)),L.Icon.Default.imagePath="./static/themes/oscar/css/images/",L.map(e)),s=new L.TileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",{minZoom:1,maxZoom:19,attribution:'Map data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors'}),e=(new L.TileLayer("https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}.png",{minZoom:1,maxZoom:19,attribution:'Wikimedia maps beta | Maps data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors'}),setTimeout(function(){map_bounds?r.fitBounds(map_bounds,{maxZoom:17}):a&&n&&(i?r.setView(new L.LatLng(n,a),i):r.setView(new L.LatLng(n,a),8))},0),r.addLayer(s),{"OSM Mapnik":s});L.control.layers(e).addTo(r),o&&L.geoJson(o).addTo(r),$(this).off(t)})}),
|
$(document).ready(function(){$(".searxng_init_map").on("click",function(t){var e=$(this).data("leaflet-target"),n=$(this).data("map-lon"),a=$(this).data("map-lat"),i=$(this).data("map-zoom"),o=$(this).data("map-boundingbox"),s=$(this).data("map-geojson"),r=(o&&(southWest=L.latLng(o[0],o[2]),northEast=L.latLng(o[1],o[3]),map_bounds=L.latLngBounds(southWest,northEast)),L.Icon.Default.imagePath="./static/themes/oscar/css/images/",L.map(e)),o=new L.TileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",{minZoom:1,maxZoom:19,attribution:'Map data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors'}),e=(new L.TileLayer("https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}.png",{minZoom:1,maxZoom:19,attribution:'Wikimedia maps beta | Maps data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors'}),setTimeout(function(){map_bounds?r.fitBounds(map_bounds,{maxZoom:17}):n&&a&&(i?r.setView(new L.LatLng(a,n),i):r.setView(new L.LatLng(a,n),8))},0),r.addLayer(o),{"OSM Mapnik":o});L.control.layers(e).addTo(r),s&&L.geoJson(s).addTo(r),$(this).off(t)})}),
|
||||||
/**
|
/**
|
||||||
* @license
|
* @license
|
||||||
* (C) Copyright Contributors to the SearXNG project.
|
* (C) Copyright Contributors to the SearXNG project.
|
||||||
* (C) Copyright Contributors to the searx project (2014 - 2021).
|
* (C) Copyright Contributors to the searx project (2014 - 2021).
|
||||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
$(document).ready(function(){let s=null;document.querySelector('body[class="preferences_endpoint"]')&&$("[data-engine-name]").hover(function(){null==s&&$.ajax("engine_descriptions.json",dataType="json").done(function(t){s=t;for(var[e,a]of Object.entries(t))for(const i of $('[data-engine-name="'+e+'"] .description')){var n=" (<i>"+searxng.translations.Source+": "+a[1]+"</i>)";i.innerHTML=a[0]+n}})})}),
|
$(document).ready(function(){let o=null;document.querySelector('body[class="preferences_endpoint"]')&&$("[data-engine-name]").hover(function(){null==o&&$.ajax("engine_descriptions.json",dataType="json").done(function(t){o=t;for(var[e,n]of Object.entries(t))for(const i of $('[data-engine-name="'+e+'"] .description')){var a=" (<i>"+searxng.translations.Source+": "+n[1]+"</i>)";i.innerHTML=n[0]+a}})})}),
|
||||||
/**
|
/**
|
||||||
* @license
|
* @license
|
||||||
* (C) Copyright Contributors to the SearXNG project.
|
* (C) Copyright Contributors to the SearXNG project.
|
||||||
|
@ -71,5 +78,5 @@ $(document).ready(function(){$("#allow-all-engines").click(function(){$(".onoffs
|
||||||
* );
|
* );
|
||||||
* searxng.image_thumbnail_layout.watch();
|
* searxng.image_thumbnail_layout.watch();
|
||||||
*/
|
*/
|
||||||
function(r,c){function t(t,e,a,n,i,s){this.container_selector=t,this.results_selector=e,this.img_selector=a,this.verticalMargin=n,this.horizontalMargin=i,this.maxHeight=s,this.isAlignDone=!0}t.prototype._getHeigth=function(t,e){for(var a,n=0,i=0;i<t.length;i++)0<(a=t[i]).naturalWidth&&0<a.naturalHeight?n+=a.naturalWidth/a.naturalHeight:n+=1;return(e-t.length*this.verticalMargin)/n},t.prototype._setSize=function(t,e){for(var a,n,i=t.length,s=0;s<i;s++)n=0<(a=t[s]).naturalWidth&&0<a.naturalHeight?e*a.naturalWidth/a.naturalHeight:e,a.style.width=n+"px",a.style.height=e+"px",a.style.marginLeft=this.horizontalMargin+"px",a.style.marginTop=this.horizontalMargin+"px",a.style.marginRight=this.verticalMargin-7+"px",a.style.marginBottom=this.verticalMargin-7+"px",(n=a.parentNode.parentNode).classList.contains("js")||n.classList.add("js")},t.prototype._alignImgs=function(t){for(var e,a,n,i,s=c.querySelector(this.container_selector),o=window.getComputedStyle(s),r=parseInt(o.getPropertyValue("padding-left"),10),o=parseInt(o.getPropertyValue("padding-right"),10),l=s.clientWidth-r-o;0<t.length;){for(e=!0,n=1;n<=t.length&&e;n++)a=t.slice(0,n),(i=this._getHeigth(a,l))<this.maxHeight&&(this._setSize(a,i),t=t.slice(n),e=!1);if(e){this._setSize(a,Math.min(this.maxHeight,i));break}}},t.prototype.align=function(){for(var t=c.querySelectorAll(this.results_selector),e=t.length,a=null,n=null,i=[],s=0;s<e;s++)(n=t[s]).previousElementSibling!==a&&0<i.length&&(this._alignImgs(i),i=[]),i.push(n.querySelector(this.img_selector)),a=n;0<i.length&&this._alignImgs(i)},t.prototype.watch=function(){var t,e,a=this,n=c.querySelectorAll(this.results_selector),i=n.length;function s(t){t.originalTarget.src=r.searxng.static_path+r.searxng.theme.img_load_error}function o(){a.isAlignDone&&(a.isAlignDone=!1,setTimeout(function(){a.align(),a.isAlignDone=!0},100))}for(r.addEventListener("pageshow",o),r.addEventListener("load",o),r.addEventListener("resize",o),t=0;t<i;t++)null!=(e=n[t].querySelector(this.img_selector))&&(e.addEventListener("load",o),e.addEventListener("error",o),r.searxng.theme.img_load_error&&e.addEventListener("error",s,{once:!0}))},r.searxng.ImageLayout=t}(window,document);
|
function(s,c){function t(t,e,n,a,i,o){this.container_selector=t,this.results_selector=e,this.img_selector=n,this.verticalMargin=a,this.horizontalMargin=i,this.maxHeight=o,this.trottleCallToAlign=null,this.alignAfterThrotteling=!1}t.prototype._getHeigth=function(t,e){for(var n,a=0,i=0;i<t.length;i++)0<(n=t[i]).naturalWidth&&0<n.naturalHeight?a+=n.naturalWidth/n.naturalHeight:a+=1;return(e-t.length*this.verticalMargin)/a},t.prototype._setSize=function(t,e){for(var n,a,i=t.length,o=0;o<i;o++)a=0<(n=t[o]).naturalWidth&&0<n.naturalHeight?e*n.naturalWidth/n.naturalHeight:e,n.setAttribute("width",Math.round(a)),n.setAttribute("height",Math.round(e)),n.style.marginLeft=Math.round(this.horizontalMargin)+"px",n.style.marginTop=Math.round(this.horizontalMargin)+"px",n.style.marginRight=Math.round(this.verticalMargin-7)+"px",n.style.marginBottom=Math.round(this.verticalMargin-7)+"px",(a=n.parentNode.parentNode).classList.contains("js")||a.classList.add("js")},t.prototype._alignImgs=function(t){for(var e,n,a,i,o=c.querySelector(this.container_selector),s=window.getComputedStyle(o),r=parseInt(s.getPropertyValue("padding-left"),10),s=parseInt(s.getPropertyValue("padding-right"),10),l=o.clientWidth-r-s;0<t.length;){for(e=!0,a=1;a<=t.length&&e;a++)n=t.slice(0,a),(i=this._getHeigth(n,l))<this.maxHeight&&(this._setSize(n,i),t=t.slice(a),e=!1);if(e){this._setSize(n,Math.min(this.maxHeight,i));break}}},t.prototype.throttleAlign=function(){var t=this;t.trottleCallToAlign?t.alignAfterThrotteling=!0:(t.alignAfterThrotteling=!1,t.align(),t.trottleCallToAlign=setTimeout(function(){t.alignAfterThrotteling&&t.align(),t.alignAfterThrotteling=!1,t.trottleCallToAlign=null},20))},t.prototype.align=function(){for(var t=c.querySelectorAll(this.results_selector),e=t.length,n=null,a=null,i=[],o=0;o<e;o++)(a=t[o]).previousElementSibling!==n&&0<i.length&&(this._alignImgs(i),i=[]),i.push(a.querySelector(this.img_selector)),n=a;0<i.length&&this._alignImgs(i)},t.prototype._monitorImages=function(){var t,e,n=this.throttleAlign.bind(this),a=c.querySelectorAll(this.results_selector),i=a.length;function o(t){t.originalTarget.src=s.searxng.static_path+s.searxng.theme.img_load_error}for(t=0;t<i;t++)null==(e=a[t].querySelector(this.img_selector))||e.classList.contains("aligned")||(e.addEventListener("load",n),e.addEventListener("error",n),e.addEventListener("timeout",n),s.searxng.theme.img_load_error&&e.addEventListener("error",o,{once:!0}),e.classList.add("aligned"))},t.prototype.watch=function(){var t=this.throttleAlign.bind(this),a=(s.addEventListener("pageshow",t),s.addEventListener("load",t),s.addEventListener("resize",t),this._monitorImages(),this);let e=new MutationObserver(e=>{let n=!1;for(let t=0;t<e.length;t++)if(0<e[t].addedNodes.length&&e[t].addedNodes[0].classList.contains("result")){n=!0;break}n&&a._monitorImages()});e.observe(c.querySelector(this.container_selector),{childList:!0,subtree:!0,attributes:!1,characterData:!1})},s.searxng.ImageLayout=t}(window,document);
|
||||||
//# sourceMappingURL=searxng.min.js.map
|
//# sourceMappingURL=searxng.min.js.map
|
File diff suppressed because one or more lines are too long
|
@ -19,6 +19,7 @@ window.searxng = (function(d) {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
autocompleter: script.getAttribute('data-autocompleter') === 'true',
|
autocompleter: script.getAttribute('data-autocompleter') === 'true',
|
||||||
|
infinite_scroll: script.getAttribute('data-infinite-scroll') === 'true',
|
||||||
method: script.getAttribute('data-method'),
|
method: script.getAttribute('data-method'),
|
||||||
translations: JSON.parse(script.getAttribute('data-translations'))
|
translations: JSON.parse(script.getAttribute('data-translations'))
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* (C) Copyright Contributors to the SearXNG project.
|
||||||
|
* (C) Copyright Contributors to the searx project (2014 - 2021).
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
$(document).ready(function() {
|
||||||
|
function hasScrollbar() {
|
||||||
|
var root = document.compatMode=='BackCompat'? document.body : document.documentElement;
|
||||||
|
return root.scrollHeight>root.clientHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadNextPage() {
|
||||||
|
var formData = $('#pagination form:last').serialize();
|
||||||
|
if (formData) {
|
||||||
|
$('#pagination').html('<div class="loading-spinner"></div>');
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: $('#search_form').prop('action'),
|
||||||
|
data: formData,
|
||||||
|
dataType: 'html',
|
||||||
|
success: function(data) {
|
||||||
|
var body = $(data);
|
||||||
|
$('#pagination').remove();
|
||||||
|
$('#main_results').append('<hr/>');
|
||||||
|
$('#main_results').append(body.find('.result'));
|
||||||
|
$('#main_results').append(body.find('#pagination'));
|
||||||
|
if(!hasScrollbar()) {
|
||||||
|
loadNextPage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (searxng.infinite_scroll) {
|
||||||
|
var win = $(window);
|
||||||
|
$("html").addClass('infinite_scroll');
|
||||||
|
if(!hasScrollbar()) {
|
||||||
|
loadNextPage();
|
||||||
|
}
|
||||||
|
win.on('scroll', function() {
|
||||||
|
if ($(document).height() - win.height() - win.scrollTop() < 150) {
|
||||||
|
loadNextPage();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
|
@ -2,6 +2,7 @@
|
||||||
0% { transform: rotate(0deg) }
|
0% { transform: rotate(0deg) }
|
||||||
100% { transform: rotate(360deg) }
|
100% { transform: rotate(360deg) }
|
||||||
}
|
}
|
||||||
|
|
||||||
.loading-spinner {
|
.loading-spinner {
|
||||||
animation-duration: 0.75s;
|
animation-duration: 0.75s;
|
||||||
animation-iteration-count: infinite;
|
animation-iteration-count: infinite;
|
||||||
|
@ -14,6 +15,7 @@
|
||||||
border-radius: 50% !important;
|
border-radius: 50% !important;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
#pagination button {
|
|
||||||
|
html.infinite_scroll #pagination button {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
}
|
}
|
|
@ -4,6 +4,7 @@
|
||||||
@import "../../../../__common__/less/result_templates.less";
|
@import "../../../../__common__/less/result_templates.less";
|
||||||
@import "../../less/result_templates.less";
|
@import "../../less/result_templates.less";
|
||||||
@import "../../less/preferences.less";
|
@import "../../less/preferences.less";
|
||||||
|
@import "../infinite_scroll.less";
|
||||||
@import "../../generated/pygments-logicodev.less";
|
@import "../../generated/pygments-logicodev.less";
|
||||||
|
|
||||||
@stacked-bar-chart: rgb(213, 216, 215, 1);
|
@stacked-bar-chart: rgb(213, 216, 215, 1);
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
@import "../../../../__common__/less/result_templates.less";
|
@import "../../../../__common__/less/result_templates.less";
|
||||||
@import "../../less/result_templates.less";
|
@import "../../less/result_templates.less";
|
||||||
@import "../../less/preferences.less";
|
@import "../../less/preferences.less";
|
||||||
|
@import "../infinite_scroll.less";
|
||||||
@import "../../generated/pygments-logicodev.less";
|
@import "../../generated/pygments-logicodev.less";
|
||||||
|
|
||||||
@import "navbar.less";
|
@import "navbar.less";
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
@import "../../../../__common__/less/result_templates.less";
|
@import "../../../../__common__/less/result_templates.less";
|
||||||
@import "../../less/result_templates.less";
|
@import "../../less/result_templates.less";
|
||||||
@import "../../less/preferences.less";
|
@import "../../less/preferences.less";
|
||||||
|
@import "../infinite_scroll.less";
|
||||||
@import "../../generated/pygments-pointhi.less";
|
@import "../../generated/pygments-pointhi.less";
|
||||||
|
|
||||||
@import "footer.less";
|
@import "footer.less";
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -59,17 +59,12 @@ window.searxng = (function (w, d) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
searxng.http = function (method, url) {
|
searxng.http = function (method, url, data = null) {
|
||||||
var req = new XMLHttpRequest(),
|
return new Promise(function (resolve, reject) {
|
||||||
resolve = function () {},
|
|
||||||
reject = function () {},
|
|
||||||
promise = {
|
|
||||||
then: function (callback) { resolve = callback; return promise; },
|
|
||||||
catch: function (callback) { reject = callback; return promise; }
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
var req = new XMLHttpRequest();
|
||||||
req.open(method, url, true);
|
req.open(method, url, true);
|
||||||
|
req.timeout = 20000;
|
||||||
|
|
||||||
// On load
|
// On load
|
||||||
req.onload = function () {
|
req.onload = function () {
|
||||||
|
@ -89,13 +84,20 @@ window.searxng = (function (w, d) {
|
||||||
reject(Error("Transaction is aborted"));
|
reject(Error("Transaction is aborted"));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
req.ontimeout = function () {
|
||||||
|
reject(Error("Timeout"));
|
||||||
|
}
|
||||||
|
|
||||||
// Make the request
|
// Make the request
|
||||||
|
if (data) {
|
||||||
|
req.send(data)
|
||||||
|
} else {
|
||||||
req.send();
|
req.send();
|
||||||
|
}
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
reject(ex);
|
reject(ex);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
return promise;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
searxng.loadStyle = function (src) {
|
searxng.loadStyle = function (src) {
|
||||||
|
@ -148,5 +150,16 @@ window.searxng = (function (w, d) {
|
||||||
this.parentNode.classList.add('invisible');
|
this.parentNode.classList.add('invisible');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function getEndpoint () {
|
||||||
|
for (var className of d.getElementsByTagName('body')[0].classList.values()) {
|
||||||
|
if (className.endsWith('_endpoint')) {
|
||||||
|
return className.split('_')[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
searxng.endpoint = getEndpoint();
|
||||||
|
|
||||||
return searxng;
|
return searxng;
|
||||||
})(window, document);
|
})(window, document);
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
|
@ -2,6 +2,10 @@
|
||||||
(function (w, d, searxng) {
|
(function (w, d, searxng) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
if (searxng.endpoint !== 'preferences') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
searxng.ready(function () {
|
searxng.ready(function () {
|
||||||
let engine_descriptions = null;
|
let engine_descriptions = null;
|
||||||
function load_engine_descriptions () {
|
function load_engine_descriptions () {
|
||||||
|
@ -19,10 +23,8 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d.querySelector('body[class="preferences_endpoint"]')) {
|
|
||||||
for (const el of d.querySelectorAll('[data-engine-name]')) {
|
for (const el of d.querySelectorAll('[data-engine-name]')) {
|
||||||
searxng.on(el, 'mouseenter', load_engine_descriptions);
|
searxng.on(el, 'mouseenter', load_engine_descriptions);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
});
|
||||||
})(window, document, window.searxng);
|
})(window, document, window.searxng);
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
(function (w, d, searxng) {
|
(function (w, d, searxng) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
if (searxng.endpoint !== 'results') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
searxng.ready(function () {
|
searxng.ready(function () {
|
||||||
searxng.image_thumbnail_layout = new searxng.ImageLayout('#urls', '#urls .result-images', 'img.image_thumbnail', 14, 6, 200);
|
searxng.image_thumbnail_layout = new searxng.ImageLayout('#urls', '#urls .result-images', 'img.image_thumbnail', 14, 6, 200);
|
||||||
searxng.image_thumbnail_layout.watch();
|
searxng.image_thumbnail_layout.watch();
|
||||||
|
|
|
@ -771,15 +771,19 @@ article[data-vim-selected].category-social {
|
||||||
margin: 1rem @results-tablet-offset 0 @results-tablet-offset;
|
margin: 1rem @results-tablet-offset 0 @results-tablet-offset;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 100%;
|
grid-template-columns: 100%;
|
||||||
grid-template-rows: min-content min-content 1fr min-content min-content;
|
grid-template-rows: min-content min-content min-content 1fr min-content;
|
||||||
gap: 0;
|
gap: 0;
|
||||||
grid-template-areas:
|
grid-template-areas:
|
||||||
"corrections"
|
"corrections"
|
||||||
"urls"
|
|
||||||
"answers"
|
"answers"
|
||||||
"sidebar"
|
"sidebar"
|
||||||
|
"urls"
|
||||||
"pagination";
|
"pagination";
|
||||||
|
|
||||||
|
#sidebar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
#urls {
|
#urls {
|
||||||
width: inherit;
|
width: inherit;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|
|
@ -100,6 +100,7 @@
|
||||||
<script src="{{ url_for('static', filename='js/searxng.min.js') }}"
|
<script src="{{ url_for('static', filename='js/searxng.min.js') }}"
|
||||||
data-method="{{ method or 'POST' }}"
|
data-method="{{ method or 'POST' }}"
|
||||||
data-autocompleter="{% if autocomplete %}true{% else %}false{% endif %}"
|
data-autocompleter="{% if autocomplete %}true{% else %}false{% endif %}"
|
||||||
|
data-infinite-scroll="{% if infinite_scroll %}true{% else %}false{% endif %}"
|
||||||
data-translations="{{ translations }}"></script>
|
data-translations="{{ translations }}"></script>
|
||||||
{% for script in scripts %}
|
{% for script in scripts %}
|
||||||
{{""}}<script src="{{ url_for('static', filename=script) }}"></script>
|
{{""}}<script src="{{ url_for('static', filename=script) }}"></script>
|
||||||
|
|
|
@ -248,6 +248,17 @@
|
||||||
{{ preferences_item_footer(info, label, rtl) }}
|
{{ preferences_item_footer(info, label, rtl) }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
{% if 'infinite_scroll' not in locked_preferences %}
|
||||||
|
{% set label = _('Infinite scroll') %}
|
||||||
|
{% set info = _('Automatically load next page when scrolling to bottom of current page') %}
|
||||||
|
{{ preferences_item_header(info, label, rtl, 'infinite_scroll') }}
|
||||||
|
<select class="form-control {{ custom_select_class(rtl) }}" name="infinite_scroll" id="infinite_scroll">
|
||||||
|
<option value="1" {% if infinite_scroll %}selected="selected"{% endif %}>{{ _('On') }}</option>
|
||||||
|
<option value="0" {% if not infinite_scroll %}selected="selected"{% endif %}>{{ _('Off')}}</option>
|
||||||
|
</select>
|
||||||
|
{{ preferences_item_footer(info, label, rtl) }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{{ plugin_of_category('ui' )}}
|
{{ plugin_of_category('ui' )}}
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
data-method="{{ method or 'POST' }}"
|
data-method="{{ method or 'POST' }}"
|
||||||
data-autocompleter="{% if autocomplete %}true{% else %}false{% endif %}"
|
data-autocompleter="{% if autocomplete %}true{% else %}false{% endif %}"
|
||||||
data-search-on-category-select="{{ 'true' if 'plugins/js/search_on_category_select.js' in scripts else 'false'}}"
|
data-search-on-category-select="{{ 'true' if 'plugins/js/search_on_category_select.js' in scripts else 'false'}}"
|
||||||
data-infinite-scroll="{{ 'true' if 'plugins/js/infinite_scroll.js' in scripts else 'false' }}"
|
data-infinite-scroll="{% if infinite_scroll %}true{% else %}false{% endif %}"
|
||||||
data-hotkeys="{{ 'true' if 'plugins/js/vim_hotkeys.js' in scripts else 'false' }}"
|
data-hotkeys="{{ 'true' if 'plugins/js/vim_hotkeys.js' in scripts else 'false' }}"
|
||||||
data-static-path="{{ url_for('static', filename='themes/simple') }}/"
|
data-static-path="{{ url_for('static', filename='themes/simple') }}/"
|
||||||
data-translations="{{ translations }}"></script>
|
data-translations="{{ translations }}"></script>
|
||||||
|
|
|
@ -226,6 +226,18 @@
|
||||||
<div class="description">{{_('Open result links on new browser tabs') }}</div>
|
<div class="description">{{_('Open result links on new browser tabs') }}</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if 'infinite_scroll' not in locked_preferences %}
|
||||||
|
<fieldset>
|
||||||
|
<legend>{{ _('Infinite scroll') }}</legend>
|
||||||
|
<p class="value">
|
||||||
|
<select name='infinite_scroll'>
|
||||||
|
<option value="1" {% if infinite_scroll %}selected="selected"{% endif %}>{{ _('On') }}</option>
|
||||||
|
<option value="0" {% if not infinite_scroll %}selected="selected"{% endif %}>{{ _('Off')}}</option>
|
||||||
|
</select>
|
||||||
|
</p>
|
||||||
|
<div class="description">{{ _('Automatically load next page when scrolling to bottom of current page') }}</div>
|
||||||
|
</fieldset>
|
||||||
|
{% endif %}
|
||||||
{{ plugin_preferences('ui') }}
|
{{ plugin_preferences('ui') }}
|
||||||
{{ tab_footer() }}
|
{{ tab_footer() }}
|
||||||
|
|
||||||
|
|
|
@ -431,6 +431,8 @@ def get_translations():
|
||||||
'no_item_found': gettext('No item found'),
|
'no_item_found': gettext('No item found'),
|
||||||
# /preferences: the source of the engine description (wikipedata, wikidata, website)
|
# /preferences: the source of the engine description (wikipedata, wikidata, website)
|
||||||
'Source': gettext('Source'),
|
'Source': gettext('Source'),
|
||||||
|
# infinite scroll
|
||||||
|
'error_loading_next_page': gettext('Error loading the next page'),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -463,6 +465,7 @@ def render(template_name: str, override_theme: str = None, **kwargs):
|
||||||
kwargs['preferences'] = request.preferences
|
kwargs['preferences'] = request.preferences
|
||||||
kwargs['method'] = request.preferences.get_value('method')
|
kwargs['method'] = request.preferences.get_value('method')
|
||||||
kwargs['autocomplete'] = request.preferences.get_value('autocomplete')
|
kwargs['autocomplete'] = request.preferences.get_value('autocomplete')
|
||||||
|
kwargs['infinite_scroll'] = request.preferences.get_value('infinite_scroll')
|
||||||
kwargs['results_on_new_tab'] = request.preferences.get_value('results_on_new_tab')
|
kwargs['results_on_new_tab'] = request.preferences.get_value('results_on_new_tab')
|
||||||
kwargs['advanced_search'] = request.preferences.get_value('advanced_search')
|
kwargs['advanced_search'] = request.preferences.get_value('advanced_search')
|
||||||
kwargs['query_in_title'] = request.preferences.get_value('query_in_title')
|
kwargs['query_in_title'] = request.preferences.get_value('query_in_title')
|
||||||
|
|
Loading…
Reference in New Issue