stable-diffusion-webui-state/javascript/state.utils.js

246 lines
8.3 KiB
JavaScript

window.state = window.state || {};
state = window.state;
let selectingQueue = -1;
state.utils = {
triggerEvent: function triggerEvent(element, event) {
if (! element) {
state.logging.warn('Element not found');
return;
}
element.dispatchEvent(new Event(event.trim()));
return element;
},
triggerMouseEvent: function triggerMouseEvent(element, event) {
if (! element) {
state.logging.warn('Element not found');
return;
}
event = event || 'click';
element.dispatchEvent(new MouseEvent(event, {
view: window,
bubbles: true,
cancelable: true,
}));
return element;
},
clickToggleMenu: function openToggleMenu(element) {
if (! element) {
state.logging.warn('Toggle button not found');
return;
}
let mouseEvent = new MouseEvent('click', {
view: window,
bubbles: true,
cancelable: true
});
element.dispatchEvent(mouseEvent);
let icon = element.parentNode.querySelector('.icon');
if (icon) {
icon.dispatchEvent(mouseEvent);
}
let checkbox = element.parentNode.querySelector('input[type="checkbox"]');
if (checkbox) {
checkbox.checked = !checkbox.checked;
checkbox.dispatchEvent(mouseEvent);
}
return element;
},
setValue: function setValue(element, value, event) {
switch (element.type) {
case 'checkbox':
element.checked = value === 'true';
this.triggerEvent(element, event);
break;
case 'radio':
if (element.value === value) {
element.checked = true;
this.triggerEvent(element, event);
} else {
element.checked = false;
}
break;
default:
element.value = value;
this.triggerEvent(element, event);
}
},
onContentChange: function onContentChange(targetNode, func) {
const observer = new MutationObserver((mutationsList, observer) => {
for (const mutation of mutationsList) {
if (mutation.type === 'childList') {
func(targetNode);
}
}
});
observer.observe(targetNode, {
childList: true,
characterData: true,
subtree: true
});
},
handleSelect: function handleSelect(select, id, store) {
try {
let value = store.get(id);
if (value) {
selectingQueue += 1;
setTimeout(() => {
let input = select.querySelector('input');
state.utils.triggerMouseEvent(input, 'focus');
setTimeout(() => {
let items = Array.from(select.querySelectorAll('ul li'));
items.forEach(li => {
if (li.lastChild.wholeText.trim() === value) {
state.utils.triggerMouseEvent(li, 'mousedown');
return false;
}
});
state.utils.triggerMouseEvent(input, 'blur');
selectingQueue -= 1;
}, 100);
}, selectingQueue * 200)
}
setTimeout(() => {
state.utils.onContentChange(select, function (el) {
let selected = el.querySelector('span.single-select');
if (selected) {
store.set(id, selected.textContent);
} else {
// new gradio version...
let input = select.querySelector('input');
if (input) {
store.set(id, input.value);
}
}
});
}, 150);
} catch (error) {
console.error('[state]: Error:', error);
}
},
handleMultipleSelect: function handleMultipleSelect(select, id, store) {
try {
let value = store.get(id);
if (value) {
value = value.split(',').reverse();
if (value.length) {
let input = select.querySelector('input');
let selectOption = function () {
if (! value.length) {
state.utils.triggerMouseEvent(input, 'blur');
return;
}
let option = value.pop();
state.utils.triggerMouseEvent(input, 'focus');
setTimeout(() => {
let items = Array.from(select.querySelectorAll('ul li'));
items.forEach(li => {
if (li.lastChild.wholeText.trim() === option) {
state.utils.triggerMouseEvent(li, 'mousedown');
return false;
}
});
setTimeout(selectOption, 100);
}, 100);
}
selectOption();
}
}
state.utils.onContentChange(select, function (el) {
const selected = Array.from(el.querySelectorAll('.token > span')).map(item => item.textContent);
store.set(id, selected);
});
} catch (error) {
console.error('[state]: Error:', error);
}
},
txtToId: function txtToId(txt) {
return txt.split(' ').join('-').toLowerCase();
},
callXTimes: function callXTimes(func, times) {
let called = 0;
return function() {
if (called < times) {
called++;
return func.apply(this);
}
}
},
saveFile: function saveJSON(fileName ,data) {
const json = JSON.stringify(data, null, 4);
const blob = new Blob([json], {type: 'application/json'});
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = fileName + '.json';
document.body.appendChild(link);
link.click();
link.parentNode.removeChild(link);
},
debounce: function debounce(func, delay) {
let lastCallTime = 0;
return function() {
const currentCallTime = new Date().getTime();
if (currentCallTime - lastCallTime > delay) {
lastCallTime = currentCallTime;
func.apply(this, arguments);
}
}
},
onNextUiUpdates: function (func) {
// brute force this to to ensure that the method is called after next few updates
onUiUpdate(this.callXTimes(function () { setTimeout(func, 5); }, 150));
}
};
state.utils.html = {
setStyle: function setStyle(elements, style) {
if (elements instanceof NodeList) {
elements = Array.from(elements);
} else if (elements instanceof Node){
elements = [elements];
} else {
return;
}
elements.forEach(element => {
for (let key in style) {
if (style.hasOwnProperty(key)) {
element.style[key] = style[key];
}
}
});
},
create: function create(type, props, style) {
const element = document.createElement(type);
if (props) {
for (let key in props) {
if (props.hasOwnProperty(key)) {
element[key] = props[key];
}
}
}
if (style) {
this.setStyle(element, style);
}
return element;
},
createButton: function createButton(text, onclick) {
const btn = document.createElement('button');
btn.innerHTML = text;
btn.onclick = onclick || function () {};
btn.className = 'gr-button gr-button-lg gr-button-primary';
return btn;
}
};