2022-11-02 10:05:00 -06:00
// various functions for interaction with ui.py not large enough to warrant putting them in separate files
2022-09-02 14:25:29 -06:00
2022-10-17 10:24:24 -06:00
function set _theme ( theme ) {
2023-04-30 13:08:52 -06:00
var gradioURL = window . location . href ;
2022-10-17 10:24:24 -06:00
if ( ! gradioURL . includes ( '?__theme=' ) ) {
window . location . replace ( gradioURL + '?__theme=' + theme ) ;
2022-10-17 03:05:05 -06:00
}
}
2023-03-25 12:52:47 -06:00
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 ( ) {
2023-08-18 20:38:43 -06:00
return all _gallery _buttons ( ) . find ( elem => elem . classList . contains ( 'selected' ) ) ? ? null ;
2023-03-25 12:52:47 -06:00
}
2022-09-02 14:25:29 -06:00
function selected _gallery _index ( ) {
2023-08-18 20:38:43 -06:00
return all _gallery _buttons ( ) . findIndex ( elem => elem . classList . contains ( 'selected' ) ) ;
2022-09-02 14:25:29 -06:00
}
function extract _image _from _gallery ( gallery ) {
2023-03-25 12:52:47 -06:00
if ( gallery . length == 0 ) {
return [ null ] ;
}
if ( gallery . length == 1 ) {
return [ gallery [ 0 ] ] ;
2022-09-02 14:25:29 -06:00
}
2023-04-30 13:08:52 -06:00
var index = selected _gallery _index ( ) ;
2022-09-02 14:25:29 -06:00
if ( index < 0 || index >= gallery . length ) {
2023-03-25 12:52:47 -06:00
// Use the first image in the gallery as the default
index = 0 ;
2022-09-02 14:25:29 -06:00
}
2023-01-02 12:44:46 -07:00
return [ gallery [ index ] ] ;
2022-09-10 15:17:34 -06:00
}
2023-05-19 04:01:36 -06:00
window . args _to _array = Array . from ; // Compatibility with e.g. extensions that may expect this to be around
2022-09-23 13:49:21 -06:00
function switch _to _txt2img ( ) {
2022-10-13 11:42:27 -06:00
gradioApp ( ) . querySelector ( '#tabs' ) . querySelectorAll ( 'button' ) [ 0 ] . click ( ) ;
2022-09-23 13:49:21 -06:00
2023-05-19 04:01:36 -06:00
return Array . from ( arguments ) ;
2022-09-23 13:49:21 -06:00
}
2023-01-14 12:43:01 -07:00
function switch _to _img2img _tab ( no ) {
2022-10-13 11:42:27 -06:00
gradioApp ( ) . querySelector ( '#tabs' ) . querySelectorAll ( 'button' ) [ 1 ] . click ( ) ;
2023-01-14 12:43:01 -07:00
gradioApp ( ) . getElementById ( 'mode_img2img' ) . querySelectorAll ( 'button' ) [ no ] . click ( ) ;
}
function switch _to _img2img ( ) {
switch _to _img2img _tab ( 0 ) ;
2023-05-19 04:01:36 -06:00
return Array . from ( arguments ) ;
2023-01-14 12:43:01 -07:00
}
function switch _to _sketch ( ) {
switch _to _img2img _tab ( 1 ) ;
2023-05-19 04:01:36 -06:00
return Array . from ( arguments ) ;
2023-01-14 12:43:01 -07:00
}
function switch _to _inpaint ( ) {
switch _to _img2img _tab ( 2 ) ;
2023-05-19 04:01:36 -06:00
return Array . from ( arguments ) ;
2023-01-14 12:43:01 -07:00
}
2022-09-23 13:49:21 -06:00
2023-01-14 12:43:01 -07:00
function switch _to _inpaint _sketch ( ) {
switch _to _img2img _tab ( 3 ) ;
2023-05-19 04:01:36 -06:00
return Array . from ( arguments ) ;
2022-09-23 13:49:21 -06:00
}
function switch _to _extras ( ) {
2022-10-13 11:42:27 -06:00
gradioApp ( ) . querySelector ( '#tabs' ) . querySelectorAll ( 'button' ) [ 2 ] . click ( ) ;
2022-09-23 13:49:21 -06:00
2023-05-19 04:01:36 -06:00
return Array . from ( arguments ) ;
2022-09-23 13:49:21 -06:00
}
2022-09-22 03:11:48 -06:00
function get _tab _index ( tabId ) {
2023-05-19 04:06:12 -06:00
let buttons = gradioApp ( ) . getElementById ( tabId ) . querySelector ( 'div' ) . querySelectorAll ( 'button' ) ;
for ( let i = 0 ; i < buttons . length ; i ++ ) {
if ( buttons [ i ] . classList . contains ( 'selected' ) ) {
return i ;
2023-05-17 06:46:58 -06:00
}
2023-05-19 04:06:12 -06:00
}
return 0 ;
2022-09-22 03:11:48 -06:00
}
function create _tab _index _args ( tabId , args ) {
2023-05-19 04:01:36 -06:00
var res = Array . from ( args ) ;
2022-09-22 03:11:48 -06:00
res [ 0 ] = get _tab _index ( tabId ) ;
return res ;
}
2023-01-18 10:16:52 -07:00
function get _img2img _tab _index ( ) {
2023-05-19 04:01:36 -06:00
let res = Array . from ( arguments ) ;
2023-03-28 11:36:57 -06:00
res . splice ( - 2 ) ;
2023-01-18 10:16:52 -07:00
res [ 0 ] = get _tab _index ( 'mode_img2img' ) ;
return res ;
}
2022-09-22 03:11:48 -06:00
function create _submit _args ( args ) {
2023-05-19 04:01:36 -06:00
var res = Array . from ( args ) ;
2022-09-16 23:03:47 -06:00
// 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.
2022-12-14 19:01:32 -07:00
// 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.
2022-09-16 23:03:47 -06:00
// If gradio at some point stops sending outputs, this may break something
if ( Array . isArray ( res [ res . length - 3 ] ) ) {
res [ res . length - 3 ] = null ;
}
2022-09-05 17:09:01 -06:00
return res ;
2022-09-07 12:26:19 -06:00
}
2022-09-07 13:58:11 -06:00
2024-02-01 12:34:29 -07:00
function setSubmitButtonsVisibility ( tabname , showInterrupt , showSkip , showInterrupting ) {
gradioApp ( ) . getElementById ( tabname + '_interrupt' ) . style . display = showInterrupt ? "block" : "none" ;
gradioApp ( ) . getElementById ( tabname + '_skip' ) . style . display = showSkip ? "block" : "none" ;
gradioApp ( ) . getElementById ( tabname + '_interrupting' ) . style . display = showInterrupting ? "block" : "none" ;
}
2023-01-15 08:50:56 -07:00
function showSubmitButtons ( tabname , show ) {
2024-02-02 10:51:54 -07:00
setSubmitButtonsVisibility ( tabname , ! show , ! show , false ) ;
2024-02-01 12:34:29 -07:00
}
function showSubmitInterruptingPlaceholder ( tabname ) {
setSubmitButtonsVisibility ( tabname , false , true , true ) ;
2023-01-15 08:50:56 -07:00
}
2023-04-29 13:16:54 -06:00
function showRestoreProgressButton ( tabname , show ) {
2023-04-30 13:08:52 -06:00
var button = gradioApp ( ) . getElementById ( tabname + "_restore_progress" ) ;
2023-04-29 13:16:54 -06:00
if ( ! button ) return ;
2024-03-11 12:26:50 -06:00
button . style . setProperty ( 'display' , show ? 'flex' : 'none' , 'important' ) ;
2023-04-29 13:16:54 -06:00
}
2022-09-22 03:11:48 -06:00
function submit ( ) {
2023-01-15 08:50:56 -07:00
showSubmitButtons ( 'txt2img' , false ) ;
2023-03-28 10:17:19 -06:00
var id = randomId ( ) ;
2023-08-04 23:48:03 -06:00
localSet ( "txt2img_task_id" , id ) ;
2023-04-29 13:16:54 -06:00
2023-01-15 08:50:56 -07:00
requestProgress ( id , gradioApp ( ) . getElementById ( 'txt2img_gallery_container' ) , gradioApp ( ) . getElementById ( 'txt2img_gallery' ) , function ( ) {
showSubmitButtons ( 'txt2img' , true ) ;
2023-08-04 23:48:03 -06:00
localRemove ( "txt2img_task_id" ) ;
2023-04-29 13:16:54 -06:00
showRestoreProgressButton ( 'txt2img' , false ) ;
2023-01-15 08:50:56 -07:00
} ) ;
2022-09-22 03:11:48 -06:00
2023-01-15 08:50:56 -07:00
var res = create _submit _args ( arguments ) ;
res [ 0 ] = id ;
return res ;
2022-09-22 03:11:48 -06:00
}
2024-01-01 09:31:06 -07:00
function submit _txt2img _upscale ( ) {
2024-01-01 10:20:54 -07:00
var res = submit ( ... arguments ) ;
2024-01-01 09:31:06 -07:00
res [ 2 ] = selected _gallery _index ( ) ;
return res ;
}
2022-09-22 03:11:48 -06:00
function submit _img2img ( ) {
2023-01-15 08:50:56 -07:00
showSubmitButtons ( 'img2img' , false ) ;
2023-03-28 10:17:19 -06:00
var id = randomId ( ) ;
2023-08-04 23:48:03 -06:00
localSet ( "img2img_task_id" , id ) ;
2023-04-29 13:16:54 -06:00
2023-01-15 08:50:56 -07:00
requestProgress ( id , gradioApp ( ) . getElementById ( 'img2img_gallery_container' ) , gradioApp ( ) . getElementById ( 'img2img_gallery' ) , function ( ) {
showSubmitButtons ( 'img2img' , true ) ;
2023-08-04 23:48:03 -06:00
localRemove ( "img2img_task_id" ) ;
2023-04-29 13:16:54 -06:00
showRestoreProgressButton ( 'img2img' , false ) ;
2023-01-15 08:50:56 -07:00
} ) ;
2022-09-22 03:11:48 -06:00
2023-01-15 08:50:56 -07:00
var res = create _submit _args ( arguments ) ;
2022-09-22 03:11:48 -06:00
2023-01-15 08:50:56 -07:00
res [ 0 ] = id ;
res [ 1 ] = get _tab _index ( 'mode_img2img' ) ;
2022-09-22 03:11:48 -06:00
return res ;
}
2023-12-02 08:01:11 -07:00
function submit _extras ( ) {
showSubmitButtons ( 'extras' , false ) ;
var id = randomId ( ) ;
requestProgress ( id , gradioApp ( ) . getElementById ( 'extras_gallery_container' ) , gradioApp ( ) . getElementById ( 'extras_gallery' ) , function ( ) {
showSubmitButtons ( 'extras' , true ) ;
} ) ;
var res = create _submit _args ( arguments ) ;
res [ 0 ] = id ;
console . log ( res ) ;
return res ;
}
2023-04-30 13:12:24 -06:00
function restoreProgressTxt2img ( ) {
2023-05-01 04:58:10 -06:00
showRestoreProgressButton ( "txt2img" , false ) ;
2023-08-04 23:48:03 -06:00
var id = localGet ( "txt2img_task_id" ) ;
2023-04-29 13:16:54 -06:00
if ( id ) {
2024-03-11 12:26:50 -06:00
showSubmitInterruptingPlaceholder ( 'txt2img' ) ;
2023-04-29 13:16:54 -06:00
requestProgress ( id , gradioApp ( ) . getElementById ( 'txt2img_gallery_container' ) , gradioApp ( ) . getElementById ( 'txt2img_gallery' ) , function ( ) {
showSubmitButtons ( 'txt2img' , true ) ;
} , null , 0 ) ;
}
2023-05-01 04:59:52 -06:00
return id ;
2023-04-29 13:16:54 -06:00
}
2023-05-01 04:58:10 -06:00
2023-04-30 13:12:24 -06:00
function restoreProgressImg2img ( ) {
2023-05-01 05:39:46 -06:00
showRestoreProgressButton ( "img2img" , false ) ;
2023-04-29 13:16:54 -06:00
2023-08-04 23:48:03 -06:00
var id = localGet ( "img2img_task_id" ) ;
2023-04-29 13:16:54 -06:00
if ( id ) {
2024-03-11 12:26:50 -06:00
showSubmitInterruptingPlaceholder ( 'img2img' ) ;
2023-04-29 13:16:54 -06:00
requestProgress ( id , gradioApp ( ) . getElementById ( 'img2img_gallery_container' ) , gradioApp ( ) . getElementById ( 'img2img_gallery' ) , function ( ) {
showSubmitButtons ( 'img2img' , true ) ;
} , null , 0 ) ;
}
2023-05-01 04:59:52 -06:00
return id ;
2023-04-29 13:16:54 -06:00
}
2023-12-13 03:22:13 -07:00
/ * *
* Configure the width and height elements on ` tabname ` to accept
* pasting of resolutions in the form of "width x height" .
* /
function setupResolutionPasting ( tabname ) {
var width = gradioApp ( ) . querySelector ( ` # ${ tabname } _width input[type=number] ` ) ;
var height = gradioApp ( ) . querySelector ( ` # ${ tabname } _height input[type=number] ` ) ;
for ( const el of [ width , height ] ) {
el . addEventListener ( 'paste' , function ( event ) {
var pasteData = event . clipboardData . getData ( 'text/plain' ) ;
var parsed = pasteData . match ( /^\s*(\d+)\D+(\d+)\s*$/ ) ;
if ( parsed ) {
width . value = parsed [ 1 ] ;
height . value = parsed [ 2 ] ;
updateInput ( width ) ;
updateInput ( height ) ;
event . preventDefault ( ) ;
}
} ) ;
}
}
2023-04-29 13:16:54 -06:00
onUiLoaded ( function ( ) {
2023-08-04 23:48:03 -06:00
showRestoreProgressButton ( 'txt2img' , localGet ( "txt2img_task_id" ) ) ;
showRestoreProgressButton ( 'img2img' , localGet ( "img2img_task_id" ) ) ;
2023-12-13 03:22:13 -07:00
setupResolutionPasting ( 'txt2img' ) ;
setupResolutionPasting ( 'img2img' ) ;
2023-04-29 13:16:54 -06:00
} ) ;
2023-01-18 23:25:37 -07:00
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 ;
}
2022-09-22 03:11:48 -06:00
2022-09-11 08:35:12 -06:00
function ask _for _style _name ( _ , prompt _text , negative _prompt _text ) {
2023-04-30 13:08:52 -06:00
var name _ = prompt ( 'Style name:' ) ;
2022-10-15 05:22:30 -06:00
return [ name _ , prompt _text , negative _prompt _text ] ;
2022-09-09 14:16:02 -06:00
}
2022-09-18 13:25:18 -06:00
2022-12-10 03:46:18 -07:00
function confirm _clear _prompt ( prompt , negative _prompt ) {
if ( confirm ( "Delete prompt?" ) ) {
prompt = "" ;
negative _prompt = "" ;
2022-10-20 00:08:24 -06:00
}
2022-10-20 16:03:25 -06:00
2022-12-10 03:46:18 -07:00
return [ prompt , negative _prompt ] ;
2022-10-20 00:08:24 -06:00
}
2023-01-29 15:03:31 -07:00
2023-04-30 13:08:52 -06:00
var opts = { } ;
2023-05-25 00:09:13 -06:00
onAfterUiUpdate ( function ( ) {
2022-09-18 13:25:18 -06:00
if ( Object . keys ( opts ) . length != 0 ) return ;
2023-04-30 13:08:52 -06:00
var json _elem = gradioApp ( ) . getElementById ( 'settings_json' ) ;
2022-09-18 13:25:18 -06:00
if ( json _elem == null ) return ;
2023-01-20 23:48:38 -07:00
var textarea = json _elem . querySelector ( 'textarea' ) ;
var jsdata = textarea . value ;
2022-09-18 13:25:18 -06:00
opts = JSON . parse ( jsdata ) ;
2023-05-18 00:59:10 -06:00
executeCallbacks ( optionsChangedCallbacks ) ; /*global optionsChangedCallbacks*/
2022-09-18 13:25:18 -06:00
Object . defineProperty ( textarea , 'value' , {
set : function ( newValue ) {
var valueProp = Object . getOwnPropertyDescriptor ( HTMLTextAreaElement . prototype , 'value' ) ;
var oldValue = valueProp . get . call ( textarea ) ;
valueProp . set . call ( textarea , newValue ) ;
if ( oldValue != newValue ) {
opts = JSON . parse ( textarea . value ) ;
}
2023-01-14 05:55:40 -07:00
executeCallbacks ( optionsChangedCallbacks ) ;
2022-09-18 13:25:18 -06:00
} ,
get : function ( ) {
var valueProp = Object . getOwnPropertyDescriptor ( HTMLTextAreaElement . prototype , 'value' ) ;
return valueProp . get . call ( textarea ) ;
}
} ) ;
json _elem . parentElement . style . display = "none" ;
} ) ;
2022-09-27 13:56:18 -06:00
2023-01-14 05:55:40 -07:00
onOptionsChanged ( function ( ) {
2023-04-30 13:08:52 -06:00
var elem = gradioApp ( ) . getElementById ( 'sd_checkpoint_hash' ) ;
var sd _checkpoint _hash = opts . sd _checkpoint _hash || "" ;
2023-04-30 13:15:59 -06:00
var shorthash = sd _checkpoint _hash . substring ( 0 , 10 ) ;
2023-01-14 05:55:40 -07:00
if ( elem && elem . textContent != shorthash ) {
elem . textContent = shorthash ;
elem . title = sd _checkpoint _hash ;
elem . href = "https://google.com/search?q=" + sd _checkpoint _hash ;
}
} ) ;
2022-09-28 07:43:54 -06:00
let txt2img _textarea , img2img _textarea = undefined ;
2022-10-01 17:12:49 -06:00
function restart _reload ( ) {
document . body . innerHTML = '<h1 style="font-family:monospace;margin-top:20%;color:lightgray;text-align:center;">Reloading...</h1>' ;
2023-05-09 02:42:47 -06:00
var requestPing = function ( ) {
requestGet ( "./internal/ping" , { } , function ( data ) {
location . reload ( ) ;
} , function ( ) {
setTimeout ( requestPing , 500 ) ;
} ) ;
} ;
setTimeout ( requestPing , 2000 ) ;
2022-11-06 00:02:25 -06:00
return [ ] ;
2022-10-01 17:12:49 -06:00
}
2023-01-17 04:15:47 -07:00
// 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 ) {
2023-05-18 00:59:10 -06:00
let e = new Event ( "input" , { bubbles : true } ) ;
2023-01-17 04:15:47 -07:00
Object . defineProperty ( e , "target" , { value : target } ) ;
target . dispatchEvent ( e ) ;
}
2023-01-28 12:52:27 -07:00
var desiredCheckpointName = null ;
function selectCheckpoint ( name ) {
desiredCheckpointName = name ;
gradioApp ( ) . getElementById ( 'change_checkpoint' ) . click ( ) ;
}
2023-04-03 20:27:48 -06:00
2023-05-18 00:59:10 -06:00
function currentImg2imgSourceResolution ( w , h , scaleBy ) {
2023-03-28 13:23:40 -06:00
var img = gradioApp ( ) . querySelector ( '#mode_img2img > div[style="display: block;"] img' ) ;
return img ? [ img . naturalWidth , img . naturalHeight , scaleBy ] : [ 0 , 0 , scaleBy ] ;
}
2023-04-29 10:39:22 -06:00
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 ) ;
2023-05-18 01:03:48 -06:00
return [ ] ;
2023-05-17 14:18:56 -06:00
}
2023-04-03 20:27:48 -06:00
2023-05-17 14:27:06 -06:00
function setRandomSeed ( elem _id ) {
var input = gradioApp ( ) . querySelector ( "#" + elem _id + " input" ) ;
if ( ! input ) return [ ] ;
input . value = "-1" ;
updateInput ( input ) ;
2023-04-03 20:27:48 -06:00
return [ ] ;
}
2023-05-17 14:27:06 -06:00
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 ;
2023-04-03 20:27:48 -06:00
width . value = height . value ;
height . value = tmp ;
2023-05-17 14:27:06 -06:00
updateInput ( width ) ;
updateInput ( height ) ;
2023-04-03 20:27:48 -06:00
return [ ] ;
}
2023-10-01 01:15:23 -06:00
var onEditTimers = { } ;
2024-03-03 23:37:23 -07:00
// calls func after afterMs milliseconds has passed since the input elem has been edited by user
2023-10-01 01:15:23 -06:00
function onEdit ( editId , elem , afterMs , func ) {
var edited = function ( ) {
var existingTimer = onEditTimers [ editId ] ;
if ( existingTimer ) clearTimeout ( existingTimer ) ;
onEditTimers [ editId ] = setTimeout ( func , afterMs ) ;
} ;
elem . addEventListener ( "input" , edited ) ;
return edited ;
}