Goodreads - Sort lists by rating or votes

Sort lists

  1. // ==UserScript==
  2. // @name Goodreads - Sort lists by rating or votes
  3. // @namespace goodreads
  4. // @description Sort lists
  5. // @include https://www.goodreads.com/list/show/*
  6. // @version 1.1
  7. // @grant none
  8. // ==/UserScript==
  9.  
  10. function isNumeric(num){
  11. return !isNaN(num)
  12. }
  13.  
  14. function parseNumber(str) {
  15. var out = "";
  16. for(var i = 0; i < str.length; ++i) {
  17. if(isNumeric(str[i])) {
  18. out += str[i];
  19. }
  20. }
  21. return parseInt(out);
  22. }
  23.  
  24. var App = {
  25. order: "desc",
  26. loadPage: 2,
  27. sort: function(cmp) {
  28. var elems = jQuery(".tableList").find("tr").get();
  29. elems.sort(cmp);
  30. if(App.order === "asc") {
  31. App.order = "desc";
  32. }
  33. else {
  34. App.order = "asc";
  35. elems.reverse();
  36. }
  37. for(var i = 0; i < elems.length; ++i) {
  38. elems[i].parentNode.appendChild(elems[i]);
  39. }
  40. },
  41. init: function() {
  42. $sortByRating = jQuery("<a></a>").attr("id", "sortByRating")
  43. .attr("href", "#")
  44. .text("sort by rating")
  45. .addClass("tab");
  46. $sortByVotes = jQuery("<a></a>").attr("id", "sortByVotes")
  47. .attr("href", "#")
  48. .text("sort by votes")
  49. .addClass("tab");
  50. jQuery(".bigTabs > div:nth-child(1)", ".leftContainer").append($sortByRating)
  51. .append($sortByVotes);
  52. jQuery("#sortByRating").on("click", function(){
  53. App.sort(function(lhs, rhs){
  54. var lhsRating = jQuery(lhs).find(".minirating").text().match(/[0-9]{1}\.[0-9]{2}/)[0];
  55. var rhsRating = jQuery(rhs).find(".minirating").text().match(/[0-9]{1}\.[0-9]{2}/)[0];
  56. return parseFloat(lhsRating) - parseFloat(rhsRating);
  57. });
  58. });
  59. jQuery("#sortByVotes").on("click", function(){
  60. App.sort(function(lhs, rhs){
  61. var lhsVotes = parseNumber(jQuery(lhs).find(".minirating").text().match(/\d{1,3}(?:[,]\d{3})* rating/)[0]);
  62. var rhsVotes = parseNumber(jQuery(rhs).find(".minirating").text().match(/\d{1,3}(?:[,]\d{3})* rating/)[0]);
  63. if(lhsVotes < rhsVotes) { return -1; }
  64. if(lhsVotes > rhsVotes) { return 1; }
  65. return 0;
  66. });
  67. });
  68. var hasPages = jQuery("#all_votes > .pagination").length > 0;
  69. if(hasPages) {
  70. $pagination = jQuery("#all_votes > .pagination > a");
  71. var numPages = parseInt($pagination.get(-2).innerHTML);
  72. $loadPage = jQuery("<a></a>").attr("id", "loadNextPage")
  73. .attr("href", "#")
  74. .text("load page #2")
  75. .addClass("tab");
  76. jQuery(".bigTabs > div:nth-child(1)", ".leftContainer").append($loadPage);
  77. var nextPageUrl = "https://www.goodreads.com" + $pagination.last().attr("href");
  78. jQuery("#loadNextPage").on("click", function(){
  79. jQuery("#loadNextPage").text("loading page #" + App.loadPage);
  80. jQuery.get(nextPageUrl, function(data){
  81. $html = jQuery(data);
  82. $html.find(".tableList tr").appendTo(jQuery(".tableList tbody"));
  83. nextPageUrl = "https://www.goodreads.com" + $html.find(".pagination a").last().attr("href");
  84. App.loadPage++;
  85. if(App.loadPage > numPages) {
  86. // Remove load link if loaded last page
  87. jQuery("#loadNextPage").remove();
  88. }
  89. else {
  90. jQuery("#loadNextPage").text("load page #" + App.loadPage);
  91. }
  92. });
  93. });
  94. }
  95. }
  96. };
  97.  
  98. jQuery(document).ready(App.init);