MediaWiki:Gadget-multiple-category-boxes.js
Uwaga: aby zobaczyć zmiany po opublikowaniu, może zajść potrzeba wyczyszczenia pamięci podręcznej przeglądarki.
- Firefox / Safari: Przytrzymaj Shift podczas klikania Odśwież bieżącą stronę, lub naciśnij klawisze Ctrl+F5, lub Ctrl+R (⌘-R na komputerze Mac)
- Google Chrome: Naciśnij Ctrl-Shift-R (⌘-Shift-R na komputerze Mac)
- Internet Explorer / Edge: Przytrzymaj Ctrl, jednocześnie klikając Odśwież, lub naciśnij klawisze Ctrl+F5
- Opera: Naciśnij klawisze Ctrl+F5.
/**
* Umieszczanie listy kategorii pod każdą sekcją językową
* Autor: Peter Bowman @ plwikt
*/
var gadget = mw.libs.multipleCategoryBoxes = {},
config = mw.config.get( [
'wgFormattedNamespaces',
'wgPageName',
'wgArticlePath'
] );
function stripCategoryNamespace( title ) {
return title.slice( config.wgFormattedNamespaces[ 14 ].length + 1 );
}
function testCatboxId( $catbox ) {
var id = $catbox.attr( 'id' ).slice( 'catlinks-'.length );
return id in gadget.sections;
}
function processCategoryInfo( data ) {
$.each( data.query.pages[ 0 ].categories, function ( i, cat ) {
gadget.catlist[ cat.title ] = cat.hidden ? 'hidden' : 'visible';
} );
}
function retrieveCategoryInfo() {
return gadget.api.get( {
formatversion: 2,
prop: 'categories',
titles: config.wgPageName,
clprop: 'hidden',
cllimit: 'max'
} );
}
function purgePage() {
var query = {
action: 'purge',
forcelinkupdate: true,
titles: config.wgPageName
};
return gadget.api.post( query );
}
function requestExpandedText() {
return gadget.api.get( {
formatversion: 2,
action: 'expandtemplates',
title: config.wgPageName,
text: '{' + '{:' + config.wgPageName + '}}',
prop: 'wikitext'
} );
}
function requestCallback( data ) {
analyzeExpandedText( data.expandtemplates && data.expandtemplates.wikitext || '' );
if ( !gadget.retried && !gadget.catboxes.every( testCatboxId ) ) {
resetState( false );
gadget.retried = true;
return purgePage()
.then( retrieveCategoryInfo )
.done( processCategoryInfo )
.then( requestExpandedText )
.done( requestCallback );
} else {
$.each( gadget.catboxes, function () {
if ( testCatboxId( this ) ) {
fillCatBox( this );
} else {
this.find( '.catlinks-spinner' ).replaceWith( generateLabel( 'błąd odczytu danych' ) );
}
} );
}
}
function extractCategories( wikitext, fullname, shortname ) {
var m, map = {};
while ( m = gadget.categoryRegex.exec( wikitext ) ) {
if (
fullname === 'Esperanto' &&
m[ 1 ].indexOf( 'Esperanto - morfemy' ) === 0
) {
return true;
}
map[ m[ 1 ] ] = true;
}
return $.map( map, function ( value, key ) {
return key;
} );
}
function classifyCategories( $catbox ) {
$catbox
.children( '.mw-normal-catlinks' )
.find( 'li > a' )
.each( function () {
gadget.catlist[ this.title ] = 'visible';
} );
$catbox
.children( '.mw-hidden-catlinks' )
.find( 'li > a' )
.each( function () {
gadget.catlist[ this.title ] = 'hidden';
} );
}
function analyzeExpandedText( text ) {
// zob. [[Moduł:nagłówek języka]]
var sections = text.split( /(?=<span class="lang-code primary-lang-code)/ );
sections.shift(); // sekcja zerowa, czyli interwiki, podobne oraz TOC
$.each( sections, function ( i, section ) {
var shortname, fullname,
index = section.indexOf( 'id=' ),
idAttr = section.slice( index, section.indexOf( '>', index ) ),
id = idAttr.match( /^id="(.+?)"$/ )[ 1 ];
shortname = mw.libs.langData.code2lang[ id ];
if ( !id || !shortname ) {
return true;
}
if ( mw.libs.langData.shortLangs.indexOf( shortname ) === -1 ) {
fullname = 'Język ' + shortname;
} else {
fullname = shortname.charAt( 0 ).toUpperCase() + shortname.slice( 1 );
}
gadget.sections[ id ] = {
text: section,
fullname: fullname,
shortname: shortname,
categories: extractCategories( section, fullname, shortname )
};
} );
}
function fillCatBox( $catbox ) {
var id, visible, hidden;
id = $catbox.attr( 'id' ).slice( 'catlinks-'.length );
$catbox.data( 'spinner' ).remove();
gadget.sections[ id ].$box = $catbox;
visible = [];
hidden = [];
$.each( gadget.sections[ id ].categories, function ( i, cat ) {
var $el = $( '<li>' ).append(
$( '<a>' )
.attr( {
href: config.wgArticlePath.replace( '$1', cat ),
title: cat
} )
.text( stripCategoryNamespace( cat ) )
);
if ( !( cat in gadget.catlist ) || gadget.catlist[ cat ] === 'hidden' ) {
hidden.push( $el.prop( 'outerHTML' ) );
} else {
visible.push( $el.prop( 'outerHTML' ) );
}
} );
if ( !visible.length ) {
if ( !hidden.length || !Number( mw.user.options.get( 'showhiddencats' ) ) ) {
$catbox.children( '.mw-normal-catlinks' ).append( generateLabel( 'brak' ) );
} else {
$catbox.children( '.mw-normal-catlinks' ).remove();
}
} else {
$catbox.children( '.mw-normal-catlinks' )
.find( 'ul' )
.append( visible );
}
if ( !hidden.length ) {
$catbox.children( '.mw-hidden-catlinks' ).remove();
} else {
$catbox.children( '.mw-hidden-catlinks' )
.find( 'ul' )
.append( hidden );
if ( Number( mw.user.options.get( 'showhiddencats' ) ) ) {
$catbox.children( '.mw-hidden-catlinks' ).removeClass( 'mw-hidden-cats-hidden' );
}
}
}
function createCatBox( id, $catbox ) {
var $spinner = $.createSpinner( id )
.addClass( 'catlinks-spinner' );
$catbox
.attr( 'id', 'catlinks-' + id )
.addClass( 'catlinks-section' )
.data( 'spinner', $spinner );
$catbox
.children( '.mw-normal-catlinks' )
.attr( 'id', 'mw-normal-catlinks-' + id )
.append( $spinner )
.find( 'ul' )
.empty();
$catbox
.children( '.mw-hidden-catlinks' )
.attr( 'id', 'mw-hidden-catlinks-' + id )
.addClass( 'mw-hidden-cats-hidden' )
.find( 'ul' )
.empty();
gadget.catboxes.push( $catbox );
return $catbox;
}
function insertCatBoxes( $content, $catbox ) {
var $fields = $content.children(),
currentId = null,
isFirstSection = true;
$fields.each( function ( i ) {
var $this = $( this );
// TODO: remove check on `h2` once [[mw:Heading HTML changes]] is fully migrated
if ( $this.is( '.mw-heading' ) || $this.is( 'h2' ) ) {
if ( isFirstSection ) {
isFirstSection = false;
} else if ( currentId ) {
$this.before( createCatBox( currentId, $catbox.clone() ) );
}
currentId = $this.find( '.primary-lang-code' ).attr( 'id' );
} else if ( i === $fields.length - 1 && currentId ) {
$this.after( createCatBox( currentId, $catbox.clone() ) );
}
} );
resetHash( true );
}
function generateLabel( message ) {
return $( '<span>' )
.addClass( 'catlinks-message' )
.text( message );
}
function resetHash( check ) {
if ( location.hash && check ) {
location.hash = location.hash;
}
}
function resetState( hardReset ) {
gadget.sections = {};
gadget.catlist = {};
gadget.scrolled = false;
gadget.retried = false;
if ( hardReset ) {
gadget.catboxes = [];
}
}
mw.libs.langData = require( 'ext.gadget.langdata' );
gadget.api = new mw.Api();
gadget.categoryRegex = new RegExp( '\\[\\[(' + config.wgFormattedNamespaces[ 14 ] +
':.+?)(?:\\|.*?)?\\]\\]', 'g' );
// TODO: użycie wikipage.content oraz wikipage.categories
$( function () {
var $catbox = gadget.$originalCatbox = $( '#catlinks' ),
$content = $( '#mw-content-text' );
if ( $catbox.hasClass( 'catlinks-allhidden' ) ) {
return;
}
if ( $content.find( '.primary-lang-code' ).length < 2 ) {
mw.hook( 'multipleCategoryBoxes.ready' ).fire( $catbox );
return;
}
resetState( true );
classifyCategories( $catbox );
insertCatBoxes( $content.find( '.mw-parser-output' ).first(), $catbox );
$catbox.detach();
requestExpandedText().then( requestCallback )
.done( function () {
resetHash( !gadget.scrolled );
mw.hook( 'multipleCategoryBoxes.ready' ).fire( $content.find( '.catlinks' ) );
} )
.fail( function () {
$content.find( '.catlinks-spinner' ).replaceWith( generateLabel( 'błąd API' ) );
} );
$( window ).on( 'mousedown wheel DOMMouseScroll mousewheel keyup', function () {
gadget.scrolled = true;
} );
} );