diff --git a/ui/media/js/searchable-models.js b/ui/media/js/searchable-models.js
index 7ffb4a5a..bdd81117 100644
--- a/ui/media/js/searchable-models.js
+++ b/ui/media/js/searchable-models.js
@@ -12,7 +12,7 @@ Merely calling getModels() makes all the magic happen behind the scene to refres
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.
-
+
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')
@@ -37,6 +37,7 @@ class ModelDropdown
modelKey //= undefined
flatModelList //= []
noneEntry //= ''
+ modelFilterInitialized //= undefined
/* MIMIC A REGULAR INPUT FIELD */
get parentElement() {
@@ -105,9 +106,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) {
// is there an immediate sibling?
- let prevSibling = elem.previousElementSibling
+ let prevSibling = this.getPreviousVisibleSibling(elem)
if (prevSibling) {
// if the previous sibling is a model file, just select it
if (prevSibling.classList.contains('model-file')) return prevSibling
@@ -117,19 +133,34 @@ class ModelDropdown
}
// 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 the previous entry is a model file, select it
if (prevSibling.classList.contains('model-file')) return prevSibling
// 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) {
// is there an immediate sibling?
- let nextSibling = elem.nextElementSibling
+ let nextSibling = this.getNextVisibleSibling(elem)
if (nextSibling) {
// if the next sibling is a model file, just select it
if (nextSibling.classList.contains('model-file')) return nextSibling
@@ -139,13 +170,13 @@ class ModelDropdown
}
// 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 the next entry is a model file, select it
if (nextSibling.classList.contains('model-file')) return nextSibling
// 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 +250,7 @@ class ModelDropdown
{
this.saveCurrentSelection(this.highlightedModelEntry, this.highlightedModelEntry.innerText, this.highlightedModelEntry.dataset.path)
this.hideModelList()
+ this.showAllEntries()
}
this.modelFilter.focus()
}
@@ -493,12 +525,16 @@ class ModelDropdown
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))
- this.modelFilter.addEventListener('focus', this.bind(this.modelListFocus, this))
- this.modelFilter.addEventListener('blur', this.bind(this.hideModelList, this))
- this.modelFilter.addEventListener('click', this.bind(this.showModelList, this))
- this.modelFilter.addEventListener('keydown', this.bind(this.processKey, this))
+
+ if (this.modelFilterInitialized !== true) {
+ this.modelFilter.addEventListener('input', this.bind(this.filterList, this))
+ this.modelFilter.addEventListener('focus', this.bind(this.modelListFocus, this))
+ this.modelFilter.addEventListener('blur', this.bind(this.hideModelList, 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.modelList.addEventListener('mousemove', this.bind(this.highlightModelAtPosition, this))
this.modelList.addEventListener('mousedown', this.bind(this.processClick, this))
From 074a14f05677be2840a608c57588f0914b4019bf Mon Sep 17 00:00:00 2001
From: patriceac <48073125+patriceac@users.noreply.github.com>
Date: Mon, 13 Feb 2023 01:37:00 -0800
Subject: [PATCH 2/2] Second batch of fixes for search models
Addresses the issues reported by JeLuf:
- - gfpgan: the list with models doesn't appear under the box
- merge models: As long as no models are selected, the box is very short.
- When searching for models by name, the width of the model list shrinks and is smaller than the element.
---
ui/media/js/searchable-models.js | 54 +++++++++++++++++++++++++++++---
1 file changed, 50 insertions(+), 4 deletions(-)
diff --git a/ui/media/js/searchable-models.js b/ui/media/js/searchable-models.js
index bdd81117..d28bbcdf 100644
--- a/ui/media/js/searchable-models.js
+++ b/ui/media/js/searchable-models.js
@@ -85,6 +85,14 @@ class ModelDropdown
this.inputModels = modelsOptions[this.modelKey]
this.populateModels()
}, 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) {
@@ -455,6 +463,47 @@ class ModelDropdown
}
/* 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) {
models.forEach(entry => {
if (Array.isArray(entry)) {
@@ -521,10 +570,7 @@ class ModelDropdown
this.modelList = document.querySelector(`#${this.modelFilter.id}-model-list`)
this.modelResult = document.querySelector(`#${this.modelFilter.id}-model-result`)
this.modelNoResult = document.querySelector(`#${this.modelFilter.id}-model-no-result`)
- this.modelList.style.display = 'block'
- this.modelFilter.style.width = this.modelList.offsetWidth + 'px'
- this.modelFilterArrow.style.height = this.modelFilter.offsetHeight + 'px'
- this.modelList.style.display = 'none'
+ this.updateInputSize()
if (this.modelFilterInitialized !== true) {
this.modelFilter.addEventListener('input', this.bind(this.filterList, this))