diff options
Diffstat (limited to 'javascript/ui.js')
-rw-r--r-- | javascript/ui.js | 184 |
1 files changed, 150 insertions, 34 deletions
diff --git a/javascript/ui.js b/javascript/ui.js index 2cb280e5..b7a8268a 100644 --- a/javascript/ui.js +++ b/javascript/ui.js @@ -1,4 +1,4 @@ -// various functions for interation with ui.py not large enough to warrant putting them in separate files +// 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 @@ -19,7 +19,7 @@ function selected_gallery_index(){ function extract_image_from_gallery(gallery){ if(gallery.length == 1){ - return gallery[0] + return [gallery[0]] } index = selected_gallery_index() @@ -28,7 +28,7 @@ function extract_image_from_gallery(gallery){ return [null] } - return gallery[index]; + return [gallery[index]]; } function args_to_array(args){ @@ -45,16 +45,33 @@ function switch_to_txt2img(){ return args_to_array(arguments); } -function switch_to_img2img(){ +function switch_to_img2img_tab(no){ gradioApp().querySelector('#tabs').querySelectorAll('button')[1].click(); - gradioApp().getElementById('mode_img2img').querySelectorAll('button')[0].click(); + gradioApp().getElementById('mode_img2img').querySelectorAll('button')[no].click(); +} +function switch_to_img2img(){ + switch_to_img2img_tab(0); + return args_to_array(arguments); +} +function switch_to_sketch(){ + switch_to_img2img_tab(1); + return args_to_array(arguments); +} + +function switch_to_inpaint(){ + switch_to_img2img_tab(2); + return args_to_array(arguments); +} + +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')[1].click(); + gradioApp().getElementById('mode_img2img').querySelectorAll('button')[2].click(); return args_to_array(arguments); } @@ -87,9 +104,11 @@ function create_tab_index_args(tabId, args){ return res } -function get_extras_tab_index(){ - const [,,...args] = [...arguments] - return [get_tab_index('mode_extras'), get_tab_index('extras_resize_mode'), ...args] +function get_img2img_tab_index() { + let res = args_to_array(arguments) + res.splice(-2) + res[0] = get_tab_index('mode_img2img') + return res } function create_submit_args(args){ @@ -100,7 +119,7 @@ function create_submit_args(args){ // 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 seding outputs along with inputs, but we can prevent sending the image gallery here, which seems to be an issue for some. + // 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 @@ -109,19 +128,51 @@ function create_submit_args(args){ 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 submit(){ - requestProgress('txt2img') + rememberGallerySelection('txt2img_gallery') + showSubmitButtons('txt2img', false) + + var id = randomId() + requestProgress(id, gradioApp().getElementById('txt2img_gallery_container'), gradioApp().getElementById('txt2img_gallery'), function(){ + showSubmitButtons('txt2img', true) + + }) - return create_submit_args(arguments) + var res = create_submit_args(arguments) + + res[0] = id + + return res } function submit_img2img(){ - requestProgress('img2img') + rememberGallerySelection('img2img_gallery') + showSubmitButtons('img2img', false) - res = create_submit_args(arguments) + var id = randomId() + requestProgress(id, gradioApp().getElementById('img2img_gallery_container'), gradioApp().getElementById('img2img_gallery'), function(){ + showSubmitButtons('img2img', true) + }) - res[0] = get_tab_index('mode_img2img') + var res = create_submit_args(arguments) + + res[0] = id + res[1] = get_tab_index('mode_img2img') + + return res +} + +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 } @@ -141,26 +192,38 @@ function confirm_clear_prompt(prompt, negative_prompt) { } +promptTokecountUpdateFuncs = {} -opts = {} -function apply_settings(jsdata){ - console.log(jsdata) +function recalculatePromptTokens(name){ + if(promptTokecountUpdateFuncs[name]){ + promptTokecountUpdateFuncs[name]() + } +} - opts = JSON.parse(jsdata) +function recalculate_prompts_txt2img(){ + recalculatePromptTokens('txt2img_prompt') + recalculatePromptTokens('txt2img_neg_prompt') + return args_to_array(arguments); +} - return jsdata +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; json_elem = gradioApp().getElementById('settings_json') if(json_elem == null) return; - textarea = json_elem.querySelector('textarea') - jsdata = textarea.value + var textarea = json_elem.querySelector('textarea') + var jsdata = textarea.value opts = JSON.parse(jsdata) - + executeCallbacks(optionsChangedCallbacks); Object.defineProperty(textarea, 'value', { set: function(newValue) { @@ -171,6 +234,8 @@ onUiUpdate(function(){ if (oldValue != newValue) { opts = JSON.parse(textarea.value) } + + executeCallbacks(optionsChangedCallbacks); }, get: function() { var valueProp = Object.getOwnPropertyDescriptor(HTMLTextAreaElement.prototype, 'value'); @@ -180,19 +245,55 @@ onUiUpdate(function(){ json_elem.parentElement.style.display="none" - if (!txt2img_textarea) { - txt2img_textarea = gradioApp().querySelector("#txt2img_prompt > label > textarea"); - txt2img_textarea?.addEventListener("input", () => update_token_counter("txt2img_token_button")); - } - if (!img2img_textarea) { - img2img_textarea = gradioApp().querySelector("#img2img_prompt > label > textarea"); - img2img_textarea?.addEventListener("input", () => update_token_counter("img2img_token_button")); + 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 + } + + prompt.parentElement.insertBefore(counter, prompt) + counter.classList.add("token-counter") + prompt.parentElement.style.position = "relative" + + 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){ + 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) + + 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 token_timeout; +let token_timeouts = {}; function update_txt2img_tokens(...args) { update_token_counter("txt2img_token_button") @@ -209,9 +310,9 @@ function update_img2img_tokens(...args) { } function update_token_counter(button_id) { - if (token_timeout) - clearTimeout(token_timeout); - token_timeout = 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(){ @@ -220,3 +321,18 @@ function restart_reload(){ 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); +} + + +var desiredCheckpointName = null; +function selectCheckpoint(name){ + desiredCheckpointName = name; + gradioApp().getElementById('change_checkpoint').click() +} |