From 0cc05fc492a9360d3b2f1b3f64c7d74f9041f74e Mon Sep 17 00:00:00 2001 From: AUTOMATIC <16777216c@gmail.com> Date: Sun, 21 May 2023 00:41:41 +0300 Subject: work on startup profile display --- javascript/profilerVisualization.js | 91 +++++++++++++++++++++++++++++++++++++ javascript/ui_settings_hints.js | 2 +- 2 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 javascript/profilerVisualization.js (limited to 'javascript') diff --git a/javascript/profilerVisualization.js b/javascript/profilerVisualization.js new file mode 100644 index 00000000..1bd75986 --- /dev/null +++ b/javascript/profilerVisualization.js @@ -0,0 +1,91 @@ + +function createRow(table, cellName, items) { + var tr = document.createElement('tr'); + var res = []; + + items.forEach(function(x) { + var td = document.createElement(cellName); + td.textContent = x; + tr.appendChild(td); + res.push(td); + }); + + table.appendChild(tr); + + return res; +} + +function showProfile(path, cutoff = 0.0005) { + requestGet(path, {}, function(data) { + var table = document.createElement('table'); + table.className = 'popup-table'; + + data.records['total'] = data.total; + var keys = Object.keys(data.records).sort(function(a, b) { + return data.records[b] - data.records[a]; + }); + var items = keys.map(function(x) { + return {key: x, parts: x.split('/'), time: data.records[x]}; + }); + var maxLength = items.reduce(function(a, b) { + return Math.max(a, b.parts.length); + }, 0); + + var cols = createRow(table, 'th', ['record', 'seconds']); + cols[0].colSpan = maxLength; + + function arraysEqual(a, b) { + return !(a < b || b < a); + } + + var addLevel = function(level, parent) { + var matching = items.filter(function(x) { + return x.parts[level] && !x.parts[level + 1] && arraysEqual(x.parts.slice(0, level), parent); + }); + var sorted = matching.sort(function(a, b) { + return b.time - a.time; + }); + var othersTime = 0; + var othersList = []; + sorted.forEach(function(x) { + if (x.time < cutoff) { + othersTime += x.time; + othersList.push(x.parts[level]); + return; + } + + var cells = []; + for (var i = 0; i < maxLength; i++) { + cells.push(x.parts[i]); + } + cells.push(x.time.toFixed(3)); + var cols = createRow(table, 'td', cells); + for (i = 0; i < level; i++) { + cols[i].className = 'muted'; + } + + addLevel(level + 1, parent.concat([x.parts[level]])); + }); + + if (othersTime > 0) { + var cells = []; + for (var i = 0; i < maxLength; i++) { + cells.push(parent[i]); + } + cells.push(othersTime.toFixed(3)); + var cols = createRow(table, 'td', cells); + for (i = 0; i < level; i++) { + cols[i].className = 'muted'; + } + + cols[level].textContent = 'others'; + cols[level].title = othersList.join(", "); + } + }; + + addLevel(0, []); + + popup(table); + }); +} + diff --git a/javascript/ui_settings_hints.js b/javascript/ui_settings_hints.js index e216852b..d088f949 100644 --- a/javascript/ui_settings_hints.js +++ b/javascript/ui_settings_hints.js @@ -42,7 +42,7 @@ onOptionsChanged(function() { function settingsHintsShowQuicksettings() { requestGet("./internal/quicksettings-hint", {}, function(data) { var table = document.createElement('table'); - table.className = 'settings-value-table'; + table.className = 'popup-table'; data.forEach(function(obj) { var tr = document.createElement('tr'); -- cgit v1.2.1 From 5ed970b94972004961ecada3bc1c936ef6017f3c Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Sun, 21 May 2023 23:16:14 +0300 Subject: Move token counters to separate JS file, fix names --- javascript/token-counters.js | 75 ++++++++++++++++++++++++++++++++++++++++++++ javascript/ui.js | 71 +---------------------------------------- 2 files changed, 76 insertions(+), 70 deletions(-) create mode 100644 javascript/token-counters.js (limited to 'javascript') diff --git a/javascript/token-counters.js b/javascript/token-counters.js new file mode 100644 index 00000000..0b74658c --- /dev/null +++ b/javascript/token-counters.js @@ -0,0 +1,75 @@ +let promptTokenCountDebounceTime = 800; +let promptTokenCountTimeouts = {}; +var promptTokenCountUpdateFunctions = {}; + +function update_txt2img_tokens(...args) { + // Called from Gradio + update_token_counter("txt2img_token_button"); + if (args.length == 2) { + return args[0]; + } + return args; +} + +function update_img2img_tokens(...args) { + // Called from Gradio + update_token_counter("img2img_token_button"); + if (args.length == 2) { + return args[0]; + } + return args; +} + +function update_token_counter(button_id) { + if (promptTokenCountTimeouts[button_id]) { + clearTimeout(promptTokenCountTimeouts[button_id]); + } + promptTokenCountTimeouts[button_id] = setTimeout( + () => gradioApp().getElementById(button_id)?.click(), + promptTokenCountDebounceTime, + ); +} + + +function recalculatePromptTokens(name) { + promptTokenCountUpdateFunctions[name]?.(); +} + +function recalculate_prompts_txt2img() { + // Called from Gradio + recalculatePromptTokens('txt2img_prompt'); + recalculatePromptTokens('txt2img_neg_prompt'); + return Array.from(arguments); +} + +function recalculate_prompts_img2img() { + // Called from Gradio + recalculatePromptTokens('img2img_prompt'); + recalculatePromptTokens('img2img_neg_prompt'); + return Array.from(arguments); +} + +function setupTokenCounting(id, id_counter, id_button) { + var prompt = gradioApp().getElementById(id); + var counter = gradioApp().getElementById(id_counter); + var textarea = gradioApp().querySelector(`#${id} > label > textarea`); + + if (counter.parentElement == prompt.parentElement) { + return; + } + + prompt.parentElement.insertBefore(counter, prompt); + prompt.parentElement.style.position = "relative"; + + promptTokenCountUpdateFunctions[id] = function() { + update_token_counter(id_button); + }; + textarea.addEventListener("input", promptTokenCountUpdateFunctions[id]); +} + +function setupTokenCounters() { + setupTokenCounting('txt2img_prompt', 'txt2img_token_counter', 'txt2img_token_button'); + setupTokenCounting('txt2img_neg_prompt', 'txt2img_negative_token_counter', 'txt2img_negative_token_button'); + setupTokenCounting('img2img_prompt', 'img2img_token_counter', 'img2img_token_button'); + setupTokenCounting('img2img_neg_prompt', 'img2img_negative_token_counter', 'img2img_negative_token_button'); +} diff --git a/javascript/ui.js b/javascript/ui.js index 648a5290..800a2ae6 100644 --- a/javascript/ui.js +++ b/javascript/ui.js @@ -248,27 +248,6 @@ function confirm_clear_prompt(prompt, negative_prompt) { } -var promptTokecountUpdateFuncs = {}; - -function recalculatePromptTokens(name) { - if (promptTokecountUpdateFuncs[name]) { - promptTokecountUpdateFuncs[name](); - } -} - -function recalculate_prompts_txt2img() { - recalculatePromptTokens('txt2img_prompt'); - recalculatePromptTokens('txt2img_neg_prompt'); - return Array.from(arguments); -} - -function recalculate_prompts_img2img() { - recalculatePromptTokens('img2img_prompt'); - recalculatePromptTokens('img2img_neg_prompt'); - return Array.from(arguments); -} - - var opts = {}; onUiUpdate(function() { if (Object.keys(opts).length != 0) return; @@ -302,28 +281,7 @@ onUiUpdate(function() { json_elem.parentElement.style.display = "none"; - function registerTextarea(id, id_counter, id_button) { - var prompt = gradioApp().getElementById(id); - var counter = gradioApp().getElementById(id_counter); - var textarea = gradioApp().querySelector("#" + id + " > label > textarea"); - - if (counter.parentElement == prompt.parentElement) { - return; - } - - prompt.parentElement.insertBefore(counter, prompt); - prompt.parentElement.style.position = "relative"; - - promptTokecountUpdateFuncs[id] = function() { - update_token_counter(id_button); - }; - textarea.addEventListener("input", promptTokecountUpdateFuncs[id]); - } - - registerTextarea('txt2img_prompt', 'txt2img_token_counter', 'txt2img_token_button'); - registerTextarea('txt2img_neg_prompt', 'txt2img_negative_token_counter', 'txt2img_negative_token_button'); - registerTextarea('img2img_prompt', 'img2img_token_counter', 'img2img_token_button'); - registerTextarea('img2img_neg_prompt', 'img2img_negative_token_counter', 'img2img_negative_token_button'); + setupTokenCounters(); var show_all_pages = gradioApp().getElementById('settings_show_all_pages'); var settings_tabs = gradioApp().querySelector('#settings div'); @@ -354,33 +312,6 @@ onOptionsChanged(function() { }); let txt2img_textarea, img2img_textarea = undefined; -let wait_time = 800; -let token_timeouts = {}; - -function update_txt2img_tokens(...args) { - update_token_counter("txt2img_token_button"); - if (args.length == 2) { - return args[0]; - } - return args; -} - -function update_img2img_tokens(...args) { - update_token_counter( - "img2img_token_button" - ); - if (args.length == 2) { - return args[0]; - } - return args; -} - -function update_token_counter(button_id) { - if (token_timeouts[button_id]) { - clearTimeout(token_timeouts[button_id]); - } - token_timeouts[button_id] = setTimeout(() => gradioApp().getElementById(button_id)?.click(), wait_time); -} function restart_reload() { document.body.innerHTML = '

Reloading...

'; -- cgit v1.2.1 From 618c59b01d8b90794df0aea625de1c1d5d94d407 Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Sun, 21 May 2023 23:20:50 +0300 Subject: Add option to disable prompt token counters --- javascript/token-counters.js | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'javascript') diff --git a/javascript/token-counters.js b/javascript/token-counters.js index 0b74658c..9d81a723 100644 --- a/javascript/token-counters.js +++ b/javascript/token-counters.js @@ -21,6 +21,9 @@ function update_img2img_tokens(...args) { } function update_token_counter(button_id) { + if (opts.disable_token_counters) { + return; + } if (promptTokenCountTimeouts[button_id]) { clearTimeout(promptTokenCountTimeouts[button_id]); } @@ -54,6 +57,11 @@ function setupTokenCounting(id, id_counter, id_button) { var counter = gradioApp().getElementById(id_counter); var textarea = gradioApp().querySelector(`#${id} > label > textarea`); + if (opts.disable_token_counters) { + counter.style.display = "none"; + return; + } + if (counter.parentElement == prompt.parentElement) { return; } -- cgit v1.2.1 From a862428902c4aecde8852761c3a4d95c196885cb Mon Sep 17 00:00:00 2001 From: missionfloyd Date: Sun, 21 May 2023 18:17:32 -0600 Subject: Fix dragging text to prompt --- javascript/dragdrop.js | 4 ++-- javascript/imageParams.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'javascript') diff --git a/javascript/dragdrop.js b/javascript/dragdrop.js index fe008924..90cdd507 100644 --- a/javascript/dragdrop.js +++ b/javascript/dragdrop.js @@ -51,7 +51,7 @@ function dropReplaceImage( imgWrap, files ) { window.document.addEventListener('dragover', e => { const target = e.composedPath()[0]; const imgWrap = target.closest('[data-testid="image"]'); - if ( !imgWrap && target.placeholder && target.placeholder.indexOf("Prompt") == -1) { + if (e.dataTransfer.files.length == 0 || (!imgWrap && target.placeholder && target.placeholder.indexOf("Prompt") == -1)) { return; } e.stopPropagation(); @@ -61,7 +61,7 @@ window.document.addEventListener('dragover', e => { window.document.addEventListener('drop', e => { const target = e.composedPath()[0]; - if (target.placeholder.indexOf("Prompt") == -1) { + if (e.dataTransfer.files.length == 0 || target.placeholder.indexOf("Prompt") == -1) { return; } const imgWrap = target.closest('[data-testid="image"]'); diff --git a/javascript/imageParams.js b/javascript/imageParams.js index 64aee93b..ed0df939 100644 --- a/javascript/imageParams.js +++ b/javascript/imageParams.js @@ -1,7 +1,7 @@ window.onload = (function(){ window.addEventListener('drop', e => { const target = e.composedPath()[0]; - if (target.placeholder.indexOf("Prompt") == -1) return; + if (e.dataTransfer.files.length == 0 || target.placeholder.indexOf("Prompt") == -1) return; let prompt_target = get_tab_index('tabs') == 1 ? "img2img_prompt_image" : "txt2img_prompt_image"; -- cgit v1.2.1 From ee65e729319e4184fc0d49552657e98aa0e28f17 Mon Sep 17 00:00:00 2001 From: AUTOMATIC <16777216c@gmail.com> Date: Mon, 22 May 2023 09:49:51 +0300 Subject: repair file paste for Firefox from #10615 remove animation when pasting files into prompt rework two dragdrop js files into one --- javascript/dragdrop.js | 53 ++++++++++++++++++++++++++++++++++++----------- javascript/imageParams.js | 18 ---------------- 2 files changed, 41 insertions(+), 30 deletions(-) delete mode 100644 javascript/imageParams.js (limited to 'javascript') diff --git a/javascript/dragdrop.js b/javascript/dragdrop.js index fd6b3154..aa79871a 100644 --- a/javascript/dragdrop.js +++ b/javascript/dragdrop.js @@ -48,12 +48,27 @@ function dropReplaceImage(imgWrap, files) { } } +function eventHasFiles(e) { + if (!e.dataTransfer || !e.dataTransfer.files) return false; + if (e.dataTransfer.files.length > 0) return true; + if (e.dataTransfer.items.length > 0 && e.dataTransfer.items[0].kind == "file") return true; + + return false; +} + +function dragDropTargetIsPrompt(target) { + if (!(target?.placeholder?.indexOf("Prompt") >= 0)) return true; + if (target?.parentNode?.parentNode) return true; + return false; +} + window.document.addEventListener('dragover', e => { const target = e.composedPath()[0]; - const imgWrap = target.closest('[data-testid="image"]'); - if (e.dataTransfer.files.length == 0 || (!imgWrap && target.placeholder && target.placeholder.indexOf("Prompt") == -1)) { - return; - } + if (!eventHasFiles(e)) return; + + var targetImage = target.closest('[data-testid="image"]'); + if (!dragDropTargetIsPrompt(target) && !targetImage) return; + e.stopPropagation(); e.preventDefault(); e.dataTransfer.dropEffect = 'copy'; @@ -61,17 +76,31 @@ window.document.addEventListener('dragover', e => { window.document.addEventListener('drop', e => { const target = e.composedPath()[0]; - if (e.dataTransfer.files.length == 0 || target.placeholder.indexOf("Prompt") == -1) { - return; + if (!eventHasFiles(e)) return; + + if (dragDropTargetIsPrompt(target)) { + e.stopPropagation(); + e.preventDefault(); + + let prompt_target = get_tab_index('tabs') == 1 ? "img2img_prompt_image" : "txt2img_prompt_image"; + + const imgParent = gradioApp().getElementById(prompt_target); + const files = e.dataTransfer.files; + const fileInput = imgParent.querySelector('input[type="file"]'); + if (fileInput) { + fileInput.files = files; + fileInput.dispatchEvent(new Event('change')); + } } - const imgWrap = target.closest('[data-testid="image"]'); - if (!imgWrap) { + + var targetImage = target.closest('[data-testid="image"]'); + if (targetImage) { + e.stopPropagation(); + e.preventDefault(); + const files = e.dataTransfer.files; + dropReplaceImage(targetImage, files); return; } - e.stopPropagation(); - e.preventDefault(); - const files = e.dataTransfer.files; - dropReplaceImage(imgWrap, files); }); window.addEventListener('paste', e => { diff --git a/javascript/imageParams.js b/javascript/imageParams.js deleted file mode 100644 index 0cdd717a..00000000 --- a/javascript/imageParams.js +++ /dev/null @@ -1,18 +0,0 @@ -window.onload = (function() { - window.addEventListener('drop', e => { - const target = e.composedPath()[0]; - if (e.dataTransfer.files.length == 0 || target.placeholder.indexOf("Prompt") == -1) return; - - let prompt_target = get_tab_index('tabs') == 1 ? "img2img_prompt_image" : "txt2img_prompt_image"; - - e.stopPropagation(); - e.preventDefault(); - const imgParent = gradioApp().getElementById(prompt_target); - const files = e.dataTransfer.files; - const fileInput = imgParent.querySelector('input[type="file"]'); - if (fileInput) { - fileInput.files = files; - fileInput.dispatchEvent(new Event('change')); - } - }); -}); -- cgit v1.2.1 From cc2f6e3b7b8d720a8e0fb2732751e34b7f41c2e9 Mon Sep 17 00:00:00 2001 From: AUTOMATIC <16777216c@gmail.com> Date: Mon, 22 May 2023 15:40:10 +0300 Subject: fix error in dragdrop logic --- javascript/dragdrop.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'javascript') diff --git a/javascript/dragdrop.js b/javascript/dragdrop.js index aa79871a..5803daea 100644 --- a/javascript/dragdrop.js +++ b/javascript/dragdrop.js @@ -57,8 +57,8 @@ function eventHasFiles(e) { } function dragDropTargetIsPrompt(target) { - if (!(target?.placeholder?.indexOf("Prompt") >= 0)) return true; - if (target?.parentNode?.parentNode) return true; + if (target?.placeholder && target?.placeholder.indexOf("Prompt") >= 0) return true; + if (target?.parentNode?.parentNode?.className?.indexOf("prompt") > 0) return true; return false; } -- cgit v1.2.1 From d66c64b9d76553a9518ae6a3141714519d65d796 Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Wed, 24 May 2023 20:19:16 +0300 Subject: Optimize tooltip checks * Instead of traversing tens of thousands of text nodes, only look at elements and their children * Debounce the checks to happen only every one second --- javascript/hints.js | 61 +++++++++++++++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 28 deletions(-) (limited to 'javascript') diff --git a/javascript/hints.js b/javascript/hints.js index 46f342cb..a8c72976 100644 --- a/javascript/hints.js +++ b/javascript/hints.js @@ -116,17 +116,17 @@ var titles = { "Negative Guidance minimum sigma": "Skip negative prompt for steps where image is already mostly denoised; the higher this value, the more skips there will be; provides increased performance in exchange for minor quality reduction." }; -function updateTooltipForSpan(span) { - if (span.title) return; // already has a title +function updateTooltip(element) { + if (element.title) return; // already has a title - let tooltip = localization[titles[span.textContent]] || titles[span.textContent]; + let tooltip = localization[titles[element.textContent]] || titles[element.textContent]; if (!tooltip) { - tooltip = localization[titles[span.value]] || titles[span.value]; + tooltip = localization[titles[element.value]] || titles[element.value]; } if (!tooltip) { - for (const c of span.classList) { + for (const c of element.classList) { if (c in titles) { tooltip = localization[titles[c]] || titles[c]; break; @@ -135,34 +135,39 @@ function updateTooltipForSpan(span) { } if (tooltip) { - span.title = tooltip; + element.title = tooltip; } } -function updateTooltipForSelect(select) { - if (select.onchange != null) return; +// Nodes to check for adding tooltips. +const tooltipCheckNodes = new Set(); +// Timer for debouncing tooltip check. +let tooltipCheckTimer = null; - select.onchange = function() { - select.title = localization[titles[select.value]] || titles[select.value] || ""; - }; +function processTooltipCheckNodes() { + for (const node of tooltipCheckNodes) { + updateTooltip(node); + } + tooltipCheckNodes.clear(); } -var observedTooltipElements = {SPAN: 1, BUTTON: 1, SELECT: 1, P: 1}; - -onUiUpdate(function(m) { - m.forEach(function(record) { - record.addedNodes.forEach(function(node) { - if (observedTooltipElements[node.tagName]) { - updateTooltipForSpan(node); - } - if (node.tagName == "SELECT") { - updateTooltipForSelect(node); - } - - if (node.querySelectorAll) { - node.querySelectorAll('span, button, select, p').forEach(updateTooltipForSpan); - node.querySelectorAll('select').forEach(updateTooltipForSelect); +onUiUpdate(function(mutationRecords) { + for (const record of mutationRecords) { + for (const node of record.addedNodes) { + if (node.nodeType === Node.ELEMENT_NODE && !node.classList.contains("hide")) { + if ( + node.tagName === "SPAN" || + node.tagName === "BUTTON" || + node.tagName === "P" + ) { + tooltipCheckNodes.add(node); + } + node.querySelectorAll('span, button, p').forEach(n => tooltipCheckNodes.add(n)); } - }); - }); + } + } + if (tooltipCheckNodes.size) { + clearTimeout(tooltipCheckTimer); + tooltipCheckTimer = setTimeout(processTooltipCheckNodes, 1000); + } }); -- cgit v1.2.1 From b82d4a65fe9b025e9da1b8c7a72ed9d56b96315d Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Wed, 24 May 2023 20:34:57 +0300 Subject: Restore support for dropdown tooltips --- javascript/hints.js | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) (limited to 'javascript') diff --git a/javascript/hints.js b/javascript/hints.js index a8c72976..7f8885bc 100644 --- a/javascript/hints.js +++ b/javascript/hints.js @@ -153,14 +153,27 @@ function processTooltipCheckNodes() { onUiUpdate(function(mutationRecords) { for (const record of mutationRecords) { + if (record.type === "childList" && record.target.classList.contains("options")) { + // This smells like a Gradio dropdown menu having changed, + // so let's enqueue an update for the input element that shows the current value. + let wrap = record.target.parentNode; + let input = wrap?.querySelector("input"); + if (input) { + input.title = ""; // So we'll even have a chance to update it. + tooltipCheckNodes.add(input); + } + } for (const node of record.addedNodes) { if (node.nodeType === Node.ELEMENT_NODE && !node.classList.contains("hide")) { - if ( - node.tagName === "SPAN" || - node.tagName === "BUTTON" || - node.tagName === "P" - ) { - tooltipCheckNodes.add(node); + if (!node.title) { + if ( + node.tagName === "SPAN" || + node.tagName === "BUTTON" || + node.tagName === "P" || + node.tagName === "INPUT" + ) { + tooltipCheckNodes.add(node); + } } node.querySelectorAll('span, button, p').forEach(n => tooltipCheckNodes.add(n)); } -- cgit v1.2.1 From 32b0f7c9bbb908b870c2e0d488bd63a9c71ba078 Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Wed, 24 May 2023 20:45:05 +0300 Subject: Add support for tooltips on dropdown options --- javascript/hints.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'javascript') diff --git a/javascript/hints.js b/javascript/hints.js index 7f8885bc..05ae5f22 100644 --- a/javascript/hints.js +++ b/javascript/hints.js @@ -119,10 +119,18 @@ var titles = { function updateTooltip(element) { if (element.title) return; // already has a title - let tooltip = localization[titles[element.textContent]] || titles[element.textContent]; + let text = element.textContent; + let tooltip = localization[titles[text]] || titles[text]; if (!tooltip) { - tooltip = localization[titles[element.value]] || titles[element.value]; + let value = element.value; + if (value) tooltip = localization[titles[value]] || titles[value]; + } + + if (!tooltip) { + // Gradio dropdown options have `data-value`. + let dataValue = element.dataset.value; + if (dataValue) tooltip = localization[titles[dataValue]] || titles[dataValue]; } if (!tooltip) { @@ -170,7 +178,8 @@ onUiUpdate(function(mutationRecords) { node.tagName === "SPAN" || node.tagName === "BUTTON" || node.tagName === "P" || - node.tagName === "INPUT" + node.tagName === "INPUT" || + (node.tagName === "LI" && node.classList.contains("item")) // Gradio dropdown item ) { tooltipCheckNodes.add(node); } -- cgit v1.2.1 From dc7a1bbb1c70ba7585ca64c0a96e1bcba4d2302f Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Thu, 25 May 2023 09:09:13 +0300 Subject: Use onAfterUiUpdate where possible --- javascript/aspectRatioOverlay.js | 2 +- javascript/contextMenus.js | 4 +--- javascript/generationParams.js | 2 +- javascript/imageMaskFix.js | 2 +- javascript/imageviewer.js | 2 +- javascript/notification.js | 2 +- javascript/ui.js | 2 +- 7 files changed, 7 insertions(+), 9 deletions(-) (limited to 'javascript') diff --git a/javascript/aspectRatioOverlay.js b/javascript/aspectRatioOverlay.js index 1c08a1a9..2cf2d571 100644 --- a/javascript/aspectRatioOverlay.js +++ b/javascript/aspectRatioOverlay.js @@ -81,7 +81,7 @@ function dimensionChange(e, is_width, is_height) { } -onUiUpdate(function() { +onAfterUiUpdate(function() { var arPreviewRect = gradioApp().querySelector('#imageARPreview'); if (arPreviewRect) { arPreviewRect.style.display = 'none'; diff --git a/javascript/contextMenus.js b/javascript/contextMenus.js index f14af1d4..d60a10c4 100644 --- a/javascript/contextMenus.js +++ b/javascript/contextMenus.js @@ -167,6 +167,4 @@ var addContextMenuEventListener = initResponse[2]; })(); //End example Context Menu Items -onUiUpdate(function() { - addContextMenuEventListener(); -}); +onAfterUiUpdate(addContextMenuEventListener); diff --git a/javascript/generationParams.js b/javascript/generationParams.js index a877f8a5..7c0fd221 100644 --- a/javascript/generationParams.js +++ b/javascript/generationParams.js @@ -1,7 +1,7 @@ // attaches listeners to the txt2img and img2img galleries to update displayed generation param text when the image changes let txt2img_gallery, img2img_gallery, modal = undefined; -onUiUpdate(function() { +onAfterUiUpdate(function() { if (!txt2img_gallery) { txt2img_gallery = attachGalleryListeners("txt2img"); } diff --git a/javascript/imageMaskFix.js b/javascript/imageMaskFix.js index 3c9b8a6f..900c56f3 100644 --- a/javascript/imageMaskFix.js +++ b/javascript/imageMaskFix.js @@ -39,5 +39,5 @@ function imageMaskResize() { }); } -onUiUpdate(imageMaskResize); +onAfterUiUpdate(imageMaskResize); window.addEventListener('resize', imageMaskResize); diff --git a/javascript/imageviewer.js b/javascript/imageviewer.js index 78e24eb9..677e95c1 100644 --- a/javascript/imageviewer.js +++ b/javascript/imageviewer.js @@ -170,7 +170,7 @@ function modalTileImageToggle(event) { event.stopPropagation(); } -onUiUpdate(function() { +onAfterUiUpdate(function() { var fullImg_preview = gradioApp().querySelectorAll('.gradio-gallery > div > img'); if (fullImg_preview != null) { fullImg_preview.forEach(setupImageForLightbox); diff --git a/javascript/notification.js b/javascript/notification.js index a68a76f2..76c5715d 100644 --- a/javascript/notification.js +++ b/javascript/notification.js @@ -4,7 +4,7 @@ let lastHeadImg = null; let notificationButton = null; -onUiUpdate(function() { +onAfterUiUpdate(function() { if (notificationButton == null) { notificationButton = gradioApp().getElementById('request_notifications'); diff --git a/javascript/ui.js b/javascript/ui.js index 800a2ae6..d70a681b 100644 --- a/javascript/ui.js +++ b/javascript/ui.js @@ -249,7 +249,7 @@ function confirm_clear_prompt(prompt, negative_prompt) { var opts = {}; -onUiUpdate(function() { +onAfterUiUpdate(function() { if (Object.keys(opts).length != 0) return; var json_elem = gradioApp().getElementById('settings_json'); -- cgit v1.2.1 From df59b74cedf6db12419de43f3b45c71cf457896e Mon Sep 17 00:00:00 2001 From: missionfloyd Date: Sun, 28 May 2023 20:42:47 -0600 Subject: Only poll gamepads while connected --- javascript/imageviewerGamepad.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'javascript') diff --git a/javascript/imageviewerGamepad.js b/javascript/imageviewerGamepad.js index 31d226de..0510c02a 100644 --- a/javascript/imageviewerGamepad.js +++ b/javascript/imageviewerGamepad.js @@ -1,7 +1,9 @@ +let gamepads = []; + window.addEventListener('gamepadconnected', (e) => { const index = e.gamepad.index; let isWaiting = false; - setInterval(async() => { + gamepads[index] = setInterval(async() => { if (!opts.js_modal_lightbox_gamepad || isWaiting) return; const gamepad = navigator.getGamepads()[index]; const xValue = gamepad.axes[0]; @@ -22,6 +24,7 @@ window.addEventListener('gamepadconnected', (e) => { isWaiting = false; } }, 10); + window.addEventListener('gamepaddisconnected', (e) => clearInterval(gamepads[e.gamepad.index])) }); /* -- cgit v1.2.1 From 679e8738759b9aa2678a40d518bf6d67915e98fe Mon Sep 17 00:00:00 2001 From: missionfloyd Date: Sun, 28 May 2023 20:49:46 -0600 Subject: Update imageviewerGamepad.js --- javascript/imageviewerGamepad.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'javascript') diff --git a/javascript/imageviewerGamepad.js b/javascript/imageviewerGamepad.js index 0510c02a..45cc4cbf 100644 --- a/javascript/imageviewerGamepad.js +++ b/javascript/imageviewerGamepad.js @@ -24,7 +24,7 @@ window.addEventListener('gamepadconnected', (e) => { isWaiting = false; } }, 10); - window.addEventListener('gamepaddisconnected', (e) => clearInterval(gamepads[e.gamepad.index])) + window.addEventListener('gamepaddisconnected', (e) => clearInterval(gamepads[e.gamepad.index])); }); /* -- cgit v1.2.1 From baa81126c485434211cb6d58292f77de00dc2432 Mon Sep 17 00:00:00 2001 From: missionfloyd Date: Mon, 29 May 2023 23:52:19 -0600 Subject: Move gamepaddisconnected listener --- javascript/imageviewerGamepad.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'javascript') diff --git a/javascript/imageviewerGamepad.js b/javascript/imageviewerGamepad.js index 45cc4cbf..a22c7e6e 100644 --- a/javascript/imageviewerGamepad.js +++ b/javascript/imageviewerGamepad.js @@ -24,7 +24,10 @@ window.addEventListener('gamepadconnected', (e) => { isWaiting = false; } }, 10); - window.addEventListener('gamepaddisconnected', (e) => clearInterval(gamepads[e.gamepad.index])); +}); + +window.addEventListener('gamepaddisconnected', (e) => { + clearInterval(gamepads[e.gamepad.index]); }); /* -- cgit v1.2.1 From a5e851028e23e411c392a66e7c791e388b3e4aba Mon Sep 17 00:00:00 2001 From: AUTOMATIC <16777216c@gmail.com> Date: Thu, 1 Jun 2023 10:01:42 +0300 Subject: add hiding and a colspans to startup profile table --- javascript/profilerVisualization.js | 84 ++++++++++++++++++++++++++++++++----- 1 file changed, 73 insertions(+), 11 deletions(-) (limited to 'javascript') diff --git a/javascript/profilerVisualization.js b/javascript/profilerVisualization.js index 1bd75986..9d8e5f42 100644 --- a/javascript/profilerVisualization.js +++ b/javascript/profilerVisualization.js @@ -3,11 +3,29 @@ function createRow(table, cellName, items) { var tr = document.createElement('tr'); var res = []; - items.forEach(function(x) { + items.forEach(function(x, i) { + if (x === undefined) { + res.push(null); + return; + } + var td = document.createElement(cellName); td.textContent = x; tr.appendChild(td); res.push(td); + + var colspan = 1; + for (var n = i + 1; n < items.length; n++) { + if (items[n] !== undefined) { + break; + } + + colspan += 1; + } + + if (colspan > 1) { + td.colSpan = colspan; + } }); table.appendChild(tr); @@ -15,7 +33,7 @@ function createRow(table, cellName, items) { return res; } -function showProfile(path, cutoff = 0.0005) { +function showProfile(path, cutoff = 0.05) { requestGet(path, {}, function(data) { var table = document.createElement('table'); table.className = 'popup-table'; @@ -38,7 +56,7 @@ function showProfile(path, cutoff = 0.0005) { return !(a < b || b < a); } - var addLevel = function(level, parent) { + var addLevel = function(level, parent, hide) { var matching = items.filter(function(x) { return x.parts[level] && !x.parts[level + 1] && arraysEqual(x.parts.slice(0, level), parent); }); @@ -47,12 +65,10 @@ function showProfile(path, cutoff = 0.0005) { }); var othersTime = 0; var othersList = []; + var othersRows = []; + var childrenRows = []; sorted.forEach(function(x) { - if (x.time < cutoff) { - othersTime += x.time; - othersList.push(x.parts[level]); - return; - } + var visible = x.time >= cutoff && !hide; var cells = []; for (var i = 0; i < maxLength; i++) { @@ -64,7 +80,32 @@ function showProfile(path, cutoff = 0.0005) { cols[i].className = 'muted'; } - addLevel(level + 1, parent.concat([x.parts[level]])); + var tr = cols[0].parentNode; + if (!visible) { + tr.classList.add("hidden"); + } + + if (x.time >= cutoff) { + childrenRows.push(tr); + } else { + othersTime += x.time; + othersList.push(x.parts[level]); + othersRows.push(tr); + } + + var children = addLevel(level + 1, parent.concat([x.parts[level]]), true); + if (children.length > 0) { + var cell = cols[level]; + var onclick = function() { + cell.classList.remove("link"); + cell.removeEventListener("click", onclick); + children.forEach(function(x) { + x.classList.remove("hidden"); + }); + }; + cell.classList.add("link"); + cell.addEventListener("click", onclick); + } }); if (othersTime > 0) { @@ -73,14 +114,35 @@ function showProfile(path, cutoff = 0.0005) { cells.push(parent[i]); } cells.push(othersTime.toFixed(3)); + cells[level] = 'others'; var cols = createRow(table, 'td', cells); for (i = 0; i < level; i++) { cols[i].className = 'muted'; } - cols[level].textContent = 'others'; - cols[level].title = othersList.join(", "); + var cell = cols[level]; + var tr = cell.parentNode; + var onclick = function() { + tr.classList.add("hidden"); + cell.classList.remove("link"); + cell.removeEventListener("click", onclick); + othersRows.forEach(function(x) { + x.classList.remove("hidden"); + }); + }; + + cell.title = othersList.join(", "); + cell.classList.add("link"); + cell.addEventListener("click", onclick); + + if (hide) { + tr.classList.add("hidden"); + } + + childrenRows.push(tr); } + + return childrenRows; }; addLevel(0, []); -- cgit v1.2.1 From 7dca8e7698101fd5f610675f21569eba628883f8 Mon Sep 17 00:00:00 2001 From: catboxanon <122327233+catboxanon@users.noreply.github.com> Date: Fri, 2 Jun 2023 04:08:45 +0000 Subject: Support dynamic sort of extra networks --- javascript/extraNetworks.js | 47 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'javascript') diff --git a/javascript/extraNetworks.js b/javascript/extraNetworks.js index aafe0a00..58bc7f1d 100644 --- a/javascript/extraNetworks.js +++ b/javascript/extraNetworks.js @@ -3,10 +3,17 @@ function setupExtraNetworksForTab(tabname) { var tabs = gradioApp().querySelector('#' + tabname + '_extra_tabs > div'); var search = gradioApp().querySelector('#' + tabname + '_extra_search textarea'); + var sort = gradioApp().getElementById(tabname + '_extra_sort'); + var sortOrder = gradioApp().getElementById(tabname + '_extra_sortorder'); var refresh = gradioApp().getElementById(tabname + '_extra_refresh'); search.classList.add('search'); + sort.classList.add('sort'); + sortOrder.classList.add('sortorder'); + sort.dataset.sortkey = 'sortDefault' tabs.appendChild(search); + tabs.appendChild(sort); + tabs.appendChild(sortOrder); tabs.appendChild(refresh); var applyFilter = function() { @@ -26,8 +33,48 @@ function setupExtraNetworksForTab(tabname) { }); }; + var applySort = function() { + var reverse = sortOrder.classList.contains("sortReverse"); + var sortKey = sort.querySelector("input").value.toLowerCase().replace("sort","").replaceAll(" ", "_").replace(/_+$/, "").trim(); + sortKey = sortKey ? "sort" + sortKey.charAt(0).toUpperCase() + sortKey.slice(1) : "" + var sortKeyStore = sortKey ? sortKey + (reverse ? "Reverse" : "") : "" + if (!sortKey || sortKeyStore == sort.dataset.sortkey) + return; + + sort.dataset.sortkey = sortKeyStore; + + var cards = gradioApp().querySelectorAll('#' + tabname + '_extra_tabs div.card') + cards.forEach(function(card) { + card.originalParentElement = card.parentElement; + }) + var sortedCards = Array.from(cards); + sortedCards.sort(function(cardA, cardB) { + var a = cardA.dataset[sortKey]; + var b = cardB.dataset[sortKey]; + if (!isNaN(a) && !isNaN(b)) + return parseInt(a) - parseInt(b); + + return (a < b ? -1 : (a > b ? 1 : 0)); + }) + if (reverse) + sortedCards.reverse(); + cards.forEach(function(card) { + card.remove(); + }) + sortedCards.forEach(function(card) { + card.originalParentElement.appendChild(card); + }) + } + search.addEventListener("input", applyFilter); applyFilter(); + ["change", "blur", "click"].forEach(function(evt) { + sort.querySelector("input").addEventListener(evt, applySort); + }) + sortOrder.addEventListener("click", function() { + sortOrder.classList.toggle("sortReverse"); + applySort(); + }); extraNetworksApplyFilter[tabname] = applyFilter; } -- cgit v1.2.1 From 4cc0cede6d4cae74779b1b4cfc4b7bf7bfdaeaa6 Mon Sep 17 00:00:00 2001 From: catboxanon <122327233+catboxanon@users.noreply.github.com> Date: Fri, 2 Jun 2023 04:12:08 +0000 Subject: lint fixes --- javascript/extraNetworks.js | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) (limited to 'javascript') diff --git a/javascript/extraNetworks.js b/javascript/extraNetworks.js index 58bc7f1d..b87bca3e 100644 --- a/javascript/extraNetworks.js +++ b/javascript/extraNetworks.js @@ -10,7 +10,7 @@ function setupExtraNetworksForTab(tabname) { search.classList.add('search'); sort.classList.add('sort'); sortOrder.classList.add('sortorder'); - sort.dataset.sortkey = 'sortDefault' + sort.dataset.sortkey = 'sortDefault'; tabs.appendChild(search); tabs.appendChild(sort); tabs.appendChild(sortOrder); @@ -35,42 +35,45 @@ function setupExtraNetworksForTab(tabname) { var applySort = function() { var reverse = sortOrder.classList.contains("sortReverse"); - var sortKey = sort.querySelector("input").value.toLowerCase().replace("sort","").replaceAll(" ", "_").replace(/_+$/, "").trim(); - sortKey = sortKey ? "sort" + sortKey.charAt(0).toUpperCase() + sortKey.slice(1) : "" - var sortKeyStore = sortKey ? sortKey + (reverse ? "Reverse" : "") : "" - if (!sortKey || sortKeyStore == sort.dataset.sortkey) + var sortKey = sort.querySelector("input").value.toLowerCase().replace("sort", "").replaceAll(" ", "_").replace(/_+$/, "").trim(); + sortKey = sortKey ? "sort" + sortKey.charAt(0).toUpperCase() + sortKey.slice(1) : ""; + var sortKeyStore = sortKey ? sortKey + (reverse ? "Reverse" : "") : ""; + if (!sortKey || sortKeyStore == sort.dataset.sortkey) { return; + } sort.dataset.sortkey = sortKeyStore; - var cards = gradioApp().querySelectorAll('#' + tabname + '_extra_tabs div.card') + var cards = gradioApp().querySelectorAll('#' + tabname + '_extra_tabs div.card'); cards.forEach(function(card) { card.originalParentElement = card.parentElement; - }) + }); var sortedCards = Array.from(cards); sortedCards.sort(function(cardA, cardB) { var a = cardA.dataset[sortKey]; var b = cardB.dataset[sortKey]; - if (!isNaN(a) && !isNaN(b)) + if (!isNaN(a) && !isNaN(b)) { return parseInt(a) - parseInt(b); + } return (a < b ? -1 : (a > b ? 1 : 0)); - }) - if (reverse) + }); + if (reverse) { sortedCards.reverse(); + } cards.forEach(function(card) { card.remove(); - }) + }); sortedCards.forEach(function(card) { card.originalParentElement.appendChild(card); - }) - } + }); + }; search.addEventListener("input", applyFilter); applyFilter(); ["change", "blur", "click"].forEach(function(evt) { sort.querySelector("input").addEventListener(evt, applySort); - }) + }); sortOrder.addEventListener("click", function() { sortOrder.classList.toggle("sortReverse"); applySort(); -- cgit v1.2.1 From 46e4777fd60cb589ac3fba4d6b8c76076cb7d27f Mon Sep 17 00:00:00 2001 From: w-e-w <40751091+w-e-w@users.noreply.github.com> Date: Thu, 8 Jun 2023 17:48:45 +0900 Subject: Generate Forever during generation Generate Forever during generation --- javascript/contextMenus.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'javascript') diff --git a/javascript/contextMenus.js b/javascript/contextMenus.js index d60a10c4..ccae242f 100644 --- a/javascript/contextMenus.js +++ b/javascript/contextMenus.js @@ -148,12 +148,18 @@ var addContextMenuEventListener = initResponse[2]; 500); }; - appendContextMenuOption('#txt2img_generate', 'Generate forever', function() { + let generateOnRepeat_txt2img = function() { generateOnRepeat('#txt2img_generate', '#txt2img_interrupt'); - }); - appendContextMenuOption('#img2img_generate', 'Generate forever', function() { + }; + + let generateOnRepeat_img2img = function() { generateOnRepeat('#img2img_generate', '#img2img_interrupt'); - }); + }; + + appendContextMenuOption('#txt2img_generate', 'Generate forever', generateOnRepeat_txt2img); + appendContextMenuOption('#txt2img_interrupt', 'Generate forever', generateOnRepeat_txt2img); + appendContextMenuOption('#img2img_generate', 'Generate forever', generateOnRepeat_img2img); + appendContextMenuOption('#img2img_interrupt', 'Generate forever', generateOnRepeat_img2img); let cancelGenerateForever = function() { clearInterval(window.generateOnRepeatInterval); -- cgit v1.2.1 From f7ae0e68c9c91cd95e28552ef930299286026cd7 Mon Sep 17 00:00:00 2001 From: zhtttylz Date: Sun, 18 Jun 2023 15:46:08 +0800 Subject: Fix Typo of hints.js --- javascript/hints.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'javascript') diff --git a/javascript/hints.js b/javascript/hints.js index 46f342cb..a2f222e5 100644 --- a/javascript/hints.js +++ b/javascript/hints.js @@ -15,7 +15,7 @@ var titles = { "CFG Scale": "Classifier Free Guidance Scale - how strongly the image should conform to prompt - lower values produce more creative results", "Seed": "A value that determines the output of random number generator - if you create an image with same parameters and seed as another image, you'll get the same result", "\u{1f3b2}\ufe0f": "Set seed to -1, which will cause a new random number to be used every time", - "\u267b\ufe0f": "Reuse seed from last generation, mostly useful if it was randomed", + "\u267b\ufe0f": "Reuse seed from last generation, mostly useful if it was randomized", "\u2199\ufe0f": "Read generation parameters from prompt or last generation if prompt is empty into user interface.", "\u{1f4c2}": "Open images output directory", "\u{1f4be}": "Save style", @@ -112,7 +112,7 @@ var titles = { "Resize height to": "Resizes image to this height. If 0, height is inferred from either of two nearby sliders.", "Multiplier for extra networks": "When adding extra network such as Hypernetwork or Lora to prompt, use this multiplier for it.", "Discard weights with matching name": "Regular expression; if weights's name matches it, the weights is not written to the resulting checkpoint. Use ^model_ema to discard EMA weights.", - "Extra networks tab order": "Comma-separated list of tab names; tabs listed here will appear in the extra networks UI first and in order lsited.", + "Extra networks tab order": "Comma-separated list of tab names; tabs listed here will appear in the extra networks UI first and in order listed.", "Negative Guidance minimum sigma": "Skip negative prompt for steps where image is already mostly denoised; the higher this value, the more skips there will be; provides increased performance in exchange for minor quality reduction." }; -- cgit v1.2.1