// ==UserScript==
// @name Handy ExHentai
// @namespace handyexhentai
// @version 2024.01.30
// @description Handy ExHentai.org
// @match *://exhentai.org/s/*
// @match *://g.e-hentai.org/s/*
// @match *://exhentai.org/mpv/*
// @match *://g.e-hentai.org/mpv/*
// @run-at document-end
// @grant unsafeWindow
// @noframes
// ==/UserScript==
function id(id) {return document.getElementById(id);}
if (typeof unsafeWindow === "undefined"){unsafeWindow = window;}
if(window.location.pathname.indexOf("/s/") == 0)
{
// hide top panel
id("i1").firstElementChild.style.display = "none";
id("i2").style.display = "none";
// hide scrollbar
document.body.style.overflow = "hidden";
function onkeydownP(b)
{
switch (b.keyCode)
{
case KeyEvent.DOM_VK_UP:
window.scrollBy({
top: -150,
left: 0,
behavior: 'smooth'
});
cancelEvent(b);
break;
case KeyEvent.DOM_VK_DOWN:
window.scrollBy({
top: 150,
left: 0,
behavior: 'smooth'
});
cancelEvent(b);
break;
case 112: // KeyEvent.DOM_VK_F1
if(!document.webkitFullscreenElement && !document.mozFullScreenElement)
{
if(!document.documentElement.webkitRequestFullscreen){document.documentElement.webkitRequestFullscreen = document.documentElement.mozRequestFullScreen;}
document.documentElement.webkitRequestFullscreen(window.ALLOW_KEYBOARD_INPUT);
}
else
{
if (document.webkitCancelFullScreen)
{
document.webkitCancelFullScreen();
}
else if (document.mozCancelFullScreen)
{
document.mozCancelFullScreen();
}
}
cancelEvent(b);
break;
}
}
window.addEventListener("keydown", onkeydownP, true);
if(navigator.userAgent.indexOf('Firefox') != -1) // firefox disables mouse wheel scroll if scrollbar is invisible, let's fix this
{
function onWheel(e)
{
window.scrollBy({
top: e.detail*2,
left: 0,
behavior: 'smooth'
});
}
unsafeWindow.addEventListener ("MozMousePixelScroll", onWheel, false);
}
// auto detect failed images
var DT;
function ad()
{
if(DT){clearTimeout(DT);}
DT = setTimeout(function() { console.warn("check");if(id("img").naturalWidth == 0){id("loadfail").click();}DT=0; }, 1500);
}
ad();
// preload 1 next page
var FireFox = ((navigator.userAgent.indexOf('Firefox') != -1) ? true : false);
var adr, ifr_img;
function makeframe()
{
var img = id("img");
var preload = id("preload");
if(!preload)
{
preload = document.createElement('iframe');
preload.id = "preload";
preload.style.display = "none";
document.body.appendChild(preload);
}
if(history.length != 1) // no preload right after direct page open from gallery with CTRL
{
if(FireFox)
{
adr = preload.src;
ifr_img = preload.contentDocument.img;
}
else
{
if(typeof preload.location !== 'undefined' ){adr = preload.location.href;}
ifr_img = preload.img;
}
if(!adr || parseInt(img.parentNode.href.split("-").pop()) > parseInt(adr.split("-").pop())) // not: reached last page || going backwards
{
if(typeof ifr_img === 'undefined' || ifr_img.complete || !ifr_img.naturalWidth) // image loaded or not started loading
{
preload.setAttribute("src", img.parentNode.href);
}
else
{
setTimeout(function() { makeframe(); }, 555);
}
}
}
}
if (typeof exportFunction === "undefined")
{
delete unsafeWindow.history.replaceState;
unsafeWindow.history.EXreplaceState = unsafeWindow.history.replaceState;
unsafeWindow.history.__proto__.replaceState = function (a,b,c)
{
unsafeWindow.history.EXreplaceState(a,b,c);
setTimeout(function() { makeframe(); }, 222);
ad();
}
}
else // FF 31
{
function RS(a,b,c)
{
//unsafeWindow.history.EXreplaceState(a,b,c); // no idea, wtf firefox?
setTimeout(function() { makeframe(); }, 222);
ad();
}
unsafeWindow.history.EXreplaceState = unsafeWindow.history.replaceState;
exportFunction(RS, unsafeWindow.history.__proto__, {defineAs: "replaceState"});
}
}
else // MPV
{
id("bar1").remove(); // settings pane at right
id("pane_thumbs").remove(); // thumbnails at left
// centering
id("pane_images").style.position="absolute";
id("pane_images").style.top="0px";
id("pane_images").style.left="0px";
id("pane_images").style.right="0px";
id("pane_images").style.bottom="0px";
id("pane_images").style.margin="auto auto";
// auto detect failed images
if (typeof exportFunction === "undefined")
{
unsafeWindow.Rrescale_image = unsafeWindow.rescale_image;
unsafeWindow.rescale_image= function (a,b)
{
unsafeWindow.Rrescale_image(a,b);
setTimeout(function() { if(b.naturalWidth == 0){unsafeWindow.action_reload(a); }}, 2000);
}
unsafeWindow.sync_thumbpane = function(){}; // - errors
unsafeWindow.preload_scroll_thumbs = function(){}; // - errors
}
else // FF 31
{
function rescale_image(a,b)
{
unsafeWindow.Rrescale_image(a,b);
setTimeout(function() { if(b.naturalWidth == 0){unsafeWindow.action_reload(a); }}, 2000);
}
unsafeWindow.Rrescale_image = unsafeWindow.rescale_image;
exportFunction(rescale_image, unsafeWindow, {defineAs: "rescale_image"});
exportFunction(function(){}, unsafeWindow, {defineAs: "sync_thumbpane"}); // - errors
exportFunction(function(){}, unsafeWindow, {defineAs: "preload_scroll_thumbs"}); // - errors
}
// F1 hotkey to FullScreen
function onkeydownP(b)
{
switch (b.keyCode)
{
case 112: // KeyEvent.DOM_VK_F1
document.styleSheets[1].cssRules[0].style.setProperty("border","0px solid rgb(227, 224, 209)"); // no border on images
if(!document.webkitFullscreenElement && !document.mozFullScreenElement)
{
if(!document.documentElement.webkitRequestFullscreen){document.documentElement.webkitRequestFullscreen = document.documentElement.mozRequestFullScreen;}
document.documentElement.webkitRequestFullscreen(window.ALLOW_KEYBOARD_INPUT);
}
else
{
if (document.webkitCancelFullScreen)
{
document.webkitCancelFullScreen();
}
else if (document.mozCancelFullScreen)
{
document.mozCancelFullScreen();
}
}
cancelEvent(b);
break;
}
}
window.addEventListener("keydown", onkeydownP, true);
}