Google Search shows 'Cached' again! ('Im Cache'.de_DE)

Provides the 'Cached' button for each searchresult.

  1. // ==UserScript==
  2. // @name Google Search shows 'Cached' again! ('Im Cache'.de_DE)
  3. // @namespace cortex
  4. // @description Provides the 'Cached' button for each searchresult.
  5. // @include http://www.google.*
  6. // @include https://www.google.*
  7. // @include http://webcache.googleusercontent.*
  8. // @include https://webcache.googleusercontent.*
  9. // @version 1.2.0
  10. // @run-at document-start
  11. // @icon https://goo.gl/ZglzYI
  12. // ==/UserScript==
  13.  
  14. function main(e) {
  15. if (insideCache) casche(e);
  16. else rezultz(e);
  17. }
  18.  
  19. const bref = "http://webcache.googleusercontent.com/search?ie=UTF-8&q=cache:";
  20.  
  21. var iconAcnhor, gComemBack, insideCache;
  22.  
  23. function rezultz(e) {
  24. if (Xel('//a[starts-with(@class,"googCacheComeBack")]')) {
  25. return;
  26. }
  27. if (e) e.preventDefault(), e.stopPropagation();
  28. try {
  29. var rez = Xels('//div[@id="search"]//div[@class="g"]');
  30. for (var i = 0, li = rez.length; i < li; i++) {
  31. var a = Xel('.//a', rez[i]);
  32. a.removeAttribute("onmousedown");
  33. var aref = bref + hesc(a.href); //
  34. var cache = buildEl('span', {
  35. style: 'color: black'
  36. }, null, ' &#x2023; ');
  37. cache.appendChild(buildEl('a', {
  38. href: aref
  39. , 'class': 'googCacheComeBack fl'
  40. , target: '_blank'
  41. }, null, 'gCache'));
  42. var cite = Xel('.//cite', rez[i]);
  43. cite && cite.appendChild(cache);
  44. }
  45. }
  46. catch (e) {
  47. GM_log('cacherr:\n' + e)
  48. }
  49. }
  50.  
  51. function casche(e) {
  52. if (Xel('//a[starts-with(@class,"gooCache")]')) {
  53. return;
  54. }
  55. if (runByEsc || runByEscCached) e.preventDefault(), e.stopPropagation();
  56. var hloc = location.href + '';
  57. hloc = hloc.split(/\/?\#|\%23/)[0];
  58. var loc = hloc.match(/[\&\?]q\=cache\:(.*)/);
  59. if (!loc || !loc[1]) {
  60. GM_log('not webcache\n' + hloc);
  61. return;
  62. }
  63. loc = Xel("/html/body/div/div/a").href + '';
  64. var ctr = 0;
  65. var dom = FLD(loc);
  66. var L = unsafeWindow.document.links;
  67. GM_addStyle(iconAcnhor);
  68. for (var i = L.length - 1; i >= 0; i--) {
  69. var ref = L[i].href.split(/\/?\#|\%23/);
  70. if (ref.length > 1 && ref[0] == loc) {
  71. L[i].href = hloc + '#' + ref[1];
  72. L[i].removeAttribute("onmousedown");
  73. L[i].className = (L[i].className ? L[i].className + ' ' : '') + 'gooCacheAnchor';
  74. }
  75. else {
  76. var refdom = FLD(ref[0]);
  77. if (refdom && dom) {
  78. e = buildEl('a', {
  79. 'class': (refdom.d == dom.d) ? 'gooCacheLink' : 'gooCacheExt'
  80. , /* */
  81. title: 'cached'
  82. , /* */
  83. href: bref + hesc(L[i].href)
  84. }, null, ''); //'&darr;'
  85. insAfter(e, L[i]);
  86. }
  87. }
  88. }
  89. }
  90.  
  91. function hesc(href) {
  92. var hr = href + '';
  93. const re = /^(.+?)([\?\#\&].*)$/;
  94. var m = hr.match(re);
  95. if (m && m.length == 3) {
  96. hr = m[1] + escape(m[2]);
  97. }
  98. return hr;
  99. }
  100.  
  101. function buildEl(type, attrArray, eL, html) {
  102. var node = document.createElement(type);
  103. for (var attr in attrArray)
  104. if (attrArray.hasOwnProperty(attr)) node.setAttribute(attr, attrArray[attr]);
  105. if (eL) node.addEventListener(eL[0], eL[1], eL[2] ? true : false);
  106. if (html) node.innerHTML = html;
  107. return node;
  108. }
  109.  
  110. function Xel(XPath, contextNode) {
  111. var a = document.evaluate(XPath, (contextNode || document), null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
  112. return (a.snapshotLength ? a.snapshotItem(0) : null);
  113. }
  114.  
  115. function Xels(XPath, contextNode) {
  116. var ret = []
  117. , i = 0;
  118. var a = document.evaluate(XPath, (contextNode || document), null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
  119. while (a.snapshotItem(i)) ret.push(a.snapshotItem(i++));
  120. return ret;
  121. }
  122.  
  123. function FLD(url) {
  124. var dm = url.match(/^(https?\:)\/\/(.+?)\//);
  125. if (!dm || dm.length < 3) return null;
  126. dd = dm[2].split('.');
  127. if (dd.length < 2) return null;
  128. return {
  129. p: dm[1]
  130. , d: dd[dd.length - 2] + '.' + dd[dd.length - 1]
  131. };
  132. }
  133.  
  134. function insAfter(n, e) {
  135. if (e.nextSibling) {
  136. e.parentNode.insertBefore(n, e.nextSibling);
  137. }
  138. else if (e.nextElementSibling) {
  139. e.parentNode.insertBefore(n, e.nextElementSibling);
  140. }
  141. else e.parentNode.appendChild(n);
  142. }
  143.  
  144. iconCacheLink = 'content:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAANCAYAAABy6+R8AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAABMklEQVQoz42QP0tCYRSHnxuXhjCIigtW4KBRweuU1NDS0lIY9AFaWqItDIy+goM01RAI0ewkCG1BShQuweXqTRwasugS9EejWk6DaPfmTfot73nPOQ+/c46GS+l8Xdz/xPKYRi+l83VxmiIiIk5T5PjcERVPyr8AFU+Kiiclf/0qm0e2L6i3g9EBiK7uYuZSGkBla1uGA/2+Jn3t4MuneFNv+EJaofouewenPfc1JiJkd6KaZ7y1pXmK5SduHxWl2k9zLAwhw8Q+O/HudFV99gDpjXtqD00u7QilGoSMbmcd8ABzk0NMjwdYmX2jctegWP4DcqvtnL1QwCCxcLAbcl4+CRkmoEhkgsTCAK23NZ6Jbfk4LcyMAC3w9yH8pANkDvc7CeUqflhgWzC1uI6ZS3Xy35M8hMl4RkDrAAAAAElFTkSuQmCC)';
  145. iconAcnhor = '.gooCacheAnchor:after{position: relative; top: 6px;content:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAKCAYAAACJxx+AAAAAWElEQVR42mNkQAM6vmX/r2zuYoTxGdEl1R1iGW4eWMwAU8RIkgnBvZf/w9hri3XJMAGnApDRMCORFYDE4YIg14MUwRSAJEG+gSsA0SBFMADzKkY4wNgwawC9Qz2rUJ9HmwAAAABJRU5ErkJggg==)}.gooCacheLink:before{position: relative; top: 6px; opacity: 0.8;' + iconCacheLink + '}.gooCacheExt:before{position: relative; bottom: 4px; opacity: 0.8;content:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAKCAYAAACJxx+AAAAAkklEQVR42mNkQALbLn76f+PpF4b1u08yvL9zHCzGyIAF9G179h+miBGXZKCrOdgkRmTVICCoYgmWLPKSAssx2hau/w8S4BaTBCuY3FgOVnS4P5AR5CZGHd+y/7n1nWAJZHBlcxfYehQFSZkFYJNAbBQFMAkQ+PrqOcO86RMQCkBuADkQZC8IwNggN4AV4PMFiA8ADbFh5B0GQNAAAAAASUVORK5CYII=)}.googCacheComeBack{}';
  146.  
  147. // from: [http://userstyles.org/styles/64844/google-search-plain-view-cached-similar-links]
  148. // by luckymouse [http://userstyles.org/users/14255]
  149. gComeBack = '\
  150. .clickable-dropdown-arrow.ab_button\
  151. ,a[id^="am-b"].ab_button\
  152. {display: none !important;}\
  153. .action-menu.ab_ctl {\
  154. position: static !important;\
  155. display: inline-block !important;\
  156. margin: 0 !important; \
  157. vertical-align: baseline !important;}\
  158. .action-menu-panel.ab_dropdown {\
  159. visibility: visible !important;\
  160. position: static !important;\
  161. box-shadow: none !important;\
  162. border: none !important;}\
  163. .ab_dropdownitem {display: inline !important;}\
  164. .ab_dropdownitem::before,\
  165. .ab_ctl + a.fl[href*="translate.google.com/"]::before\
  166. {content: "\\00a0\\2023"; color: #000;\
  167. padding-right: 2px; font-size: 14px !important;}\
  168. .ab_dropdownitem:hover {cursor: auto !important; background: transparent !important;}\
  169. .action-menu a[id^="am-b"],/*14-05-20*/\
  170. .action-menu-item div.action-menu-button {display: none !important; }\
  171. .action-menu-item a.fl {\
  172. color: #1122CC !important;\
  173. display: inline !important;\
  174. padding: 0 3px 0 0 !important;\
  175. font-size: 14px !important;\
  176. }\
  177. .action-menu-item a.fl:hover {text-decoration: underline !important;}\
  178. /*2013-06-14*/\
  179. .action-menu-panel.ab_dropdown {background-color: transparent !important;}\
  180. div.f[style*="white-space:nowrap"] {white-space:normal !important;} \
  181. .action-menu-button {display: inline !important; }/**/\
  182. .kv, .slp { display: inline-block !important; padding-left: 4px !important;}\
  183. /*2014-07-14*/\
  184. .s .f.slp:empty{display:none!important;}\
  185. .s span.st {display:inline-block !important;}\
  186. .cr-dwn-arw{margin-left: 2px!important;}\
  187. ';
  188. insideCache = location.href.indexOf('webcache') >= 0;
  189. if (!insideCache) GM_addStyle(gComeBack);