diff options
Diffstat (limited to 'javascript/ui.js')
-rw-r--r-- | javascript/ui.js | 476 |
1 files changed, 305 insertions, 171 deletions
diff --git a/javascript/ui.js b/javascript/ui.js index b7a8268a..c7316ddb 100644 --- a/javascript/ui.js +++ b/javascript/ui.js @@ -1,229 +1,302 @@ // various functions for interaction with ui.py not large enough to warrant putting them in separate files -function set_theme(theme){ - gradioURL = window.location.href +function set_theme(theme) { + var gradioURL = window.location.href; if (!gradioURL.includes('?__theme=')) { - window.location.replace(gradioURL + '?__theme=' + theme); + window.location.replace(gradioURL + '?__theme=' + theme); } } -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') +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 = all_gallery_buttons(); + var button = selected_gallery_button(); - var result = -1 - buttons.forEach(function(v, i){ if(v==button) { result = i } }) + var result = -1; + buttons.forEach(function(v, i) { + if (v == button) { + result = i; + } + }); - return result + return result; } -function extract_image_from_gallery(gallery){ - if(gallery.length == 1){ - return [gallery[0]] +function extract_image_from_gallery(gallery) { + if (gallery.length == 0) { + return [null]; + } + if (gallery.length == 1) { + return [gallery[0]]; } - index = selected_gallery_index() + var index = selected_gallery_index(); - if (index < 0 || index >= gallery.length){ - return [null] + if (index < 0 || index >= gallery.length) { + // Use the first image in the gallery as the default + index = 0; } return [gallery[index]]; } -function args_to_array(args){ - res = [] - for(var i=0;i<args.length;i++){ - res.push(args[i]) +function args_to_array(args) { + var res = []; + for (var i = 0; i < args.length; i++) { + res.push(args[i]); } - return res + return res; } -function switch_to_txt2img(){ +function switch_to_txt2img() { gradioApp().querySelector('#tabs').querySelectorAll('button')[0].click(); return args_to_array(arguments); } -function switch_to_img2img_tab(no){ +function switch_to_img2img_tab(no) { gradioApp().querySelector('#tabs').querySelectorAll('button')[1].click(); gradioApp().getElementById('mode_img2img').querySelectorAll('button')[no].click(); } -function switch_to_img2img(){ +function switch_to_img2img() { switch_to_img2img_tab(0); return args_to_array(arguments); } -function switch_to_sketch(){ +function switch_to_sketch() { switch_to_img2img_tab(1); return args_to_array(arguments); } -function switch_to_inpaint(){ +function switch_to_inpaint() { switch_to_img2img_tab(2); return args_to_array(arguments); } -function switch_to_inpaint_sketch(){ +function switch_to_inpaint_sketch() { switch_to_img2img_tab(3); return args_to_array(arguments); } -function switch_to_inpaint(){ - gradioApp().querySelector('#tabs').querySelectorAll('button')[1].click(); - gradioApp().getElementById('mode_img2img').querySelectorAll('button')[2].click(); - - return args_to_array(arguments); -} - -function switch_to_extras(){ +function switch_to_extras() { gradioApp().querySelector('#tabs').querySelectorAll('button')[2].click(); return args_to_array(arguments); } -function get_tab_index(tabId){ - var res = 0 +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) - res = i - }) + gradioApp().getElementById(tabId).querySelector('div').querySelectorAll('button').forEach(function(button, i) { + if (button.className.indexOf('selected') != -1) { + res = i; + } + }); - return res + return res; } -function create_tab_index_args(tabId, args){ - var res = [] - for(var i=0; i<args.length; i++){ - res.push(args[i]) +function create_tab_index_args(tabId, args) { + var res = []; + for (var i = 0; i < args.length; i++) { + res.push(args[i]); } - res[0] = get_tab_index(tabId) + res[0] = get_tab_index(tabId); - return res + return res; } function get_img2img_tab_index() { - let res = args_to_array(arguments) - res.splice(-2) - res[0] = get_tab_index('mode_img2img') - return res + let res = args_to_array(arguments); + res.splice(-2); + res[0] = get_tab_index('mode_img2img'); + return res; } -function create_submit_args(args){ - res = [] - for(var i=0;i<args.length;i++){ - res.push(args[i]) +function create_submit_args(args) { + var res = []; + for (var i = 0; i < args.length; i++) { + res.push(args[i]); } // As it is currently, txt2img and img2img send back the previous output args (txt2img_gallery, generation_info, html_info) whenever you generate a new image. // This can lead to uploading a huge gallery of previously generated images, which leads to an unnecessary delay between submitting and beginning to generate. // I don't know why gradio is sending outputs along with inputs, but we can prevent sending the image gallery here, which seems to be an issue for some. // If gradio at some point stops sending outputs, this may break something - if(Array.isArray(res[res.length - 3])){ - res[res.length - 3] = null + if (Array.isArray(res[res.length - 3])) { + res[res.length - 3] = null; } - return res + return res; +} + +function showSubmitButtons(tabname, show) { + gradioApp().getElementById(tabname + '_interrupt').style.display = show ? "none" : "block"; + gradioApp().getElementById(tabname + '_skip').style.display = show ? "none" : "block"; } -function showSubmitButtons(tabname, show){ - gradioApp().getElementById(tabname+'_interrupt').style.display = show ? "none" : "block" - gradioApp().getElementById(tabname+'_skip').style.display = show ? "none" : "block" +function showRestoreProgressButton(tabname, show) { + var button = gradioApp().getElementById(tabname + "_restore_progress"); + if (!button) return; + + button.style.display = show ? "flex" : "none"; +} + +function submit() { + showSubmitButtons('txt2img', false); + + var id = randomId(); + localStorage.setItem("txt2img_task_id", id); + + requestProgress(id, gradioApp().getElementById('txt2img_gallery_container'), gradioApp().getElementById('txt2img_gallery'), function() { + showSubmitButtons('txt2img', true); + localStorage.removeItem("txt2img_task_id"); + showRestoreProgressButton('txt2img', false); + }); + + var res = create_submit_args(arguments); + + res[0] = id; + + return res; } -function submit(){ - rememberGallerySelection('txt2img_gallery') - showSubmitButtons('txt2img', false) +function submit_img2img() { + showSubmitButtons('img2img', false); - var id = randomId() - requestProgress(id, gradioApp().getElementById('txt2img_gallery_container'), gradioApp().getElementById('txt2img_gallery'), function(){ - showSubmitButtons('txt2img', true) + var id = randomId(); + localStorage.setItem("img2img_task_id", id); - }) + requestProgress(id, gradioApp().getElementById('img2img_gallery_container'), gradioApp().getElementById('img2img_gallery'), function() { + showSubmitButtons('img2img', true); + localStorage.removeItem("img2img_task_id"); + showRestoreProgressButton('img2img', false); + }); - var res = create_submit_args(arguments) + var res = create_submit_args(arguments); - res[0] = id + res[0] = id; + res[1] = get_tab_index('mode_img2img'); - return res + return res; } -function submit_img2img(){ - rememberGallerySelection('img2img_gallery') - showSubmitButtons('img2img', false) +function restoreProgressTxt2img() { + showRestoreProgressButton("txt2img", false); + var id = localStorage.getItem("txt2img_task_id"); + + id = localStorage.getItem("txt2img_task_id"); + + if (id) { + requestProgress(id, gradioApp().getElementById('txt2img_gallery_container'), gradioApp().getElementById('txt2img_gallery'), function() { + showSubmitButtons('txt2img', true); + }, null, 0); + } + + return id; +} - var id = randomId() - requestProgress(id, gradioApp().getElementById('img2img_gallery_container'), gradioApp().getElementById('img2img_gallery'), function(){ - showSubmitButtons('img2img', true) - }) +function restoreProgressImg2img() { + showRestoreProgressButton("img2img", false); - var res = create_submit_args(arguments) + var id = localStorage.getItem("img2img_task_id"); - res[0] = id - res[1] = get_tab_index('mode_img2img') + if (id) { + requestProgress(id, gradioApp().getElementById('img2img_gallery_container'), gradioApp().getElementById('img2img_gallery'), function() { + showSubmitButtons('img2img', true); + }, null, 0); + } - return res + return id; } -function modelmerger(){ - var id = randomId() - requestProgress(id, gradioApp().getElementById('modelmerger_results_panel'), null, function(){}) - var res = create_submit_args(arguments) - res[0] = id - return res +onUiLoaded(function() { + showRestoreProgressButton('txt2img', localStorage.getItem("txt2img_task_id")); + showRestoreProgressButton('img2img', localStorage.getItem("img2img_task_id")); +}); + + +function modelmerger() { + var id = randomId(); + requestProgress(id, gradioApp().getElementById('modelmerger_results_panel'), null, function() {}); + + var res = create_submit_args(arguments); + res[0] = id; + return res; } function ask_for_style_name(_, prompt_text, negative_prompt_text) { - name_ = prompt('Style name:') - return [name_, prompt_text, negative_prompt_text] + var name_ = prompt('Style name:'); + return [name_, prompt_text, negative_prompt_text]; } function confirm_clear_prompt(prompt, negative_prompt) { - if(confirm("Delete prompt?")) { - prompt = "" - negative_prompt = "" + if (confirm("Delete prompt?")) { + prompt = ""; + negative_prompt = ""; } - return [prompt, negative_prompt] + return [prompt, negative_prompt]; } -promptTokecountUpdateFuncs = {} +var promptTokecountUpdateFuncs = {}; -function recalculatePromptTokens(name){ - if(promptTokecountUpdateFuncs[name]){ - promptTokecountUpdateFuncs[name]() +function recalculatePromptTokens(name) { + if (promptTokecountUpdateFuncs[name]) { + promptTokecountUpdateFuncs[name](); } } -function recalculate_prompts_txt2img(){ - recalculatePromptTokens('txt2img_prompt') - recalculatePromptTokens('txt2img_neg_prompt') +function recalculate_prompts_txt2img() { + recalculatePromptTokens('txt2img_prompt'); + recalculatePromptTokens('txt2img_neg_prompt'); return args_to_array(arguments); } -function recalculate_prompts_img2img(){ - recalculatePromptTokens('img2img_prompt') - recalculatePromptTokens('img2img_neg_prompt') +function recalculate_prompts_img2img() { + recalculatePromptTokens('img2img_prompt'); + recalculatePromptTokens('img2img_neg_prompt'); return args_to_array(arguments); } -opts = {} -onUiUpdate(function(){ - if(Object.keys(opts).length != 0) return; +var opts = {}; +onUiUpdate(function() { + if (Object.keys(opts).length != 0) return; + + var json_elem = gradioApp().getElementById('settings_json'); + if (json_elem == null) return; - json_elem = gradioApp().getElementById('settings_json') - if(json_elem == null) return; + var textarea = json_elem.querySelector('textarea'); + var jsdata = textarea.value; + opts = JSON.parse(jsdata); - var textarea = json_elem.querySelector('textarea') - var jsdata = textarea.value - opts = JSON.parse(jsdata) - executeCallbacks(optionsChangedCallbacks); + executeCallbacks(optionsChangedCallbacks); /*global optionsChangedCallbacks*/ Object.defineProperty(textarea, 'value', { set: function(newValue) { @@ -232,7 +305,7 @@ onUiUpdate(function(){ valueProp.set.call(textarea, newValue); if (oldValue != newValue) { - opts = JSON.parse(textarea.value) + opts = JSON.parse(textarea.value); } executeCallbacks(optionsChangedCallbacks); @@ -243,96 +316,157 @@ onUiUpdate(function(){ } }); - json_elem.parentElement.style.display="none" + json_elem.parentElement.style.display = "none"; - function registerTextarea(id, id_counter, id_button){ - var prompt = gradioApp().getElementById(id) - var counter = gradioApp().getElementById(id_counter) + function registerTextarea(id, id_counter, id_button) { + var prompt = gradioApp().getElementById(id); + var counter = gradioApp().getElementById(id_counter); var textarea = gradioApp().querySelector("#" + id + " > label > textarea"); - if(counter.parentElement == prompt.parentElement){ - return + if (counter.parentElement == prompt.parentElement) { + return; } - prompt.parentElement.insertBefore(counter, prompt) - counter.classList.add("token-counter") - prompt.parentElement.style.position = "relative" + prompt.parentElement.insertBefore(counter, prompt); + prompt.parentElement.style.position = "relative"; - promptTokecountUpdateFuncs[id] = function(){ update_token_counter(id_button); } - textarea.addEventListener("input", promptTokecountUpdateFuncs[id]); + promptTokecountUpdateFuncs[id] = function() { + update_token_counter(id_button); + }; + textarea.addEventListener("input", promptTokecountUpdateFuncs[id]); } - registerTextarea('txt2img_prompt', 'txt2img_token_counter', 'txt2img_token_button') - registerTextarea('txt2img_neg_prompt', 'txt2img_negative_token_counter', 'txt2img_negative_token_button') - registerTextarea('img2img_prompt', 'img2img_token_counter', 'img2img_token_button') - registerTextarea('img2img_neg_prompt', 'img2img_negative_token_counter', 'img2img_negative_token_button') - - show_all_pages = gradioApp().getElementById('settings_show_all_pages') - settings_tabs = gradioApp().querySelector('#settings div') - if(show_all_pages && settings_tabs){ - settings_tabs.appendChild(show_all_pages) - show_all_pages.onclick = function(){ - gradioApp().querySelectorAll('#settings > div').forEach(function(elem){ + registerTextarea('txt2img_prompt', 'txt2img_token_counter', 'txt2img_token_button'); + registerTextarea('txt2img_neg_prompt', 'txt2img_negative_token_counter', 'txt2img_negative_token_button'); + registerTextarea('img2img_prompt', 'img2img_token_counter', 'img2img_token_button'); + registerTextarea('img2img_neg_prompt', 'img2img_negative_token_counter', 'img2img_negative_token_button'); + + var show_all_pages = gradioApp().getElementById('settings_show_all_pages'); + var settings_tabs = gradioApp().querySelector('#settings div'); + if (show_all_pages && settings_tabs) { + settings_tabs.appendChild(show_all_pages); + show_all_pages.onclick = function() { + gradioApp().querySelectorAll('#settings > div').forEach(function(elem) { + if (elem.id == "settings_tab_licenses") { + return; + } + elem.style.display = "block"; - }) - } + }); + }; } -}) +}); -onOptionsChanged(function(){ - elem = gradioApp().getElementById('sd_checkpoint_hash') - sd_checkpoint_hash = opts.sd_checkpoint_hash || "" - shorthash = sd_checkpoint_hash.substr(0,10) +onOptionsChanged(function() { + var elem = gradioApp().getElementById('sd_checkpoint_hash'); + var sd_checkpoint_hash = opts.sd_checkpoint_hash || ""; + var shorthash = sd_checkpoint_hash.substring(0, 10); - if(elem && elem.textContent != shorthash){ - elem.textContent = shorthash - elem.title = sd_checkpoint_hash - elem.href = "https://google.com/search?q=" + sd_checkpoint_hash - } -}) + if (elem && elem.textContent != shorthash) { + elem.textContent = shorthash; + elem.title = sd_checkpoint_hash; + elem.href = "https://google.com/search?q=" + sd_checkpoint_hash; + } +}); let txt2img_textarea, img2img_textarea = undefined; -let wait_time = 800 +let wait_time = 800; let token_timeouts = {}; function update_txt2img_tokens(...args) { - update_token_counter("txt2img_token_button") - if (args.length == 2) - return args[0] - return args; + update_token_counter("txt2img_token_button"); + if (args.length == 2) { + return args[0]; + } + return args; } function update_img2img_tokens(...args) { - update_token_counter("img2img_token_button") - if (args.length == 2) - return args[0] - return args; + update_token_counter( + "img2img_token_button" + ); + if (args.length == 2) { + return args[0]; + } + return args; } function update_token_counter(button_id) { - if (token_timeouts[button_id]) - clearTimeout(token_timeouts[button_id]); - token_timeouts[button_id] = setTimeout(() => gradioApp().getElementById(button_id)?.click(), wait_time); + if (token_timeouts[button_id]) { + clearTimeout(token_timeouts[button_id]); + } + token_timeouts[button_id] = setTimeout(() => gradioApp().getElementById(button_id)?.click(), wait_time); } -function restart_reload(){ - document.body.innerHTML='<h1 style="font-family:monospace;margin-top:20%;color:lightgray;text-align:center;">Reloading...</h1>'; - setTimeout(function(){location.reload()},2000) +function restart_reload() { + document.body.innerHTML = '<h1 style="font-family:monospace;margin-top:20%;color:lightgray;text-align:center;">Reloading...</h1>'; + + var requestPing = function() { + requestGet("./internal/ping", {}, function(data) { + location.reload(); + }, function() { + setTimeout(requestPing, 500); + }); + }; + + setTimeout(requestPing, 2000); - return [] + return []; } // Simulate an `input` DOM event for Gradio Textbox component. Needed after you edit its contents in javascript, otherwise your edits // will only visible on web page and not sent to python. -function updateInput(target){ - let e = new Event("input", { bubbles: true }) - Object.defineProperty(e, "target", {value: target}) - target.dispatchEvent(e); +function updateInput(target) { + let e = new Event("input", {bubbles: true}); + Object.defineProperty(e, "target", {value: target}); + target.dispatchEvent(e); } var desiredCheckpointName = null; -function selectCheckpoint(name){ +function selectCheckpoint(name) { desiredCheckpointName = name; - gradioApp().getElementById('change_checkpoint').click() + gradioApp().getElementById('change_checkpoint').click(); +} + +function currentImg2imgSourceResolution(w, h, scaleBy) { + var img = gradioApp().querySelector('#mode_img2img > div[style="display: block;"] img'); + return img ? [img.naturalWidth, img.naturalHeight, scaleBy] : [0, 0, scaleBy]; +} + +function updateImg2imgResizeToTextAfterChangingImage() { + // At the time this is called from gradio, the image has no yet been replaced. + // There may be a better solution, but this is simple and straightforward so I'm going with it. + + setTimeout(function() { + gradioApp().getElementById('img2img_update_resize_to').click(); + }, 500); + + return []; + +} + + + +function setRandomSeed(elem_id) { + var input = gradioApp().querySelector("#" + elem_id + " input"); + if (!input) return []; + + input.value = "-1"; + updateInput(input); + return []; +} + +function switchWidthHeight(tabname) { + var width = gradioApp().querySelector("#" + tabname + "_width input[type=number]"); + var height = gradioApp().querySelector("#" + tabname + "_height input[type=number]"); + if (!width || !height) return []; + + var tmp = width.value; + width.value = height.value; + height.value = tmp; + + updateInput(width); + updateInput(height); + return []; } |