MediaWiki:Gadget-ll-script-loader.js

/**
	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.org/wiki/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[ m[ 1 ] ] || {};
				arr = obj.nodes || [];
				arr.push( el );
				obj.nodes = arr;
				moduleRegistry[ m[ 1 ] ] = obj;
			}
		} );
		
		delete moduleRegistry[ loader ]; // na wszelki wypadek
		
		Object.keys( moduleRegistry ).filter( function ( script ) {
			var nodes = this[ script ].nodes;
			return Array.isArray( nodes ) && nodes.length !== 0;
		}, moduleRegistry ).forEach( function ( script ) {
			var module,
				obj = this[ script ],
				$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 );
	}
} );

Content Disclaimer

Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.

  1. The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
  2. There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
  3. It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
  4. Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
  5. Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.
Kembali kehalaman sebelumnya