MediaWiki:Common.js
Page de l’interface de MediaWiki
Autres actions
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 présent ici sera exécuté par tous les utilisateurs à chaque chargement de page. */
$( function () {
$( '.citizen-search-trigger' ).on( 'click', function () {
$( '#searchInput' ).focus();
} );
// Raccourci Ctrl+K (ou Cmd+K sur Mac)
$( document ).on( 'keydown', function ( e ) {
if ( ( e.ctrlKey || e.metaKey ) && e.key === 'k' ) {
e.preventDefault();
$( '#searchInput' ).focus();
}
} );
} );
/**
* MinecraftConnect - Boutons de copie d'adresse serveur Minecraft
* Inspiré de l'extension PreToClip
*/
(function() {
'use strict';
function initMinecraftButtons($content) {
$content.find('.minecraft-connect-wrapper').each(function() {
var $wrapper = $(this);
// Éviter la double initialisation
if ($wrapper.data('mc-initialized')) {
return;
}
$wrapper.data('mc-initialized', true);
var serverAddress = $wrapper.data('mc-server');
var buttonText = $wrapper.data('mc-text');
// Créer le bouton
var $button = $('<button>')
.addClass('mw-ui-button mw-ui-progressive minecraft-connect-btn')
.attr('type', 'button')
.attr('title', 'Cliquer pour copier : ' + serverAddress)
.text(buttonText + ' 📋');
// Remplacer le span par le bouton
$wrapper.replaceWith($button);
// Gestion du clic
$button.on('click', function() {
copyToClipboard(serverAddress, $button, buttonText);
});
});
}
function copyToClipboard(text, $button, originalText) {
// Méthode moderne (Clipboard API)
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(text).then(
function() {
showSuccess($button, originalText);
},
function() {
// Fallback si échec
fallbackCopy(text, $button, originalText);
}
);
} else {
// Fallback pour anciens navigateurs
fallbackCopy(text, $button, originalText);
}
}
function fallbackCopy(text, $button, originalText) {
var $temp = $('<textarea>')
.val(text)
.css({
position: 'fixed',
top: 0,
left: 0,
width: '2em',
height: '2em',
padding: 0,
border: 'none',
outline: 'none',
boxShadow: 'none',
background: 'transparent'
})
.appendTo('body');
$temp[0].select();
$temp[0].setSelectionRange(0, 99999);
try {
var successful = document.execCommand('copy');
if (successful) {
showSuccess($button, originalText);
} else {
showError($button, originalText);
}
} catch (err) {
showError($button, originalText);
}
$temp.remove();
}
function showSuccess($button, originalText) {
mw.notify('Adresse copiée dans le presse-papier !', {
type: 'success',
autoHide: true,
tag: 'minecraft-connect'
});
$button
.text('✓ Copié !')
.removeClass('mw-ui-progressive')
.addClass('mw-ui-constructive')
.prop('disabled', true);
setTimeout(function() {
$button
.text(originalText + ' 📋')
.prop('disabled', false)
.removeClass('mw-ui-constructive')
.addClass('mw-ui-progressive');
}, 2000);
}
function showError($button, originalText) {
mw.notify('Erreur lors de la copie', {
type: 'error',
autoHide: true,
tag: 'minecraft-connect'
});
$button
.text('✗ Erreur')
.removeClass('mw-ui-progressive')
.addClass('mw-ui-destructive');
setTimeout(function() {
$button
.text(originalText + ' 📋')
.removeClass('mw-ui-destructive')
.addClass('mw-ui-progressive');
}, 2000);
}
// Initialisation au chargement et pour VisualEditor
mw.hook('wikipage.content').add(initMinecraftButtons);
}());
/* === Modèle:Règle — copie d'ancre === */
mw.hook('wikipage.content').add(function ($content) {
/* Crée le toast une seule fois */
var $toast = $('#regle-toast');
if ($toast.length === 0) {
$toast = $('<div>')
.attr('id', 'regle-toast')
.addClass('regle-toast')
.appendTo('body');
}
var toastTimer;
function showToast(message) {
clearTimeout(toastTimer);
$toast.text(message).addClass('regle-toast--visible');
toastTimer = setTimeout(function () {
$toast.removeClass('regle-toast--visible');
}, 2000);
}
/* Cible tous les liens internes dont le href commence par #r- */
$content.find('a[href^="#r-"]').off('click.regle').on('click.regle', function (e) {
e.preventDefault();
var ancre = $(this).attr('href').replace('#', '');
var url = window.location.origin
+ window.location.pathname
+ '#' + ancre;
/* Défilement vers l'ancre */
var cible = document.getElementById(ancre);
if (cible) {
cible.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
/* Mise à jour de l'URL */
history.replaceState(null, '', '#' + ancre);
/* Copie dans le presse-papier */
if (navigator.clipboard && window.isSecureContext) {
navigator.clipboard.writeText(url)
.then(function () { showToast('🔗 Lien copié !'); })
.catch(function () { showToast('❌ Copie impossible'); });
} else {
/* Fallback navigateurs anciens */
var $tmp = $('<textarea>')
.val(url)
.css({ position: 'fixed', opacity: 0 })
.appendTo('body');
$tmp[0].select();
try {
document.execCommand('copy');
showToast('Lien copié !');
} catch (err) {
showToast('❌ Copie impossible');
}
$tmp.remove();
}
});
});
/* === Modèle:Règle — injection CSS du toast === */
(function () {
if (document.getElementById('regle-toast-style')) return;
var style = document.createElement('style');
style.id = 'regle-toast-style';
style.textContent = [
'.regle-toast {',
' position: fixed;',
' bottom: 2rem;',
' left: 50%;',
' transform: translateX(-50%) translateY(1rem);',
' background: var(--color-surface-2);',
' color: var(--color-base);',
' border: 1px solid var(--color-surface-4);',
' padding: 0.4rem 1rem;',
' border-radius: var(--border-radius-pill, 2rem);',
' font-size: 0.875rem;',
' font-weight: 500;',
' letter-spacing: 0.01em;',
' opacity: 0;',
' pointer-events: none;',
' transition: opacity 0.25s ease, transform 0.25s ease;',
' z-index: 200000;',
' white-space: nowrap;',
' box-shadow: var(--box-shadow-dialog, 0 4px 16px rgba(0,0,0,0.15));',
' display: flex;',
' align-items: center;',
' gap: 0.4em;',
'}',
'.regle-toast.regle-toast--visible {',
' opacity: 1;',
' transform: translateX(-50%) translateY(0);',
'}'
].join('\n');
document.head.appendChild(style);
}());
/* === fin injection CSS === */
/* === fin Modèle:Règle === */
/* MiniCard Grid - Ajustement dynamique des colonnes */
( function () {
'use strict';
function adjustMiniCardGrids() {
document.querySelectorAll( '.minicard-grid' ).forEach( function ( grid ) {
var cards = grid.querySelectorAll( '.minicard' );
var total = cards.length;
if ( total === 0 ) return;
var containerWidth = grid.offsetWidth;
var minCardWidth = 130; /* largeur minimale souhaitée par carte */
var gap = 12;
/* Nombre max de colonnes qui tiennent dans le conteneur */
var maxCols = Math.floor(
( containerWidth + gap ) / ( minCardWidth + gap )
);
maxCols = Math.max( 1, Math.min( maxCols, total ) );
/* On cherche le diviseur de total le plus proche de maxCols */
var bestCols = 1;
for ( var n = 1; n <= maxCols; n++ ) {
if ( total % n === 0 ) {
bestCols = n;
}
}
/* Si aucun diviseur exact, on prend maxCols directement */
/* (dernière ligne incomplète inévitable, mais on maximise l'usage) */
if ( bestCols === 1 && maxCols > 1 ) {
bestCols = maxCols;
}
grid.style.gridTemplateColumns = 'repeat(' + bestCols + ', 1fr)';
} );
}
/* Debounce pour éviter trop d'appels au resize */
var resizeTimer;
function onResize() {
clearTimeout( resizeTimer );
resizeTimer = setTimeout( adjustMiniCardGrids, 100 );
}
/* Init au chargement */
if ( document.readyState === 'loading' ) {
document.addEventListener( 'DOMContentLoaded', adjustMiniCardGrids );
} else {
adjustMiniCardGrids();
}
window.addEventListener( 'resize', onResize );
}() );