Reverse TinEye Image Search

Dragging any image allows you to do a TinEye image search.

当前为 2018-05-05 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name        Reverse TinEye Image Search
// @namespace   AmineKudo
// @description Dragging any image allows you to do a TinEye image search.
// @include     *
// @exclude     *www.google.*/imghp*
// @exclude     *www.google.*/search?*site=imghp&*
// @exclude     *www.google.*/search?tbs=sbi:*
// @grant       none
// @version     1.00
// ==/UserScript==

if (!document || !document.body || top !== self) return;

/*=============*\
|*  CONSTANTS  *|
\*=============*/
var CONSTANT = {
    incorrectTimeout: 2000,      //Milliseconds
};

var EL = {
    body:       document.body,
    head:       document.getElementsByTagName('head')[0],
    zone:       null,       //Set later
    form:       null,       //Set later
    message:    null,       //Set later
};

var VAR = {
    dragImgSrc:    null,    //String
    dontHide:      false,   //Bool
    draggedOver:   false,   //Bool
};

var MESSAGE = {
    drop:       "Drop image here!",
    incorrect:  "This is not a valid image.",
    oldBrowser: "You browser is too old and cannot use FileReader HTML5 API, please uninstall this userscript",
};

var URL = {
    imageSearch:    "https://www.tineye.com/search?url=",
    formSearch:     "https://www.tineye.com/search",
};

/*=============*\
|*   CHECKS    *|
\*=============*/
if(!window.FileReader) {
    alert(MESSAGE.oldBrowser);
    return;
}

/*=============*\
|*  FUNCTIONS  *|
\*=============*/
function getId(id) {
    return document.getElementById(id);
}

function createEl(elementName, id /*optional*/, attrArr /*optional*/) {
    var el = document.createElement(elementName);
    if (id) {
        el.id = id;
    }
    if (attrArr) {
        try{
        for (var attr in attrArr) {
            el.setAttribute(attr, attrArr[attr]);
        }
        }catch(e){alert("Attributes are set wrong: "+e);}
    }
    return el;
}

function fileNameFromFileUrl (url) {
    var index = url.lastIndexOf("/");
    if (index == -1) {return url;}
    return url.substr(index + 1);
}

function fixDataUrl(dataURL) {
    return dataURL.substr(dataURL.indexOf(",") + 1)
                  .replace(/\//gm, "_").replace(/\+/gm, "-");
}


/*=============*\
|*    HTML     *|
\*=============*/
function addDropZone() {
    EL.zone = createEl("div", "userscripts-dropzone");
    EL.body.appendChild(EL.zone);
    
    EL.message = createEl("div", "userscripts-dropzone-message");
    EL.zone.appendChild(EL.message);
    attachDragEvents(false);
}

/*=============*\
|*     CSS     *|
\*=============*/
(function(){
    var CSS = {
            "#userscripts-dropzone" : {
                "margin" : "0",
                "height" : "50px",
                "width" : "100%",
                "-webkit-user-select" : "none",
                "-moz-user-select" : "none",
                "user-select" : "none",
                "position" : "fixed",
                "top" : "-140px",
                "left" : "0px",
                "background" : "#f0f0f0",
                "box-shadow" : "0 0px 10px rgba(0,0,0,0.8)",
                "box-sizing" : "border-box",
                "-webkit-box-sizing" : "border-box",
                "-moz-box-sizing" : "border-box",
                "z-index" : "10000000",
                "-moz-transition-property" : "top",
                "-moz-transition-duration" : "0.2s",
                "-moz-transition-timing-function" : "ease-out",
                "-webkit-transition-property" : "top",
                "-webkit-transition-duration" : "0.2s",
                "-webkit-transition-timing-function" : "ease-out",
                "transition-property" : "top",
                "transition-duration" : "0.2s",
                "transition-timing-function" : "ease-out",
            },
            "#userscripts-dropzone.show" : {
                "top"     : "0px",
            },
            "#userscripts-dropzone-message": {
                "text-align" : "center",
                "font-size" : "18px !important",
                "font-weight" : "bold !important",
                "font-family" : "Arial, san-serif !important",
                "color" : "black !important",
                "padding" : "15px",
            },
        },
        cssString = "",
        propString = "",
        eachSelector = "",
        style = createEl("style");
    for(var selector in CSS) {
        eachSelector = CSS[selector];
        propString = "";
        for(var property in eachSelector) {
            propString += property + ":" + eachSelector[property] + ";";
        }
        cssString += selector + "{" + propString + "}";
    }
    style.appendChild(document.createTextNode(cssString));
    EL.head.appendChild(style);
})();

/*=============*\
|*  FUNCTIONS  *|
\*=============*/

function openSearchUrl(url) {
    var fileName = fileNameFromFileUrl(url);
    
    // Check if real file
    if (fileName.indexOf(".") === -1) {
        displayIncorrectFile();
        return;
    }
    var tehUrl = URL.imageSearch + escape(url);
    window.open(tehUrl, "_blank");
    hide();
}

function displayIncorrectFile() {
    VAR.dontHide = true;
    EL.message.innerHTML = MESSAGE.incorrect;
    setTimeout(function(){
        VAR.dontHide = false;
        hide();
    }, CONSTANT.incorrectTimeout);
}

function processDrop(event) {
try{
    var dt = event.dataTransfer,
        link = dt.getData("Text"),
        imgUrl = VAR.dragImgSrc,
        files = dt.files,
        file = null,
        i = 0;
        
    if (imgUrl != null) {
        clearImageSource();
        openSearchUrl(imgUrl);
    } else if (link != "") {
        console.log(link)
        openSearchUrl(link);
    } else if (files.length > 0) {
        for (; i < files.length; i++) {
            file = files[i];
            var reader = new FileReader();
            reader.file = file;
            reader.addEventListener("loadend", processFile, false);
            try {
                reader.readAsDataURL(file);
            }catch(error) {
                displayIncorrectFile();
                if (console && console.log) {
                    console.log(error);
                }
            }
        }
    } else {
        displayIncorrectFile();
        if (console && console.log) {
            console.log("Not an image",event);
        }
    }
    stopBrowser(event);
}catch(e){alert(e)}
}

function processFile(event) {
    event.currentTarget.removeEventListener('loadend', processFile, false);
    if (this.result == "") {    
        displayIncorrectFile();
        return;
    }
    var dataUrl = fixDataUrl(this.result),
        fileName = this.file.name;
        
    setImageForm(dataUrl, fileName);
    EL.form.submit();
    hide();
    this.file = null;
    setImageForm("", "");
    
    // Fixes Chrome's form searching
    var counter = parseInt(EL.form.getAttribute('counter')) + 1;
    EL.form.setAttribute('counter', counter);
    EL.form.action = EL.form.getAttribute('origAction') + counter;
}

function setImageForm(dataUrl, fileName) {
    if (EL.form) {
        getId('userscripts-form-data-url').setAttribute('value', dataUrl);
        getId('userscripts-form-filename').setAttribute('value', fileName);
        return;
    }
    EL.form = createEl("form", "userscripts-form-image-search", {
                    enctype:    'multipart/form-data',
                    method:     'POST',
                    target:     '_blank',
                    action:     (URL.formSearch + '?d=0'),
                    origAction: (URL.formSearch + '?d'),
                    counter:    0,
                });
    var field1 = createEl("input", 'userscripts-form-data-url', {
                    type:       'hidden',
                    name:       'image',
                    value:      dataUrl
                }),
        field2 = createEl("input", null, {
                    type:       'hidden',
                    name:       'btnG',
                    value:      'Search'
                }),
        field3 = createEl("input", 'userscripts-form-filename', {
                    type:       'hidden',
                    name:       'filename',
                    value:      fileName
                }),
        field4 = createEl("input", null, {
                    type:       'hidden',
                    name:       'hl',
                    value:      'en'
                });
    EL.form.appendChild(field1);
    EL.form.appendChild(field2);
    EL.form.appendChild(field3);
    EL.form.appendChild(field4);
    EL.zone.appendChild(EL.form);
}

/*=============*\
|*   EVENTS    *|
\*=============*/

function detachDragEvents() {
    document.removeEventListener("dragstart", processDragStart, false);
    document.removeEventListener("dragenter", processDragEnter, false);
    
    document.addEventListener("dragend", clearImageSource, false);
    document.addEventListener("mouseover", mouseMove, false);
    EL.zone.addEventListener("dragover", dragOverZone, false);
    EL.zone.addEventListener("dragleave", dragOutZone, false);
    EL.zone.addEventListener("drop", processDrop, false);
}

function attachDragEvents(shouldRemoveEvents) {
    document.addEventListener("dragenter", processDragEnter, false);
    document.addEventListener("dragstart", processDragStart, false);
    
    if (!shouldRemoveEvents) {
        document.removeEventListener("dragend", clearImageSource, false);
        document.removeEventListener("mouseover", mouseMove, false);
        EL.zone.removeEventListener("dragover", dragOverZone, false);
        EL.zone.removeEventListener("dragleave", dragOutZone, false);
        EL.zone.removeEventListener("drop", processDrop, false);
    }
}
function stopBrowser(evt) {
    evt.stopPropagation();
    evt.preventDefault();
}

function dragOverZone(event){
    VAR.draggedOver = true;
    stopBrowser(event);
}

function dragOutZone(event){    
    VAR.draggedOver = false;
    stopBrowser(event);
}

function mouseMove(e) {
    if (VAR.draggedOver) {
        return;
    }
    if (EL.zone.className === "show") {
        hide();
    } else {
        attachDragEvents();
    }
}

function processDragStart(event) {
    var el = event.target;
    if (el.tagName === "IMG") {
        VAR.dragImgSrc = el.src;
    } else {
        var imgs = el.getElementsByTagName('img');
        if (imgs.length > 0) {
            VAR.dragImgSrc = imgs[0].src;
        } else {
            if (el.tagName !== "A" || el.getAttribute("href") == "") {
                detachDragEvents();
                return;
            }
        }
    }
    show();
}

function processDragEnter(event) {
    if (VAR.dragImgSrc != null || event.dataTransfer.getData('Text') == "") {
        show();
    } else {    
        detachDragEvents();
    }
}

/*=============*\
|*     MISC    *|
\*=============*/
function clearImageSource(event) {
    VAR.dragImgSrc = null;
    hide();
}

function show() {
    if (EL.zone.className === "show") {
        return;
    }
    EL.message.innerHTML = MESSAGE.drop;
    detachDragEvents();
    EL.zone.className = "show";
}

function hide() {
    if (EL.zone.className === "") {
        return;
    }
    attachDragEvents();
    if (VAR.dontHide) {
        return;
    }
    VAR.draggedOver = false;
    EL.zone.className = "";
}

/*=============*\
|*    START    *|
\*=============*/
addDropZone();