MediaWiki:Vector-2022.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.
/* All JavaScript here will be loaded for users of the Vector skin */
/* Second logo in the header, linking to www.linn.co.uk */
mw.loader.using( 'mediawiki.util' ).then( function () {
var start = document.querySelector( '.vector-header-start' );
if ( !start || document.getElementById( 'linn-site-logo' ) ) {
return;
}
var link = document.createElement( 'a' );
link.id = 'linn-site-logo';
link.href = 'https://www.linn.co.uk/';
link.title = 'Linn – www.linn.co.uk';
link.target = '_blank';
link.rel = 'noopener';
var img = document.createElement( 'img' );
img.src = mw.config.get( 'wgScriptPath' ) + '/images/Linn_Logo.png';
img.alt = 'Linn';
link.appendChild( img );
start.appendChild( link );
} );
/* In-page table of contents for Vector 2022 (in addition to the sidebar) */
$( function () {
var content = document.querySelector( '#mw-content-text .mw-parser-output' );
if ( !content || document.getElementById( 'toc' ) ) {
return;
}
// MediaWiki leaves this marker where the TOC belongs; none means no TOC
// (e.g. __NOTOC__, or fewer than four headings without __FORCETOC__)
var marker = content.querySelector( 'meta[property="mw:PageProp/toc"]' );
if ( !marker ) {
return;
}
var headings = content.querySelectorAll( 'h2[id], h3[id], h4[id], h5[id], h6[id]' );
if ( !headings.length ) {
return;
}
var levels = Array.prototype.map.call( headings, function ( h ) {
return Number( h.tagName.charAt( 1 ) );
} );
var base = Math.min.apply( null, levels );
var root = document.createElement( 'ul' );
var stack = [ root ];
var nums = [];
Array.prototype.forEach.call( headings, function ( h, i ) {
var depth = levels[ i ] - base;
while ( stack.length - 1 > depth ) {
stack.pop();
}
while ( stack.length - 1 < depth ) {
var parent = stack[ stack.length - 1 ];
var lastLi = parent.lastElementChild || parent.appendChild( document.createElement( 'li' ) );
stack.push( lastLi.appendChild( document.createElement( 'ul' ) ) );
}
nums.length = depth + 1;
nums[ depth ] = ( nums[ depth ] || 0 ) + 1;
var li = document.createElement( 'li' );
li.className = 'toclevel-' + ( depth + 1 );
var a = document.createElement( 'a' );
a.href = '#' + h.id;
var num = document.createElement( 'span' );
num.className = 'tocnumber';
num.textContent = nums.map( function ( n ) { return n || 1; } ).join( '.' );
var text = document.createElement( 'span' );
text.className = 'toctext';
text.textContent = h.textContent.trim();
a.appendChild( num );
a.appendChild( document.createTextNode( ' ' ) );
a.appendChild( text );
li.appendChild( a );
stack[ stack.length - 1 ].appendChild( li );
} );
var toc = document.createElement( 'div' );
toc.id = 'toc';
toc.className = 'toc';
toc.setAttribute( 'role', 'navigation' );
var title = document.createElement( 'div' );
title.className = 'toctitle';
title.textContent = 'Contents';
toc.appendChild( title );
toc.appendChild( root );
marker.parentNode.replaceChild( toc, marker );
} );
/* PIN Hamburger menu if no TOC */
$( function () {
const html = document.documentElement;
// Page has a TOC, so leave the sidebar alone
if ( document.getElementById( 'vector-toc' ) ) {
return;
}
// Main menu is already pinned
if ( html.classList.contains( 'vector-feature-main-menu-pinned-enabled' ) ) {
return;
}
const isReady = () =>
html.classList.contains( 'vector-animations-ready' ) ||
document.body.classList.contains( 'vector-animations-ready' );
const pin = () => {
const btn = document.querySelector(
'[data-event-name="pinnable-header.vector-main-menu.pin"]'
);
if ( btn ) {
btn.click();
}
};
if ( isReady() ) {
pin();
return;
}
// Wait until Vector's own JS has finished setting up
const obs = new MutationObserver( () => {
if ( isReady() ) {
obs.disconnect();
pin();
}
} );
obs.observe( html, { attributes: true, attributeFilter: [ 'class' ] } );
obs.observe( document.body, { attributes: true, attributeFilter: [ 'class' ] } );
} );