-
-
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.15 | |
// @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; | |
[ | |
['.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 | |
].forEach(element => { | |
if (node.closest(element[0])) { | |
[container, version] = [node.closest(element[0]), element[1]]; | |
} | |
}); | |
return [container, version]; | |
} | |
// 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.nextSibling.querySelector('div a span').parentElement.parentElement.className.split(" ")[0]; // Desktop | |
} 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.nextSibling.querySelector('div a span').parentElement.parentElement.className.split(" ")[0]; // Desktop | |
} 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); |
You're welcome.
Added new Visit button class: kWgFk
@ner00 just curious, do you also use this on your phone with an extension-capable browser? (For reference I use Kiwi)
If yes, do you also experience this janky layout where the new Google Lens icon pushes the View Image button to the right?
@raniesantos I added a variable at the top of the script called SearchImgBtn
, if you reinstall the script now and set it to false then the Search Image button won't be visible.
Hello,
The view button is not visible when I'm signed in to my google account. I tested signing out and the view button is visible and working fine.
Is this a known limitation?
The view button is not visible when I'm signed in to my google account. I tested signing out and the view button is visible and working fine.
Is this a known limitation?
Yes and no.
The script uses class names to identify the location where it will place the button, problem is that Google randomly changes the class name every now and then; this used to happen very rarely, but now it's almost like every 2 or 3 months.
Ideally, this script should be rewritten to have a more robust approach, but unfortunately my coding chops aren't great and time is limited, so I just update the script mostly as is with the new class names whenever they change for anyone.
Since it is working for me as is, I can't find the new class name at the moment... but you can by following these instructions.
I'm using Vivaldi 6.2.3105.45 (Chrome 116.0.5845.168)
<img src="https://upload.wikimedia.org/wikipedia/commons/e/e7/Everest_North_Face_toward_Base_Camp_Tibet_Luca_Galuzzi_2006.jpg" jsaction="VQAsE" class="r48jcc pT0Scc iPVvYb" style="max-width: 2000px; height: 310px; margin: 0px; width: 465px;" alt="Mountain - Wikipedia" jsname="kn3ccd" aria-hidden="false">
Visit button
<a data-ved="0CBMQ3YkBahcKEwiIlIvA2ImBAxUAAAAAHQAAAAAQQw" class="j7ZI7c" role="button" tabindex="0" rel="noopener" target="_blank" href="https://www.google.com/url?sa=i&url=https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FMountain&psig=AOvVaw1k3dsLQ3BmMaUpwvwbv9HF&ust=1693667297371000&source=images&cd=vfe&opi=89978449&ved=0CBMQ3YkBahcKEwiIlIvA2ImBAxUAAAAAHQAAAAAQQw" jsaction="focus:trigger.HTIQtd;mousedown:trigger.HTIQtd;touchstart:trigger.HTIQtd;" aria-label="Visit Wikipedia" rlhc="1">
<div class="CMTEG efwPxe xdVOWd MjJqGe cd29Sd kM7Sgc">
<span class="iLgTbf indIKd cS4Vcb-pGL6qe-lfQAOe">Visit</span>
<svg viewBox="0 0 24 24" focusable="false" height="18" width="18">
<path d="M0 0h24v24H0z" fill="none"></path>
<path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"></path>
</svg>
</div>
</a>
@onmyouji Updated the script to v3.7.0.3 based on the info you shared. Update/reinstall and try it out.
It works, thank you!
Great! You're welcome.
I implemented a few changes that are supposed to hold out for longer and dynamically find the class names when they change. It still depends on a fixed structure which doesn't seem to change often, but when it does it will also break. For now this is just testing, I've left all the original code in commented.
v3.7.0.5 is the current version and seems to work fine with the dynamic implementation, time will tell if it was a good idea.
Can confirm, works in Firefox by Tampermonkey. Thank you!
It still doesn't work on me so I just send this here
Opera GX LVL 5 (core: 101.0.4843.85) Chromium version:115.0.5790.171
Img:
<img src="https://gumlet.assettype.com/afkgaming%2Fimport%2Fmedia%2Fimages%2F64144-5f5d9b481fe5863c196d3441322ab983.jpeg?w=1200&auto=format%2Ccompress&ogImage=true&enlarge=true" jsaction="VQAsE" class="r48jcc pT0Scc iPVvYb" style="max-width: 1200px; height: 299px; margin: 0px; width: 559px;" alt="What Does Copium Mean in Twitch Chat and Where Did It Originate?" jsname="kn3ccd" data-iml="4199.10000000149" aria-hidden="false">
Visit button:
<a data-ved="0CBMQ3YkBahcKEwj4kd7tpp2BAxUAAAAAHQAAAAAQBA" class="kWgFk j7ZI7c" role="button" aria-label="Buka" tabindex="0" rel="noopener" target="_blank" href="https://www.google.com/url?sa=i&url=https%3A%2F%2Fafkgaming.com%2Fesports%2Fnews%2F7410-what-does-copium-mean-in-twitch-chat-and-where-did-it-originate&psig=AOvVaw24sRPKHS9o6hINMVvcHlvr&ust=1694340367357000&source=images&cd=vfe&opi=89978449&ved=0CBMQ3YkBahcKEwj4kd7tpp2BAxUAAAAAHQAAAAAQBA" jsaction="focus:trigger.HTIQtd;mousedown:trigger.HTIQtd;touchstart:trigger.HTIQtd;" rlhc="1">
<div class="efwPxe MjJqGe kM7Sgc">
<span class="iLgTbf CzIFEe cS4Vcb-pGL6qe-lfQAOe">Buka</span>
</div>
</a>
Opera
This might be your problem, actually.
The class names you posted are known, but since I "improved" the script to not need them anymore, or at least for the time being, that's most probably not the cause of the issue. Not being too familiar with Opera and its extension mechanism, I tried this myself and sure enough it didn't work.
First, I had to go through hoops to enable TamperMonkey, since it's blacklisted by Opera for whatever reason, and then I noticed that even then it wasn't working, but the userscript was also not being loaded at all. That led to question why isn't TamperMonkey running a userscript when it definitely should be? The reason was not hard to find:
Opera implements an additional privacy protection mechanism. By default, extensions are not allowed to access and manipulate search results provided by most built-in engines. Users can give access to search page results on the Extensions list.
So, in order to work around this you have to give that access to the extension manually. Open opera://extensions
and scroll down to TamperMonkey (or whatever userscript extension you use), then enable the option Allow access to search page results
, that'll probably solve your problem.
@CharlieDavyKW do you have the actual View Image extension installed concurrently? If so, disable it.
Opera
This might be your problem, actually.
Ok now it is working. thanks
@ner00 I disabled it. I even cleared my Cookies and Cache. But it's still not working for me.
@CharlieDavyKW I'm not sure what could be the issue beside Google rolling out a "major" change for chunks of users at a time.
The following is obsolete, but let me know your results anyway:
Since it is working for me as is, I can't find the new class name at the moment... but you can by following these instructions.
Can you make this compatible with mobile version too?
Can you make this compatible with mobile version too?
I made a few adjustments, it seems to be working (at least for me on Kiwi browser, Android).
Give it a try now with v3.7.0.6
Btw, if you're bothered by the Google Lens icon (for searching identical images), you can disable it by changing the value of SearchImgBtn
to false
, in line 18
@CharlieDavyKW Check if the latest update (v3.7.0.6) fixes your previous issue - assuming you still have it.
For one of my two google users, google image searches don't have the "tbm=isch" parameter in the urls so the script won't trigger. Instead, I get "udm=2". So this makes the script work:
// @include http*://*.google.tld/search*udm=2*
@AuroraWright Thank you for sharing that, I've updated the script to include it.
My View Image Button is gone.... I Have Firefox and since today, the button is gone ._.! Oh man why...?
@AydenHitcher Same... just noticed, will have a look later on or tomorrow.
Thank you so much! Hope you find it. Have a nice Day :)!
I updated the script, but this is getting sloppier by the second. I didn't find a reliable way to hook to the target elements as before due to the elements and their characteristics being too bland to distinguish, and this last ditch effort is relying on a specific layout, which is different for desktop/tablet and mobile. If this keeps up I'll revert back to the old, but reliable, static class names.
As of now, v3.7.0.9 should be working on both desktop/tablet and mobile (most of the time)... feedback is appreciated.
Thanks for the update!