User:GregU/randomlink.js
Appearance
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump. This code will be executed when previewing this page. |
![]() | Documentation for this user script can be added at User:GregU/randomlink. |
// Travel to a random page linked in the article or listed on a special page.
// Rewritten from [[User:Proteins/followrandomlinkonpage.js]] and improved so
// it does the right thing on all special pages, using only the main item links.
//
// For example, on recent changes or user contributions (among many others),
// it will choose a title from the list, excluding user links and other links.
// But on history pages, it will follow ONLY user page links, as they are the
// main thing there. In categories, it will choose only items... if there are
// any pages or files in the category. Else, it will use content links and
// subcategories (and parent categories, currently).
//
// To enable this tool, add "importScript('User:GregU/randomlink.js')" to your
// monobook.js subpage under your user page. This adds the "Random link"
// option to the navigation menu.
//
// Greg Ubben
//randomlink_start = [ "Wikipedia:Featured articles", "Wikipedia:Featured pictures" ];
//randomlink_hops = 2;
//randomlink_bigcat = true; // if category has over 200 entries
//randomlink_open = true; // if you want to open in new windows
//randomlink_debug = true; // set this, to debug
function scrapeLinks()
{
var topnode = document.getElementById('bodyContent') || document;
var atags = [];
var links = [];
var nspat = /^(Talk|User|Wikipedia|File|MediaWiki|Template|Help|Category|Portal)( talk)?:/i;
var spec = getElementsByClassName(topnode, 'div', 'mw-spcontent');
if (spec.length == 1) topnode = spec[0]; // skip help links at top of specials
for (var id in {'mw-pages':0, 'mw-category-media':0 }) {
var node = document.getElementById( id );
if (node) {
var nodelist = node.getElementsByTagName('a');
atags = atags.concat( Array.prototype.slice.call( nodelist ));
}
}
if (atags.length == 0)
atags = topnode.getElementsByTagName('a');
nextlink:
for (var i=0; i < atags.length; i++) {
var link = atags[i];
var href = link.href;
var title = link.title;
if (!href) // needed?
continue;
if (link.className.search(/^(mw-redirect|mw-userlink|Cat.*)?$/) == -1)
continue; // external or image
if (href.search(/\/Special:|\?(?!.*redirect=)/) >= 0) // not a normal page
continue;
if (wgIsArticle && wgNamespaceNumber != 14 && title.search(/^(Category|File):|^$/) >= 0)
continue;
if (wgIsArticle && wgNamespaceNumber == 0 && title.search(nspat) >= 0)
continue;
if ((wgAction == "history") != (link.className == "mw-userlink"))
continue;
if (link.host != location.host) // commons.wikimedia.org on images
continue;
if (link.parentNode.id == "coordinates")
continue; // coords too common, or help link
// Exclude message boxes and the Metadata section on Image pages.
// And also mw-usertool links and comments in page listings.
// And also top links on Recent changes and watchlists.
//
for (var n = link.parentNode; n != topnode; n = n.parentNode) {
if (n.id.search(/^mw-watchlist-options|^recentchangestext/) >= 0)
continue nextlink;
if (n.className.search(/\b(usertool|summary|metadata|.mbox|comment)/) >= 0)
continue nextlink;
}
links.push( link );
}
while (links.length && links[0].parentNode.id.search( /contentSub|jump-to|target/i ) >= 0)
links.shift(); // breadcrumb links
if (links.length && links[0].title == "Wikipedia:FAQ/Categories")
links.shift(); // "learn more" link in cats
return links;
}
function randomLink( links, hops )
{
var continuing = (typeof links == "object" && links == null);
if (typeof links == "undefined" && typeof randomlink_start != "undefined")
links = randomlink_start;
if (typeof hops == "undefined" && typeof randomlink_hops != "undefined")
hops = randomlink_hops;
if (typeof hops == "undefined")
hops = 1;
if (hops > 3) // sanity check
hops = 3;
if (typeof links == "string")
links = links.split("|");
if (typeof links == "object" && links != null) {
for (var i=0; i < links.length; i++)
links[i] = wgArticlePath.replace("$1", encodeURIComponent(links[i]));
hops++;
}
else {
links = scrapeLinks();
}
if (typeof randomlink_debug != "undefined") { // DEBUG
var msg = links.length + " links:";
for (i=0; i < links.length; i++) {
msg += "\n " + links[i];
}
alert( msg );
return;
}
if (links.length == 0) {
alert("I am unable to comply.");
return;
}
var newpage = links[ Math.floor(links.length * Math.random()) ].toString();
if (typeof randomlink_bigcat != "undefined" && randomlink_bigcat && newpage.search(/\/Category[:%]/) >= 0) {
var alphabet = "!abcdefghijklmnoprstuvwy~";
var key = alphabet.charAt(alphabet.length * Math.random()).toUpperCase()
+ alphabet.charAt(alphabet.length * Math.random());
newpage += "?" + (key < "M" ? "from" : "until") + "=" + key;
}
if (--hops > 0) {
newpage += (newpage.indexOf("?") >= 0) ? "&" : "?";
newpage += "random_hops=" + hops;
}
if (typeof randomlink_open != "undefined" && randomlink_open && !continuing)
window.open( newpage );
else
window.location = newpage;
}
addOnloadHook( function()
{
var hops = document.URL.match( /[?&]random_hops=(\d+)/ );
if (hops) randomLink( null, hops[1] );
addPortletLink('p-navigation', 'javascript:randomLink()', 'Random link',
'n-randomlink', 'Follow a randomly chosen link on this page', '@');
});