From a5407176155b0de97bb4d59d284f5fc587229884 Mon Sep 17 00:00:00 2001 From: Astrid van Eerd Date: Thu, 14 Nov 2024 22:24:06 +0100 Subject: [PATCH] [K6.3] Stripping linebreaks when removing attachment. (#9764) * Update upload.main.js Stripping linebreaks when removing attachment. * Update upload.main.js * Update upload.main.js Removed Insert private attachment as this doesn't work. Inserted private attachments are still visible for everyone. Buttons are now ok. * Update upload.main.js Remove all working I think * Update upload.main.js buttons display fixed and remove individual attachment now possible * Update upload.main.js Added buttons Is Private and all attachments private Requires adding language constants COM_KUNENA_ATTACHMENT_IS_PRIVATE and COM_KUNENA_ALL_ATTACHMENTS_ARE_PRIVATE added to transifex * Update upload.main.js hide insert when private is clicked and hide private when insert is clicked for individual attachment and all attachments * Update upload.main.js changed language constants to existing language constants for private buttons * Update upload.main.js All buttons should now be hidden as expected. * Update upload.main.js * Update upload.main.js --- src/media/kunena/core/js/upload.main.js | 1049 +++++++++++++---------- 1 file changed, 618 insertions(+), 431 deletions(-) diff --git a/src/media/kunena/core/js/upload.main.js b/src/media/kunena/core/js/upload.main.js index ae140a8f9b7..bec1a6940a0 100644 --- a/src/media/kunena/core/js/upload.main.js +++ b/src/media/kunena/core/js/upload.main.js @@ -68,228 +68,277 @@ jQuery(function ($) { var fileeditinline = 0; $('#set-secure-all').on('click', function (e) { - e.preventDefault(); - - const child = $('#kattach-list').find('input'); - const filesidtosetprivate = []; - - child.each(function (i, el) { - const elem = $(el); + e.preventDefault(); - if (!elem.attr('id').match("[a-z]{8}")) { - const fileid = elem.attr('id').match("[0-9]{1,8}"); + const child = $('#kattach-list').find('input'); + const filesidtosetprivate = []; + const $this = $(this); - filesidtosetprivate.push(fileid); - } - }); + child.each(function (i, el) { + const elem = $(el); - if (filesidtosetprivate.length !== 0) { - $.ajax({ - url: Joomla.getOptions('com_kunena.kunena_upload_files_set_private') + '&files_id=' + JSON.stringify(filesidtosetprivate), - type: 'POST' - }) - .done(function (data) { - - }) - .fail(function () { - //TODO: handle the error of ajax request - }); + if (!elem.attr('id').match("[a-z]{8}")) { + const fileid = elem.attr('id').match("[0-9]{1,8}"); + filesidtosetprivate.push(fileid); } }); - $('#remove-all').on('click', function (e) { - e.preventDefault(); - - $('#progress').hide(); - - $('#insert-all').removeClass('btn-success'); - $('#insert-all').addClass('btn-primary'); - $('#insert-all').html(Joomla.getOptions('com_kunena.icons.upload') + ' ' + Joomla.Text._('COM_KUNENA_UPLOADED_LABEL_INSERT_ALL_BUTTON')); - - $('#remove-all').hide(); - $('#insert-all').hide(); - - var editor_text = null; - if (Joomla.getOptions('com_kunena.ckeditor_config') !== undefined) { - editor_text = CKEDITOR.instances.message.getData(); - } else { - editor_text = sceditor.instance(document.getElementById('message')).val(); - } - - // Removing items in edit if they are present - if ($.isEmptyObject(filesedit) === false) { - const filesidinedittodelete = []; - - $(filesedit).each(function (index, file) { - if ($('#kattachs-' + file.id).length === 0) { - $('#kattach-list').append(''); + if (filesidtosetprivate.length !== 0) { + $.ajax({ + url: Joomla.getOptions('com_kunena.kunena_upload_files_set_private') + '&files_id=' + JSON.stringify(filesidtosetprivate), + type: 'POST' + }) + .done(function (data) { + // Update all individual private buttons + $('#files button').each(function() { + const $btn = $(this); + if ($btn.html().includes(Joomla.Text._('COM_KUNENA_EDITOR_INSERT_PRIVATE_ATTACHMENT'))) { + $btn.removeClass('btn-primary') + .addClass('btn-success') + .prop('disabled', true) + .html(Joomla.getOptions('com_kunena.icons.secure') + ' ' + + Joomla.Text._('COM_KUNENA_EDITOR_ATTACHMENT_IS_SECURED')); + + // Hide the corresponding insert button in the same container + $btn.siblings('button').each(function() { + const $siblingBtn = $(this); + if ($siblingBtn.html().includes(Joomla.Text._('COM_KUNENA_EDITOR_INSERT')) || + $siblingBtn.html().includes(Joomla.Text._('COM_KUNENA_EDITOR_IN_MESSAGE'))) { + $siblingBtn.hide(); + } + }); } + }); - if ($('#kattach-' + file.id).length > 0) { - $('#kattach-' + file.id).remove(); + // Update the set-secure-all button + $this.removeClass('btn-primary') + .addClass('btn-success') + .prop('disabled', true) + .html(Joomla.getOptions('com_kunena.icons.secure') + ' ' + + Joomla.Text._('COM_KUNENA_EDITOR_ATTACHMENTS_ARE_SECURED')); + + // Hide both insert and insert-all buttons + $('button').each(function() { + const $btn = $(this); + if ($btn.html().includes(Joomla.Text._('COM_KUNENA_EDITOR_INSERT')) || + $btn.html().includes(Joomla.Text._('COM_KUNENA_EDITOR_IN_MESSAGE')) || + $btn.attr('id') === 'insert-all') { + $btn.hide(); } - - filesidinedittodelete.push(file.id); }); - $.ajax({ - url: Joomla.getOptions('com_kunena.kunena_upload_files_rem') + '&files_id_delete=' + JSON.stringify(filesidinedittodelete) + '&editor_text=' + editor_text, - type: 'POST' - }) - .done(function (data) { - $('#files').empty(); + // Explicitly hide the insert-all button + $('#insert-all').hide(); + }) + .fail(function () { + //TODO: handle the error of ajax request + }); + } +}); - if (data.text_prepared !== false) { - if (Joomla.getOptions('com_kunena.ckeditor_config') !== undefined) { - CKEDITOR.instances.message.setData(data.text_prepared); - } else { - sceditor.instance(document.getElementById('message')).insert(data.text_prepared); - } - } - }) - .fail(function () { - //TODO: handle the error of ajax request - }); + $('#remove-all').on('click', function (e) { + e.preventDefault(); - filesedit = null; - } + $('#progress').hide(); - const child = $('#kattach-list').find('input'); - const filesidtodelete = []; + // Reset insert-all button state + $('#insert-all').removeClass('btn-success').addClass('btn-outline-primary'); + $('#insert-all').html(Joomla.getOptions('com_kunena.icons.upload') + ' ' + Joomla.Text._('COM_KUNENA_UPLOADED_LABEL_INSERT_ALL_BUTTON')); - child.each(function (i, el) { - const elem = $(el); + // Hide action buttons + $('#remove-all').hide(); + $('#insert-all').hide(); + $('#set-secure-all').hide(); // Also hide the secure-all button - if (!elem.attr('id').match("[a-z]{8}")) { - const fileid = elem.attr('id').match("[0-9]{1,8}"); + // Get editor content while preserving line breaks + let editor_text = ''; + if (Joomla.getOptions('com_kunena.ckeditor_config') !== undefined) { + editor_text = CKEDITOR.instances.message.getData(); + } else { + editor_text = sceditor.instance(document.getElementById('message')).val(); + } - if ($('#kattachs-' + fileid).length === 0) { - $('#kattach-list').append(''); - } + // Find all attachment BBCodes + const attachmentRegex = /\[attachment=([0-9]+)\]([^[\]]+)\[\/attachment\]/g; + const attachments = []; + let attachmentMatches; + + // Collect all attachments from the editor content + while ((attachmentMatches = attachmentRegex.exec(editor_text)) !== null) { + attachments.push({ + id: parseInt(attachmentMatches[1]), + filename: attachmentMatches[2] + }); + } - if ($('#kattach-' + fileid).length > 0) { - $('#kattach-' + fileid).remove(); + // Also collect attachments from the #files container that aren't in the editor + $('#files > div').each(function() { + const $buttons = $(this).find('button'); + $buttons.each(function() { + const $btn = $(this); + const data = $btn.data(); + if (data.result?.data?.id || data.file_id) { + const fileId = data.result?.data?.id || data.file_id; + if (!attachments.some(a => a.id === fileId)) { + attachments.push({ + id: fileId, + filename: data.result?.data?.filename || data.name + }); } - - filesidtodelete.push(fileid); } }); + }); - if (filesidtodelete.length !== 0) { - $.ajax({ - url: Joomla.getOptions('com_kunena.kunena_upload_files_rem') + '&files_id_delete=' + JSON.stringify(filesidtodelete) + '&editor_text=' + editor_text, - type: 'POST' - }) - .done(function (data) { - $('#files').empty(); + // Remove all attachments if we found any + if (attachments.length > 0) { + // Clean editor content + const cleanedEditorText = editor_text.replace(attachmentRegex, ''); + + // Update editor content + if (Joomla.getOptions('com_kunena.ckeditor_config') !== undefined) { + CKEDITOR.instances.message.setData(cleanedEditorText); + } else { + sceditor.instance(document.getElementById('message')).val(cleanedEditorText); + } - if (data.text_prepared !== false) { - if (Joomla.getOptions('com_kunena.ckeditor_config') !== undefined) { - CKEDITOR.instances.message.setData(data.text_prepared); - } else { - sceditor.instance(document.getElementById('message')).insert(data.text_prepared); - } + // Remove each attachment via AJAX + let i = 0; + const removeAttachments = function() { + if (i < attachments.length) { + const attachment = attachments[i]; + $.ajax({ + url: Joomla.getOptions('com_kunena.kunena_upload_files_rem'), + type: 'POST', + data: { + files_id_delete: JSON.stringify([attachment.id]) } }) - .fail(function () { - //TODO: handle the error of ajax request + .always(function () { + // Remove the attachment's input fields + $('#kattachs-' + attachment.id).remove(); + $('#kattach-' + attachment.id).remove(); + + i++; + removeAttachments(); }); - } - - $('#alert_max_file').remove(); - - fileCount = 0; - }); - - $('#insert-all').bind('keypress keydown keyup', function(e){ - if(e.keyCode == 13) { e.preventDefault(); } - }); - - $('#insert-all').on('click', function (e) { - e.preventDefault(); - - const child = $('#kattach-list').find('input'); - const files_id = []; - let content_to_inject = ''; - - child.each(function (i, el) { - const elem = $(el); - - if (!elem.attr('id').match("[a-z]{8}")) { - const attachid = elem.attr('id').match("[0-9]{1,8}"); - const filename = elem.attr('placeholder'); - - content_to_inject += '[attachment=' + attachid + ']' + filename + '[/attachment]'; - - $('#insert-all').removeClass('btn-primary'); - $('#insert-all').addClass('btn-success'); - $('#insert-all').html(Joomla.getOptions('com_kunena.icons.upload') + Joomla.Text._('COM_KUNENA_EDITOR_IN_MESSAGE')); - - files_id.push(attachid); + } else { + // Clear the files container and reset counters + $('#files').empty(); + fileCount = 0; + fileeditinline = 0; } - }); + }; + removeAttachments(); + } - // Inserting items in message from edit if they aren't already present - if ($.isEmptyObject(filesedit) === false) { - const filesid_list = []; + // Remove any alert messages + $('#alert_max_file').remove(); +}); - $(filesedit).each(function (index, file) { - if (file.inline !== true) { - content_to_inject += '[attachment=' + file.id + ']' + file.name + '[/attachment]'; - files_id.push(file.id); - } + + $('#insert-all').on('click', function (e) { + e.preventDefault(); + + const child = $('#kattach-list').find('input'); + const files_id = []; + let content_to_inject = ''; + + child.each(function (i, el) { + const elem = $(el); + + if (!elem.attr('id').match("[a-z]{8}")) { + const attachid = elem.attr('id').match("[0-9]{1,8}"); + const filename = elem.attr('placeholder'); + + content_to_inject += '[attachment=' + attachid + ']' + filename + '[/attachment]'; + + // Find all buttons in #files div + $('#files > div').each(function() { + const $buttons = $(this).find('button'); + $buttons.each(function() { + const $btn = $(this); + // Check if this is the insert button (not private or remove button) + if ($btn.hasClass('btn-primary') && + !$btn.hasClass('btn-danger') && + $btn.html().includes(Joomla.Text._('COM_KUNENA_EDITOR_INSERT')) && + ($btn.data('result')?.data?.id == attachid || + $btn.data('id') == attachid)) { + $btn.removeClass('btn-primary btn-outline-primary') + .addClass('btn-success') + .html(Joomla.getOptions('com_kunena.icons.upload') + ' ' + + Joomla.Text._('COM_KUNENA_EDITOR_IN_MESSAGE')); + + // Hide the private button for this attachment + $(this).siblings('button').each(function() { + if ($(this).html().includes(Joomla.Text._('COM_KUNENA_EDITOR_INSERT_PRIVATE_ATTACHMENT'))) { + $(this).hide(); + } + }); + } + }); }); - } - // Prevent the press on enter key to press the button enter all when previously clicked - if ($('#message').length > 0) - { - if (Joomla.getOptions('com_kunena.ckeditor_config') !== undefined) { - CKEDITOR.instances.message.insertText(content_to_inject); - } else { - sceditor.instance(document.getElementById('message')).insert(content_to_inject); - } + files_id.push(attachid); } + }); - $('#files .btn.btn-primary').each(function () { - $('#files .btn.btn-primary').addClass('btn-success'); - $('#files .btn.btn-success').removeClass('btn-primary'); - $('#files .btn.btn-success').html(Joomla.getOptions('com_kunena.icons.upload') + Joomla.Text._('COM_KUNENA_EDITOR_IN_MESSAGE')); + // Update the Insert All button state + $('#insert-all').removeClass('btn-outline-primary btn-primary') + .addClass('btn-success') + .html(Joomla.getOptions('com_kunena.icons.upload') + ' ' + + Joomla.Text._('COM_KUNENA_EDITOR_IN_MESSAGE')); + + // Hide the "Set all attachments private" button since they're now inline + $('#set-secure-all').hide(); + + // Inserting items in message from edit if they aren't already present + if ($.isEmptyObject(filesedit) === false) { + $(filesedit).each(function (index, file) { + if (file.inline !== true) { + content_to_inject += '[attachment=' + file.id + ']' + file.name + '[/attachment]'; + files_id.push(file.id); + } }); + } - $.ajax({ - url: Joomla.getOptions('com_kunena.kunena_upload_files_set_inline') + '&files_id=' + JSON.stringify(files_id), - type: 'POST' - }) - .done(function (data) { - - }) - .fail(function () { - //TODO: handle the error of ajax request - }); + // Insert content into message + if ($('#message').length > 0) { + if (Joomla.getOptions('com_kunena.ckeditor_config') !== undefined) { + CKEDITOR.instances.message.insertText(content_to_inject); + } else { + sceditor.instance(document.getElementById('message')).insert(content_to_inject); + } + } - filesedit = null; + $.ajax({ + url: Joomla.getOptions('com_kunena.kunena_upload_files_set_inline') + '&files_id=' + JSON.stringify(files_id), + type: 'POST' + }) + .done(function (data) { + // Success handler if needed + }) + .fail(function () { + // TODO: handle the error of ajax request }); - const setPrivateButton = $('').insertBefore($('#files')); - - $('#form_submit_button').prop('disabled', false); - - return false; + // Update editor content with the cleaned text + if (Joomla.getOptions('com_kunena.ckeditor_config') !== undefined) { + CKEDITOR.instances.message.setData(cleanedEditorText); } else { - fileCount = Object.keys(data['files']).length + fileCount; - } - }) - .bind('fileuploadchange', function (e, data) { - $('#form_submit_button').prop('disabled', true); - - $('#remove-all').show(); - $('#insert-all').show(); - - if (Joomla.getOptions('com_kunena.privateMessage') == 1) { - $('#set-secure-all').show(); + sceditor.instance(document.getElementById('message')).val(cleanedEditorText); } - const filecoutntmp = Object.keys(data['files']).length + fileCount; + const file_query_id = [file_id]; - if (filecoutntmp > Joomla.getOptions('com_kunena.kunena_upload_files_maxfiles')) { - $('').insertBefore($('#files')); - - $('#form_submit_button').prop('disabled', false); + // Enable submit button before AJAX call + $('#form_submit_button').prop('disabled', false); - return false; - } else { - fileCount = Object.keys(data['files']).length + fileCount; - } - }) - .on('fileuploadadd', function (e, data) { - $('#progress-bar').css( - 'width', - '0%' - ); - - $('#progress').show(); - - data.context = $('
').appendTo('#files'); - - $.each(data.files, function (index, file) { - const node = $('

') - .append($('').text(file.name)); - if (!index) { - node - .append('
'); - } + // Ajax Request to delete the file + $.ajax({ + url: Joomla.getOptions('com_kunena.kunena_upload_files_rem') + '&files_id_delete=' + JSON.stringify(file_query_id) + '&editor_text=' + encodeURIComponent(cleanedEditorText), + type: 'POST' + }) + .done(function (data) { + // Remove the attachment container + $this.closest('div').remove(); - node.appendTo(data.context); + // Ensure submit button is enabled after successful removal + setTimeout(function() { + $('#form_submit_button').prop('disabled', false); + }, 100); + }) + .fail(function () { + // Keep submit button enabled even on failure + setTimeout(function() { + $('#form_submit_button').prop('disabled', false); + }, 100); + }) + .always(function() { + // Final check to ensure button is enabled + setTimeout(function() { + $('#form_submit_button').prop('disabled', false); + }, 200); }); - }).on('fileuploadprocessalways', function (e, data) { - const index = data.index, - file = data.files[index], - node = $(data.context.children()[index]); - if (file.preview) { - node - .prepend('
') - .prepend(file.preview); - } - - if (file.error) { - node - .append('
') - .append($('').text(file.error)); - } - - if (index + 1 === data.files.length) { - data.context.find('button.btn-primary') - .text(Joomla.Text._('COM_KUNENA_UPLOADED_LABEL_UPLOAD_BUTTON')) - .prop('disabled', !!data.files.error); - } - }).on('fileuploaddone', function (e, data) { - // $.each(data.result.data, function (index, file) - const progress = parseInt(data.loaded / data.total * 100, 10); - - $('.progress-bar').css( - 'width', - progress + '%' - ); + }); - $('.progress-bar').prop('aria-valuenow', progress); + $('#fileupload').fileupload({ + url: $('#kunena_upload_files_url').val(), + dataType: 'json', + autoUpload: true, + // Enable image resizing, except for Android and Opera, + // which actually support image resizing, but fail to + // send Blob objects via XHR requests: + disableImageResize: /Android(?!.*Chrome)|Opera/ + .test(window.navigator.userAgent), + previewMaxWidth: 100, + previewMaxHeight: 100, + previewCrop: true +}) +.bind('fileuploadsubmit', function (e, data) { + var params = {}; + $.each(data.files, function (index, file) { + params = { + 'catid': $('#kunena_upload').val(), + 'filename': file.name, + 'size': file.size, + 'mime': file.type + }; + }); + data.formData = params; +}) +.bind('fileuploaddrop', function (e, data) { + $('#form_submit_button').prop('disabled', true); + $('#remove-all').show(); + $('#insert-all').show(); + + if (Joomla.getOptions('com_kunena.privateMessage') == 1) { + $('#set-secure-all').show(); + } - const link = $('') - .attr('target', '_blank') - .prop('href', data.result.location); + $('#kattach_form').show(); - data.context.find('span') - .wrap(link); + const fileCountTotal = Object.keys(data['files']).length + fileCount; - if (data.result.success === true) { - $('#form_submit_button').prop('disabled', false); - - // The attachment has been right uploaded, so now we need to put into input hidden to added to message - $('#kattach-list').append(''); - $('#kattach-list').append(''); + if (fileCountTotal > Joomla.getOptions('com_kunena.kunena_upload_files_maxfiles')) { + $('

') + .insertBefore($('#files')); + + $('#form_submit_button').prop('disabled', false); + return false; + } + + fileCount = fileCountTotal; +}) +.bind('fileuploadchange', function (e, data) { + $('#form_submit_button').prop('disabled', true); + $('#remove-all').show(); + $('#insert-all').show(); + + if (Joomla.getOptions('com_kunena.privateMessage') == 1) { + $('#set-secure-all').show(); + } - data.uploaded = true; + const fileCountTotal = Object.keys(data['files']).length + fileCount; - data.context.append(insertButton.clone(true).data(data)); - if (data.context.find('button').hasClass('btn-danger')) { - data.context.find('button.btn-danger').remove(); - } - - if (Joomla.getOptions('com_kunena.privateMessage') == 1) { - data.context.append(setPrivateButton.clone(true).data(data)); - } + if (fileCountTotal > Joomla.getOptions('com_kunena.kunena_upload_files_maxfiles')) { + $('') + .insertBefore($('#files')); + + $('#form_submit_button').prop('disabled', false); + return false; + } + + fileCount = fileCountTotal; +}) +.on('fileuploadadd', function (e, data) { + $('#progress-bar').css('width', '0%'); + $('#progress').show(); + + data.context = $('
').appendTo('#files'); + + $.each(data.files, function (index, file) { + const node = $('

').append($('').text(file.name)); + if (!index) { + node.append('
'); + } + node.appendTo(data.context); + }); +}) +.on('fileuploadprocessalways', function (e, data) { + const index = data.index, + file = data.files[index], + node = $(data.context.children()[index]); + + if (file.preview) { + node.prepend('
').prepend(file.preview); + } - data.context.append(removeButton.clone(true).data(data)); - } else if (data.result.message) { - $('#form_submit_button').prop('disabled', false); + if (file.error) { + node.append('
') + .append($('').text(file.error)); + } - data.uploaded = false; - data.context.append(removeButton.clone(true).data(data)); + if (index + 1 === data.files.length) { + data.context.find('button.btn-primary') + .text(Joomla.Text._('COM_KUNENA_UPLOADED_LABEL_UPLOAD_BUTTON')) + .prop('disabled', !!data.files.error); + } +}) +.on('fileuploaddone', function (e, data) { + const progress = parseInt(data.loaded / data.total * 100, 10); + $('.progress-bar').css('width', progress + '%') + .prop('aria-valuenow', progress); + + const link = $('
').attr('target', '_blank') + .prop('href', data.result.location); + + data.context.find('span').wrap(link); + + if (data.result.success === true) { + $('#form_submit_button').prop('disabled', false); + + // Add hidden inputs for attachments + $('#kattach-list').append( + '' + + '' + ); - var error = null; + data.uploaded = true; - if (data.result.message.length > 0) { - error = $('