Google Images direct link

Add direct link to images and pages in google image search

目前为 2015-02-15 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name Google Images direct link
  3. // @namespace https://github.com/Lorentz83
  4. // @description Add direct link to images and pages in google image search
  5. // @include http*://images.google.*/images*
  6. // @include http*://www.google.*/images*
  7. // @include http*://www.google.*/webhp*
  8. // @include http*://www.google.*/search?*
  9. // @include http*://www.google.*/imgres*
  10. // @include http*://images.google.*/search?*
  11. // @include https://encrypted.google.com/search?*
  12. // @version 5.4c
  13. // @grant none
  14. // @icon https://raw.githubusercontent.com/Lorentz83/userscripts/master/GoogleImageDirectLink/icon.png
  15. // @license GPLv2; http://www.gnu.org/licenses/
  16. // ==/UserScript==
  17.  
  18. /**
  19. * This program is free software: you can redistribute it and/or modify
  20. * it under the terms of the GNU General Public License as published by
  21. * the Free Software Foundation, either version 2 of the License, or
  22. * (at your option) any later version.
  23. *
  24. * This program is distributed in the hope that it will be useful,
  25. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  26. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  27. * GNU General Public License for more details.
  28. *
  29. * You should have received a copy of the GNU General Public License
  30. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  31. */
  32.  
  33. var isUndefined = function(val) {
  34. return ( (typeof val) === 'undefined' );
  35. }
  36. var decode = function(component) {
  37. if ( isUndefined(component) )
  38. return false;
  39. return decodeURIComponent(component);
  40. }
  41.  
  42. var doubleDecode = function (component){
  43. if ( isUndefined(component) )
  44. return false;
  45. var tmp = decodeURIComponent(component);
  46. tmp = decodeURIComponent(tmp);
  47. return tmp;
  48. }
  49.  
  50. var parseUrl = function (url) {
  51. var pos = url.indexOf('?');
  52. if (pos < 0)
  53. return [];
  54. var qparms = url.substring(pos+1);
  55. var rawparams = qparms.split('&');
  56. var par = [];
  57. for (var i=0 ; i<rawparams.length ; i++){
  58. var p = rawparams[i].split("=");
  59. par[p[0]] = p[1];
  60. }
  61. return par;
  62. }
  63.  
  64. var getImageLinks = function (url) {
  65. var param = parseUrl(url);
  66. var links = new Object();
  67. links.toImgHref = decode(param["imgurl"]);
  68. links.toPageHref = decode(param["url"]);
  69. return links;
  70. }
  71.  
  72. var getNewImageLinks = function (url) {
  73. var param = parseUrl(url);
  74. var links = new Object();
  75. links.toImgHref = doubleDecode(param["imgurl"]);
  76. links.toPageHref = decode(param["imgrefurl"]);
  77. return links;
  78. }
  79.  
  80. var firstOrNull = function (elems) {
  81. return (elems.length > 0 ) ? elems[0] : null;
  82. }
  83.  
  84. var imgTable = firstOrNull(document.getElementsByClassName('images_table'));
  85. if ( imgTable ) { // for basic version
  86. var imgCell = imgTable.getElementsByTagName('td');
  87. for( j=0 ; j<imgCell.length ; j++ ) {
  88. var imageAnchor = imgCell[j].getElementsByTagName('a')[0];
  89. var domainText = imgCell[j].getElementsByTagName('cite')[0];
  90. console.log(imageAnchor.href);
  91. var links = getImageLinks(imageAnchor.href);
  92. //links.toPageHref = imageAnchor.href; // TODO fixme
  93. links.toImgHref = imageAnchor.href; // TODO fixme
  94. domainText.innerHTML = '<a href="' + links.toPageHref + '">' + domainText.innerHTML + '/&hellip;<\a>';
  95. imageAnchor.href = links.toImgHref;
  96. }
  97. }
  98. else { // standard version
  99. console.log("standard version");
  100. var stopEvent = function(event){
  101. event.stopPropagation()
  102. }
  103. var fixStyle = function(target){
  104. if (target.style.color == 'gray')
  105. return; //only to avoid endless loops
  106. target.style.color = 'gray';
  107. var parent = target.parentNode;
  108. parent.style.height = target.style.height;
  109. parent.style.width = target.style.width;
  110. parent.style.left = target.style.left;
  111. }
  112. var fixBoxObserver = new MutationObserver(function(mutations){
  113. mutations.forEach(function(mutation) {
  114. var target = mutation.target;
  115. var parent = mutation.target.parentNode;
  116. if (mutation.attributeName === 'style'){
  117. fixStyle(target);
  118. }
  119. });
  120. });
  121. var fixBoxMutationConfig = { attributes: true, childList: true, characterData: false, subtree: false };
  122. var fixImageBox = function(image){
  123. if ( /\blinkOk\b/.test(image.className) ) {
  124. return;
  125. }
  126. var span = image.querySelector('span.rg_ilmn');
  127. if (span !== null) {
  128. var a = firstOrNull(image.getElementsByTagName('a'));
  129. var links = getNewImageLinks(a.href);
  130. a.href = links.toImgHref;
  131. var newA = document.createElement('a');
  132. newA.style = a.style;
  133. newA.innerHTML = a.innerHTML;
  134. newA.href = a.href;
  135. a.parentNode.replaceChild(newA, a);
  136. a=newA;
  137. a.addEventListener('click', stopEvent, false);
  138.  
  139. var newContainer = document.createElement('div');
  140. newContainer.className = 'newCont';
  141.  
  142. a.parentNode.appendChild(newContainer);
  143. newContainer.appendChild(a);
  144. newContainer.appendChild(span.parentNode);
  145.  
  146. fixStyle(a);
  147. var desc = span.innerHTML;
  148. span.innerHTML = '<a style="color:#fff" href="' + links.toPageHref + '">' + desc + '</a>';
  149. span.addEventListener('click', stopEvent, false);
  150. image.className += ' linkOk'
  151. fixBoxObserver.observe(a, fixBoxMutationConfig);
  152. }
  153. else {
  154. console.log("incomplete span");
  155. image.className += ' notComplete';
  156. }
  157. }
  158. var fixImages = function(){
  159. var imagesContainer = document.getElementById('rg_s');
  160. if ( imagesContainer == null ) return;
  161. var images = imagesContainer.getElementsByClassName('rg_di');
  162. for (var i = 0 ; i< images.length ; i++) {
  163. fixImageBox(images[i]);
  164. }
  165. }
  166. var newBoxMutationConfig = { attributes: false, childList: true, characterData: false, subtree: true };
  167. var newBoxObserver = new MutationObserver(function(mutations){
  168. var needFix = false;
  169. mutations.forEach(function(mutation) {
  170. needFix = needFix || mutation.target.id == 'rg_s';
  171. });
  172. if (needFix)
  173. fixImages();
  174. });
  175.  
  176. fixImages();
  177. newBoxObserver.observe(document.body, newBoxMutationConfig);
  178.  
  179. var css = []; var i = 0;
  180. css[i++] = '.newCont { min-height: 30px; position: relative; height:100%; overflow: hidden; }';
  181. css[i++] = '.newCont>a { display: block; width: 100%; text-align: center; }';
  182. css[i++] = '.newCont>a>img { display: inline-block; }';
  183. css[i++] = '.newCont > a :not(img) { display: none; visibility: hidden; }';
  184. css[i++] = '.newCont .rg_ilmbg { display: none; left:0; }';
  185. css[i++] = '.newCont:hover .rg_ilmbg { display: block; }';
  186. css[i++] = '.imgSiteLnk {'; //img preview
  187. css[i++] = ' background-color: rgba(255, 255, 255, 0.77);';
  188. css[i++] = ' bottom: 0;';
  189. css[i++] = ' color: #000000;';
  190. css[i++] = ' display: block;';
  191. css[i++] = ' line-height: normal;';
  192. css[i++] = ' position: absolute;';
  193. css[i++] = ' text-decoration: none;';
  194. css[i++] = ' width: 100%; ';
  195. css[i++] = ' display: none }';
  196. css[i++] = '.imgPrev:hover .imgSiteLnk { display: block }';//img preview
  197. var style = document.createElement('style');
  198. style.type = 'text/css';
  199. style.appendChild(document.createTextNode(css.join('\n')));
  200. document.head.appendChild(style);
  201.  
  202. //img preview in google search (only links to page)
  203. var fixImagePreview = function(div){
  204. var images = document.getElementsByClassName('bicc');
  205. console.log('img preview in google search ' + images.length);
  206. for (var i = 0 ; i<images.length ; i++) {
  207. var div = images[i];
  208. var el = div.getElementsByTagName('a');
  209. if ( el.length == 1 ) {
  210. div.className += ' imgPrev';
  211. //div.style.border = '4em solid black';
  212. var href = el[0].href;
  213. var link = doubleDecode(parseUrl(href)['imgil']);
  214. if (link === false) continue;
  215. link = decode(link.split(';')[5]);
  216. var a = document.createElement('a');
  217. a.href = link;
  218. a.className = 'imgSiteLnk';
  219. a.textContent = link.split('/')[2];
  220. div.appendChild(a);
  221. }
  222. }
  223. }
  224. var searchObserver = new MutationObserver(function(mutations){
  225. fixImagePreview();
  226. });
  227. searchObserver.observe(document.body,
  228. {
  229. attributes: false,
  230. childList: true,
  231. characterData: false,
  232. subtree: true
  233. }
  234. );
  235. // visually similar search img preview (oly links to image)
  236. var similars = document.querySelectorAll('div#ires div.th a');
  237. console.log('visually similar search ' + similars.length)
  238. for (var i = 0 ; i < similars.length ; i++){
  239. var a = similars[i];
  240. var href = getNewImageLinks(a.href);
  241. if ( href.toImgHref === false ) {
  242. continue;
  243. }
  244. var newA = document.createElement('a');
  245. newA.href = href.toImgHref;
  246. newA.appendChild(a.firstChild);
  247. a.parentNode.replaceChild(newA, a);
  248. }
  249. console.log('end standard version');
  250. } //end standard version
  251.