Utilisateur:Guillaumrs/RiderRaking.js
Note : après avoir enregistré la page, vous devrez forcer le rechargement complet du cache de votre navigateur pour voir les changements.
Mozilla / Firefox / Konqueror / Safari : maintenez la touche Majuscule (Shift) en cliquant sur le bouton Actualiser (Reload) ou pressez Maj-Ctrl-R (Cmd-R sur Apple Mac) ;
Firefox (sur GNU/Linux) / Chrome / Internet Explorer / Opera : maintenez la touche Ctrl en cliquant sur le bouton Actualiser ou pressez Ctrl-F5./**
* Gadget pour remplacer {{Classements mondiaux UCI}} par {{Cycling race/Riderranking|QXXXXXXXX}} via Wikidata
*
* @author Claude (Anthropic) - Conversation avec Guillaumrs
* @date Mai 2026
* @version 1.2
*/
( function () {
'use strict';
/* ── Seulement en espace principal et Wikipédia ── */
var ns = mw.config.get( 'wgNamespaceNumber' );
if ( ns !== 0 && ns !== 4 ) return;
/* ── Seulement en mode lecture ── */
if ( mw.config.get( 'wgAction' ) !== 'view' ) return;
/* ── Regex : repère le bloc complet ──
IMPORTANT : ne pas utiliser le flag /g sur une regex réutilisée avec .test()
car lastIndex avance et provoque des faux négatifs en alternance.
On recrée la regex à chaque usage, ou on utilise une fonction. */
function hasUciBlock( text ) {
return /\{\{Classements mondiaux UCI\/En-tête\}\}[\s\S]*?\{\{Classements mondiaux UCI\/Fin\}\}/i.test( text );
}
function replaceUciBlock( text, replacement ) {
return text.replace(
/\{\{Classements mondiaux UCI\/En-tête\}\}[\s\S]*?\{\{Classements mondiaux UCI\/Fin\}\}/gi,
replacement
);
}
function getWikidataQid() {
return mw.config.get( 'wgWikibaseItemId' ) || null;
}
/* ────────────────────────────────────────────────────────
Applique la modification via l'API MediaWiki
──────────────────────────────────────────────────────── */
function doReplace( qid ) {
var api = new mw.Api();
var pageName = mw.config.get( 'wgPageName' );
api.get( {
action : 'query',
prop : 'revisions',
titles : pageName,
rvprop : 'content',
rvslots : 'main',
formatversion: 2
} ).done( function ( data ) {
var page = data.query.pages[ 0 ];
var oldText = page.revisions[ 0 ].slots.main.content;
if ( !hasUciBlock( oldText ) ) {
mw.notify( 'Aucun bloc {{Classements mondiaux UCI}} trouvé.', { type: 'warn' } );
return;
}
var newTemplate = '{{Cycling race/Riderranking|' + qid + '}}';
var newText = replaceUciBlock( oldText, newTemplate );
var summary =
'Remplacement du modèle obsolète ' +
'[[Modèle:Classements mondiaux UCI|{{Classements mondiaux UCI}}]] ' +
'par [[Modèle:Cycling race/Riderranking|{{Cycling race/Riderranking}}]] ' +
'avec intégration des données Wikidata (' + qid + ') ' +
'([[Utilisateur:Guillaumrs/RiderRaking.js|script]])';
api.postWithToken( 'csrf', {
action : 'edit',
title : pageName,
text : newText,
summary : summary,
notminor : true,
bot : false
} ).done( function ( result ) {
if ( result.edit && result.edit.result === 'Success' ) {
mw.notify( '✔ Modèle remplacé avec succès — rechargement…', { type: 'success' } );
setTimeout( function () { location.reload(); }, 1200 );
} else {
mw.notify( 'Erreur lors de la sauvegarde.', { type: 'error' } );
console.error( result );
}
} ).fail( function ( err ) {
mw.notify( 'Erreur API : ' + err, { type: 'error' } );
console.error( err );
} );
} ).fail( function ( err ) {
mw.notify( 'Impossible de lire le wikicode.', { type: 'error' } );
console.error( err );
} );
}
/* ────────────────────────────────────────────────────────
Panneau flottant fixe
──────────────────────────────────────────────────────── */
function injectPanel( qid ) {
/* Évite le double-ajout */
if ( $( '#uci-replace-panel' ).length ) return;
var $panel = $( '<div></div>' )
.attr( 'id', 'uci-replace-panel' )
.css( {
'position' : 'fixed',
'bottom' : '24px',
'right' : '24px',
'z-index' : '9998', /* légèrement sous colonnes2 (9999) pour éviter la superposition */
'background' : '#1a1a2e',
'border' : '1px solid rgba(72,187,120,0.4)',
'border-radius' : '12px',
'padding' : '12px 14px',
'box-shadow' : '0 4px 20px rgba(0,0,0,0.4)',
'display' : 'flex',
'align-items' : 'center',
'gap' : '10px',
'font-family' : 'sans-serif',
'font-size' : '13px',
'color' : '#e2e8f0',
'max-width' : '320px'
} );
/* Icône vélo */
var $icon = $( '<span></span>' )
.text( '🚴' )
.css( { 'font-size': '20px', 'flex-shrink': '0' } );
/* Texte */
var $label = $( '<span></span>' )
.html(
'<strong style="color:#68d391;display:block;margin-bottom:2px">Classements mondiaux UCI</strong>' +
'Modèle obsolète détecté — ' + mw.html.escape( qid )
)
.css( { 'line-height': '1.4', 'flex': '1' } );
/* Bouton remplacer */
var $btn = $( '<button></button>' )
.text( '⇄ Remplacer' )
.css( {
'background' : 'rgba(72,187,120,0.2)',
'border' : '1px solid rgba(72,187,120,0.5)',
'color' : '#68d391',
'border-radius' : '8px',
'padding' : '5px 10px',
'cursor' : 'pointer',
'font-size' : '12px',
'font-weight' : 'bold',
'white-space' : 'nowrap',
'transition' : 'all 0.2s',
'flex-shrink' : '0'
} )
.on( 'mouseenter', function () {
$( this ).css( {
'background' : 'rgba(72,187,120,0.4)',
'transform' : 'scale(1.05)'
} );
} )
.on( 'mouseleave', function () {
$( this ).css( {
'background' : 'rgba(72,187,120,0.2)',
'transform' : 'scale(1)'
} );
} )
.on( 'click', function () {
$( this ).text( '…' ).prop( 'disabled', true );
doReplace( qid );
} );
/* Bouton fermer */
var $close = $( '<button></button>' )
.text( '×' )
.attr( 'title', 'Fermer' )
.css( {
'background' : 'none',
'border' : 'none',
'color' : '#718096',
'font-size' : '18px',
'cursor' : 'pointer',
'padding' : '0 2px',
'line-height' : '1',
'flex-shrink' : '0',
'transition' : 'color 0.2s'
} )
.on( 'mouseenter', function () { $( this ).css( 'color', '#fc8181' ); } )
.on( 'mouseleave', function () { $( this ).css( 'color', '#718096' ); } )
.on( 'click', function () { $panel.remove(); } );
$panel.append( $icon, $label, $btn, $close );
$( 'body' ).append( $panel );
}
/* ── Point d'entrée ──
On utilise uniquement 'mediawiki.api' qui est toujours disponible.
mw.notify fait partie du core MediaWiki et n'a pas besoin d'être chargé séparément. */
$( function () {
mw.loader.using( 'mediawiki.api', function () {
var api = new mw.Api();
api.get( {
action : 'query',
prop : 'revisions',
titles : mw.config.get( 'wgPageName' ),
rvprop : 'content',
rvslots : 'main',
formatversion: 2
} ).done( function ( data ) {
var page = data.query.pages[ 0 ];
if ( !page.revisions ) return;
var src = page.revisions[ 0 ].slots.main.content;
if ( !hasUciBlock( src ) ) return;
var qid = getWikidataQid();
if ( !qid ) {
console.warn( '[RiderRaking] Pas de QID Wikidata pour cette page.' );
return;
}
injectPanel( qid );
} ).fail( function ( err ) {
console.error( '[RiderRaking] Erreur lors de la lecture de la page :', err );
} );
} );
} );
}() );