1
0
mirror of https://github.com/searxng/searxng.git synced 2024-11-05 04:40:11 +01:00

Merge pull request #689 from mrpaulblack/images-flexbox

[simple theme] use flexbox instead of js for positioning images
This commit is contained in:
Alexandre Flament 2022-02-27 10:36:55 +01:00 committed by GitHub
commit afde954df8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 363 additions and 345 deletions

View File

@ -278,12 +278,18 @@ class ResultContainer:
result['parsed_url'] = result['parsed_url']._replace(scheme="http")
result['url'] = result['parsed_url'].geturl()
# avoid duplicate content between the content and title fields
if result.get('content') == result.get('title'):
del result['content']
# make sure there is a template
if 'template' not in result:
result['template'] = 'default.html'
# strip multiple spaces and cariage returns from content
if result.get('content'):
result['content'] = WHITESPACE_REGEX.sub(' ', result['content'])
return True
def __merge_url_result(self, result, position):
result['engines'] = set([result['engine']])
with self._lock:

File diff suppressed because one or more lines are too long

View File

@ -60,7 +60,7 @@ module.exports = function(grunt) {
separator: ';'
},
dist: {
src: ['src/js/*.js', '../__common__/js/image_layout.js'],
src: ['src/js/*.js'],
dest: 'js/searxng.js'
}
},

View File

@ -183,6 +183,230 @@ $(document).ready(function(){
searxng.image_thumbnail_layout = new searxng.ImageLayout('#main_results', '#main_results .result-images', 'img.img-thumbnail', 15, 3, 200);
searxng.image_thumbnail_layout.watch();
});
;/**
*
* Google Image Layout v0.0.1
* Description, by Anh Trinh.
* Heavily modified for searx
* https://ptgamr.github.io/2014-09-12-google-image-layout/
* https://ptgamr.github.io/google-image-layout/src/google-image-layout.js
*
* @license Free to use under the MIT License.
*
* @example <caption>Example usage of searxng.ImageLayout class.</caption>
* searxng.image_thumbnail_layout = new searxng.ImageLayout(
* '#urls', // container_selector
* '#urls .result-images', // results_selector
* 'img.image_thumbnail', // img_selector
* 14, // verticalMargin
* 6, // horizontalMargin
* 200 // maxHeight
* );
* searxng.image_thumbnail_layout.watch();
*/
(function (w, d) {
function ImageLayout (container_selector, results_selector, img_selector, verticalMargin, horizontalMargin, maxHeight) {
this.container_selector = container_selector;
this.results_selector = results_selector;
this.img_selector = img_selector;
this.verticalMargin = verticalMargin;
this.horizontalMargin = horizontalMargin;
this.maxHeight = maxHeight;
this.trottleCallToAlign = null;
this.alignAfterThrotteling = false;
}
/**
* Get the height that make all images fit the container
*
* width = w1 + w2 + w3 + ... = r1*h + r2*h + r3*h + ...
*
* @param {[type]} images the images to be calculated
* @param {[type]} width the container witdth
* @param {[type]} margin the margin between each image
*
* @return {[type]} the height
*/
ImageLayout.prototype._getHeigth = function (images, width) {
var i, img;
var r = 0;
for (i = 0; i < images.length; i++) {
img = images[i];
if ((img.naturalWidth > 0) && (img.naturalHeight > 0)) {
r += img.naturalWidth / img.naturalHeight;
} else {
// assume that not loaded images are square
r += 1;
}
}
return (width - images.length * this.verticalMargin) / r; // have to round down because Firefox will automatically roundup value with number of decimals > 3
};
ImageLayout.prototype._setSize = function (images, height) {
var i, img, imgWidth;
var imagesLength = images.length, resultNode;
for (i = 0; i < imagesLength; i++) {
img = images[i];
if ((img.naturalWidth > 0) && (img.naturalHeight > 0)) {
imgWidth = height * img.naturalWidth / img.naturalHeight;
} else {
// not loaded image : make it square as _getHeigth said it
imgWidth = height;
}
img.setAttribute('width', Math.round(imgWidth));
img.setAttribute('height', Math.round(height));
img.style.marginLeft = Math.round(this.horizontalMargin) + 'px';
img.style.marginTop = Math.round(this.horizontalMargin) + 'px';
img.style.marginRight = Math.round(this.verticalMargin - 7) + 'px'; // -4 is the negative margin of the inline element
img.style.marginBottom = Math.round(this.verticalMargin - 7) + 'px';
resultNode = img.parentNode.parentNode;
if (!resultNode.classList.contains('js')) {
resultNode.classList.add('js');
}
}
};
ImageLayout.prototype._alignImgs = function (imgGroup) {
var isSearching, slice, i, h;
var containerElement = d.querySelector(this.container_selector);
var containerCompStyles = window.getComputedStyle(containerElement);
var containerPaddingLeft = parseInt(containerCompStyles.getPropertyValue('padding-left'), 10);
var containerPaddingRight = parseInt(containerCompStyles.getPropertyValue('padding-right'), 10);
var containerWidth = containerElement.clientWidth - containerPaddingLeft - containerPaddingRight;
while (imgGroup.length > 0) {
isSearching = true;
for (i = 1; i <= imgGroup.length && isSearching; i++) {
slice = imgGroup.slice(0, i);
h = this._getHeigth(slice, containerWidth);
if (h < this.maxHeight) {
this._setSize(slice, h);
// continue with the remaining images
imgGroup = imgGroup.slice(i);
isSearching = false;
}
}
if (isSearching) {
this._setSize(slice, Math.min(this.maxHeight, h));
break;
}
}
};
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 () {
var i;
var results_selectorNode = d.querySelectorAll(this.results_selector);
var results_length = results_selectorNode.length;
var previous = null;
var current = null;
var imgGroup = [];
for (i = 0; i < results_length; i++) {
current = results_selectorNode[i];
if (current.previousElementSibling !== previous && imgGroup.length > 0) {
// the current image is not connected to previous one
// so the current image is the start of a new group of images.
// so call _alignImgs to align the current group
this._alignImgs(imgGroup);
// and start a new empty group of images
imgGroup = [];
}
// add the current image to the group (only the img tag)
imgGroup.push(current.querySelector(this.img_selector));
// update the previous variable
previous = current;
}
// align the remaining images
if (imgGroup.length > 0) {
this._alignImgs(imgGroup);
}
};
ImageLayout.prototype._monitorImages = function () {
var i, img;
var objthrottleAlign = this.throttleAlign.bind(this);
var results_nodes = d.querySelectorAll(this.results_selector);
var results_length = results_nodes.length;
function img_load_error (event) {
// console.log("ERROR can't load: " + event.originalTarget.src);
event.originalTarget.src = w.searxng.static_path + w.searxng.theme.img_load_error;
}
for (i = 0; i < results_length; i++) {
img = results_nodes[i].querySelector(this.img_selector);
if (img !== null && img !== undefined && !img.classList.contains('aligned')) {
img.addEventListener('load', objthrottleAlign);
// https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onerror
img.addEventListener('error', objthrottleAlign);
img.addEventListener('timeout', objthrottleAlign);
if (w.searxng.theme.img_load_error) {
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;
}(window, document));
;/**
* @license
* (C) Copyright Contributors to the SearXNG project.
@ -368,227 +592,3 @@ $(document).ready(function(){
});
});
;/**
*
* Google Image Layout v0.0.1
* Description, by Anh Trinh.
* Heavily modified for searx
* https://ptgamr.github.io/2014-09-12-google-image-layout/
* https://ptgamr.github.io/google-image-layout/src/google-image-layout.js
*
* @license Free to use under the MIT License.
*
* @example <caption>Example usage of searxng.ImageLayout class.</caption>
* searxng.image_thumbnail_layout = new searxng.ImageLayout(
* '#urls', // container_selector
* '#urls .result-images', // results_selector
* 'img.image_thumbnail', // img_selector
* 14, // verticalMargin
* 6, // horizontalMargin
* 200 // maxHeight
* );
* searxng.image_thumbnail_layout.watch();
*/
(function (w, d) {
function ImageLayout (container_selector, results_selector, img_selector, verticalMargin, horizontalMargin, maxHeight) {
this.container_selector = container_selector;
this.results_selector = results_selector;
this.img_selector = img_selector;
this.verticalMargin = verticalMargin;
this.horizontalMargin = horizontalMargin;
this.maxHeight = maxHeight;
this.trottleCallToAlign = null;
this.alignAfterThrotteling = false;
}
/**
* Get the height that make all images fit the container
*
* width = w1 + w2 + w3 + ... = r1*h + r2*h + r3*h + ...
*
* @param {[type]} images the images to be calculated
* @param {[type]} width the container witdth
* @param {[type]} margin the margin between each image
*
* @return {[type]} the height
*/
ImageLayout.prototype._getHeigth = function (images, width) {
var i, img;
var r = 0;
for (i = 0; i < images.length; i++) {
img = images[i];
if ((img.naturalWidth > 0) && (img.naturalHeight > 0)) {
r += img.naturalWidth / img.naturalHeight;
} else {
// assume that not loaded images are square
r += 1;
}
}
return (width - images.length * this.verticalMargin) / r; // have to round down because Firefox will automatically roundup value with number of decimals > 3
};
ImageLayout.prototype._setSize = function (images, height) {
var i, img, imgWidth;
var imagesLength = images.length, resultNode;
for (i = 0; i < imagesLength; i++) {
img = images[i];
if ((img.naturalWidth > 0) && (img.naturalHeight > 0)) {
imgWidth = height * img.naturalWidth / img.naturalHeight;
} else {
// not loaded image : make it square as _getHeigth said it
imgWidth = height;
}
img.setAttribute('width', Math.round(imgWidth));
img.setAttribute('height', Math.round(height));
img.style.marginLeft = Math.round(this.horizontalMargin) + 'px';
img.style.marginTop = Math.round(this.horizontalMargin) + 'px';
img.style.marginRight = Math.round(this.verticalMargin - 7) + 'px'; // -4 is the negative margin of the inline element
img.style.marginBottom = Math.round(this.verticalMargin - 7) + 'px';
resultNode = img.parentNode.parentNode;
if (!resultNode.classList.contains('js')) {
resultNode.classList.add('js');
}
}
};
ImageLayout.prototype._alignImgs = function (imgGroup) {
var isSearching, slice, i, h;
var containerElement = d.querySelector(this.container_selector);
var containerCompStyles = window.getComputedStyle(containerElement);
var containerPaddingLeft = parseInt(containerCompStyles.getPropertyValue('padding-left'), 10);
var containerPaddingRight = parseInt(containerCompStyles.getPropertyValue('padding-right'), 10);
var containerWidth = containerElement.clientWidth - containerPaddingLeft - containerPaddingRight;
while (imgGroup.length > 0) {
isSearching = true;
for (i = 1; i <= imgGroup.length && isSearching; i++) {
slice = imgGroup.slice(0, i);
h = this._getHeigth(slice, containerWidth);
if (h < this.maxHeight) {
this._setSize(slice, h);
// continue with the remaining images
imgGroup = imgGroup.slice(i);
isSearching = false;
}
}
if (isSearching) {
this._setSize(slice, Math.min(this.maxHeight, h));
break;
}
}
};
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 () {
var i;
var results_selectorNode = d.querySelectorAll(this.results_selector);
var results_length = results_selectorNode.length;
var previous = null;
var current = null;
var imgGroup = [];
for (i = 0; i < results_length; i++) {
current = results_selectorNode[i];
if (current.previousElementSibling !== previous && imgGroup.length > 0) {
// the current image is not connected to previous one
// so the current image is the start of a new group of images.
// so call _alignImgs to align the current group
this._alignImgs(imgGroup);
// and start a new empty group of images
imgGroup = [];
}
// add the current image to the group (only the img tag)
imgGroup.push(current.querySelector(this.img_selector));
// update the previous variable
previous = current;
}
// align the remaining images
if (imgGroup.length > 0) {
this._alignImgs(imgGroup);
}
};
ImageLayout.prototype._monitorImages = function () {
var i, img;
var objthrottleAlign = this.throttleAlign.bind(this);
var results_nodes = d.querySelectorAll(this.results_selector);
var results_length = results_nodes.length;
function img_load_error (event) {
// console.log("ERROR can't load: " + event.originalTarget.src);
event.originalTarget.src = w.searxng.static_path + w.searxng.theme.img_load_error;
}
for (i = 0; i < results_length; i++) {
img = results_nodes[i].querySelector(this.img_selector);
if (img !== null && img !== undefined && !img.classList.contains('aligned')) {
img.addEventListener('load', objthrottleAlign);
// https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onerror
img.addEventListener('error', objthrottleAlign);
img.addEventListener('timeout', objthrottleAlign);
if (w.searxng.theme.img_load_error) {
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;
}(window, document));

View File

@ -4,7 +4,7 @@
* (C) Copyright Contributors to the searx project (2014 - 2021).
* 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"),infinite_scroll:"true"===t.getAttribute("data-infinite-scroll"),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";var e,e=t.currentScript||(e=t.getElementsByTagName("script"))[e.length-1];return{autocompleter:"true"===e.getAttribute("data-autocompleter"),infinite_scroll:"true"===e.getAttribute("data-infinite-scroll"),method:e.getAttribute("data-method"),translations:JSON.parse(e.getAttribute("data-translations"))}}(document),
/**
* @license
* (C) Copyright Contributors to the SearXNG project.
@ -20,43 +20,7 @@ $(document).ready(function(){var t,n="";searxng.autocompleter&&((t=new Bloodhoun
* (C) 2014 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>
* 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"),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
* (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(){$(".infobox").each(function(){var t=$(this).find(".infobox_body");t.prop("scrollHeight")+t.find("img.infobox_part").height()<=t.css("max-height").replace("px","")&&$(this).find(".infobox_toggle").hide()})}),
/**
* @license
* (C) Copyright Contributors to the SearXNG project.
* (C) Copyright Contributors to the searx project (2014 - 2021).
* (C) 2014 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
$(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
* (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(){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+":&nbsp;"+n[1]+"</i>)";i.innerHTML=n[0]+a}})})}),
/**
* @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(){$("#allow-all-engines").click(function(){$(".onoffswitch-checkbox").each(function(){this.checked=!1})}),$("#disable-all-engines").click(function(){$(".onoffswitch-checkbox").each(function(){this.checked=!0})})}),
$(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"),e=$(t+" > iframe"),t=e.attr("src");void 0!==t&&!1!==t||e.attr("src",e.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()}),
/**
*
* Google Image Layout v0.0.1
@ -78,5 +42,41 @@ $(document).ready(function(){$("#allow-all-engines").click(function(){$(".onoffs
* );
* searxng.image_thumbnail_layout.watch();
*/
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);
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++)n=0<(a=t[o]).naturalWidth&&0<a.naturalHeight?e*a.naturalWidth/a.naturalHeight:e,a.setAttribute("width",Math.round(n)),a.setAttribute("height",Math.round(e)),a.style.marginLeft=Math.round(this.horizontalMargin)+"px",a.style.marginTop=Math.round(this.horizontalMargin)+"px",a.style.marginRight=Math.round(this.verticalMargin-7)+"px",a.style.marginBottom=Math.round(this.verticalMargin-7)+"px",(a=a.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);s.addEventListener("pageshow",t),s.addEventListener("load",t),s.addEventListener("resize",t),this._monitorImages();var a=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),
/**
* @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
* (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(){$(".infobox").each(function(){var t=$(this).find(".infobox_body");t.prop("scrollHeight")+t.find("img.infobox_part").height()<=t.css("max-height").replace("px","")&&$(this).find(".infobox_toggle").hide()})}),
/**
* @license
* (C) Copyright Contributors to the SearXNG project.
* (C) Copyright Contributors to the searx project (2014 - 2021).
* (C) 2014 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
$(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");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/";var r=L.map(e),e=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'});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(e),L.control.layers({"OSM Mapnik":e}).addTo(r),s&&L.geoJson(s).addTo(r),$(this).off(t)})}),
/**
* @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(){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+":&nbsp;"+n[1]+"</i>)";i.innerHTML=n[0]+a}})})}),
/**
* @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(){$("#allow-all-engines").click(function(){$(".onoffswitch-checkbox").each(function(){this.checked=!1})}),$("#disable-all-engines").click(function(){$(".onoffswitch-checkbox").each(function(){this.checked=!0})})});
//# sourceMappingURL=searxng.min.js.map

File diff suppressed because one or more lines are too long

View File

@ -128,7 +128,7 @@
obj.trottleCallToAlign = null;
}, 20);
}
}
};
ImageLayout.prototype.align = function () {
var i;
@ -183,7 +183,7 @@
img.classList.add('aligned');
}
}
}
};
ImageLayout.prototype.watch = function () {
var objthrottleAlign = this.throttleAlign.bind(this);
@ -216,7 +216,7 @@
subtree: true,
attributes: false,
characterData: false,
})
});
};
w.searxng.ImageLayout = ImageLayout;

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

View File

@ -108,7 +108,6 @@ module.exports = function (grunt) {
'js/searxng.head.min.js': ['src/js/head/*.js'],
'js/searxng.min.js': [
'src/js/main/*.js',
'../__common__/js/*.js',
'./node_modules/autocomplete-js/dist/autocomplete.js'
]
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -7,9 +7,6 @@
}
searxng.ready(function () {
searxng.image_thumbnail_layout = new searxng.ImageLayout('#urls', '#urls .result-images', 'img.image_thumbnail', 14, 6, 200);
searxng.image_thumbnail_layout.watch();
d.querySelectorAll('#urls img.image').forEach(
img =>
img.addEventListener(
@ -74,13 +71,11 @@
}
}
d.getElementById('results').classList.add('image-detail-open');
searxng.image_thumbnail_layout.align();
searxng.scrollPageToSelected();
}
searxng.closeDetail = function (e) {
d.getElementById('results').classList.remove('image-detail-open');
searxng.image_thumbnail_layout.align();
searxng.scrollPageToSelected();
}
searxng.on('.result-detail-close', 'click', e => {

View File

@ -68,8 +68,8 @@
--color-result-search-url-border: #ddd;
--color-result-search-url-font: #000;
// Images Colors
--color-result-image-span-background-hover: rgba(0, 0, 0, 0.6);
--color-result-image-span-font: #fff;
--color-result-image-span-font: #444;
--color-result-image-span-font-selected: #fff;
--color-result-image-background: #fff;
/// Settings Colors
--color-settings-tr-hover: #f7f7f7;
@ -179,8 +179,8 @@
--color-result-detail-loader-border: rgba(255, 255, 255, 0.2);
--color-result-detail-loader-borderleft: rgba(0, 0, 0, 0);
// Images Colors
--color-result-image-span-background-hover: rgba(0, 0, 0, 0.6);
--color-result-image-span-font: #fff;
--color-result-image-span-font: #bbb;
--color-result-image-span-font-selected: #222;
--color-result-image-background: #222;
/// Settings Colors
--color-settings-tr-hover: #2d2d2d;
@ -230,9 +230,11 @@
@results-gap: 5rem;
@results-margin: 0.125rem;
@result-padding: 1rem;
@results-image-row-height: 12rem;
@results-image-row-height-phone: 6rem;
@search-width: 40rem;
// heigh of #search, see detail.less
@search-height: 7.75rem;
@search-height: 7.6rem;
/// Device Size
/// @desktop > @tablet

View File

@ -39,6 +39,7 @@ article.result-images .detail {
border: none;
object-fit: contain;
width: inherit;
height: inherit;
max-width: 100%;
min-height: inherit;
max-height: calc(100vh - 25rem - 7rem);

View File

@ -83,6 +83,11 @@
}
}
// Image flexbox
#main_results div#results.only_template_images #urls {
direction: rtl;
}
// Image detail
#results.image-detail-open article.result-images[data-vim-selected] .detail .result-images-labels p {
direction: rtl;

View File

@ -143,6 +143,10 @@ article.result-images[data-vim-selected] {
.image_thumbnail {
filter: opacity(60%);
}
span.title {
color: var(--color-result-image-span-font-selected);
}
}
article[data-vim-selected].category-videos,
@ -284,6 +288,16 @@ article[data-vim-selected].category-social {
}
}
.template_group_images {
display: flex;
flex-wrap: wrap;
}
.template_group_images::after {
flex-grow: 10;
content: "";
}
.category-videos,
.category-news,
.category-map,
@ -357,40 +371,38 @@ article[data-vim-selected].category-social {
}
.result-images {
display: inline-block;
margin: 0;
padding: 0;
position: relative;
max-height: 200px;
flex-grow: 1;
padding: 0.5rem 0.5rem 2rem 0.5rem;
margin: 0.25rem;
border: none !important;
height: @results-image-row-height;
& > a {
position: relative;
}
img {
float: inherit;
margin: 0.125rem;
margin: 0;
padding: 0;
border: none;
max-height: 200px;
height: 100%;
width: 100%;
object-fit: cover;
vertical-align: bottom;
background: var(--color-result-image-background);
}
span.title {
display: none;
color: var(--color-result-image-span-font);
}
&:hover span.title {
display: block;
position: absolute;
bottom: 0;
.ltr-right(0);
padding: 4px;
margin-top: 0;
.ltr-margin-right(0);
margin-bottom: 4px;
.ltr-margin-left(4px);
// color: @color-result-image-span-font;
background-color: var(--color-result-image-span-background-hover);
font-size: 0.7em;
width: 100%;
font-size: 0.9rem;
color: var(--color-result-image-span-font);
padding: 0.5rem 0 0 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
@ -785,8 +797,14 @@ article[data-vim-selected].category-social {
}
#urls {
width: inherit;
margin: 0;
display: flex;
flex-wrap: wrap;
}
#urls::after {
flex-grow: 10;
content: "";
}
#backToTop {
@ -837,8 +855,7 @@ article[data-vim-selected].category-social {
.result-images {
margin: 0;
padding: 0;
border: none;
height: @results-image-row-height-phone;
}
}

View File

@ -15,7 +15,7 @@
{% if results and results|map(attribute='template')|unique|list|count == 1 %}
{% set only_template = 'only_template_' + results[0]['template']|default('default')|replace('.html', '') %}
{% else %}
{% set unique_template = '' %}
{% set only_template = '' %}
{% endif %}
<div id="results" class="{{ only_template }}">
@ -131,12 +131,10 @@
<div id="urls">
{% for result in results %}
{% if result.open_group and not only_template %}<div class="template_group_{{ result['template']|replace('.html', '') }}">{% endif %}
{% set index = loop.index %}
{% if result['template'] %}
{% include get_result_template('simple', result['template']) %}
{% else %}
{% include 'simple/result_templates/default.html' %}
{% endif %}
{% include get_result_template('simple', result['template']) %}
{% if result.close_group and not only_template %}</div>{% endif %}
{% endfor %}
{% if not results and not answers %}
{% include 'simple/messages/no_results.html' %}

View File

@ -726,6 +726,9 @@ def search():
# Server-Timing header
request.timings = result_container.get_timings() # pylint: disable=assigning-non-slot
current_template = None
previous_result = None
# output
for result in results:
if output_format == 'html':
@ -762,6 +765,18 @@ def search():
else:
result['publishedDate'] = format_date(result['publishedDate'])
# set result['open_group'] = True when the template changes from the previous result
# set result['close_group'] = True when the template changes on the next result
if current_template != result.get('template'):
result['open_group'] = True
if previous_result:
previous_result['close_group'] = True # pylint: disable=unsupported-assignment-operation
current_template = result.get('template')
previous_result = result
if previous_result:
previous_result['close_group'] = True
if output_format == 'json':
x = {
'query': search_query.query,

View File

@ -33,7 +33,8 @@ class ViewsTestCase(SearxTestCase):
'engine': 'startpage',
'parsed_url': ParseResult(
scheme='http', netloc='first.test.xyz', path='/', params='', query='', fragment=''
), # noqa
),
'template': 'default.html',
},
{
'content': 'second test content',
@ -43,7 +44,8 @@ class ViewsTestCase(SearxTestCase):
'engine': 'youtube',
'parsed_url': ParseResult(
scheme='http', netloc='second.test.xyz', path='/', params='', query='', fragment=''
), # noqa
),
'template': 'default.html',
},
]