MediaWiki:Common.js
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).
- Internet Explorer / Edge : maintenez la touche Ctrl en cliquant sur le bouton Actualiser ou pressez Ctrl + F5.
- Opera : appuyez sur Ctrl + F5.
/* Tout JavaScript présent ici sera exécuté par tous les utilisateurs à chaque chargement de page. */
/* ============================================================
NEPHILIM — Double scrollbar (haut + bas) pour tableaux
À copier dans MediaWiki:Common.js
Fonctionne avec les paires :
<div class="neph-scroll-top"><div class="neph-scroll-top-spacer"></div></div>
<div class="neph-scroll-table"> ... </div>
============================================================ */
( function () {
'use strict';
function initDoubleScroll() {
// Cherche toutes les paires top + table
var tops = document.querySelectorAll( '.neph-scroll-top' );
tops.forEach( function ( topDiv ) {
// Le conteneur de tableau est l'élément frère suivant
var tableDiv = topDiv.nextElementSibling;
if ( !tableDiv || !tableDiv.classList.contains( 'neph-scroll-table' ) ) {
return;
}
// Trouve ou crée le spacer dans la barre haute
var spacer = topDiv.querySelector( '.neph-scroll-top-spacer' );
if ( !spacer ) {
spacer = document.createElement( 'div' );
spacer.className = 'neph-scroll-top-spacer';
topDiv.appendChild( spacer );
}
// Synchronise la largeur du spacer avec le contenu du tableau
function syncWidth() {
spacer.style.width = tableDiv.scrollWidth + 'px';
}
syncWidth();
// Re-synchronise si la fenêtre change de taille
window.addEventListener( 'resize', syncWidth );
// Observe aussi les changements de contenu (chargement tardif, etc.)
if ( typeof ResizeObserver !== 'undefined' ) {
var ro = new ResizeObserver( syncWidth );
ro.observe( tableDiv );
}
// --- Synchronisation bidirectionnelle du scroll ---
var syncing = false;
topDiv.addEventListener( 'scroll', function () {
if ( !syncing ) {
syncing = true;
tableDiv.scrollLeft = topDiv.scrollLeft;
syncing = false;
}
} );
tableDiv.addEventListener( 'scroll', function () {
if ( !syncing ) {
syncing = true;
topDiv.scrollLeft = tableDiv.scrollLeft;
syncing = false;
}
} );
} );
}
// Lance après le chargement complet de la page
if ( document.readyState === 'complete' ) {
initDoubleScroll();
} else {
window.addEventListener( 'load', initDoubleScroll );
}
}() );
/* ============================================
CALCULATEUR DE RÉSOLUTION — Nephilim 5e
À ajouter dans MediaWiki:Common.js
============================================ */
( function () {
'use strict';
// Ne s'active que si le calculateur est présent sur la page
var calc = document.querySelector( '.neph-calc' );
if ( !calc ) {
return;
}
// Raccourci pour trouver les éléments par data-neph ou data-neph-out
function input( name ) {
return calc.querySelector( '[data-neph="' + name + '"]' );
}
function output( name ) {
return calc.querySelector( '[data-neph-out="' + name + '"]' );
}
function val( name ) {
var el = input( name );
return el ? ( parseInt( el.value, 10 ) || 0 ) : 0;
}
// Recalcule les scores à chaque changement de select
function compute() {
var vecu = val( 'vecu' );
var approche = val( 'approche' );
var metamorphe = val( 'metamorphe' );
var bonus = val( 'bonus' );
var malus = val( 'malus' );
var brut = vecu + approche + metamorphe;
var net = Math.max( 0, brut + bonus - malus );
var seuil = Math.min( net * 10, 100 );
output( 'scoreBrut' ).textContent = brut;
output( 'scoreNet' ).textContent = net;
output( 'seuil' ).textContent = seuil + '%';
// Masquer le résultat précédent
var panel = output( 'resultPanel' );
panel.className = 'neph-calc-result';
output( 'resetWrap' ).className = 'neph-calc-reset-wrap';
output( 'marginBar' ).style.display = 'none';
output( 'marginFill' ).style.width = '0';
}
// Résout l'action
function resolve() {
var net = Math.max( 0, val( 'vecu' ) + val( 'approche' ) + val( 'metamorphe' ) + val( 'bonus' ) - val( 'malus' ) );
var seuil = Math.min( net * 10, 100 );
var jetEl = input( 'jet' );
var jetInput = jetEl.value.trim();
if ( jetInput === '' ) {
jetEl.focus();
return;
}
var jetVal = parseInt( jetInput, 10 );
var isMaladresse = ( jetInput === '00' || jetInput === '000' || jetVal === 0 || jetVal === 100 );
if ( isMaladresse ) {
jetVal = 100;
}
var panel = output( 'resultPanel' );
var verdict = output( 'resultVerdict' );
var detail = output( 'resultDetail' );
var marginText = output( 'resultMargin' );
var marginBar = output( 'marginBar' );
var marginFill = output( 'marginFill' );
var resetWrap = output( 'resetWrap' );
// Reset classes
panel.className = 'neph-calc-result neph-visible';
marginBar.style.display = 'none';
marginFill.style.width = '0';
if ( isMaladresse ) {
panel.className += ' neph-maladresse';
verdict.textContent = '\u2620 Maladresse !';
detail.textContent = 'Échec critique \u2014 le sort s\'acharne sur le Nephilim.';
marginText.textContent = '';
} else if ( jetVal <= seuil ) {
// Réussite
var dizaines = Math.floor( jetVal / 10 );
var bonusMarge = Math.max( 0, net - 10 );
var marge = dizaines + bonusMarge;
panel.className += ' neph-success';
verdict.textContent = '\u2726 Réussite';
detail.textContent = 'Jet de ' + jetVal + ' \u2264 seuil de ' + seuil + '%';
var margeLabel = '';
if ( marge <= 1 ) { margeLabel = 'Réussite de justesse'; }
else if ( marge <= 3 ) { margeLabel = 'Réussite convenable'; }
else if ( marge <= 5 ) { margeLabel = 'Belle réussite'; }
else if ( marge <= 7 ) { margeLabel = 'Réussite remarquable'; }
else if ( marge <= 9 ) { margeLabel = 'Réussite mémorable'; }
else { margeLabel = 'Réussite extraordinaire'; }
var margeText = 'Marge de réussite : ' + marge;
if ( bonusMarge > 0 ) {
margeText += ' (' + dizaines + ' + ' + bonusMarge + ' bonus)';
}
margeText += ' \u2014 ' + margeLabel;
marginText.textContent = margeText;
marginBar.style.display = 'block';
var pct = Math.min( 100, Math.round( ( marge / 15 ) * 100 ) );
setTimeout( function () {
marginFill.style.width = pct + '%';
}, 50 );
} else {
// Échec
panel.className += ' neph-failure';
verdict.textContent = '\u2715 Échec';
detail.textContent = 'Jet de ' + jetVal + ' > seuil de ' + seuil + '%';
marginText.textContent = '';
}
resetWrap.className = 'neph-calc-reset-wrap neph-visible';
}
// Réinitialise tout
function resetAll() {
[ 'vecu', 'approche', 'metamorphe', 'bonus', 'malus' ].forEach( function ( name ) {
var el = input( name );
if ( el ) { el.value = '0'; }
} );
var jetEl = input( 'jet' );
if ( jetEl ) { jetEl.value = ''; }
compute();
}
// Attacher les événements aux selects
var selects = calc.querySelectorAll( '.neph-calc-select' );
for ( var i = 0; i < selects.length; i++ ) {
selects[ i ].addEventListener( 'change', compute );
}
// Bouton Résoudre
var btnResolve = calc.querySelector( '[data-neph-action="resolve"]' );
if ( btnResolve ) {
btnResolve.addEventListener( 'click', resolve );
}
// Bouton Réinitialiser
var btnReset = calc.querySelector( '[data-neph-action="reset"]' );
if ( btnReset ) {
btnReset.addEventListener( 'click', resetAll );
}
// Entrée dans le champ dé → résoudre
var jetEl = input( 'jet' );
if ( jetEl ) {
jetEl.addEventListener( 'keydown', function ( e ) {
if ( e.key === 'Enter' ) {
resolve();
}
} );
}
}() );