aboutsummaryrefslogtreecommitdiff
path: root/javascript
diff options
context:
space:
mode:
Diffstat (limited to 'javascript')
-rw-r--r--javascript/aspectRatioOverlay.js49
-rw-r--r--javascript/contextMenus.js2
-rw-r--r--javascript/edit-attention.js2
-rw-r--r--javascript/extraNetworks.js38
-rw-r--r--javascript/hints.js14
-rw-r--r--javascript/imageviewer.js90
-rw-r--r--javascript/notification.js2
-rw-r--r--javascript/progressbar.js67
-rw-r--r--javascript/ui.js39
9 files changed, 139 insertions, 164 deletions
diff --git a/javascript/aspectRatioOverlay.js b/javascript/aspectRatioOverlay.js
index 0f164b82..a8278cca 100644
--- a/javascript/aspectRatioOverlay.js
+++ b/javascript/aspectRatioOverlay.js
@@ -12,7 +12,7 @@ function dimensionChange(e, is_width, is_height){
currentHeight = e.target.value*1.0
}
- var inImg2img = Boolean(gradioApp().querySelector("button.rounded-t-lg.border-gray-200"))
+ var inImg2img = gradioApp().querySelector("#tab_img2img").style.display == "block";
if(!inImg2img){
return;
@@ -22,7 +22,7 @@ function dimensionChange(e, is_width, is_height){
var tabIndex = get_tab_index('mode_img2img')
if(tabIndex == 0){ // img2img
- targetElement = gradioApp().querySelector('div[data-testid=image] img');
+ targetElement = gradioApp().querySelector('#img2img_image div[data-testid=image] img');
} else if(tabIndex == 1){ //Sketch
targetElement = gradioApp().querySelector('#img2img_sketch div[data-testid=image] img');
} else if(tabIndex == 2){ // Inpaint
@@ -30,7 +30,7 @@ function dimensionChange(e, is_width, is_height){
} else if(tabIndex == 3){ // Inpaint sketch
targetElement = gradioApp().querySelector('#inpaint_sketch div[data-testid=image] img');
}
-
+
if(targetElement){
@@ -38,7 +38,7 @@ function dimensionChange(e, is_width, is_height){
if(!arPreviewRect){
arPreviewRect = document.createElement('div')
arPreviewRect.id = "imageARPreview";
- gradioApp().getRootNode().appendChild(arPreviewRect)
+ gradioApp().appendChild(arPreviewRect)
}
@@ -91,23 +91,26 @@ onUiUpdate(function(){
if(arPreviewRect){
arPreviewRect.style.display = 'none';
}
- var inImg2img = Boolean(gradioApp().querySelector("button.rounded-t-lg.border-gray-200"))
- if(inImg2img){
- let inputs = gradioApp().querySelectorAll('input');
- inputs.forEach(function(e){
- var is_width = e.parentElement.id == "img2img_width"
- var is_height = e.parentElement.id == "img2img_height"
-
- if((is_width || is_height) && !e.classList.contains('scrollwatch')){
- e.addEventListener('input', function(e){dimensionChange(e, is_width, is_height)} )
- e.classList.add('scrollwatch')
- }
- if(is_width){
- currentWidth = e.value*1.0
- }
- if(is_height){
- currentHeight = e.value*1.0
- }
- })
- }
+ var tabImg2img = gradioApp().querySelector("#tab_img2img");
+ if (tabImg2img) {
+ var inImg2img = tabImg2img.style.display == "block";
+ if(inImg2img){
+ let inputs = gradioApp().querySelectorAll('input');
+ inputs.forEach(function(e){
+ var is_width = e.parentElement.id == "img2img_width"
+ var is_height = e.parentElement.id == "img2img_height"
+
+ if((is_width || is_height) && !e.classList.contains('scrollwatch')){
+ e.addEventListener('input', function(e){dimensionChange(e, is_width, is_height)} )
+ e.classList.add('scrollwatch')
+ }
+ if(is_width){
+ currentWidth = e.value*1.0
+ }
+ if(is_height){
+ currentHeight = e.value*1.0
+ }
+ })
+ }
+ }
});
diff --git a/javascript/contextMenus.js b/javascript/contextMenus.js
index 11bcce1b..06f505b0 100644
--- a/javascript/contextMenus.js
+++ b/javascript/contextMenus.js
@@ -43,7 +43,7 @@ contextMenuInit = function(){
})
- gradioApp().getRootNode().appendChild(contextMenu)
+ gradioApp().appendChild(contextMenu)
let menuWidth = contextMenu.offsetWidth + 4;
let menuHeight = contextMenu.offsetHeight + 4;
diff --git a/javascript/edit-attention.js b/javascript/edit-attention.js
index 619bb1fa..20a5aadf 100644
--- a/javascript/edit-attention.js
+++ b/javascript/edit-attention.js
@@ -1,6 +1,6 @@
function keyupEditAttention(event){
let target = event.originalTarget || event.composedPath()[0];
- if (!target.matches("[id*='_toprow'] textarea.gr-text-input[placeholder]")) return;
+ if (! target.matches("[id*='_toprow'] [id*='_prompt'] textarea")) return;
if (! (event.metaKey || event.ctrlKey)) return;
let isPlus = event.key == "ArrowUp"
diff --git a/javascript/extraNetworks.js b/javascript/extraNetworks.js
index 2fb87cd5..25322138 100644
--- a/javascript/extraNetworks.js
+++ b/javascript/extraNetworks.js
@@ -139,3 +139,41 @@ function extraNetworksShowMetadata(text){
popup(elem);
}
+
+function requestGet(url, data, handler, errorHandler){
+ var xhr = new XMLHttpRequest();
+ var args = Object.keys(data).map(function(k){ return encodeURIComponent(k) + '=' + encodeURIComponent(data[k]) }).join('&')
+ xhr.open("GET", url + "?" + args, true);
+
+ xhr.onreadystatechange = function () {
+ if (xhr.readyState === 4) {
+ if (xhr.status === 200) {
+ try {
+ var js = JSON.parse(xhr.responseText);
+ handler(js)
+ } catch (error) {
+ console.error(error);
+ errorHandler()
+ }
+ } else{
+ errorHandler()
+ }
+ }
+ };
+ var js = JSON.stringify(data);
+ xhr.send(js);
+}
+
+function extraNetworksRequestMetadata(event, extraPage, cardName){
+ showError = function(){ extraNetworksShowMetadata("there was an error getting metadata"); }
+
+ requestGet("./sd_extra_networks/metadata", {"page": extraPage, "item": cardName}, function(data){
+ if(data && data.metadata){
+ extraNetworksShowMetadata(data.metadata)
+ } else{
+ showError()
+ }
+ }, showError)
+
+ event.stopPropagation()
+}
diff --git a/javascript/hints.js b/javascript/hints.js
index 7f4101b2..f48a0eb6 100644
--- a/javascript/hints.js
+++ b/javascript/hints.js
@@ -18,11 +18,10 @@ titles = {
"\u2199\ufe0f": "Read generation parameters from prompt or last generation if prompt is empty into user interface.",
"\u{1f4c2}": "Open images output directory",
"\u{1f4be}": "Save style",
- "\u{1f5d1}": "Clear prompt",
+ "\u{1f5d1}\ufe0f": "Clear prompt",
"\u{1f4cb}": "Apply selected styles to current prompt",
"\u{1f4d2}": "Paste available values into the field",
- "\u{1f3b4}": "Show extra networks",
-
+ "\u{1f3b4}": "Show/hide extra networks",
"Inpaint a part of image": "Draw a mask over an image, and the script will regenerate the masked area with content according to prompt",
"SD upscale": "Upscale image normally, split result into tiles, improve each tile using img2img, merge whole image back",
@@ -40,8 +39,7 @@ titles = {
"Inpaint at full resolution": "Upscale masked region to target resolution, do inpainting, downscale back and paste into original image",
"Denoising strength": "Determines how little respect the algorithm should have for image's content. At 0, nothing will change, and at 1 you'll get an unrelated image. With values below 1.0, processing will take less steps than the Sampling Steps slider specifies.",
- "Denoising strength change factor": "In loopback mode, on each loop the denoising strength is multiplied by this value. <1 means decreasing variety so your sequence will converge on a fixed picture. >1 means increasing variety so your sequence will become more and more chaotic.",
-
+
"Skip": "Stop processing current image and continue processing.",
"Interrupt": "Stop processing images and return any results accumulated so far.",
"Save": "Write image to a directory (default - log/images) and generation parameters into csv file.",
@@ -71,8 +69,10 @@ titles = {
"Directory name pattern": "Use following tags to define how subdirectories for images and grids are chosen: [steps], [cfg],[prompt_hash], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [model_name], [prompt_words], [date], [datetime], [datetime<Format>], [datetime<Format><Time Zone>], [job_timestamp]; leave empty for default.",
"Max prompt words": "Set the maximum number of words to be used in the [prompt_words] option; ATTENTION: If the words are too long, they may exceed the maximum length of the file path that the system can handle",
- "Loopback": "Process an image, use it as an input, repeat.",
- "Loops": "How many times to repeat processing an image and using it as input for the next iteration",
+ "Loopback": "Performs img2img processing multiple times. Output images are used as input for the next loop.",
+ "Loops": "How many times to process an image. Each output is used as the input of the next loop. If set to 1, behavior will be as if this script were not used.",
+ "Final denoising strength": "The denoising strength for the final loop of each image in the batch.",
+ "Denoising strength curve": "The denoising curve controls the rate of denoising strength change each loop. Aggressive: Most of the change will happen towards the start of the loops. Linear: Change will be constant through all loops. Lazy: Most of the change will happen towards the end of the loops.",
"Style 1": "Style to apply; styles have components for both positive and negative prompts and apply to both",
"Style 2": "Style to apply; styles have components for both positive and negative prompts and apply to both",
diff --git a/javascript/imageviewer.js b/javascript/imageviewer.js
index 28e748b7..d6483562 100644
--- a/javascript/imageviewer.js
+++ b/javascript/imageviewer.js
@@ -32,13 +32,7 @@ function negmod(n, m) {
function updateOnBackgroundChange() {
const modalImage = gradioApp().getElementById("modalImage")
if (modalImage && modalImage.offsetParent) {
- let allcurrentButtons = gradioApp().querySelectorAll(".gallery-item.transition-all.\\!ring-2")
- let currentButton = null
- allcurrentButtons.forEach(function(elem) {
- if (elem.parentElement.offsetParent) {
- currentButton = elem;
- }
- })
+ let currentButton = selected_gallery_button();
if (currentButton?.children?.length > 0 && modalImage.src != currentButton.children[0].src) {
modalImage.src = currentButton.children[0].src;
@@ -50,22 +44,10 @@ function updateOnBackgroundChange() {
}
function modalImageSwitch(offset) {
- var allgalleryButtons = gradioApp().querySelectorAll(".gallery-item.transition-all")
- var galleryButtons = []
- allgalleryButtons.forEach(function(elem) {
- if (elem.parentElement.offsetParent) {
- galleryButtons.push(elem);
- }
- })
+ var galleryButtons = all_gallery_buttons();
if (galleryButtons.length > 1) {
- var allcurrentButtons = gradioApp().querySelectorAll(".gallery-item.transition-all.\\!ring-2")
- var currentButton = null
- allcurrentButtons.forEach(function(elem) {
- if (elem.parentElement.offsetParent) {
- currentButton = elem;
- }
- })
+ var currentButton = selected_gallery_button();
var result = -1
galleryButtons.forEach(function(v, i) {
@@ -136,37 +118,29 @@ function modalKeyHandler(event) {
}
}
-function showGalleryImage() {
- setTimeout(function() {
- fullImg_preview = gradioApp().querySelectorAll('img.w-full.object-contain')
-
- if (fullImg_preview != null) {
- fullImg_preview.forEach(function function_name(e) {
- if (e.dataset.modded)
- return;
- e.dataset.modded = true;
- if(e && e.parentElement.tagName == 'DIV'){
- e.style.cursor='pointer'
- e.style.userSelect='none'
-
- var isFirefox = isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1
-
- // For Firefox, listening on click first switched to next image then shows the lightbox.
- // If you know how to fix this without switching to mousedown event, please.
- // For other browsers the event is click to make it possiblr to drag picture.
- var event = isFirefox ? 'mousedown' : 'click'
-
- e.addEventListener(event, function (evt) {
- if(!opts.js_modal_lightbox || evt.button != 0) return;
- modalZoomSet(gradioApp().getElementById('modalImage'), opts.js_modal_lightbox_initially_zoomed)
- evt.preventDefault()
- showModal(evt)
- }, true);
- }
- });
- }
+function setupImageForLightbox(e) {
+ if (e.dataset.modded)
+ return;
+
+ e.dataset.modded = true;
+ e.style.cursor='pointer'
+ e.style.userSelect='none'
+
+ var isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1
+
+ // For Firefox, listening on click first switched to next image then shows the lightbox.
+ // If you know how to fix this without switching to mousedown event, please.
+ // For other browsers the event is click to make it possiblr to drag picture.
+ var event = isFirefox ? 'mousedown' : 'click'
+
+ e.addEventListener(event, function (evt) {
+ if(!opts.js_modal_lightbox || evt.button != 0) return;
+
+ modalZoomSet(gradioApp().getElementById('modalImage'), opts.js_modal_lightbox_initially_zoomed)
+ evt.preventDefault()
+ showModal(evt)
+ }, true);
- }, 100);
}
function modalZoomSet(modalImage, enable) {
@@ -199,21 +173,21 @@ function modalTileImageToggle(event) {
}
function galleryImageHandler(e) {
- if (e && e.parentElement.tagName == 'BUTTON') {
+ //if (e && e.parentElement.tagName == 'BUTTON') {
e.onclick = showGalleryImage;
- }
+ //}
}
onUiUpdate(function() {
- fullImg_preview = gradioApp().querySelectorAll('img.w-full')
+ fullImg_preview = gradioApp().querySelectorAll('.gradio-gallery > div > img')
if (fullImg_preview != null) {
- fullImg_preview.forEach(galleryImageHandler);
+ fullImg_preview.forEach(setupImageForLightbox);
}
updateOnBackgroundChange();
})
document.addEventListener("DOMContentLoaded", function() {
- const modalFragment = document.createDocumentFragment();
+ //const modalFragment = document.createDocumentFragment();
const modal = document.createElement('div')
modal.onclick = closeModal;
modal.id = "lightboxModal";
@@ -277,9 +251,9 @@ document.addEventListener("DOMContentLoaded", function() {
modal.appendChild(modalNext)
+ gradioApp().appendChild(modal)
- gradioApp().getRootNode().appendChild(modal)
- document.body.appendChild(modalFragment);
+ document.body.appendChild(modal);
});
diff --git a/javascript/notification.js b/javascript/notification.js
index 5ae6df24..8ddd4c5d 100644
--- a/javascript/notification.js
+++ b/javascript/notification.js
@@ -15,7 +15,7 @@ onUiUpdate(function(){
}
}
- const galleryPreviews = gradioApp().querySelectorAll('div[id^="tab_"][style*="display: block"] div[id$="_results"] img.h-full.w-full.overflow-hidden');
+ const galleryPreviews = gradioApp().querySelectorAll('div[id^="tab_"][style*="display: block"] div[id$="_results"] .thumbnail-item > img');
if (galleryPreviews == null) return;
diff --git a/javascript/progressbar.js b/javascript/progressbar.js
index 9ccc9da4..4ac9b8db 100644
--- a/javascript/progressbar.js
+++ b/javascript/progressbar.js
@@ -1,78 +1,13 @@
// code related to showing and updating progressbar shown as the image is being made
-
-galleries = {}
-storedGallerySelections = {}
-galleryObservers = {}
-
function rememberGallerySelection(id_gallery){
- storedGallerySelections[id_gallery] = getGallerySelectedIndex(id_gallery)
-}
-function getGallerySelectedIndex(id_gallery){
- let galleryButtons = gradioApp().querySelectorAll('#'+id_gallery+' .gallery-item')
- let galleryBtnSelected = gradioApp().querySelector('#'+id_gallery+' .gallery-item.\\!ring-2')
-
- let currentlySelectedIndex = -1
- galleryButtons.forEach(function(v, i){ if(v==galleryBtnSelected) { currentlySelectedIndex = i } })
-
- return currentlySelectedIndex
}
-// this is a workaround for https://github.com/gradio-app/gradio/issues/2984
-function check_gallery(id_gallery){
- let gallery = gradioApp().getElementById(id_gallery)
- // if gallery has no change, no need to setting up observer again.
- if (gallery && galleries[id_gallery] !== gallery){
- galleries[id_gallery] = gallery;
- if(galleryObservers[id_gallery]){
- galleryObservers[id_gallery].disconnect();
- }
+function getGallerySelectedIndex(id_gallery){
- storedGallerySelections[id_gallery] = -1
-
- galleryObservers[id_gallery] = new MutationObserver(function (){
- let galleryButtons = gradioApp().querySelectorAll('#'+id_gallery+' .gallery-item')
- let galleryBtnSelected = gradioApp().querySelector('#'+id_gallery+' .gallery-item.\\!ring-2')
- let currentlySelectedIndex = getGallerySelectedIndex(id_gallery)
- prevSelectedIndex = storedGallerySelections[id_gallery]
- storedGallerySelections[id_gallery] = -1
-
- if (prevSelectedIndex !== -1 && galleryButtons.length>prevSelectedIndex && !galleryBtnSelected) {
- // automatically re-open previously selected index (if exists)
- activeElement = gradioApp().activeElement;
- let scrollX = window.scrollX;
- let scrollY = window.scrollY;
-
- galleryButtons[prevSelectedIndex].click();
- showGalleryImage();
-
- // When the gallery button is clicked, it gains focus and scrolls itself into view
- // We need to scroll back to the previous position
- setTimeout(function (){
- window.scrollTo(scrollX, scrollY);
- }, 50);
-
- if(activeElement){
- // i fought this for about an hour; i don't know why the focus is lost or why this helps recover it
- // if someone has a better solution please by all means
- setTimeout(function (){
- activeElement.focus({
- preventScroll: true // Refocus the element that was focused before the gallery was opened without scrolling to it
- })
- }, 1);
- }
- }
- })
- galleryObservers[id_gallery].observe( gallery, { childList:true, subtree:false })
- }
}
-onUiUpdate(function(){
- check_gallery('txt2img_gallery')
- check_gallery('img2img_gallery')
-})
-
function request(url, data, handler, errorHandler){
var xhr = new XMLHttpRequest();
var url = url;
diff --git a/javascript/ui.js b/javascript/ui.js
index b7a8268a..4a440193 100644
--- a/javascript/ui.js
+++ b/javascript/ui.js
@@ -7,9 +7,31 @@ function set_theme(theme){
}
}
+function all_gallery_buttons() {
+ var allGalleryButtons = gradioApp().querySelectorAll('[style="display: block;"].tabitem div[id$=_gallery].gradio-gallery .thumbnails > .thumbnail-item.thumbnail-small');
+ var visibleGalleryButtons = [];
+ allGalleryButtons.forEach(function(elem) {
+ if (elem.parentElement.offsetParent) {
+ visibleGalleryButtons.push(elem);
+ }
+ })
+ return visibleGalleryButtons;
+}
+
+function selected_gallery_button() {
+ var allCurrentButtons = gradioApp().querySelectorAll('[style="display: block;"].tabitem div[id$=_gallery].gradio-gallery .thumbnail-item.thumbnail-small.selected');
+ var visibleCurrentButton = null;
+ allCurrentButtons.forEach(function(elem) {
+ if (elem.parentElement.offsetParent) {
+ visibleCurrentButton = elem;
+ }
+ })
+ return visibleCurrentButton;
+}
+
function selected_gallery_index(){
- var buttons = gradioApp().querySelectorAll('[style="display: block;"].tabitem div[id$=_gallery] .gallery-item')
- var button = gradioApp().querySelector('[style="display: block;"].tabitem div[id$=_gallery] .gallery-item.\\!ring-2')
+ var buttons = all_gallery_buttons();
+ var button = selected_gallery_button();
var result = -1
buttons.forEach(function(v, i){ if(v==button) { result = i } })
@@ -18,14 +40,18 @@ function selected_gallery_index(){
}
function extract_image_from_gallery(gallery){
- if(gallery.length == 1){
- return [gallery[0]]
+ if (gallery.length == 0){
+ return [null];
+ }
+ if (gallery.length == 1){
+ return [gallery[0]];
}
index = selected_gallery_index()
if (index < 0 || index >= gallery.length){
- return [null]
+ // Use the first image in the gallery as the default
+ index = 0;
}
return [gallery[index]];
@@ -86,7 +112,7 @@ function get_tab_index(tabId){
var res = 0
gradioApp().getElementById(tabId).querySelector('div').querySelectorAll('button').forEach(function(button, i){
- if(button.className.indexOf('bg-white') != -1)
+ if(button.className.indexOf('selected') != -1)
res = i
})
@@ -255,7 +281,6 @@ onUiUpdate(function(){
}
prompt.parentElement.insertBefore(counter, prompt)
- counter.classList.add("token-counter")
prompt.parentElement.style.position = "relative"
promptTokecountUpdateFuncs[id] = function(){ update_token_counter(id_button); }