FA - Gallery Usability Handler

Provides actual download link, shows image checkerboard and adds keyboard shortcuts

This script is marked as "external"
This script was commisioned by someone else, and I will not check if it works. If it breaks, contact me
Click here to install Browse More Scripts
// ==UserScript==
// @name         FA - Gallery Usability Handler
// @namespace    23e6f0ae9d41ec47fdf7e8670c7e1d379a23613c
// @version      4.3
// @description  Provides actual download link, shows image checkerboard and adds keyboard shortcuts
// @author       /u/AyrA_ch
// @include      https://www.furaffinity.net/*
// @include      http://www.furaffinity.net/*
// @include      https://furaffinity.net/*
// @include      http://furaffinity.net/*
// @external     true
// @expired      false
// @grant        GM_download
// @run-at       document-end
// ==/UserScript==

//Changelog
//=========
//4.3 - Remove furarchiver integration. It's now its own script.
//4.2 - Show link on journal and fav pages too.
//4.1 - Add furarchiver link
//4.0 - Update for new page design. Not sure if old design still works
//3.3 - Limit maximum width to container width
//3.2 - No longer triggers keyboard shortcuts on certain elements (flash for example)
//3.1 - Keyboard Shortcuts (D=Download, F=Fullview, Right=Previous, Left=Next)
//3.0 - Fix download button
//2.2 - Reformatting and description edit
//2.1 - Background checkerboard for large images
//2.0 - Added better full view handler (shows load progress)
//1.1 - Adapted for "full_url" variable no longer being present
//1.0 - Initial release

(function ($, $$) {
    'use strict';
    //Regex that matches the id from an URL
    var idMatch = /\/view\/(\d+)\/?$/;
    var userRegex = /\/(?:user|gallery|scraps|favorites|journals)\/([^\/]+)\/?/;
    var IMG_BG = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgA" +
        "AABAAAAAQCAIAAACQkWg2AAAAJ0lEQVR42mOcOXMmAzZw9uxZrOKM" +
        "oxpooiEtLQ2rhLGx8agG+mkAACpiL/lWCxuBAAAAAElFTkSuQmCC";
    var getDownloadLink = function () {
        var all = $$(".actions a");
        for (var i = 0; i < all.length; i++) {
            if (all[i].textContent === "Download") {
                return all[i];
            }
        }
        return null;
    };

    var isGallery = !!location.pathname.match(idMatch);

    var downloadFile = function (e) {
        var downloadLink = e.target;
        if (downloadLink && downloadLink.href) {
            e.preventDefault();
            e.stopPropagation();
            var url = downloadLink.href;
            downloadLink.textContent = "Loading...";
            GM_download({
                url: url,
                name: url.match(/[^/]+$/)[0],
                onerror: function (e) {
                    console.error(e);
                    alert("Unable to download file. Reason: " + e.error);
                },
                onprogress: function (e) {
                    console.log("Progress:", e, arguments);
                },
                onload: function (e) {
                    //Argument is always empty
                    downloadLink.textContent = "Complete";
                }
            });
        }
    };

    var makeFull = function () {
        var i = $("img#submissionImg");
        if (i) {
            var rules = [
                "background-image:url(" + IMG_BG + ")",
                "min-width:" + i.clientWidth + "px",
                "min-height:" + i.clientHeight + "px",
                "max-width:100%"
            ];
            var full = i.getAttribute("data-fullview-src");
            var small = i.getAttribute("data-preview-src");
            var n = document.createElement("img");
            n.setAttribute("style", rules.join(';'));
            n.setAttribute("src", full);
            n.setAttribute("data-fullview", 1);
            n.setAttribute("data-fullview-src", full);
            n.setAttribute("data-preview-src", small);
            n.title = "Click or press [F] to switch to preview";
            n.onclick = makeSmall;
            i.parentNode.replaceChild(n, i);
            n.id = "submissionImg";
        }
    };

    var makeSmall = function () {
        var i = $("img#submissionImg");
        if (i) {
            var full = i.getAttribute("data-fullview-src");
            var small = i.getAttribute("data-preview-src");
            var n = document.createElement("img");
            n.setAttribute("src", small);
            n.setAttribute("data-fullview", 0);
            n.setAttribute("data-fullview-src", full);
            n.setAttribute("data-preview-src", small);
            n.title = "Click or press [F] to switch to full view";
            n.onclick = makeFull;
            i.parentNode.replaceChild(n, i);
            n.id = "submissionImg";
        }
    };

    var swapFS = function () {
        if ($("img[data-fullview='1']")) {
            makeSmall();
        } else {
            makeFull();
        }
    };

    var currentId = function () {
        return +location.pathname.match(idMatch)[1];
    };

    var getPreviews = function () {
        //Get up to 6 other entries
        var gallery = Array.from($$(".preview-gallery-container a")).map(function (v) {
            return +v.href.match(idMatch)[1];
        });
        if (gallery.length === 0) {
            return [];
        }
        gallery.push(currentId());
        //Sort in descending order
        return gallery.sort(function (a, b) {
            return b - a;
        });
    };

    var newerImage = function (e) {
        if (e && typeof(e.click) === typeof(function () {})) {
            e.click();
        } else {
            var id = currentId();
            var p = getPreviews();
            var index = p.indexOf(id);
            if (p.length > 0 && index >= 0) {
                if (index > 0) {
                    location.href = "/view/" + p[index - 1] + "/";
                } else {
                    console.log("End of gallery");
                }
            } else {
                console.log("No gallery");
            }
        }
    };

    var olderImage = function (e) {
        if (e && typeof(e.click) === typeof(function () {})) {
            e.click();
        } else {
            var id = currentId();
            var p = getPreviews();
            var index = p.indexOf(id);
            if (p.length > 0 && index >= 0) {
                if (index < p.length - 1) {
                    location.href = "/view/" + p[index + 1] + "/";
                } else {
                    console.log("End of gallery");
                }
            } else {
                console.log("No gallery");
            }
        }
    };

    var handleNavButtons = function () {
        var oldBtn = {
            next: $("a.next"),
            prev: $("a.prev")
        };
        if (oldBtn.next) {
            oldBtn.next.title = "Press [Left Arrow] for quick access";
        }
        if (oldBtn.prev) {
            oldBtn.prev.title = "Press [Right Arrow] for quick access";
        }
        if (!getDownloadLink()) {
            var section = document.createElement("section");
            var newer = $(".buttons > .fav").cloneNode(true);
            var older = $(".buttons > .note").cloneNode(true);
            //fix copied fav link
            var link = newer.querySelector("a");
            link.href = "#";
            link.textContent = "<< Newer";
            link.title = "Press [Left Arrow] for quick access";
            link.addEventListener("click", newerImage);

            //fix copied note link
            link = older.querySelector("a");
            link.href = "#";
            link.textContent = "Older >>";
            link.title = "Press [Right Arrow] for quick access";
            link.addEventListener("click", olderImage);
            section.appendChild(newer);
            section.appendChild(older);

            section.setAttribute("class", "buttons");

            $(".submission-sidebar").insertBefore(section, $(".submission-sidebar .buttons"));
        }
    };

    if (isGallery) {
        var downloadLink = getDownloadLink();
        if (downloadLink) {
            //Make this look like a button
            downloadLink.setAttribute("class", "button-link");
        } else {
            downloadLink = $(".download>a");
        }
        //Attributes that are in use for the new and old design
        if (downloadLink) {
            //Make this a download link
            downloadLink.setAttribute("download", "");
            downloadLink.setAttribute("title", "Press [D] for quick download with full resolution");
            //Attach custom handler
            downloadLink.addEventListener("click", downloadFile);
        }
        makeSmall();

        document.addEventListener("keydown", function (e) {
            //We don't accept input on elements that might need them
            var skip = [
                "INPUT", "TEXTAREA", "SELECT",
                "OBJECT", "EMBED"
            ];
            var c = {
                click: function () {}
            };
            if (skip.indexOf(e.target.nodeName) < 0) {
                //Don't accept arrow keys if image doesn't exists (allows arrow keys in flash)
                var img = $("img#submissionImg");
                switch (e.keyCode) {
                case 37: //Left Arrow
                    if (img) {
                        newerImage($("a.next"));
                    }
                    break;
                case 39: //Right Arrow
                    if (img) {
                        olderImage($("a.prev"));
                    }
                    break;
                case 68: //D
                    if (downloadLink) {
                        downloadLink.click();
                    }
                    break;
                case 70: //F
                    swapFS();
                    break;
                }
            } else {
                console.debug("Ignoring key because in focusable element");
            }

        });
        handleNavButtons();
    }
})(document.querySelector.bind(document), document.querySelectorAll.bind(document));

/*
LICENSE:
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
The full license text can be found here: http://creativecommons.org/licenses/by-nc-sa/4.0/
The link has an easy to understand version of the license and the full license text.

DISCLAIMER:
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
*/

Copyright © 2018 by Kevin Gut 📧 | More services | Generated for 44.192.54.67