Explorar o código

Start / Restart generation by Ctrl (Alt) + Enter

Add ability to interrupt current generation and start generation again by Ctrl (Alt) + Enter
Khachatur Avanesian hai 1 ano
pai
achega
f00eaa4d00
Modificáronse 1 ficheiros con 165 adicións e 163 borrados
  1. 165 163
      script.js

+ 165 - 163
script.js

@@ -1,163 +1,165 @@
-function gradioApp() {
-    const elems = document.getElementsByTagName('gradio-app');
-    const elem = elems.length == 0 ? document : elems[0];
-
-    if (elem !== document) {
-        elem.getElementById = function(id) {
-            return document.getElementById(id);
-        };
-    }
-    return elem.shadowRoot ? elem.shadowRoot : elem;
-}
-
-/**
- * Get the currently selected top-level UI tab button (e.g. the button that says "Extras").
- */
-function get_uiCurrentTab() {
-    return gradioApp().querySelector('#tabs > .tab-nav > button.selected');
-}
-
-/**
- * Get the first currently visible top-level UI tab content (e.g. the div hosting the "txt2img" UI).
- */
-function get_uiCurrentTabContent() {
-    return gradioApp().querySelector('#tabs > .tabitem[id^=tab_]:not([style*="display: none"])');
-}
-
-var uiUpdateCallbacks = [];
-var uiAfterUpdateCallbacks = [];
-var uiLoadedCallbacks = [];
-var uiTabChangeCallbacks = [];
-var optionsChangedCallbacks = [];
-var uiAfterUpdateTimeout = null;
-var uiCurrentTab = null;
-
-/**
- * Register callback to be called at each UI update.
- * The callback receives an array of MutationRecords as an argument.
- */
-function onUiUpdate(callback) {
-    uiUpdateCallbacks.push(callback);
-}
-
-/**
- * Register callback to be called soon after UI updates.
- * The callback receives no arguments.
- *
- * This is preferred over `onUiUpdate` if you don't need
- * access to the MutationRecords, as your function will
- * not be called quite as often.
- */
-function onAfterUiUpdate(callback) {
-    uiAfterUpdateCallbacks.push(callback);
-}
-
-/**
- * Register callback to be called when the UI is loaded.
- * The callback receives no arguments.
- */
-function onUiLoaded(callback) {
-    uiLoadedCallbacks.push(callback);
-}
-
-/**
- * Register callback to be called when the UI tab is changed.
- * The callback receives no arguments.
- */
-function onUiTabChange(callback) {
-    uiTabChangeCallbacks.push(callback);
-}
-
-/**
- * Register callback to be called when the options are changed.
- * The callback receives no arguments.
- * @param callback
- */
-function onOptionsChanged(callback) {
-    optionsChangedCallbacks.push(callback);
-}
-
-function executeCallbacks(queue, arg) {
-    for (const callback of queue) {
-        try {
-            callback(arg);
-        } catch (e) {
-            console.error("error running callback", callback, ":", e);
-        }
-    }
-}
-
-/**
- * Schedule the execution of the callbacks registered with onAfterUiUpdate.
- * The callbacks are executed after a short while, unless another call to this function
- * is made before that time. IOW, the callbacks are executed only once, even
- * when there are multiple mutations observed.
- */
-function scheduleAfterUiUpdateCallbacks() {
-    clearTimeout(uiAfterUpdateTimeout);
-    uiAfterUpdateTimeout = setTimeout(function() {
-        executeCallbacks(uiAfterUpdateCallbacks);
-    }, 200);
-}
-
-var executedOnLoaded = false;
-
-document.addEventListener("DOMContentLoaded", function() {
-    var mutationObserver = new MutationObserver(function(m) {
-        if (!executedOnLoaded && gradioApp().querySelector('#txt2img_prompt')) {
-            executedOnLoaded = true;
-            executeCallbacks(uiLoadedCallbacks);
-        }
-
-        executeCallbacks(uiUpdateCallbacks, m);
-        scheduleAfterUiUpdateCallbacks();
-        const newTab = get_uiCurrentTab();
-        if (newTab && (newTab !== uiCurrentTab)) {
-            uiCurrentTab = newTab;
-            executeCallbacks(uiTabChangeCallbacks);
-        }
-    });
-    mutationObserver.observe(gradioApp(), {childList: true, subtree: true});
-});
-
-/**
- * Add a ctrl+enter as a shortcut to start a generation
- */
-document.addEventListener('keydown', function(e) {
-    var handled = false;
-    if (e.key !== undefined) {
-        if ((e.key == "Enter" && (e.metaKey || e.ctrlKey || e.altKey))) handled = true;
-    } else if (e.keyCode !== undefined) {
-        if ((e.keyCode == 13 && (e.metaKey || e.ctrlKey || e.altKey))) handled = true;
-    }
-    if (handled) {
-        var button = get_uiCurrentTabContent().querySelector('button[id$=_generate]');
-        if (button) {
-            button.click();
-        }
-        e.preventDefault();
-    }
-});
-
-/**
- * checks that a UI element is not in another hidden element or tab content
- */
-function uiElementIsVisible(el) {
-    if (el === document) {
-        return true;
-    }
-
-    const computedStyle = getComputedStyle(el);
-    const isVisible = computedStyle.display !== 'none';
-
-    if (!isVisible) return false;
-    return uiElementIsVisible(el.parentNode);
-}
-
-function uiElementInSight(el) {
-    const clRect = el.getBoundingClientRect();
-    const windowHeight = window.innerHeight;
-    const isOnScreen = clRect.bottom > 0 && clRect.top < windowHeight;
-
-    return isOnScreen;
-}
+function gradioApp() {
+    const elems = document.getElementsByTagName('gradio-app');
+    const elem = elems.length == 0 ? document : elems[0];
+
+    if (elem !== document) {
+        elem.getElementById = function(id) {
+            return document.getElementById(id);
+        };
+    }
+    return elem.shadowRoot ? elem.shadowRoot : elem;
+}
+
+/**
+ * Get the currently selected top-level UI tab button (e.g. the button that says "Extras").
+ */
+function get_uiCurrentTab() {
+    return gradioApp().querySelector('#tabs > .tab-nav > button.selected');
+}
+
+/**
+ * Get the first currently visible top-level UI tab content (e.g. the div hosting the "txt2img" UI).
+ */
+function get_uiCurrentTabContent() {
+    return gradioApp().querySelector('#tabs > .tabitem[id^=tab_]:not([style*="display: none"])');
+}
+
+var uiUpdateCallbacks = [];
+var uiAfterUpdateCallbacks = [];
+var uiLoadedCallbacks = [];
+var uiTabChangeCallbacks = [];
+var optionsChangedCallbacks = [];
+var uiAfterUpdateTimeout = null;
+var uiCurrentTab = null;
+
+/**
+ * Register callback to be called at each UI update.
+ * The callback receives an array of MutationRecords as an argument.
+ */
+function onUiUpdate(callback) {
+    uiUpdateCallbacks.push(callback);
+}
+
+/**
+ * Register callback to be called soon after UI updates.
+ * The callback receives no arguments.
+ *
+ * This is preferred over `onUiUpdate` if you don't need
+ * access to the MutationRecords, as your function will
+ * not be called quite as often.
+ */
+function onAfterUiUpdate(callback) {
+    uiAfterUpdateCallbacks.push(callback);
+}
+
+/**
+ * Register callback to be called when the UI is loaded.
+ * The callback receives no arguments.
+ */
+function onUiLoaded(callback) {
+    uiLoadedCallbacks.push(callback);
+}
+
+/**
+ * Register callback to be called when the UI tab is changed.
+ * The callback receives no arguments.
+ */
+function onUiTabChange(callback) {
+    uiTabChangeCallbacks.push(callback);
+}
+
+/**
+ * Register callback to be called when the options are changed.
+ * The callback receives no arguments.
+ * @param callback
+ */
+function onOptionsChanged(callback) {
+    optionsChangedCallbacks.push(callback);
+}
+
+function executeCallbacks(queue, arg) {
+    for (const callback of queue) {
+        try {
+            callback(arg);
+        } catch (e) {
+            console.error("error running callback", callback, ":", e);
+        }
+    }
+}
+
+/**
+ * Schedule the execution of the callbacks registered with onAfterUiUpdate.
+ * The callbacks are executed after a short while, unless another call to this function
+ * is made before that time. IOW, the callbacks are executed only once, even
+ * when there are multiple mutations observed.
+ */
+function scheduleAfterUiUpdateCallbacks() {
+    clearTimeout(uiAfterUpdateTimeout);
+    uiAfterUpdateTimeout = setTimeout(function() {
+        executeCallbacks(uiAfterUpdateCallbacks);
+    }, 200);
+}
+
+var executedOnLoaded = false;
+
+document.addEventListener("DOMContentLoaded", function() {
+    var mutationObserver = new MutationObserver(function(m) {
+        if (!executedOnLoaded && gradioApp().querySelector('#txt2img_prompt')) {
+            executedOnLoaded = true;
+            executeCallbacks(uiLoadedCallbacks);
+        }
+
+        executeCallbacks(uiUpdateCallbacks, m);
+        scheduleAfterUiUpdateCallbacks();
+        const newTab = get_uiCurrentTab();
+        if (newTab && (newTab !== uiCurrentTab)) {
+            uiCurrentTab = newTab;
+            executeCallbacks(uiTabChangeCallbacks);
+        }
+    });
+    mutationObserver.observe(gradioApp(), {childList: true, subtree: true});
+});
+
+/**
+ * Add a Ctrl (Alt) + Enter as a shortcut to start / restart a generation
+ */
+document.addEventListener('keydown', (e) => {
+    const isEnter = e.key === 'Enter' || e.keyCode === 13
+    const isModifierKey = e.metaKey || e.ctrlKey || e.altKey
+
+    const interruptButton = get_uiCurrentTabContent().querySelector('button[id$=_interrupt]')
+    const generateButton = get_uiCurrentTabContent().querySelector('button[id$=_generate]')
+
+    if (isEnter && isModifierKey) {
+        if (interruptButton.style.display === 'block') {
+            interruptButton.click()
+            setTimeout(() => generateButton.click(), 500)
+        } else {
+            generateButton.click()
+        }
+        e.preventDefault()
+    }
+})
+
+/**
+ * checks that a UI element is not in another hidden element or tab content
+ */
+function uiElementIsVisible(el) {
+    if (el === document) {
+        return true;
+    }
+
+    const computedStyle = getComputedStyle(el);
+    const isVisible = computedStyle.display !== 'none';
+
+    if (!isVisible) return false;
+    return uiElementIsVisible(el.parentNode);
+}
+
+function uiElementInSight(el) {
+    const clRect = el.getBoundingClientRect();
+    const windowHeight = window.innerHeight;
+    const isOnScreen = clRect.bottom > 0 && clRect.top < windowHeight;
+
+    return isOnScreen;
+}