123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- /**
- * Display the currently active img2img tab's input image as an uninteractable
- * background image behind ControlNet's image input. This change will hint user
- * that if no ControlNet input image is uploaded, by default ControlNet will
- * fallback onto img2img input image.
- */
- (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) {
- // Do not add fallback image if controlnet input already exists.
- if (container.querySelector('img')) {
- continue;
- }
- // Set the background image
- container.style.backgroundImage = `url('${imgDataURL}')`;
- // Set other background properties
- 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) {
- // Iterate over all mutations that just occured
- for (let mutation of mutationsList) {
- // Check if the mutation is an addition or removal of a node
- if (mutation.type === 'childList') {
- // Check if nodes were added
- if (mutation.addedNodes.length > 0) {
- for (const node of mutation.addedNodes) {
- if (node.tagName === 'IMG') {
- return ImgChangeType.ADD;
- }
- }
- }
- // Check if nodes were removed
- if (mutation.removedNodes.length > 0) {
- for (const node of mutation.removedNodes) {
- if (node.tagName === 'IMG') {
- return ImgChangeType.REMOVE;
- }
- }
- }
- }
- // Check if the mutation is a change of an attribute
- 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;
- // Every time img2img input updates, update fallback preview.
- 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,
- });
- }
- // Every time controlnet input updates, update fallback preview.
- 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,
- });
- }
- // Every time the img2img tab is switched, update fallback preview.
- 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;
- });
- })();
|