Last active
January 9, 2017 12:05
-
-
Save mcpower/0fc6ef8d61a81bfdd7b50e4478b2d293 to your computer and use it in GitHub Desktop.
Dynasty Preloader
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Dynasty Preloader | |
// @namespace http://tampermonkey.net/ | |
// @version 0.3.5.1 | |
// @description Preloads Dynasty Reader pages. | |
// @author mcpower | |
// @match http://dynasty-scans.com/chapters/* | |
// @grant none | |
// @license GPLv3 | |
// ==/UserScript== | |
// Dynasty Preloader - a UserScript to preload pages in Dynasty Reader | |
// Copyright (C) 2017 mcpower | |
// | |
// This program is free software: you can redistribute it and/or modify | |
// it under the terms of the GNU General Public License as published by | |
// the Free Software Foundation, either version 3 of the License, or | |
// (at your option) any later version. | |
// | |
// This program is distributed in the hope that it will be useful, | |
// but WITHOUT ANY WARRANTY; without even the implied warranty of | |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
// GNU General Public License for more details. | |
// | |
// You should have received a copy of the GNU General Public License | |
// along with this program. If not, see <http://www.gnu.org/licenses/>. | |
// This preloads Dynasty Reader pages and indicates it with colours. | |
// Red means it's in the queue, but it hasn't preloaded it yet. | |
// Yellow means it's currently preloading. | |
// Green means it's preloaded. | |
// | |
// If you wish, you can also preload all pages by clicking on the "Load All" button | |
// to the right of the "Fullscreen" button. | |
// Change these variables if you wish. | |
// lookahead is the number of pages to load ahead of you. | |
// lookbehind | |
// max_concurrent is the maximum number of image requests at any one time. | |
// Turn this down if you get loading screens, even though the page has been preloaded. | |
const lookahead = 4; | |
const lookbehind = 2; | |
const max_concurrent = 5; | |
(function () { | |
"use strict"; | |
let queue = []; // page objects | |
let images = []; // stack/queue of Image objects to be used after they've been loaded | |
const states = { | |
default: -1, | |
queued: 0, | |
loading: 1, | |
loaded: 2 | |
}; | |
const state_classes = { | |
[states.default]: "", | |
[states.queued]: "queued", | |
[states.loading]: "loading", | |
[states.loaded]: "loaded" | |
}; | |
const state_list = Object.keys(states); | |
const css_text = ".queued{background:#ebccd1} .loading{background:#fcf8e3} .loaded{background:#dff0d8}"; | |
// initialise images with the image elements | |
// define the onload event so we don't have to define it later | |
// just set any Image.page then Image.src and then it'll be all good | |
function img_onload(event) { | |
const img = event.path[0]; | |
const page = img.page; | |
page.state = states.loaded; | |
images.push(img); | |
update_style(page); | |
check_queue(); | |
} | |
for (let i = 0; i < max_concurrent; i++) { | |
const cur_img = new Image(); | |
cur_img.onload = img_onload; | |
images.push(cur_img); | |
} | |
function update_style(page) { | |
if (page.state === page.styled_state) return; | |
const cl = page.element.classList; | |
if (page.styled_state !== states.default) { | |
cl.remove(state_classes[page.styled_state]); | |
} | |
cl.add(state_classes[page.state]); | |
page.styled_state = page.state; | |
} | |
// To load stuff, chuck it onto the queue and call this function | |
function check_queue() { | |
while (images.length > 0 && queue.length > 0) { | |
load(queue.shift()); | |
} | |
} | |
// Actually, to check stuff on the queue you should probably use this function | |
// You still need to call check_queue though. | |
function chuck_on_queue(page) { | |
if (page.state === states.loading || page.state === states.loaded) return; | |
page.state = states.queued; | |
queue.push(page); | |
update_style(page); | |
} | |
function load(page) { | |
if (page.state === states.loading || page.state === states.loaded) return; | |
const img = images.pop(); | |
page.state = states.loading; | |
update_style(page); | |
img.page = page; | |
img.src = page.image; | |
} | |
// loads `lookahead` pages after the current page and `lookbehind` before. | |
function load_lookahead() { | |
let cur_page; | |
switch (window.location.hash) { | |
case "#last": | |
cur_page = window.pages.length; | |
break; | |
case "": | |
cur_page = 1; | |
break; | |
default: | |
cur_page = parseInt(window.location.hash.substr(1)); | |
} | |
// clamp juust in case | |
cur_page = Math.min(window.pages.length, Math.max(1, cur_page)); | |
const cur_index = cur_page - 1; | |
// Always load lookahead before lookbehind | |
for (let i = cur_index; i <= cur_index + lookahead && i < window.pages.length; i++) { | |
chuck_on_queue(window.pages[i]); | |
} | |
for (let i = cur_index - 1; i >= cur_index - lookbehind && i >= 0; i--) { | |
chuck_on_queue(window.pages[i]); | |
} | |
check_queue(); | |
} | |
// loads all pages | |
function load_all() { | |
window.pages.forEach(chuck_on_queue); | |
check_queue(); | |
return false; | |
} | |
// inject the CSS we want | |
const css = document.createElement("style"); | |
css.innerHTML = css_text; | |
document.body.appendChild(css); | |
// precalculate all the DOM elements | |
const pages_list = document.getElementById("prev_link").parentElement; | |
for (let i = 0; i < window.pages.length; i++) { | |
window.pages[i].element = pages_list.children[i+1]; | |
window.pages[i].state = states.default; | |
window.pages[i].styled_state = states.default; | |
} | |
// create the "Load All" button | |
const load_button = document.createElement("a"); | |
load_button.className = "btn btn-mini"; | |
load_button.innerHTML = "Load All"; | |
load_button.href = "#"; | |
load_button.onclick = load_all; | |
document.getElementById("fullscreen").insertAdjacentElement("afterend", load_button); | |
// lookahead stuff | |
window.addEventListener("hashchange", load_lookahead); | |
load_lookahead(); | |
}()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment