MediaWiki:Gadget-entry-dom-layout.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.
/**
* Analiza i uporządkowanie drzewa DOM u haseł w przestrzeni głównej.
*
* Serwer generuje poniższy kod HTML, przykładowo dla hasła polskiego (wyrywek):
*
* <h2> <!-- nagłówek sekcji językowej --> </h2>
* <dl>
* <dt> <!-- nagłówek pola znaczeń --> </dt>
* </dl>
* <p> <!-- np. ''rzeczownik, rodzaj męski'' --> </p>
* <dl>
* <dd> <!-- znaczenie (1.1) --> </dd>
* <dd> <!-- znaczenie (1.2) --> </dd>
* </dl>
* <dl> <!-- następne pole --> </dl>
*
* Skrypt skupia wszystkie elementy dotyczące tego samego pola we wspólnym węźle
* <dl>, przydzielając mu klasę "fldt-<nazwa_pola>". Całą sekcję językową owija
* w węzeł <section> z klasą wskazującą na kod języka:
*
* <section class="lang-section lang-pl">
* <h2 class="section-heading"> <!-- nagłówek sekcji językowej --> </h2>
* <div class="section-intro"> <!-- np. ilustracje --> </div>
* <dl class="field fldt-znaczenia">
* <dt> <!-- nagłówek pola znaczeń --> </dt>
* <dd><p> <!-- np. ''rzeczownik, rodzaj męski'' --> </p></dd>
* <dd> <!-- znaczenie (1.1) --> </dd>
* <dd> <!-- znaczenie (1.2) --> </dd>
* </dl>
* <dl class="field fldt-..."> <!-- następne pole --> </dl>
* </section>
*
* Grupowanie podwęzłów najczęściej dotyczy pola znaczeń (<p>), tłumaczeń (<ul>)
* oraz źródeł (<ol> wewnątrz <div>). Zob. też [[Dyskusja szablonu:pole#Gadżet]].
*
* Dodatkowo skrypt ukrywa niewypełnione pola. Aby złagodzić wizualny efekt
* przewijania ładującej się strony wskutek ukrycia pustych pól, wykorzystano
* standardowe API bez użycia jQuery. Kod powinien działać zarówno w wersji
* standardowej, jak i w wersji mobilnej Wikisłownika.
*
* Zmierzony narzut czasowy (FF 74.0, wersja standardowa):
*
* - [[ratunek]] (jedna sekcja językowa): 1-3 ms
* - [[kot]] (cztery sekcje): 6-8 ms
* - [[Uganda]] (najdłuższa strona, 79 sekcji): 160-200 ms.
*/
function tryScroll( fragment ) {
var el,
fragment = fragment || location.hash;
if ( fragment && ( el = document.querySelector( fragment ) ) ) {
// przewiń stronę do wskazanej w URL sekcji językowej
el.scrollIntoView();
return true;
}
return false;
}
function process( el, prevEl, append ) {
var child, dd;
if ( el.tagName === 'DL' ) {
child = el.firstElementChild;
if ( child.tagName === 'DT' ) {
if (
child.firstElementChild &&
child.firstElementChild.tagName === 'SPAN' &&
child.firstElementChild.classList.contains( 'field-title' )
) {
// pogrubiony nagłówek "znaczenia:"
// <span class="field-title" data-field="znaczenia"></span>
el.className = 'field fldt-' + child.firstElementChild.dataset.field;
}
if (
child.nextElementSibling !== null &&
child.nextElementSibling.tagName === 'DD' &&
child.nextElementSibling.childNodes.length === 0
) {
// pusty <dd> w każdym polu: [[Dyskusja szablonu:pole#Dwukropek]]
el.removeChild( child.nextElementSibling );
}
if ( child.nextElementSibling === null ) {
// pole jest puste i należy je ukryć
el.classList.add( 'empty-field' );
}
if ( append ) {
prevEl.parentNode.appendChild( el );
}
} else if ( prevEl.tagName === 'DL' ) {
// lista definicji w polu znaczeń, które element <p> (np.
// ''rzeczownik, rodzaj męski') oddziela od nagłówka <dt>
// (pogrubiony napis '''znaczenia:''')
while ( el.hasChildNodes() ) {
prevEl.appendChild( el.firstChild );
}
el.parentNode.removeChild( el );
} else if ( append ) {
// potencjalne błędy w wikiskładni
prevEl.parentNode.appendChild( el );
}
} else if ( prevEl.tagName === 'DL' ) {
// np. <p> (znaczenia), <ul> (tłumaczenia), <div> (źródła)
dd = document.createElement( 'dd' );
prevEl.classList.remove( 'empty-field' );
prevEl.appendChild( dd );
dd.className = 'field-no-indent';
dd.appendChild( el );
} else if ( prevEl.className === 'section-intro' ) {
// grupowanie elementów pod nagłówkiem, przed pierwszym polem
prevEl.appendChild( el );
} else if ( append ) {
// potencjalne błędy w wikiskładni
prevEl.parentNode.appendChild( el );
}
}
if ( mw.config.get( 'wgNamespaceNumber' ) === 0 ) {
mw.hook( 'wikipage.content' ).add( function ( $content ) {
var i, j, el, header, intro, nestedChildren,
topChildren = $content.find( '.mw-parser-output' ).children().get(),
langSection = null;
for ( i = 0; i < topChildren.length; i++ ) {
el = topChildren[ i ];
if ( el.tagName === 'H2' ) {
// nagłówek sekcji językowej
header = el.getElementsByClassName( 'primary-lang-code' )[ 0 ];
if ( header !== null ) {
el.classList.add( 'section-heading' );
intro = document.createElement( 'div' );
intro.className = 'section-intro';
if (
el.nextElementSibling !== null &&
el.nextElementSibling.tagName === 'SECTION'
) {
// nagłówek w wersji mobilnej
langSection = el.nextElementSibling;
langSection.insertBefore( intro, langSection.firstChild );
} else {
// nagłówek w wersji standardowej
langSection = document.createElement( 'section' );
el.parentNode.insertBefore( langSection, el );
langSection.appendChild( el );
langSection.appendChild( intro );
}
langSection.classList.add( 'lang-section' );
langSection.classList.add( 'lang-' + header.id );
}
} else if ( el.tagName === 'SECTION' && el.hasChildNodes() ) {
// zwijana sekcja językowa w wersji mobilnej
nestedChildren = Array.prototype.slice.call( el.children );
for ( j = 1; j < nestedChildren.length; j++ ) {
process( nestedChildren[ j ], nestedChildren[ j ].previousElementSibling, false );
}
} else if ( langSection !== null ) {
// sekcja językowa w wersji standardowej
process( el, langSection.lastElementChild, true );
}
}
tryScroll();
} );
}
module.exports = { tryScroll: tryScroll };