Return Pagination to Google

Makes Google searches break down into separate pages, rather than displaying as one continuous page.

当前为 2024-03-18 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Return Pagination to Google
  3. // @description Makes Google searches break down into separate pages, rather than displaying as one continuous page.
  4. // @namespace Violentmonkey Scripts
  5. // @include https://www.google.*/search*
  6. // @match https://www.google.com/search*
  7. // @grant none
  8. // @version 1.5
  9. // @author Jupiter Liar
  10. // @license Attribution CC BY
  11. // @description 03/17/2024, 11:15 PM
  12. // ==/UserScript==
  13.  
  14. // Function to generate links for the page numbers
  15. function generatePageLink(urlWithoutAnchor, startParam, startValue, newStartValue) {
  16. if (newStartValue === 0) {
  17. newStartValue = '0';
  18. }
  19. var linkHref;
  20. if (startIndex === -1) {
  21. linkHref = urlWithoutAnchor + startParam + newStartValue;
  22. } else {
  23. linkHref = urlWithoutAnchor.replace(startParam + startValue, startParam + newStartValue);
  24. }
  25. return linkHref;
  26. }
  27.  
  28. var botstuffDiv = document.getElementById('botstuff');
  29. var footerElement = document.querySelector('footer');
  30.  
  31. // Extract the page number from the URL
  32. var startParam = "&start=";
  33. var startIndex = window.location.href.indexOf(startParam);
  34.  
  35. // Create a variable to store the page number
  36. var pageNumber;
  37.  
  38. function generateTable() {
  39. // Create the table element
  40. var table = document.createElement('table');
  41. table.className = 'AaVjTc return-pagination';
  42. table.style.margin = 'auto';
  43. table.style.marginBottom = '28px';
  44. // table.style.scale = '80%';
  45. table.style.border = '1px solid hsla(0, 0%, 0%, 10%)';
  46. table.style.borderRadius = '1em';
  47.  
  48. if (footerElement) {
  49. table.style.marginTop = '28px';
  50. }
  51.  
  52. if (!botstuffDiv) {
  53. table.style.padding = '0.4em';
  54. } else {
  55. table.style.padding = '0 0.5em';
  56. }
  57.  
  58.  
  59.  
  60. if (startIndex === -1) {
  61. pageNumber = 1;
  62. } else {
  63. var startValue = parseInt(window.location.href.substring(startIndex + startParam.length));
  64. pageNumber = Math.floor(startValue / 10) + 1;
  65. }
  66.  
  67. // Remove the anchor portion from the URL
  68. var urlWithoutAnchor = window.location.href.split("#")[0];
  69.  
  70. // Create the table columns
  71. for (var i = 0; i < 11; i++) {
  72. var column = document.createElement('td');
  73. column.style.textAlign = 'center';
  74. column.style.verticalAlign = 'middle';
  75. column.style.minWidth = '16px';
  76. column.style.fontSize = '16pt';
  77.  
  78. // Add padding to middle columns
  79. if (i > 0 && i < 10) {
  80. if (botstuffDiv) {
  81. column.style.padding = '0pt 6.4pt 0';
  82. } else {
  83. column.style.padding = '1pt 6.4pt 0';
  84. }
  85. }
  86.  
  87. // Add padding to previous and next columns
  88. if (i === 0) {
  89. column.style.padding = '0 12.8pt 0 0';
  90. }
  91.  
  92. if (i === 10) {
  93. column.style.padding = '0 0 0 12.8pt';
  94. }
  95.  
  96. // Add content to the columns
  97. if (i === 0) {
  98. if (pageNumber !== 1) {
  99. var previousLink = document.createElement('a');
  100. previousLink.href = urlWithoutAnchor.replace(startParam + startValue, startParam + (startValue - 10));
  101. var previousSpan = document.createElement('span');
  102. previousSpan.style.padding = '0 12.8pt 0 6.4pt'; // Changed from '0 8pt' to '0 16pt'
  103. previousSpan.style.fontSize = '22.4pt';
  104. previousSpan.style.verticalAlign = 'middle'; // Added vertical-align style
  105. previousSpan.innerText = '<';
  106. previousLink.appendChild(previousSpan);
  107. var previousTextSpan = document.createElement('span');
  108. previousTextSpan.style.verticalAlign = 'middle'; // Added vertical-align style
  109. previousTextSpan.innerText = 'Previous';
  110. previousLink.appendChild(previousTextSpan);
  111. column.appendChild(previousLink);
  112. }
  113. } else if (i === 10) {
  114. var nextLink = document.createElement('a');
  115. var nextStartValue = (pageNumber) * 10;
  116. if (startIndex === -1) {
  117. nextLink.href = urlWithoutAnchor + startParam + nextStartValue;
  118. } else {
  119. nextLink.href = urlWithoutAnchor.replace(startParam + startValue, startParam + nextStartValue);
  120. }
  121. var nextTextSpan = document.createElement('span');
  122. nextTextSpan.style.verticalAlign = 'middle'; // Added vertical-align style
  123. nextTextSpan.innerText = 'Next';
  124. nextLink.appendChild(nextTextSpan);
  125. var nextSpan = document.createElement('span');
  126. nextSpan.style.padding = '0 6.4pt 0 12.8pt'; // Changed from '0 8pt' to '0 16pt'
  127. nextSpan.style.fontSize = '22.4pt';
  128. nextSpan.style.verticalAlign = 'middle'; // Added vertical-align style
  129. nextSpan.innerText = '>';
  130. nextLink.appendChild(nextSpan);
  131. column.appendChild(nextLink);
  132. } else {
  133. // Calculate the page number for the column
  134. var columnNumber;
  135. if (pageNumber < 5) {
  136. columnNumber = i;
  137. } else if (pageNumber >= 5) {
  138. columnNumber = pageNumber - 5 + i;
  139. }
  140.  
  141. if (columnNumber === pageNumber) {
  142. // Add page number without link
  143. column.innerText = columnNumber;
  144. } else {
  145. // Generate links for the page number
  146. var newStartValue = (columnNumber - 1) * 10;
  147. var linkHref = generatePageLink(urlWithoutAnchor, startParam, startValue, newStartValue);
  148.  
  149. // Create the link element
  150. var link = document.createElement('a');
  151. link.href = linkHref;
  152. link.innerText = columnNumber;
  153.  
  154. // Append the link to the column
  155. column.appendChild(link);
  156. }
  157. }
  158.  
  159. // Add class to the column
  160. column.classList.add(`ret-pag-col-${i + 1}`);
  161.  
  162. // Append the column to the table
  163. table.appendChild(column);
  164. }
  165.  
  166. // Check if the first column is empty and delete it
  167. var firstColumn = table.querySelector('td:first-child');
  168. if (firstColumn.innerText === '') {
  169. table.removeChild(firstColumn);
  170. }
  171.  
  172. // Append the table to the 'botstuff' div or the beginning of the footer element
  173.  
  174.  
  175. if (botstuffDiv) {
  176. botstuffDiv.appendChild(table);
  177. }
  178.  
  179. if (footerElement) {
  180. footerElement.insertBefore(table, footerElement.firstChild);
  181. }
  182.  
  183. }
  184.  
  185.  
  186. // Check if the page has the required conditions
  187. if ((botstuffDiv && !document.querySelector('table.AaVjTc')) || footerElement) {
  188. console.log('Attempting to generate table...');
  189. generateTable();
  190. }
  191.  
  192.  
  193. // ...
  194.  
  195.  
  196.  
  197. // Check if the page has the required conditions
  198. if (document.getElementById('botstuff')) {
  199. var botstuffDiv = document.getElementById('botstuff');
  200. var divsToHide = botstuffDiv.querySelectorAll('div[jscontroller="ogmBcd"]');
  201. for (var i = 0; i < divsToHide.length; i++) {
  202. divsToHide[i].style.display = "none";
  203. }
  204. }
  205.  
  206.  
  207. // Function to hide elements with class "C4clhf"
  208. function hideElementWithClass(className) {
  209. var elements = document.getElementsByClassName(className);
  210. for (var i = 0; i < elements.length; i++) {
  211. elements[i].style.display = "none";
  212. }
  213. }
  214.  
  215. // Function to handle mutations and hide elements
  216. function handleMutations(mutationsList) {
  217. for (var i = 0; i < mutationsList.length; i++) {
  218. var mutation = mutationsList[i];
  219. var addedNodes = mutation.addedNodes;
  220. for (var j = 0; j < addedNodes.length; j++) {
  221. var addedNode = addedNodes[j];
  222. if (addedNode.classList && addedNode.classList.contains("C4clhf")) {
  223. hideElementWithClass("C4clhf");
  224. }
  225. }
  226. }
  227. }
  228.  
  229. // Create a new mutation observer
  230. var observer = new MutationObserver(handleMutations);
  231.  
  232. // Start observing the 'search' div and its descendants
  233. var searchDiv = document.getElementById('search');
  234. if (searchDiv) {
  235. observer.observe(searchDiv, { childList: true, subtree: true });
  236. }
  237.  
  238. // Hide existing elements with class "C4clhf"
  239. hideElementWithClass("C4clhf");
  240.  
  241.  
  242.  
  243.  
  244.  
  245.  
  246.  
  247. if ((document.querySelector('div.card-section a[href*="&filter=0"]') !== null) ||
  248. (document.querySelectorAll('div.card-section p, div.card-section li').length > 1) ||
  249. (document.querySelector('div.uzjuFc') !== null)) {
  250.  
  251. if (pageNumber === 1) {
  252. // Remove the 'return-pagination' table if pageNumber is 1
  253. var returnPaginationTable = document.querySelector('table.AaVjTc.return-pagination');
  254. if (returnPaginationTable) {
  255. returnPaginationTable.remove();
  256. }
  257. } else {
  258. // Find and remove the column ret-pag-col-11
  259. var column11 = table.querySelector('.ret-pag-col-11');
  260. if (column11) {
  261. column11.remove();
  262. }
  263.  
  264. // Remove numbers and links from columns ret-pag-col-2 to ret-pag-col-10
  265. for (var i = 2; i <= 10; i++) {
  266. var column = table.querySelector(`.ret-pag-col-${i}`);
  267. column.innerHTML = '';
  268. }
  269.  
  270. // Set the current page number in ret-pag-col-10
  271. var column10 = table.querySelector('.ret-pag-col-10');
  272. column10.innerText = pageNumber;
  273.  
  274. // Generate and set the page numbers in the remaining columns as links
  275. for (var i = 9; i >= 2; i--) {
  276. var column = table.querySelector(`.ret-pag-col-${i}`);
  277. var columnNumber = pageNumber - (10 - i);
  278. if (columnNumber > 0) {
  279. var linkURL = getCurrentPageURL();
  280. var newStartNumber = (columnNumber - 1) * 10;
  281. linkURL = replaceStartNumber(linkURL, newStartNumber);
  282. column.innerHTML = generateLink(columnNumber, linkURL);
  283. } else {
  284. column.remove();
  285. }
  286. }
  287. }
  288.  
  289. // Function to get the current page URL
  290. function getCurrentPageURL() {
  291. return window.location.href.split("#")[0];
  292. }
  293.  
  294. // Function to replace the "start" number in the URL
  295. function replaceStartNumber(url, newStartNumber) {
  296. return url.replace(/([&?])start=\d+/, "$1start=" + newStartNumber);
  297. }
  298.  
  299. // Function to generate a link with the specified page number and URL
  300. function generateLink(pageNumber, url) {
  301. return `<a href="${url}">${pageNumber}</a>`;
  302. }
  303.  
  304. }
  305.  
  306.  
  307. // Function to handle scaling and transforming the table
  308. function scaleTableToFit(tableContainerDiv) {
  309. var table = document.querySelector('.return-pagination');
  310. var viewportWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
  311.  
  312. if (table.offsetWidth > tableContainerDiv.offsetWidth) {
  313. var scale = tableContainerDiv.offsetWidth / table.offsetWidth;
  314. table.style.transform = 'scale(' + scale + ')';
  315. table.style.transformOrigin = 'top left';
  316. } else {
  317. // Reset the table's scale and transform origin
  318. table.style.transform = '';
  319. table.style.transformOrigin = '';
  320. }
  321. }
  322.  
  323. // Create a ResizeObserver instance
  324. var resizeObserver = new ResizeObserver(function(entries) {
  325. for (var entry of entries) {
  326. if (entry.target.id === 'botstuff') {
  327. tableContainerDiv = botstuffDiv;
  328. // Call the scaling function when #botstuff width changes
  329. scaleTableToFit(tableContainerDiv);
  330. console.log('Botstuff resizer in action.');
  331. break;
  332. }
  333.  
  334. if (footerElement) {
  335. tableContainerDiv = footerElement;
  336. // Call the scaling function when <footer> width changes
  337. scaleTableToFit(tableContainerDiv);
  338. console.log('Footer resizer in action.');
  339. break;
  340. }
  341. }
  342. });
  343.  
  344. // Observe changes in the width of #botstuff
  345. if (botstuffDiv) {
  346. resizeObserver.observe(botstuffDiv);
  347. }
  348.  
  349. if (footerElement) {
  350. resizeObserver.observe(footerElement);
  351. }