jumbo patch

This commit is contained in:
Vladimir Mandic
2023-05-17 14:15:38 -04:00
parent 554f26296e
commit 0ccda9bc8b
56 changed files with 686 additions and 612 deletions
+2 -1
View File
@@ -16,6 +16,7 @@
"no-unused-vars":"off",
"no-plusplus":"off",
"no-param-reassign":"off",
"no-restricted-syntax":"off"
"no-restricted-syntax":"off",
"no-mixed-operators":"off"
}
}
+7 -18
View File
@@ -1,3 +1,5 @@
/* global gradioApp, onUiUpdate, get_tab_index */
let currentWidth = null;
let currentHeight = null;
let arFrameTimeout = setTimeout(() => {}, 0);
@@ -9,7 +11,7 @@ function dimensionChange(e, is_width, is_height) {
if (!inImg2img) return;
let targetElement = null;
const tabIndex = get_tab_index('mode_img2img');
if (tabIndex === 0) targetElement = gradioApp().querySelector('#img2img_image div[data-testid=image] img'); // img2img
if (tabIndex === 0) targetElement = gradioApp().querySelector('#img2img_image div[data-testid=image] img'); // img2img
else if (tabIndex === 1) targetElement = gradioApp().querySelector('#img2img_sketch div[data-testid=image] img'); // Sketch
else if (tabIndex === 2) targetElement = gradioApp().querySelector('#img2maskimg div[data-testid=image] img'); // Inpaint
else if (tabIndex === 3) targetElement = gradioApp().querySelector('#inpaint_sketch div[data-testid=image] img'); // Inpaint sketch
@@ -23,26 +25,20 @@ function dimensionChange(e, is_width, is_height) {
}
const viewportOffset = targetElement.getBoundingClientRect();
const viewportscale = Math.min(targetElement.clientWidth / targetElement.naturalWidth, targetElement.clientHeight / targetElement.naturalHeight);
const scaledx = targetElement.naturalWidth * viewportscale;
const scaledy = targetElement.naturalHeight * viewportscale;
const cleintRectTop = (viewportOffset.top + window.scrollY);
const cleintRectLeft = (viewportOffset.left + window.scrollX);
const cleintRectCentreY = cleintRectTop + (targetElement.clientHeight / 2);
const cleintRectCentreX = cleintRectLeft + (targetElement.clientWidth / 2);
const arscale = Math.min(scaledx / currentWidth, scaledy / currentHeight);
const arscaledx = currentWidth * arscale;
const arscaledy = currentHeight * arscale;
const arRectTop = cleintRectCentreY - (arscaledy / 2);
const arRectLeft = cleintRectCentreX - (arscaledx / 2);
const arRectWidth = arscaledx;
const arRectHeight = arscaledy;
arPreviewRect.style.top = `${arRectTop}px`;
arPreviewRect.style.left = `${arRectLeft}px`;
arPreviewRect.style.width = `${arRectWidth}px`;
@@ -58,9 +54,7 @@ function dimensionChange(e, is_width, is_height) {
onUiUpdate(() => {
const arPreviewRect = gradioApp().querySelector('#imageARPreview');
if (arPreviewRect) {
arPreviewRect.style.display = 'none';
}
if (arPreviewRect) arPreviewRect.style.display = 'none';
const tabImg2img = gradioApp().querySelector('#tab_img2img');
if (tabImg2img) {
const inImg2img = tabImg2img.style.display === 'block';
@@ -69,17 +63,12 @@ onUiUpdate(() => {
inputs.forEach((e) => {
const is_width = e.parentElement.id === 'img2img_width';
const is_height = e.parentElement.id === 'img2img_height';
if ((is_width || is_height) && !e.classList.contains('scrollwatch')) {
e.addEventListener('input', (e) => { dimensionChange(e, is_width, is_height); });
e.addEventListener('input', (evt) => { dimensionChange(evt, is_width, is_height); });
e.classList.add('scrollwatch');
}
if (is_width) {
currentWidth = e.value * 1.0;
}
if (is_height) {
currentHeight = e.value * 1.0;
}
if (is_width) currentWidth = e.value * 1.0;
if (is_height) currentHeight = e.value * 1.0;
});
}
}
+17 -47
View File
@@ -1,23 +1,18 @@
contextMenuInit = function () {
/* global gradioApp, uiCurrentTab, onUiUpdate, get_uiCurrentTabContent */
const contextMenuInit = () => {
let eventListenerApplied = false;
const menuSpecs = new Map();
const uid = function () {
return Date.now().toString(36) + Math.random().toString(36).substring(2);
};
const uid = () => Date.now().toString(36) + Math.random().toString(36).substring(2);
function showContextMenu(event, element, menuEntries) {
const posx = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
const posy = event.clientY + document.body.scrollTop + document.documentElement.scrollTop;
const oldMenu = gradioApp().querySelector('#context-menu');
if (oldMenu) {
oldMenu.remove();
}
if (oldMenu) oldMenu.remove();
const tabButton = uiCurrentTab;
const baseStyle = window.getComputedStyle(tabButton);
const contextMenu = document.createElement('nav');
contextMenu.id = 'context-menu';
contextMenu.style.background = baseStyle.background;
@@ -25,40 +20,26 @@ contextMenuInit = function () {
contextMenu.style.fontFamily = baseStyle.fontFamily;
contextMenu.style.top = `${posy}px`;
contextMenu.style.left = `${posx}px`;
const contextMenuList = document.createElement('ul');
contextMenuList.className = 'context-menu-items';
contextMenu.append(contextMenuList);
menuEntries.forEach((entry) => {
const contextMenuEntry = document.createElement('a');
contextMenuEntry.innerHTML = entry.name;
contextMenuEntry.addEventListener('click', (e) => {
entry.func();
});
contextMenuEntry.addEventListener('click', (e) => entry.func());
contextMenuList.append(contextMenuEntry);
});
gradioApp().appendChild(contextMenu);
const menuWidth = contextMenu.offsetWidth + 4;
const menuHeight = contextMenu.offsetHeight + 4;
const windowWidth = window.innerWidth;
const windowHeight = window.innerHeight;
if ((windowWidth - posx) < menuWidth) {
contextMenu.style.left = `${windowWidth - menuWidth}px`;
}
if ((windowHeight - posy) < menuHeight) {
contextMenu.style.top = `${windowHeight - menuHeight}px`;
}
if ((windowWidth - posx) < menuWidth) contextMenu.style.left = `${windowWidth - menuWidth}px`;
if ((windowHeight - posy) < menuHeight) contextMenu.style.top = `${windowHeight - menuHeight}px`;
}
function appendContextMenuOption(targetElementSelector, entryName, entryFunction) {
currentItems = menuSpecs.get(targetElementSelector);
let currentItems = menuSpecs.get(targetElementSelector);
if (!currentItems) {
currentItems = [];
menuSpecs.set(targetElementSelector, currentItems);
@@ -69,7 +50,6 @@ contextMenuInit = function () {
func: entryFunction,
isNew: true,
};
currentItems.push(newItem);
return newItem.id;
}
@@ -89,15 +69,11 @@ contextMenuInit = function () {
gradioApp().addEventListener('click', (e) => {
if (!e.isTrusted) return;
const oldMenu = gradioApp().querySelector('#context-menu');
if (oldMenu) {
oldMenu.remove();
}
if (oldMenu) oldMenu.remove();
});
gradioApp().addEventListener('contextmenu', (e) => {
const oldMenu = gradioApp().querySelector('#context-menu');
if (oldMenu) {
oldMenu.remove();
}
if (oldMenu) oldMenu.remove();
menuSpecs.forEach((v, k) => {
if (e.composedPath()[0].matches(k)) {
showContextMenu(e, e.composedPath()[0], v);
@@ -107,14 +83,13 @@ contextMenuInit = function () {
});
eventListenerApplied = true;
}
return [appendContextMenuOption, removeContextMenuOption, addContextMenuEventListener];
};
initResponse = contextMenuInit();
appendContextMenuOption = initResponse[0];
removeContextMenuOption = initResponse[1];
addContextMenuEventListener = initResponse[2];
const initResponse = contextMenuInit();
const appendContextMenuOption = initResponse[0];
const removeContextMenuOption = initResponse[1];
const addContextMenuEventListener = initResponse[2];
(function () {
// Start example Context Menu Items
@@ -128,9 +103,7 @@ addContextMenuEventListener = initResponse[2];
window.generateOnRepeatInterval = setInterval(
() => {
const busy = document.getElementById('progressbar')?.style.display === 'block';
if (!busy) {
genbutton.click();
}
if (!busy) genbutton.click();
},
500,
);
@@ -151,7 +124,6 @@ addContextMenuEventListener = initResponse[2];
appendContextMenuOption('#txt2img_generate', 'Cancel generate forever', cancelGenerateForever);
appendContextMenuOption('#img2img_interrupt', 'Cancel generate forever', cancelGenerateForever);
appendContextMenuOption('#img2img_generate', 'Cancel generate forever', cancelGenerateForever);
appendContextMenuOption(
'#roll',
'Roll three',
@@ -165,6 +137,4 @@ addContextMenuEventListener = initResponse[2];
}());
// End example Context Menu Items
onUiUpdate(() => {
addContextMenuEventListener();
});
onUiUpdate(() => addContextMenuEventListener());
+7 -9
View File
@@ -1,16 +1,14 @@
function setInactive(elem, inactive) {
if (inactive) elem.classList.add('inactive');
else elem.classList.remove('inactive');
}
/* global gradioApp, opts */
function onCalcResolutionHires(enable, width, height, hr_scale, hr_resize_x, hr_resize_y) {
function setInactive(elem, inactive) {
elem.classList.toggle('inactive', !!inactive);
}
const hrUpscaleBy = gradioApp().getElementById('txt2img_hr_scale');
const hrResizeX = gradioApp().getElementById('txt2img_hr_resize_x');
const hrResizeY = gradioApp().getElementById('txt2img_hr_resize_y');
gradioApp().getElementById('txt2img_hires_fix_row2').style.display = opts.use_old_hires_fix_width_height ? 'none' : '';
setInactive(hrUpscaleBy, opts.use_old_hires_fix_width_height || hr_resize_x > 0 || hr_resize_y > 0);
setInactive(hrResizeX, opts.use_old_hires_fix_width_height || hr_resize_x === 0);
setInactive(hrResizeY, opts.use_old_hires_fix_width_height || hr_resize_y === 0);
// return [enable, width, height, hr_scale, hr_resize_x, hr_resize_y];
setTimeout(() => [enable, width, height, hr_scale, hr_resize_x, hr_resize_y], 100);
setInactive(hrResizeX, opts.use_old_hires_fix_width_height || hr_resize_x == 0);
setInactive(hrResizeY, opts.use_old_hires_fix_width_height || hr_resize_y == 0);
return [enable, width, height, hr_scale, hr_resize_x, hr_resize_y];
}
+5 -5
View File
@@ -1,3 +1,4 @@
/* global gradioApp, onUiUpdate */
/**
* temporary fix for https://github.com/AUTOMATIC1111/stable-diffusion-webui/issues/668
* @see https://github.com/gradio-app/gradio/issues/1721
@@ -5,7 +6,6 @@
function imageMaskResize() {
const canvases = gradioApp().querySelectorAll('#img2maskimg .touch-none canvas');
if (!canvases.length) {
canvases_fixed = false;
window.removeEventListener('resize', imageMaskResize);
return;
}
@@ -14,7 +14,7 @@ function imageMaskResize() {
const previewImage = wrapper.previousElementSibling;
if (!previewImage.complete) {
previewImage.addEventListener('load', () => imageMaskResize());
previewImage.addEventListener('load', imageMaskResize);
return;
}
@@ -23,7 +23,6 @@ function imageMaskResize() {
const nw = previewImage.naturalWidth;
const nh = previewImage.naturalHeight;
const portrait = nh > nw;
const factor = portrait;
const wW = Math.min(w, portrait ? h / nh * nw : w / nw * nw);
const wH = Math.min(h, portrait ? h / nh * nh : w / nw * nh);
@@ -34,12 +33,13 @@ function imageMaskResize() {
wrapper.style.top = '0px';
canvases.forEach((c) => {
c.style.width = c.style.height = '';
c.style.width = '';
c.style.height = '';
c.style.maxWidth = '100%';
c.style.maxHeight = '100%';
c.style.objectFit = 'contain';
});
}
onUiUpdate(imageMaskResize);
window.addEventListener('resize', imageMaskResize);
onUiUpdate(() => imageMaskResize());
+1 -3
View File
@@ -1,12 +1,10 @@
/* global gradioApp, get_tab_index */
window.onload = (function () {
window.addEventListener('drop', (e) => {
const target = e.composedPath()[0];
if (!target.placeholder) return;
const idx = selected_gallery_index();
if (target.placeholder.indexOf('Prompt') == -1) return;
const prompt_target = get_tab_index('tabs') == 1 ? 'img2img_prompt_image' : 'txt2img_prompt_image';
e.stopPropagation();
e.preventDefault();
const imgParent = gradioApp().getElementById(prompt_target);
+8 -8
View File
@@ -1,3 +1,4 @@
/* global gradioApp, onUiUpdate */
// A full size 'lightbox' preview modal shown when left clicking on gallery previews
function closeModal() {
gradioApp().getElementById('lightboxModal').style.display = 'none';
@@ -96,6 +97,11 @@ function modalKeyHandler(event) {
}
}
function modalZoomSet(modalImage, enable) {
localStorage.setItem('modalZoom', enable ? 'yes' : 'no');
if (modalImage) modalImage.classList.toggle('modalImageFullscreen', !!enable);
}
function setupImageForLightbox(e) {
if (e.dataset.modded) return;
e.dataset.modded = true;
@@ -106,21 +112,15 @@ function setupImageForLightbox(e) {
const event = isFirefox ? 'mousedown' : 'click';
e.addEventListener(event, (evt) => {
if (evt.button != 0) return;
initialZoom = (localStorage.getItem('modalZoom') || true) == 'yes';
const initialZoom = (localStorage.getItem('modalZoom') || true) == 'yes';
modalZoomSet(gradioApp().getElementById('modalImage'), initialZoom);
evt.preventDefault();
showModal(evt);
}, true);
}
function modalZoomSet(modalImage, enable) {
if (enable) modalImage.classList.add('modalImageFullscreen');
else modalImage.classList.remove('modalImageFullscreen');
localStorage.setItem('modalZoom', enable ? 'yes' : 'no');
}
function modalZoomToggle(event) {
modalImage = gradioApp().getElementById('modalImage');
const modalImage = gradioApp().getElementById('modalImage');
modalZoomSet(modalImage, !modalImage.classList.contains('modalImageFullscreen'));
event.stopPropagation();
}
+106 -106
View File
@@ -1,133 +1,133 @@
/* global opts */
function rememberGallerySelection(id_gallery) {}
function getGallerySelectedIndex(id_gallery) {}
function request(url, data, handler, errorHandler) {
var xhr = new XMLHttpRequest();
var url = url;
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
try {
var js = JSON.parse(xhr.responseText);
handler(js)
} catch (error) {
console.error(error);
errorHandler()
}
} else{
errorHandler()
}
const xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
try {
const js = JSON.parse(xhr.responseText);
handler(js);
} catch (error) {
console.error(error);
errorHandler();
}
};
var js = JSON.stringify(data);
xhr.send(js);
} else {
errorHandler();
}
}
};
const js = JSON.stringify(data);
xhr.send(js);
}
function pad2(x) {
return x<10 ? '0'+x : x
return x < 10 ? `0${x}` : x;
}
function formatTime(secs) {
if(secs > 3600) return pad2(Math.floor(secs/60/60)) + ":" + pad2(Math.floor(secs/60)%60) + ":" + pad2(Math.floor(secs)%60)
else if(secs > 60) return pad2(Math.floor(secs/60)) + ":" + pad2(Math.floor(secs)%60)
else return Math.floor(secs) + "s"
if (secs > 3600) return `${pad2(Math.floor(secs / 60 / 60))}:${pad2(Math.floor(secs / 60) % 60)}:${pad2(Math.floor(secs) % 60)}`;
if (secs > 60) return `${pad2(Math.floor(secs / 60))}:${pad2(Math.floor(secs) % 60)}`;
return `${Math.floor(secs)}s`;
}
function setTitle(progress) {
var title = 'SD.Next'
if (progress) title += ' ' + progress.split(' ')[0].trim();
if (document.title != title) document.title = title;
let title = 'SD.Next';
if (progress) title += ` ${progress.split(' ')[0].trim()}`;
if (document.title != title) document.title = title;
}
function randomId() {
return "task(" + Math.random().toString(36).slice(2, 7) + Math.random().toString(36).slice(2, 7) + Math.random().toString(36).slice(2, 7)+")"
return `task(${Math.random().toString(36).slice(2, 7)}${Math.random().toString(36).slice(2, 7)}${Math.random().toString(36).slice(2, 7)})`;
}
// starts sending progress requests to "/internal/progress" uri, creating progressbar above progressbarContainer element and
// preview inside gallery element. Cleans up all created stuff when the task is over and calls atEnd.
// calls onProgress every time there is a progress update
function requestProgress(id_task, progressbarContainer, gallery, atEnd = null, onProgress = null, once = false) {
var hasStarted = false
var dateStart = new Date()
var prevProgress = null
var parentProgressbar = progressbarContainer.parentNode
var parentGallery = gallery ? gallery.parentNode : null
var divProgress = document.createElement('div')
divProgress.className='progressDiv'
divProgress.id = 'progressbar'
divProgress.style.display = opts.show_progressbar ? "block" : "none"
var divInner = document.createElement('div')
divInner.className='progress'
divProgress.appendChild(divInner)
parentProgressbar.insertBefore(divProgress, progressbarContainer)
localStorage.setItem('task', id_task);
console.debug('task active:', id_task)
if (parentGallery) {
var livePreview = document.createElement('div')
livePreview.className='livePreview'
parentGallery.insertBefore(livePreview, gallery)
}
let hasStarted = false;
const dateStart = new Date();
const prevProgress = null;
const parentProgressbar = progressbarContainer.parentNode;
const parentGallery = gallery ? gallery.parentNode : null;
const divProgress = document.createElement('div');
divProgress.className = 'progressDiv';
divProgress.id = 'progressbar';
divProgress.style.display = opts.show_progressbar ? 'block' : 'none';
const divInner = document.createElement('div');
divInner.className = 'progress';
divProgress.appendChild(divInner);
parentProgressbar.insertBefore(divProgress, progressbarContainer);
localStorage.setItem('task', id_task);
console.debug('task active:', id_task);
if (parentGallery) {
const livePreview = document.createElement('div');
livePreview.className = 'livePreview';
parentGallery.insertBefore(livePreview, gallery);
}
var removeProgressBar = function() {
console.debug('task end: ', id_task)
localStorage.removeItem('task');
setTitle("")
if (divProgress) parentProgressbar.removeChild(divProgress)
if (parentGallery) parentGallery.removeChild(livePreview)
if (atEnd) atEnd()
}
const removeProgressBar = function () {
console.debug('task end: ', id_task);
localStorage.removeItem('task');
setTitle('');
if (divProgress) parentProgressbar.removeChild(divProgress);
if (parentGallery) parentGallery.removeChild(livePreview);
if (atEnd) atEnd();
};
var fun = function(id_task, id_live_preview){
request("./internal/progress", {"id_task": id_task, "id_live_preview": id_live_preview}, function(res){
var elapsedFromStart = (new Date() - dateStart) / 1000
if (res.completed) {
removeProgressBar()
return
}
var rect = progressbarContainer.getBoundingClientRect()
if (rect.width) divProgress.style.width = rect.width + "px";
progressText = ""
divInner.style.width = ((res.progress || 0) * 100.0) + '%'
divInner.style.background = res.progress ? "" : "transparent"
if (res.progress > 0) progressText = ((res.progress || 0) * 100.0).toFixed(0) + '%'
if (res.eta) progressText += " ETA: " + formatTime(res.eta)
setTitle(progressText)
if (res.textinfo && res.textinfo.indexOf("\n") == -1) progressText = res.textinfo + " " + progressText
divInner.textContent = progressText
hasStarted |= res.active
if (!res.active && (hasStarted || once)) {
removeProgressBar()
return
}
if (res.completed) {
removeProgressBar()
return
}
if (elapsedFromStart > 30 && !res.queued && res.progress == prevProgress) {
removeProgressBar()
return
}
if (res.live_preview && gallery) {
var rect = gallery.getBoundingClientRect()
if(rect.width){
livePreview.style.width = rect.width + "px"
livePreview.style.height = rect.height + "px"
}
var img = new Image();
img.onload = function() {
livePreview.appendChild(img)
if (livePreview.childElementCount > 2) livePreview.removeChild(livePreview.firstElementChild)
}
img.src = res.live_preview;
}
if (onProgress) onProgress(res)
setTimeout(() => fun(id_task, res.id_live_preview), opts.live_preview_refresh_period || 250)
}, function() {
removeProgressBar()
})
}
fun(id_task, 0)
const fun = function (id_task, id_live_preview) {
request('./internal/progress', { id_task, id_live_preview }, (res) => {
const elapsedFromStart = (new Date() - dateStart) / 1000;
if (res.completed) {
removeProgressBar();
return;
}
var rect = progressbarContainer.getBoundingClientRect();
if (rect.width) divProgress.style.width = `${rect.width}px`;
progressText = '';
divInner.style.width = `${(res.progress || 0) * 100.0}%`;
divInner.style.background = res.progress ? '' : 'transparent';
if (res.progress > 0) progressText = `${((res.progress || 0) * 100.0).toFixed(0)}%`;
if (res.eta) progressText += ` ETA: ${formatTime(res.eta)}`;
setTitle(progressText);
if (res.textinfo && res.textinfo.indexOf('\n') == -1) progressText = `${res.textinfo} ${progressText}`;
divInner.textContent = progressText;
hasStarted |= res.active;
if (!res.active && (hasStarted || once)) {
removeProgressBar();
return;
}
if (res.completed) {
removeProgressBar();
return;
}
if (elapsedFromStart > 30 && !res.queued && res.progress == prevProgress) {
removeProgressBar();
return;
}
if (res.live_preview && gallery) {
var rect = gallery.getBoundingClientRect();
if (rect.width) {
livePreview.style.width = `${rect.width}px`;
livePreview.style.height = `${rect.height}px`;
}
const img = new Image();
img.onload = function () {
livePreview.appendChild(img);
if (livePreview.childElementCount > 2) livePreview.removeChild(livePreview.firstElementChild);
};
img.src = res.live_preview;
}
if (onProgress) onProgress(res);
setTimeout(() => fun(id_task, res.id_live_preview), opts.live_preview_refresh_period || 250);
}, () => {
removeProgressBar();
});
};
fun(id_task, 0);
}
+21 -1
View File
@@ -108,7 +108,12 @@ button.custom-button{
}
}
#txt2img_gallery img, #img2img_gallery img{
a{
font-weight: bold;
cursor: pointer;
}
#txt2img_gallery img, #img2img_gallery img, #extras_gallery img{
object-fit: scale-down;
}
#txt2img_actions_column, #img2img_actions_column {
@@ -406,6 +411,21 @@ div#extras_scale_to_tab div.form{
#lightboxModal > img.modalImageFullscreen{
object-fit: contain;
height: 100%;
width: 100%;
min-height: 0;
}
table.settings-value-table{
background: white;
border-collapse: collapse;
margin: 1em;
border: 4px solid white;
}
table.settings-value-table td{
padding: 0.4em;
border: 1px solid #ccc;
max-width: 36em;
}
.modalPrev,