Add support to next/prev page
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
// ==UserScript==
|
||||
// @name E-Hentai better viewer
|
||||
// @namespace https://github.com/lifegpc/userscript
|
||||
// @version 0.2.0
|
||||
// @version 0.2.1
|
||||
// @description Add a viewer to view original picture on website.
|
||||
// @author lifegpc
|
||||
// @match https://*.e-hentai.org/s/*/*
|
||||
@@ -14,34 +14,136 @@
|
||||
// @run-at document-start
|
||||
// ==/UserScript==
|
||||
GM_addStyle(GM_getResourceText("viewercss"));
|
||||
let cur_img = null;
|
||||
let obs = new MutationObserver((list) => {
|
||||
for (const m of list) {
|
||||
if (m.type == 'childList') {
|
||||
m.removedNodes.forEach(v => {
|
||||
if (cur_img != null && v == cur_img) {
|
||||
load();
|
||||
cur_img = null;
|
||||
}
|
||||
})
|
||||
function indirectEval(script) {
|
||||
return eval(`"use strict";${script}`);
|
||||
}
|
||||
function find_script() {
|
||||
let cols = document.getElementsByTagName("script");
|
||||
for (let col of cols) {
|
||||
if (col.innerHTML.startsWith("var ")) {
|
||||
return col.innerHTML;
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
let base_url = undefined;
|
||||
let cur_img = null;
|
||||
let cur_viewer = null;
|
||||
let script_text = undefined;
|
||||
let api_url = undefined;
|
||||
let gid = undefined;
|
||||
let showkey = undefined;
|
||||
let img_keys = {};
|
||||
let cur_page = null;
|
||||
let total_page = null;
|
||||
function get_api_url() {
|
||||
if (api_url !== undefined) return api_url;
|
||||
if (script_text === undefined) {
|
||||
script_text = find_script();
|
||||
}
|
||||
if (script_text === undefined) return undefined;
|
||||
api_url = indirectEval(`${script_text};api_url`);
|
||||
return api_url;
|
||||
}
|
||||
function get_base_url() {
|
||||
if (base_url !== undefined) return base_url;
|
||||
base_url = new URL(document.location.href)
|
||||
return base_url;
|
||||
}
|
||||
function get_gid() {
|
||||
if (gid !== undefined) return gid;
|
||||
if (script_text === undefined) {
|
||||
script_text = find_script();
|
||||
}
|
||||
if (script_text === undefined) return undefined;
|
||||
gid = indirectEval(`${script_text};gid`);
|
||||
return gid;
|
||||
}
|
||||
function get_showkey() {
|
||||
if (showkey !== undefined) return showkey;
|
||||
if (script_text === undefined) {
|
||||
script_text = find_script();
|
||||
}
|
||||
if (script_text === undefined) return undefined;
|
||||
showkey = indirectEval(`${script_text};showkey`);
|
||||
return showkey;
|
||||
}
|
||||
function api_call(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let api_url = get_api_url();
|
||||
if (!api_url) {
|
||||
reject("api_url not found.");
|
||||
return;
|
||||
}
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", api_url);
|
||||
xhr.withCredentials = true;
|
||||
xhr.onload = (ev) => {
|
||||
resolve(xhr);
|
||||
};
|
||||
xhr.onerror = (ev) => {
|
||||
reject(ev);
|
||||
}
|
||||
xhr.onabort = (ev) => {
|
||||
reject(ev);
|
||||
}
|
||||
xhr.send(JSON.stringify(data));
|
||||
})
|
||||
}
|
||||
function genUrl(gid, imgkey, page) {
|
||||
return new URL(`/s/${imgkey}/${gid}-${page}`, get_base_url())
|
||||
}
|
||||
async function loadPage(page) {
|
||||
let gid = get_gid();
|
||||
if (!gid) throw Error("gid not found.");
|
||||
let showkey = get_showkey();
|
||||
if (!showkey) throw Error("showkey not found.");
|
||||
let imgkey = img_keys[page];
|
||||
if (!imgkey) return;
|
||||
history.pushState({ page, imgkey }, document.title, genUrl(gid, imgkey, page).toString());
|
||||
let xhr = await api_call({ method: "showpage", gid, page, imgkey, showkey });
|
||||
let a = JSON.parse(xhr.responseText);
|
||||
if (cur_viewer) cur_viewer.destroy();
|
||||
document.getElementById("i1").style.width = a.x + "px";
|
||||
document.getElementById("i2").innerHTML = a.n + a.i;
|
||||
document.getElementById("i3").innerHTML = a.i3;
|
||||
document.getElementById("i4").innerHTML = a.i + a.n;
|
||||
document.getElementById("i5").innerHTML = a.i5;
|
||||
document.getElementById("i6").innerHTML = a.i6;
|
||||
document.getElementById("i7").innerHTML = a.i7;
|
||||
update_window_extents(parseInt(a.x), parseInt(a.y));
|
||||
load();
|
||||
}
|
||||
function replaceLink(a) {
|
||||
let ohtml = a.innerHTML;
|
||||
let na = document.createElement('a');
|
||||
let matched = a.href.match(/e[x-]hentai\.org\/s\/([^\/]+)\/\d+-(\d+)/);
|
||||
if (!matched) return;
|
||||
let num = parseInt(matched[2]);
|
||||
let img_key = matched[1];
|
||||
img_keys[num] = img_key;
|
||||
na.innerHTML = ohtml;
|
||||
na.addEventListener("click", () => { loadPage(num); });
|
||||
a.replaceWith(na);
|
||||
}
|
||||
let load = () => {
|
||||
let img = document.getElementById("img");
|
||||
if (img == null) {
|
||||
setTimeout(load, 100);
|
||||
return;
|
||||
}
|
||||
cur_page = parseInt(document.querySelector('#i2 span').innerText);
|
||||
total_page = parseInt(document.querySelector('#i2 span:last-child').innerText);
|
||||
cur_img = img;
|
||||
let parent = img.parentElement;
|
||||
parent.replaceWith(img);
|
||||
obs.observe(img.parentElement, {'childList': true, 'subtree': true});
|
||||
let options = {
|
||||
title: () => {
|
||||
return document.getElementsByTagName("h1")[0].innerText
|
||||
},
|
||||
navbar: false
|
||||
keyboard: false,
|
||||
navbar: false,
|
||||
loop: false,
|
||||
toolbar: { prev: { show: true, click: prevImage }, zoomIn: { show: true }, zoomOut: { show: true }, oneToOne: { show: true }, next: { show: true, click: nextImage } }
|
||||
};
|
||||
/**@type {HTMLAnchorElement}*/
|
||||
let original = document.querySelector("#i7>a");
|
||||
@@ -58,6 +160,74 @@ let load = () => {
|
||||
console.log("Inited complete");
|
||||
await viewer.show();
|
||||
};
|
||||
cur_viewer = viewer;
|
||||
img.addEventListener("click", click);
|
||||
let links = document.querySelectorAll(".sn a");
|
||||
for (let i of links) {
|
||||
replaceLink(i);
|
||||
}
|
||||
console.log(img_keys);
|
||||
};
|
||||
window.addEventListener("DOMContentLoaded", load);
|
||||
window.addEventListener("DOMContentLoaded", () => {
|
||||
// Remove default keyboard binding.
|
||||
// Add custom event listener.
|
||||
let scr = document.createElement("script");
|
||||
scr.innerHTML = 'document.onkeydown = () => {};document.addEventListener("update_window_extents", (ev) => {xres=ev.xres;yres=ev.yres;update_window_extents();});';
|
||||
document.head.append(scr);
|
||||
});
|
||||
function zoomIn() {
|
||||
if (cur_viewer) cur_viewer.zoom(-0.1);
|
||||
}
|
||||
function zoomOut() {
|
||||
if (cur_viewer) cur_viewer.zoom(0.1);
|
||||
}
|
||||
function moveDown() {
|
||||
if (cur_viewer) cur_viewer.move(0, -10);
|
||||
}
|
||||
function moveUp() {
|
||||
if (cur_viewer) cur_viewer.move(0, 10);
|
||||
}
|
||||
function moveLeft() {
|
||||
if (cur_viewer) cur_viewer.move(10, 0);
|
||||
}
|
||||
function moveRight() {
|
||||
if (cur_viewer) cur_viewer.move(-10, 0);
|
||||
}
|
||||
function prevImage() {
|
||||
if (cur_page === null) return;
|
||||
loadPage(cur_page - 1)
|
||||
}
|
||||
function nextImage() {
|
||||
if (cur_page === null) return;
|
||||
loadPage(cur_page + 1)
|
||||
}
|
||||
function update_window_extents(xres, yres) {
|
||||
let ev = new Event("update_window_extents");
|
||||
ev.xres = xres;
|
||||
ev.yres = yres;
|
||||
document.dispatchEvent(ev);
|
||||
}
|
||||
window.addEventListener("keydown", (e) => {
|
||||
if (!e.ctrlKey && !e.shiftKey) {
|
||||
if (e.key == "ArrowDown") {
|
||||
zoomIn();
|
||||
} else if (e.key == "ArrowUp") {
|
||||
zoomOut();
|
||||
} else if (e.key == "ArrowLeft") {
|
||||
prevImage();
|
||||
} else if (e.key == "ArrowRight") {
|
||||
nextImage();
|
||||
}
|
||||
} else if (e.ctrlKey && !e.shiftKey) {
|
||||
if (e.key == "ArrowDown") {
|
||||
moveDown();
|
||||
} else if (e.key == "ArrowUp") {
|
||||
moveUp();
|
||||
} else if (e.key == "ArrowLeft") {
|
||||
moveLeft();
|
||||
} else if (e.key == "ArrowRight") {
|
||||
moveRight();
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user