|
|
| (6 versions intermédiaires par le même utilisateur non affichées) |
| Ligne 2 : |
Ligne 2 : |
|
| |
|
| /* ============================================================ | | /* ============================================================ |
| * Infothèque — Gadget "Ajouter un téléchargement" | | * Barre de recherche de la page d'accueil |
| * À 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 () { | | (function () { |
| 'use strict'; | | '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() { | | function init() { |
| var textarea = document.getElementById('wpTextbox1'); | | var trigger = document.querySelector('.ith-home-search'); |
| if (!textarea) { | | var real = document.getElementById('citizen-search-summary'); |
| return; // pas en édition source | | if (!trigger || !real) { |
| | return; |
| } | | } |
| addButton(textarea); | | trigger.setAttribute('role', 'button'); |
| }
| | trigger.setAttribute('tabindex', '0'); |
| | | trigger.addEventListener('click', function () { |
| function addButton(textarea) {
| | real.click(); |
| 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); | | trigger.addEventListener('keydown', function (e) { |
| }
| | if (e.key === 'Enter' || e.key === ' ') { |
| | | e.preventDefault(); |
| function openModal(textarea) {
| | real.click(); |
| 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();
| |
| } | | } |
|
| |
|