Gelbooru Image Viewer

Adds a fullscreen image view option when you click on images

Versione datata 23/11/2016. Vedi la nuova versione l'ultima versione.

Dovrai installare un'estensione come Tampermonkey, Greasemonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Userscripts per installare questo script.

Dovrai installare un'estensione come ad esempio Tampermonkey per installare questo script.

Dovrai installare un gestore di script utente per installare questo script.

(Ho già un gestore di script utente, lasciamelo installare!)

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

(Ho già un gestore di stile utente, lasciamelo installare!)

// ==UserScript==
// @id             gelbooru-slide
// @name           Gelbooru Image Viewer
// @version        1.0.4
// @namespace      intermission
// @author         intermission
// @license        CC0; https://wiki.creativecommons.org/wiki/CC0
// @description    Adds a fullscreen image view option when you click on images
// @include        http://gelbooru.com/index.php?*
// @include        https://gelbooru.com/index.php?*
// @run-at         document-start
// @grant          GM_registerMenuCommand
// ==/UserScript==

(function(){
	"use strict";
	var d = document, array = a => [].slice.call(a), observer, request, mouseUp, slideEl, slider, slidin, base = a => a.split("/").pop().split(".")[0].split("_").pop(), keyDown, find, current, preload, stor = localStorage, l, toggle = stor["gelbooru-slide"] == "true";
	
	if (!stor["gelbooru-slide"]) stor["gelbooru-slide"] = "false";
	
	GM_registerMenuCommand("Current image mode: " + (toggle ? "Always original size" : "Sample only"), () => {
		stor["gelbooru-slide"] = toggle ? "false" : "true";
		location.reload();
	});
	
	l = toggle ? ["ul>li>a[style*='font-weight:']", "href"] : ["#image", "src"];
	
	current = a => d.querySelector("img.preview[src*='" + base(slideEl.src) + "']").parentNode.parentNode;
	
	mouseUp = e => e.button == 0 && (e.preventDefault(), e.stopPropagation(), slider(e.target.parentNode));
	
	find = function(el, method) {
		var a;
		do {
			try {
				el = el[(method ? "next" : "previous") + "ElementSibling"];
				a = el.querySelector("a[data-full]");
			} catch(err) {
				return false;
			}
			if (a) break;
			a = false;
		} while(!a);
		return a;
	};
	
	preload = function() {
		var curr = current(), a = find(curr, true), b = find(curr, false);
		a && request(a);
		b && request(b);
		return;
	};
	
	keyDown = function(e) {
		var move;
		switch(e.keyCode) {
			case 32:
			case 39:
				move = true;
				break;
			case 37:
				move = false;
				break;
			case 38:
				window.location = current().firstElementChild.href;
				break;
			case 40:
				e.preventDefault();
				slideEl.click();
				break;
		}
		if (typeof move != "undefined") {
			e = find(current(), move);
			if (e) {
				let source = e.dataset.full
				if (source == "loading") {
					source = e.firstElementChild.src;
					request(e);
				}
				slideEl.removeAttribute("src");
				slideEl.src = source;
			}
			preload();
		}
	};
	
	slider = function(a) {
		var source = a.dataset.full, list;
		if (source == "loading") {
			source = a.firstElementChild.src;
			request(a);
		}
		list = array(d.querySelectorAll("body > *"));
		if (slidin) {
			let center;
			slidin = false;
			a = current().firstElementChild;
			slideEl.remove();
			slideEl = null;
			d.documentElement.removeAttribute("style");
			d.body.removeAttribute("style");
			list.forEach(a => a.dataset.slide = "false");
			a.classList.add("outlined");
			d.removeEventListener("keydown", keyDown, false);
			center = a.offsetTop + a.offsetHeight / 2 - window.innerHeight / 2;
			window.scrollTo(0, center < 0 ? 0 : center);
		} else {
			slidin = true;
			list.forEach(a => a.dataset.slide = "true");
			array(d.querySelectorAll("span>a.outlined")).map(a => a.classList.remove("outlined"));
			d.documentElement.style.height = d.body.style.height = d.documentElement.style.width = d.body.style.width = "100%";
			slideEl = d.createElement("img");
			slideEl.id = "slide";
			slideEl.alt = "Loading...";
			slideEl.src = source;
			slideEl.onclick = () => slider(a);
			d.body.appendChild(slideEl);
			d.addEventListener("keydown", keyDown, false);
			preload();
		} return;
	};
	
	request = function(node) {
		if (node.dataset.alreadyLoading) return;
		node.dataset.alreadyLoading = "true";
		return fetch(node.href).then(x => {
			if (x.ok) {
				x.text().then(text => {
					var doc = d.createElement("div"), img, _base;
					doc.innerHTML = text;
					if (img = doc.querySelector(l[0])) {
						_base = base(img[l[1]]);
						node.dataset.full = img[l[1]];
						if (slideEl.src.indexOf(_base) > -1)
							slideEl.src = img[l[1]];
					} else {
						fetch("/intermission.php").then(x2 => request(node))
					}
				});
			} else alert("Failed to make HTTP request\nDo you have an internet connection?")
		});
	};
	
	observer = new MutationObserver(function(mutations) {
		mutations.forEach(function(mutation) {
			array(mutation.addedNodes).forEach(function(node) {
				let a;
				if (node.nodeType == 1 && node.matches("span.thumb[id^='s']") && (a = node.firstElementChild) && !a.dataset.full) {
					if (node.querySelector("img[alt*='webm']")) return;
					a.dataset.full = "loading";
					a.onclick = mouseUp;
				}
			});
		}); 
	});
	observer.observe(d, {
		childList: true,
		subtree: true
	});
	
	d.addEventListener("animationend", e => e.animationName == 'Outlined' && e.target.classList.remove("outlined"), false);
	
	{
		let css = d.createElement("style");
		css.textContent = '@keyframes Outlined{0%{outline:6px solid orange}60%{outline:6px solid orange}100%{outline:6px solid transparent}}\n[data-slide="true"]{display:none!important;}#slide{max-width:100%;max-height:100%;min-width:100%;min-height:100%;object-fit:contain}.outlined{outline:6px solid transparent;animation-duration:4s;animation-name:Outlined}';
		d.head.appendChild(css);
	}
}())