diff --git a/defaults/yacy.init b/defaults/yacy.init index a9dc0abfc..a6365f18f 100644 --- a/defaults/yacy.init +++ b/defaults/yacy.init @@ -907,6 +907,11 @@ search.excludehosth= # the cases of nocache, iffresh and ifexist causes an index deletion search.verify.delete = true +# If enabled, the results are sorted in the browser using Javascript. +# This usually improves ranking accuracy, but doesn't work well for users +# who have Javascript disabled, are using screen readers, or are on slow computers. +search.jsresort = false + # remote search details remotesearch.maxcount = 10 remotesearch.maxtime = 3000 diff --git a/htroot/js/yacysearch.js b/htroot/js/yacysearch.js index 8ae63aa59..0b397b121 100644 --- a/htroot/js/yacysearch.js +++ b/htroot/js/yacysearch.js @@ -42,9 +42,12 @@ function fadeOutBar() { } /** + * @param offset item number to start with + * @param itemsperpage count of items requested per page + * @param totalcount count of items available from YaCy node for this query * @returns pagination buttons */ -function renderPaginationButtons(offset, itemsperpage, totalcount, navurlbase, localQuery) { +function renderPaginationButtons(offset, itemsperpage, totalcount, navurlbase, localQuery, jsResort) { var resnav = ""; @@ -95,7 +110,7 @@ function parseFormattedInt(strIntValue) { return intValue; } -function statistics(offset, itemscount, itemsperpage, totalcount, localIndexCount, remoteIndexCount, remotePeerCount, navurlbase, localQuery, feedRunning) { +function statistics(offset, itemscount, itemsperpage, totalcount, localIndexCount, remoteIndexCount, remotePeerCount, navurlbase, localQuery, feedRunning, jsResort) { var totalcountIntValue = parseFormattedInt(totalcount); var offsetIntValue = parseFormattedInt(offset); var itemscountIntValue = parseFormattedInt(itemscount); @@ -173,8 +188,8 @@ function statistics(offset, itemscount, itemsperpage, totalcount, localIndexCoun progresseBarElement.setAttribute('style',"width:" + percent + "%"); } var resnavElement = document.getElementById("resNav"); - if (resnavElement != null) { - resnavElement.innerHTML = renderPaginationButtons(offsetIntValue, itemsperpageIntValue, totalcountIntValue, navurlbase, localQuery); + if (resnavElement != null && !jsResort) { + resnavElement.innerHTML = renderPaginationButtons(offsetIntValue, itemsperpageIntValue, totalcountIntValue, navurlbase, localQuery, jsResort); } } diff --git a/htroot/js/yacysort.js b/htroot/js/yacysort.js new file mode 100644 index 000000000..3b18b4a03 --- /dev/null +++ b/htroot/js/yacysort.js @@ -0,0 +1,342 @@ +var itemCount = 0; +var highestRanking = Infinity; + +var displayPage = function() { + // For every search item that has already been displayed... + $("#resultscontainer").find(".searchresults").each( function(i) { + // Apply the "earlierpage" class IFF the item is from an earlier page. + $(this).toggleClass("earlierpage", parseFloat($(this).data("ranking")) > highestRanking); + }); + + // For every search item from an earlier page... + $("#resultscontainer").find(".searchresults.earlierpage").each( function(i) { + // Hide the item + $(this).removeClass("currentpage"); + $(this).css('animation', '1s 1 forwards hide'); + }); + + // For every search item from a current or later page... + $("#resultscontainer").find(".searchresults:not(.earlierpage)").each( function(i) { + // If we now have too many results, hide the lowest-ranking ones. + if (i >= requestedResults) { + $(this).removeClass("currentpage"); + $(this).css('animation', '1s 1 forwards hide'); + } + else { + $(this).addClass("currentpage"); + $(this).css('display', ''); + $(this).css('animation', '1s 1 forwards show'); + } + }); + + // TODO: The following statistical displays could maybe be moved to the latestinfo() call. + + var offset = $("#resultscontainer").find(".searchresults.earlierpage").length + 1; + var itemscount = $("#resultscontainer").find(".searchresults.earlierpage").length + $("#resultscontainer").find(".searchresults.currentpage").length; + + // TODO: This seems to often be smaller than the "totalcount" that statistics() ends up with. Why is that? + var totalcount = $("#resultscontainer").find(".searchresults").length; + + $("#offset").html(offset); + $("#itemscount").html(itemscount); + + $("#resNav").html(renderPaginationButtons(offset, requestedResults, totalcount, null, theLocalQuery, true)); + + //latestinfo(); + + console.log("Showing results " + ($("#resultscontainer").find(".searchresults.earlierpage").length + 1) + " - " + ($("#resultscontainer").find(".searchresults.earlierpage").length + requestedResults) + " out of " + $("#resultscontainer").find(".searchresults").length + "; notEarlierPage = " + $("#resultscontainer").find(".searchresults:not(.earlierpage)").length); +}; + +var earlierPage = function() { + // Find all items that are on an earlier page. + var allEarlierItems = $("#resultscontainer").find(".searchresults.earlierpage"); + + // If going back one page would put us at the beginning... + if (allEarlierItems.length <= requestedResults) { + highestRanking = Infinity; + } + // If going back one page would still be in the middle of the results... + else { + var earlierItem = allEarlierItems.get().reverse()[ requestedResults - 1 ]; + highestRanking = parseFloat($(earlierItem).data("ranking")); + console.log("highestRanking is now " + highestRanking); + } + + // Update the display to show the new page. + displayPage(); +}; + +var laterPage = function() { + // Find all items that are on a later page. + var allCurrentAndLaterItems = $("#resultscontainer").find(".searchresults:not(.earlierpage)"); + + // If going forward one page would put us past the end... + if (allCurrentAndLaterItems.length <= requestedResults) { + return; + } + // If going forward one page would still be in the middle of the results... + else { + var laterItem = allCurrentAndLaterItems.get(requestedResults); + highestRanking = parseFloat($(laterItem).data("ranking")); + console.log("highestRanking is now " + highestRanking); + } + + // Update the display to show the new page. + displayPage(); +}; + +// pageNumber starts at 0. +var numberedPage = function(pageNumber) { + // Find all items. + var allItems = $("#resultscontainer").find(".searchresults"); + + var itemNumber = pageNumber * requestedResults; + + // Check if the item number is too high. + while ( allItems.length - 1 < itemNumber) { + itemNumber = itemNumber - requestedResults; + } + + // If the beginning of results is requested, set highestRanking to Infinity. + if ( itemNumber <= 0 ) { + highestRanking = Infinity; + } + else { + var item = allItems.get(itemNumber); + highestRanking = parseFloat($(item).data("ranking")); + } + + console.log("highestRanking is now " + highestRanking); + + // Update the display to show the new page. + displayPage(); +}; + +var processSidebarNavProtocols = function(navProtocolsOld, navProtocolsNew) { + navProtocolsOld.find(".btn-group-xs").each( function(index, oldProtocol) { + var protocolId = $(oldProtocol).attr("id"); + + var newProtocol = navProtocolsNew.find("#" + protocolId); + + // Check whether the protocol has been removed in the new sidebar. + if (newProtocol.length === 0) { + console.log("Deleting nav-protocol..."); + $(oldProtocol).hide(1000); + } + } ); + + navProtocolsNew.find(".btn-group-xs").each( function(index, newProtocol) { + var protocolId = $(newProtocol).attr("id"); + + var oldProtocol = navProtocolsOld.find("#" + protocolId); + + // Check whether the protocol exists in both the new and old sidebar + if (oldProtocol.length === 1) { + // Replace the HTML. + // TODO: Look into smoother animations. + $(oldProtocol).html($(newProtocol).html()).show(1000); + } + + // Check whether the protocol has been added in the new sidebar. + if (oldProtocol.length === 0) { + // We need to insert the protocol in the right position. + + // TODO: Insert in the correct position instead of the end. + $(newProtocol).hide(); + $(navProtocolsOld).append($(newProtocol)); + $(newProtocol).show(1000); + } + } ); +}; + +// TODO: test this function +// This is for sidebar items that are