Direct Google

(移除谷歌重定向并解析出缓存链接)Removes Google redirects and exposes "Cached" links.

  1. // ==UserScript==
  2. // @name Direct Google
  3. // @namespace http://userscripts.org/users/92143
  4. // @version 2.3
  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 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 custom search redirects
  45. $('.gsc-results a[href][data-cturl]').each(function() {
  46. blockListeners(this, 'mousedown')
  47. })
  48. //remove image search redirects
  49. $('a').filter('[class^="irc_"], [class*=" irc_"], [id^="irc_"]').each(function() {
  50. blockListeners(this, 'mousedown')
  51. })
  52. //remove news search redirects
  53. if(href.contains('tbm=nws') || hostname.startsWith('news.google.')) {
  54. $('a.article[href^="http"]').each(function() {
  55. blockListeners(this, 'click contextmenu mousedown mousemove')
  56. })
  57. }
  58. //remove shopping search redirects
  59. else if(href.contains('tbm=shop') || pathname.startsWith('/shopping/')) {
  60. $('a').filter('[href*="/aclk?"], [href*="/url?"]').each(function() {
  61. var m = this.href.match(/(?:\&adurl|\?q|\&url)\=(http.*?)(\&|$)/i)
  62. if(m && m[1]) {
  63. var link = decodeURIComponent(m[1])
  64. link = link.replace('=http://clickserve.dartsearch.net/', '=')
  65. m = link.match(/\=(https?(\%3A\%2F\%2F|\:\/\/).*?)(\&|$)/i)
  66. if(m && m[1]) {
  67. link = decodeURIComponent(m[1])
  68. }
  69. this.href = link
  70. }
  71. })
  72. }
  73. //remove map search redirects; does not remove redirects of advertisement
  74. else if(pathname.startsWith('/maps/') || '/maps' == pathname) {
  75. $('a[href^="http"]').each(function() {
  76. blockListeners(this, 'click contextmenu')
  77. //legacy
  78. if(this.href.contains('url?')) {
  79. var m = this.href.match(/(?:\&|\?)q\=(http.*?)(\&|$)/i)
  80. if(m && m[1]) {
  81. this.href = decodeURIComponent(m[1])
  82. }
  83. }
  84. })
  85. }
  86. //remove legacy search redirects and docs redirects
  87. //should be done last as shopping uses the same url pattern
  88. $('a[href*="/url?"]').each(function() {
  89. var m = this.href.match(/\/url\?(?:url|q)\=(http.*?)(\&|$)/i)
  90. if(m && m[1]) {
  91. this.href = decodeURIComponent(m[1])
  92. }
  93. })
  94. //expose cached links
  95. $('div[role="menu"] ol li').find('a[href^="http://webcache.googleusercontent."]' +
  96. ', a[href^="https://webcache.googleusercontent."]').each(
  97. function() {
  98. this.style.display = 'inline'
  99. $(this).closest('div.action-menu.ab_ctl, div._nBb')
  100. .after(' <a href="' + this.href.replace(/^http\:/, 'https:') +
  101. '">(https)</a> ')
  102. .after($(this))
  103. }
  104. )
  105. }
  106.  
  107. MutationObserver = window.MutationObserver || window.WebKitMutationObserver
  108. if(MutationObserver) {
  109. var observer = new MutationObserver(function(mutations) {
  110. modifyGoogle()
  111. })
  112. //tiny delay needed for firefox
  113. setTimeout(function() {
  114. observer.observe(document.body, {
  115. childList: true,
  116. subtree: true
  117. })
  118. modifyGoogle()
  119. }, 100)
  120. }
  121. //for chrome v18-, firefox v14-, internet explorer v11-, opera v15- and safari v6-
  122. else {
  123. setInterval(function() {
  124. modifyGoogle()
  125. }, 500)
  126. }