MediaWiki:Gadget-multiupload.js
Apparence
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.
function sanitize(word) { return word .replace(/&/g, "&") .replace(/</g, "<") .replace(/>/g, ">") .replace(/"/g, """) .replace(/'/g, "'"); } function createFilePreview(file, isPerFile) { var filePreview = ""; if (file.name.endsWith('.mp4')) { filePreview = '<video width="220" height="150" controls>' + '<source src="' + URL.createObjectURL(file) + '" type="video/mp4">' + '</video>'; } else if (file.name.endsWith('.ogg')) { filePreview = '<div style="width:220px"><audio controls style="width: 220px;">' + '<source src="' + URL.createObjectURL(file) + '" type="audio/ogg">' + '</audio></div>'; } else { if (isPerFile) { filePreview = $('<img>').attr('src', URL.createObjectURL(file)).css({ 'max-width': '100%', 'max-height': '150px', 'display': 'block', 'margin-left': '10px' }); } else { filePreview = $('<img>').attr('src', URL.createObjectURL(file)).css({ 'max-width': '220px', 'max-height': '150px' }); } } return filePreview; } $(function() { // Ajouter un lien "Téléversement multiple" à la barre latérale var sidebarLink = $('<li id="t-multiupload" class="mw-list-item">').append( $('<a>').attr('href', '#').text('Téléversement multiple') ); $('#t-upload').after(sidebarLink); // Variables globales var wasPreviousFileUploaded = true; var defaultDescription = ""; var moduleDescriptionDescription = '{{#' + 'invoke:Description|sprite|source=}}'; var teraRaidDescription = "Image pour le [[cristal de raid " + "événementiel XXX]].\n\n" + "{{Informations Fichier\n" + "| source=[https://serebii.net/scarletviolet/teraraidbattleevents.shtml " + "Serebii]\n" + "| auteur=[[GAME FREAK (studio de développement)" + "|GAME FREAK]]\n" + "}}\n\n" + "[[Catégorie:Image de raid "+ "Téracristal événementiel]]\n" + "[[Catégorie:Image Pokémon " + "représentant XXX]]"; // Lorsque le lien est cliqué, afficher le modal de sélection de mode sidebarLink.on('click', function(event) { event.preventDefault(); showOptionModal(); }); function showOptionModal() { var modal = $('<div>').addClass('mw-body-content').css({ 'position': 'fixed', 'top': '50%', 'left': '50%', 'transform': 'translate(-50%, -50%)', 'background-color': '#FFF', 'padding': '15px', 'box-shadow': '0px 0px 20px rgba(0, 0, 0, 0.3)', 'z-index': '1001', 'width': '700px', 'line-height': '22.4px', 'border-radius': '10px', 'border': 'solid 1px #888' }); var title = $('<h2>').text('Téléversement multiple').css({ 'margin-bottom': '10px', }); var description = "<div style='font-size:14px'><p>Utilisez ce formulaire pour téléverser plusieurs fichiers à la fois sur le serveur. " + "Pour voir ou rechercher des images précédemment envoyées, consultez la <a href='/Spécial:Liste_des_fichiers' title='Spécial:Liste des fichiers'>liste des fichiers téléversés</a>.</p>" + "<p>Avant de téléverser un nouveau fichier, assurez-vous d'avoir lu la <a href='/Aide:Ajouter_une_image' title='Aide:Ajouter une image'>page d'aide dédiée</a>. " + "Elle contient des éléments essentiels concernant le format, la classification et le bon usage des fichiers.</p>" + "<p>Mal utilisé, les modifications engendrées par ce gadget peuvent s'avérer très longues à réparer. " + "Ne l'utilisez pas n'importe comment.</p>" + '<hr style="margin:10px 0px;">' + "<p>Sélectionnez une option pour renseigner la description des fichiers à importer :</p></div>"; var buttonContainer = $('<div>').css({ 'display': 'flex', 'justify-content': 'space-between', 'margin-top': '15px' }); var perFileBtn = $('<button>').text('Description par fichier').css({ 'padding': '10px', 'background-color': '#3366CC', 'color': '#FFF', 'border': 'none', 'border-radius': '5px', 'cursor': 'pointer', 'width': '32%', 'font-size': '14px', 'font-weight': 'bold' }); var globalDescriptionBtn = $('<button>').text('Description globale').css({ 'padding': '10px', 'background-color': '#3366CC', 'color': '#FFF', 'border': 'none', 'border-radius': '5px', 'cursor': 'pointer', 'width': '32%', 'font-size': '14px', 'font-weight': 'bold' }); var cancelBtn = $('<button>').text('Annuler').css({ 'padding': '10px', 'background-color': '#CCC', 'color': '#000', 'border': 'none', 'border-radius': '5px', 'cursor': 'pointer', 'width': '32%', 'font-size': '14px', 'font-weight': 'bold' }); perFileBtn.on('click', function() { modal.remove(); openFileSelector(true); }); globalDescriptionBtn.on('click', function() { modal.remove(); openFileSelector(false); }); cancelBtn.on('click', function() { modal.remove(); }); buttonContainer.append(perFileBtn, globalDescriptionBtn, cancelBtn); modal.append(title, description, buttonContainer); $('body').append(modal); } function openFileSelector(isPerFile) { var fileInput = $('<input>').attr({ 'type': 'file', 'multiple': 'multiple' }).css('display', 'none'); fileInput.on('change', function(event) { var files = event.target.files; if (files.length > 0) { if (isPerFile) { handleFiles(files); } else { createGlobalDescriptionModal(files); } } }); fileInput.click(); } function handleFiles(files) { var fileArray = Array.from(files); var index = 0; function nextFile() { if (index < fileArray.length) { createUploadModal(fileArray[index], index + 1, fileArray.length, function() { index++; nextFile(); }); } else { if (wasPreviousFileUploaded) { alert("Le dernier fichier a bien été téléversé."); } else { alert("Le dernier fichier n'a pas été téléversé."); } } } nextFile(); } function createUploadModal(file, fileIndex, totalFiles, callback) { var modal = $('<div>').addClass('mw-body-content').css({ 'position': 'fixed', 'top': '50%', 'left': '50%', 'transform': 'translate(-50%, -50%)', 'background-color': '#FFF', 'padding': '15px', 'box-shadow': '0px 0px 20px rgba(0, 0, 0, 0.3)', 'z-index': '1001', 'border-radius': '10px', 'border': 'solid 1px #888' }); var title = $('<h2>').text('Téléverser des fichiers (' + fileIndex + '/' + totalFiles + ')'); var previousFileState = $('<p>').css({ 'font-size': '14px', 'margin': '0px' }); if (wasPreviousFileUploaded) { previousFileState.css('color', 'green'); previousFileState.text('Le fichier précédent a bien été téléversé.'); } else { previousFileState.css('color', 'red'); previousFileState.text("Le fichier précédent n'a pas été téléversé."); } var fileNameLabel = $('<label>').text('Nom du fichier').css({ 'display': 'block', 'margin-bottom': '5px', 'font-weight': 'bold' }); var fileNameInput = $('<input>').attr('type', 'text').val(file.name).css({ 'width': '100%', 'padding': '10px', 'box-sizing': 'border-box', 'border': '1px solid #CCC', 'border-radius': '5px' }); var fileNameContainer = $('<div>'); fileNameContainer.append(fileNameLabel, fileNameInput); var upperContent = $('<div>').css({ 'width': '100%', 'display': 'flex', 'flex-direction': 'column', 'justify-content': 'space-between' }); // Pour un espacement plus harmonieux var spacingContainer = $('<div>').css({ 'height': '5px' }); if (fileIndex === 1) { upperContent.append(title, fileNameContainer, spacingContainer); } else { upperContent.append(title, previousFileState, fileNameContainer, spacingContainer); } var filePreview = createFilePreview(file, true); var upperContainer = $('<div>').css({ 'display': 'flex' }); upperContainer.append(upperContent, filePreview); var descriptionLabel = $('<label>').text('Description du fichier').css({ 'display': 'block', 'margin-bottom': '5px', 'font-weight': 'bold' }); var defaultDescriptionTemplate = "<!-- Remplacer cette ligne par la description du fichier -->\n\n" + "{{Informations Fichier\n" + "| source=<!-- Indiquer un lien vers l'endroit où le fichier a été obtenu, ou le nom de l'utilisateur l'ayant créé -->\n" + "| auteur=<!-- Indiquer l'auteur de l'image au sens juridique (développeur du jeu, etc) -->\n" + "}}\n\n" + "<!-- Remplacer cette ligne par la catégorisation du fichier -->"; if (fileIndex === 1) { defaultDescription = defaultDescriptionTemplate; } var descriptionInput = $('<textarea>').attr('placeholder', 'Entrer la description du fichier').text(defaultDescription).css({ 'width': '700px', 'height': '170px', 'padding': '10px', 'margin-bottom': '10px', 'box-sizing': 'border-box', 'border': '1px solid #CCC', 'border-radius': '5px' }); var buttonContainer = $('<div>').css({ 'display': 'flex', 'white-space': 'nowrap' }); var descriptionOptions = [ {text: 'Description par défaut', value: defaultDescriptionTemplate}, {text: 'Module description', value: moduleDescriptionDescription}, {text: 'Image de raid Téracristal', value: teraRaidDescription} ]; var descriptionSelect = $('<select>').css({ 'width': '100%', 'min-width': '200px', 'padding': '10px', 'box-sizing': 'border-box', 'border': '1px solid #CCC', 'border-radius': '5px' }); descriptionOptions.forEach(function(option) { descriptionSelect.append($('<option>').text(option.text).val(option.value)); }); descriptionSelect.on('change', function() { descriptionInput.val($(this).val()); defaultDescription = $(this).val(); }); var uploadBtn = $('<button>').text('Téléverser').css({ 'padding': '10px 20px', 'background-color': '#3366CC', 'color': '#FFF', 'border': 'none', 'border-radius': '5px', 'cursor': 'pointer', 'font-size': '14px', 'font-weight': 'bold', 'margin-left': '10px' }); var cancelBtn = $('<button>').text('Annuler').css({ 'padding': '10px 20px', 'background-color': '#CCC', 'color': '#000', 'border': 'none', 'border-radius': '5px', 'cursor': 'pointer', 'font-size': '14px', 'font-weight': 'bold', 'margin-left': '10px' }); var cancelAllBtn = $('<button>').text('Annuler tout').css({ 'padding': '10px 20px', 'background-color': '#CCC', 'color': '#000', 'border': 'none', 'border-radius': '5px', 'cursor': 'pointer', 'font-size': '14px', 'font-weight': 'bold', 'margin-left': '10px' }); uploadBtn.on('click', function() { uploadBtn.css({ 'cursor': 'wait', 'background-color': '#7A95CC' }); uploadBtn.text("Téléversement en cours..."); uploadFile(file, fileNameInput.val(), descriptionInput.val(), modal, callback); }); cancelBtn.on('click', function() { wasPreviousFileUploaded = false; modal.remove(); // Pour éviter d'afficher l'état du dernier fichier s'il a été annulé if (fileIndex != totalFiles) { callback(); } }); cancelAllBtn.on('click', function() { wasPreviousFileUploaded = false; modal.remove(); // Reset the file handling process }); buttonContainer.append(descriptionSelect, uploadBtn, cancelBtn, cancelAllBtn); modal.append(upperContainer, descriptionLabel, descriptionInput, buttonContainer); $('body').append(modal); } function uploadFile(file, fileName, description, modal, callback) { var formData = new FormData(); var text = description; if (!text.includes("== Description ==")) { text = "== Description ==\n" + text; } formData.append('file', file); formData.append('filename', fileName); formData.append('text', text); formData.append('comment', description); formData.append('action', 'upload'); formData.append('tags', 'multiupload'); formData.append('ignorewarnings', '1'); formData.append('format', 'json'); formData.append('token', mw.user.tokens.get('csrfToken')); $.ajax({ url: mw.util.wikiScript('api'), type: 'POST', data: formData, processData: false, contentType: false, success: function(response) { if (response.upload && response.upload.result === 'Success') { wasPreviousFileUploaded = true; } else { wasPreviousFileUploaded = false; console.error(response); } modal.remove(); callback(); }, error: function(xhr, status, error) { wasPreviousFileUploaded = false; console.error(error); modal.remove(); callback(); } }); } function createGlobalDescriptionModal(files) { var fileNames = []; for (i = 0; i < files.length; i++) { fileNames[i] = files[i].name; } var modal = $('<div>').addClass('mw-body-content').css({ 'position': 'fixed', 'top': '50%', 'left': '50%', 'transform': 'translate(-50%, -50%)', 'background-color': '#FFF', 'padding': '15px', 'box-shadow': '0px 0px 20px rgba(0, 0, 0, 0.3)', 'z-index': '1001', 'border-radius': '10px', 'border': 'solid 1px #888' }); var s = ''; if (files.length > 1) { s = 's'; } var title = $('<h2>').text('Téléverser ' + files.length + ' fichier' + s).css({ 'margin-bottom': '25px' }); var description = $('<p>').text('Les fichiers auront tous la description suivante.').css({ 'font-size': '14px', 'margin-bottom': '20px' }); var upperContent = $('<div>').css({ 'width': '100%' }); upperContent.append(title, description); var descriptionLabel = $('<label>').text('Description des fichiers').css({ 'display': 'block', 'margin-bottom': '5px', 'font-weight': 'bold' }); var defaultDescription = "<!-- Remplacer cette ligne par la description des fichiers -->\n\n" + "{{Informations Fichier\n" + "| source=<!-- Indiquer un lien vers l'endroit où les fichiers ont été obtenus, ou le nom de l'utilisateur les ayant créés -->\n" + "| auteur=<!-- Indiquer l'auteur des images au sens juridique (développeur du jeu, etc) -->\n" + "}}\n\n" + "<!-- Remplacer cette ligne par la catégorisation des fichiers -->"; var descriptionInput = $('<textarea>').attr('placeholder', 'Entrer la description des fichiers').text(defaultDescription).css({ 'width': '700px', 'height': '170px', 'padding': '10px', 'margin-bottom': '10px', 'box-sizing': 'border-box', 'border': '1px solid #CCC', 'border-radius': '5px' }); var filePreviewContainer = $('<div>').css({ 'width': '220px', 'height': '150px' }); var filePanel = $('<div>'); var fileContainer = $('<div>').css({ 'display': 'flex', 'align-items': 'center', 'text-align': 'center', 'margin-left': '5px' }); var leftArrow = $('<button>').text('<').css({ 'padding': '5px 10px', 'margin-right': '10px', 'background-color': '#CCC', 'color': '#000', 'border': 'none', 'border-radius': '5px', 'cursor': 'pointer', 'font-size': '14px', 'font-weight': 'bold' }); var rightArrow = $('<button>').text('>').css({ 'padding': '5px 10px', 'margin-left': '10px', 'background-color': '#CCC', 'color': '#000', 'border': 'none', 'border-radius': '5px', 'cursor': 'pointer', 'font-size': '14px', 'font-weight': 'bold', }); var filePreviewIndex = 0; var filePreview = $('<div>').html(createFilePreview(files[filePreviewIndex], false)); filePreviewContainer.append(filePreview); var fileTextInput = $('<input>').val(sanitize(fileNames[filePreviewIndex])).css({ 'margin-bottom': '0px', 'margin-top': '5px', 'padding': '10px', 'box-sizing': 'border-box', 'border': '1px solid #CCC', 'border-radius': '5px', 'width': '100%' }); fileTextInput.on('input', function() { fileNames[filePreviewIndex] = $(this).val(); }); function showPreviousImage() { if (filePreviewIndex > 0) { filePreviewIndex--; } else { filePreviewIndex = files.length - 1; } filePreview.html(createFilePreview(files[filePreviewIndex], false)); fileTextInput.val(fileNames[filePreviewIndex]); } function showNextImage() { if (filePreviewIndex < files.length - 1) { filePreviewIndex++; } else { filePreviewIndex = 0; } filePreview.html(createFilePreview(files[filePreviewIndex], false)); fileTextInput.val(fileNames[filePreviewIndex]); } leftArrow.on('click', showPreviousImage); rightArrow.on('click', showNextImage); window.addEventListener('keydown', function(event) { if (event.target.matches('input, textarea, select, button')) { return; } if (event.key === 'ArrowLeft') { showPreviousImage(); } else if (event.key === 'ArrowRight') { showNextImage(); } }); if (files.length > 1) { fileContainer.append(leftArrow, filePreviewContainer, rightArrow); } else { fileContainer.append(filePreviewContainer); } filePanel.append(fileContainer, fileTextInput); var upperContainer = $('<div>').css({ 'display': 'flex' }); upperContainer.append(upperContent, filePanel); var buttonContainer = $('<div>').css({ 'display': 'flex', 'white-space': 'nowrap' }); var descriptionOptions = [ {text: 'Description par défaut', value: defaultDescription}, {text: 'Module description', value: moduleDescriptionDescription}, {text: 'Image de raid Téracristal', value: teraRaidDescription} ]; var descriptionSelect = $('<select>').css({ 'width': '100%', 'min-width': '200px', 'padding': '10px', 'box-sizing': 'border-box', 'border': '1px solid #CCC', 'border-radius': '5px' }); descriptionOptions.forEach(function(option) { descriptionSelect.append($('<option>').text(option.text).val(option.value)); }); descriptionSelect.on('change', function() { descriptionInput.val($(this).val()); }); var uploadBtn = $('<button>').text('Téléverser tout').css({ 'padding': '10px 20px', 'background-color': '#3366CC', 'color': '#FFF', 'border': 'none', 'border-radius': '5px', 'cursor': 'pointer', 'font-size': '14px', 'font-weight': 'bold', 'margin-left': '10px' }); var cancelBtn = $('<button>').text('Annuler').css({ 'padding': '10px 20px', 'background-color': '#CCC', 'color': '#000', 'border': 'none', 'border-radius': '5px', 'cursor': 'pointer', 'font-size': '14px', 'font-weight': 'bold', 'margin-left': '10px' }); uploadBtn.on('click', function() { uploadBtn.css({ 'cursor': 'wait', 'background-color': '#7A95CC' }); uploadBtn.text("Téléversement en cours..."); uploadAllFilesSequentially(files, fileNames, descriptionInput.val(), modal); }); cancelBtn.on('click', function() { modal.remove(); }); buttonContainer.append(descriptionSelect, uploadBtn, cancelBtn); modal.append(upperContainer, descriptionLabel, descriptionInput, buttonContainer); $('body').append(modal); function uploadAllFilesSequentially(files, fileNames, description, modal) { var index = 0; var failedFiles = []; function uploadNextFile() { uploadBtn.text("Téléversement en cours... (" + (index + 1) + "/" + files.length + ")"); if (index < files.length) { var file = files[index]; var fileName = fileNames[index]; var formData = new FormData(); var text = description; if (!text.includes("== Description ==")) { text = "== Description ==\n" + text; } formData.append('file', file); formData.append('filename', fileName); formData.append('text', text); formData.append('comment', description); formData.append('action', 'upload'); formData.append('tags', 'multiupload'); formData.append('ignorewarnings', '1'); formData.append('format', 'json'); formData.append('token', mw.user.tokens.get('csrfToken')); $.ajax({ url: mw.util.wikiScript('api'), type: 'POST', data: formData, processData: false, contentType: false, success: function(response) { if (response.upload && response.upload.result === 'Success') { console.log('Fichier téléversé avec succès : ' + fileName); } else { console.error('Erreur lors du téléversement du fichier : ' + fileName, response); failedFiles.push(fileName); } index++; uploadNextFile(); }, error: function(xhr, status, error) { console.error('Erreur lors du téléversement du fichier : ' + fileName, error); index++; uploadNextFile(); } }); } else { if (failedFiles.length > 0) { alert("Le téléversement des fichiers est terminé. Les fichiers suivants n'ont pas pu être téléversés :\n" + failedFiles.join('\n')); } else { alert('Tous les fichiers ont bien été téléversés.'); } modal.remove(); } } uploadNextFile(); } } });