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. */
/* ============================================================
* Infothèque — Gadget "Ajouter un téléchargement"
* À coller dans : MediaWiki:Common.js (à la suite du contenu existant)
*
* N'agit que sur la page d'édition en mode source (là où
* #wpTextbox1 existe). Ajoute un bouton qui ouvre un petit
* formulaire, puis insère automatiquement le bon bloc de
* paramètres numérotés dans l'appel {{Téléchargements|...}}
* existant (ou en crée un nouveau à l'endroit du curseur si
* aucun n'est trouvé sur la page).
*
* Le format (disquette / CD / ZIP) est traduit automatiquement
* en icône — voir ITH_DL_FORMATS ci-dessous. Adapte les noms de
* fichiers si tu uploades tes icônes sous d'autres noms.
* ============================================================ */
(function () {
'use strict';
var ITH_DL_FORMATS = {
disquette: { label: 'Disquette', wikitext: '[[Fichier:Icône disquettes.png|centré]]' },
cd: { label: 'CD-ROM / DVD', wikitext: '[[Fichier:Icone_CD.png|centré|sans_cadre]]' },
zip: { label: 'Fichier ZIP / téléchargement numérique', wikitext: '[[Fichier:Zipfldr.dll 14 123-3.png|centré|sans_cadre]]' },
autre: { label: 'Autre (icône personnalisée)', wikitext: '' }
};
function init() {
var textarea = document.getElementById('wpTextbox1');
if (!textarea) {
return; // pas en édition source
}
addButton(textarea);
}
function addButton(textarea) {
var btn = document.createElement('button');
btn.type = 'button';
btn.id = 'ith-dl-add-btn';
btn.className = 'ith-dl-add-btn';
btn.textContent = '+ Ajouter un téléchargement';
btn.addEventListener('click', function () {
openModal(textarea);
});
textarea.parentNode.insertBefore(btn, textarea);
}
function openModal(textarea) {
var overlay = document.createElement('div');
overlay.className = 'ith-dl-overlay';
var box = document.createElement('div');
box.className = 'ith-dl-modal';
box.innerHTML =
'<h3>Ajouter un téléchargement</h3>' +
'<label>Édition <span class="ith-dl-req">*</span><input type="text" id="ith-dl-edition" placeholder="Ex : Windows 95"></label>' +
'<label>Version<input type="text" id="ith-dl-version" placeholder="Ex : OSR 2.5 OEM 4.03.1216"></label>' +
'<label>Langue<input type="text" id="ith-dl-langue" value="Français"></label>' +
'<label>Description<textarea id="ith-dl-description" rows="2" placeholder="Notes libres, facultatif"></textarea></label>' +
'<label>Format<select id="ith-dl-format"></select></label>' +
'<label id="ith-dl-format-autre-wrap" style="display:none">Icône personnalisée (wikitexte)<input type="text" id="ith-dl-format-autre" placeholder="[[Fichier:Mon icône.png|centré]]"></label>' +
'<label>Image<input type="text" id="ith-dl-image" placeholder="[[Fichier:Photo.jpg|centré|vignette]] (facultatif)"></label>' +
'<label>Liens de téléchargement <span class="ith-dl-req">*</span>' +
'<textarea id="ith-dl-liens" rows="3" placeholder="Une ligne par lien, format : URL | Texte du lien"></textarea>' +
'</label>' +
'<div class="ith-dl-actions">' +
'<button type="button" id="ith-dl-cancel" class="ith-dl-btn-secondary">Annuler</button>' +
'<button type="button" id="ith-dl-submit" class="ith-dl-btn-primary">Ajouter</button>' +
'</div>' +
'<p class="ith-dl-error" id="ith-dl-error" style="display:none"></p>';
overlay.appendChild(box);
document.body.appendChild(overlay);
var select = box.querySelector('#ith-dl-format');
Object.keys(ITH_DL_FORMATS).forEach(function (key) {
var opt = document.createElement('option');
opt.value = key;
opt.textContent = ITH_DL_FORMATS[key].label;
select.appendChild(opt);
});
select.addEventListener('change', function () {
var autreWrap = box.querySelector('#ith-dl-format-autre-wrap');
autreWrap.style.display = select.value === 'autre' ? '' : 'none';
});
box.querySelector('#ith-dl-cancel').addEventListener('click', closeModal);
overlay.addEventListener('click', function (e) {
if (e.target === overlay) closeModal();
});
box.querySelector('#ith-dl-submit').addEventListener('click', function () {
submit(textarea);
});
function closeModal() {
document.body.removeChild(overlay);
}
function submit(ta) {
var edition = box.querySelector('#ith-dl-edition').value.trim();
var liensRaw = box.querySelector('#ith-dl-liens').value.trim();
var errEl = box.querySelector('#ith-dl-error');
if (!edition || !liensRaw) {
errEl.textContent = 'Édition et au moins un lien de téléchargement sont obligatoires.';
errEl.style.display = '';
return;
}
var version = box.querySelector('#ith-dl-version').value.trim();
var langue = box.querySelector('#ith-dl-langue').value.trim();
var description = box.querySelector('#ith-dl-description').value.trim();
var formatKey = select.value;
var format = formatKey === 'autre'
? box.querySelector('#ith-dl-format-autre').value.trim()
: ITH_DL_FORMATS[formatKey].wikitext;
var image = box.querySelector('#ith-dl-image').value.trim();
var liens = buildLiens(liensRaw);
var data = {
edition: edition,
version: version,
langue: langue,
description: description,
format: format,
image: image,
liens: liens
};
insertIntoTextarea(ta, data);
closeModal();
}
}
function buildLiens(raw) {
var lines = raw.split('\n').map(function (l) { return l.trim(); }).filter(Boolean);
var formatted = lines.map(function (line) {
var parts = line.split('|');
var url = (parts[0] || '').trim();
var texte = (parts[1] || 'Téléchargement').trim();
return '[' + url + ' ' + texte + ']';
});
if (formatted.length === 1) {
return formatted[0];
}
return formatted.map(function (f) { return '* ' + f; }).join('\n');
}
function insertIntoTextarea(textarea, data) {
var text = textarea.value;
var startIdx = text.indexOf('{{Téléchargements');
if (startIdx === -1) {
var block = '{{Téléchargements\n' + buildParamLines(1, data) + '\n}}';
insertAtCursor(textarea, block);
return;
}
// Trouve l'accolade fermante correspondante en comptant la profondeur des {{ }}.
var depth = 0;
var endIdx = -1;
for (var i = startIdx; i < text.length - 1; i++) {
if (text[i] === '{' && text[i + 1] === '{') { depth++; i++; }
else if (text[i] === '}' && text[i + 1] === '}') {
depth--; i++;
if (depth === 0) { endIdx = i; break; }
}
}
if (endIdx === -1) {
// Structure inattendue : on n'insère pas au hasard, on ajoute un nouveau bloc à part.
var fallback = '{{Téléchargements\n' + buildParamLines(1, data) + '\n}}';
insertAtCursor(textarea, fallback);
return;
}
var callText = text.slice(startIdx, endIdx + 1);
var maxIndex = 0;
var re = /edition(\d+)\s*=/g;
var m;
while ((m = re.exec(callText))) {
maxIndex = Math.max(maxIndex, parseInt(m[1], 10));
}
var nextIndex = maxIndex + 1;
if (nextIndex > 10) {
alert('Ce tableau contient déjà 10 téléchargements (le maximum géré par le modèle). Préviens l\'admin du wiki pour étendre le modèle.');
return;
}
var paramLines = buildParamLines(nextIndex, data);
// insère juste avant le "}}" final (donc avant l'avant-dernier caractère de endIdx)
var insertPos = endIdx - 1;
var newText = text.slice(0, insertPos) + '\n' + paramLines + text.slice(insertPos);
textarea.value = newText;
textarea.dispatchEvent(new Event('input', { bubbles: true }));
textarea.focus();
}
function buildParamLines(n, data) {
return [
' |edition' + n + '=' + data.edition,
' |version' + n + '=' + data.version,
' |langue' + n + '=' + data.langue,
' |description' + n + '=' + data.description,
' |format' + n + '=' + data.format,
' |image' + n + '=' + data.image,
' |liens' + n + '=' + data.liens
].join('\n');
}
function insertAtCursor(textarea, text) {
var start = textarea.selectionStart || 0;
var end = textarea.selectionEnd || 0;
var before = textarea.value.slice(0, start);
var after = textarea.value.slice(end);
textarea.value = before + text + after;
textarea.dispatchEvent(new Event('input', { bubbles: true }));
textarea.focus();
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();