/* global gradioApp, onUiUpdate */ // A full size 'lightbox' preview modal shown when left clicking on gallery previews function closeModal() { gradioApp().getElementById('lightboxModal').style.display = 'none'; } function showModal(event) { const source = event.target || event.srcElement; const modalImage = gradioApp().getElementById('modalImage'); const lb = gradioApp().getElementById('lightboxModal'); modalImage.src = source.src; if (modalImage.style.display === 'none') lb.style.setProperty('background-image', `url(${source.src})`); lb.style.display = 'flex'; lb.focus(); const tabTxt2Img = gradioApp().getElementById('tab_txt2img'); const tabImg2Img = gradioApp().getElementById('tab_img2img'); // show the save button in modal only on txt2img or img2img tabs if (tabTxt2Img.style.display != 'none' || tabImg2Img.style.display != 'none') gradioApp().getElementById('modal_save').style.display = 'inline'; else gradioApp().getElementById('modal_save').style.display = 'none'; event.stopPropagation(); } function negmod(n, m) { return ((n % m) + m) % m; } function updateOnBackgroundChange() { const modalImage = gradioApp().getElementById('modalImage'); if (modalImage && modalImage.offsetParent) { const currentButton = selected_gallery_button(); if (currentButton?.children?.length > 0 && modalImage.src != currentButton.children[0].src) { modalImage.src = currentButton.children[0].src; if (modalImage.style.display === 'none') modal.style.setProperty('background-image', `url(${modalImage.src})`); } } } function modalImageSwitch(offset) { const galleryButtons = all_gallery_buttons(); if (galleryButtons.length > 1) { const currentButton = selected_gallery_button(); let result = -1; galleryButtons.forEach((v, i) => { if (v == currentButton) result = i; }); if (result != -1) { nextButton = galleryButtons[negmod((result + offset), galleryButtons.length)]; nextButton.click(); const modalImage = gradioApp().getElementById('modalImage'); const modal = gradioApp().getElementById('lightboxModal'); modalImage.src = nextButton.children[0].src; if (modalImage.style.display === 'none') modal.style.setProperty('background-image', `url(${modalImage.src})`); setTimeout(() => modal.focus(), 10); } } } function saveImage() { const tabTxt2Img = gradioApp().getElementById('tab_txt2img'); const tabImg2Img = gradioApp().getElementById('tab_img2img'); const saveTxt2Img = 'save_txt2img'; const saveImg2Img = 'save_img2img'; if (tabTxt2Img.style.display != 'none') gradioApp().getElementById(saveTxt2Img).click(); else if (tabImg2Img.style.display != 'none') gradioApp().getElementById(saveImg2Img).click(); else console.error('missing implementation for saving modal of this type'); } function modalSaveImage(event) { saveImage(); event.stopPropagation(); } function modalNextImage(event) { modalImageSwitch(1); event.stopPropagation(); } function modalPrevImage(event) { modalImageSwitch(-1); event.stopPropagation(); } function modalKeyHandler(event) { switch (event.key) { case 's': saveImage(); break; case 'ArrowLeft': modalPrevImage(event); break; case 'ArrowRight': modalNextImage(event); break; case 'Escape': closeModal(); break; } } function modalZoomSet(modalImage, enable) { localStorage.setItem('modalZoom', enable ? 'yes' : 'no'); if (modalImage) modalImage.classList.toggle('modalImageFullscreen', !!enable); } function setupImageForLightbox(e) { if (e.dataset.modded) return; e.dataset.modded = true; e.style.cursor = 'pointer'; e.style.userSelect = 'none'; const isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1; const event = isFirefox ? 'mousedown' : 'click'; e.addEventListener(event, (evt) => { if (evt.button != 0) return; const initialZoom = (localStorage.getItem('modalZoom') || true) == 'yes'; modalZoomSet(gradioApp().getElementById('modalImage'), initialZoom); evt.preventDefault(); showModal(evt); }, true); } function modalZoomToggle(event) { const modalImage = gradioApp().getElementById('modalImage'); modalZoomSet(modalImage, !modalImage.classList.contains('modalImageFullscreen')); event.stopPropagation(); } function modalTileImageToggle(event) { const modalImage = gradioApp().getElementById('modalImage'); const modal = gradioApp().getElementById('lightboxModal'); const isTiling = modalImage.style.display === 'none'; if (isTiling) { modalImage.style.display = 'block'; modal.style.setProperty('background-image', 'none'); } else { modalImage.style.display = 'none'; modal.style.setProperty('background-image', `url(${modalImage.src})`); } event.stopPropagation(); } function galleryImageHandler(e) { e.onclick = showGalleryImage; } onUiUpdate(() => { fullImg_preview = gradioApp().querySelectorAll('.gradio-gallery > div > img'); if (fullImg_preview != null) fullImg_preview.forEach(setupImageForLightbox); updateOnBackgroundChange(); }); document.addEventListener('DOMContentLoaded', () => { // const modalFragment = document.createDocumentFragment(); const modal = document.createElement('div'); modal.onclick = closeModal; modal.id = 'lightboxModal'; modal.tabIndex = 0; modal.addEventListener('keydown', modalKeyHandler, true); const modalControls = document.createElement('div'); modalControls.className = 'modalControls gradio-container'; modal.append(modalControls); const modalZoom = document.createElement('span'); modalZoom.className = 'modalZoom cursor'; modalZoom.innerHTML = '⤡'; modalZoom.addEventListener('click', modalZoomToggle, true); modalZoom.title = 'Toggle zoomed view'; modalControls.appendChild(modalZoom); const modalTileImage = document.createElement('span'); modalTileImage.className = 'modalTileImage cursor'; modalTileImage.innerHTML = '⊞'; modalTileImage.addEventListener('click', modalTileImageToggle, true); modalTileImage.title = 'Preview tiling'; modalControls.appendChild(modalTileImage); const modalSave = document.createElement('span'); modalSave.className = 'modalSave cursor'; modalSave.id = 'modal_save'; modalSave.innerHTML = '🖫'; modalSave.addEventListener('click', modalSaveImage, true); modalSave.title = 'Save Image(s)'; modalControls.appendChild(modalSave); const modalClose = document.createElement('span'); modalClose.className = 'modalClose cursor'; modalClose.innerHTML = '×'; modalClose.onclick = closeModal; modalClose.title = 'Close image viewer'; modalControls.appendChild(modalClose); const modalImage = document.createElement('img'); modalImage.id = 'modalImage'; modalImage.onclick = closeModal; modalImage.tabIndex = 0; modalImage.addEventListener('keydown', modalKeyHandler, true); modal.appendChild(modalImage); const modalPrev = document.createElement('a'); modalPrev.className = 'modalPrev'; modalPrev.innerHTML = '❮'; modalPrev.tabIndex = 0; modalPrev.addEventListener('click', modalPrevImage, true); modalPrev.addEventListener('keydown', modalKeyHandler, true); modal.appendChild(modalPrev); const modalNext = document.createElement('a'); modalNext.className = 'modalNext'; modalNext.innerHTML = '❯'; modalNext.tabIndex = 0; modalNext.addEventListener('click', modalNextImage, true); modalNext.addEventListener('keydown', modalKeyHandler, true); modal.appendChild(modalNext); try { gradioApp().appendChild(modal); } catch (e) { gradioApp().body.appendChild(modal); } });