NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name Reverse Image Search // @namespace github.com/cvzi/ // @version 1.0.3 // @description Search largest image on the page or current image on Google, TinEye, Yandex, SauceNAO and iqdb.org // @author cuzi // @copyright 2022, cuzi (https://github.com/cvzi/) // @license GPL-3.0-or-later // @match *://*/* // @icon https://raw.githubusercontent.com/hfg-gmuend/openmoji/master/color/72x72/1F5BC.png // @grant GM_openInTab // @grant GM_registerMenuCommand // ==/UserScript== /* Reverse Image Search Search largest image on the page or current image on Google, TinEye, Yandex, SauceNAO and iqdb.org Copyright (C) 2022, cuzi (https://github.com/cvzi/) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>. */ /* globals GM_openInTab, GM_registerMenuCommand */ /* jshint asi: true, esversion: 8 */ (function () { 'use strict' function onKeyDown (keyCode, cb) { return function (ev) { if (document.activeElement === document.body) { if (ev.ctrlKey && ev.key === keyCode) { ev.preventDefault() cb(ev) } } } } function getUrl () { if (document && document.body && document.body.firstChild.tagName === 'IMG') { return document.location.href } else { const biggestImage = Array.from(document.querySelectorAll('img[src^=http],img[srcset]')).filter(img => img.src.startsWith('http')).map(img => { return { img, size: img.clientWidth + img.clientHeight + img.naturalHeight + img.naturalWidth } }).sort((a, b) => a.size - b.size).map(o => o.img.src).pop() if (biggestImage) { return biggestImage } } return document.location.href } function google () { /* Google reverse image search */ GM_openInTab('https://www.google.com/imghp?sbi=1#habibi=' + encodeURIComponent(getUrl()), { active: true }) } function tinEye () { /* TinEye reverse image search */ GM_openInTab('https://tineye.com/search?url=' + encodeURIComponent(getUrl())) } function yandex () { /* Yandex reverse image search */ GM_openInTab('https://yandex.com/images/search?rpt=imageview&url=' + encodeURIComponent(getUrl())) } function sauceNAO () { /* SauceNAO reverse image search */ GM_openInTab('https://saucenao.com/search.php?url=' + encodeURIComponent(getUrl())) } function iqdb () { /* iqdb.org reverse image search */ GM_openInTab('http://iqdb.org/?url=' + encodeURIComponent(getUrl())) } GM_registerMenuCommand('Reverse Image Search - Google', google, 'g') GM_registerMenuCommand('Reverse Image Search - TinEye', tinEye, 'q') GM_registerMenuCommand('Reverse Image Search - Yandex', yandex, 'y') GM_registerMenuCommand('Reverse Image Search - SauceNAO', sauceNAO, 'x') GM_registerMenuCommand('Reverse Image Search - iqdb.org', iqdb, ',') if (document && document.body && document.body.firstChild.tagName === 'IMG') { document.addEventListener('keydown', onKeyDown('g', google)) document.addEventListener('keydown', onKeyDown('q', tinEye)) document.addEventListener('keydown', onKeyDown('y', yandex)) document.addEventListener('keydown', onKeyDown('x', sauceNAO)) document.addEventListener('keydown', onKeyDown(',', iqdb)) } else if (document.location.href.startsWith('/imghp') !== -1 && document.location.hash.startsWith('#habibi=')) { // Enter url into Google search form window.setTimeout(() => { const button = Array.from(document.querySelectorAll('[role="button"][jscontroller]>img[src],[role="button"][jscontroller]>svg')).pop() if (button.click) { button.click() } else { button.parentElement.click() } window.setTimeout(() => { document.querySelector('input[text=text]').value = decodeURIComponent(document.location.hash.substring(8)) document.querySelector('input[text=text]').nextElementSibling.click() }, 500) }, 500) } })()