Basculer le menu
Changer de menu des préférences
Basculer le menu personnel
Non connecté(e)
Votre adresse IP sera visible au public si vous faites des modifications.

« MediaWiki:Common.js » : différence entre les versions

Page de l’interface de MediaWiki
Aucun résumé des modifications
Aucun résumé des modifications
 
(2 versions intermédiaires par le même utilisateur non affichées)
Ligne 2 : Ligne 2 :


/* ===== Fil d'Ariane des tuiles dans l'en-tete (skin Citizen) =====
/* ===== Fil d'Ariane des tuiles dans l'en-tete (skin Citizen) =====
   Affiche entre Accueil et Recherche un rectangle noir avec le titre
   Affiche entre Accueil et Recherche UN rectangle noir avec le titre
   de la/les tuile(s) qui contient(ent) la page courante
   de la tuile la plus pertinente pour la page courante :
   (tuile directe ou tuile parente d'un sous-article).
  0) page de provenance : chaque clic interne memorise la page ou l'on
      etait (sessionStorage) ; si c'est la cible d'une tuile (ex. on
      arrive de RetroGaming), c'est CETTE tuile qui est affichee.
      Le referrer sert de secours (bouton precedent, URL saisie).
  1) sinon si la page est elle-meme cible d'une tuile : sa tuile
   2) sinon (sous-article) : parmi les hubs qui pointent vers la page,
      le seul dont le nom ressemble le plus a celui de la page.
   MediaWiki 1.45 : le module mediawiki.title n'existe plus,
   MediaWiki 1.45 : le module mediawiki.title n'existe plus,
   mw.Title est fourni par mediawiki.api.
   mw.Title est fourni par mediawiki.api.
   Un MutationObserver re-insere la pastille si le skin reconstruit
   Un MutationObserver re-insere la pastille si le skin reconstruit
   l'en-tete apres l'insertion (sinon elle disparait a la navigation). */
   l'en-tete apres l'insertion. */
( function () {
( function () {
'use strict';
'use strict';
if ( mw.config.get( 'wgNamespaceNumber' ) !== 0 ) return;
if ( mw.config.get( 'wgNamespaceNumber' ) !== 0 ) return;
// Memorise la page de provenance a chaque clic sur un lien interne.
document.addEventListener( 'click', function ( e ) {
var a = e.target && e.target.closest ? e.target.closest( 'a[href]' ) : null;
if ( !a ) return;
try {
var u = new URL( a.href, location.href );
if ( u.hostname === location.hostname ) {
sessionStorage.setItem( 'fil-ariane-precedente',
location.pathname + location.search );
}
} catch ( err ) {}
} );
var current = mw.config.get( 'wgPageName' );
var current = mw.config.get( 'wgPageName' );
if ( current === 'Accueil' ) return;
if ( current === 'Accueil' ) return;
Ligne 18 : Ligne 38 :
try { return new mw.Title( nom ).toText(); }
try { return new mw.Title( nom ).toText(); }
catch ( e ) { return nom; }
catch ( e ) { return nom; }
}
function similarite( a, b ) {
var na = a.toLowerCase().replace( /_/g, ' ' ).split( /[^a-z0-9]+/ ).filter( Boolean );
var nb = b.toLowerCase().replace( /_/g, ' ' ).split( /[^a-z0-9]+/ ).filter( Boolean );
if ( !na.length || !nb.length ) return 0;
var setB = {};
nb.forEach( function ( t ) { setB[ t ] = 1; } );
var commun = 0;
na.forEach( function ( t ) { if ( setB[ t ] ) commun++; } );
return commun / Math.max( na.length, nb.length );
}
function titreDepuisUrl( url ) {
if ( !url ) return null;
try {
var u = new URL( url, location.origin );
var t = u.searchParams.get( 'title' );
if ( !t ) {
var m = u.pathname.match( /\/index\.php\/(.+)$/ );
if ( m ) t = decodeURIComponent( m[ 1 ] );
}
if ( !t ) return null;
return titreNormalise( t.replace( /#.*/, '' ) );
} catch ( e ) { return null; }
}
}


Ligne 71 : Ligne 116 :
}
}
} );
} );
var trouvees = tuiles.filter( function ( t ) {
function tuileDe( titreCible ) {
return titreNormalise( t.cible ) === norm;
var trouvees = tuiles.filter( function ( t ) {
} );
return titreNormalise( t.cible ) === titreCible;
} );
return trouvees.length ? trouvees[ 0 ] : null;
}
// 0) page de provenance (clic memorise, puis referrer en secours)
var provenances = [
titreDepuisUrl( sessionStorage.getItem( 'fil-ariane-precedente' ) ),
titreDepuisUrl( document.referrer )
];
for ( var i = 0; i < provenances.length; i++ ) {
var ref = provenances[ i ];
if ( ref && ref !== norm ) {
var tuileRef = tuileDe( ref );
if ( tuileRef ) { pastilles( [ tuileRef ] ); return; }
}
}
// 1) la page courante EST la cible d'une tuile
var directe = tuileDe( norm );
if ( directe ) { pastilles( [ directe ] ); return; }
// 2) sous-article : hubs qui pointent vers la page courante
return api.get( { action: 'query', list: 'backlinks', bltitle: norm,
return api.get( { action: 'query', list: 'backlinks', bltitle: norm,
bllimit: 500, blnamespace: 0, formatversion: 2 } )
bllimit: 500, blnamespace: 0, formatversion: 2 } )
.then( function ( bd ) {
.then( function ( bd ) {
var liens = ( bd.query.backlinks || [] ).map( function ( p ) { return p.title; } );
var liens = {};
tuiles.forEach( function ( t ) {
( bd.query.backlinks || [] ).forEach( function ( p ) {
var cibleNorm = titreNormalise( t.cible );
liens[ titreNormalise( p.title ) ] = 1;
if ( cibleNorm !== norm && liens.indexOf( cibleNorm ) !== -1 ) {
} );
trouvees.push( t );
var candidats = tuiles.filter( function ( t ) {
}
return liens[ titreNormalise( t.cible ) ];
} );
if ( !candidats.length ) return;
// une seule pastille : le parent au nom le plus proche
var best = candidats[ 0 ];
var bestScore = -1;
candidats.forEach( function ( t ) {
var s = similarite( t.cible, current );
if ( s > bestScore ) { bestScore = s; best = t; }
} );
} );
if ( trouvees.length ) pastilles( trouvees );
pastilles( [ best ] );
} );
} );
} );
} );

Dernière version du 24 octobre 2026 à 13:46

/* Tout JavaScript present ici sera execute par tous les utilisateurs a chaque chargement de page. */

/* ===== Fil d'Ariane des tuiles dans l'en-tete (skin Citizen) =====
   Affiche entre Accueil et Recherche UN rectangle noir avec le titre
   de la tuile la plus pertinente pour la page courante :
   0) page de provenance : chaque clic interne memorise la page ou l'on
      etait (sessionStorage) ; si c'est la cible d'une tuile (ex. on
      arrive de RetroGaming), c'est CETTE tuile qui est affichee.
      Le referrer sert de secours (bouton precedent, URL saisie).
   1) sinon si la page est elle-meme cible d'une tuile : sa tuile
   2) sinon (sous-article) : parmi les hubs qui pointent vers la page,
      le seul dont le nom ressemble le plus a celui de la page.
   MediaWiki 1.45 : le module mediawiki.title n'existe plus,
   mw.Title est fourni par mediawiki.api.
   Un MutationObserver re-insere la pastille si le skin reconstruit
   l'en-tete apres l'insertion. */
( function () {
	'use strict';
	if ( mw.config.get( 'wgNamespaceNumber' ) !== 0 ) return;

	// Memorise la page de provenance a chaque clic sur un lien interne.
	document.addEventListener( 'click', function ( e ) {
		var a = e.target && e.target.closest ? e.target.closest( 'a[href]' ) : null;
		if ( !a ) return;
		try {
			var u = new URL( a.href, location.href );
			if ( u.hostname === location.hostname ) {
				sessionStorage.setItem( 'fil-ariane-precedente',
					location.pathname + location.search );
			}
		} catch ( err ) {}
	} );

	var current = mw.config.get( 'wgPageName' );
	if ( current === 'Accueil' ) return;

	function titreNormalise( nom ) {
		try { return new mw.Title( nom ).toText(); }
		catch ( e ) { return nom; }
	}

	function similarite( a, b ) {
		var na = a.toLowerCase().replace( /_/g, ' ' ).split( /[^a-z0-9]+/ ).filter( Boolean );
		var nb = b.toLowerCase().replace( /_/g, ' ' ).split( /[^a-z0-9]+/ ).filter( Boolean );
		if ( !na.length || !nb.length ) return 0;
		var setB = {};
		nb.forEach( function ( t ) { setB[ t ] = 1; } );
		var commun = 0;
		na.forEach( function ( t ) { if ( setB[ t ] ) commun++; } );
		return commun / Math.max( na.length, nb.length );
	}

	function titreDepuisUrl( url ) {
		if ( !url ) return null;
		try {
			var u = new URL( url, location.origin );
			var t = u.searchParams.get( 'title' );
			if ( !t ) {
				var m = u.pathname.match( /\/index\.php\/(.+)$/ );
				if ( m ) t = decodeURIComponent( m[ 1 ] );
			}
			if ( !t ) return null;
			return titreNormalise( t.replace( /#.*/, '' ) );
		} catch ( e ) { return null; }
	}

	function pastilles( tuiles ) {
		function construire() {
			var zone = document.createElement( 'div' );
			zone.className = 'tuile-fil-ariane citizen-header__item';
			tuiles.forEach( function ( t ) {
				var a = document.createElement( 'a' );
				a.href = mw.util.getUrl( t.cible );
				a.className = 'tuile-pastille';
				a.title = 'Retour a la tuile : ' + t.titre;
				var span = document.createElement( 'span' );
				span.textContent = t.titre;
				a.appendChild( span );
				zone.appendChild( a );
			} );
			return zone;
		}

		function verifier() {
			var header = document.querySelector( '.citizen-header' );
			if ( !header ) return;
			if ( header.querySelector( '.tuile-fil-ariane' ) ) return;
			var logo = header.querySelector( '.citizen-header__logo' );
			if ( !logo ) return;
			logo.insertAdjacentElement( 'afterend', construire() );
		}

		verifier();
		// Le skin peut reconstruire l'en-tete apres insertion : re-insere si besoin.
		var observer = new MutationObserver( verifier );
		observer.observe( document.body, { childList: true, subtree: true } );
		window.addEventListener( 'load', verifier );
	}

	function lancer() {
		var api = new mw.Api();
		var norm = titreNormalise( current );
		api.get( { action: 'parse', page: 'Accueil', prop: 'text', formatversion: 2 } )
		.then( function ( data ) {
			var doc = new DOMParser().parseFromString( data.parse.text, 'text/html' );
			var tuiles = [];
			doc.querySelectorAll( '.accueil-tile' ).forEach( function ( el ) {
				var cible = el.getAttribute( 'data-cible' );
				var cle = el.getAttribute( 'data-tuile' );
				var titre = el.querySelector( '.accueil-tile-title' );
				if ( cible && cle ) {
					tuiles.push( {
						cible: cible, key: cle,
						titre: titre ? titre.textContent.trim() : cle
					} );
				}
			} );
			function tuileDe( titreCible ) {
				var trouvees = tuiles.filter( function ( t ) {
					return titreNormalise( t.cible ) === titreCible;
				} );
				return trouvees.length ? trouvees[ 0 ] : null;
			}
			// 0) page de provenance (clic memorise, puis referrer en secours)
			var provenances = [
				titreDepuisUrl( sessionStorage.getItem( 'fil-ariane-precedente' ) ),
				titreDepuisUrl( document.referrer )
			];
			for ( var i = 0; i < provenances.length; i++ ) {
				var ref = provenances[ i ];
				if ( ref && ref !== norm ) {
					var tuileRef = tuileDe( ref );
					if ( tuileRef ) { pastilles( [ tuileRef ] ); return; }
				}
			}
			// 1) la page courante EST la cible d'une tuile
			var directe = tuileDe( norm );
			if ( directe ) { pastilles( [ directe ] ); return; }
			// 2) sous-article : hubs qui pointent vers la page courante
			return api.get( { action: 'query', list: 'backlinks', bltitle: norm,
				bllimit: 500, blnamespace: 0, formatversion: 2 } )
			.then( function ( bd ) {
				var liens = {};
				( bd.query.backlinks || [] ).forEach( function ( p ) {
					liens[ titreNormalise( p.title ) ] = 1;
				} );
				var candidats = tuiles.filter( function ( t ) {
					return liens[ titreNormalise( t.cible ) ];
				} );
				if ( !candidats.length ) return;
				// une seule pastille : le parent au nom le plus proche
				var best = candidats[ 0 ];
				var bestScore = -1;
				candidats.forEach( function ( t ) {
					var s = similarite( t.cible, current );
					if ( s > bestScore ) { bestScore = s; best = t; }
				} );
				pastilles( [ best ] );
			} );
		} );
	}

	function quandPret( fn ) {
		if ( document.readyState !== 'loading' ) { fn(); }
		else { document.addEventListener( 'DOMContentLoaded', fn ); }
	}

	quandPret( function () {
		mw.loader.using( [ 'mediawiki.api', 'mediawiki.util' ], lancer );
	} );
}() );