Greasy Fork

Mangadex Plus

Adds a few useful features to Mangadex

目前为 2020-10-03 提交的版本。查看 最新版本

// ==UserScript==
// @name         Mangadex Plus
// @namespace    https://greasyfork.org/users/553660
// @icon         https://mangadex.org/images/misc/navbar.svg
// @version      1.0
// @description  Adds a few useful features to Mangadex
// @author       Mr. M
// @match        https://mangadex.org/*
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_listValues
// @grant        GM_deleteValue
// ==/UserScript==

(function() {
    'use strict';

    /* TODO

    - Show managa cover on hover

    */

    /*
        Global values
    */

    var domain = [
        "mangadex.org"
    ]
    var url = window.location;
    var nVer = "1.0";

    /*
        Global functions
    */

    // Get the domain from the visiting website
    function url_domain(data) {
        var a = document.createElement('a');
        a.href = data;
        return a.hostname;
    }

    // Add a global CSS style by inputting a String
    function addGlobalStyle(css) {
        var head, style;
        head = document.getElementsByTagName('head')[0];
        if (!head) { return; }
        style = document.createElement('style');
        style.type = 'text/css';
        style.innerHTML = css;
        head.appendChild(style);
    }

    // Get site subpage name/directory from provided url
    function getSubPage(directoryIndex){
        let url = document.location.href;
        var segment = url.replace(/^https?:\/\//, '').split('/')[directoryIndex];
        return segment;
    }
    
    // Get current Url
    function currentUrl(){
        return document.location.href;
    }

    /*
        Storage defaults
    */

    let first_time;

    if (GM_getValue("first_time") != "false"){
        first_time = false;
        GM_setValue("first_time", "false");
        //GM_setValue("folders_index", 0);
        let folders = {"folders" : []};
        GM_setValue("folders", JSON.stringify(folders));
        let options = {"options" : [{"preloading" : 0}]};
        GM_setValue("options", JSON.stringify(options));
        GM_setValue("update_notif", "true");
        alert("Thank you for installing Mangadex Plus! Go to Settings -> About to learn more about Mangadex Plus!")
    }

    // Version check (last version / newest version)
    
    if (GM_getValue("version") != nVer && first_time == undefined){
        GM_setValue("version", nVer);
        GM_setValue("update_notif", "true")
        alert("A feature update is here! MD+ has been updated to " + GM_getValue("version") + "! Check Change Log in MD+ Settings for more info!");
    }

    var red_badge;
    if (GM_getValue("update_notif") == "true"){
        GM_setValue("notif_badge", '<span class="badge badge-danger"> ! </span>')
    }
    else{
        GM_setValue("notif_badge", '')
    }

    /*
        Site functions
    */

    // Startup functions
    function startup(){

        if (getSubPage(1) == "title"){
            main("title");
        }
        else if (getSubPage(1) == "chapter"){
            main("chapter")
        }
        else{
            main("other");
        }

    }

    /*
        HTML Elements
    */

    // Color categorizing CSS classes -> "badge" || "text" + "-" + "success"/"danger"/"primary"/nothing
    //let friends_icon = '<span class="fas fa-user-friends fa-fw text-success" aria-hidden="true"></span>';

    //red_badge = '<span class="badge badge-danger"> ! </span>';
    //let green_badge = '<span class="badge badge-success"> ! </span>';

    //let msg_icon = '<span class="fas fa-envelope fa-fw text-danger" aria-hidden="true"></span>';

    let container = document.getElementsByTagName("body")[0];

    let pageMask = '<div id="page-mask"></div>';

    let closeButton = '<span aria-hidden="true" class="fas fa-times fa-fw plus-clsBtn"> To Exit click anywhere or press <i>Esc</i>.</span>';

    /*
        Functions and features
    */

    function main(level){

        let menuButton = '<li id="menuButton" class="nav-item dropdown mx-1 btn btn-secondary">' +
            '<a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="true"><span class="fas fa-plus-circle fa-fw " aria-hidden="true"></span>' +
            ' MD Plus ' + GM_getValue("notif_badge") +'</a>' +
            '<div class="dropdown-menu">' +
            '<p class="dropdown-item plus-folders"><span class="fas fa-folder fa-fw " aria-hidden="true"></span> Folders</p>' +
            '<p class="dropdown-item plus-options"><span class="fas fa-list fa-fw " aria-hidden="true"></span> Options</p>' +
            '<p class="dropdown-item plus-settings"><span class="fas fa-cog fa-fw " aria-hidden="true"></span> Settings ' + GM_getValue("notif_badge") + '</p>' +
            '</div>' +
            '</li>';

        if (level == "title" || (level == "chapter" || level == "other")){
            function mainButton(){

                container.insertAdjacentHTML("afterbegin", menuButton);
                addGlobalStyle("#menuButton { position: fixed; z-index: 99999; top: 10px; right: 15px; list-style-type: none; border-radius: 0.25rem; padding: unset;}");
                addGlobalStyle("p.dropdown-item { margin: 0px; }");

                folders();
                settings();
                options();
            }
            mainButton();
        }

        if (level == "title"){
            function cardButtons(){
            }
            cardButtons();
            actionsBar();
        }

        if (level == "chapter"){
            function readerFeatures(){
                preload();
            }
            readerFeatures();
        }

    }

    function closeMenu(){
        try{
            document.getElementsByClassName("plus-box")[0].remove();
            document.getElementById("page-mask").remove();
            document.getElementsByClassName("plus-clsBtn")[0].remove();
        }
        catch(e){
            //Nothing
        }
        try{
            document.getElementsByClassName("plus-options-window")[0].remove();
            document.getElementById("page-mask").remove();
            document.getElementsByClassName("plus-clsBtn")[0].remove();
        }
        catch(e){
            //Nothing
        }
    }

    function settings(){

        let notes = "(*) This will restore default values for options.</br>" +
            "(**) This will wipe all Storage data (Folders and entries).</br>" +
            "(***) This will restore default values for options and wipe storage (Folders and entries)."

        let items = '<div x-placement="bottom-start" style="left: 0px !important;' +
            'right: 0px !important;' +
            'width: 800px !important;' +
            'margin-left: auto;' +
            'margin-right: auto;' +
            'margin-top: 100px;' +
            'margin-bottom: auto;" class="dropdown-menu show plus-box">' +
            '<div class="modal-header" style="padding-right: 1rem; padding-bottom: 0.5rem; padding-left: 1rem; padding-top: 0rem;">' +
            '<h5 class="modal-title" id="homepage_settings_label" style="color: rgb(204, 204, 204) !important;">' +
            '<span class="fas fa-cog fa-fw " aria-hidden="true"></span> Mangadex Plus Settings</h5>' +
            '<button type="button" class="close plus-close" data-dismiss="modal" aria-label="Close">' +
            '<span aria-hidden="true">×</span></button></div>' +
            '<p class="dropdown-item plus-about" >' +
            '<span class="fas fa-info fa-fw " aria-hidden="true" ></span> About ' + GM_getValue("notif_badge") + '</p>' +
            '<p class="dropdown-item plus-change-log" >' +
            '<span class="fas fa-code fa-fw " aria-hidden="true" ></span> Change Log</p>' +
            '<p class="dropdown-item plus-reset" style="color: #f90 !important;">' +
            '<span class="fas fa-undo fa-fw " aria-hidden="true" style="color: #f90 !important;"></span> Reset Defaults (*)</p>' +
            '<p class="dropdown-item plus-wipe" style="color: #f90 !important;">' +
            '<span class="fas fa-trash fa-fw " aria-hidden="true" style="color: #f90 !important;"></span> Wipe Storage (**)</p>' +
            '<p class="dropdown-item plus-reset-wipe" style="color: #f00 !important;">' +
            '<span class="fas fa-exclamation-triangle fa-fw " aria-hidden="true" style="color: #f00 !important;"></span> Reset & Wipe Mangadex Plus (***)</p>' +
            '<div class="modal-footer"><p style="margin-bottom: 0px;color: rgb(204,204,204);">' + notes + '</p></div>'
        '</div>';

        function openSettingsMenu(){
            container.insertAdjacentHTML("afterbegin", items);
            addGlobalStyle("div.plus-box { position: fixed !important; right: 700px !important; left: 700px !important; top: 100px !important; z-index: 100001;}");

            container.insertAdjacentHTML("afterbegin", pageMask);
            addGlobalStyle("#page-mask { background: rgba(0, 0, 0, 0.5); position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 100000;}");

            container.insertAdjacentHTML("afterbegin", closeButton);
            addGlobalStyle(".plus-clsBtn { right: 150px !important; position: fixed !important; z-index: 100000; width: auto; color: white; background-color: #444;}");

            document.getElementById("page-mask").addEventListener("click", closeMenu);
            document.getElementsByClassName("plus-clsBtn")[0].addEventListener("click", closeMenu);
            document.getElementsByClassName("plus-reset-wipe")[0].addEventListener("click", function(){resetMDP("rw")});
            document.getElementsByClassName("plus-reset")[0].addEventListener("click", function(){resetMDP("r")});
            document.getElementsByClassName("plus-wipe")[0].addEventListener("click", function(){resetMDP("w")});
            document.getElementsByClassName("plus-change-log")[0].addEventListener("click", changeLog);
            document.getElementsByClassName("plus-about")[0].addEventListener("click", about);
            document.getElementsByClassName("plus-close")[0].addEventListener("click", closeMenu);
        }

        function about(){

            GM_setValue("update_notif", "false");
            GM_setValue("notif_badge", "")

            let text = "Welcome to Mangadex Plus!<br><br>" +
                "<b>\"What is Mangadex Plus?\"</b><br>Mangadex Plus is a Userscript that adds some useful features to Mangadex.<br><br>" +
                "<b>\"What are these Useful features you speak of?\"</b><br>These currently include:</p>" +
                "<ul><li>Custom folders</li><li>Marking all chapters of a Manga as read/unread</li><li>Start reading button</li>" +
                "<li>Automatic Chapter Preloading</li></ul>" +
                "<p>For more info on the features head to the <b>Change Log</b>. As of now these are all but more features will be added through time.<br><br>" +
                "<b>\"I really want a feature to be added to this script! Do you take suggestions?\"</b><br>I do so Welcomely. Please go to the GreasyFork page of this Userscript and add a suggestion there.<br><br>" +
                "<b>\"Hey! I found a bug! Where can I report It?\"</b><br> Please report bugs on the GreasyFork page of this Userscript and I'll do my best to fix them ASAP.<br><br>" +
                '</p><p style="color: gray"> To remove the red badge (<span class="badge badge-danger"> ! </span>) please reload the page.';

            let element = '<div x-placement="bottom-start" style="left: 0px !important;' +
                'right: 0px !important;' +
                'width: 800px !important;' +
                'margin-left: auto;' +
                'margin-right: auto;' +
                'margin-top: 100px;' +
                'margin-bottom: auto;" class="dropdown-menu show plus-box">' +
                '<div class="modal-header" style="padding-right: 1rem; padding-bottom: 0.5rem; padding-left: 1rem; padding-top: 0rem;">' +
                '<h5 class="modal-title" id="homepage_settings_label" style="color: rgb(204, 204, 204) !important;">' +
                '<span class="fas fa-info fa-fw " aria-hidden="true"></span> About</h5>' +
                '<button type="button" class="close plus-close" data-dismiss="modal" aria-label="Close">' +
                '<span aria-hidden="true">×</span></button></div>' +
                '<div class="" style="overflow-y: scroll; overflow-x: break-word; max-height: 400px; word-wrap: break-word; color: rgb(204,204,204); padding: 1rem;"><p>' + text + '</p></div>' +
                '<div class="modal-footer">' +
                '<a class="btn btn-secondary mx-auto plus-back-settings" style="display: block;width: max-content; color: rgb(204,204,204)">' +
                '<span class="fas fa-arrow-left fa-fw " aria-hidden="true"></span> Back to Settings</div>' +
                '</div>';

            closeMenu();

            container.insertAdjacentHTML("afterbegin", element);
            addGlobalStyle("div.plus-box { position: fixed !important; right: 700px !important; left: 700px !important; top: 100px !important; z-index: 100001;}");

            container.insertAdjacentHTML("afterbegin", pageMask);
            addGlobalStyle("#page-mask { background: rgba(0, 0, 0, 0.5); position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 100000;}");

            container.insertAdjacentHTML("afterbegin", closeButton);
            addGlobalStyle(".plus-clsBtn { right: 150px !important; position: fixed !important; z-index: 100000; width: auto; color: white; background-color: #444;}");

            document.getElementsByClassName("plus-back-settings")[0].addEventListener("click", function(){closeMenu(); settings(); openSettingsMenu();});
            document.getElementById("page-mask").addEventListener("click", closeMenu);
            document.getElementsByClassName("plus-clsBtn")[0].addEventListener("click", closeMenu);
            document.getElementsByClassName("plus-close")[0].addEventListener("click", closeMenu);
        }

        function changeLog(){


            let text = "Mangadex Plus version 1.0 is here!<br><br>" +
                "The very first version brings these features to the table:</p>" +
                "<ul><li><b>Custom folders:</b> You can make folders and add your chosen titles to It.</li><li><b>Mark all chapters of a Manga as read/unread:</b> " +
                "Saves you the trouble of having to mark all chapters individually.</li><li><b>Start reading button:</b> Goes to the first chapter of a Manga without having to scroll or switch pages.</li>" +
                "<li><b>Automatic Chapter Preloading:</b> Whenever you are in the reader (and are logged into your MD Account) the chapter will automatically start preloading. " +
                "You can turn this feature on/off in th Options Menu.</li></ul><p>" +
                "I am planning on improving the current features and adding new ones. If you have a suggestion/bug report please let me know on the Userscript's GreasyFork page forum.";

            let element = '<div x-placement="bottom-start" style="left: 0px !important;' +
                'right: 0px !important;' +
                'width: 800px !important;' +
                'margin-left: auto;' +
                'margin-right: auto;' +
                'margin-top: 100px;' +
                'margin-bottom: auto;" class="dropdown-menu show plus-box">' +
                '<div class="modal-header" style="padding-right: 1rem; padding-bottom: 0.5rem; padding-left: 1rem; padding-top: 0rem;">' +
                '<h5 class="modal-title" id="homepage_settings_label" style="color: rgb(204, 204, 204) !important;">' +
                '<span class="fas fa-code fa-fw " aria-hidden="true"></span> Change Log</h5>' +
                '<button type="button" class="close plus-close" data-dismiss="modal" aria-label="Close">' +
                '<span aria-hidden="true">×</span></button></div>' +
                '<div class="" style="overflow-y: scroll; max-height: 400px; word-wrap: break-word; color: rgb(204,204,204); padding: 1rem;"><p>' + text + '</p></div>' +
                '<div class="modal-footer">' +
                '<a class="btn btn-secondary mx-auto plus-back-settings" style="display: block;width: max-content; color: rgb(204,204,204)">' +
                '<span class="fas fa-arrow-left fa-fw " aria-hidden="true"></span> Back to Settings</div>' +
                '</div>';

            closeMenu();

            container.insertAdjacentHTML("afterbegin", element);
            addGlobalStyle("div.plus-box { position: fixed !important; right: 700px !important; left: 700px !important; top: 100px !important; z-index: 100001;}");

            container.insertAdjacentHTML("afterbegin", pageMask);
            addGlobalStyle("#page-mask { background: rgba(0, 0, 0, 0.5); position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 100000;}");

            container.insertAdjacentHTML("afterbegin", closeButton);
            addGlobalStyle(".plus-clsBtn { right: 150px !important; position: fixed !important; z-index: 100000; width: auto; color: white; background-color: #444;}");

            document.getElementsByClassName("plus-back-settings")[0].addEventListener("click", function(){closeMenu(); openSettingsMenu();});
            document.getElementById("page-mask").addEventListener("click", closeMenu);
            document.getElementsByClassName("plus-clsBtn")[0].addEventListener("click", closeMenu);
            document.getElementsByClassName("plus-close")[0].addEventListener("click", closeMenu);
        }

        function resetMDP(level){

            function prompt(level){

                let text_rw = "WARNING: By confirming this you will DELETE ALL Your Mangadex Plus saved data! This includes options and folders! \nAre you sure you want to proceed?";
                let text_r = "WARNING: By confirming this you will RESET ALL Your Mangadex Plus options to Default values! \nAre you sure you want to proceed?";
                let text_w = "WARNING: By confirming this you will WIPE ALL Your Mangadex Plus folders and It's Entries! \nAre you sure you want to proceed?";

                if (level == "rw"){
                    if (confirm(text_rw)) {
                        resets("rw");
                    }
                }
                else if (level == "r"){
                    if (confirm(text_r)) {
                        resets("r");
                    }
                }
                else if (level == "w"){
                    if (confirm(text_w)) {
                        resets("w");
                    }
                }

            }
            prompt(level);
        }

        function checkKey(e) {
            e = e || window.event;
            if (e.keyCode == '27' || e.keyCode == '27') {
                closeMenu();
            }
        }
        document.onkeydown = checkKey;

        document.getElementsByClassName("plus-settings")[0].addEventListener("click", openSettingsMenu);

    }

    function folders(){

        function getFolders(){

            let folders = (JSON.parse(GM_getValue("folders"))).folders;

            let backFolder = '<p class="dropdown-item plus-disabled"><span class="fas fa-arrow-left fa-fw " aria-hidden="true"></span style="color: #333"> <i>..</i></p>'
            let createFolder = '<p class="dropdown-item plus-createFolder"><span class="fas fa-plus-circle fa-fw " aria-hidden="true"></span style="color: #333"> <i>Create New Folder</i></p>'
            let otherFolders = "";

            let edit_btn = '<p class="dropdown-item plus-edit-folder" title="Edit Folder Name" style="width: max-content;padding-left: 5px;padding-right: 5px; display: inline-table;">' +
                '<span aria-hidden="true" class="fas fa-pen fa-fw folder_0"></span></p>';
            let delete_btn = '<p class="dropdown-item plus-delete-folder" title="Delete Folder" style="width: max-content;padding-left: 5px;padding-right: 16px;">' +
                '<span aria-hidden="true" class="fas fa-trash fa-fw folder_0"></span></p>';

            for (let i = 0; i < folders.length; i++){
                otherFolders = otherFolders + '<div style="display: flex"><p class="dropdown-item "><span class="fas fa-folder-open fa-fw folder_' + (i) + '" aria-hidden="true">' +
                    '</span style="color: #333"> ' + folders[i].name + '</p>' + edit_btn + delete_btn + '</div>';
            }

            return backFolder + otherFolders + createFolder;
        }

        function folderItems(index){

            let backFolder = '<p class="dropdown-item plus-back"><span class="fas fa-arrow-left fa-fw " aria-hidden="true"></span style="color: #333"> <i>..</i></p>'

            let folders = (JSON.parse(GM_getValue("folders"))).folders;
            let folder_name = (JSON.parse(GM_getValue("folders"))).folders[index].name;

            let delete_btn = '<p class="dropdown-item plus-delete-entry" title="Delete Entry" style="width: max-content;padding-left: 5px;padding-right: 16px;">' +
                '<span aria-hidden="true" class="fas fa-trash fa-fw folder_0"></span></p>';

            let html = "";

            for (let i = 0; i < (folders[index].entries).length; i++){
                html = html + '<div style="display: flex"><a style="display: contents" href="' + folders[index].entries[i].link + '"><p class="dropdown-item " title="' + folders[index].entries[i].title + '">' +
                    '<span class="fas fa-book fa-fw " aria-hidden="true"></span style="color: #333"> ' + folders[index].entries[i].title + '</p></a>' + delete_btn + '</div>';
            }

            html = backFolder + html;

            return '<div x-placement="bottom-start" style="left: 0px !important;' +
                'right: 0px !important;' +
                'width: 600px !important;' +
                'margin-left: auto;' +
                'margin-right: auto;' +
                'margin-top: 100px;' +
                'margin-bottom: auto;" class="dropdown-menu show plus-box">' +
                '<div class="modal-header" style="padding-right: 1rem; padding-bottom: 0.5rem; padding-left: 1rem; padding-top: 0rem;">' +
                '<h5 class="modal-title" id="homepage_settings_label" style="color: rgb(204, 204, 204) !important;">' +
                '<span class="fas fa-folder-open fa-fw " aria-hidden="true"></span> ' + folder_name + '</h5>' +
                '<button type="button" class="close plus-close" data-dismiss="modal" aria-label="Close">' +
                '<span aria-hidden="true">×</span></button></div>' +
                html + '</div>';
        }

        function createFolder(){

            if (editing_busy == false){

                editing_busy = true;

                function writeFolder(){

                    let value = "" + document.getElementsByClassName("folderInput")[0].value;
                    let folders = JSON.parse(GM_getValue("folders"));

                    folders.folders[folders.folders.length] = {"name" : value + "", "entries" : []};
                    GM_setValue("folders", JSON.stringify(folders));
                    editing_busy = false;
                }

                let option = document.getElementsByClassName("dropdown-item plus-createFolder")[0];
                option.innerHTML = '<input class="folderInput" type="text" placeholder="When finished writing press Enter"></input>';
                document.getElementsByClassName("plus-createFolder")[0].removeEventListener("click", createFolder);

                function checkKey(e) {
                    e = e || window.event;
                    if (e.keyCode == '13') {
                        writeFolder();
                        closeMenu();
                        openFoldersMenu();
                        document.onkeydown = null
                    }
                }
                document.onkeydown = checkKey;

                document.getElementsByClassName("folderInput")[0].addEventListener("onsubmit", writeFolder);
                document.getElementsByClassName("folderInput")[0].select();

            }
        }



        function refreshFolders(){
            return '<div x-placement="bottom-start" style="left: 0px !important;' +
                'right: 0px !important;' +
                'width: 600px !important;' +
                'margin-left: auto;' +
                'margin-right: auto;' +
                'margin-top: 100px;' +
                'margin-bottom: auto;" class="dropdown-menu show plus-box">' +
                '<div class="modal-header" style="padding-right: 1rem; padding-bottom: 0.5rem; padding-left: 1rem; padding-top: 0rem;">' +
                '<h5 class="modal-title" id="homepage_settings_label" style="color: rgb(204, 204, 204) !important;">' +
                '<span class="fas fa-folder fa-fw " aria-hidden="true"></span> Folders</h5>' +
                '<button type="button" class="close plus-close" data-dismiss="modal" aria-label="Close">' +
                '<span aria-hidden="true">×</span></button></div>' +
                getFolders() +
                '</div>';
        }

        function openFoldersMenu(){
            container.insertAdjacentHTML("afterbegin", refreshFolders());
            addGlobalStyle("div.plus-box { position: fixed !important; right: 700px !important; left: 700px !important; top: 100px !important; z-index: 100001;}");
            addGlobalStyle(".plus-disabled{ color: #555}");
            addGlobalStyle(".plus-disabled:hover{ background-color: unset; color: #555}");

            container.insertAdjacentHTML("afterbegin", pageMask);
            addGlobalStyle("#page-mask { background: rgba(0, 0, 0, 0.5); position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 100000;}");

            container.insertAdjacentHTML("afterbegin", closeButton);
            addGlobalStyle(".plus-clsBtn { right: 150px !important; position: fixed !important; z-index: 100000; width: auto; color: white; background-color: #444;}");

            document.getElementById("page-mask").addEventListener("click", closeMenu);
            document.getElementsByClassName("plus-clsBtn")[0].addEventListener("click", closeMenu);
            document.getElementsByClassName("plus-createFolder")[0].addEventListener("click", createFolder);
            document.getElementsByClassName("plus-close")[0].addEventListener("click", closeMenu);

            let folders = (JSON.parse(GM_getValue("folders"))).folders;

            for (let i = 0; i < folders.length; i++){
                document.getElementsByClassName("folder_" + i)[0].parentNode.addEventListener("click", function(){browseFolder(i)});
                document.getElementsByClassName("plus-delete-folder")[i].addEventListener("click", function(){deleteFolder(i)});
                document.getElementsByClassName("plus-edit-folder")[i].addEventListener("click", function(){editFolder(i)});
            }

        }

        function browseFolder(index){
            closeMenu();
            container.insertAdjacentHTML("afterbegin", folderItems(index));
            addGlobalStyle("div.plus-box { position: fixed !important; right: 700px !important; left: 700px !important; top: 100px !important; z-index: 100001;}");

            container.insertAdjacentHTML("afterbegin", pageMask);
            addGlobalStyle("#page-mask { background: rgba(0, 0, 0, 0.5); position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 100000;}");

            container.insertAdjacentHTML("afterbegin", closeButton);
            addGlobalStyle(".plus-clsBtn { right: 150px !important; position: fixed !important; z-index: 100000; width: auto; color: white; background-color: #444;}");

            document.getElementsByClassName("plus-back")[0].addEventListener("click", function(){closeMenu();openFoldersMenu();})
            document.getElementById("page-mask").addEventListener("click", closeMenu);
            document.getElementsByClassName("plus-clsBtn")[0].addEventListener("click", closeMenu);
            document.getElementsByClassName("plus-close")[0].addEventListener("click", closeMenu);

            let folders = (JSON.parse(GM_getValue("folders"))).folders[index].entries;

            for (let i = 0; i < folders.length; i++){
                document.getElementsByClassName("plus-delete-entry")[i].addEventListener("click", function(){deleteEntry(index, i)});
            }
        }

        function deleteFolder(index){

            let folder = JSON.parse(GM_getValue("folders"));

            function prompt(){
                if(confirm("Folder " + folder.folders[index].name + " will be deleted. Proceed?")){
                    folder.folders.splice(index, 1);
                    GM_setValue("folders", JSON.stringify(folder));
                    closeMenu();
                    openFoldersMenu();
                }
            }
            prompt();
        }

        function deleteEntry(folder, entry){

            let folders = JSON.parse(GM_getValue("folders"));

            function prompt(){
                if(confirm("\"" + folders.folders[folder].entries[entry].title + "\" will be removed from this Folder. Proceed?")){
                    folders.folders[folder].entries.splice(entry, 1);
                    GM_setValue("folders", JSON.stringify(folders));
                    closeMenu();
                    browseFolder(folder);
                }
            }
            prompt();
        }

        let editing_busy = false;

        function editFolder(index){

            if (editing_busy == false){

                editing_busy = true;

                function writeFolder(){

                    let value = "" + document.getElementsByClassName("folderInput")[0].value;
                    let folders = JSON.parse(GM_getValue("folders"));

                    folders.folders[index].name = value;
                    GM_setValue("folders", JSON.stringify(folders));
                    editing_busy = false;
                }

                let folder = JSON.parse(GM_getValue("folders"));

                let option = document.getElementsByClassName("folder_" + index)[0].parentNode;
                option.innerHTML = '<input class="folderInput" type="text" placeholder="When finished writing press Enter"></input>';
                document.getElementsByClassName("folderInput")[0].value = "" + folder.folders[index].name

                var el = document.getElementsByClassName('folderInput')[0].parentNode,
                    elClone = el.cloneNode(true);
                el.parentNode.replaceChild(elClone, el);

                function checkKey(e) {
                    e = e || window.event;
                    if (e.keyCode == '13') {
                        writeFolder();
                        closeMenu();
                        openFoldersMenu();
                        document.onkeydown = null
                    }
                }
                document.onkeydown = checkKey;

                document.getElementsByClassName("folderInput")[0].addEventListener("onsubmit", writeFolder);
                document.getElementsByClassName("folderInput")[0].select();
            }


        }

        function checkKey(e) {
            e = e || window.event;
            if (e.keyCode == '27' || e.keyCode == '27') {
                closeMenu();
            }
        }
        document.onkeydown = checkKey;

        document.getElementsByClassName("plus-folders")[0].addEventListener("click", openFoldersMenu);
        addGlobalStyle("p.dropdown-item { overflow: hidden;}");
        addGlobalStyle(".plus-delete-folder:hover { color: #f00;}");
        addGlobalStyle(".plus-delete-entry:hover { color: #f00;}");

    }

    function options(){

        var temp_storage = {
            "preloading" : JSON.parse(GM_getValue("options")).options[0].preloading
        }

        var style = window.getComputedStyle(document.getElementById('homepage_settings_modal'));

        addGlobalStyle(".plus-options-window {position: fixed; left: 0px !important; right: 0px !important; width: 800px !important; margin-left: auto; margin-right: auto; margin-top: 100px; margin-bottom: auto;)");
        addGlobalStyle(".modal-footer{display: block;}");

        let preloading = '<div class="form-group row">' +
            '<label for="language" class="col-lg-3 col-form-label-modal">Auto preloading (*):</label>' +

            '<div class="col-lg-9">' +
            '<div class="dropdown bootstrap-select form-control">' +
            '<select class="form-control selectpicker">' +
            '<option selected="" value="1">On</option>' +
            '<option value="0">Off</option>' +
            '</select>' +
            '<button type="button" class="btn dropdown-toggle btn-light" data-toggle="dropdown" role="button" data-id="theme_id" title="N">' +
            '<div class="filter-option">' +
            '<div class="filter-option-inner">' +

            '<div class="filter-option-inner-inner plus-preloading-selected"> NaN </div>' +
            '</div>' +
            '</div>' +
            '</button>' +
            '<div class="dropdown-menu" role="combobox">' +
            '<div class="inner show" role="listbox" aria-expanded="false" tabindex="-1">' +
            '<ul class="dropdown-menu inner show plus-preloading-options">' +
            '<li><a role="option" class="dropdown-item" aria-disabled="false" aria-selected="false" tabindex="0"><span class=" bs-ok-default check-mark"></span><span class="text">On</span></a></li>' +
            '<li><a role="option" class="dropdown-item" aria-disabled="false" aria-selected="false" tabindex="0"><span class=" bs-ok-default check-mark"></span><span class="text">Off</span></a></li>' +
            '</ul>' +
            '</div>' +
            '</div>' +
            '</div>' +
            '</div>' +
            '</div>';

        let notes = '<p style="margin-top: 16px;">(*) Automatically starts preloading chapter when in the reader. Only works for logged-in users.</p>'

        let options = //'<div id="plus-options-win" class="modal-dialog modal-dialog-centered modal-lg plus-options-window" role="document">' +
            '<div class="modal-content plus-options-window" style="z-index: 100000">' +
            '<div class="modal-header">' +
            '<h5 class="modal-title" id="homepage_settings_label">' +
            '<span class="fas fa-list fa-fw " aria-hidden="true"></span> Mangadex Plus Options' +
            '</h5>' +
            '<button type="button" class="close plus-close" data-dismiss="modal" aria-label="Close">' +
            '<span aria-hidden="true">×</span>' +
            '</button>' +
            '</div>' +
            '<div class="modal-body">' +
            '<form method="post" id="homepage_settings_form">' +
            preloading +
            '</form>' +
            '</div>' +
            '<div class="modal-footer">' +
            '<a class="btn btn-secondary mx-auto plus-options-save" style="display: block;width: max-content;">' +
            '<span class="fas fa-save fa-fw " aria-hidden="true"></span> Save' +
            '</a>' +
            notes +
            '</div>' +
            '</div>';
        //'</div>';

        function listeners(){
            //Listeners for options buttons
            for(let i = 0; i < document.getElementsByClassName("plus-preloading-options")[0].getElementsByTagName("a").length; i++){
                document.getElementsByClassName("plus-preloading-options")[0].getElementsByTagName("a")[i].addEventListener("click", function(){selectOption("preloading", i)});
            }
            document.getElementsByClassName("plus-options-save")[0].addEventListener("click", saveOptions);
        }

        function openOptionsMenu(){
            container.insertAdjacentHTML("afterbegin", options);
            addGlobalStyle("div.plus-box { position: fixed !important; right: 700px !important; left: 700px !important; top: 100px !important; z-index: 100001;}");

            container.insertAdjacentHTML("afterbegin", pageMask);
            addGlobalStyle("#page-mask { background: rgba(0, 0, 0, 0.5); position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 100000;}");

            container.insertAdjacentHTML("afterbegin", closeButton);
            addGlobalStyle(".plus-clsBtn { right: 150px !important; position: fixed !important; z-index: 100000; width: auto; color: white; background-color: #444;}");

            document.getElementById("page-mask").addEventListener("click", closeMenu);
            document.getElementsByClassName("plus-clsBtn")[0].addEventListener("click", closeMenu);
            document.getElementsByClassName("plus-close")[0].addEventListener("click", closeMenu);

            loadOptions();
            listeners();
        }

        function checkKey(e) {
            e = e || window.event;
            if (e.keyCode == '27' || e.keyCode == '27') {
                closeMenu();
            }
        }

        let sample_options = {
            "options" : [
                {
                    "preloading" : 0
                }
            ]
        }

        function saveOptions(){

            GM_setValue("options", "{\"options\":[" + JSON.stringify(temp_storage) + "]}")
            location.reload()
        }

        function loadOptions(){
            var options = JSON.parse(GM_getValue("options"));

            let preloading = options.options[0].preloading;

            selectOption("preloading", preloading);
        }

        function selectOption(option, index){
            if(option == "preloading"){
                let val;
                for(let i = 0; i < document.getElementsByClassName("plus-preloading-options")[0].getElementsByTagName("a").length; i++){
                    try{
                        document.getElementsByClassName("plus-preloading-options")[0].getElementsByTagName("a")[i].classList.remove('selected');
                        document.getElementsByClassName("plus-preloading-options")[0].getElementsByTagName("a")[i].classList.remove('active');

                        val = document.getElementsByClassName("plus-preloading-options")[0].getElementsByTagName("a")[index].childNodes[1].innerHTML;
                    }
                    catch(e){/*Nothing*/}
                }

                document.getElementsByClassName("plus-preloading-options")[0].getElementsByTagName("a")[index].classList.add("active");
                document.getElementsByClassName("plus-preloading-options")[0].getElementsByTagName("a")[index].classList.add("selected");
                document.getElementsByClassName("plus-preloading-selected")[0].innerHTML = val;
                temp_storage.preloading = index;
            }
        }

        document.onkeydown = checkKey;

        document.getElementsByClassName("plus-options")[0].addEventListener("click", openOptionsMenu);


    }

    function actionsBar(){

        function makeBar(){

            let bar = '<div class="row m-0 py-1 px-0 border-top">' +
                '<div class="col-lg-3 col-xl-2 strong">Mangadex+ Actions:</div>' +
                '<div class="col-lg-9 col-xl-10 plus-actionbar">' +
                '</div>' +
                '</div>';

            var position = document.getElementsByClassName("col-xl-9 col-lg-8 col-md-7")[0];

            position.insertAdjacentHTML("beforeend", bar);
        }

        function addToFolder(){

            function addEntry(index){

                let folders = JSON.parse(GM_getValue("folders"));

                let link = ("" + window.location).replace("#", "");

                let pass = true;

                for(let i = 0; i < folders.folders[index].entries.length; i++){
                    try{
                        if(link == folders.folders[index].entries[0].link){
                            pass = false;
                        }
                    }
                    catch(e){
                        if (e == TypeError){
                            pass = true;
                        }
                    }
                }

                if (pass == true){
                    folders.folders[index].entries[folders.folders[index].entries.length] = {"title": "" + document.getElementsByClassName("card-header")[0].childNodes[3].innerHTML, "link" : "" + link};
                    GM_setValue("folders","" + JSON.stringify(folders));
                }

            }

            function listFolders(){

                let folders = JSON.parse(GM_getValue("folders"));
                let html = "";

                for (let i = 0; i < folders.folders.length; i++){
                    html = html + '<p class="dropdown-item plus-add-folder-' + i + '" ><span class="fas fa-folder-open fa-fw " aria-hidden="true" ></span> ' + folders.folders[i].name + '</p>';
                }

                return html;

            }

            let bar = '<div class="btn-group">' +
                '<button type="button" class="btn btn-secondary dropdown-toggle plus-folder-trigger" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">' +
                '<span class="fas fa-plus-circle fa-fw " aria-hidden="true"></span>' +
                '<span class="d-none d-xl-inline"> Add to Folder</span></button>' +
                '<div class="dropdown-menu dropdown-menu-right plus-actions-folders">' +
                listFolders() +
                '</div>' +
                '</div>&nbsp';

            let position2 = document.getElementsByClassName("plus-actionbar")[0];

            position2.insertAdjacentHTML("beforeend", bar);

            let folders = JSON.parse(GM_getValue("folders"));

            for (let i = 0; i < folders.folders.length; i++){
                document.getElementsByClassName("plus-add-folder-" + i)[0].addEventListener("click", function(){addEntry(i)});
            }

            function reloadFolders(){

                let index = document.getElementsByClassName("plus-actions-folders")[0].childNodes.length

                for(let i = 0; i < index; i++){
                    document.getElementsByClassName("plus-add-folder-" + i)[0].remove();
                }

                let position3 = document.getElementsByClassName("plus-actions-folders")[0];
                position3.insertAdjacentHTML("afterbegin", listFolders());
                let folders = JSON.parse(GM_getValue("folders"));

                for (let i = 0; i < folders.folders.length; i++){
                    document.getElementsByClassName("plus-add-folder-" + i)[0].addEventListener("click", function(){addEntry(i)});
                }

            }

            document.getElementsByClassName("plus-folder-trigger")[0].addEventListener("click", reloadFolders);
        }

        function markAs(){

            let mark_button = '<div class="btn-group">' +
                '<button type="button" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">' +
                '<span class="fas fa-eye fa-fw " aria-hidden="true"></span>' +
                '<span class="d-none d-xl-inline"> Mark All As </span></button>' +
                '<div class="dropdown-menu dropdown-menu-right">' +

                '<p class="dropdown-item" onclick="javascript:var mark = document.getElementsByClassName(\'chapter_mark_read_button\');for (var i = 0; i < mark.length; i++){mark[i].click();}">' +
                '<span class="fas fa-eye fa-fw " aria-hidden="true" ></span> Read</p>' +

                '<p class="dropdown-item" onclick="javascript:var mark = document.getElementsByClassName(\'chapter_mark_unread_button\');for (var i = 0; i < mark.length; i++){mark[i].click();}">' +
                '<span class="fas fa-eye-slash fa-fw " aria-hidden="true" ></span> Unread</p>' +

                '</div>' +
                '</div>&nbsp';

            let position2 = document.getElementsByClassName("plus-actionbar")[0];

            position2.insertAdjacentHTML("beforeend", mark_button);
        }

        function startReading(){

            let manga_id = getSubPage(2);
            let chapter_id = "";
            let api_url = "https://mangadex.org/api/manga/" + manga_id;

            async function getapi(url) {

                let response = await fetch(url);

                var data = await response.json();
                var data2 = "";
                for(let i = 0; i < Object.entries(data.chapter).length; i++){
                    if (await Object.entries(Object.entries(data.chapter)[i][1])[3][1] == "English"){
                        data2 = await Object.entries(data.chapter)[i][0];
                        break;
                    }
                }

                data.chapter[data2]
                return data2

            }

            getapi(api_url).then(x => {

                chapter_id = x;
                let link = "https://mangadex.org/chapter/" + chapter_id;
                let mark_button = '<button class="btn btn-secondary" onclick="javascript:document.location.href = \'' + link + '\'">' +
                    '<span class="fas fa-book fa-fw"></span>' +
                    '<span class="d-none d-xl-inline">&nbsp;Start Reading</span>' +
                    '</button>'

                var position2 = document.getElementsByClassName("plus-actionbar")[0];
                position2.insertAdjacentHTML("beforeend", mark_button);

            });

        }

        makeBar();
        addToFolder();
        markAs();
        startReading();

    }

    function preload(){
        async function doPreload(){
            let index = 100;
            for (let i = 0; i < index; i++){
                if (document.getElementById("preload-all").getAttribute("disabled") == ""){
                    await new Promise(r => setTimeout(r, 100));
                }
                else{
                    document.getElementById("preload-all").click();
                    i = index;
                }
            }
        }

        let enabled = (JSON.parse(GM_getValue("options"))).options[0].preloading

        if (enabled == 0){
            doPreload();
        }

        function checkKey(e) {
            e = e || window.event;
            if (e.keyCode == '37' || e.keyCode == '39') {
                doPreload();
            }
        }
        document.onkeydown = checkKey;
        document.getElementsByClassName("reader-images col-auto row no-gutters flex-nowrap m-auto text-center cursor-pointer directional constrained")[0].onclick = function(){doPreload()};

    }

    function resets(level){
        if(level == "r"){
            let options = {"options" : [{"preloading" : 0}]};
            GM_setValue("options", JSON.stringify(options));
            location.reload();
        }
        else if(level == "w"){
            let folders = {"folders" : []};
            GM_setValue("folders", JSON.stringify(folders));
            location.reload();
        }
        else if(level == "rw"){
            let options = {"options" : [{"preloading" : 0}]};
            GM_setValue("options", JSON.stringify(options));
            let folders = {"folders" : []};
            GM_setValue("folders", JSON.stringify(folders));
            GM_deleteValue("first_time");
            location.reload();
        }
    }

    startup();

})();