MediaWiki:Common.js
Note: After publishing, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
/* Any JavaScript here will be loaded for all users on every page load. */
( function () {
'use strict';
var CONFIG = {
category: 'Groups',
minBytes: 3000,
dailyStable: true,
blurbChars: 320
};
function init() {
var container = document.getElementById( 'lhc-random-article' );
if ( !container ) {
return;
}
var api = new mw.Api();
api.get( {
action: 'query',
generator: 'categorymembers',
gcmtitle: 'Category:' + CONFIG.category,
gcmnamespace: 0,
gcmtype: 'page',
gcmlimit: 'max',
prop: 'info',
formatversion: 2
} ).then( function ( data ) {
var pages = ( data.query && data.query.pages ) || [];
var candidates = pages.filter( function ( p ) {
return p.length >= CONFIG.minBytes;
} ).sort( function ( a, b ) {
// Stable order matters for the daily-seed pick.
return a.title.localeCompare( b.title );
} );
if ( !candidates.length ) {
return fail( container );
}
var pick = candidates[ pickIndex( candidates.length ) ];
return loadArticle( api, container, pick.title );
} ).catch( function () {
fail( container );
} );
}
function pickIndex( n ) {
if ( !CONFIG.dailyStable ) {
return Math.floor( Math.random() * n );
}
var d = new Date();
var key = '' + d.getUTCFullYear() + d.getUTCMonth() + d.getUTCDate();
var h = 2166136261;
for ( var i = 0; i < key.length; i++ ) {
h = ( h ^ key.charCodeAt( i ) ) * 16777619 >>> 0;
}
return h % n;
}
function loadArticle( api, container, title ) {
return api.get( {
action: 'parse',
page: title,
prop: 'text',
section: 0,
redirects: 1,
formatversion: 2
} ).then( function ( data ) {
var html = data.parse && data.parse.text;
if ( !html ) {
return fail( container );
}
var doc = new DOMParser().parseFromString( html, 'text/html' );
render( container, {
title: title,
image: extractImage( doc ),
blurb: extractBlurb( doc )
} );
} );
}
function extractImage( doc ) {
var img = doc.querySelector(
'.infobox img, .infobox-image img, table.infobox img'
) || doc.querySelector( 'img' );
if ( !img ) {
return null;
}
var src = img.getAttribute( 'src' );
if ( !src ) {
return null;
}
// Parser output uses protocol-relative or root-relative paths.
if ( src.indexOf( '//' ) === 0 ) {
return location.protocol + src;
}
if ( src.indexOf( '/' ) === 0 ) {
return location.origin + src;
}
return src;
}
function extractBlurb( doc ) {
var junk = doc.querySelectorAll(
'table, .infobox, .navbox, .hatnote, .thumb, ' +
'sup.reference, .mw-editsection, .noexcerpt, style'
);
Array.prototype.forEach.call( junk, function ( el ) {
el.parentNode.removeChild( el );
} );
var paras = doc.querySelectorAll( 'p' );
for ( var i = 0; i < paras.length; i++ ) {
var text = paras[ i ].textContent.replace( /\s+/g, ' ' ).trim();
if ( text.length > 40 ) {
return truncate( text, CONFIG.blurbChars );
}
}
return null;
}
function truncate( text, max ) {
if ( text.length <= max ) {
return text;
}
var cut = text.slice( 0, max );
var space = cut.lastIndexOf( ' ' );
return ( space > 0 ? cut.slice( 0, space ) : cut ) + '…';
}
function render( container, article ) {
var href = mw.util.getUrl( article.title );
var wrap = document.createElement( 'div' );
wrap.className = 'lhc-ra';
if ( article.image ) {
var link = document.createElement( 'a' );
link.href = href;
var img = document.createElement( 'img' );
img.src = article.image;
img.alt = article.title;
img.className = 'lhc-ra-image';
link.appendChild( img );
wrap.appendChild( link );
}
var body = document.createElement( 'div' );
body.className = 'lhc-ra-body';
var heading = document.createElement( 'div' );
heading.className = 'lhc-ra-title';
var titleLink = document.createElement( 'a' );
titleLink.href = href;
titleLink.textContent = article.title;
heading.appendChild( titleLink );
body.appendChild( heading );
if ( article.blurb ) {
var p = document.createElement( 'p' );
p.className = 'lhc-ra-blurb';
p.textContent = article.blurb;
body.appendChild( p );
}
var more = document.createElement( 'a' );
more.href = href;
more.className = 'lhc-ra-more';
more.textContent = 'Read the full article →';
body.appendChild( more );
wrap.appendChild( body );
container.textContent = '';
container.appendChild( wrap );
}
function fail( container ) {
var a = document.createElement( 'a' );
a.href = mw.util.getUrl(
'Special:RandomInCategory/' + CONFIG.category
);
a.textContent = 'Show me a random article';
container.textContent = '';
container.appendChild( a );
}
mw.loader.using( [ 'mediawiki.api', 'mediawiki.util' ] ).then( function () {
if ( document.readyState !== 'loading' ) {
init();
} else {
document.addEventListener( 'DOMContentLoaded', init );
}
} );
}() );