More actions
Default chiuso su TOC lunga + persistenza |
sezioni collassabili + sostituzione box TBC |
||
| Line 63: | Line 63: | ||
} ); | } ); | ||
} ); | } ); | ||
/* === [SEZIONI] inizio === | |||
Sezioni collassabili in tutta la wiki. | |||
- Granularità: intestazioni di 2º livello (== ==). Le sotto-sezioni (=== ===) | |||
restano dentro la loro sezione. | |||
- Default: CHIUSE al primo approdo (nessuno stato salvato per la pagina). | |||
- Lo stato (quali sezioni aperte) è ricordato per-pagina in localStorage. | |||
- I link interni / le voci della TOC riaprono la sezione di destinazione. */ | |||
mw.hook( 'wikipage.content' ).add( function () { | |||
var body = document.querySelector( '#mw-content-text .mw-parser-output' ); | |||
if ( !body || body.dataset.ceSecDone ) { | |||
return; | |||
} | |||
// intestazioni H2 di primo livello nel corpo (wrapper .mw-heading2 in MW 1.45, | |||
// o <h2> nudo come fallback) | |||
var headings = Array.prototype.slice.call( body.children ).filter( function ( n ) { | |||
return ( n.classList && n.classList.contains( 'mw-heading2' ) ) || n.tagName === 'H2'; | |||
} ); | |||
if ( !headings.length ) { | |||
return; | |||
} | |||
body.dataset.ceSecDone = '1'; | |||
function headingId( h ) { | |||
var hx = h.querySelector ? ( h.querySelector( 'h1,h2,h3,h4' ) || h ) : h; | |||
return hx.id || null; | |||
} | |||
var SKEY = 'ce-sections:' + mw.config.get( 'wgPageName' ); | |||
var stored = null; | |||
try { stored = localStorage.getItem( SKEY ); } catch ( e ) {} | |||
var openIds = {}; | |||
if ( stored ) { | |||
try { | |||
JSON.parse( stored ).forEach( function ( id ) { openIds[ id ] = 1; } ); | |||
} catch ( e ) {} | |||
} | |||
function save() { | |||
var open = []; | |||
headings.forEach( function ( h ) { | |||
if ( !h.classList.contains( 'ce-collapsed' ) ) { | |||
var id = headingId( h ); | |||
if ( id ) { open.push( id ); } | |||
} | |||
} ); | |||
try { localStorage.setItem( SKEY, JSON.stringify( open ) ); } catch ( e ) {} | |||
} | |||
headings.forEach( function ( h ) { | |||
// avvolge i fratelli fino alla prossima intestazione H2 | |||
var content = document.createElement( 'div' ); | |||
content.className = 'ce-sec-content'; | |||
var sib = h.nextSibling; | |||
while ( sib ) { | |||
var next = sib.nextSibling; | |||
if ( sib.nodeType === 1 && | |||
( ( sib.classList && sib.classList.contains( 'mw-heading2' ) ) || sib.tagName === 'H2' ) ) { | |||
break; | |||
} | |||
content.appendChild( sib ); | |||
sib = next; | |||
} | |||
h.parentNode.insertBefore( content, h.nextSibling ); | |||
content._ceHeading = h; | |||
h.classList.add( 'ce-sec-h' ); | |||
h.setAttribute( 'tabindex', '0' ); | |||
var hid = headingId( h ); | |||
var open = stored ? !!openIds[ hid ] : false; // default: chiusa | |||
h.setAttribute( 'aria-expanded', open ? 'true' : 'false' ); | |||
if ( !open ) { | |||
h.classList.add( 'ce-collapsed' ); | |||
} | |||
var toggle = function () { | |||
var c = h.classList.toggle( 'ce-collapsed' ); | |||
h.setAttribute( 'aria-expanded', c ? 'false' : 'true' ); | |||
save(); | |||
}; | |||
h.addEventListener( 'click', function ( e ) { | |||
if ( e.target.closest( 'a' ) || e.target.closest( '.mw-editsection' ) ) { | |||
return; // non interferire con i link / modifica-sezione | |||
} | |||
toggle(); | |||
} ); | |||
h.addEventListener( 'keydown', function ( e ) { | |||
if ( ( e.key === 'Enter' || e.key === ' ' ) && | |||
!e.target.closest( 'a' ) && !e.target.closest( '.mw-editsection' ) ) { | |||
e.preventDefault(); | |||
toggle(); | |||
} | |||
} ); | |||
} ); | |||
// riapri la sezione di destinazione quando si segue un'àncora | |||
function expandFor( hash ) { | |||
if ( !hash || hash.length < 2 ) { return; } | |||
var id; | |||
try { id = decodeURIComponent( hash.replace( /^#/, '' ) ); } catch ( e ) { id = hash.slice( 1 ); } | |||
var el = document.getElementById( id ); | |||
if ( !el ) { return; } | |||
var hWrap = el.closest( '.ce-sec-h' ); | |||
if ( hWrap ) { | |||
hWrap.classList.remove( 'ce-collapsed' ); | |||
hWrap.setAttribute( 'aria-expanded', 'true' ); | |||
} else { | |||
var c = el.closest( '.ce-sec-content' ); | |||
if ( c && c._ceHeading ) { | |||
c._ceHeading.classList.remove( 'ce-collapsed' ); | |||
c._ceHeading.setAttribute( 'aria-expanded', 'true' ); | |||
} | |||
} | |||
save(); | |||
setTimeout( function () { | |||
var t = document.getElementById( id ); | |||
if ( t && t.scrollIntoView ) { t.scrollIntoView(); } | |||
}, 0 ); | |||
} | |||
window.addEventListener( 'hashchange', function () { expandFor( location.hash ); } ); | |||
document.addEventListener( 'click', function ( e ) { | |||
var a = e.target.closest( 'a[href^="#"]' ); | |||
if ( a ) { | |||
var href = a.getAttribute( 'href' ); | |||
setTimeout( function () { expandFor( href ); }, 0 ); | |||
} | |||
} ); | |||
if ( location.hash ) { expandFor( location.hash ); } | |||
} ); | |||
/* === [SEZIONI] fine === */ | |||
Revision as of 13:55, 16 June 2026
/* All JavaScript here will be loaded for users of the Citizen skin */
/* Indice d'archivio:
1) dove esiste il rail di Citizen lo mettiamo lì SOPRA la TOC nativa (riuso);
dove il rail non c'è, l'indice resta flottante (.ai-rail) e non sparisce.
2) collassabile (chevron nella testata). Stato iniziale:
- se l'utente ha già scelto, si ricorda (localStorage);
- altrimenti default intelligente: chiuso se la TOC della pagina è lunga.
3) la testata (link alla Dashboard) resta sempre visibile. */
mw.hook( 'wikipage.content' ).add( function () {
var KEY = 'ce-indice-collapsed';
// 1) posizionamento
var floatBox = document.querySelector( '.archivio-indice.ai-rail' );
if ( floatBox ) {
var rail =
document.querySelector( '.citizen-page-sidebar' ) ||
document.querySelector( '.citizen-sidebar' ) ||
document.querySelector( '.citizen-toc-container' );
if ( rail ) {
floatBox.classList.remove( 'ai-rail' );
floatBox.classList.add( 'ai-in-rail' );
rail.prepend( floatBox );
}
}
var idx = document.querySelector( '.archivio-indice' );
if ( !idx ) {
return;
}
// 2) stato iniziale
var saved = null;
try {
saved = localStorage.getItem( KEY );
} catch ( e ) {}
var tocCount = document.querySelectorAll( '.citizen-toc-link' ).length;
var collapsed = ( saved === null ) ? ( tocCount > 8 ) : ( saved === '1' );
if ( collapsed ) {
idx.classList.add( 'ai-collapsed' );
}
// 3) toggle + persistenza
document.querySelectorAll( '.archivio-indice .ai-toggle' ).forEach( function ( t ) {
if ( t.dataset.bound ) {
return;
}
t.dataset.bound = '1';
var act = function () {
var b = t.closest( '.archivio-indice' );
b.classList.toggle( 'ai-collapsed' );
try {
localStorage.setItem( KEY, b.classList.contains( 'ai-collapsed' ) ? '1' : '0' );
} catch ( e ) {}
};
t.addEventListener( 'click', act );
t.addEventListener( 'keydown', function ( e ) {
if ( e.key === 'Enter' || e.key === ' ' ) {
e.preventDefault();
act();
}
} );
} );
} );
/* === [SEZIONI] inizio ===
Sezioni collassabili in tutta la wiki.
- Granularità: intestazioni di 2º livello (== ==). Le sotto-sezioni (=== ===)
restano dentro la loro sezione.
- Default: CHIUSE al primo approdo (nessuno stato salvato per la pagina).
- Lo stato (quali sezioni aperte) è ricordato per-pagina in localStorage.
- I link interni / le voci della TOC riaprono la sezione di destinazione. */
mw.hook( 'wikipage.content' ).add( function () {
var body = document.querySelector( '#mw-content-text .mw-parser-output' );
if ( !body || body.dataset.ceSecDone ) {
return;
}
// intestazioni H2 di primo livello nel corpo (wrapper .mw-heading2 in MW 1.45,
// o <h2> nudo come fallback)
var headings = Array.prototype.slice.call( body.children ).filter( function ( n ) {
return ( n.classList && n.classList.contains( 'mw-heading2' ) ) || n.tagName === 'H2';
} );
if ( !headings.length ) {
return;
}
body.dataset.ceSecDone = '1';
function headingId( h ) {
var hx = h.querySelector ? ( h.querySelector( 'h1,h2,h3,h4' ) || h ) : h;
return hx.id || null;
}
var SKEY = 'ce-sections:' + mw.config.get( 'wgPageName' );
var stored = null;
try { stored = localStorage.getItem( SKEY ); } catch ( e ) {}
var openIds = {};
if ( stored ) {
try {
JSON.parse( stored ).forEach( function ( id ) { openIds[ id ] = 1; } );
} catch ( e ) {}
}
function save() {
var open = [];
headings.forEach( function ( h ) {
if ( !h.classList.contains( 'ce-collapsed' ) ) {
var id = headingId( h );
if ( id ) { open.push( id ); }
}
} );
try { localStorage.setItem( SKEY, JSON.stringify( open ) ); } catch ( e ) {}
}
headings.forEach( function ( h ) {
// avvolge i fratelli fino alla prossima intestazione H2
var content = document.createElement( 'div' );
content.className = 'ce-sec-content';
var sib = h.nextSibling;
while ( sib ) {
var next = sib.nextSibling;
if ( sib.nodeType === 1 &&
( ( sib.classList && sib.classList.contains( 'mw-heading2' ) ) || sib.tagName === 'H2' ) ) {
break;
}
content.appendChild( sib );
sib = next;
}
h.parentNode.insertBefore( content, h.nextSibling );
content._ceHeading = h;
h.classList.add( 'ce-sec-h' );
h.setAttribute( 'tabindex', '0' );
var hid = headingId( h );
var open = stored ? !!openIds[ hid ] : false; // default: chiusa
h.setAttribute( 'aria-expanded', open ? 'true' : 'false' );
if ( !open ) {
h.classList.add( 'ce-collapsed' );
}
var toggle = function () {
var c = h.classList.toggle( 'ce-collapsed' );
h.setAttribute( 'aria-expanded', c ? 'false' : 'true' );
save();
};
h.addEventListener( 'click', function ( e ) {
if ( e.target.closest( 'a' ) || e.target.closest( '.mw-editsection' ) ) {
return; // non interferire con i link / modifica-sezione
}
toggle();
} );
h.addEventListener( 'keydown', function ( e ) {
if ( ( e.key === 'Enter' || e.key === ' ' ) &&
!e.target.closest( 'a' ) && !e.target.closest( '.mw-editsection' ) ) {
e.preventDefault();
toggle();
}
} );
} );
// riapri la sezione di destinazione quando si segue un'àncora
function expandFor( hash ) {
if ( !hash || hash.length < 2 ) { return; }
var id;
try { id = decodeURIComponent( hash.replace( /^#/, '' ) ); } catch ( e ) { id = hash.slice( 1 ); }
var el = document.getElementById( id );
if ( !el ) { return; }
var hWrap = el.closest( '.ce-sec-h' );
if ( hWrap ) {
hWrap.classList.remove( 'ce-collapsed' );
hWrap.setAttribute( 'aria-expanded', 'true' );
} else {
var c = el.closest( '.ce-sec-content' );
if ( c && c._ceHeading ) {
c._ceHeading.classList.remove( 'ce-collapsed' );
c._ceHeading.setAttribute( 'aria-expanded', 'true' );
}
}
save();
setTimeout( function () {
var t = document.getElementById( id );
if ( t && t.scrollIntoView ) { t.scrollIntoView(); }
}, 0 );
}
window.addEventListener( 'hashchange', function () { expandFor( location.hash ); } );
document.addEventListener( 'click', function ( e ) {
var a = e.target.closest( 'a[href^="#"]' );
if ( a ) {
var href = a.getAttribute( 'href' );
setTimeout( function () { expandFor( href ); }, 0 );
}
} );
if ( location.hash ) { expandFor( location.hash ); }
} );
/* === [SEZIONI] fine === */