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
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 qui contient la page courante :
   (tuile directe ou tuile parente d'un sous-article).
   - tuile directe (la page est la cible de la tuile)
  - sinon, parmi les pages cibles qui pointent vers la page courante,
    la seule 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';
Ligne 18 : Ligne 20 :
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 );
}
}


Ligne 71 : Ligne 84 :
}
}
} );
} );
var trouvees = tuiles.filter( function ( t ) {
// 1) la page courante EST la cible d'une tuile : afficher cette tuile
var directes = tuiles.filter( function ( t ) {
return titreNormalise( t.cible ) === norm;
return titreNormalise( t.cible ) === norm;
} );
} );
if ( directes.length ) { pastilles( directes ); 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 ] );
} );
} );
} );
} );

Version du 24 octobre 2026 à 13:28

/* 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 qui contient la page courante :
   - tuile directe (la page est la cible de la tuile)
   - sinon, parmi les pages cibles qui pointent vers la page courante,
     la seule 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;
	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 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
					} );
				}
			} );
			// 1) la page courante EST la cible d'une tuile : afficher cette tuile
			var directes = tuiles.filter( function ( t ) {
				return titreNormalise( t.cible ) === norm;
			} );
			if ( directes.length ) { pastilles( directes ); 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 );
	} );
}() );