// ==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();