/**
Uniwersalny gadżet do automatycznego wczytywania modułów wspierających
dzialanie różnych szablonów. Powstał po dyskusji w kawiarence technicznej:
https://pl.wikipedia.org/w/index.php?oldid=54598545#Szablon:podzi%C4%99kowanie
Wspierane moduły powinny deklarować następujące funkcje w obiekcie
`module.exports` automatycznie eksponowanym przez mechanizmy ResourceLoader:
///
/// Sprawdza warunki konieczne do uruchomienia gadżetu.
///
/// @return {boolean}
testPreconditions()
///
/// Przeprowadza wstępną konfigurację gadżetu, np. tworzenie obiektów
/// globalnych, rejestrowanie komunikatów itd.
///
initialize()
///
/// Odrzuca elementy, które nie spełniają określonych warunków.
///
/// @param {jQuery} $els
/// @return {jQuery}
filter( $els )
///
/// Przetwarza poszczególne elementy.
///
/// @param {jQuery} $els
process( $els )
W zależności od modułu niektóre z powyższych nie będą wykorzystywane. Zaleca
się oznaczanie pustych definicji funkcji za pomocą `$.noop`.
Zasada działania algorytmu:
1. wyszukaj elementy HTML, które mają atrybut `class="ll-script"`
2. w znalezionych elementach znajdź atrybut(y) `class="ll-script-<jakaś-nazwa>"`
3. znajdź moduł(y) "ll-script-<jakaś-nazwa>" ("MediaWiki:Gadget-ll-script-<jakaś-nazwa>.js")
4. uruchom funkcję `testPreconditions` z gadżetu, pomijając dalsze kroki,
jeżeli zostanie zwrócona wartość logiczna `false`; skrypty mogą na tym
etapie sprawdzić m.in. czy przestrzeń nazw jest odpowiednia; ta funkcja
zostanie wywołana tylko raz
5. uruchom funkcję `initialize` z gadżetu, przeprowadzając wstępną
konfigurację skryptu; ta funkcja zostanie wywołana tylko raz
6. uruchom funkcję `filter` z gadżetu, przekazując jej znalezione elementy;
skrypty mogą odrzucić niepasujące elementy za pośrednictwem metod jQuery
takich jak `.filter()` albo `.not()`
7. uruchom funkcję `process` z gadżetu, przekazując jej elementy wynikające
z poprzedniego kroku
Algorytm jest wykonywany za każdym razem, gdy zostaje wywołane zdarzenie
`wikipage.content`, przykładowo w trakcie korzystania z Suwaka Wersji lub
Live Preview.
Lista obecnie dostępnych skryptów:
https://pl.wikipedia.orghttps://wiki386.com/pl/Specjalna:Strony_wed%C5%82ug_prefiksu?prefix=Gadget-ll-script&namespace=8
*/
var re,
prefix = 'll-script',
loader = prefix + '-loader',
moduleRegistry = {};
// https://stackoverflow.com/a/1232046/10404307
function clearArray( arr ) {
arr.length = 0;
}
mw.hook( 'wikipage.content' ).add( function ( $content ) {
var $els = $content.find( '.' + prefix );
if ( $els.length ) {
re = re || new RegExp( prefix + '-(\\S+)', 'g' );
$els.each( function ( i, el ) {
var m, obj, arr;
while ( ( m = re.exec( el.className ) ) !== null ) {
obj = moduleRegistry ] || {};
arr = obj.nodes || ;
arr.push( el );
obj.nodes = arr;
moduleRegistry ] = obj;
}
} );
delete moduleRegistry; // na wszelki wypadek
Object.keys( moduleRegistry ).filter( function ( script ) {
var nodes = this.nodes;
return Array.isArray( nodes ) && nodes.length !== 0;
}, moduleRegistry ).forEach( function ( script ) {
var module,
obj = this,
$nodes = $( ).add( obj.nodes );
if ( obj.hasOwnProperty( 'exports' ) ) {
if ( obj.load ) {
$nodes = obj.exports.filter( $nodes ) || $nodes;
if ( $nodes.length ) {
obj.exports.process( $nodes );
}
}
clearArray( obj.nodes );
} else {
module = mw.format( 'ext.gadget.$1-$2', prefix, script );
if ( mw.loader.getModuleNames().indexOf( module ) !== -1 ) {
mw.loader.using( module ).done( function ( require ) {
obj.exports = require( module );
obj.load = obj.exports.testPreconditions() !== false;
if ( obj.load ) {
obj.exports.initialize();
$nodes = obj.exports.filter( $nodes ) || $nodes;
if ( $nodes.length ) {
obj.exports.process( $nodes );
}
}
clearArray( obj.nodes );
} );
} else {
clearArray( obj.nodes );
}
}
}, moduleRegistry );
}
} );