Files
Assetmanager/app/static/js/image-editor.js
T

134 lines
4.3 KiB
JavaScript

(() => {
function initImageEditor(editor) {
if (!editor || editor.dataset.imageEditorReady === '1') return;
const removeButton = editor.querySelector('[data-image-remove]');
const removeInput = editor.querySelector('[data-image-remove-input]');
let preview = editor.querySelector('[data-image-preview]');
let previewImage = preview?.querySelector('img');
const imageInput = editor.querySelector('input[type="file"][data-image-input]');
const libraryUpload = editor.querySelector('input[type="file"][data-image-library-upload]');
const libraryChoices = Array.from(editor.querySelectorAll('[data-image-library-choice]'));
const pending = editor.querySelector('[data-image-remove-pending]');
if (!removeInput) return;
const originalPreviewSrc = previewImage?.getAttribute('src') || '';
let objectUrl = null;
const releaseObjectUrl = () => {
if (objectUrl) {
URL.revokeObjectURL(objectUrl);
objectUrl = null;
}
};
const ensurePreview = () => {
if (preview && previewImage) return;
preview = document.createElement('div');
preview.className = 'asset-edit-image-preview';
preview.dataset.imagePreview = '';
preview.hidden = true;
preview.style.display = 'none';
previewImage = document.createElement('img');
previewImage.className = 'asset-edit-preview-image';
previewImage.alt = '';
preview.appendChild(previewImage);
const firstControl = editor.querySelector('[data-image-remove-input]');
editor.insertBefore(preview, firstControl);
};
const showPreview = src => {
ensurePreview();
if (src) previewImage.src = src;
preview.hidden = false;
preview.style.display = '';
if (removeButton) {
removeButton.hidden = false;
removeButton.disabled = false;
}
};
const hidePreview = () => {
if (!preview) return;
preview.hidden = true;
preview.style.display = 'none';
if (removeButton) { removeButton.hidden = true; removeButton.disabled = true; }
};
const clearLibraryChoices = () => {
libraryChoices.forEach(choice => { choice.checked = false; });
};
const clearRemoveState = () => {
removeInput.value = '0';
if (pending) pending.hidden = true;
if (removeButton) {
removeButton.disabled = false;
removeButton.setAttribute('aria-pressed', 'false');
}
};
const setRemoveState = remove => {
removeInput.value = remove ? '1' : '0';
if (pending) pending.hidden = !remove;
if (removeButton) {
removeButton.disabled = remove;
removeButton.setAttribute('aria-pressed', remove ? 'true' : 'false');
}
if (remove) {
releaseObjectUrl();
if (imageInput) imageInput.value = '';
if (libraryUpload) libraryUpload.value = '';
clearLibraryChoices();
hidePreview();
}
};
removeButton?.addEventListener('click', event => {
event.preventDefault();
event.stopPropagation();
setRemoveState(true);
});
imageInput?.addEventListener('change', () => {
if (!imageInput.files || !imageInput.files.length) return;
releaseObjectUrl();
objectUrl = URL.createObjectURL(imageInput.files[0]);
if (libraryUpload) libraryUpload.value = '';
clearLibraryChoices();
clearRemoveState();
showPreview(objectUrl);
});
libraryUpload?.addEventListener('change', () => {
if (!libraryUpload.files || !libraryUpload.files.length) return;
releaseObjectUrl();
objectUrl = URL.createObjectURL(libraryUpload.files[0]);
if (imageInput) imageInput.value = '';
clearLibraryChoices();
clearRemoveState();
showPreview(objectUrl);
});
libraryChoices.forEach(choice => {
choice.addEventListener('change', () => {
if (!choice.checked) return;
releaseObjectUrl();
if (imageInput) imageInput.value = '';
if (libraryUpload) libraryUpload.value = '';
clearRemoveState();
showPreview(choice.dataset.imageSrc || choice.value);
});
});
window.addEventListener('beforeunload', releaseObjectUrl, { once: true });
editor.dataset.imageEditorReady = '1';
editor.dataset.originalImageSrc = originalPreviewSrc;
}
document.querySelectorAll('[data-image-editor]').forEach(initImageEditor);
})();