Google No Redirects

Removes Google redirects.

  1. // ==UserScript==
  2. // @name Google No Redirects
  3. // @namespace https://greasyfork.org/zh-CN/scripts/23721-google-no-redirects
  4. // @version 1.1
  5. // @description Removes Google redirects.
  6. // @include /^https?\:\/\/(www|news|maps|docs|cse|encrypted)\.google\./
  7. // @author liliang13
  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 stopBubbling(event) {
  27. event.stopPropagation()
  28. }
  29.  
  30. function blockListeners(element, events) {
  31. if(!(element instanceof EventTarget && typeof events === 'string')) {
  32. return
  33. }
  34. var eventList = events.split(/\W+/) || []
  35. for(var i = 0, event; event = eventList[i]; i++) {
  36. //removeEventListener is not needed as duplicate listeners would be discarded
  37. element.addEventListener(event, stopBubbling, true)
  38. }
  39. }
  40.  
  41. function modifyGoogle() {
  42. //remove web/video search redirects
  43. $('a[onmousedown^="return rwt("]').removeAttr('onmousedown')
  44. //remove web/video safe-browsing redirects
  45. $('a[href^="/interstitial?"]').each(function() {
  46. var m = $(this).attr('href').match(/(?:\?|\&)url\=([^\&]+)/i)
  47. if(m && m[1]) {
  48. this.href = decodeURIComponent(m[1])
  49. //warning prefix
  50. if(!$(this).index()) {
  51. $('<span title="Unsafe">&#9888</span>').insertBefore(this)
  52. }
  53. }
  54. })
  55. //remove custom search redirects
  56. $('.gsc-results a[href][data-cturl]').each(function() {
  57. blockListeners(this, 'mousedown')
  58. })
  59. //remove image search redirects
  60. $('a').filter('[class^="irc_"], [class*=" irc_"], [id^="irc_"]').each(function() {
  61. blockListeners(this, 'mousedown')
  62. })
  63. //remove news search redirects
  64. if(href.contains('tbm=nws') || hostname.startsWith('news.google.')) {
  65. $('a.article[href^="http"]').each(function() {
  66. blockListeners(this, 'click contextmenu mousedown mousemove')
  67. })
  68. }
  69. //remove shopping search redirects
  70. else if(href.contains('tbm=shop') || pathname.startsWith('/shopping/')) {
  71. $('a').filter('[href*="/aclk?"], [href*="/url?"]').each(function() {
  72. var m = this.href.match(/(?:\&adurl|\?q|\&url)\=(http.*?)(\&|$)/i)
  73. if(m && m[1]) {
  74. var link = decodeURIComponent(m[1])
  75. link = link.replace
  76. (/\=http(\%3A|\:)(\%2F|\/){2}.*(?=\=https?(\%3A|\:)(\%2F|\/){2})/i, '')
  77. m = link.match(/\=(https?(\%3A|\:)(\%2F|\/){2}.*?)(\&|$)/i)
  78. if(m && m[1]) {
  79. link = decodeURIComponent(m[1])
  80. }
  81. this.href = link
  82. }
  83. })
  84. }
  85. //remove map search redirects; does not remove redirects of advertisement
  86. else if(pathname.startsWith('/maps/') || '/maps' == pathname) {
  87. $('a[href^="http"]').each(function() {
  88. blockListeners(this, 'click contextmenu')
  89. //legacy
  90. if(this.href.contains('url?')) {
  91. var m = this.href.match(/(?:\&|\?)q\=(http.*?)(\&|$)/i)
  92. if(m && m[1]) {
  93. this.href = decodeURIComponent(m[1])
  94. }
  95. }
  96. })
  97. }
  98. //remove legacy search redirects and docs redirects
  99. //should be done last as shopping uses the same url pattern
  100. $('a[href*="/url?"]').each(function() {
  101. var m = this.href.match(/\/url\?(?:url|q)\=(http.*?)(\&|$)/i)
  102. if(m && m[1]) {
  103. this.href = decodeURIComponent(m[1])
  104. }
  105. })
  106. }
  107.  
  108. MutationObserver = window.MutationObserver || window.WebKitMutationObserver
  109. if(MutationObserver) {
  110. var observer = new MutationObserver(function(mutations) {
  111. modifyGoogle()
  112. })
  113. //tiny delay needed for firefox
  114. setTimeout(function() {
  115. observer.observe(document.body, {
  116. childList: true,
  117. subtree: true
  118. })
  119. modifyGoogle()
  120. }, 100)
  121. }
  122. //for chrome v18-, firefox v14-, internet explorer v11-, opera v15- and safari v6-
  123. else {
  124. setInterval(function() {
  125. modifyGoogle()
  126. }, 500)
  127. }