Jump to content

User:Mxn/serendipity.js

From Wikipedia, the free encyclopedia
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
/**
 * Serendipity
 * 
 * Endows Wikipedia with the “sense of wonder” and “serendipitous discoveries”
 * that proud owners of the print Encyclopædia Britannica find sorely lacking on
 * the Internet. Now, whenever you look up an entry in this ephemeral reference,
 * “lose yourself” in the alphabetically adjacent bounty of knowledge that any
 * self-respecting encyclopedia should offer by default.
 * 
 * :-P
 */

if (mw.config.get("wgAction") == "view" && mw.config.get("wgNamespaceNumber") == 0) {
    mw.loader.using("mediawiki.api", function () {
        var api = new mw.Api();
        
        /**
         * Retrieves the rendered HTML content of an alphabetically adjacent
         * article and passes the content to a callback function.
         * 
         * @param forward   {boolean}   True to get the next page; false to get
         *                              the previous one.
         * @param ok        {function}  A callback function that takes two
         *                              arguments: title, html.
         */
        function fetchAdjacentArticle(forward, ok) {
            api.get({
                list: "allpages",
                apfrom: mw.config.get("wgPageName"),
                apnamespace: 0,
                apfilterredir: "nonredirects",
                aplimit: 2,
                apdir: forward ? "ascending" : "descending",
            }).done(function (data) {
                var pages = data.query && data.query.allpages;
                var page = pages && data.query.allpages[1];
                if(!page) return;
                
                $.get(mw.util.wikiScript("index"), {
                    title: page.title,
                    action: "render",
                }, function (html) {
                    if (ok) ok(page.title, html);
                }, "html");
            });
        }
        
        /**
         * Hides content features that facilitate user contributions, multimedia
         * experiences, non-linear navigation, or fact-checking.
         */
        function hideNewFangledFeatures() {
            // Links
            $("#bodyContent a").unbind("click").click(function (evt) {
                evt.preventDefault();
                evt.stopPropagation();
            });
            var extLinkHeadings = $("h2:contains('xternal link')");
            extLinkHeadings.hide().nextAll("ul").hide();
            if (extLinkHeadings) {
                $(".toctext:contains('xternal link')").parent().hide();
            }
            
            // Cite extension
            var refHeadings = $(".reflist").prev("h2:contains('eference')");
            refHeadings.hide();
            if (refHeadings) $(".toctext:contains('eference')").parent().hide();
            
            // WikiMiniAtlas
            wma_settings = {enabled: false};
            
            // Stylesheets only need to be applied once.
            if (hideNewFangledFeatures.stylesAdded) return;
            hideNewFangledFeatures.stylesAdded = true;
            
            // Links
            mw.util.addCSS("#bodyContent a {" +
                           "background: transparent !important; cursor: inherit;" +
                           "color: inherit; padding-right: 0 !important;" +
                           "text-decoration: inherit;" +
                           "}");
            
            // Abbreviations
            mw.util.addCSS("#bodyContent abbr, #bodyContent acronym," +
                           "#bodyContent .explain {" +
                           "border-bottom: none; cursor: inherit;" +
                           "}");
            
            // Software-powered features
            mw.util.addCSS("#mw-articlefeedback, #catlinks, .mw-editsection," +
                           ".magnify, .toctoggle {display: none;}");
            
            // Cite extension
            mw.util.addCSS(".reference, .reflist {display: none;}");
            
            // Template-powered features
            mw.util.addCSS("#coordinates, img[alt='play'], .navbox, .stub" +
                            "{display: none;}");
        }
        
        /**
         * Inserts the contents of the previous article above the original one.
         */
        function insertPreviousArticle(title, html) {
            // Stuff the main article’s title inside its body element.
            $("#bodyContent").prepend($("#firstHeading"));
            $("#firstHeading").css({
                "font-size": 1.25 * parseFloat($("#firstHeading").css("font-size")),
            });
            
            $("#bodyContent").prepend("<div class='visualClear'></div>")
                             .prepend($(html).wrap("<div id='prevBodyContent'></div>"))
                             .prepend("<h1 id='prevFirstHeading' class='firstHeading'>" +
                                      "<span dir='auto'>" + title + "</span>" +
                                      "</h1>");
            hideNewFangledFeatures();
        };
        
        /**
         * Inserts the contents of the next article above the original one.
         */
        function insertNextArticle(title, html) {
            $("#bodyContent").append("<h1 id='nextFirstHeading' class='firstHeading'>" +
                                     "<span dir='auto'>" + title + "</span>" +
                                     "</h1>")
                             .append($(html).wrap("<div id='nextBodyContent'></div>"))
                             .append("<div class='visualClear'></div>");
            hideNewFangledFeatures();
        };
        
        $(function () {
            fetchAdjacentArticle(false, insertPreviousArticle);
            fetchAdjacentArticle(true, insertNextArticle);
        });
    });
}