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

Page de l’interface de MediaWiki
Version datée du 24 octobre 2026 à 13:46 par Admin (discussion | contributions)
(diff) ← Version précédente | Version actuelle (diff) | Version suivante → (diff)

Note : après avoir publié vos modifications, il se peut que vous deviez forcer le rechargement complet du cache de votre navigateur pour voir les changements.

  • Firefox / Safari : maintenez la touche Maj (Shift) en cliquant sur le bouton Actualiser ou appuyez sur Ctrl + F5 ou Ctrl + R (⌘ + R sur un Mac).
  • Google Chrome : appuyez sur Ctrl + Maj + R (⌘ + Shift + R sur un Mac).
  •  Edge : maintenez la touche Ctrl en cliquant sur le bouton Actualiser ou pressez Ctrl + F5.
/* 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 );
	} );
}() );