User:Pyrospirit/showrandomlinksonpage.js

// 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', '$', ''); });