| | |
| | |
| | |
| | |
| | |
| | |
| | (function () { |
| | function getActiveImg2ImgTabImgSrc(img2imgTabs) { |
| | const tabs = img2imgTabs.querySelectorAll('.tabitem'); |
| | const activeTabs = [...tabs].filter(tab => tab.style.display !== 'none'); |
| | if (!activeTabs) return; |
| | const image = activeTabs[0].querySelector('.image-container img') |
| | return image ? image.src : undefined; |
| | } |
| |
|
| | function updateControlNetInputFallbackPreview(cnetInputContainers, imgDataURL) { |
| | for (const container of cnetInputContainers) { |
| | const badge = container.querySelector('.cnet-badge'); |
| | if (badge) badge.remove(); |
| |
|
| | if (imgDataURL) { |
| | |
| | if (container.querySelector('img')) |
| | continue; |
| |
|
| | |
| | container.style.backgroundImage = `url('${imgDataURL}')`; |
| |
|
| | |
| | container.style.backgroundPosition = 'center'; |
| | container.style.backgroundRepeat = 'no-repeat'; |
| | container.style.backgroundSize = 'contain'; |
| | container.title = "Img2Img input will be used if no ControlNet input is specified."; |
| |
|
| | const div = document.createElement('div'); |
| | div.classList.add('cnet-badge', 'primary', 'cnet-a1111-badge'); |
| | div.innerHTML = 'A1111'; |
| | container.appendChild(div); |
| | } else { |
| | container.style.backgroundImage = 'none'; |
| | } |
| | } |
| | } |
| |
|
| | const ImgChangeType = { |
| | NO_CHANGE: 0, |
| | REMOVE: 1, |
| | ADD: 2, |
| | SRC_CHANGE: 3, |
| | }; |
| |
|
| | function imgChangeObserved(mutationsList) { |
| | |
| | for (let mutation of mutationsList) { |
| | |
| | if (mutation.type === 'childList') { |
| | |
| | if (mutation.addedNodes.length > 0) { |
| | for (const node of mutation.addedNodes) { |
| | if (node.tagName === 'IMG') { |
| | return ImgChangeType.ADD; |
| | } |
| | } |
| | } |
| |
|
| | |
| | if (mutation.removedNodes.length > 0) { |
| | for (const node of mutation.removedNodes) { |
| | if (node.tagName === 'IMG') { |
| | return ImgChangeType.REMOVE; |
| | } |
| | } |
| | } |
| | } |
| | |
| | else if (mutation.type === 'attributes') { |
| | if (mutation.target.tagName === 'IMG' && mutation.attributeName === 'src') { |
| | return ImgChangeType.SRC_CHANGE; |
| | } |
| | } |
| | } |
| | return ImgChangeType.NO_CHANGE; |
| | } |
| |
|
| | let callback_registered = false; |
| | onUiUpdate(() => { |
| | if (callback_registered) return; |
| |
|
| | const cnetInputContainers = gradioApp().querySelectorAll( |
| | "#img2img_controlnet_tabs .cnet-input-image-group .cnet-image"); |
| | if (!cnetInputContainers) return; |
| |
|
| | const img2imgTabs = gradioApp().querySelector("#mode_img2img"); |
| | if (!img2imgTabs) return; |
| |
|
| | |
| | const img2imgContainers = img2imgTabs.querySelectorAll('.tabitem .image-container'); |
| | for (const container of img2imgContainers) { |
| | new MutationObserver((mutationsList) => { |
| | if (imgChangeObserved(mutationsList) !== ImgChangeType.NO_CHANGE) { |
| | updateControlNetInputFallbackPreview( |
| | cnetInputContainers, |
| | getActiveImg2ImgTabImgSrc(img2imgTabs) |
| | ); |
| | return; |
| | } |
| | }).observe(container, { |
| | childList: true, |
| | attributes: true, |
| | attributeFilter: ['src'], |
| | subtree: true, |
| | }); |
| | } |
| |
|
| | |
| | for (const container of cnetInputContainers) { |
| | new MutationObserver((mutationsList) => { |
| | const changeObserved = imgChangeObserved(mutationsList); |
| | if (changeObserved === ImgChangeType.REMOVE) { |
| | updateControlNetInputFallbackPreview( |
| | [container], |
| | getActiveImg2ImgTabImgSrc(img2imgTabs) |
| | ); |
| | return; |
| | } |
| | if (changeObserved === ImgChangeType.ADD || |
| | changeObserved === ImgChangeType.SRC_CHANGE) { |
| | updateControlNetInputFallbackPreview( |
| | [container], |
| | undefined |
| | ); |
| | return; |
| | } |
| | }).observe(container, { |
| | childList: true, |
| | attributes: true, |
| | attributeFilter: ['src'], |
| | subtree: true, |
| | }); |
| | } |
| |
|
| | |
| | new MutationObserver((mutationsList) => { |
| | for (const mutation of mutationsList) { |
| | if (mutation.type === 'childList') { |
| | updateControlNetInputFallbackPreview( |
| | cnetInputContainers, |
| | getActiveImg2ImgTabImgSrc(img2imgTabs) |
| | ); |
| | return; |
| | } |
| | } |
| | }).observe(img2imgTabs.querySelector('.tab-nav'), { childList: true }); |
| |
|
| | callback_registered = true; |
| | }); |
| | })(); |