Direct Google - Rix

Removes Google redirects and exposes "Cached" links.

  1. // ==UserScript==
  2. // @name Direct Google - Rix
  3. // @namespace http://userscripts.org/users/92143
  4. // @version 1.4
  5. // @description Removes Google redirects and exposes "Cached" links.
  6. // @include /^https?\:\/\/(www|news|maps|docs|cse|encrypted)\.google\./
  7. // @author zanetu
  8. // @license GPL version 2 or any later version; http://www.gnu.org/licenses/gpl-2.0.txt
  9. // @require http://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.3/jquery.min.js
  10. // @grant GM_addStyle
  11. // @run-at document-end
  12. // ==/UserScript==
  13.  
  14. var hostname = location.hostname
  15. var pathname = location.pathname
  16. var href = location.href
  17.  
  18. String.prototype.contains = function(s) {
  19. return -1 !== this.indexOf(s)
  20. }
  21.  
  22. String.prototype.startsWith = function(s) {
  23. return this.slice(0, s.length) == s
  24. }
  25.  
  26. function blockListeners(element, events) {
  27. function stopBubbling(event) {
  28. event.stopPropagation()
  29. }
  30.  
  31. var eventList = events.split(' ')
  32. if(eventList) {
  33. var i, event
  34. for(i = eventList.length - 1; i > -1; i--) {
  35. event = eventList[i].trim()
  36. if(event) {
  37. element.removeEventListener(event, stopBubbling, true)
  38. element.addEventListener(event, stopBubbling, true)
  39. }
  40. }
  41. }
  42. }
  43.  
  44. function modifyGoogle() {
  45. //remove web/video search redirects
  46. $('a[onmousedown^="return rwt("]').removeAttr('onmousedown').each(function() {
  47. this.target = "_blank";
  48. });
  49. //remove custom search redirects
  50. $('.gsc-results a[href][data-cturl]').each(function() {
  51. this.target = "_blank";
  52. blockListeners(this, 'mousedown')
  53. })
  54. //remove image search redirects
  55. $('a').filter('[class^="irc_"], [class*=" irc_"], [id^="irc_"]').each(function() {
  56. this.target = "_blank";
  57. blockListeners(this, 'mousedown')
  58. })
  59. //remove news search redirects
  60. if(href.contains('tbm=nws') || hostname.startsWith('news.google.')) {
  61. $('a.article[href^="http"]').each(function() {
  62. this.target = "_blank";
  63. blockListeners(this, 'click contextmenu mousedown mousemove')
  64. })
  65. }
  66. //remove shopping search redirects
  67. else if(href.contains('tbm=shop') || pathname.startsWith('/shopping/')) {
  68. $('a').filter('[href*="/aclk?"], [href*="/url?"]').each(function() {
  69. this.target = "_blank";
  70. var m = this.href.match(/(?:\&adurl|\?q|\&url)\=(http.*?)(\&|$)/i)
  71. if(m && m[1]) {
  72. var link = decodeURIComponent(m[1])
  73. m = link.match(/\=(https?(\%3A\%2F\%2F|\:\/\/).*?)(\&|$)/i)
  74. if(m && m[1]) {
  75. link = decodeURIComponent(m[1])
  76. }
  77. this.href = link
  78. }
  79. })
  80. }
  81. //remove map search redirects; does not remove redirects of advertisement
  82. else if(pathname.startsWith('/maps/') || '/maps' == pathname) {
  83. $('a[href^="http"]').each(function() {
  84. this.target = "_blank";
  85. blockListeners(this, 'click contextmenu')
  86. //legacy
  87. if(this.href.contains('url?')) {
  88. var m = this.href.match(/(?:\&|\?)q\=(http.*?)(\&|$)/i)
  89. if(m && m[1]) {
  90. this.href = decodeURIComponent(m[1])
  91. }
  92. }
  93. })
  94. }
  95. //remove legacy search redirects and docs redirects
  96. //should be done last as shopping uses the same url pattern
  97. $('a[href*="/url?"]').each(function() {
  98. this.target = "_blank";
  99. var m = this.href.match(/\/url\?(?:url|q)\=(http.*?)(\&|$)/i)
  100. if(m && m[1]) {
  101. this.href = decodeURIComponent(m[1])
  102. }
  103. })
  104. //expose cached links
  105. $('div[role="menu"] ul li a[href^="http://webcache.googleusercontent."]').each(
  106. function() {
  107. this.style.display = 'inline'
  108. $(this).closest('div.action-menu.ab_ctl, div._nBb')
  109. .after(' <a href="https' + this.href.substring(4) + '">(https)</a> ')
  110. .after($(this))
  111. }
  112. )
  113. }
  114.  
  115. MutationObserver = window.MutationObserver || window.WebKitMutationObserver
  116. if(MutationObserver) {
  117. var observer = new MutationObserver(function(mutations) {
  118. modifyGoogle()
  119. })
  120. //tiny delay needed for firefox
  121. setTimeout(function() {
  122. observer.observe(document.body, {
  123. childList: true,
  124. subtree: true
  125. })
  126. modifyGoogle()
  127. }, 100)
  128. }
  129. //for chrome v18-, firefox v14-, internet explorer v11-, opera v15- and safari v6-
  130. else {
  131. setInterval(function() {
  132. modifyGoogle()
  133. }, 500)
  134. }