Image download helper

add keyboard shortcuts to open and download image files quicker

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Image download helper
// @namespace    https://github.com/glubsy/userscripts
// @version      0.09
// @description  add keyboard shortcuts to open and download image files quicker
// @author       glubsy
// @license      GPLv2
// @compatible   chrome Chrome_59.0.3071.109  + TamperMonkey
// @match        *
// @include      /^https?://.*tumblr.*/
// @include      /^https?://.*imgur.*/
// @include      /^https?://.*mixtape.*/
// @include      /^https?://.*uploadir.*/
// @copyright    Fuck copyrights
//// @require  	 https://code.jquery.com/jquery-1.11.2.min.js
// @require      https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js
// @grant        GM_openInTab
// @grant        GM_download
//// @grant       GM_addStyle
// @run-at       document-idle
//// @noframes
//jshint multistr: true
//esversion: 6
// ==/UserScript==

//TODO: -maybe implement a better save-as system? ie https://gist.github.com/derjanb/4431f674124ef1b11e30
//      -clean up

document.addEventListener ("DOMContentLoaded", DOM_ContentReady);

//=====================================================

var modkey_pressed = false, pointed_obj, pointed_div;
var img_links, img_links_iframe, class_links, currentLink, divs_links;
var photo_cover_class_links, photo_cover_ishref = "false";

$(document).ready(get_iframes_id());

function DOM_ContentReady () { gatherImages(); }

function gatherImages(){
	let myimages =  window.document.images;
	for (let i=0; i <= myimages.length; i++){
		if (myimages[i] === undefined) { continue; }
		if (myimages[i].src.indexOf("avatar") > 0) { continue; }
		myimages[i].onmouseenter = function (){ updateLink(this.src); pointed_obj = this; };
		myimages[i].onmouseout = function (){ updateLink(undefined); pointed_obj = undefined; };
		console.log("gatherImages: " + myimages[i].src);
	}
}


img_links = document.getElementsByTagName('img');
class_links = document.getElementsByClassName('photoset_photo');
a_links = document.getElementsByTagName('a');
divs_links = document.getElementsByTagName('div');
photo_cover_class_links = document.getElementsByClassName('photo-cover'); //a tumblr theme's specific case


/*/============================================================
// Just testing this, in case is becomes useful eventually:
var IMGmatches = [], IMGelems = document.getElementsByTagName("img"),
	iframes = document.getElementsByTagName('iframe'), l = IMGelems.length,
	m = iframes.length, i, j;
for( let i=0; i<l; i++) IMGmatches[i] = IMGelems[i];
for( let j=0; j<m; j++) {
	IMGelems = iframes[j].contentDocument.getElementsByTagName("img");
	l = IMGelems.length;
	for( i=0; i<l; i++) IMGmatches.push(IMGelems[i]);
}
//console.log("IMGelems: " + IMGmatches + IMGelems);

//==========================================================*/


function get_iframes_id(){
	//console.log("get_iframes_id()");

	/*
	var frames = window.frames;
	for (let i = 0; i < frames.length; i++) {
		console.log("frames.length: " + frames.length);
		console.log("frames[" + i + "] :" + frames[i].class);
	}*/

	//$('iframe').each(function(){
	$('.photoset').each(function(){  //.photoset works?
		var src = $(this).attr("src"); //photoset_number
		if ( src === undefined ) { return; }
		var iframe_numb = "photoset_iframe_" + src.replace(/\/post\/(\d+)\/photoset_iframe.*/, '$1');
		//console.log("get_iframes_id() found iframe:" + iframe_numb);

		var iframe = document.getElementById(iframe_numb);
		var innerDoc = iframe.contentDocument || iframe.contentWindow.document; //TODO: fix the error on cross-origin iframes
		//console.log("get_iframes_id(): iframe innerdoc: " + iframe + " " + innerDoc);

		/*TESTING deferring after fully loaded iframes
		if (iframe.addEventListener)
			iframe.addEventListener("load", function(){ console.log("TESTLOADED");}, false);
		else
			iframe.attachEvent("onload", function(){ console.log("TESTLOADEDELSE");});
		//END TESTING*/

		iframe.addEventListener("load", function() {
			console.log("get_iframes_id(): LOADED iFRAME!");
			/*iframe.addEventListener("keydown", function(event){ //not needed apparently
				if( event.keyCode==87 && event.shiftKey ) {
					modkey_pressed = true;
					downloadThis(currentLink);
				}
				console.log("%c get_iframes_id(): Key currentLink:" + currentLink, 'background: #222; color: #bb55cc' );
			});*/

			img_links_iframe = innerDoc.getElementsByTagName('img');  //	or img_links_iframe = innerDoc.links; ??
			a_links_iframe = innerDoc.getElementsByTagName('a');
			//console.log("get_iframes_id(): img_links_iframe: " + img_links_iframe.length);
			for(let i =0; i < img_links_iframe.length; i++){
				img_links_iframe[i].onmousemove = function (){ updateLink(this.src); pointed_obj = this; };
				console.log("get_iframes_id(): img_links_iframes[" + i + "]: " + img_links_iframe[i].src);
			}
			for(let j =0; j < a_links_iframe.length; i++){
				a_links_iframe[j].onmousemove = function (){ updateLink(this.href); pointed_obj = this; };
				console.log("get_iframes_id(): a_links_iframes[" + j + "]: " + a_links_iframe[j].href);
			}

		},false);
	}
					   );
}

//=======================================================

function updateLink(arg) {
	//console.log("%c BEFORE updateLink  :" + currentLink,'background: #222; color: #ccaa99');
	currentLink = arg;
	console.log("%c AFTER updateLink   :" + currentLink ,'background: #222; color: #bada99');
}

function downloadThis(thelink) {
	if( !modkey_pressed ) {
		return;
	}
	//GM_openInTab( currentLink );
	//console.log("%c Downloading currentlink :" + currentLink, 'background: #222; color: #bada55' );
	checkSize(0, thelink);
	//console.log("%c new_url                 :" + new_url, 'background: #222; color: #f46b42');
	if ( new_url.indexOf("NOLINK!") > -1) { return; }
	//=========================================================
	var filename = new_url.substring(new_url.lastIndexOf('/')+1);
	GM_download({url: new_url, name: filename, saveAs: true});
	//===========================================================*/
	if ( window.location.href.substring("imgur") > -1) {
		fadeImg(pointed_div);
	}
	else { fadeImg(pointed_obj); }
}

function openThisInTab(thelink) { //requires Tumblr Image Size script for best results
	//console.log("openThisInTab(): " + thelink);
	if( !modkey_pressed || thelink === undefined ) { return; }
	let cleanedLink = cleanRedirectURL( thelink );
	console.log("cleanedlink: " + cleanedLink);
	GM_openInTab( cleanedLink );
	if ( window.location.href.substring("imgur") > -1) { //fade div
		fadeImg(pointed_div, 0.6);
	}
	else { fadeImg(pointed_obj, 0.6); }
}

function cleanRedirectURL(crapLink){ //clean stupid tumblr redirect analytics
	crapLink = crapLink.replace(/(.*redirect.*)(http.*)&t=.*/, '$2');
	return translateHTMLCodes(crapLink);
}

function translateHTMLCodes(mystring){
	return mystring.replace(/&amp;/g, "&").replace(/&gt;/g, ">").replace(/&lt;/g, "<").replace(/&quot;/g, "\"").replace(/%3A/g, ":").replace(/%2F/g, "/");
}

document.addEventListener("keydown", function(event){
	if( event.keyCode==87 && event.shiftKey) {
		modkey_pressed = true;
		downloadThis(currentLink);
	}
	else if (event.altKey){
		modkey_pressed = true;
		openThisInTab(currentLink);
	}
	console.log("%c Key currentLink        :" + currentLink, 'background: #222; color: #bb55cc' );
});

document.addEventListener("keyup", function(event){
	//if( event.keyCode==87 && event.shiftKey) {
	//    modkey_pressed = false;
	//}
	if (event.keycode!==0) {
		modkey_pressed = false;
		currentLink = undefined;
		//console.log("ctrl_pressed is:" + modkey_pressed);
	}
});

document.addEventListener("keypress", onKeyPress);

function onKeyPress(event){
	if( event.keyCode!=87 && !event.shiftKey ) {
		modkey_pressed = false;
	}
}

document.addEventListener("mousemove",function(event){ //or "mousemove" or "mouseover" or mouseenter
	if( event.keyCode!=87 && !event.shiftKey ) {
		//get_iframes_id();
		//monitorLinks();
	}
});

checkForClickThroughCase();
getPhotoCoverLinks();
monitorLinks();


function getPhotoCoverLinks(){
	for(let i =0; i < photo_cover_class_links.length; i++){
		if (photo_cover_ishref == "false" ) { return; } //if a link to an external imgur is not there, skip it, don't add the extra original image above
		//console.log("photo_cover_class_links[" + i + "] :" + photo_cover_class_links[i].style.backgroundImage); //getting link from the css style, not ideal

		let myimg = photo_cover_class_links[i].style.backgroundImage;

		myimg = myimg.substring(4, myimg.length-1);
		myimg = myimg.replace(/(.*)(?=_)(_\d+)(.*)/, '$1' + '_500' + '$3');
		let myimghref = '<img src=' + myimg + '>'; //inserting extra original tumblr thumbnail above actual post

		photo_cover_class_links[i].innerHTML = photo_cover_class_links[i].innerHTML + myimghref;
		photo_cover_class_links[i].outerHTML+=myimghref; // add it to the div

		//console.log("innerHTML on : " + photo_cover_class_links[i] + "with :" + myimghref);
	}
}

function checkForClickThroughCase(){
	for(let i =0; i < a_links.length; i++){
		if (a_links[i].className == 'click-through-picture') {
			/*console.log("click-through detected for :" + a_links[i]);*/
			if (a_links[i].href.indexOf("redirect") > 0 || a_links[i].href.indexOf("tumblr") < 0 ) {
				photo_cover_ishref = "true";
			}
		}
	}
}

function monitorLinks(){
	for(let i =0; i < img_links.length; i++){
		img_links[i].onmouseenter = function(){
			//console.log("monitorLinks(): img_links[" + i + "]: updateLink with: " + this.src);
			updateLink(this.src);
			pointed_obj = this;
		};
	}
	for(let i =0; i < divs_links.length; i++){
		divs_links[i].onmouseenter = function(){
			//console.log("monitorLinks(): divs_links[" + i + "]: updateLink with: " + this);
			pointed_div = this;
			pointed_obj = this;
		};
	}
	for(let i =0; i < a_links.length; i++){
		a_links[i].onmouseenter = function(){
			//console.log("monitorLinks(): a_links[" + i + "]: updateLink with: " + this.href);
			updateLink(this.href);
			pointed_div = this;
		};
	}
}


function fadeImg(img, f_Opacity = 0.4){
	//console.log("fadeImg(): " + img);
	img.style.opacity = f_Opacity;
}

//====================================================================
// Tumblr/imgur specific checks

var sizes = [ '_raw.', '_1280.' ];
var new_url;

function checkSize(index, url) {
	if (url === undefined) { console.log("checkSize(): arg was undefined."); new_url = "NOLINK!"; return; }
	if (url.indexOf("tumblr") > -1) {
		if(url.indexOf("avatar") > -1) { new_url = url ; return; }
		if (index >= sizes.length) return;
		new_url = url.replace(/(https?:\/\/)?\d+\.(.*(?=_))(_\d*.)(.*)/, '$1' + '$2' + sizes[index] + '$4');
		if (new_url == url) return;
		$.ajax({
			url: new_url,
			type: 'HEAD',
			success: function(data, textStatus, jqXHR) {
				//console.log("New url is:" + new_url);
			},
			error: function(jqXHR, textStatus, errorThrown) {
				checkSize(index + 1);
			}
		});
	}
	else if (url.indexOf("imgur.com") > -1) {
		new_url = url.replace(/(https?:\/\/.*)&t.*/, '$1');  //remove imgur junk
		new_url = new_url.replace(/(https?:\/\/.*)g(\..*)/, '$1' + '$2' ); //don't fetch thumbnail
		//console.log("imgur new link: " + new_url);
	}
	else { new_url = url; return; }
}

//====================================================