| @@ -1,65 +1,101 @@ | ||
| 1 | -document.addEventListener('DOMContentLoaded', function() { | |
| 2 | - document.body.addEventListener('click', function(e) { | |
| 3 | - if (e.target && e.target.id === 'generate-alt-text-button') { | |
| 4 | - let postId = e.target.getAttribute('data-post-id'); | |
| 5 | - let button = e.target; | |
| 6 | - let spinner = document.getElementById('loading-spinner'); | |
| 1 | +// Wait for the DOM to be fully loaded before executing any script | |
| 2 | +document.addEventListener('DOMContentLoaded', () => { | |
| 7 | 3 | |
| 8 | - // Enable spinner and disable button | |
| 9 | - button.disabled = true; | |
| 10 | - button.textContent = 'Generazione in corso...'; | |
| 11 | - if (spinner) { | |
| 12 | - spinner.style.display = 'inline-block'; | |
| 13 | - spinner.classList.add('is-active'); | |
| 14 | - } | |
| 15 | - // AJAX Request to generate Alt Text | |
| 16 | - let nonce = AATXT.altTextNonce; | |
| 17 | - fetch(ajaxurl, { | |
| 4 | + // Delegate click event to the body to handle dynamically loaded buttons | |
| 5 | + document.body.addEventListener('click', async (e) => { | |
| 6 | + const button = e.target; | |
| 7 | + | |
| 8 | + // Only proceed if the clicked element is the correct button | |
| 9 | + if (!button || button.id !== 'generate-alt-text-button') return; | |
| 10 | + | |
| 11 | + // Extract the post ID from the button's data attributes | |
| 12 | + const postId = button.getAttribute('data-post-id'); | |
| 13 | + | |
| 14 | + // Reference to the spinner element, used to indicate loading state | |
| 15 | + const spinner = document.getElementById('loading-spinner'); | |
| 16 | + | |
| 17 | + // Nonce token provided by WordPress for security | |
| 18 | + const nonce = AATXT?.altTextNonce; | |
| 19 | + | |
| 20 | + // Set UI to loading state: disable button and show spinner | |
| 21 | + toggleUIState(button, spinner, true); | |
| 22 | + | |
| 23 | + try { | |
| 24 | + // Send a POST request to the WordPress AJAX handler | |
| 25 | + const response = await fetch(ajaxurl, { | |
| 18 | 26 | method: 'POST', |
| 19 | - headers: { | |
| 20 | - 'Content-Type': 'application/x-www-form-urlencoded' | |
| 21 | - }, | |
| 22 | - body: 'action=generate_alt_text&nonce=' + nonce + '&post_id=' + postId | |
| 23 | - }) | |
| 24 | - .then(response => response.json()) | |
| 25 | - .then(data => { | |
| 26 | - if (data.success) { | |
| 27 | - let uploadAltTextField = document.querySelector('.attachment-info .setting.alt-text textarea'); | |
| 27 | + headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, | |
| 28 | + body: new URLSearchParams({ | |
| 29 | + action: 'generate_alt_text', // WordPress action hook | |
| 30 | + nonce, | |
| 31 | + post_id: postId | |
| 32 | + }) | |
| 33 | + }); | |
| 28 | 34 | |
| 29 | - if (uploadAltTextField) { | |
| 30 | - uploadAltTextField.value = data.data.alt_text; | |
| 35 | + // Parse the JSON response from the server | |
| 36 | + const data = await response.json(); | |
| 31 | 37 | |
| 32 | - let event = new Event('change', { | |
| 33 | - bubbles: true, | |
| 34 | - cancelable: true, | |
| 35 | - }); | |
| 36 | - uploadAltTextField.dispatchEvent(event); | |
| 38 | + // If the server indicates success, update the alt text fields | |
| 39 | + if (!data.success) { | |
| 40 | + console.error('Error generating alt text:', data); | |
| 41 | + return; | |
| 42 | + } | |
| 37 | 43 | |
| 38 | - if (wp && wp.media && wp.media.frame && wp.media.frame.content && wp.media.frame.content.get) { | |
| 39 | - wp.media.frame.content.get().save(); | |
| 40 | - } | |
| 41 | - } else { | |
| 42 | - let attachmentAltTextField = document.getElementById('attachment_alt'); | |
| 43 | - if (attachmentAltTextField) { | |
| 44 | - attachmentAltTextField.value = data.data.alt_text; | |
| 45 | - } | |
| 46 | - } | |
| 47 | - } else { | |
| 48 | - console.error('Error generating Alt Text', data); | |
| 49 | - } | |
| 50 | - }) | |
| 51 | - .catch(error => { | |
| 52 | - console.error('Error during AJAX Request:', error); | |
| 53 | - }) | |
| 54 | - .finally(() => { | |
| 55 | - // enable button and hide spinner | |
| 56 | - button.disabled = false; | |
| 57 | - button.textContent = 'Generate Alt Text'; | |
| 58 | - if (spinner) { | |
| 59 | - spinner.style.display = 'none'; | |
| 60 | - spinner.classList.remove('is-active'); | |
| 61 | - } | |
| 62 | - }); | |
| 44 | + updateAltTextFields(data.data.alt_text); | |
| 45 | + | |
| 46 | + } catch (error) { | |
| 47 | + // Handle any network or JavaScript errors that occur during fetch | |
| 48 | + console.error('Error during AJAX request:', error); | |
| 49 | + } finally { | |
| 50 | + // Restore the UI: enable button and hide spinner | |
| 51 | + toggleUIState(button, spinner, false); | |
| 63 | 52 | } |
| 64 | 53 | }); |
| 65 | -}); | |
| 54 | + | |
| 55 | + /** | |
| 56 | + * Toggles the visual state of the UI between loading and normal. | |
| 57 | + * It disables/enables the button and shows/hides the loading spinner. | |
| 58 | + * | |
| 59 | + * @param {HTMLElement} button - The button that triggered the action | |
| 60 | + * @param {HTMLElement|null} spinner - The loading spinner element (if present) | |
| 61 | + * @param {boolean} loading - Whether to enable or disable the loading state | |
| 62 | + */ | |
| 63 | + function toggleUIState(button, spinner, loading) { | |
| 64 | + button.disabled = loading; | |
| 65 | + button.textContent = loading ? 'Generating alt text...' : 'Generate Alt Text'; | |
| 66 | + | |
| 67 | + if (spinner) { | |
| 68 | + spinner.style.display = loading ? 'inline-block' : 'none'; | |
| 69 | + spinner.classList.toggle('is-active', loading); | |
| 70 | + } | |
| 71 | + } | |
| 72 | + | |
| 73 | + /** | |
| 74 | + * Updates the appropriate alt text field in the WordPress Media Library or modal overlay. | |
| 75 | + * Triggers a `change` event and invokes WordPress's media `save()` function if available. | |
| 76 | + * | |
| 77 | + * @param {string} altText - The alt text returned from the server | |
| 78 | + */ | |
| 79 | + function updateAltTextFields(altText) { | |
| 80 | + // Check if we are in the media library sidebar | |
| 81 | + const uploadField = document.querySelector('.attachment-info .setting.alt-text textarea'); | |
| 82 | + | |
| 83 | + // Or in the media details overlay | |
| 84 | + const overlayField = document.getElementById('attachment-details-alt-text'); | |
| 85 | + | |
| 86 | + // Use whichever field is available | |
| 87 | + const field = uploadField || overlayField; | |
| 88 | + | |
| 89 | + if (!field) return; | |
| 90 | + | |
| 91 | + // Set the alt text and dispatch a change event to notify WordPress | |
| 92 | + field.value = altText; | |
| 93 | + field.dispatchEvent(new Event('change', { bubbles: true })); | |
| 94 | + | |
| 95 | + // If the WordPress media frame is active, trigger a save | |
| 96 | + const content = wp?.media?.frame?.content?.get?.(); | |
| 97 | + if (typeof content?.save === 'function') { | |
| 98 | + content.save(); | |
| 99 | + } | |
| 100 | + } | |
| 101 | +}); | |