Adds a fullscreen image view option when you click on images
当前为
// ==UserScript==
// @id gelbooru-slide
// @name Gelbooru Image Viewer
// @version 1.0.3
// @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 none
// ==/UserScript==
(function(){
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;
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("#image")) {
_base = base(img.src);
node.dataset.full = img.src;
if (slideEl.src.indexOf(_base) > -1)
slideEl.src = img.src;
} 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);
}
}())