summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--defaults/yacy.init5
-rw-r--r--htroot/js/yacysort.js139
-rw-r--r--htroot/yacysearch.html42
-rw-r--r--htroot/yacysearch.java9
4 files changed, 190 insertions, 5 deletions
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/yacysort.js b/htroot/js/yacysort.js
new file mode 100644
index 000000000..4ed983506
--- /dev/null
+++ b/htroot/js/yacysort.js
@@ -0,0 +1,139 @@
+var itemCount = 0;
+var highestRanking = Infinity;
+
+var displayPage = function() {
+ // For every search item that has already been displayed...
+ $("#resultscontainer .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 .searchresults.earlierpage").each( function(i) {
+ // Hide the item
+ $(this).removeClass("currentpage");
+ $(this).hide(1000);
+ });
+
+ // For every search item from a current or later page...
+ $("#resultscontainer .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).hide(1000);
+ }
+ else {
+ $(this).addClass("currentpage");
+ $(this).show(1000);
+ }
+ });
+
+ $("#offset").html($("#resultscontainer .searchresults.earlierpage").length + 1);
+ $("#itemscount").html($("#resultscontainer .searchresults.earlierpage").length + $("#resultscontainer .searchresults.currentpage").length);
+
+ console.log("Showing results " + ($("#resultscontainer .searchresults.earlierpage").length + 1) + " - " + ($("#resultscontainer .searchresults.earlierpage").length + requestedResults) + " out of " + $("#resultscontainer .searchresults").length + "; notEarlierPage = " + $("#resultscontainer .searchresults:not(.earlierpage)").length);
+};
+
+var earlierPage = function() {
+ // Find all items that are on an earlier page.
+ var allEarlierItems = $("#resultscontainer .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 .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();
+};
+
+var processItem = function(data) {
+ var newItem = $(data).hide();
+
+ // If we didn't get a valid response from YaCy, wait 1 second and try again.
+ if( ! newItem.data("ranking") ) {
+ //console.log("Got undefined item, waiting 1 second...");
+ setTimeout(function() {
+ $.get(
+ "yacysearchitem.html",
+ {
+ eventID: theEventID,
+ item: itemCount
+ },
+ processItem
+ );
+ }, 1000);
+ return;
+ }
+
+ // For every search item that has already been displayed...
+ $("#resultscontainer .searchresults").each( function(i) {
+ // If the existing search item is lower-ranked than the new item...
+ if (parseFloat($(this).data("ranking")) <= parseFloat(newItem.data("ranking")) ) {
+ // Insert new item before the existing item
+ newItem.insertBefore(this);
+
+ return false;
+ }
+ // If the new item is lower-ranked than all existing items...
+ else if (i == $("#resultscontainer .searchresults").length - 1) {
+ // And if the new item (position i + 1) would be ranked 0 to requestedResults - 1...
+ if (i + 1 < requestedResults) {
+ // Insert new item at the end
+ newItem.appendTo("#resultscontainer");
+ return false;
+ }
+ // If the new item is too irrelevant to be displayed...
+ else {
+ // Insert new item at the end
+ newItem.appendTo("#resultscontainer");
+ console.log("Hiding search result because ranking " + newItem.data("ranking") + " too low.");
+ return false;
+ }
+ }
+ });
+
+ // Special case if this is the first search item...
+ if ($("#resultscontainer .searchresults").length === 0) {
+ // Display the new item
+ newItem.appendTo("#resultscontainer");
+ }
+
+ displayPage();
+
+ // Increment itemCount and get another item.
+ itemCount++;
+ $.get(
+ "yacysearchitem.html",
+ {
+ eventID: theEventID,
+ item: itemCount
+ },
+ processItem
+ );
+};
diff --git a/htroot/yacysearch.html b/htroot/yacysearch.html
index 8a46a2041..437bfccb5 100644
--- a/htroot/yacysearch.html
+++ b/htroot/yacysearch.html
@@ -12,6 +12,13 @@
<script type="text/javascript" src="js/highslide/highslide.js"></script>
<script type="text/javascript">hs.outlineType = 'rounded-white';</script>
<script type="text/javascript" src="env/bootstrap/js/typeahead.jquery.min.js"></script>
+ #(jsResort)#::
+ <script type="text/javascript">
+ var requestedResults = #[results]#;
+ var theEventID = "#[eventID]#";
+ </script>
+ <script type="text/javascript" src="js/yacysort.js"></script>
+ #(/jsResort)#
<script type="text/javascript">
var suggestMatcher = function() {
return function opensearch(q, cb) {
@@ -31,7 +38,19 @@
});
};
};
+
$(document).ready(function() {
+ #(jsResort)#::
+ $.get(
+ "yacysearchitem.html",
+ {
+ eventID: theEventID,
+ item: itemCount
+ },
+ processItem
+ );
+ #(/jsResort)#
+
$('#search').typeahead({hint:false,highlight:true,minLength:1}, {
name: 'states',
displayKey: 'value',
@@ -175,9 +194,14 @@ document.getElementById("Enter").innerHTML = "search again";
<!-- linklist begin -->
#(resultTable)#::<table width="100%"><tr class="TableHeader"><td width="30%">Media</td><td width="70%">URL</td></tr>#(/resultTable)#
-#{results}#
-<!--#include virtual="yacysearchitem.html?item=#[item]#&eventID=#[eventID]#" -->
-#{/results}#
+#(jsResort)#
+ #{results}#
+ <!--#include virtual="yacysearchitem.html?item=#[item]#&eventID=#[eventID]#" -->
+ #{/results}#
+::
+ <div id="resultscontainer">
+ </div>
+#(/jsResort)#
#(resultTable)#::</table>#(/resultTable)#
<!-- linklist end -->
@@ -185,7 +209,11 @@ document.getElementById("Enter").innerHTML = "search again";
::
::
::
- <span id="resNav" class="col-sm-12 col-md-12" style="display: inline;"></span>
+ #(jsResort)#
+ <span id="resNav" class="col-sm-12 col-md-12" style="display: inline;"></span>
+ ::
+ <p><br><br><a href="javascript:earlierPage();">Prev Page</a>&nbsp;&nbsp;&nbsp;&nbsp;<a href="javascript:laterPage();">Next Page</a></p>
+ #(/jsResort)#
::
#(/num-results)#
@@ -222,7 +250,11 @@ function latestinfo() {
}
if(rsp && rsp.offset != null) {
- statistics(rsp.offset, rsp.itemscount, rsp.itemsperpage, rsp.totalcount, rsp.localIndexCount, rsp.remoteIndexCount, rsp.remotePeerCount, rsp.navurlBase, #[localQuery]#, rsp.feedRunning);
+ #(jsResort)#
+ statistics(rsp.offset, rsp.itemscount, rsp.itemsperpage, rsp.totalcount, rsp.localIndexCount, rsp.remoteIndexCount, rsp.remotePeerCount, rsp.navurlBase, #[localQuery]#, rsp.feedRunning);
+ ::
+ statistics($("#resultscontainer .searchresults.earlierpage").length + 1, $("#resultscontainer .searchresults.earlierpage").length + $("#resultscontainer .searchresults.currentpage").length, rsp.itemsperpage, rsp.totalcount, rsp.localIndexCount, rsp.remoteIndexCount, rsp.remotePeerCount, rsp.navurlBase, #[localQuery]#, rsp.feedRunning);
+ #(/jsResort)#
if(rsp.feedRunning) {
/* Refresh statistics while server feeders are still running */
window.setTimeout(latestinfo, 1000);
diff --git a/htroot/yacysearch.java b/htroot/yacysearch.java
index 79bed9769..4c2de7d7a 100644
--- a/htroot/yacysearch.java
+++ b/htroot/yacysearch.java
@@ -835,14 +835,22 @@ public class yacysearch {
QueryParams.navurlBase(RequestHeader.FileType.HTML, theQuery, null, true).append("&startRecord=")
.append(startRecord).append("&resortCachedResults=true").toString());
+ prop.put("jsResort", sb.getConfigBool("search.jsresort", false) );
+ prop.put("num-results_jsResort", sb.getConfigBool("search.jsresort", false) );
+
// generate the search result lines; the content will be produced by another servlet
for ( int i = 0; i < theQuery.itemsPerPage(); i++ ) {
prop.put("results_" + i + "_item", startRecord + i);
prop.put("results_" + i + "_eventID", theQuery.id(false));
+
+ prop.put("jsResort_results_" + i + "_item", startRecord + i);
+ prop.put("jsResort_results_" + i + "_eventID", theQuery.id(false));
}
prop.put("results", theQuery.itemsPerPage());
+ prop.put("jsResort_results", theQuery.itemsPerPage());
prop.put("resultTable", (contentdom == ContentDomain.APP || contentdom == ContentDomain.AUDIO || contentdom == ContentDomain.VIDEO) ? 1 : 0);
prop.put("eventID", theQuery.id(false)); // for bottomline
+ prop.put("jsResort_eventID", theQuery.id(false));
// process result of search
if ( !filtered.isEmpty() ) {
@@ -864,6 +872,7 @@ public class yacysearch {
prop.put("depth", "0");
prop.put("localQuery", theSearch.query.isLocal() ? "1" : "0");
+ prop.put("jsResort_localQuery", theSearch.query.isLocal() ? "1" : "0");
}
prop.put("focus", focus ? 1 : 0); // focus search field