mirror of
https://github.com/AUTOMATIC1111/stable-diffusion-webui.git
synced 2024-06-07 21:20:49 +00:00
d295e97a0d
LF instead CRLF
174 lines
4.9 KiB
JavaScript
174 lines
4.9 KiB
JavaScript
function gradioApp() {
|
|
const elems = document.getElementsByTagName('gradio-app')
|
|
const elem = elems.length == 0 ? document : elems[0]
|
|
|
|
if (elem !== document) {
|
|
elem.getElementById = function (id) {
|
|
return document.getElementById(id)
|
|
}
|
|
}
|
|
return elem.shadowRoot ? elem.shadowRoot : elem
|
|
}
|
|
|
|
/**
|
|
* Get the currently selected top-level UI tab button (e.g. the button that says "Extras").
|
|
*/
|
|
function get_uiCurrentTab() {
|
|
return gradioApp().querySelector('#tabs > .tab-nav > button.selected')
|
|
}
|
|
|
|
/**
|
|
* Get the first currently visible top-level UI tab content (e.g. the div hosting the "txt2img" UI).
|
|
*/
|
|
function get_uiCurrentTabContent() {
|
|
return gradioApp().querySelector(
|
|
'#tabs > .tabitem[id^=tab_]:not([style*="display: none"])'
|
|
)
|
|
}
|
|
|
|
var uiUpdateCallbacks = []
|
|
var uiAfterUpdateCallbacks = []
|
|
var uiLoadedCallbacks = []
|
|
var uiTabChangeCallbacks = []
|
|
var optionsChangedCallbacks = []
|
|
var uiAfterUpdateTimeout = null
|
|
var uiCurrentTab = null
|
|
|
|
/**
|
|
* Register callback to be called at each UI update.
|
|
* The callback receives an array of MutationRecords as an argument.
|
|
*/
|
|
function onUiUpdate(callback) {
|
|
uiUpdateCallbacks.push(callback)
|
|
}
|
|
|
|
/**
|
|
* Register callback to be called soon after UI updates.
|
|
* The callback receives no arguments.
|
|
*
|
|
* This is preferred over `onUiUpdate` if you don't need
|
|
* access to the MutationRecords, as your function will
|
|
* not be called quite as often.
|
|
*/
|
|
function onAfterUiUpdate(callback) {
|
|
uiAfterUpdateCallbacks.push(callback)
|
|
}
|
|
|
|
/**
|
|
* Register callback to be called when the UI is loaded.
|
|
* The callback receives no arguments.
|
|
*/
|
|
function onUiLoaded(callback) {
|
|
uiLoadedCallbacks.push(callback)
|
|
}
|
|
|
|
/**
|
|
* Register callback to be called when the UI tab is changed.
|
|
* The callback receives no arguments.
|
|
*/
|
|
function onUiTabChange(callback) {
|
|
uiTabChangeCallbacks.push(callback)
|
|
}
|
|
|
|
/**
|
|
* Register callback to be called when the options are changed.
|
|
* The callback receives no arguments.
|
|
* @param callback
|
|
*/
|
|
function onOptionsChanged(callback) {
|
|
optionsChangedCallbacks.push(callback)
|
|
}
|
|
|
|
function executeCallbacks(queue, arg) {
|
|
for (const callback of queue) {
|
|
try {
|
|
callback(arg)
|
|
} catch (e) {
|
|
console.error('error running callback', callback, ':', e)
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Schedule the execution of the callbacks registered with onAfterUiUpdate.
|
|
* The callbacks are executed after a short while, unless another call to this function
|
|
* is made before that time. IOW, the callbacks are executed only once, even
|
|
* when there are multiple mutations observed.
|
|
*/
|
|
function scheduleAfterUiUpdateCallbacks() {
|
|
clearTimeout(uiAfterUpdateTimeout)
|
|
uiAfterUpdateTimeout = setTimeout(function () {
|
|
executeCallbacks(uiAfterUpdateCallbacks)
|
|
}, 200)
|
|
}
|
|
|
|
var executedOnLoaded = false
|
|
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
var mutationObserver = new MutationObserver(function (m) {
|
|
if (!executedOnLoaded && gradioApp().querySelector('#txt2img_prompt')) {
|
|
executedOnLoaded = true
|
|
executeCallbacks(uiLoadedCallbacks)
|
|
}
|
|
|
|
executeCallbacks(uiUpdateCallbacks, m)
|
|
scheduleAfterUiUpdateCallbacks()
|
|
const newTab = get_uiCurrentTab()
|
|
if (newTab && newTab !== uiCurrentTab) {
|
|
uiCurrentTab = newTab
|
|
executeCallbacks(uiTabChangeCallbacks)
|
|
}
|
|
})
|
|
mutationObserver.observe(gradioApp(), {childList: true, subtree: true})
|
|
})
|
|
|
|
/**
|
|
* Add a ctrl+enter as a shortcut to start a generation
|
|
*/
|
|
document.addEventListener('keydown', function (e) {
|
|
const isEnter = e.key === 'Enter' || e.keyCode === 13
|
|
const isModifierKey = e.metaKey || e.ctrlKey || e.altKey
|
|
|
|
const interruptButton = get_uiCurrentTabContent().querySelector(
|
|
'button[id$=_interrupt]'
|
|
)
|
|
const generateButton = get_uiCurrentTabContent().querySelector(
|
|
'button[id$=_generate]'
|
|
)
|
|
|
|
if (isEnter && isModifierKey) {
|
|
if (interruptButton.style.display === 'block') {
|
|
interruptButton.click()
|
|
setTimeout(function () {
|
|
generateButton.click()
|
|
}, 500)
|
|
} else {
|
|
generateButton.click()
|
|
}
|
|
e.preventDefault()
|
|
}
|
|
})
|
|
|
|
/**
|
|
* checks that a UI element is not in another hidden element or tab content
|
|
*/
|
|
function uiElementIsVisible(el) {
|
|
if (el === document) {
|
|
return true
|
|
}
|
|
|
|
const computedStyle = getComputedStyle(el)
|
|
const isVisible = computedStyle.display !== 'none'
|
|
|
|
if (!isVisible) return false
|
|
return uiElementIsVisible(el.parentNode)
|
|
}
|
|
|
|
function uiElementInSight(el) {
|
|
const clRect = el.getBoundingClientRect()
|
|
const windowHeight = window.innerHeight
|
|
const isOnScreen = clRect.bottom > 0 && clRect.top < windowHeight
|
|
|
|
return isOnScreen
|
|
}
|