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
Hiob (discussion | contributions)
m citizen style
Hiob (discussion | contributions)
Aucun résumé des modifications
Ligne 254 : Ligne 254 :


/* === fin Modèle:Règle === */
/* === 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 );
}() );

Version du 4 mars 2026 à 15:34

/* 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 );

}() );
Les témoins (''cookies'') nous aident à fournir nos services. En utilisant nos services, vous acceptez notre utilisation de témoins.