-
-
Save ner00/ec9ae47e202b8e99f19be44a5af6baf3 to your computer and use it in GitHub Desktop.
| // ==UserScript== | |
| // @name View Image | |
| // @namespace https://github.com/bijij/ViewImage | |
| // @version 3.7.0.18 | |
| // @description Re-implements the Google Images' "View Image" and "Search by Image" buttons. | |
| // @author Joshua B | |
| // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAFdElEQVRoge2YX2xTVRzHv7ejc8BGmuAYwQXHgxmEIDVqIiEmHULUxIcaffShE2YMgdjBgwRM4HHu5ZpofGDorfpAjA8j0ZjxZxbcwERZWOKTPhjGxv51W9vb293/5/hw1/Z299ze27WgJPs2be89f379/M45v3N+t8C61rWuJ1qcW0X6zIkIR8FTRQ5TVQUIASi1KgvfBa3c02J5qX7r1z+U/cZi7F2K1e2Kt7byognrIvHcCZw+f8TBu4EFr997K2L89U8yPwg2eBl/eR3LCbvI4gKj7yoHVtm42HkaI00HmPYCzEJD4jfs+BMbD00yO7nBVyd/fQY6T2Nk+xHXeuYMEGMpDACNezIAKB4O7ag4vaXRZ5fbtWiS8oKyWbVsb23gfMG7OgBTLkI07skgKAZ6Z29tG2c0dLdssItThHS5tevYtZNvyKTDyEsY2H0KI22V4QGXINZ/bbcNHQU4riv46tRNT2s1KP3RUYHMz8VINuuAL8AMfdzs4GXGgNWl8H70Ssd7LHhRxMBua9kQTSqSAO5h5uLA41M63iOQuVkLvvMURrYfBlGzMOVFxpJ1qoIDj34WrJGfjZGcBT+6Am9IM4kNLTt7/diosIQerYrwooiBzl6Mbj8McwV++NOXuv3aYe9CBRUWnumypaxRdvhLnacw2vYaE97PMLIdWNPB5E/peI9AUiX4ERd4vzgeQVzfGFgNv9ZlY5fHNlo//RZ9IzIzNVUOr9QGD/jaRuvjyIErQzfTWan7s53vY7TNGnldmnaFN/JT0LMPoGUnoIsT0LMTTLvsk/hWWzk14bqCXbN1OYmPnBmLccGNgqkvJ4b71j7yBT32g+x634sJoue76gEP+N6FXJ971qQbfS/XLa/6z1OJWuVykK2egfocZPFv8hcMwu3/onvT215t3/s8FzG5QNKOdPnkZr/ZaP0V/y4fTS/j/IJEoye/XY57tV+QgCWJYtH2ZslHOu29jdJ7kZA5dsgV6sPkmY6ljT8KqRyFKFPklikfF6Swp13HhVN1mQHTMAepnuGNsUiMVa8adHCC+ymktCZAAaRyFMtmYDAupEO1/nbN6bT+R4SnylSEyvfxVbaN77l2tmxkj944J0znU2FCCbTmO1BaEyAEmM+SDo08JXgSeiyAmtJp424kyunzcRhZ9Ev7cDndGFKonowlL4QAoGf4bCwlL8byulLcmbXm25BbBagGsJCn0ZNChXigzEs/DhR6UddUUPs9EoYpCVSdQb+0D1fVdhBK8DA/H+IMOXns+icRUV/mlxTRBmHZ0lvuQG4VIMoUokL54x7xUGk42Q5UAAesoG2AKlD5fqhfeh5X1fYioE50TEpzYYWoyVlpobjGqQ2DgkJrsWYilaNQa4gHn8lc+TlgmuCJPBHuz+3FkPoM6MqrIMXQcF98CJMSJnxBevNt5LcKSGVJh+oSD14P9T4PspLE24diDyanYpcyu3BTexqAWuxS3os6rBRLbBUmhmEQEYHpd6LHL87HvvxgW8KbwtMBd205+EsCQAL4u9quFXQFwLmyEgOlDKzSE1nVM/C45fV0+79O5qiPbdTnDNQ3na5WlSaB6YCicWhqLHX7nhwMH7v+QgUzzmy11vxVnLsWFh+8XtqFDIXZzsUBoClode2T9uMu9ywPLNlaUNtnZTH3IpeOZW23XIW8bRJN88cAAKQaBzL5wHhoMwn3SfsxpLYDSLvAOAgqQ7HuqVsdBVpGAQBNs90gSob5XynTAUkO9J6b2Jsc3bQDCFQPXS24s750rW0egRHMokF7k/kM7Rqdr/DRCAlQnmsMhLlgwNqvPH1xNnCU0NWoziUGACAURKOgijlOG9A93vuzr3+r17WudT1h+hcMcjsg9ZBlWQAAAABJRU5ErkJggg== | |
| // @run-at document-end | |
| // @match *://*.google.com/search*tbm=isch* | |
| // @match *://*.google.ad/search*tbm=isch* | |
| // @match *://*.google.ae/search*tbm=isch* | |
| // @match *://*.google.com.af/search*tbm=isch* | |
| // @match *://*.google.com.ag/search*tbm=isch* | |
| // @match *://*.google.com.ai/search*tbm=isch* | |
| // @match *://*.google.al/search*tbm=isch* | |
| // @match *://*.google.am/search*tbm=isch* | |
| // @match *://*.google.co.ao/search*tbm=isch* | |
| // @match *://*.google.com.ar/search*tbm=isch* | |
| // @match *://*.google.as/search*tbm=isch* | |
| // @match *://*.google.at/search*tbm=isch* | |
| // @match *://*.google.com.au/search*tbm=isch* | |
| // @match *://*.google.az/search*tbm=isch* | |
| // @match *://*.google.ba/search*tbm=isch* | |
| // @match *://*.google.com.bd/search*tbm=isch* | |
| // @match *://*.google.be/search*tbm=isch* | |
| // @match *://*.google.bf/search*tbm=isch* | |
| // @match *://*.google.bg/search*tbm=isch* | |
| // @match *://*.google.com.bh/search*tbm=isch* | |
| // @match *://*.google.bi/search*tbm=isch* | |
| // @match *://*.google.bj/search*tbm=isch* | |
| // @match *://*.google.com.bn/search*tbm=isch* | |
| // @match *://*.google.com.bo/search*tbm=isch* | |
| // @match *://*.google.com.br/search*tbm=isch* | |
| // @match *://*.google.bs/search*tbm=isch* | |
| // @match *://*.google.bt/search*tbm=isch* | |
| // @match *://*.google.co.bw/search*tbm=isch* | |
| // @match *://*.google.by/search*tbm=isch* | |
| // @match *://*.google.com.bz/search*tbm=isch* | |
| // @match *://*.google.ca/search*tbm=isch* | |
| // @match *://*.google.cd/search*tbm=isch* | |
| // @match *://*.google.cf/search*tbm=isch* | |
| // @match *://*.google.cg/search*tbm=isch* | |
| // @match *://*.google.ch/search*tbm=isch* | |
| // @match *://*.google.ci/search*tbm=isch* | |
| // @match *://*.google.co.ck/search*tbm=isch* | |
| // @match *://*.google.cl/search*tbm=isch* | |
| // @match *://*.google.cm/search*tbm=isch* | |
| // @match *://*.google.cn/search*tbm=isch* | |
| // @match *://*.google.com.co/search*tbm=isch* | |
| // @match *://*.google.co.cr/search*tbm=isch* | |
| // @match *://*.google.com.cu/search*tbm=isch* | |
| // @match *://*.google.cv/search*tbm=isch* | |
| // @match *://*.google.com.cy/search*tbm=isch* | |
| // @match *://*.google.cz/search*tbm=isch* | |
| // @match *://*.google.de/search*tbm=isch* | |
| // @match *://*.google.dj/search*tbm=isch* | |
| // @match *://*.google.dk/search*tbm=isch* | |
| // @match *://*.google.dm/search*tbm=isch* | |
| // @match *://*.google.com.do/search*tbm=isch* | |
| // @match *://*.google.dz/search*tbm=isch* | |
| // @match *://*.google.com.ec/search*tbm=isch* | |
| // @match *://*.google.ee/search*tbm=isch* | |
| // @match *://*.google.com.eg/search*tbm=isch* | |
| // @match *://*.google.es/search*tbm=isch* | |
| // @match *://*.google.com.et/search*tbm=isch* | |
| // @match *://*.google.fi/search*tbm=isch* | |
| // @match *://*.google.com.fj/search*tbm=isch* | |
| // @match *://*.google.fm/search*tbm=isch* | |
| // @match *://*.google.fr/search*tbm=isch* | |
| // @match *://*.google.ga/search*tbm=isch* | |
| // @match *://*.google.ge/search*tbm=isch* | |
| // @match *://*.google.gg/search*tbm=isch* | |
| // @match *://*.google.com.gh/search*tbm=isch* | |
| // @match *://*.google.com.gi/search*tbm=isch* | |
| // @match *://*.google.gl/search*tbm=isch* | |
| // @match *://*.google.gm/search*tbm=isch* | |
| // @match *://*.google.gr/search*tbm=isch* | |
| // @match *://*.google.com.gt/search*tbm=isch* | |
| // @match *://*.google.gy/search*tbm=isch* | |
| // @match *://*.google.hk/search*tbm=isch* | |
| // @match *://*.google.com.hk/search*tbm=isch* | |
| // @match *://*.google.hn/search*tbm=isch* | |
| // @match *://*.google.hr/search*tbm=isch* | |
| // @match *://*.google.ht/search*tbm=isch* | |
| // @match *://*.google.hu/search*tbm=isch* | |
| // @match *://*.google.co.id/search*tbm=isch* | |
| // @match *://*.google.ie/search*tbm=isch* | |
| // @match *://*.google.co.il/search*tbm=isch* | |
| // @match *://*.google.im/search*tbm=isch* | |
| // @match *://*.google.co.in/search*tbm=isch* | |
| // @match *://*.google.iq/search*tbm=isch* | |
| // @match *://*.google.is/search*tbm=isch* | |
| // @match *://*.google.it/search*tbm=isch* | |
| // @match *://*.google.je/search*tbm=isch* | |
| // @match *://*.google.com.jm/search*tbm=isch* | |
| // @match *://*.google.jo/search*tbm=isch* | |
| // @match *://*.google.jp/search*tbm=isch* | |
| // @match *://*.google.co.jp/search*tbm=isch* | |
| // @match *://*.google.co.ke/search*tbm=isch* | |
| // @match *://*.google.com.kh/search*tbm=isch* | |
| // @match *://*.google.ki/search*tbm=isch* | |
| // @match *://*.google.kg/search*tbm=isch* | |
| // @match *://*.google.co.kr/search*tbm=isch* | |
| // @match *://*.google.com.kw/search*tbm=isch* | |
| // @match *://*.google.kz/search*tbm=isch* | |
| // @match *://*.google.la/search*tbm=isch* | |
| // @match *://*.google.com.lb/search*tbm=isch* | |
| // @match *://*.google.li/search*tbm=isch* | |
| // @match *://*.google.lk/search*tbm=isch* | |
| // @match *://*.google.co.ls/search*tbm=isch* | |
| // @match *://*.google.lt/search*tbm=isch* | |
| // @match *://*.google.lu/search*tbm=isch* | |
| // @match *://*.google.lv/search*tbm=isch* | |
| // @match *://*.google.com.ly/search*tbm=isch* | |
| // @match *://*.google.co.ma/search*tbm=isch* | |
| // @match *://*.google.md/search*tbm=isch* | |
| // @match *://*.google.me/search*tbm=isch* | |
| // @match *://*.google.mg/search*tbm=isch* | |
| // @match *://*.google.mk/search*tbm=isch* | |
| // @match *://*.google.ml/search*tbm=isch* | |
| // @match *://*.google.com.mm/search*tbm=isch* | |
| // @match *://*.google.mn/search*tbm=isch* | |
| // @match *://*.google.ms/search*tbm=isch* | |
| // @match *://*.google.com.mt/search*tbm=isch* | |
| // @match *://*.google.mu/search*tbm=isch* | |
| // @match *://*.google.mv/search*tbm=isch* | |
| // @match *://*.google.mw/search*tbm=isch* | |
| // @match *://*.google.com.mx/search*tbm=isch* | |
| // @match *://*.google.com.my/search*tbm=isch* | |
| // @match *://*.google.co.mz/search*tbm=isch* | |
| // @match *://*.google.com.na/search*tbm=isch* | |
| // @match *://*.google.com.ng/search*tbm=isch* | |
| // @match *://*.google.com.ni/search*tbm=isch* | |
| // @match *://*.google.ne/search*tbm=isch* | |
| // @match *://*.google.nl/search*tbm=isch* | |
| // @match *://*.google.no/search*tbm=isch* | |
| // @match *://*.google.com.np/search*tbm=isch* | |
| // @match *://*.google.nr/search*tbm=isch* | |
| // @match *://*.google.nu/search*tbm=isch* | |
| // @match *://*.google.co.nz/search*tbm=isch* | |
| // @match *://*.google.com.om/search*tbm=isch* | |
| // @match *://*.google.com.pa/search*tbm=isch* | |
| // @match *://*.google.com.pe/search*tbm=isch* | |
| // @match *://*.google.com.pg/search*tbm=isch* | |
| // @match *://*.google.com.ph/search*tbm=isch* | |
| // @match *://*.google.com.pk/search*tbm=isch* | |
| // @match *://*.google.pl/search*tbm=isch* | |
| // @match *://*.google.pn/search*tbm=isch* | |
| // @match *://*.google.com.pr/search*tbm=isch* | |
| // @match *://*.google.ps/search*tbm=isch* | |
| // @match *://*.google.pt/search*tbm=isch* | |
| // @match *://*.google.com.py/search*tbm=isch* | |
| // @match *://*.google.com.qa/search*tbm=isch* | |
| // @match *://*.google.ro/search*tbm=isch* | |
| // @match *://*.google.ru/search*tbm=isch* | |
| // @match *://*.google.rw/search*tbm=isch* | |
| // @match *://*.google.com.sa/search*tbm=isch* | |
| // @match *://*.google.com.sb/search*tbm=isch* | |
| // @match *://*.google.sc/search*tbm=isch* | |
| // @match *://*.google.se/search*tbm=isch* | |
| // @match *://*.google.com.sg/search*tbm=isch* | |
| // @match *://*.google.sh/search*tbm=isch* | |
| // @match *://*.google.si/search*tbm=isch* | |
| // @match *://*.google.sk/search*tbm=isch* | |
| // @match *://*.google.com.sl/search*tbm=isch* | |
| // @match *://*.google.sn/search*tbm=isch* | |
| // @match *://*.google.so/search*tbm=isch* | |
| // @match *://*.google.sm/search*tbm=isch* | |
| // @match *://*.google.sr/search*tbm=isch* | |
| // @match *://*.google.st/search*tbm=isch* | |
| // @match *://*.google.com.sv/search*tbm=isch* | |
| // @match *://*.google.td/search*tbm=isch* | |
| // @match *://*.google.tg/search*tbm=isch* | |
| // @match *://*.google.co.th/search*tbm=isch* | |
| // @match *://*.google.com.tj/search*tbm=isch* | |
| // @match *://*.google.tl/search*tbm=isch* | |
| // @match *://*.google.tm/search*tbm=isch* | |
| // @match *://*.google.tn/search*tbm=isch* | |
| // @match *://*.google.to/search*tbm=isch* | |
| // @match *://*.google.com.tr/search*tbm=isch* | |
| // @match *://*.google.tt/search*tbm=isch* | |
| // @match *://*.google.com.tw/search*tbm=isch* | |
| // @match *://*.google.co.tz/search*tbm=isch* | |
| // @match *://*.google.com.ua/search*tbm=isch* | |
| // @match *://*.google.co.ug/search*tbm=isch* | |
| // @match *://*.google.co.uk/search*tbm=isch* | |
| // @match *://*.google.com.uy/search*tbm=isch* | |
| // @match *://*.google.co.uz/search*tbm=isch* | |
| // @match *://*.google.com.vc/search*tbm=isch* | |
| // @match *://*.google.co.ve/search*tbm=isch* | |
| // @match *://*.google.vg/search*tbm=isch* | |
| // @match *://*.google.co.vi/search*tbm=isch* | |
| // @match *://*.google.com.vn/search*tbm=isch* | |
| // @match *://*.google.vu/search*tbm=isch* | |
| // @match *://*.google.ws/search*tbm=isch* | |
| // @match *://*.google.rs/search*tbm=isch* | |
| // @match *://*.google.co.za/search*tbm=isch* | |
| // @match *://*.google.co.zm/search*tbm=isch* | |
| // @match *://*.google.co.zw/search*tbm=isch* | |
| // @match *://*.google.cat/search*tbm=isch* | |
| // @match *://*.google.com/search*udm=2* | |
| // @match *://*.google.ad/search*udm=2* | |
| // @match *://*.google.ae/search*udm=2* | |
| // @match *://*.google.com.af/search*udm=2* | |
| // @match *://*.google.com.ag/search*udm=2* | |
| // @match *://*.google.com.ai/search*udm=2* | |
| // @match *://*.google.al/search*udm=2* | |
| // @match *://*.google.am/search*udm=2* | |
| // @match *://*.google.co.ao/search*udm=2* | |
| // @match *://*.google.com.ar/search*udm=2* | |
| // @match *://*.google.as/search*udm=2* | |
| // @match *://*.google.at/search*udm=2* | |
| // @match *://*.google.com.au/search*udm=2* | |
| // @match *://*.google.az/search*udm=2* | |
| // @match *://*.google.ba/search*udm=2* | |
| // @match *://*.google.com.bd/search*udm=2* | |
| // @match *://*.google.be/search*udm=2* | |
| // @match *://*.google.bf/search*udm=2* | |
| // @match *://*.google.bg/search*udm=2* | |
| // @match *://*.google.com.bh/search*udm=2* | |
| // @match *://*.google.bi/search*udm=2* | |
| // @match *://*.google.bj/search*udm=2* | |
| // @match *://*.google.com.bn/search*udm=2* | |
| // @match *://*.google.com.bo/search*udm=2* | |
| // @match *://*.google.com.br/search*udm=2* | |
| // @match *://*.google.bs/search*udm=2* | |
| // @match *://*.google.bt/search*udm=2* | |
| // @match *://*.google.co.bw/search*udm=2* | |
| // @match *://*.google.by/search*udm=2* | |
| // @match *://*.google.com.bz/search*udm=2* | |
| // @match *://*.google.ca/search*udm=2* | |
| // @match *://*.google.cd/search*udm=2* | |
| // @match *://*.google.cf/search*udm=2* | |
| // @match *://*.google.cg/search*udm=2* | |
| // @match *://*.google.ch/search*udm=2* | |
| // @match *://*.google.ci/search*udm=2* | |
| // @match *://*.google.co.ck/search*udm=2* | |
| // @match *://*.google.cl/search*udm=2* | |
| // @match *://*.google.cm/search*udm=2* | |
| // @match *://*.google.cn/search*udm=2* | |
| // @match *://*.google.com.co/search*udm=2* | |
| // @match *://*.google.co.cr/search*udm=2* | |
| // @match *://*.google.com.cu/search*udm=2* | |
| // @match *://*.google.cv/search*udm=2* | |
| // @match *://*.google.com.cy/search*udm=2* | |
| // @match *://*.google.cz/search*udm=2* | |
| // @match *://*.google.de/search*udm=2* | |
| // @match *://*.google.dj/search*udm=2* | |
| // @match *://*.google.dk/search*udm=2* | |
| // @match *://*.google.dm/search*udm=2* | |
| // @match *://*.google.com.do/search*udm=2* | |
| // @match *://*.google.dz/search*udm=2* | |
| // @match *://*.google.com.ec/search*udm=2* | |
| // @match *://*.google.ee/search*udm=2* | |
| // @match *://*.google.com.eg/search*udm=2* | |
| // @match *://*.google.es/search*udm=2* | |
| // @match *://*.google.com.et/search*udm=2* | |
| // @match *://*.google.fi/search*udm=2* | |
| // @match *://*.google.com.fj/search*udm=2* | |
| // @match *://*.google.fm/search*udm=2* | |
| // @match *://*.google.fr/search*udm=2* | |
| // @match *://*.google.ga/search*udm=2* | |
| // @match *://*.google.ge/search*udm=2* | |
| // @match *://*.google.gg/search*udm=2* | |
| // @match *://*.google.com.gh/search*udm=2* | |
| // @match *://*.google.com.gi/search*udm=2* | |
| // @match *://*.google.gl/search*udm=2* | |
| // @match *://*.google.gm/search*udm=2* | |
| // @match *://*.google.gr/search*udm=2* | |
| // @match *://*.google.com.gt/search*udm=2* | |
| // @match *://*.google.gy/search*udm=2* | |
| // @match *://*.google.hk/search*udm=2* | |
| // @match *://*.google.com.hk/search*udm=2* | |
| // @match *://*.google.hn/search*udm=2* | |
| // @match *://*.google.hr/search*udm=2* | |
| // @match *://*.google.ht/search*udm=2* | |
| // @match *://*.google.hu/search*udm=2* | |
| // @match *://*.google.co.id/search*udm=2* | |
| // @match *://*.google.ie/search*udm=2* | |
| // @match *://*.google.co.il/search*udm=2* | |
| // @match *://*.google.im/search*udm=2* | |
| // @match *://*.google.co.in/search*udm=2* | |
| // @match *://*.google.iq/search*udm=2* | |
| // @match *://*.google.is/search*udm=2* | |
| // @match *://*.google.it/search*udm=2* | |
| // @match *://*.google.je/search*udm=2* | |
| // @match *://*.google.com.jm/search*udm=2* | |
| // @match *://*.google.jo/search*udm=2* | |
| // @match *://*.google.jp/search*udm=2* | |
| // @match *://*.google.co.jp/search*udm=2* | |
| // @match *://*.google.co.ke/search*udm=2* | |
| // @match *://*.google.com.kh/search*udm=2* | |
| // @match *://*.google.ki/search*udm=2* | |
| // @match *://*.google.kg/search*udm=2* | |
| // @match *://*.google.co.kr/search*udm=2* | |
| // @match *://*.google.com.kw/search*udm=2* | |
| // @match *://*.google.kz/search*udm=2* | |
| // @match *://*.google.la/search*udm=2* | |
| // @match *://*.google.com.lb/search*udm=2* | |
| // @match *://*.google.li/search*udm=2* | |
| // @match *://*.google.lk/search*udm=2* | |
| // @match *://*.google.co.ls/search*udm=2* | |
| // @match *://*.google.lt/search*udm=2* | |
| // @match *://*.google.lu/search*udm=2* | |
| // @match *://*.google.lv/search*udm=2* | |
| // @match *://*.google.com.ly/search*udm=2* | |
| // @match *://*.google.co.ma/search*udm=2* | |
| // @match *://*.google.md/search*udm=2* | |
| // @match *://*.google.me/search*udm=2* | |
| // @match *://*.google.mg/search*udm=2* | |
| // @match *://*.google.mk/search*udm=2* | |
| // @match *://*.google.ml/search*udm=2* | |
| // @match *://*.google.com.mm/search*udm=2* | |
| // @match *://*.google.mn/search*udm=2* | |
| // @match *://*.google.ms/search*udm=2* | |
| // @match *://*.google.com.mt/search*udm=2* | |
| // @match *://*.google.mu/search*udm=2* | |
| // @match *://*.google.mv/search*udm=2* | |
| // @match *://*.google.mw/search*udm=2* | |
| // @match *://*.google.com.mx/search*udm=2* | |
| // @match *://*.google.com.my/search*udm=2* | |
| // @match *://*.google.co.mz/search*udm=2* | |
| // @match *://*.google.com.na/search*udm=2* | |
| // @match *://*.google.com.ng/search*udm=2* | |
| // @match *://*.google.com.ni/search*udm=2* | |
| // @match *://*.google.ne/search*udm=2* | |
| // @match *://*.google.nl/search*udm=2* | |
| // @match *://*.google.no/search*udm=2* | |
| // @match *://*.google.com.np/search*udm=2* | |
| // @match *://*.google.nr/search*udm=2* | |
| // @match *://*.google.nu/search*udm=2* | |
| // @match *://*.google.co.nz/search*udm=2* | |
| // @match *://*.google.com.om/search*udm=2* | |
| // @match *://*.google.com.pa/search*udm=2* | |
| // @match *://*.google.com.pe/search*udm=2* | |
| // @match *://*.google.com.pg/search*udm=2* | |
| // @match *://*.google.com.ph/search*udm=2* | |
| // @match *://*.google.com.pk/search*udm=2* | |
| // @match *://*.google.pl/search*udm=2* | |
| // @match *://*.google.pn/search*udm=2* | |
| // @match *://*.google.com.pr/search*udm=2* | |
| // @match *://*.google.ps/search*udm=2* | |
| // @match *://*.google.pt/search*udm=2* | |
| // @match *://*.google.com.py/search*udm=2* | |
| // @match *://*.google.com.qa/search*udm=2* | |
| // @match *://*.google.ro/search*udm=2* | |
| // @match *://*.google.ru/search*udm=2* | |
| // @match *://*.google.rw/search*udm=2* | |
| // @match *://*.google.com.sa/search*udm=2* | |
| // @match *://*.google.com.sb/search*udm=2* | |
| // @match *://*.google.sc/search*udm=2* | |
| // @match *://*.google.se/search*udm=2* | |
| // @match *://*.google.com.sg/search*udm=2* | |
| // @match *://*.google.sh/search*udm=2* | |
| // @match *://*.google.si/search*udm=2* | |
| // @match *://*.google.sk/search*udm=2* | |
| // @match *://*.google.com.sl/search*udm=2* | |
| // @match *://*.google.sn/search*udm=2* | |
| // @match *://*.google.so/search*udm=2* | |
| // @match *://*.google.sm/search*udm=2* | |
| // @match *://*.google.sr/search*udm=2* | |
| // @match *://*.google.st/search*udm=2* | |
| // @match *://*.google.com.sv/search*udm=2* | |
| // @match *://*.google.td/search*udm=2* | |
| // @match *://*.google.tg/search*udm=2* | |
| // @match *://*.google.co.th/search*udm=2* | |
| // @match *://*.google.com.tj/search*udm=2* | |
| // @match *://*.google.tl/search*udm=2* | |
| // @match *://*.google.tm/search*udm=2* | |
| // @match *://*.google.tn/search*udm=2* | |
| // @match *://*.google.to/search*udm=2* | |
| // @match *://*.google.com.tr/search*udm=2* | |
| // @match *://*.google.tt/search*udm=2* | |
| // @match *://*.google.com.tw/search*udm=2* | |
| // @match *://*.google.co.tz/search*udm=2* | |
| // @match *://*.google.com.ua/search*udm=2* | |
| // @match *://*.google.co.ug/search*udm=2* | |
| // @match *://*.google.co.uk/search*udm=2* | |
| // @match *://*.google.com.uy/search*udm=2* | |
| // @match *://*.google.co.uz/search*udm=2* | |
| // @match *://*.google.com.vc/search*udm=2* | |
| // @match *://*.google.co.ve/search*udm=2* | |
| // @match *://*.google.vg/search*udm=2* | |
| // @match *://*.google.co.vi/search*udm=2* | |
| // @match *://*.google.com.vn/search*udm=2* | |
| // @match *://*.google.vu/search*udm=2* | |
| // @match *://*.google.ws/search*udm=2* | |
| // @match *://*.google.rs/search*udm=2* | |
| // @match *://*.google.co.za/search*udm=2* | |
| // @match *://*.google.co.zm/search*udm=2* | |
| // @match *://*.google.co.zw/search*udm=2* | |
| // @match *://*.google.cat/search*udm=2* | |
| // @match *://*.google.com/imgres* | |
| // @match *://*.google.ad/imgres* | |
| // @match *://*.google.ae/imgres* | |
| // @match *://*.google.com.af/imgres* | |
| // @match *://*.google.com.ag/imgres* | |
| // @match *://*.google.com.ai/imgres* | |
| // @match *://*.google.al/imgres* | |
| // @match *://*.google.am/imgres* | |
| // @match *://*.google.co.ao/imgres* | |
| // @match *://*.google.com.ar/imgres* | |
| // @match *://*.google.as/imgres* | |
| // @match *://*.google.at/imgres* | |
| // @match *://*.google.com.au/imgres* | |
| // @match *://*.google.az/imgres* | |
| // @match *://*.google.ba/imgres* | |
| // @match *://*.google.com.bd/imgres* | |
| // @match *://*.google.be/imgres* | |
| // @match *://*.google.bf/imgres* | |
| // @match *://*.google.bg/imgres* | |
| // @match *://*.google.com.bh/imgres* | |
| // @match *://*.google.bi/imgres* | |
| // @match *://*.google.bj/imgres* | |
| // @match *://*.google.com.bn/imgres* | |
| // @match *://*.google.com.bo/imgres* | |
| // @match *://*.google.com.br/imgres* | |
| // @match *://*.google.bs/imgres* | |
| // @match *://*.google.bt/imgres* | |
| // @match *://*.google.co.bw/imgres* | |
| // @match *://*.google.by/imgres* | |
| // @match *://*.google.com.bz/imgres* | |
| // @match *://*.google.ca/imgres* | |
| // @match *://*.google.cd/imgres* | |
| // @match *://*.google.cf/imgres* | |
| // @match *://*.google.cg/imgres* | |
| // @match *://*.google.ch/imgres* | |
| // @match *://*.google.ci/imgres* | |
| // @match *://*.google.co.ck/imgres* | |
| // @match *://*.google.cl/imgres* | |
| // @match *://*.google.cm/imgres* | |
| // @match *://*.google.cn/imgres* | |
| // @match *://*.google.com.co/imgres* | |
| // @match *://*.google.co.cr/imgres* | |
| // @match *://*.google.com.cu/imgres* | |
| // @match *://*.google.cv/imgres* | |
| // @match *://*.google.com.cy/imgres* | |
| // @match *://*.google.cz/imgres* | |
| // @match *://*.google.de/imgres* | |
| // @match *://*.google.dj/imgres* | |
| // @match *://*.google.dk/imgres* | |
| // @match *://*.google.dm/imgres* | |
| // @match *://*.google.com.do/imgres* | |
| // @match *://*.google.dz/imgres* | |
| // @match *://*.google.com.ec/imgres* | |
| // @match *://*.google.ee/imgres* | |
| // @match *://*.google.com.eg/imgres* | |
| // @match *://*.google.es/imgres* | |
| // @match *://*.google.com.et/imgres* | |
| // @match *://*.google.fi/imgres* | |
| // @match *://*.google.com.fj/imgres* | |
| // @match *://*.google.fm/imgres* | |
| // @match *://*.google.fr/imgres* | |
| // @match *://*.google.ga/imgres* | |
| // @match *://*.google.ge/imgres* | |
| // @match *://*.google.gg/imgres* | |
| // @match *://*.google.com.gh/imgres* | |
| // @match *://*.google.com.gi/imgres* | |
| // @match *://*.google.gl/imgres* | |
| // @match *://*.google.gm/imgres* | |
| // @match *://*.google.gr/imgres* | |
| // @match *://*.google.com.gt/imgres* | |
| // @match *://*.google.gy/imgres* | |
| // @match *://*.google.hk/imgres* | |
| // @match *://*.google.com.hk/imgres* | |
| // @match *://*.google.hn/imgres* | |
| // @match *://*.google.hr/imgres* | |
| // @match *://*.google.ht/imgres* | |
| // @match *://*.google.hu/imgres* | |
| // @match *://*.google.co.id/imgres* | |
| // @match *://*.google.ie/imgres* | |
| // @match *://*.google.co.il/imgres* | |
| // @match *://*.google.im/imgres* | |
| // @match *://*.google.co.in/imgres* | |
| // @match *://*.google.iq/imgres* | |
| // @match *://*.google.is/imgres* | |
| // @match *://*.google.it/imgres* | |
| // @match *://*.google.je/imgres* | |
| // @match *://*.google.com.jm/imgres* | |
| // @match *://*.google.jo/imgres* | |
| // @match *://*.google.jp/imgres* | |
| // @match *://*.google.co.jp/imgres* | |
| // @match *://*.google.co.ke/imgres* | |
| // @match *://*.google.com.kh/imgres* | |
| // @match *://*.google.ki/imgres* | |
| // @match *://*.google.kg/imgres* | |
| // @match *://*.google.co.kr/imgres* | |
| // @match *://*.google.com.kw/imgres* | |
| // @match *://*.google.kz/imgres* | |
| // @match *://*.google.la/imgres* | |
| // @match *://*.google.com.lb/imgres* | |
| // @match *://*.google.li/imgres* | |
| // @match *://*.google.lk/imgres* | |
| // @match *://*.google.co.ls/imgres* | |
| // @match *://*.google.lt/imgres* | |
| // @match *://*.google.lu/imgres* | |
| // @match *://*.google.lv/imgres* | |
| // @match *://*.google.com.ly/imgres* | |
| // @match *://*.google.co.ma/imgres* | |
| // @match *://*.google.md/imgres* | |
| // @match *://*.google.me/imgres* | |
| // @match *://*.google.mg/imgres* | |
| // @match *://*.google.mk/imgres* | |
| // @match *://*.google.ml/imgres* | |
| // @match *://*.google.com.mm/imgres* | |
| // @match *://*.google.mn/imgres* | |
| // @match *://*.google.ms/imgres* | |
| // @match *://*.google.com.mt/imgres* | |
| // @match *://*.google.mu/imgres* | |
| // @match *://*.google.mv/imgres* | |
| // @match *://*.google.mw/imgres* | |
| // @match *://*.google.com.mx/imgres* | |
| // @match *://*.google.com.my/imgres* | |
| // @match *://*.google.co.mz/imgres* | |
| // @match *://*.google.com.na/imgres* | |
| // @match *://*.google.com.ng/imgres* | |
| // @match *://*.google.com.ni/imgres* | |
| // @match *://*.google.ne/imgres* | |
| // @match *://*.google.nl/imgres* | |
| // @match *://*.google.no/imgres* | |
| // @match *://*.google.com.np/imgres* | |
| // @match *://*.google.nr/imgres* | |
| // @match *://*.google.nu/imgres* | |
| // @match *://*.google.co.nz/imgres* | |
| // @match *://*.google.com.om/imgres* | |
| // @match *://*.google.com.pa/imgres* | |
| // @match *://*.google.com.pe/imgres* | |
| // @match *://*.google.com.pg/imgres* | |
| // @match *://*.google.com.ph/imgres* | |
| // @match *://*.google.com.pk/imgres* | |
| // @match *://*.google.pl/imgres* | |
| // @match *://*.google.pn/imgres* | |
| // @match *://*.google.com.pr/imgres* | |
| // @match *://*.google.ps/imgres* | |
| // @match *://*.google.pt/imgres* | |
| // @match *://*.google.com.py/imgres* | |
| // @match *://*.google.com.qa/imgres* | |
| // @match *://*.google.ro/imgres* | |
| // @match *://*.google.ru/imgres* | |
| // @match *://*.google.rw/imgres* | |
| // @match *://*.google.com.sa/imgres* | |
| // @match *://*.google.com.sb/imgres* | |
| // @match *://*.google.sc/imgres* | |
| // @match *://*.google.se/imgres* | |
| // @match *://*.google.com.sg/imgres* | |
| // @match *://*.google.sh/imgres* | |
| // @match *://*.google.si/imgres* | |
| // @match *://*.google.sk/imgres* | |
| // @match *://*.google.com.sl/imgres* | |
| // @match *://*.google.sn/imgres* | |
| // @match *://*.google.so/imgres* | |
| // @match *://*.google.sm/imgres* | |
| // @match *://*.google.sr/imgres* | |
| // @match *://*.google.st/imgres* | |
| // @match *://*.google.com.sv/imgres* | |
| // @match *://*.google.td/imgres* | |
| // @match *://*.google.tg/imgres* | |
| // @match *://*.google.co.th/imgres* | |
| // @match *://*.google.com.tj/imgres* | |
| // @match *://*.google.tl/imgres* | |
| // @match *://*.google.tm/imgres* | |
| // @match *://*.google.tn/imgres* | |
| // @match *://*.google.to/imgres* | |
| // @match *://*.google.com.tr/imgres* | |
| // @match *://*.google.tt/imgres* | |
| // @match *://*.google.com.tw/imgres* | |
| // @match *://*.google.co.tz/imgres* | |
| // @match *://*.google.com.ua/imgres* | |
| // @match *://*.google.co.ug/imgres* | |
| // @match *://*.google.co.uk/imgres* | |
| // @match *://*.google.com.uy/imgres* | |
| // @match *://*.google.co.uz/imgres* | |
| // @match *://*.google.com.vc/imgres* | |
| // @match *://*.google.co.ve/imgres* | |
| // @match *://*.google.vg/imgres* | |
| // @match *://*.google.co.vi/imgres* | |
| // @match *://*.google.com.vn/imgres* | |
| // @match *://*.google.vu/imgres* | |
| // @match *://*.google.ws/imgres* | |
| // @match *://*.google.rs/imgres* | |
| // @match *://*.google.co.za/imgres* | |
| // @match *://*.google.co.zm/imgres* | |
| // @match *://*.google.co.zw/imgres* | |
| // @match *://*.google.cat/imgres* | |
| // @updateURL https://gist.github.com/ner00/ec9ae47e202b8e99f19be44a5af6baf3/raw/viewimage.user.js | |
| // @downloadURL https://gist.github.com/ner00/ec9ae47e202b8e99f19be44a5af6baf3/raw/viewimage.user.js | |
| // ==/UserScript== | |
| 'use strict'; | |
| const DEBUG = false; | |
| const SearchImgBtn = true; | |
| const VERSIONS = { | |
| FEB18: 'FEB18', | |
| JUL19: 'JUL19', | |
| OCT19: 'OCT19' | |
| }; | |
| var images = new Object(); | |
| // Finds the div which contains all required elements | |
| function getContainer(node) { | |
| var container, version; | |
| // Static selectors | |
| const staticSelectors = [ | |
| ['.irc_c[style*="visibility: visible;"][style*="transform: translate3d(0px, 0px, 0px);"]', VERSIONS.FEB18], | |
| ['.irc_c[data-ved]', VERSIONS.JUL19], | |
| ['.tvh9oe', VERSIONS.OCT19], | |
| ['.EIehLd', VERSIONS.OCT19], // Actually 2024, but let's stick with it for simplicity | |
| ['.fHE6De', VERSIONS.OCT19], // Actually 2024, but let's stick with it for simplicity | |
| ['.Z7HyUd', VERSIONS.OCT19] // Actually late-2025, but let's stick with it for simplicity | |
| ]; | |
| // Try each static selector | |
| for (const [selector, ver] of staticSelectors) { | |
| container = node.closest(selector); | |
| if (container) { | |
| return [container, ver]; | |
| } | |
| } | |
| if (DEBUG) | |
| console.log('ViewImage: container class name was not found statically!'); | |
| // If no static selector matched, try dynamic lookup | |
| let img = node; | |
| if (img.tagName !== 'IMG') { | |
| img = node.querySelector('img[src][style][jsaction]') || node.closest('img[src][style][jsaction]'); | |
| } | |
| if (img && img.tagName === 'IMG') { | |
| const dynamicSelectors = [ | |
| 'div[data-lhcontainer]', | |
| '[data-lhcontainer]' | |
| ]; | |
| for (const selector of dynamicSelectors) { | |
| container = img.closest(selector); | |
| if (container) { | |
| version = VERSIONS.OCT19; | |
| return [container, version]; | |
| } | |
| } | |
| } | |
| if (DEBUG) | |
| console.log('ViewImage: container class name was not found dynamically!'); | |
| return [null, null]; | |
| } | |
| // Finds and deletes all extension related elements. | |
| function clearExtElements(container) { | |
| // Remove previously generated elements | |
| var oldExtensionElements = container.querySelectorAll('.vi_ext_addon'); | |
| for (var element of oldExtensionElements) { | |
| element.remove(); | |
| } | |
| } | |
| // Returns the image URL | |
| function findImageURL(container, version) { | |
| var image = null; | |
| switch (version) { | |
| case VERSIONS.FEB18: | |
| image = container.querySelector('img[src]#irc_mi, img[alt^="Image result"][src]:not([src^="https://encrypted-tbn"]).irc_mut, img[src].irc_mi'); | |
| break; | |
| case VERSIONS.JUL19: | |
| var iframe = container.querySelector('iframe.irc_ifr'); | |
| if (!iframe) | |
| return findImageURL(container, VERSIONS.FEB18); | |
| image = iframe.contentDocument.querySelector('img#irc_mi'); | |
| break; | |
| case VERSIONS.OCT19: | |
| //image = container.querySelector('img[src].n3VNCb, img[src].r48jcc'); | |
| image = container.querySelector('img[src][style][jsaction]'); // Testing a dynamic approach to finding the class name | |
| if (image.src in images) { | |
| return images[image.src]; | |
| } | |
| } | |
| // Override url for images using base64 embeds | |
| if (image === null || image.src === '' || image.src.startsWith('data')) { | |
| var thumbnail = document.querySelector('img[name="' + container.dataset.itemId + '"]'); | |
| if (thumbnail === null) { | |
| // If no thumbnail found, try getting image from URL | |
| var url = new URL(window.location); | |
| var imgLink = url.searchParams.get('imgurl'); | |
| if (imgLink) { | |
| return imgLink; | |
| } | |
| } else { | |
| var meta = thumbnail.closest('.rg_bx').querySelector('.rg_meta'); | |
| var metadata = JSON.parse(meta.innerHTML); | |
| return metadata.ou; | |
| } | |
| } | |
| // If the above doesn't work, use the link in related images to find it | |
| if (image === null || image.src === '' || image.src.startsWith('data')) { | |
| var target_image = container.querySelector('img.target_image'); | |
| if (target_image) { | |
| var link = target_image.closest('a'); | |
| if (link) { | |
| // Some extensions replace google image links with their original links | |
| if (link.href.match(/^[a-z]+:\/\/(?:www\.)?google\.[^/]*\/imgres\?/)) { | |
| var link_url = new URL(link.href); | |
| var new_imgLink = link_url.searchParams.get('imgurl'); | |
| if (new_imgLink) { | |
| return new_imgLink; | |
| } | |
| } else { | |
| return link.href; | |
| } | |
| } | |
| } | |
| } | |
| if (image) { | |
| return image.src; | |
| } | |
| } | |
| function addViewImageButton(container, imageURL, version) { | |
| // get the visit buttonm | |
| var visitButton, vbClassName; | |
| switch (version) { | |
| case VERSIONS.FEB18: | |
| visitButton = container.querySelector('td > a.irc_vpl[href]').parentElement; | |
| break; | |
| case VERSIONS.JUL19: | |
| visitButton = container.querySelector('a.irc_hol[href]'); | |
| break; | |
| case VERSIONS.OCT19: | |
| // Testing a dynamic approach to finding the class name | |
| try { | |
| vbClassName = document.querySelector('img[src][style][jsaction]').parentElement.parentElement.parentElement.nextSibling.querySelector('div a span').parentElement.parentElement.className.split(" ")[0]; // GIF Desktop? | |
| } catch (error) { | |
| if (DEBUG) | |
| console.log('ViewImage: vbClassName not found!'); | |
| } | |
| try { | |
| vbClassName = document.querySelector('img[src][style][jsaction]').parentElement.parentElement.parentElement.nextSibling.nextSibling.querySelector('div a span').parentElement.parentElement.className.split(" ")[0]; // Desktop | |
| } catch (error) { | |
| if (DEBUG) | |
| console.log('ViewImage: vbClassName not found!'); | |
| } | |
| try { | |
| vbClassName = document.querySelector('img[src][style][jsaction]').parentElement.parentElement.parentElement.nextSibling.querySelector('div a div').parentElement.className.split(" ")[0]; // Desktop2 | |
| } catch (error) { | |
| if (DEBUG) | |
| console.log('ViewImage: vbClassName not found!'); | |
| } | |
| try { | |
| vbClassName = document.querySelector('img[src][style][jsaction]').parentElement.parentElement.nextSibling.querySelector('div a span').parentElement.parentElement.className.split(" ")[0]; // GIF Mobile? | |
| } catch (error) { | |
| if (DEBUG) | |
| console.log('ViewImage: vbClassName not found!'); | |
| } | |
| if (!vbClassName) { vbClassName = document.querySelector('img[src][style][jsaction]').parentElement.parentElement.nextSibling.nextSibling.querySelector('div a span').parentElement.parentElement.className.split(" ")[0]; } // Mobile | |
| visitButton = container.querySelector('.ZsbmCf[href], a.J2oL9c, a.jAklOc, a.uZ49bd, a.e0XTue, a.kWgFk, a.j7ZI7c, a.'+vbClassName); | |
| break; | |
| } | |
| // Create the view image button | |
| var viewImageButton = visitButton.cloneNode(true); | |
| viewImageButton.classList.add('vi_ext_addon'); | |
| // Set the view image button url | |
| var viewImageLink; | |
| switch (version) { | |
| case VERSIONS.FEB18: | |
| viewImageLink = viewImageButton.querySelector('a'); | |
| break; | |
| default: | |
| viewImageLink = viewImageButton; | |
| } | |
| viewImageLink.href = imageURL; | |
| if (version == VERSIONS.OCT19) { | |
| viewImageLink.removeAttribute('jsaction'); | |
| } | |
| // Set additional options | |
| viewImageLink.setAttribute('target', '_blank'); | |
| // Set the view image button text | |
| var viewImageButtonText; | |
| switch (version) { | |
| case VERSIONS.FEB18: | |
| viewImageButtonText = viewImageButton.querySelector('.Tl8XHc'); | |
| break; | |
| case VERSIONS.JUL19: | |
| viewImageButtonText = viewImageButton.querySelector('.irc_ho'); | |
| break; | |
| case VERSIONS.OCT19: | |
| viewImageButtonText = viewImageButton.querySelector('.pM4Snf, .KSvtLc, .Pw5kW, .q7UPLe, .K8E1Be, .pFBf7b, span'); | |
| break; | |
| } | |
| viewImageButtonText.innerText = 'View image'; | |
| // Place the view image button | |
| visitButton.parentElement.insertBefore(viewImageButton, visitButton); | |
| visitButton.parentElement.insertBefore(visitButton, viewImageButton); | |
| } | |
| function addSearchImageButton(container, imageURL, version) { | |
| var link, vbClassName; | |
| switch (version) { | |
| case VERSIONS.FEB18: | |
| link = container.querySelector('.irc_dsh > a.irc_hol'); | |
| break; | |
| case VERSIONS.JUL19: | |
| link = container.querySelector('.irc_ft > a.irc_help'); | |
| break; | |
| case VERSIONS.OCT19: | |
| // Testing a dynamic approach to finding the class name | |
| try { | |
| vbClassName = document.querySelector('img[src][style][jsaction]').parentElement.parentElement.parentElement.nextSibling.querySelector('div a span').parentElement.parentElement.className.split(" ")[0]; // GIF? | |
| } catch (error) { | |
| if (DEBUG) | |
| console.log('ViewImage: vbClassName not found!'); | |
| } | |
| try { | |
| vbClassName = document.querySelector('img[src][style][jsaction]').parentElement.parentElement.parentElement.nextSibling.nextSibling.querySelector('div a span').parentElement.parentElement.className.split(" ")[0]; // Desktop | |
| } catch (error) { | |
| if (DEBUG) | |
| console.log('ViewImage: vbClassName not found!'); | |
| } | |
| try { | |
| vbClassName = document.querySelector('img[src][style][jsaction]').parentElement.parentElement.parentElement.nextSibling.querySelector('div a div').parentElement.className.split(" ")[0]; // Desktop2 | |
| } catch (error) { | |
| if (DEBUG) | |
| console.log('ViewImage: vbClassName not found!'); | |
| } | |
| try { | |
| vbClassName = document.querySelector('img[src][style][jsaction]').parentElement.parentElement.nextSibling.querySelector('div a span').parentElement.parentElement.className.split(" ")[0]; // GIF Mobile? | |
| } catch (error) { | |
| if (DEBUG) | |
| console.log('ViewImage: vbClassName not found!'); | |
| } | |
| if (!vbClassName) { vbClassName = document.querySelector('img[src][style][jsaction]').parentElement.parentElement.nextSibling.nextSibling.querySelector('div a span').parentElement.parentElement.className.split(" ")[0]; } // Mobile | |
| link = container.querySelector('.PvkmDc, .qnLx5b, .zSA7pe, .uZ49bd, .e0XTue, .kWgFk, .j7ZI7c, .'+vbClassName); | |
| break; | |
| } | |
| // Create the search by image button | |
| var searchImageButton = link.cloneNode(true); | |
| searchImageButton.classList.add('vi_ext_addon'); | |
| // Set the more sizes button text | |
| var searchImageButtonText; | |
| switch (version) { | |
| case VERSIONS.FEB18: | |
| searchImageButtonText = container.querySelector('.irc_ho'); | |
| break; | |
| case VERSIONS.JUL19: | |
| searchImageButtonText = searchImageButton.querySelector('span'); | |
| break; | |
| case VERSIONS.OCT19: | |
| searchImageButtonText = searchImageButton.querySelector('span'); | |
| break; | |
| } | |
| searchImageButtonText.innerText = ''; | |
| var lensButton = document.createElement("img"); | |
| lensButton.style.marginTop = "5px"; | |
| lensButton.style.width = "23px"; | |
| lensButton.src = "https://fonts.gstatic.com/s/i/productlogos/lens_2023q2/v2/192px.svg"; | |
| lensButton.alt = "Search by image"; | |
| searchImageButtonText.appendChild(lensButton); | |
| // Set the search by image button url | |
| searchImageButton.href = 'https://lens.google.com/uploadbyurl?url=' + encodeURIComponent(imageURL); | |
| // Set additional options | |
| if (true) { | |
| searchImageButton.setAttribute('target', '_blank'); | |
| } | |
| // Place the more sizes button | |
| link.parentElement.insertBefore(searchImageButton, link); | |
| link.parentElement.insertBefore(link, searchImageButton); | |
| } | |
| // Adds links to an object | |
| function addLinks(node) { | |
| if (DEBUG) | |
| console.log('ViewImage: Trying to add links to node: ', node); | |
| // Find the container | |
| var [container, version] = getContainer(node); | |
| // Return if no container was found | |
| if (!container) { | |
| if (DEBUG) | |
| console.log('ViewImage: Adding links failed, container was not found.'); | |
| return; | |
| } | |
| if (DEBUG) | |
| console.log('ViewImage: Assuming site version: ', version); | |
| // Clear any old extension elements | |
| clearExtElements(container); | |
| // Find the image url | |
| var imageURL = findImageURL(container, version); | |
| // Return if image was not found | |
| if (!imageURL) { | |
| if (DEBUG) | |
| console.log('ViewImage: Adding links failed, image was not found.'); | |
| return; | |
| } | |
| addViewImageButton(container, imageURL, version); | |
| if (SearchImgBtn) | |
| addSearchImageButton(container, imageURL, version); | |
| } | |
| function parseDataSource(array) { | |
| var meta = array[31][0][12][2]; | |
| for (var i = 0; i < meta.length; i++) { | |
| try { | |
| images[meta[i][1][2][0]] = meta[i][1][3][0]; | |
| } catch (error) { | |
| if (DEBUG) | |
| console.log('ViewImage: Skipping image'); | |
| } | |
| } | |
| } | |
| function parseDataSource1() { | |
| const start_search = /AF_initDataCallback\({key:\s'ds:1',\sisError:\s{2}false\s,\shash:\s'\d+',\sdata:/; | |
| const end_search = ', sideChannel: {}});</script>'; | |
| var match = document.documentElement.innerHTML.match(start_search); | |
| var start_index = match.index + match[0].length; | |
| var end_index = start_index + document.documentElement.innerHTML.slice(start_index).indexOf(end_search); | |
| parseDataSource(JSON.parse(document.documentElement.innerHTML.slice(start_index, end_index))); | |
| } | |
| function parseDataSource2() { | |
| const start_search = /AF_initDataCallback\({key:\s'ds:2',\sisError:\s{2}false\s,\shash:\s'\d+',\sdata:function(){return\s/; | |
| const end_search = '}});</script>'; | |
| var match = document.documentElement.innerHTML.match(start_search); | |
| var start_index = match.index + match[0].length; | |
| var end_index = start_index + document.documentElement.innerHTML.slice(start_index).indexOf(end_search); | |
| parseDataSource(JSON.parse(document.documentElement.innerHTML.slice(start_index, end_index))); | |
| } | |
| // Check if source holds array of images | |
| try { | |
| if (document.documentElement.innerHTML.indexOf('key: \'ds:1\'') != -1) { | |
| if (DEBUG) | |
| console.log('ViewImage: Attempting to parse data source 1.'); | |
| parseDataSource1(); | |
| } else if (document.documentElement.innerHTML.indexOf('key: \'ds:2\'') != -1) { | |
| if (DEBUG) | |
| console.log('ViewImage: Attempting to parse data source 2.'); | |
| parseDataSource2(); | |
| } else { | |
| throw 'Could not determine data source type.'; | |
| } | |
| if (DEBUG) | |
| console.log('ViewImage: Successfully created source images array.'); | |
| } catch (error) { | |
| if (DEBUG) { | |
| console.log('ViewImage: Failed to create source images array.'); | |
| console.error(error); | |
| } | |
| } | |
| // Define the mutation observers | |
| var observer = new MutationObserver(function (mutations) { | |
| if (DEBUG) | |
| console.log('ViewImage: Mutations detected: ', mutations); | |
| var node, imgClassName; | |
| imgClassName = document.querySelector('img[src][style][jsaction]').className.split(" ")[0]; // Testing a dynamic approach to finding the class name | |
| for (var mutation of mutations) { | |
| if (mutation.addedNodes && mutation.addedNodes.length > 0) { | |
| for (node of mutation.addedNodes) { | |
| if (node.classList) { | |
| // Check for new image nodes | |
| //if (['irc_mi', 'irc_mut', 'irc_ris', 'n3VNCb', 'r48jcc'].some(className => node.classList.contains(className))) { | |
| if ([imgClassName].some(className => node.classList.contains(className))) { | |
| addLinks(node); | |
| } | |
| } | |
| } | |
| } | |
| //if (mutation.target.classList && mutation.target.classList.contains('n3VNCb', 'r48jcc')) { | |
| if (mutation.target.classList && mutation.target.classList.contains(imgClassName)) { | |
| node = mutation.target.closest('.tvh9oe'); | |
| if (!node.hasAttribute('aria-hidden')) { | |
| addLinks(node); | |
| } | |
| } | |
| } | |
| }); | |
| // Start adding links | |
| if (DEBUG) | |
| console.log('ViewImage: Initialising observer...'); | |
| observer.observe(document.body, { | |
| childList: true, | |
| subtree: true, | |
| attributes: true | |
| }); | |
| // inject CSS into document | |
| if (DEBUG) | |
| console.log('ViewImage: Injecting CSS...'); | |
| var customStyle = document.createElement('style'); | |
| customStyle.innerText = ` | |
| .irc_dsh>.irc_hol.vi_ext_addon, | |
| .irc_ft>.irc_help.vi_ext_addon, | |
| .PvkmDc.vi_ext_addon, | |
| .qnLx5b.vi_ext_addon | |
| { | |
| margin: 0 4pt!important | |
| } | |
| .irc_hol.vi_ext_addon | |
| { | |
| flex-grow:0!important | |
| } | |
| /* | |
| .uZ49bd[href^="https://lens.google.com/uploadbyurl"] { | |
| margin-left: 4px; | |
| } | |
| */ | |
| .ZsbmCf.vi_ext_addon{ | |
| flex-grow:0 | |
| }`; | |
| document.head.appendChild(customStyle); |
@firas5673 It's a wonky implementation, but it seems to work on desktop and mobile, give it a try.
I tried it, and it works most of the time, but the button sometimes doesn't show up in rare cases.
I'm not sure if it has to do with the sites hosting the image, because I saw that most gifs from Tenor get the button just fine, but there was one that didn't show up (even after the gif loaded fully, and even after I clicked on another image and back to it). Same thing happened with another site.
Then I closed the page and tried again, clicked on the same search result, and the button showed up. I tried a lot of other results and the button showed up just fine, except for another result.
Overall I think it's fine, so thank you for the follow up.
Does it work for you? Since today the button is gone :o
It still works for me on my desktop's browsers, but on my phone it's not working. It's pretty hard to debug on the phone itself so I typically use the desktop browser's DevTools to "emulate" a smartphone, but unfortunately it still works in that mode too so I don't have any decent way of figuring out what has changed - yet.
I'm not entirely sure if the new changes I made for 3.7.0.17 fix it for anyone, but I found that Google was giving different html structures on occasion so that's what I changed on this revision. Supposedly it only fixes anything for desktop resolutions.
I'm not entirely sure if the new changes I made for 3.7.0.17 fix it for anyone, but I found that Google was giving different html structures on occasion so that's what I changed on this revision. Supposedly it only fixes anything for desktop resolutions.
Ah with he new Code it working again. Thanks a lot <3!!!
Seems to be working great, thanks. :)
Today the button is gone again haha. What the hell does google every day...
Today the button is gone again haha. What the hell does google every day...
I hear you.
I don't have that issue (yet) but for lack of opportunity and time, I'm inclined to recommend a different extension (Firefox, but might be available for Chromium browsers): https://addons.mozilla.org/en-US/firefox/addon/photoshow/
I hope you can fix it again. View Image is that Extension i usw every Day haha.
I'm inclined to recommend a different extension (Firefox, but might be available for Chromium browsers): https://addons.mozilla.org/en-US/firefox/addon/photoshow/
PhotoShow sucks tbh, please fix the extension 😭
@AydenHitcher @kevingandrades Which platform and browser are you guys using? I've tried using Firefox 145.0.2 (64-bit) and Chrome 142.0.7444.176 (64-bit) on Windows 10 and I still haven't got any issue. Although, I can see a problem with mobile resolution.
Which platform and browser are you guys using?
Microsoft Edge 142.0.3595.94 (64-bit) on Windows 11 25H2 (OS Build 26200.7171)
Thank you for the effort. Unfortunately it did not help advance a solution, as you can see in the screenshot below, using Microsoft Edge 142.0.3595.94
I can see there is a classname error though, but I can't do anything about it unless I experience it myself or get that HTML shared with me. Let's get down to basics, try following the instructions in this old comment: https://gist.github.com/ner00/ec9ae47e202b8e99f19be44a5af6baf3?permalink_comment_id=4624468#gistcomment-4624468
Usually, Google (like all big-tech) changes some code for a certain percentage of a demographic, geographic, platform. It has happened before, but I assume their geo rules may have become stricter. That being said, I can't do much without relying on my fellows first-hand experiencing those changes.
NOTE: Your resolution appears to be 1440x900, I have yet to test for that itself, I won't at the moment due to time and resources constraints.
@AydenHitcher @kevingandrades Alright, it was my turn to lose the functionality today. The good news is that the fix wasn't hard, but I also took the time to implement a dynamic lookup fallback for this particular node that was always static; I still declared it statically, but could stand better to the test of time...
The bad news is, I didn't have the time to look into mobile, so that's possibly still f*ckd - so sorry about that.
Try and update to v3.7.0.18, I hope it works!
Tested View Image 3.7.0.18 on Mozilla Firefox 146.0 (64-bit) / Microsoft Windows 10.0.26200.7309 — works great. @ner00, thanks!
Thanks for the feedback, @Korb ! Glad to know it works for you.
Works for me too on both Chrome on macOS and Safari on iOS, thanks!
Oh, wow, nice. I'm surprised it's working on mobile at all. Last time I checked it wasn't (on Android, at least). I just tested it with mine and it's now also working. I'm not sure if there is a coincidence with either the latest container class name or the dynamic lookup, but it's great in any case. Thanks for getting back with that info, @AuroraWright .


This script doesn't work with gifs. Can you please add support for them?