User:The Editor's Apprentice/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. |
This user script seems to have a documentation page at User:The Editor's Apprentice/randomlink. |
// This script adds a link titled "Random link" to the left sidebar above the standard "Random page" link.
// Clicking the link takes you to a random page linked in the current page or from a given page or
// set of pages.
// Settings
// Use "randomlink_start" to choose a random link from a given page or set of pages rather than
// the current page. This example uses [[Wikipedia:Featured articles]] and
// [[Wikipedia:Featured pictures]].
//randomlink_start = [ "Wikipedia:Featured articles", "Wikipedia:Featured pictures" ];
// Use "randomlink_hops"
//randomlink_hops = 2;
//randomlink_exclude = /^List of/;
randomlink_paged = true; // Get around the fact some special pages are paged
//randomlink_open = true; // if you want to open in new windows
//randomlink_debug = true; // set this, to debug
randomlink_maxfrom = 22000000; // 10-20% less than max page id
randomlink_maxoffset = 950; // en.wikipedia is limited to 1000
// Forked from [[User:GregU]]'s code at [[User:GregU/randomlink.js]], using the November 29, 2021version as a base.
// Forked as GregU has become inactive and no longer maintains the script.
// Last changed by [[User:The Editor's Apprentice]] on August 27, 2022
function scrapeLinks( descend )
{
var topnode = document.getElementById('bodyContent') || document;
var node = document.getElementById('mw-subcategories');
var atags = [];
var links = [];
var nspat = /^(Talk|User|Wik\w+|File|MediaWiki|Template|Help|Category|Portal|Book)( talk)?:/i;
var spec = document.getElementsByClassName(topnode, 'div', 'mw-spcontent');
if (spec.length == 1) topnode = spec[0]; // skip help links at top of specials
if (node && descend)
topnode = node; // pick a sub-category
else
for (var id in {'mw-pages':0, 'mw-category-media':0 }) {
node = document.getElementById( id );
if (node) {
var nodelist = node.getElementsByTagName('a');
for (var i=0; i < nodelist.length; i++)
atags.push( nodelist[i] );
}
}
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(/\b(external|internal|extiw|image)\b/) >= 0)
continue;
if (href.search(/\/Special:|\?(?!.*redirect=|.*from=.*to=)/) >= 0)
continue;
if (mw.config.get('wgIsArticle') && mw.config.get('wgNamespaceNumber') != 14 && title.search(/^(Category|File):|^$|^#/) >= 0)
continue;
if (mw.config.get('wgIsArticle') && mw.config.get('wgNamespaceNumber') == 0 && title.search(nspat) >= 0)
continue;
if ((mw.config.get('wgAction') == "history") != $(link).hasClass("mw-userlink"))
continue;
if (link.hostname != location.hostname) // commons.wikimedia.org on images
continue;
if (link.parentNode.id == "coordinates")
continue; // coords too common, or help link
if (typeof randomlink_exclude != "undefined" && title.search(randomlink_exclude) >= 0)
continue;
// 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|warn)/) >= 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 > 4) // sanity check; 4 needed for Special:AllPages
hops = 4;
if (typeof links == "string" &&
links.search(/^Special:(WhatLinksHere|RecentChangesLinked)$/i) >= 0)
{
links += "/" + mw.config.get('wgPageName') + "?limit=250";
if (mw.config.get('wgNamespaceNumber') == 0)
links += "&namespace=0"; // stay in article space if in it now
}
// Random contrib: Toggles between user, page, user, page, ...
//
if (typeof links == "string" && links == "Special:Contributions")
if (mw.config.get('wgPageName').search(/^User:[^\/]+$/) >= 0)
links += "/" + mw.config.get('wgPageName').slice(5) + "?namespace=0";
else
links = mw.config.get('wgPageName') + "?action=history";
if (typeof links == "string")
links = links.split("|");
if (typeof links == "object" && links != null) {
for (var i=0; i < links.length; i++)
links[i] = mw.config.get('wgArticlePath').replace("$1", links[i]).replace(/ /g, "_");
hops++;
}
else {
links = scrapeLinks( hops > 1 );
}
if (typeof randomlink_debug != "undefined" && randomlink_debug) {
var msg = links.slice(0);
if (msg.length > 36)
msg.splice( 20, msg.length-35, "..." );
alert( links.length + " links:\n " + msg.join("\n "));
}
if (links.length == 0)
return alert("I am unable to comply.");
var newpage = links[ Math.floor(links.length * Math.random()) ].toString();
if (typeof randomlink_paged != "undefined" && randomlink_paged)
newpage = pagedUrl( newpage );
if (mw.config.get('wgCanonicalNamespace') == "Category" && newpage.indexOf("/Category:") == -1)
hops = 1;
if (--hops > 0) {
newpage += (newpage.indexOf("?") >= 0) ? "&" : "?";
newpage += "random_hops=" + hops;
}
// WikiProjects organize by talk pages, but let's end on the subject page.
//
if ((mw.config.get('wgCanonicalNamespace') == "Category" || mw.config.get('wgCanonicalSpecialPageName') == "Whatlinkshere")
&& continuing && hops <= 0)
newpage = newpage.replace("/Talk:", "/").replace("_talk:", ":");
if (typeof randomlink_open != "undefined" && randomlink_open && !continuing)
window.open( newpage );
else
window.location = newpage;
}
function pagedUrl( url )
{
var param = "";
var value;
var alphabet = "!abcdefghijklmnoprstuvwy~";
if (url.indexOf("/Category:") >= 0) {
value = alphabet.charAt(alphabet.length * Math.random()).toUpperCase()
+ alphabet.charAt(alphabet.length * Math.random());
param = (value < "M" ? "from" : "until");
}
if (url.indexOf("Special:WhatLinksHere") >= 0) {
param = "from";
value = Math.floor( randomlink_maxfrom * Math.random() );
// Clustering will hurt randomness, but better than nothing
}
if (url.search(/Special:\w+s\b/) >= 0) {
param = "offset";
value = Math.floor( randomlink_maxoffset * Math.random() );
}
if (param) {
url += (url.indexOf("?") >= 0) ? "&" : "?";
url += param + "=" + encodeURIComponent(value);
}
return url;
}
addOnloadHook( function()
{
var hops = document.URL.match( /[?&]random_hops=(\d+)/ );
if (hops) randomLink( null, hops[1] );
var where = 'this page';
if (typeof randomlink_start != 'undefined')
where = randomlink_start.toString().slice(0,500);
// Set up function for adding portlet (sidebar) links
// Documented at https://doc.wikimedia.org/mediawiki-core/master/js/#!/api/mw.util-method-addPortletLink .
$.when( mw.loader.using( 'mediawiki.util' ), $.ready ).then( function () {
// General usage:
mw.util.addPortletLink( portletId, href, text /*, id, tooltip, accesskey, nextnode */ );
} );
// Add portlet (sidebar) link for following a random link on the left above the standard "Random page" link
var newElement = mw.util.addPortletLink(
'p-navigation',
'javascript:randomLink()',
'Random link',
'n-randomlink',
'Follow a randomly chosen link on ' + where,
'@',
'n-randompage'
);
});