User:HarJIT/persistent-useskin.js

From Meta, a Wikimedia project coordination wiki

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
// Make all internal links preserve an existing useskin= query-variable.
// This is useful if you want to switch to another skin for a session (rather than outright).
//
// Note the following:
//
//  * Use at your own risk (I am not selling this and guarantee neither safety nor fitness).
//  * Editing a page will still lose it.
//  * A tab action will be added to open a skin-switcher gui.
//  ** This is likely not to show up on mobile skins such as Minerva.
//  ** If you want it to show up in Wikia's Oasis skin, see [[m:User:HarJIT/portletnotifyshim.js]].
//
// Usage: mw.loader.load("//meta.wikimedia.org/w/index.php?action=raw&ctype=text/javascript&title=User:HarJIT/persistent-useskin.js");
//
// Canonical: [[m:User:HarJIT/persistent-useskin.js]]

$(function(){
if ((window.location.href + "").search(/\?.*useskin=.+/) >= 0) {
    var useskin = (window.location.href + "").split("useskin=")[1].split("#")[0].split("&")[0];
    var anchors = document.getElementsByTagName("a");
    for (var i = 0; i < anchors.length; i += 1) {
        var node = anchors[i];
        if (node.hasAttribute("href")) {
            var href = node.getAttribute("href");
            if (href.search("//") < 0 && href[0] != "#") { /* i.e. local link. */
                href = href.split("#");
                if (/^https:\/\/www.fairlatterdaysaints.org\/answers\//.test(window.location.href) && /^\/answers\/(?!index.php)/.test(href[0])) {
                    var mainsegment = href[0].substring(9);
                    var title; var query;
                    if (mainsegment.indexOf("?") < 0) {
                        title = mainsegment;
                        query = "";
                    } else {
                        title = mainsegment.substring(0, mainsegment.indexOf("?"));
                        query = "&" + mainsegment.substring(mainsegment.indexOf("?") + 1);
                    }
                    href[0] = "https://www.fairlatterdaysaints.org/answers/index.php?title=" + title + query + "&useskin=" + useskin;
                } else if (href[0].search(/\?/) >= 0) {
                    href[0] += "&useskin=" + useskin;
                } else {
                    href[0] += "?useskin=" + useskin;
                };
                node.setAttribute("href", href.join("#"));
            };
        };
    };
};
mw.util.addPortletLink("p-cactions", "javascript:void null", "Skin", "ca-useskin", "Temporarily switch skin.").onclick = function () {
    var href = window.location.href + "";
    while (href.search("useskin=") >= 0) {
        var before = href.split("useskin=", 1)[0];
        var after = href.substr(before.length);
        after = after.substr(after.split("&", 1)[0].length+1); /* Blame JS' odd split limit semantics for how complicated this has to be. */
        href = before + after;
    };
    if (href[href.length-1] == "?" || href[href.length-1] == "&") {
        href += "useskin=";
    } else if (href.search(/\?/) >= 0) {
        href += "&useskin=";
    } else {
        href += "?useskin=";
    };
    var overshadow = document.createElement("div");
    var overshadow2 = document.createElement("div");
    overshadow.setAttribute("role", "dialog");
    overshadow.appendChild(overshadow2);
    overshadow.style.position = "fixed";
    overshadow2.style.position = "absolute";
    overshadow.style.top = overshadow.style.left = overshadow2.style.top = overshadow2.style.left = "0px";
    overshadow.style.width = overshadow.style.height = overshadow2.style.width = overshadow2.style.height = "100%";
    overshadow2.style.background = "black";
    overshadow2.style.opacity = 0.5;
    overshadow.style["z-index"] = 50;
    overshadow2.style["z-index"] = 1;
    overshadow2.onclick = function () { document.body.removeChild(overshadow); };
    document.body.appendChild(overshadow);
    var menu = document.createElement("div");
    menu.style["z-index"] = 2;
    menu.style.position = "absolute";
    menu.style["overflow-y"] = "scroll";
    menu.style.left = menu.style.top = "50%";
    menu.style.background = "white";
    menu.style["margin-left"] = "-200px";
    menu.style.width = "400px";
    menu.style["margin-top"] = "-150px";
    menu.style.height = "300px";
    menu.style["border-radius"] = "2px";
    menu.style["text-align"] = "left";
    menu.style["box-shadow"] = "10px 5px 5px rgba(0, 0, 0, 0.2)";
    overshadow.appendChild(menu);
    var skins = mw.config.get("wgAvailableSkins");
    for (var ourskin of Object.keys(skins).sort()) {
        switch (ourskin) {
                case "apioutput":
                case "fallback":
            break
                default:
            var item = document.createElement("a");
            item.style.display = "block";
            item.style["font-size"] = "20px";
            item.style.height = "50px";
            item.style["border-bottom"] = "1px solid gray";
            item.style["box-sizing"] = "border-box";
            item.style["padding-left"] = "1ex";
            item.setAttribute("href", href+ourskin);
            item.setAttribute("role", "button");
            if (mw.config.get("skin") == ourskin) {
                item.setAttribute("aria-pressed", "true");
                item.style["background-color"] = "dimgray";
                item.style.color = "white";
            } else {
                item.setAttribute("aria-pressed", "false");
                item.style["background-color"] = "white";
                item.style.color = "dimgray";
            }
            menu.appendChild(item);
            item.appendChild(document.createTextNode(skins[ourskin]));
        };
    };
};
if (mw.config.get("wgAvailableSkins") == null) {
    // Post-T217772, wgAvailableSkins is no longer exported.
    // The available skin list can only be obtained elsehow.
    var hdr = {"headers": {"Api-User-Agent": "m:User:HarJIT/persistent-useskin.js"}};
    var available = {};
    mw.config.set("wgAvailableSkins", available);
    if (location.host.endsWith(".fandom.com") || location.host.endsWith(".wikia.org")) {
        // Tends not to appear in lists due to being nominally disabled (it isn't actually).
        available["fandommobile"] = "FandomMobile";
    }
    var withapi = mw.util.wikiScript('api') + "?action=query&meta=siteinfo&siprop=skins&format=json";
    var fallback_skinlist = () => {
        // Another way of getting the skin list, pre-T254048.
        // In the current version of this script, only tried if the API attempt fails.
        var fallback = (window.location.href + "").split("?", 1)[0] + "?useskin=fallback";
        jQuery.ajax(fallback, hdr).done((data) => {
            var skins = data.split("<ul>", 2)[1].split("</ul>", 1)[0];
            skins = skins.split("<code>").slice(1);
            skins.forEach((skin) => {
                var dat = skin.split("</code> / ");
                var internal = dat[0];
                dat = dat[1].split(" (");
                var friendlyname = dat[0];
                if (dat[1].substring(0, 7) == "enabled") {
                    available[internal] = friendlyname;
                } else if (internal == "minervaneue" && friendlyname == "MinervaNeue") {
                    // Availability of MinervaNeue under "minerva" usually shows up as it being
                    // disabled under "minervaneue", for some reason.
                    available["minerva"] = friendlyname;
                };
            });
        });
    }
    jQuery.ajax(withapi, hdr).done((data) => {
        if (typeof data.query != "undefined" && typeof data.query.skins != "undefined" && data.query.skins.length) {
            data.query.skins.forEach((skin) => {
                available[skin.code] = skin["*"];
            });
        } else {
            fallback_skinlist();
        }
    }).fail(fallback_skinlist);
}
});

// End: [[m:User:HarJIT/persistent-useskin.js]]