mirror of
https://github.com/easydiffusion/easydiffusion.git
synced 2025-04-30 22:34:32 +02:00
Merge pull request #869 from patriceac/searchable-models-fixes
Model search bug fixes
This commit is contained in:
commit
b7391652ca
@ -127,7 +127,7 @@
|
|||||||
<tr class="pl-5"><td><label for="seed">Seed:</label></td><td><input id="seed" name="seed" size="10" value="0" onkeypress="preventNonNumericalInput(event)"> <input id="random_seed" name="random_seed" type="checkbox" checked><label for="random_seed">Random</label></td></tr>
|
<tr class="pl-5"><td><label for="seed">Seed:</label></td><td><input id="seed" name="seed" size="10" value="0" onkeypress="preventNonNumericalInput(event)"> <input id="random_seed" name="random_seed" type="checkbox" checked><label for="random_seed">Random</label></td></tr>
|
||||||
<tr class="pl-5"><td><label for="num_outputs_total">Number of Images:</label></td><td><input id="num_outputs_total" name="num_outputs_total" value="1" size="1" onkeypress="preventNonNumericalInput(event)"> <label><small>(total)</small></label> <input id="num_outputs_parallel" name="num_outputs_parallel" value="1" size="1" onkeypress="preventNonNumericalInput(event)"> <label for="num_outputs_parallel"><small>(in parallel)</small></label></td></tr>
|
<tr class="pl-5"><td><label for="num_outputs_total">Number of Images:</label></td><td><input id="num_outputs_total" name="num_outputs_total" value="1" size="1" onkeypress="preventNonNumericalInput(event)"> <label><small>(total)</small></label> <input id="num_outputs_parallel" name="num_outputs_parallel" value="1" size="1" onkeypress="preventNonNumericalInput(event)"> <label for="num_outputs_parallel"><small>(in parallel)</small></label></td></tr>
|
||||||
<tr class="pl-5"><td><label for="stable_diffusion_model">Model:</label></td><td class="model-input">
|
<tr class="pl-5"><td><label for="stable_diffusion_model">Model:</label></td><td class="model-input">
|
||||||
<input id="stable_diffusion_model" type="text" spellcheck="false" class="model-filter" data-path="" />
|
<input id="stable_diffusion_model" type="text" spellcheck="false" autocomplete="off" class="model-filter" data-path="" />
|
||||||
<button id="reload-models" class="secondaryButton reloadModels"><i class='fa-solid fa-rotate'></i></button>
|
<button id="reload-models" class="secondaryButton reloadModels"><i class='fa-solid fa-rotate'></i></button>
|
||||||
<a href="https://github.com/cmdr2/stable-diffusion-ui/wiki/Custom-Models" target="_blank"><i class="fa-solid fa-circle-question help-btn"><span class="simple-tooltip top-left">Click to learn more about custom models</span></i></a>
|
<a href="https://github.com/cmdr2/stable-diffusion-ui/wiki/Custom-Models" target="_blank"><i class="fa-solid fa-circle-question help-btn"><span class="simple-tooltip top-left">Click to learn more about custom models</span></i></a>
|
||||||
</td></tr>
|
</td></tr>
|
||||||
@ -136,7 +136,7 @@
|
|||||||
</select>
|
</select>
|
||||||
</td></tr> -->
|
</td></tr> -->
|
||||||
<tr class="pl-5"><td><label for="vae_model">Custom VAE:</i></label></td><td>
|
<tr class="pl-5"><td><label for="vae_model">Custom VAE:</i></label></td><td>
|
||||||
<input id="vae_model" type="text" spellcheck="false" class="model-filter" data-path="" />
|
<input id="vae_model" type="text" spellcheck="false" autocomplete="off" class="model-filter" data-path="" />
|
||||||
<a href="https://github.com/cmdr2/stable-diffusion-ui/wiki/VAE-Variational-Auto-Encoder" target="_blank"><i class="fa-solid fa-circle-question help-btn"><span class="simple-tooltip top-left">Click to learn more about VAEs</span></i></a>
|
<a href="https://github.com/cmdr2/stable-diffusion-ui/wiki/VAE-Variational-Auto-Encoder" target="_blank"><i class="fa-solid fa-circle-question help-btn"><span class="simple-tooltip top-left">Click to learn more about VAEs</span></i></a>
|
||||||
</td></tr>
|
</td></tr>
|
||||||
<tr id="samplerSelection" class="pl-5"><td><label for="sampler_name">Sampler:</label></td><td>
|
<tr id="samplerSelection" class="pl-5"><td><label for="sampler_name">Sampler:</label></td><td>
|
||||||
@ -208,7 +208,7 @@
|
|||||||
<tr class="pl-5"><td><label for="guidance_scale_slider">Guidance Scale:</label></td><td> <input id="guidance_scale_slider" name="guidance_scale_slider" class="editor-slider" value="75" type="range" min="11" max="500"> <input id="guidance_scale" name="guidance_scale" size="4" pattern="^[0-9\.]+$" onkeypress="preventNonNumericalInput(event)"></td></tr>
|
<tr class="pl-5"><td><label for="guidance_scale_slider">Guidance Scale:</label></td><td> <input id="guidance_scale_slider" name="guidance_scale_slider" class="editor-slider" value="75" type="range" min="11" max="500"> <input id="guidance_scale" name="guidance_scale" size="4" pattern="^[0-9\.]+$" onkeypress="preventNonNumericalInput(event)"></td></tr>
|
||||||
<tr id="prompt_strength_container" class="pl-5"><td><label for="prompt_strength_slider">Prompt Strength:</label></td><td> <input id="prompt_strength_slider" name="prompt_strength_slider" class="editor-slider" value="80" type="range" min="0" max="99"> <input id="prompt_strength" name="prompt_strength" size="4" pattern="^[0-9\.]+$" onkeypress="preventNonNumericalInput(event)"><br/></td></tr>
|
<tr id="prompt_strength_container" class="pl-5"><td><label for="prompt_strength_slider">Prompt Strength:</label></td><td> <input id="prompt_strength_slider" name="prompt_strength_slider" class="editor-slider" value="80" type="range" min="0" max="99"> <input id="prompt_strength" name="prompt_strength" size="4" pattern="^[0-9\.]+$" onkeypress="preventNonNumericalInput(event)"><br/></td></tr>
|
||||||
<tr class="pl-5"><td><label for="hypernetwork_model">Hypernetwork:</i></label></td><td>
|
<tr class="pl-5"><td><label for="hypernetwork_model">Hypernetwork:</i></label></td><td>
|
||||||
<input id="hypernetwork_model" type="text" spellcheck="false" class="model-filter" data-path="" />
|
<input id="hypernetwork_model" type="text" spellcheck="false" autocomplete="off" class="model-filter" data-path="" />
|
||||||
</td></tr>
|
</td></tr>
|
||||||
<tr id="hypernetwork_strength_container" class="pl-5">
|
<tr id="hypernetwork_strength_container" class="pl-5">
|
||||||
<td><label for="hypernetwork_strength_slider">Hypernetwork Strength:</label></td>
|
<td><label for="hypernetwork_strength_slider">Hypernetwork Strength:</label></td>
|
||||||
|
@ -12,7 +12,7 @@ Merely calling getModels() makes all the magic happen behind the scene to refres
|
|||||||
|
|
||||||
HOW TO CREATE A MODEL DROPDOWN:
|
HOW TO CREATE A MODEL DROPDOWN:
|
||||||
1) Create an input element. Make sure to add a data-path property, as this is how model dropdowns are identified in auto-save.js.
|
1) Create an input element. Make sure to add a data-path property, as this is how model dropdowns are identified in auto-save.js.
|
||||||
<input id="stable_diffusion_model" type="text" spellcheck="false" class="model-filter" data-path="" />
|
<input id="stable_diffusion_model" type="text" spellcheck="false" autocomplete="off" class="model-filter" data-path="" />
|
||||||
|
|
||||||
2) Just declare one of these for your own dropdown (remember to change the element id, e.g. #stable_diffusion_models to your own input's id).
|
2) Just declare one of these for your own dropdown (remember to change the element id, e.g. #stable_diffusion_models to your own input's id).
|
||||||
let stableDiffusionModelField = new ModelDropdown(document.querySelector('#stable_diffusion_model'), 'stable-diffusion')
|
let stableDiffusionModelField = new ModelDropdown(document.querySelector('#stable_diffusion_model'), 'stable-diffusion')
|
||||||
@ -37,6 +37,7 @@ class ModelDropdown
|
|||||||
modelKey //= undefined
|
modelKey //= undefined
|
||||||
flatModelList //= []
|
flatModelList //= []
|
||||||
noneEntry //= ''
|
noneEntry //= ''
|
||||||
|
modelFilterInitialized //= undefined
|
||||||
|
|
||||||
/* MIMIC A REGULAR INPUT FIELD */
|
/* MIMIC A REGULAR INPUT FIELD */
|
||||||
get parentElement() {
|
get parentElement() {
|
||||||
@ -84,6 +85,14 @@ class ModelDropdown
|
|||||||
this.inputModels = modelsOptions[this.modelKey]
|
this.inputModels = modelsOptions[this.modelKey]
|
||||||
this.populateModels()
|
this.populateModels()
|
||||||
}, this))
|
}, this))
|
||||||
|
document.addEventListener("collapsibleClick", this.bind(function(e) {
|
||||||
|
// update the input size when the element becomes visible
|
||||||
|
this.updateInputSize()
|
||||||
|
}, this))
|
||||||
|
document.addEventListener("tabClick", this.bind(function(e) {
|
||||||
|
// update the input size when the tab changes
|
||||||
|
this.updateInputSize()
|
||||||
|
}, this))
|
||||||
}
|
}
|
||||||
|
|
||||||
saveCurrentSelection(elem, value, path) {
|
saveCurrentSelection(elem, value, path) {
|
||||||
@ -105,9 +114,24 @@ class ModelDropdown
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getPreviousVisibleSibling(elem) {
|
||||||
|
let prevSibling = elem.previousElementSibling
|
||||||
|
while (prevSibling && prevSibling.classList.contains('model-file')) {
|
||||||
|
if (prevSibling.style.display == 'list-item') return prevSibling
|
||||||
|
prevSibling = prevSibling.previousElementSibling
|
||||||
|
}
|
||||||
|
if (prevSibling && prevSibling.style.display == 'list-item') return prevSibling
|
||||||
|
}
|
||||||
|
|
||||||
|
getLastVisibleChild(elem) {
|
||||||
|
let lastElementChild = elem.lastElementChild
|
||||||
|
if (lastElementChild.style.display == 'list-item') return lastElementChild
|
||||||
|
return this.getPreviousVisibleSibling(lastElementChild)
|
||||||
|
}
|
||||||
|
|
||||||
findPreviousSibling(elem) {
|
findPreviousSibling(elem) {
|
||||||
// is there an immediate sibling?
|
// is there an immediate sibling?
|
||||||
let prevSibling = elem.previousElementSibling
|
let prevSibling = this.getPreviousVisibleSibling(elem)
|
||||||
if (prevSibling) {
|
if (prevSibling) {
|
||||||
// if the previous sibling is a model file, just select it
|
// if the previous sibling is a model file, just select it
|
||||||
if (prevSibling.classList.contains('model-file')) return prevSibling
|
if (prevSibling.classList.contains('model-file')) return prevSibling
|
||||||
@ -117,19 +141,34 @@ class ModelDropdown
|
|||||||
}
|
}
|
||||||
|
|
||||||
// no sibling model file and no sibling model folder. look for siblings around the parent element.
|
// no sibling model file and no sibling model folder. look for siblings around the parent element.
|
||||||
prevSibling = elem.parentElement.parentElement.previousElementSibling
|
prevSibling = this.getPreviousVisibleSibling(elem.parentElement.parentElement)
|
||||||
if (prevSibling) {
|
if (prevSibling) {
|
||||||
// if the previous entry is a model file, select it
|
// if the previous entry is a model file, select it
|
||||||
if (prevSibling.classList.contains('model-file')) return prevSibling
|
if (prevSibling.classList.contains('model-file')) return prevSibling
|
||||||
|
|
||||||
// is there another model folder to jump to before the current one?
|
// is there another model folder to jump to before the current one?
|
||||||
if (prevSibling.classList.contains('model-folder')) return prevSibling.firstElementChild.lastElementChild
|
if (prevSibling.classList.contains('model-folder')) return this.getLastVisibleChild(prevSibling.firstElementChild)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getNextVisibleSibling(elem) {
|
||||||
|
let nextSibling = elem.nextElementSibling
|
||||||
|
while (nextSibling && nextSibling.classList.contains('model-file')) {
|
||||||
|
if (nextSibling.style.display == 'list-item') return nextSibling
|
||||||
|
nextSibling = nextSibling.nextElementSibling
|
||||||
|
}
|
||||||
|
if (nextSibling && nextSibling.style.display == 'list-item') return nextSibling
|
||||||
|
}
|
||||||
|
|
||||||
|
getFirstVisibleChild(elem) {
|
||||||
|
let firstElementChild = elem.firstElementChild
|
||||||
|
if (firstElementChild.style.display == 'list-item') return firstElementChild
|
||||||
|
return this.getNextVisibleSibling(firstElementChild)
|
||||||
|
}
|
||||||
|
|
||||||
findNextSibling(elem) {
|
findNextSibling(elem) {
|
||||||
// is there an immediate sibling?
|
// is there an immediate sibling?
|
||||||
let nextSibling = elem.nextElementSibling
|
let nextSibling = this.getNextVisibleSibling(elem)
|
||||||
if (nextSibling) {
|
if (nextSibling) {
|
||||||
// if the next sibling is a model file, just select it
|
// if the next sibling is a model file, just select it
|
||||||
if (nextSibling.classList.contains('model-file')) return nextSibling
|
if (nextSibling.classList.contains('model-file')) return nextSibling
|
||||||
@ -139,13 +178,13 @@ class ModelDropdown
|
|||||||
}
|
}
|
||||||
|
|
||||||
// no sibling model file and no sibling model folder. look for siblings around the parent element.
|
// no sibling model file and no sibling model folder. look for siblings around the parent element.
|
||||||
nextSibling = elem.parentElement.parentElement.nextElementSibling
|
nextSibling = this.getNextVisibleSibling(elem.parentElement.parentElement)
|
||||||
if (nextSibling) {
|
if (nextSibling) {
|
||||||
// if the next entry is a model file, select it
|
// if the next entry is a model file, select it
|
||||||
if (nextSibling.classList.contains('model-file')) return nextSibling
|
if (nextSibling.classList.contains('model-file')) return nextSibling
|
||||||
|
|
||||||
// is there another model folder to jump to after the current one?
|
// is there another model folder to jump to after the current one?
|
||||||
if (nextSibling.classList.contains('model-folder')) return nextSibling.firstElementChild.firstElementChild
|
if (nextSibling.classList.contains('model-folder')) return this.getFirstVisibleChild(nextSibling.firstElementChild)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,6 +258,7 @@ class ModelDropdown
|
|||||||
{
|
{
|
||||||
this.saveCurrentSelection(this.highlightedModelEntry, this.highlightedModelEntry.innerText, this.highlightedModelEntry.dataset.path)
|
this.saveCurrentSelection(this.highlightedModelEntry, this.highlightedModelEntry.innerText, this.highlightedModelEntry.dataset.path)
|
||||||
this.hideModelList()
|
this.hideModelList()
|
||||||
|
this.showAllEntries()
|
||||||
}
|
}
|
||||||
this.modelFilter.focus()
|
this.modelFilter.focus()
|
||||||
}
|
}
|
||||||
@ -423,6 +463,47 @@ class ModelDropdown
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* MODEL LOADER */
|
/* MODEL LOADER */
|
||||||
|
getElementDimensions(element) {
|
||||||
|
// Clone the element
|
||||||
|
const clone = element.cloneNode(true)
|
||||||
|
|
||||||
|
// Copy the styles of the original element to the cloned element
|
||||||
|
const originalStyles = window.getComputedStyle(element)
|
||||||
|
for (let i = 0; i < originalStyles.length; i++) {
|
||||||
|
const property = originalStyles[i]
|
||||||
|
clone.style[property] = originalStyles.getPropertyValue(property)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set its visibility to hidden and display to inline-block
|
||||||
|
clone.style.visibility = "hidden"
|
||||||
|
clone.style.display = "inline-block"
|
||||||
|
|
||||||
|
// Put the cloned element next to the original element
|
||||||
|
element.parentNode.insertBefore(clone, element.nextSibling)
|
||||||
|
|
||||||
|
// Get its width and height
|
||||||
|
const width = clone.offsetWidth
|
||||||
|
const height = clone.offsetHeight
|
||||||
|
|
||||||
|
// Remove it from the DOM
|
||||||
|
clone.remove()
|
||||||
|
|
||||||
|
// Return its width and height
|
||||||
|
return { width, height }
|
||||||
|
}
|
||||||
|
|
||||||
|
updateInputSize() {
|
||||||
|
if (this.modelList !== undefined) {
|
||||||
|
const dimensions = this.getElementDimensions(this.modelList)
|
||||||
|
this.modelFilter.style.width = dimensions.width + 'px'
|
||||||
|
this.modelList.style.width = dimensions.width + 'px'
|
||||||
|
this.modelFilterArrow.style.height = dimensions.height + 'px'
|
||||||
|
if (this.modelFilter.offsetLeft > 0) {
|
||||||
|
this.modelList.style.left = this.modelFilter.offsetLeft + 'px'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
flattenModelList(models, path) {
|
flattenModelList(models, path) {
|
||||||
models.forEach(entry => {
|
models.forEach(entry => {
|
||||||
if (Array.isArray(entry)) {
|
if (Array.isArray(entry)) {
|
||||||
@ -489,16 +570,17 @@ class ModelDropdown
|
|||||||
this.modelList = document.querySelector(`#${this.modelFilter.id}-model-list`)
|
this.modelList = document.querySelector(`#${this.modelFilter.id}-model-list`)
|
||||||
this.modelResult = document.querySelector(`#${this.modelFilter.id}-model-result`)
|
this.modelResult = document.querySelector(`#${this.modelFilter.id}-model-result`)
|
||||||
this.modelNoResult = document.querySelector(`#${this.modelFilter.id}-model-no-result`)
|
this.modelNoResult = document.querySelector(`#${this.modelFilter.id}-model-no-result`)
|
||||||
this.modelList.style.display = 'block'
|
this.updateInputSize()
|
||||||
this.modelFilter.style.width = this.modelList.offsetWidth + 'px'
|
|
||||||
this.modelFilterArrow.style.height = this.modelFilter.offsetHeight + 'px'
|
|
||||||
this.modelList.style.display = 'none'
|
|
||||||
|
|
||||||
this.modelFilter.addEventListener('input', this.bind(this.filterList, this))
|
if (this.modelFilterInitialized !== true) {
|
||||||
this.modelFilter.addEventListener('focus', this.bind(this.modelListFocus, this))
|
this.modelFilter.addEventListener('input', this.bind(this.filterList, this))
|
||||||
this.modelFilter.addEventListener('blur', this.bind(this.hideModelList, this))
|
this.modelFilter.addEventListener('focus', this.bind(this.modelListFocus, this))
|
||||||
this.modelFilter.addEventListener('click', this.bind(this.showModelList, this))
|
this.modelFilter.addEventListener('blur', this.bind(this.hideModelList, this))
|
||||||
this.modelFilter.addEventListener('keydown', this.bind(this.processKey, this))
|
this.modelFilter.addEventListener('click', this.bind(this.showModelList, this))
|
||||||
|
this.modelFilter.addEventListener('keydown', this.bind(this.processKey, this))
|
||||||
|
|
||||||
|
this.modelFilterInitialized = true
|
||||||
|
}
|
||||||
this.modelFilterArrow.addEventListener('mousedown', this.bind(this.toggleModelList, this))
|
this.modelFilterArrow.addEventListener('mousedown', this.bind(this.toggleModelList, this))
|
||||||
this.modelList.addEventListener('mousemove', this.bind(this.highlightModelAtPosition, this))
|
this.modelList.addEventListener('mousemove', this.bind(this.highlightModelAtPosition, this))
|
||||||
this.modelList.addEventListener('mousedown', this.bind(this.processClick, this))
|
this.modelList.addEventListener('mousedown', this.bind(this.processClick, this))
|
||||||
|
Loading…
Reference in New Issue
Block a user