Endless Google


SUBMITTED BY: AnD888

DATE: Oct. 7, 2016, 6:07 p.m.

FORMAT: Text only

SIZE: 6.4 kB

HITS: 1527

  1. // ==UserScript==
  2. // @name Endless Google
  3. // @description Load more results automatically and endlessly.
  4. // @author tumpio
  5. // @oujs:author tumpio
  6. // @namespace tumpio@sci.fi
  7. // @homepageURL https://openuserjs.org/scripts/tumpio/tumpiosci.fi/Endless_Google
  8. // @supportURL https://github.com/tumpio/gmscripts
  9. // @icon https://github.com/tumpio/gmscripts/raw/master/Endless_Google/large.png
  10. // @include http://www.google.*
  11. // @include https://www.google.*
  12. // @include https://encrypted.google.*
  13. // @run-at document-start
  14. // @grant GM_xmlhttpRequest
  15. // @version 0.0.4
  16. // ==/UserScript==
  17. // TODO: on page refresh:
  18. // 2: load only the last scrolled page (on refresh, load last requested page) (could be a good default, needs scroll up support)
  19. // beforeunload -> store last requested page with GM_setVariable() and reload it instead
  20. // TODO: onerror, onabort: show to user "page loading failed", button to retry
  21. // FIXME: bug: Suggested images don't show up on new requested pages
  22. // case: https://www.google.fi/webhp?tab=ww&ei=e0UjU9ynEKqkyAO46YD4DQ&ved=0CBEQ1S4#q=tetsaus
  23. // workaround, hiding now
  24. // FUTURE: Options dialog
  25. // FUTURE: Replace footer with page #no info UI
  26. // FUTURE: Add page up/down and back to top/bottom controls UI + (go to the page #n)?
  27. // FUTURE: Add columns support
  28. // FUTURE: show page loading icon
  29. // FUTURE: show page fav-icons for results
  30. // FUTURE: number results
  31. // FUTURE: option to load static google css
  32. // FUTURE: support scroll up
  33. if (location.href.indexOf("tbm=isch") !== -1) // NOTE: Don't run on image search
  34. return;
  35. if (window.top !== window.self) // NOTE: Do not run on iframes
  36. return;
  37. document.addEventListener('DOMContentLoaded', function () {
  38. // NOTE: Options
  39. var request_pct = 0.05; // percentage of window height left on document to request next page, value must be between 0-1
  40. var event_type = "scroll"; // or "wheel"
  41. var on_page_refresh = 1;
  42. // 0: reload all previous pages requested
  43. // 1: load only the first page (prevent restoring the scroll position)
  44. // 2: load only the last page requested
  45. var main = document.getElementById("main");
  46. var rcnt = document.getElementById("rcnt");
  47. var input = document.getElementById("lst-ib");
  48. var input_value = input.value;
  49. var old_scrollY = 0;
  50. var scroll_events = 0;
  51. var next_link = null;
  52. var cols = [];
  53. var request_offsetHeight = 0;
  54. var stop_events = false;
  55. input.addEventListener("blur", reset, false); // NOTE: listens for new search input to reset state
  56. window.addEventListener(event_type, onScroll, false);
  57. window.addEventListener("beforeunload", function () {
  58. window.scrollTo(0, 0);
  59. }, false);
  60. function requestNextPage(link) {
  61. console.log("request next");
  62. console.log(link);
  63. GM_xmlhttpRequest({
  64. method: "GET",
  65. url: link,
  66. onload: function (response) {
  67. var el = document.getElementById('navcnt');
  68. el.parentNode.removeChild(el); //Deletes the navigation box
  69. var holder = document.createElement("div");
  70. holder.innerHTML = response.responseText;
  71. next_link = holder.querySelector("#pnnext").href;
  72. var next_col = document.createElement("div");
  73. next_col.className = "EG_col";
  74. next_col.appendChild(holder.querySelector("#center_col"));
  75. var rel_search = next_col.querySelector("#extrares");
  76. var rel_images = next_col.querySelector("#imagebox_bigimages");
  77. var rel_ads = next_col.querySelector("#tads");
  78. if (rel_search)
  79. rel_search.style.display = "none"; // NOTE: Hides repeating "related searches"
  80. if (rel_images)
  81. rel_images.style.display = "none"; // NOTE: Hides related images, that are broken (bug)
  82. if (rel_ads)
  83. rel_ads.style.display = "none"; // NOTE: Hides repeating "search results ad"
  84. cols.push(next_col);
  85. console.log("Page no: " + cols.length);
  86. next_col.id = next_col.className + "_" + (cols.length - 1); // NOTE: add unique id for every new col
  87. if (!rcnt || cols.length === 1) // NOTE: needs to be rechecked on a state reset too, and late insertation of element on google instant
  88. rcnt = document.getElementById("rcnt");
  89. rcnt.appendChild(next_col);
  90. stop_events = false;
  91. window.addEventListener(event_type, onScroll, false);
  92. }
  93. });
  94. }
  95. function onScroll(e) {
  96. var y = window.scrollY;
  97. // if (scroll_events === 0) old_scrollY = y; // stops only if scroll position was on 2. page
  98. var delta = e.deltaY || y - old_scrollY; // NOTE: e.deltaY for "wheel" event
  99. if (delta > 0 && (window.innerHeight + y) >= (document.body.clientHeight - (window.innerHeight * request_pct))) {
  100. console.log("scroll end");
  101. window.removeEventListener(event_type, onScroll, false);
  102. try {
  103. if(!stop_events){
  104. stop_events = true;
  105. requestNextPage(next_link || document.getElementById("pnnext").href);
  106. }
  107. } catch (err) {
  108. console.error(err.name + ": " + err.message);
  109. // NOTE: recovery unnecessary, input event handles it with reset on new search
  110. }
  111. }
  112. old_scrollY = y;
  113. scroll_events += 1;
  114. }
  115. // NOTE: Resets the script state on a new search
  116. function reset() {
  117. if (input.value !== input_value) {
  118. input_value = input.value;
  119. window.scrollTo(0, 0);
  120. for (var i = 0; i < cols.length; i++)
  121. rcnt.removeChild(cols[i]);
  122. cols = [];
  123. next_link = null;
  124. old_scrollY = 0;
  125. scroll_events = 0;
  126. console.log("RESET");
  127. }
  128. }
  129. console.log("egoogle.js initialized");
  130. });
  131. console.log("egoogle.js loaded");

comments powered by Disqus