FA Webcomic Auto Loader

Gives you the option to load all the subsequent comic pages on a FurAffinity comic page automatically. Even for pages without given Links

当前为 2025-02-03 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name        FA Webcomic Auto Loader
// @namespace   Violentmonkey Scripts
// @match       *://*.furaffinity.net/*
// @require     https://update.greasyfork.org/scripts/525666/1530872/Furaffinity-Prototype-Extensions.js
// @require     https://update.greasyfork.org/scripts/483952/1530883/Furaffinity-Request-Helper.js
// @require     https://update.greasyfork.org/scripts/485827/1530881/Furaffinity-Match-List.js
// @require     https://update.greasyfork.org/scripts/485153/1530882/Furaffinity-Loading-Animations.js
// @require     https://update.greasyfork.org/scripts/475041/1531083/Furaffinity-Custom-Settings.js
// @grant       GM_info
// @version     2.1.2
// @author      Midori Dragon
// @description Gives you the option to load all the subsequent comic pages on a FurAffinity comic page automatically. Even for pages without given Links
// @icon        https://www.furaffinity.net/themes/beta/img/banners/fa_logo.png
// @license     MIT
// ==/UserScript==
// jshint esversion: 8
(() => {
    "use strict";
    var LogLevel, __webpack_require__ = {
        d: (exports, definition) => {
            for (var key in definition) if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) Object.defineProperty(exports, key, {
                enumerable: true,
                get: definition[key]
            });
        },
        o: (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop)
    };
    __webpack_require__.d({}, {
        KS: () => backwardSearchSetting,
        _d: () => loadingSpinSpeedSetting,
        WE: () => overwriteNavButtonsSetting,
        uL: () => requestHelper,
        vD: () => scriptName,
        iT: () => useCustomLightboxSetting
    });
    function checkTags(element) {
        var _a;
        if (!("1" === document.body.getAttribute("data-user-logged-in"))) {
            setBlockedState(element, false);
            return;
        }
        const tagsHideMissingTags = "1" === document.body.getAttribute("data-tag-blocklist-hide-tagless"), tags = null === (_a = element.getAttribute("data-tags")) || void 0 === _a ? void 0 : _a.trim().split(/\s+/);
        let blockReason = "";
        if (null != tags && tags.length > 0 && "" !== tags[0]) {
            const blockedTags = function getBannedTags(tags) {
                var _a;
                const tagsBlocklist = null !== (_a = document.body.getAttribute("data-tag-blocklist")) && void 0 !== _a ? _a : [];
                let bTags = [];
                if (null == tags || 0 === tags.length) return [];
                for (const tag of tags) for (const blockedTag of tagsBlocklist) if (tag === blockedTag) bTags.push(blockedTag);
                return [ ...new Set(bTags) ];
            }(tags);
            if (blockedTags.length <= 0) setBlockedState(element, false); else {
                setBlockedState(element, true);
                blockReason = "Blocked tags:\n";
                for (const tag of blockedTags) blockReason += "• " + tag + "\n";
            }
        } else {
            setBlockedState(element, tagsHideMissingTags);
            if (tagsHideMissingTags) blockReason = "Content is missing tags.";
        }
        if ("" !== blockReason && "submissionImg" !== element.id) element.setAttribute("title", blockReason);
    }
    function setBlockedState(element, isBlocked) {
        element.classList[isBlocked ? "add" : "remove"]("blocked-content");
    }
    !function(LogLevel) {
        LogLevel[LogLevel.Error = 1] = "Error";
        LogLevel[LogLevel.Warning = 2] = "Warning";
        LogLevel[LogLevel.Info = 3] = "Info";
    }(LogLevel || (LogLevel = {}));
    class Logger {
        static log(logLevel = LogLevel.Warning, ...args) {
            if (null == window.__FF_GLOBAL_LOG_LEVEL__) window.__FF_GLOBAL_LOG_LEVEL__ = LogLevel.Error;
            if (!(logLevel > window.__FF_GLOBAL_LOG_LEVEL__)) switch (logLevel) {
              case LogLevel.Error:
                console.error(...args);
                break;

              case LogLevel.Warning:
                console.warn(...args);
                break;

              case LogLevel.Info:
                console.log(...args);
            }
        }
        static setLogLevel(logLevel) {
            window.__FF_GLOBAL_LOG_LEVEL__ = logLevel;
        }
        static logError(...args) {
            Logger.log(LogLevel.Error, ...args);
        }
        static logWarning(...args) {
            Logger.log(LogLevel.Warning, ...args);
        }
        static logInfo(...args) {
            Logger.log(LogLevel.Info, ...args);
        }
    }
    function getDocViewSid(doc) {
        let ogUrl = doc.querySelector('meta[property="og:url"]').getAttribute("content");
        if (null == ogUrl) return -1;
        ogUrl = ogUrl.trimEnd("/");
        return parseInt(ogUrl.split("/").pop());
    }
    const string = class {
        static isNullOrWhitespace(str) {
            return null == str || "" === str.trim();
        }
        static isNullOrEmpty(str) {
            return null == str || "" === str;
        }
    };
    class ComicNavigation {
        constructor(prevId, firstId, nextId) {
            this.prevId = -1;
            this.firstId = -1;
            this.nextId = -1;
            this.prevId = prevId;
            this.firstId = firstId;
            this.nextId = nextId;
        }
        static fromElement(elem) {
            var _a;
            const comicNav = new ComicNavigation(-1, -1, -1), navElems = elem.querySelectorAll('a[href*="view"]');
            if (null == navElems || 0 === navElems.length) return null;
            for (const navElem of Array.from(navElems)) {
                const navText = null === (_a = null == navElem ? void 0 : navElem.textContent) || void 0 === _a ? void 0 : _a.toLowerCase();
                if (string.isNullOrWhitespace(navText)) continue;
                let idText = navElem.getAttribute("href");
                if (!string.isNullOrWhitespace(idText)) {
                    idText = idText.trimEnd("/");
                    idText = idText.split("/").pop();
                    if (navText.includes("prev")) comicNav.prevId = parseInt(idText); else if (navText.includes("next")) comicNav.nextId = parseInt(idText); else if (navText.includes("start") || navText.includes("first")) comicNav.firstId = parseInt(idText);
                }
            }
            return comicNav;
        }
    }
    var __awaiter = function(thisArg, _arguments, P, generator) {
        return new (P || (P = Promise))((function(resolve, reject) {
            function fulfilled(value) {
                try {
                    step(generator.next(value));
                } catch (e) {
                    reject(e);
                }
            }
            function rejected(value) {
                try {
                    step(generator.throw(value));
                } catch (e) {
                    reject(e);
                }
            }
            function step(result) {
                result.done ? resolve(result.value) : function adopt(value) {
                    return value instanceof P ? value : new P((function(resolve) {
                        resolve(value);
                    }));
                }(result.value).then(fulfilled, rejected);
            }
            step((generator = generator.apply(thisArg, _arguments || [])).next());
        }));
    };
    class AutoLoaderSearch {
        constructor(rootImg, rootSid, comicNav) {
            this.currImgIndex = 1;
            this.currSid = -1;
            this.rootImg = rootImg;
            this.rootSid = rootSid;
            this.currComicNav = comicNav;
        }
        search() {
            return __awaiter(this, void 0, void 0, (function*() {
                var _a;
                const loadedImgs = {};
                loadedImgs[this.rootSid] = this.rootImg;
                Logger.logInfo(`${scriptName}: starting search...`);
                do {
                    try {
                        if (null == this.currComicNav) break;
                        const img = yield this.getPage(this.currComicNav.nextId);
                        if (null == img) break;
                        if (this.currSid in loadedImgs) break;
                        Logger.logInfo(`${scriptName}: found image with sid '${this.currSid}'`);
                        loadedImgs[this.currSid] = img;
                        this.currImgIndex++;
                    } catch (error) {
                        Logger.logError(error);
                        break;
                    }
                } while (-1 !== (null === (_a = this.currComicNav) || void 0 === _a ? void 0 : _a.nextId));
                Logger.logInfo(`${scriptName}: finished search. Found ${Object.keys(loadedImgs).length} images.`);
                return loadedImgs;
            }));
        }
        getPage(sid) {
            return __awaiter(this, void 0, void 0, (function*() {
                var _a;
                const page = yield requestHelper.SubmissionRequests.getSubmissionPage(sid), img = page.getElementById("submissionImg");
                img.setAttribute("wal-index", this.currImgIndex.toString());
                img.setAttribute("wal-sid", sid.toString());
                this.currSid = getDocViewSid(page);
                const descriptionElem = null === (_a = page.getElementById("columnpage")) || void 0 === _a ? void 0 : _a.querySelector('div[class*="submission-description"]');
                if (null != descriptionElem) this.currComicNav = ComicNavigation.fromElement(descriptionElem); else this.currComicNav = null;
                return img;
            }));
        }
    }
    function isSubmissionPageInGallery(doc) {
        const columnPage = doc.getElementById("columnpage"), favNav = null == columnPage ? void 0 : columnPage.querySelector('div[class*="favorite-nav"]'), mainGalleryButton = null == favNav ? void 0 : favNav.querySelector('a[title*="submissions"]');
        if (null != mainGalleryButton && mainGalleryButton.href.includes("gallery")) return true; else return false;
    }
    function isSubmissionPageInScraps(doc) {
        const columnPage = doc.getElementById("columnpage"), favNav = null == columnPage ? void 0 : columnPage.querySelector('div[class*="favorite-nav"]'), mainGalleryButton = null == favNav ? void 0 : favNav.querySelector('a[title*="submissions"]');
        if (null != mainGalleryButton && mainGalleryButton.href.includes("scraps")) return true; else return false;
    }
    function getCurrGalleryFolder() {
        const url = window.location.toString().toLowerCase();
        if (!url.includes("gallery") || !url.includes("folder")) return;
        const parts = url.split("/"), folderIdIndex = parts.indexOf("folder") + 1;
        if (folderIdIndex >= parts.length) return;
        const folderId = parts[folderIdIndex];
        return parseInt(folderId);
    }
    function generalizeString(inputString, textToNumbers, removeCommonPhrases, removeSpecialChars, removeNumbers, removeSpaces, removeRoman) {
        let outputString = inputString.toLowerCase();
        if (removeCommonPhrases) {
            const commonPhrases = [ "page", "part", "book", "episode" ];
            outputString = outputString.replace(new RegExp(`(?:^|\\s)(${commonPhrases.join("|")})(?:\\s|$)`, "g"), "");
        }
        if (removeRoman) {
            const roman = [ "i", "ii", "iii", "iv", "v", "vi", "vii", "viii", "ix", "x", "xi", "xii", "xiii", "xiv", "xv", "xvi", "xvii", "xviii", "xix", "xx" ];
            outputString = outputString.replace(new RegExp(`(?:^|[^a-zA-Z])(${roman.join("|")})(?:[^a-zA-Z]|$)`, "g"), "");
        }
        if (textToNumbers) {
            const numbers = {
                zero: 0,
                one: 1,
                two: 2,
                three: 3,
                four: 4,
                five: 5,
                six: 6,
                seven: 7,
                eight: 8,
                nine: 9,
                ten: 10,
                eleven: 11,
                twelve: 12,
                thirteen: 13,
                fourteen: 14,
                fifteen: 15,
                sixteen: 16,
                seventeen: 17,
                eighteen: 18,
                nineteen: 19,
                twenty: 20,
                thirty: 30,
                forty: 40,
                fifty: 50,
                sixty: 60,
                seventy: 70,
                eighty: 80,
                ninety: 90,
                hundred: 100
            };
            outputString = outputString.replace(new RegExp(Object.keys(numbers).join("|"), "gi"), (match => numbers[match.toLowerCase()].toString()));
        }
        if (removeSpecialChars) outputString = outputString.replace(/[^a-zA-Z0-9 ]/g, "");
        if (removeNumbers) outputString = outputString.replace(/[^a-zA-Z ]/g, "");
        if (removeSpaces) outputString = outputString.replace(/\s/g, "");
        return outputString;
    }
    function getDocUsername(doc) {
        const columnPage = doc.getElementById("columnpage"), submissionIdContainer = null == columnPage ? void 0 : columnPage.querySelector('div[class*="submission-id-container"]'), usernameContainer = null == submissionIdContainer ? void 0 : submissionIdContainer.querySelector('a[href*="user"]');
        if (null != usernameContainer) {
            let username = usernameContainer.href;
            username = username.trimEnd("/");
            username = username.split("/").pop();
            return username;
        }
    }
    var BackwardSearch_awaiter = function(thisArg, _arguments, P, generator) {
        return new (P || (P = Promise))((function(resolve, reject) {
            function fulfilled(value) {
                try {
                    step(generator.next(value));
                } catch (e) {
                    reject(e);
                }
            }
            function rejected(value) {
                try {
                    step(generator.throw(value));
                } catch (e) {
                    reject(e);
                }
            }
            function step(result) {
                result.done ? resolve(result.value) : function adopt(value) {
                    return value instanceof P ? value : new P((function(resolve) {
                        resolve(value);
                    }));
                }(result.value).then(fulfilled, rejected);
            }
            step((generator = generator.apply(thisArg, _arguments || [])).next());
        }));
    };
    class BackwardSearch {
        constructor(currSid, amount, currSubmissionPageNo) {
            this.sidToIgnore = [];
            this._currSid = currSid;
            this._amount = amount;
            this.currSubmissionPageNo = currSubmissionPageNo;
            this.sidToIgnore.push(currSid);
        }
        search() {
            return BackwardSearch_awaiter(this, void 0, void 0, (function*() {
                var _a, _b;
                const isInGallery = isSubmissionPageInGallery(document), isInScraps = isSubmissionPageInScraps(document);
                if (!isInGallery && !isInScraps) return {};
                const columnpage = document.getElementById("columnpage"), submissionIdContainer = null == columnpage ? void 0 : columnpage.querySelector('div[class*="submission-id-container"]'), submissionTitle = null == submissionIdContainer ? void 0 : submissionIdContainer.querySelector('div[class*="submission-title"]'), currTitle = null === (_b = null === (_a = null == submissionTitle ? void 0 : submissionTitle.querySelector("h2")) || void 0 === _a ? void 0 : _a.querySelector("p")) || void 0 === _b ? void 0 : _b.textContent;
                if (string.isNullOrWhitespace(currTitle)) return {};
                const currUsername = getDocUsername(document), folderId = getCurrGalleryFolder();
                Logger.logInfo(`${scriptName}: finding submission page...`);
                if (null == this.currSubmissionPageNo || this.currSubmissionPageNo < 1) if (isInGallery) this.currSubmissionPageNo = yield requestHelper.UserRequests.GalleryRequests.Gallery.getSubmissionPageNo(currUsername, this._currSid, folderId, -1, -1); else if (isInScraps) this.currSubmissionPageNo = yield requestHelper.UserRequests.GalleryRequests.Scraps.getSubmissionPageNo(currUsername, this._currSid, -1, -1);
                Logger.logInfo(`${scriptName}: found submission on page '${this.currSubmissionPageNo}'`);
                Logger.logInfo(`${scriptName}: searching figures backward...`);
                let figures = [];
                if (isInGallery) figures = yield requestHelper.UserRequests.GalleryRequests.Gallery.getFiguresInFolderBetweenPages(currUsername, folderId, this.currSubmissionPageNo, this.currSubmissionPageNo + this._amount); else if (isInScraps) figures = yield requestHelper.UserRequests.GalleryRequests.Scraps.getFiguresBetweenPages(currUsername, this.currSubmissionPageNo, this.currSubmissionPageNo + this._amount);
                let figuresFlattend = figures.flat();
                figuresFlattend = figuresFlattend.filter((figure => !this.sidToIgnore.includes(parseInt(figure.id.trimStart("sid-")))));
                figuresFlattend = figuresFlattend.filter((figure => this.figureTitleIsGenerallyEqual(figure, currTitle)));
                figuresFlattend.reverse();
                Logger.logInfo(`${scriptName}: searching figures backward found '${figuresFlattend.length}' figures`);
                Logger.logInfo(`${scriptName}: loading submission pages...`);
                const result = {};
                for (let i = 0; i < figuresFlattend.length; i++) {
                    const figureSid = figuresFlattend[i].id.trimStart("sid-"), subDoc = yield requestHelper.SubmissionRequests.getSubmissionPage(parseInt(figureSid)), img = null == subDoc ? void 0 : subDoc.getElementById("submissionImg");
                    if (null != img) {
                        img.setAttribute("wal-index", (-(figuresFlattend.length - i)).toString());
                        img.setAttribute("wal-sid", figureSid);
                        result[parseInt(figureSid)] = img;
                        Logger.logInfo(`${scriptName}: loaded submission '${figureSid}' with index '${(-(figuresFlattend.length - i)).toString()}'`);
                    }
                }
                return result;
            }));
        }
        figureTitleIsGenerallyEqual(figure, title) {
            const figCaption = figure.querySelector("figcaption"), titleElem = null == figCaption ? void 0 : figCaption.querySelector('a[href*="view"]');
            if (null != titleElem) {
                const figTitleGeneralized = generalizeString(titleElem.title.toLowerCase(), true, true, true, true, true, true), currTitleGeneralized = generalizeString(title, true, true, true, true, true, true);
                return figTitleGeneralized.includes(currTitleGeneralized) || currTitleGeneralized.includes(figTitleGeneralized);
            }
            return false;
        }
    }
    var ForwardSearch_awaiter = function(thisArg, _arguments, P, generator) {
        return new (P || (P = Promise))((function(resolve, reject) {
            function fulfilled(value) {
                try {
                    step(generator.next(value));
                } catch (e) {
                    reject(e);
                }
            }
            function rejected(value) {
                try {
                    step(generator.throw(value));
                } catch (e) {
                    reject(e);
                }
            }
            function step(result) {
                result.done ? resolve(result.value) : function adopt(value) {
                    return value instanceof P ? value : new P((function(resolve) {
                        resolve(value);
                    }));
                }(result.value).then(fulfilled, rejected);
            }
            step((generator = generator.apply(thisArg, _arguments || [])).next());
        }));
    };
    class ForwardSearch {
        constructor(currSid, currSubmissionPageNo) {
            this.sidToIgnore = [];
            this._currSid = currSid;
            this.currSubmissionPageNo = currSubmissionPageNo;
            this.sidToIgnore.push(currSid);
        }
        search() {
            return ForwardSearch_awaiter(this, void 0, void 0, (function*() {
                var _a, _b;
                const isInGallery = isSubmissionPageInGallery(document), isInScraps = isSubmissionPageInScraps(document);
                if (!isInGallery && !isInScraps) return {};
                const columnpage = document.getElementById("columnpage"), submissionIdContainer = null == columnpage ? void 0 : columnpage.querySelector('div[class*="submission-id-container"]'), submissionTitle = null == submissionIdContainer ? void 0 : submissionIdContainer.querySelector('div[class*="submission-title"]'), currTitle = null === (_b = null === (_a = null == submissionTitle ? void 0 : submissionTitle.querySelector("h2")) || void 0 === _a ? void 0 : _a.querySelector("p")) || void 0 === _b ? void 0 : _b.textContent;
                if (string.isNullOrWhitespace(currTitle)) return {};
                const currUsername = getDocUsername(document), folderId = getCurrGalleryFolder();
                Logger.logInfo(`${scriptName}: finding submission page...`);
                if (null == this.currSubmissionPageNo || this.currSubmissionPageNo < 1) if (isInGallery) this.currSubmissionPageNo = yield requestHelper.UserRequests.GalleryRequests.Gallery.getSubmissionPageNo(currUsername, this._currSid, folderId, -1, -1); else if (isInScraps) this.currSubmissionPageNo = yield requestHelper.UserRequests.GalleryRequests.Scraps.getSubmissionPageNo(currUsername, this._currSid, -1, -1);
                Logger.logInfo(`${scriptName}: found submission on page '${this.currSubmissionPageNo}'`);
                Logger.logInfo(`${scriptName}: searching figures forward...`);
                let figures = [];
                if (isInGallery) figures = yield requestHelper.UserRequests.GalleryRequests.Gallery.getFiguresInFolderBetweenIds(currUsername, folderId, void 0, this._currSid); else if (isInScraps) figures = yield requestHelper.UserRequests.GalleryRequests.Scraps.getFiguresBetweenIds(currUsername, void 0, this._currSid);
                let figuresFlattend = figures.flat();
                figuresFlattend = figuresFlattend.filter((figure => !this.sidToIgnore.includes(parseInt(figure.id.trimStart("sid-")))));
                figuresFlattend = figuresFlattend.filter((figure => this.figureTitleIsGenerallyEqual(figure, currTitle)));
                figuresFlattend.reverse();
                Logger.logInfo(`${scriptName}: searching figures forward found '${figuresFlattend.length}' figures`);
                Logger.logInfo(`${scriptName}: loading submission pages...`);
                const result = {};
                for (let i = 0; i < figuresFlattend.length; i++) {
                    const figureSid = figuresFlattend[i].id.trimStart("sid-"), subDoc = yield requestHelper.SubmissionRequests.getSubmissionPage(parseInt(figureSid)), img = null == subDoc ? void 0 : subDoc.getElementById("submissionImg");
                    if (null != img) {
                        img.setAttribute("wal-index", (i + 1).toString());
                        img.setAttribute("wal-sid", figureSid);
                        result[parseInt(figureSid)] = img;
                        Logger.logInfo(`${scriptName}: loaded submission '${figureSid}' with index '${(i + 1).toString()}'`);
                    }
                }
                return result;
            }));
        }
        figureTitleIsGenerallyEqual(figure, title) {
            const figCaption = figure.querySelector("figcaption"), titleElem = null == figCaption ? void 0 : figCaption.querySelector('a[href*="view"]');
            if (null != titleElem) {
                const figTitleGeneralized = generalizeString(titleElem.title.toLowerCase(), true, true, true, true, true, true), currTitleGeneralized = generalizeString(title, true, true, true, true, true, true);
                return figTitleGeneralized.includes(currTitleGeneralized) || currTitleGeneralized.includes(figTitleGeneralized);
            }
            return false;
        }
    }
    class Lightbox {
        constructor(orgSid, imgs) {
            this.currWalIndex = 0;
            this._imgCount = -1;
            this._lightboxContainer = document.body.querySelector('div[class*="lightbox-submission"]');
            this._lightboxContainer.innerHTML = "";
            this._lightboxContainer = this._lightboxContainer.readdToDom();
            this._lightboxContainer.addEventListener("click", (() => {
                this.isHidden = true;
            }));
            this._imgCount = Object.keys(imgs).length;
            const orgImgClone = document.getElementById("columnpage").querySelector(`img[wal-sid="${orgSid}"]`).readdToDom();
            imgs[orgSid] = orgImgClone;
            const sortedImages = Object.values(imgs).sort(((a, b) => {
                var _a, _b;
                return parseInt(null !== (_a = a.getAttribute("wal-index")) && void 0 !== _a ? _a : "0") - parseInt(null !== (_b = b.getAttribute("wal-index")) && void 0 !== _b ? _b : "0");
            }));
            for (const img of sortedImages) {
                img.addEventListener("click", (() => {
                    var _a;
                    this.currWalIndex = null !== (_a = this.getIndexOfClickedImage(img)) && void 0 !== _a ? _a : 0;
                    this.isHidden = false;
                }));
                const clone = img.cloneNode(false);
                clone.classList.add("hidden");
                this._lightboxContainer.appendChild(clone);
            }
            this._boundHandleArrowKeys = this.handleArrowKeys.bind(this);
        }
        get isHidden() {
            return this._lightboxContainer.classList.contains("hidden");
        }
        set isHidden(value) {
            var _a;
            if (this.isHidden !== value) if (value) {
                window.removeEventListener("keydown", this._boundHandleArrowKeys);
                this._lightboxContainer.classList.add("hidden");
                for (const child of Array.from(this._lightboxContainer.children)) child.classList.add("hidden");
            } else {
                window.addEventListener("keydown", this._boundHandleArrowKeys);
                null === (_a = this._lightboxContainer.children[this.currWalIndex]) || void 0 === _a || _a.classList.remove("hidden");
                this._lightboxContainer.classList.remove("hidden");
            }
        }
        navigateLeft() {
            if (this.currWalIndex > 0) {
                const currImg = this._lightboxContainer.children[this.currWalIndex], prevImg = this._lightboxContainer.children[this.currWalIndex - 1];
                if (null != currImg && null != prevImg) {
                    currImg.classList.add("hidden");
                    prevImg.classList.remove("hidden");
                }
                this.currWalIndex--;
            }
        }
        navigateRight() {
            if (this.currWalIndex < this._imgCount) {
                const currImg = this._lightboxContainer.children[this.currWalIndex], nextImg = this._lightboxContainer.children[this.currWalIndex + 1];
                if (null != currImg && null != nextImg) {
                    currImg.classList.add("hidden");
                    nextImg.classList.remove("hidden");
                }
                this.currWalIndex++;
            }
        }
        handleArrowKeys(event) {
            switch (event.key) {
              case "ArrowLeft":
              case "ArrowUp":
                this.navigateLeft();
                break;

              case "ArrowRight":
              case "ArrowDown":
                this.navigateRight();
            }
            event.preventDefault();
        }
        getIndexOfClickedImage(img) {
            let clickedWalIndex = img.getAttribute("wal-index");
            if (!string.isNullOrWhitespace(clickedWalIndex)) {
                this.currWalIndex = parseInt(clickedWalIndex);
                const clickedImg = this._lightboxContainer.querySelector(`img[wal-index="${this.currWalIndex}"]`);
                return null == clickedImg ? void 0 : clickedImg.getIndexOfThis();
            }
        }
    }
    var AutoLoader_awaiter = function(thisArg, _arguments, P, generator) {
        return new (P || (P = Promise))((function(resolve, reject) {
            function fulfilled(value) {
                try {
                    step(generator.next(value));
                } catch (e) {
                    reject(e);
                }
            }
            function rejected(value) {
                try {
                    step(generator.throw(value));
                } catch (e) {
                    reject(e);
                }
            }
            function step(result) {
                result.done ? resolve(result.value) : function adopt(value) {
                    return value instanceof P ? value : new P((function(resolve) {
                        resolve(value);
                    }));
                }(result.value).then(fulfilled, rejected);
            }
            step((generator = generator.apply(thisArg, _arguments || [])).next());
        }));
    };
    class AutoLoader {
        constructor() {
            var _a;
            this.currComicNav = null;
            this.comicNavExists = false;
            this.currSid = -1;
            const descriptionElem = null === (_a = document.getElementById("columnpage")) || void 0 === _a ? void 0 : _a.querySelector('div[class*="submission-description"]');
            if (null != descriptionElem) {
                this.currComicNav = ComicNavigation.fromElement(descriptionElem);
                if (null != this.currComicNav) if (-1 !== this.currComicNav.prevId || -1 !== this.currComicNav.firstId || -1 !== this.currComicNav.nextId) {
                    this.comicNavExists = true;
                    if (overwriteNavButtonsSetting.value) this.overwriteNavButtons();
                }
            }
            this.currSid = getDocViewSid(document);
            this.submissionImg = document.getElementById("submissionImg");
            this.submissionImg.setAttribute("wal-index", "0");
            this.submissionImg.setAttribute("wal-sid", this.currSid.toString());
            const searchButton = document.createElement("a");
            searchButton.id = this.comicNavExists ? "wal-auto-load-button" : "wal-search-button";
            searchButton.classList.add("wal-button", "button", "standard", "mobile-fix");
            searchButton.type = "button";
            searchButton.style.margin = "20px 0 10px 0";
            searchButton.textContent = this.comicNavExists ? "Auto load Pages" : "Search for similar Pages";
            searchButton.addEventListener("click", (() => {
                if (this.comicNavExists) this.startAutoloader(); else this.startSimilarSearch();
                searchButton.remove();
            }));
            this.submissionImg.parentNode.appendChild(document.createElement("br"));
            this.submissionImg.parentNode.appendChild(searchButton);
            const loadingSpinnerContainer = document.createElement("div");
            loadingSpinnerContainer.classList.add("wal-loading-spinner");
            loadingSpinnerContainer.style.margin = "20px 0 20px 0";
            this._loadingSpinner = new window.FALoadingSpinner(loadingSpinnerContainer);
            this._loadingSpinner.delay = loadingSpinSpeedSetting.value;
            this._loadingSpinner.spinnerThickness = 6;
            this.submissionImg.parentNode.appendChild(loadingSpinnerContainer);
        }
        startAutoloader() {
            this.startAutoLoaderAsync();
        }
        startAutoLoaderAsync() {
            return AutoLoader_awaiter(this, void 0, void 0, (function*() {
                this._loadingSpinner.visible = true;
                const autoLoader = new AutoLoaderSearch(this.submissionImg, this.currSid, this.currComicNav), submissions = yield autoLoader.search();
                this.addLoadedSubmissions(submissions);
                if (useCustomLightboxSetting.value) new Lightbox(this.currSid, submissions);
                this._loadingSpinner.visible = false;
            }));
        }
        startSimilarSearch() {
            this.startSimilarSearchAsync();
        }
        startSimilarSearchAsync() {
            return AutoLoader_awaiter(this, void 0, void 0, (function*() {
                this._loadingSpinner.visible = true;
                const forwardSearch = new ForwardSearch(this.currSid), submissionsAfter = yield forwardSearch.search(), backwardSearch = new BackwardSearch(this.currSid, backwardSearchSetting.value, forwardSearch.currSubmissionPageNo);
                backwardSearch.sidToIgnore.push(...Object.keys(submissionsAfter).map(Number));
                const submissionsBefore = yield backwardSearch.search();
                this.addLoadedSubmissions(submissionsBefore, submissionsAfter);
                if (useCustomLightboxSetting.value) new Lightbox(this.currSid, Object.assign(Object.assign({}, submissionsBefore), submissionsAfter));
                this._loadingSpinner.visible = false;
            }));
        }
        addLoadedSubmissions(...imgsArr) {
            const columnpage = document.getElementById("columnpage");
            for (const imgs of imgsArr) {
                Logger.logInfo(`${scriptName}: adding '${Object.keys(imgs).length}' submissions...`);
                let prevSid = this.currSid;
                for (const sid of Object.keys(imgs).map(Number)) {
                    if (imgs[sid].getAttribute("wal-sid") === this.currSid.toString()) continue;
                    const lastImg = columnpage.querySelector(`img[wal-sid="${prevSid}"]`), lastIndex = parseInt(lastImg.getAttribute("wal-index"));
                    if (parseInt(imgs[sid].getAttribute("wal-index")) < lastIndex) {
                        lastImg.insertBeforeThis(imgs[sid]);
                        imgs[sid].insertAfterThis(document.createElement("br"));
                        imgs[sid].insertAfterThis(document.createElement("br"));
                        checkTags(imgs[sid]);
                        Logger.logInfo(`${scriptName}: added submission ${sid} before submission ${prevSid}`);
                    } else {
                        lastImg.insertAfterThis(imgs[sid]);
                        imgs[sid].insertBeforeThis(document.createElement("br"));
                        imgs[sid].insertBeforeThis(document.createElement("br"));
                        checkTags(imgs[sid]);
                        Logger.logInfo(`${scriptName}: added submission ${sid} after submission ${prevSid}`);
                    }
                    prevSid = sid;
                }
            }
        }
        overwriteNavButtons() {
            var _a, _b, _c, _d, _e, _f;
            if (!this.comicNavExists) return;
            const columnpage = document.getElementById("columnpage"), favoriteNav = null == columnpage ? void 0 : columnpage.querySelector('div[class*="favorite-nav"]');
            let prevButton = null == favoriteNav ? void 0 : favoriteNav.children[0];
            if (null != prevButton && -1 !== this.currComicNav.prevId) if (null !== (_c = null === (_b = null === (_a = prevButton.textContent) || void 0 === _a ? void 0 : _a.toLowerCase()) || void 0 === _b ? void 0 : _b.includes("prev")) && void 0 !== _c ? _c : false) prevButton.href = `/view/${this.currComicNav.prevId}/`; else {
                const prevButtonReal = document.createElement("a");
                prevButtonReal.href = `/view/${this.currComicNav.prevId}/`;
                prevButtonReal.classList.add("button", "standard", "mobile-fix");
                prevButtonReal.textContent = "Prev";
                prevButtonReal.style.marginRight = "4px";
                prevButton.insertBeforeThis(prevButtonReal);
            }
            let nextButton = null == favoriteNav ? void 0 : favoriteNav.children[favoriteNav.children.length - 1];
            if (null != nextButton && -1 !== this.currComicNav.nextId) if (null !== (_f = null === (_e = null === (_d = nextButton.textContent) || void 0 === _d ? void 0 : _d.toLowerCase()) || void 0 === _e ? void 0 : _e.includes("next")) && void 0 !== _f ? _f : false) nextButton.href = `/view/${this.currComicNav.nextId}/`; else {
                const nextButtonReal = document.createElement("a");
                nextButtonReal.href = `/view/${this.currComicNav.nextId}/`;
                nextButtonReal.classList.add("button", "standard", "mobile-fix");
                nextButtonReal.textContent = "Next";
                nextButtonReal.style.marginLeft = "4px";
                nextButton.insertAfterThis(nextButtonReal);
            }
        }
    }
    const scriptName = "FA Webcomic Auto Loader", customSettings = new window.FACustomSettings("Midori's Script Settings", `${scriptName} Settings`), showSearchButtonSetting = customSettings.newSetting(window.FASettingType.Boolean, "Similar Search Button");
    showSearchButtonSetting.description = "Sets wether the search for similar Pages button is show.";
    showSearchButtonSetting.defaultValue = true;
    const loadingSpinSpeedSetting = customSettings.newSetting(window.FASettingType.Number, "Loading Animation");
    loadingSpinSpeedSetting.description = "Sets the duration that the loading animation takes for a full rotation in milliseconds.";
    loadingSpinSpeedSetting.defaultValue = 1e3;
    const backwardSearchSetting = customSettings.newSetting(window.FASettingType.Number, "Backward Search Amount");
    backwardSearchSetting.description = "Sets the amount of similar pages to search backward. (More Pages take longer)";
    backwardSearchSetting.defaultValue = 3;
    const overwriteNavButtonsSetting = customSettings.newSetting(window.FASettingType.Boolean, "Overwrite Nav Buttons");
    overwriteNavButtonsSetting.description = "Sets wether the default Navigation Buttons (next/prev) are overwritten by the Auto-Loader. (Works only if comic navigation is present)";
    overwriteNavButtonsSetting.defaultValue = true;
    const useCustomLightboxSetting = customSettings.newSetting(window.FASettingType.Boolean, "Use Custom Lightbox");
    useCustomLightboxSetting.description = "Sets wether the default Lightbox (fullscreen view) is overwritten by the Auto-Loader.";
    useCustomLightboxSetting.defaultValue = true;
    customSettings.loadSettings();
    const requestHelper = new window.FARequestHelper(2);
    if (customSettings.isFeatureEnabled) {
        const matchList = new window.FAMatchList(customSettings);
        matchList.matches = [ "net/view" ];
        matchList.runInIFrame = false;
        if (matchList.hasMatch) new AutoLoader;
    }
})();