User:Pyrospirit/showrandomlinksonpage.js

Source: Wikipedia, the free encyclopedia.
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.
// Create a slideshow of random articles linked in the article (a so-called "aleation" or an "aleatory fugue")
//
// To use this script, add "importScript('User:Proteins/showrandomlinksonpage.js');" to your monobook.js subpage 
// under your user page, as you can see at User:Proteins/monobook.js

window.showRandomLinksOnPage = {
    links_available: true, // are there any links available at all?
    max_random_links: 5, // slides to show at a time
    slideshow_delay: 3000, // milliseconds between slides
    random_link_href_list: [],
    /**
     * Setup script in preparation for use
     */
    init: function init () {
        this.link_list = this.getLinkList();
        if (!this.link_list) {
            this.links_available = false;
            return false;
        }
        return true;
    },
    /**
     * Pick some random links from link_list and make a slideshow out of them
     */
    showRandomLinks: function showRandomLinks () {
        // Get all suitable links in the article
        if (!this.links_available) {
            alert('There are no suitable hyperlinks in this article.');
            return;
        }
        else if (!this.link_list) {
            if (confirm('All links have been followed. Restart slideshow?')) {
                this.link_list = this.getLinkList();
            }
            else return;
        }

        var link_list = this.link_list;

        // Get random links 
        var random_index;
        while (this.random_link_href_list.length < this.max_random_links) {
            random_index = Math.floor(Math.random() * link_list.length);
            this.random_link_href_list.push(link_list[random_index]);
            // Remove the random item from the array to avoid duplicates
            link_list.splice(random_index, 1);
        }

        // Run the slideshow
        var num_random_links = this.random_link_href_list.length;
        var confirmation = ('Show slideshow of ' + num_random_links + ' random links from this page?\n\n'
            + this.getPageTitles(this.random_link_href_list).join('\n'));
        if (confirm(confirmation)) {
            this.new_window = window.open();
            var that = this;
            this.new_window.setTimeout(function () {
                that.timeoutRoutine.call(that);
            }, 0);
        }
    },
    /**
     * Removes the first item from the list, sets the window to that location,
     * and starts the next timer.
     */
    timeoutRoutine: function timeoutRoutine () {
        var url = this.random_link_href_list[0];
        // Remove the first item
        this.random_link_href_list.splice(0, 1);

        this.new_window.location = url;
        if (this.random_link_href_list.length > 0) {
            var that = this;
            this.new_window.setTimeout(function () {
                that.timeoutRoutine.call(that);
            }, this.slideshow_delay);
        }
    },
    /**
     * Get an array of URLs pointing to the pages to be selected from.
     */
    getLinkList: function getLinkList () {
        // Get a list of all hyperlinks in the article
        var link_list = [],
            hyperlinks = document.getElementById('bodyContent').getElementsByTagName('a'),
            num_hyperlinks = hyperlinks.length,
            current_href;

        if (!hyperlinks || num_hyperlinks < 1) { 
            return;
        }

        // Put all links to be used into link_list
        for (var i = 0; i < num_hyperlinks; i++) {
            current_href = hyperlinks[i].href;
            if (this.acceptLink(current_href)) {
                link_list.push(current_href);
            }
        }

        return link_list;
    },   
    /**
     * Given an array of Wikipedia URLs, returns an array of the page titles.
     */
    getPageTitles: function getPageTitles (url_list) {
        var result_list = [],
            url_pattern = new RegExp('^' + mw.config.get('wgServer') + mw.config.get('wgArticlePath').replace('$1', '') + '([^#]*)'),
            url_match;
        for (var i = 0, len = url_list.length; i < len; i++) {
            url_match = url_list[i].match(url_pattern);
            if (url_match) {
                result_list.push(decodeURIComponent(url_match[1].replace(/_/g, ' ')));
            }
        }
        return result_list;
    },
    /**
     * Given a URL, returns true if it should be put into the list of links in
     * the slideshow, and false otherwise.
     *
     * For mainspace pages, only mainspace links are accepted. For non-mainspace
     * pages, only the Image, Category, and Special namespaces are excluded.
     */
    acceptLink: function acceptLink (href) {
        var local_url = mw.config.get('wgServer') + mw.config.get('wgArticlePath').replace('$1', ''),
            h = href.toString().replace(/#.*/, ''),
            h_local = h.replace(local_url, ''),
            non_mainspace_link_pattern = /^[a-z]+([_ ]talk)?:[^_ ]/i;
        // Reject links to anchors, external pages, edit/history pages, etc.
        if (h == document.location.href || !RegExp('^' + local_url).test(h)) {
            return false;
        }
        // Behavior for mainspace pages
        else if (wgNamespaceNumber == 0) {
            // True for mainspace links, false otherwise
            return !(non_mainspace_link_pattern.test(h_local));
        }
        // Behavior for non-mainspace pages
        else {
            // False for non-image/category/special namespace links, true otherwise
            return !(/^(image|category|special)([_ ]talk)?:[^_ ]/i.test(h_local));
        }
    }
};

$(function () {
    showRandomLinksOnPage.init();
    mw.util.addPortletLink('p-navigation', 'javascript:showRandomLinksOnPage.showRandomLinks()', 'Show random links',
        'ca-slideshow', 'Show sequence of random links from this page', '$', '');
});