Difference between revisions of "MediaWiki:Common.js"
m (Oopsie...) |
(Add code to create a ToC in card galleries. Spacing.) |
||
Line 9: | Line 9: | ||
* this simplifies checking if new code has cleared server caches | * this simplifies checking if new code has cleared server caches | ||
*/ | */ | ||
− | var LAST_LOG = ' | + | var LAST_LOG = '13:49, 22 May 2018 (UTC)'; |
console.log('MediaWiki:Common.js last updated:', LAST_LOG); | console.log('MediaWiki:Common.js last updated:', LAST_LOG); | ||
Line 461: | Line 461: | ||
* Contact [[User talk:Becasita]] if the need arises. | * Contact [[User talk:Becasita]] if the need arises. | ||
*/ | */ | ||
− | (function($, mw) { | + | ( function( window, $, mw ) { |
/** | /** | ||
Line 467: | Line 467: | ||
* Address to «.JS-changed» to find what elements were changed/created. | * Address to «.JS-changed» to find what elements were changed/created. | ||
*/ | */ | ||
− | $(function _specialAskLabelsLinks() { | + | $( function _specialAskLabelsLinks() { |
− | if(mw.config.get('wgPageName').split(/\s*\/\s*/)[0] === 'Special:Ask') { | + | if ( mw.config.get( 'wgPageName' ).split( /\s*\/\s*/ )[ 0 ] === 'Special:Ask' ) { |
− | $('.smwtable').find('th').each(function(i,el) { | + | $( '.smwtable' ).find( 'th' ).each( function( i, el ) { |
− | $(el).html(function() { | + | $( el ).html( function() { |
− | return $(this).text().replace(/\[\[(.*?)]]/g, $('<a>', { | + | return $( this ).text().replace( /\[\[(.*?)]]/g, $( '<a>', { |
class: 'JS-changed', | class: 'JS-changed', | ||
href: 'wiki/$1', | href: 'wiki/$1', | ||
text: '$1' | text: '$1' | ||
− | }).prop('outerHTML')); | + | } ).prop( 'outerHTML' ) ); |
− | }); | + | } ); |
− | }); | + | } ); |
} | } | ||
− | }); | + | } ); |
/** End. */ | /** End. */ | ||
Line 487: | Line 487: | ||
$(function _fixTabAnchors() { | $(function _fixTabAnchors() { | ||
// Wait for the tabbers to load: | // Wait for the tabbers to load: | ||
− | mw.loader.using('ext.tabber').then(function() { | + | mw.loader.using( 'ext.tabber' ).then( function() { |
− | mw.log('DEBUG: Tabbers loaded!'); | + | mw.log( 'DEBUG: Tabbers loaded!' ); |
− | $('.tabbernav').each(function( | + | $( '.tabbernav' ).each( function( i, el ) { |
− | const $el = $(el); | + | const $el = $( el ); |
const $parent = $el.parent(); | const $parent = $el.parent(); | ||
// Gets the tab content, given a tab label: | // Gets the tab content, given a tab label: | ||
− | const getTab = function($li) { | + | const getTab = function( $li ) { |
− | return $parent.find('.tabbertab').filter(function() { | + | return $parent.find( '.tabbertab' ).filter( function() { |
− | return this.title.trim() === $li.find('a').attr('title').trim(); | + | return this.title.trim() === $li.find( 'a' ).attr( 'title' ).trim(); |
}); | }); | ||
}; | }; | ||
// Remove the default click event: | // Remove the default click event: | ||
− | $el.off('click'); | + | $el.off( 'click' ); |
// Create new click event | // Create new click event | ||
− | $el.children().click(function(e) { | + | $el.children().click( function( e ) { |
e.preventDefault(); | e.preventDefault(); | ||
// Current tab: | // Current tab: | ||
− | const $currentLabel = $el.find('.tabberactive'); | + | const $currentLabel = $el.find( '.tabberactive' ); |
− | const $currentContent = getTab($currentLabel); | + | const $currentContent = getTab( $currentLabel ); |
// New tab: | // New tab: | ||
− | const $newLabel = $(this); | + | const $newLabel = $( this ); |
− | const $newContent = getTab($newLabel); | + | const $newContent = getTab( $newLabel ); |
// Switch tabs: | // Switch tabs: | ||
− | $currentLabel.removeClass('tabberactive'); | + | $currentLabel.removeClass( 'tabberactive' ); |
− | $newLabel.addClass('tabberactive'); | + | $newLabel.addClass( 'tabberactive' ); |
$currentContent.hide(); | $currentContent.hide(); | ||
$newContent.show(); | $newContent.show(); | ||
− | }); | + | } ); |
+ | |||
+ | } ); | ||
− | + | } ); | |
+ | } ); | ||
+ | /** End. */ | ||
− | }); | + | /** |
− | }); | + | * Create a ToC for card galleries (using [[Module:Card gallery]]). |
+ | */ | ||
+ | $( function _addTocToCardGalleries() { | ||
+ | $( '.mw-headline' ).each( function() { | ||
+ | const sectionName = $( this ).text(); | ||
+ | $( '.card-gallery-toc' ).find( 'ul' ).append( | ||
+ | $( '<li>', { | ||
+ | class: 'toc-entry', | ||
+ | html: $( '<a>', { | ||
+ | href: '#' + sectionName.replace( ' ', '_' ), | ||
+ | text: sectionName | ||
+ | } ) | ||
+ | } ) | ||
+ | ); | ||
+ | } ); | ||
+ | } ); | ||
/** End. */ | /** End. */ | ||
Line 534: | Line 553: | ||
*/ | */ | ||
$(function _linkEmptyGalleries() { | $(function _linkEmptyGalleries() { | ||
− | const action = mw.util.getParamValue('action'); | + | const action = mw.util.getParamValue( 'action' ); |
− | const nsNumber = mw.config.get('wgNamespaceNumber'); | + | const nsNumber = mw.config.get( 'wgNamespaceNumber' ); |
// Function to link the empty galleries to the upload page: | // Function to link the empty galleries to the upload page: | ||
const linkEmptyGalleries = function() { | const linkEmptyGalleries = function() { | ||
− | $('.thumb').each(function() { | + | $( '.thumb' ).each( function() { |
− | const $this = $(this); | + | const $this = $( this ); |
− | if(!$this.children().length) { | + | if ( !$this.children().length ) { |
// Is an empty gallery box. | // Is an empty gallery box. | ||
const text = $this.text(); | const text = $this.text(); | ||
− | $this.text(''); | + | $this.text( '' ); |
$this.append( | $this.append( | ||
− | $('<a>', { | + | $( '<a>', { |
class: 'noFile', | class: 'noFile', | ||
href: '/index.php?title=Special:Upload&wpDestFile=' + text, | href: '/index.php?title=Special:Upload&wpDestFile=' + text, | ||
text: text | text: text | ||
− | }) | + | } ) |
); | ); | ||
} | } | ||
− | }); | + | } ); |
}; | }; | ||
Line 560: | Line 579: | ||
// Check if there were changes in the DOM to keep the links alive (when previewing edits, etc.): | // Check if there were changes in the DOM to keep the links alive (when previewing edits, etc.): | ||
− | if(window.MutationObserver && ['edit', 'submit'].includes(action)) { | + | if ( window.MutationObserver && [ 'edit', 'submit' ].includes( action ) ) { |
// Wait for the editor to load: | // Wait for the editor to load: | ||
− | mw.loader.using('jquery.wikiEditor').then(function() { | + | mw.loader.using( 'jquery.wikiEditor' ).then( function() { |
// (jQuery) Node to observe: | // (jQuery) Node to observe: | ||
− | const $targetNode = $('.wikiEditor-ui-view-preview').find('.wikiEditor-preview-contents'); | + | const $targetNode = $( '.wikiEditor-ui-view-preview' ).find( '.wikiEditor-preview-contents' ); |
// Options for the observer (which mutations to observe). | // Options for the observer (which mutations to observe). | ||
Line 577: | Line 596: | ||
// Create an observer instance and observe: | // Create an observer instance and observe: | ||
− | new MutationObserver(function(mutationsList) { | + | new MutationObserver( function( mutationsList ) { |
// No need to iterate over mutationList, | // No need to iterate over mutationList, | ||
// since we just want to execute the following function once. | // since we just want to execute the following function once. | ||
//console.log('Linking...'); | //console.log('Linking...'); | ||
linkEmptyGalleries(); | linkEmptyGalleries(); | ||
− | }).observe($targetNode.get(0), options); | + | } ).observe( $targetNode.get( 0 ), options ); |
− | }); | + | } ); |
} | } | ||
− | }); | + | } ); |
/** End. */ | /** End. */ | ||
− | })(window.jQuery, window.mediaWiki); | + | } )( window, window.jQuery, window.mediaWiki ); |
/* End of mw.loader.using callback; DO NOT ADD CODE BELOW THIS LINE */ | /* End of mw.loader.using callback; DO NOT ADD CODE BELOW THIS LINE */ | ||
}); | }); |
Revision as of 13:49, 22 May 2018
/*global mw, $, console, enableOldForumEdit */
/*jshint browser:true, curly:false, eqnull:true, strict:false */
mw.loader.using(['mediawiki.util', 'jquery.client'], function () {
/* Begin of mw.loader.using callback */
/**
* update this (replace the timestamp with 5 tildes) whenever this page is edited
* this simplifies checking if new code has cleared server caches
*/
var LAST_LOG = '13:49, 22 May 2018 (UTC)';
console.log('MediaWiki:Common.js last updated:', LAST_LOG);
/**
* dev:LastEdited customization
* see [[w:c:dev:LastEdited#Customization]] for documentation/more options
*/
window.lastEdited = {
namespaces: { /* [[User:Dinoguy1000/namespaces]] has a full list */
include: [ 102, 103, /* Property (SMW) */
106, 107, /* Form (SMW) */
108, 109, /* Concept (SMW) */
170, 171, /* Filter */
3000, 3001, /* Portal */
3004, 3005, /* Gallery */
3006, 3007, /* Set List */
3008, 3009, /* Rulings */
3010, 3011, /* Errata */
3012, 3013, /* Artworks */
3014, 3015, /* Tips */
3016, 3017, /* Trivia */
3018, 3019, /* Appearances */
3020, 3021, /* Names */
3022, 3023, /* Lores */
3024, 3025, /* Set Gallery */ ]
}
};
/**
* Load Dev scripts and whatnot
* at [[MediaWiki:ImportJS]]
*/
/**
* Collapsible tables
*
* Allows tables to be collapsed, showing only the header. See [[Help:Collapsing]].
*
* @version 2.0.3 (2014-03-14)
* @source https://www.mediawiki.org/wiki/MediaWiki:Gadget-collapsibleTables.js
* @author [[User:R. Koot]]
* @author [[User:Krinkle]]
*/
var autoCollapse = 2,
collapseCaption = 'hide',
expandCaption = 'show',
tableIndex = 0;
function collapseTable( tableIndex ) {
var Button = document.getElementById( 'collapseButton' + tableIndex ),
Table = document.getElementById( 'collapsibleTable' + tableIndex );
if ( !Table || !Button ) {
return false;
}
var Rows = Table.rows,
i,
$row0 = $(Rows[0]);
if ( Button.firstChild.data === collapseCaption ) {
for ( i = 1; i < Rows.length; i++ ) {
Rows[i].style.display = 'none';
}
Button.firstChild.data = expandCaption;
} else {
for ( i = 1; i < Rows.length; i++ ) {
Rows[i].style.display = $row0.css( 'display' );
}
Button.firstChild.data = collapseCaption;
}
}
function createClickHandler( tableIndex ) {
return function ( e ) {
e.preventDefault();
collapseTable( tableIndex );
};
}
function createCollapseButtons( $content ) {
var NavigationBoxes = {},
$Tables = $content.find( 'table' ),
i;
$Tables.each( function( i, table ) {
if ( $(table).hasClass( 'collapsible' ) ) {
/* only add button and increment count if there is a header row to work with */
var HeaderRow = table.getElementsByTagName( 'tr' )[0];
if ( !HeaderRow ) {
return;
}
var Header = table.getElementsByTagName( 'th' )[0];
if ( !Header ) {
return;
}
NavigationBoxes[ tableIndex ] = table;
table.setAttribute( 'id', 'collapsibleTable' + tableIndex );
var Button = document.createElement( 'span' ),
ButtonLink = document.createElement( 'a' ),
ButtonText = document.createTextNode( collapseCaption );
// Styles are declared in [[MediaWiki:Common.css]]
Button.className = 'collapseButton';
ButtonLink.style.color = Header.style.color;
ButtonLink.setAttribute( 'id', 'collapseButton' + tableIndex );
ButtonLink.setAttribute( 'href', '#' );
$( ButtonLink ).on( 'click', createClickHandler( tableIndex ) );
ButtonLink.appendChild( ButtonText );
Button.appendChild( document.createTextNode( '[' ) );
Button.appendChild( ButtonLink );
Button.appendChild( document.createTextNode( ']' ) );
Header.insertBefore( Button, Header.firstChild );
tableIndex++;
}
} );
for ( i = 0; i < tableIndex; i++ ) {
if ( $( NavigationBoxes[i] ).hasClass( 'collapsed' ) ||
( tableIndex >= autoCollapse && $( NavigationBoxes[i] ).hasClass( 'autocollapse' ) )
) {
collapseTable( i );
}
else if ( $( NavigationBoxes[i] ).hasClass ( 'innercollapse' ) ) {
var element = NavigationBoxes[i];
while ((element = element.parentNode)) {
if ( $( element ).hasClass( 'outercollapse' ) ) {
collapseTable ( i );
break;
}
}
}
}
}
mw.hook( 'wikipage.content' ).add( createCollapseButtons );
/*** end copied from [[wikipedia:MediaWiki:Common.js]] ***/
/**
* Archive edit tab/button disabling
*
* Disables the edit tab/button on discussion pages to stop people bumping old forum threads or editing archive pages.
* Page can still be edited by going via the edit tab on the history etc, or by
* typing the edit address manually.
* By [[User:Spang|Spang]]
* Wikia (Oasis) support by [[User:Uberfuzzy|Uberfuzzy]]
*/
function disableEditLink() {
var ns = mw.config.get('wgNamespaceNumber'),
skin = mw.config.get('skin');
if (ns !== 110 && ns !== 2 && ns % 2 !== 1) { return; }
if (
(skin !== 'vector' && skin !== 'monobook') || // need to look into MinervaNeue
$.inArray('sysop', mw.config.get('wgUserGroups')) > -1 || // disable completely for admins
typeof enableOldForumEdit !== 'undefined' ||
!$('#archived-edit-link')[0]
) { return; }
var editLink = $('#ca-edit a');
if (!editLink[0]) { return; }
editLink.html('Archived').removeAttr('href').removeAttr('title').css({'color':'gray','cursor':'auto'});
$('span.editsection-upper').remove();
}
$(disableEditLink);
/**
* Cleanup excessive space in hlist elements
*/
var items = document.querySelectorAll('.hlist li, .hlist dt, .hlist dd');
for (var i = items.length - 1; i >= 0; i--) {
items[i].innerHTML = items[i].innerHTML.trim();
}
/**
* Page format checking
*
* Maintainers: [[User:Falzar FZ]]
*/
var mNamespace = mw.config.get('wgCanonicalNamespace'),
mNamespaceNumber = mw.config.get('wgNamespaceNumber'),
mAction = mw.util.getParamValue('action'),
mSection = mw.util.getParamValue('section');
/*
* Check that you have signed your post on Talk pages and Forum pages.
* Disable for yourself on every page by adding:
var signCheck = 'Disable';
to [[Special:MyPage/common.js]]
* Alternatively, if you sign with 3 tildes, add:
var signCheck = 3;
* To disable checking on a specific page for everyone, add:
<!--~~~~-->
to that page somewhere, it will overlook it each time.
*/
if (mNamespaceNumber % 2 === 1 || mNamespaceNumber === 110) {
if (!document.URL.match('&undo') && !document.URL.match('/Archive')) {
$(function() {
$('#wpSave, #wpPreview').mousedown(signChecker);
});
var vSignCheckerCounter = 0,
mInitialLength = $('#wpTextbox1').val().length;
function signChecker() {
var vTildes = '~~\~~',
// Bypassing the line in the forum template.
vForumMessage = 'Be sure to sign your edits with four tildes: ' + vTildes,
vNoWiki = '<nowiki>' + vTildes + '</nowiki>',
vMinorChecked = $('#wpMinoredit').is(':checked'),
mFinalLength = $('#wpTextbox1').val().length,
vText = $('#wpTextbox1').val().replace(vForumMessage, '').replace(vNoWiki, '');
if (vSignCheckerCounter < 3 && !vText.match(vTildes) &&
!vText.match('{\{[Tt]alk ?header}}') && !vText.match('{\{[Dd]elete') &&
!vMinorChecked && !$('#wpSummary').val().match(/move/i) &&
!$('#wpSummary').val().match(/archive/i) &&
mFinalLength > mInitialLength + 15) {
vSignCheckerCounter++;
if (!window.signCheck) {
alert('Please sign your post by adding 4 tildes (' + vTildes + ') to the end of your post.');
} else if (window.signCheck === 3) {
alert('Please sign your post by adding 3 tildes (~\~~) to the end of your post.');
} else if (window.signCheck === 'Disable') {
vSignCheckerCounter = 9;
}
}
}
}
}
/**
* Add Template:Navigation if it's not there.
*/
if (
(mNamespace === 'Card_Rulings' && $('#wpTextbox1').val().indexOf('[\[Category:Group Rulings') === -1) ||
['Gallery', 'Errata', 'Tips', 'Appearances', 'Trivia', 'Lores', 'Artworks', 'Names', 'Sets']
.indexOf(mNamespace.replace('Card_', '')) !== -1
) {
if (!mSection && mAction !== 'submit' && typeof $('#wpTextbox1').val() !== 'undefined') {
$(addNav);
function addNav() {
var vText = $('#wpTextbox1').val()
.replace('{\{navigation', '{\{Navigation')
.replace('{\{Navigation2}', '{\{Navigation|mode=nonGame}');
if (!vText.match('{\{Navigation') && !vText.match('{\{Delete')) {
$('#wpTextbox1').val('{\{Navigation}}\n\n' + vText);
} else {
$('#wpTextbox1').val(vText);
}
$('form[name=editform]').submit(function() {
if ($('#wpTextbox1').val() === '{\{Navigation}}\n\n') {
alert('You have not made any changes to the template.');
return false;
}
});
}
}
}
/**
* Add Template:Talkheader if it's not there.
*/
if (mNamespaceNumber % 2 === 1 && mNamespaceNumber !== 3 && !mSection && mAction !== 'submit') {
$(addTalkheader);
function addTalkheader() {
var vText = $('#wpTextbox1').val().replace(/{\{[Tt]alkheader/, '{\{Talk header');
if (!vText.match('{\{Talk header') && !vText.match('{\{Delete')) {
$('#wpTextbox1').val('{\{Talk header}}\n\n' + vText);
} else {
$('#wpTextbox1').val(vText);
}
}
}
/**
* Add a preload depending on the namespace during page creation from redlink.
*/
if (mw.util.getParamValue('redlink')) {
var vPreloadText = '';
switch (mNamespace) {
case 'Card_Tips': // fallthrough
case 'Card_Trivia': // fallthrough
case 'Card_Names':
vPreloadText += '* '; // Deliberate no "\n" at the end.
break;
case 'Card_Gallery':
vPreloadText += '{\{GalleryHeader|lang=en}}\n<gallery widths="175px">\n' +
'Image.png | [[Card Number]] ([[Rarity]])<br />\'\'([[Edition]])\'\'<br />[[Set Name]]\n</gallery>\n|}\n\n' +
'{\{GalleryHeader|lang=jp|set=Anime}}\n<gallery widths="175px">\nImage.png | [[]]\n</gallery>\n|}\n';
break;
case 'Card_Appearances':
vPreloadText += '* In [[Yu-Gi-Oh! VRAINS - Episode 000|episode 00]], [[character name]] plays this card ' +
'against [[opponent name]].\n';
break;
case 'Card_Errata':
vPreloadText += '{\{Errata table\n| lore0 = \n| image0 = \n| cap0 = [[Card Number]]<br />' +
'[[Set Name]]\n\n| lore1 = \n| image1 = \n| cap1 = [[Card Number]]<br />[[Set Name]]\n}}\n';
break;
case 'Card_Artworks':
vPreloadText += '* \n\n{\{ArtworkHeader|lang=jp}}\n<gallery widths="275px">\n' +
'Image.png | Japanese\nImage.png | International\n</gallery>\n|}\n';
break;
}
if (vPreloadText !== '') {
$(addPreload('{\{Navigation}}\n\n' + vPreloadText));
}
function addPreload(pBlankTemplate) {
$('#wpTextbox1').val(pBlankTemplate);
$('#wpSave, #wpPreview').mousedown(cleanUpStuff);
function cleanUpStuff() {
$('#wpTextbox1').val($('#wpTextbox1').val()
.replace('{\{Navigation2}}', '{\{Navigation|mode=nonGame}}')
.replace('{\{Navigation3}}', '{\{Navigation|mode=otherGame}}')
);
}
$('form[name=editform]').submit(function() {
if ($('#wpTextbox1').val() === pBlankTemplate) {
alert('You have not made any changes to the template.');
return false;
}
});
}
}
/**
* Add missing preload to [[MediaWiki:Createbox-exists]].
* Using js since there doesn't seem to be a "getURL" option in the wikia magic words.
*/
if (mAction === 'create' && $('[name="preload"]').val() === '') {
$('[name="preload"]').val(mw.util.getParamValue('preload'));
}
/**
* Remove empty rows from {{Infobox}} transclusions
*/
$('.infobox tr').each(function () {
if (
!$.trim($(this).text()) &&
!$(this).find('img').length &&
!$(this).find('hr').length
) {
$(this).remove();
}
});
/**
* Allow for redirecting Luster_Dragon#2 to Luster_Dragon_2 etc. via {{Hash redirect}}
*/
if ($('.hash_redirect')) {
var redirects = document.getElementsByClassName('hash_redirect');
var hash = window.location.hash.substring(1);
for (var k = 0; k < redirects.length; k++) {
if (redirects[k].getAttribute('data-value') === hash) {
window.location = window.location.href.replace('#', '_');
}
}
}
/**
* Show card details on hover
*/
$('.card-link').on('mouseenter', function() {
if (! document.getElementById('main-card-table')) {
$(this).find('.card-link-hover-data').load(
this.getElementsByTagName('a')[0].href + ' #main-card-table', function() {
$(this).find('.chronology').remove();
}
);
}
});
$('.card-link').on('mouseleave', function() {
$('.card-link-hover-data').html('');
});
/**
* Image switcher for card tables
*/
$('.image-switcher a').on('click', function(ev) {
ev.preventDefault();
var $imagecolumn = $(this).parents('.imagecolumn'),
$selected = $(this).parents('.image-dimensions'),
$image_wrapper = $imagecolumn.find('.cardtable-main_image-wrapper'),
$main_image = $image_wrapper.find('img:first'),
image_name = this.getAttribute('title'),
// Images are not to go wider than the first one.
max_width = $imagecolumn.data('max_width') ? $imagecolumn.data('max_width') : $main_image.width(),
// Natural dimensions of the selected image
n_width = $selected.data('width'),
n_height = $selected.data('height'),
// Dimensions to display the selected image at
width = (n_width < max_width) ? n_width : max_width,
height = (n_width < max_width) ? n_height : n_height * width / n_width,
src = this.href;
/*srcset = [1.5, 2].map(function(ratio) {
return src.replace('\.com//', '$&thumb/') + '/' + Math.round(width * ratio) + 'px-' + image_name + ' ' + ratio + 'x';
}).join();*/
if (width !== n_width) {
src = '/thumb.php?f=' + image_name + '&w=' + width;
}
// Preventing content jumping
$imagecolumn.css('width', max_width);
$imagecolumn.find('\+.infocolumn').css('width', 'calc(100% - '+max_width+'px)');
$image_wrapper.css('min-height', $image_wrapper.height());
var img = new Image();
img.onload = function() {
// Change the main image's URL to the new image and set its width and height
$main_image
.attr('src', src)
//.attr('srcset', srcset)
.attr('width', width)
.attr('height', height)
.removeAttr('srcset');
// Change the main image's link and hover text to match the new image
$main_image.parents('a')
.attr('href', '/wiki/File:'+image_name)
.attr('title', image_name);
};
img.src = src;
});
/**
* The following code is currently maintained by [[User:Becasita]].
* Contact [[User talk:Becasita]] if the need arises.
*/
( function( window, $, mw ) {
/**
* Fix Special:Ask table headers when wikilinked.
* Address to «.JS-changed» to find what elements were changed/created.
*/
$( function _specialAskLabelsLinks() {
if ( mw.config.get( 'wgPageName' ).split( /\s*\/\s*/ )[ 0 ] === 'Special:Ask' ) {
$( '.smwtable' ).find( 'th' ).each( function( i, el ) {
$( el ).html( function() {
return $( this ).text().replace( /\[\[(.*?)]]/g, $( '<a>', {
class: 'JS-changed',
href: 'wiki/$1',
text: '$1'
} ).prop( 'outerHTML' ) );
} );
} );
}
} );
/** End. */
/**
* Fix tabbers labels achors.
*/
$(function _fixTabAnchors() {
// Wait for the tabbers to load:
mw.loader.using( 'ext.tabber' ).then( function() {
mw.log( 'DEBUG: Tabbers loaded!' );
$( '.tabbernav' ).each( function( i, el ) {
const $el = $( el );
const $parent = $el.parent();
// Gets the tab content, given a tab label:
const getTab = function( $li ) {
return $parent.find( '.tabbertab' ).filter( function() {
return this.title.trim() === $li.find( 'a' ).attr( 'title' ).trim();
});
};
// Remove the default click event:
$el.off( 'click' );
// Create new click event
$el.children().click( function( e ) {
e.preventDefault();
// Current tab:
const $currentLabel = $el.find( '.tabberactive' );
const $currentContent = getTab( $currentLabel );
// New tab:
const $newLabel = $( this );
const $newContent = getTab( $newLabel );
// Switch tabs:
$currentLabel.removeClass( 'tabberactive' );
$newLabel.addClass( 'tabberactive' );
$currentContent.hide();
$newContent.show();
} );
} );
} );
} );
/** End. */
/**
* Create a ToC for card galleries (using [[Module:Card gallery]]).
*/
$( function _addTocToCardGalleries() {
$( '.mw-headline' ).each( function() {
const sectionName = $( this ).text();
$( '.card-gallery-toc' ).find( 'ul' ).append(
$( '<li>', {
class: 'toc-entry',
html: $( '<a>', {
href: '#' + sectionName.replace( ' ', '_' ),
text: sectionName
} )
} )
);
} );
} );
/** End. */
/**
* Links for image uploads on galleries.
*/
$(function _linkEmptyGalleries() {
const action = mw.util.getParamValue( 'action' );
const nsNumber = mw.config.get( 'wgNamespaceNumber' );
// Function to link the empty galleries to the upload page:
const linkEmptyGalleries = function() {
$( '.thumb' ).each( function() {
const $this = $( this );
if ( !$this.children().length ) {
// Is an empty gallery box.
const text = $this.text();
$this.text( '' );
$this.append(
$( '<a>', {
class: 'noFile',
href: '/index.php?title=Special:Upload&wpDestFile=' + text,
text: text
} )
);
}
} );
};
// Execute it:
linkEmptyGalleries();
// Check if there were changes in the DOM to keep the links alive (when previewing edits, etc.):
if ( window.MutationObserver && [ 'edit', 'submit' ].includes( action ) ) {
// Wait for the editor to load:
mw.loader.using( 'jquery.wikiEditor' ).then( function() {
// (jQuery) Node to observe:
const $targetNode = $( '.wikiEditor-ui-view-preview' ).find( '.wikiEditor-preview-contents' );
// Options for the observer (which mutations to observe).
// We only want to see when content is loaded from the backed
// and then appended.
// Therefore, observe when new child nodes are placed or removed:
const options = {
childList: true
};
// Create an observer instance and observe:
new MutationObserver( function( mutationsList ) {
// No need to iterate over mutationList,
// since we just want to execute the following function once.
//console.log('Linking...');
linkEmptyGalleries();
} ).observe( $targetNode.get( 0 ), options );
} );
}
} );
/** End. */
} )( window, window.jQuery, window.mediaWiki );
/* End of mw.loader.using callback; DO NOT ADD CODE BELOW THIS LINE */
});