soinov commited on
Commit
a0dda07
·
verified ·
1 Parent(s): a34f3e3

Upload script.js with huggingface_hub

Browse files
Files changed (1) hide show
  1. script.js +199 -0
script.js ADDED
@@ -0,0 +1,199 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ function gradioApp() {
2
+ const elems = document.getElementsByTagName('gradio-app');
3
+ const elem = elems.length == 0 ? document : elems[0];
4
+
5
+ if (elem !== document) {
6
+ elem.getElementById = function(id) {
7
+ return document.getElementById(id);
8
+ };
9
+ }
10
+ return elem.shadowRoot ? elem.shadowRoot : elem;
11
+ }
12
+
13
+ /**
14
+ * Get the currently selected top-level UI tab button (e.g. the button that says "Extras").
15
+ */
16
+ function get_uiCurrentTab() {
17
+ return gradioApp().querySelector('#tabs > .tab-nav > button.selected');
18
+ }
19
+
20
+ /**
21
+ * Get the first currently visible top-level UI tab content (e.g. the div hosting the "txt2img" UI).
22
+ */
23
+ function get_uiCurrentTabContent() {
24
+ return gradioApp().querySelector('#tabs > .tabitem[id^=tab_]:not([style*="display: none"])');
25
+ }
26
+
27
+ var uiUpdateCallbacks = [];
28
+ var uiAfterUpdateCallbacks = [];
29
+ var uiLoadedCallbacks = [];
30
+ var uiTabChangeCallbacks = [];
31
+ var optionsChangedCallbacks = [];
32
+ var uiAfterUpdateTimeout = null;
33
+ var uiCurrentTab = null;
34
+
35
+ /**
36
+ * Register callback to be called at each UI update.
37
+ * The callback receives an array of MutationRecords as an argument.
38
+ */
39
+ function onUiUpdate(callback) {
40
+ uiUpdateCallbacks.push(callback);
41
+ }
42
+
43
+ /**
44
+ * Register callback to be called soon after UI updates.
45
+ * The callback receives no arguments.
46
+ *
47
+ * This is preferred over `onUiUpdate` if you don't need
48
+ * access to the MutationRecords, as your function will
49
+ * not be called quite as often.
50
+ */
51
+ function onAfterUiUpdate(callback) {
52
+ uiAfterUpdateCallbacks.push(callback);
53
+ }
54
+
55
+ /**
56
+ * Register callback to be called when the UI is loaded.
57
+ * The callback receives no arguments.
58
+ */
59
+ function onUiLoaded(callback) {
60
+ uiLoadedCallbacks.push(callback);
61
+ }
62
+
63
+ /**
64
+ * Register callback to be called when the UI tab is changed.
65
+ * The callback receives no arguments.
66
+ */
67
+ function onUiTabChange(callback) {
68
+ uiTabChangeCallbacks.push(callback);
69
+ }
70
+
71
+ /**
72
+ * Register callback to be called when the options are changed.
73
+ * The callback receives no arguments.
74
+ * @param callback
75
+ */
76
+ function onOptionsChanged(callback) {
77
+ optionsChangedCallbacks.push(callback);
78
+ }
79
+
80
+ function executeCallbacks(queue, arg) {
81
+ for (const callback of queue) {
82
+ try {
83
+ callback(arg);
84
+ } catch (e) {
85
+ console.error("error running callback", callback, ":", e);
86
+ }
87
+ }
88
+ }
89
+
90
+ /**
91
+ * Schedule the execution of the callbacks registered with onAfterUiUpdate.
92
+ * The callbacks are executed after a short while, unless another call to this function
93
+ * is made before that time. IOW, the callbacks are executed only once, even
94
+ * when there are multiple mutations observed.
95
+ */
96
+ function scheduleAfterUiUpdateCallbacks() {
97
+ clearTimeout(uiAfterUpdateTimeout);
98
+ uiAfterUpdateTimeout = setTimeout(function() {
99
+ executeCallbacks(uiAfterUpdateCallbacks);
100
+ }, 200);
101
+ }
102
+
103
+ var executedOnLoaded = false;
104
+
105
+ document.addEventListener("DOMContentLoaded", function() {
106
+ var mutationObserver = new MutationObserver(function(m) {
107
+ if (!executedOnLoaded && gradioApp().querySelector('#txt2img_prompt')) {
108
+ executedOnLoaded = true;
109
+ executeCallbacks(uiLoadedCallbacks);
110
+ }
111
+
112
+ executeCallbacks(uiUpdateCallbacks, m);
113
+ scheduleAfterUiUpdateCallbacks();
114
+ const newTab = get_uiCurrentTab();
115
+ if (newTab && (newTab !== uiCurrentTab)) {
116
+ uiCurrentTab = newTab;
117
+ executeCallbacks(uiTabChangeCallbacks);
118
+ }
119
+ });
120
+ mutationObserver.observe(gradioApp(), {childList: true, subtree: true});
121
+ });
122
+
123
+ /**
124
+ * Add keyboard shortcuts:
125
+ * Ctrl+Enter to start/restart a generation
126
+ * Alt/Option+Enter to skip a generation
127
+ * Esc to interrupt a generation
128
+ */
129
+ document.addEventListener('keydown', function(e) {
130
+ const isEnter = e.key === 'Enter' || e.keyCode === 13;
131
+ const isCtrlKey = e.metaKey || e.ctrlKey;
132
+ const isAltKey = e.altKey;
133
+ const isEsc = e.key === 'Escape';
134
+
135
+ const generateButton = get_uiCurrentTabContent().querySelector('button[id$=_generate]');
136
+ const interruptButton = get_uiCurrentTabContent().querySelector('button[id$=_interrupt]');
137
+ const skipButton = get_uiCurrentTabContent().querySelector('button[id$=_skip]');
138
+
139
+ if (isCtrlKey && isEnter) {
140
+ if (interruptButton.style.display === 'block') {
141
+ interruptButton.click();
142
+ const callback = (mutationList) => {
143
+ for (const mutation of mutationList) {
144
+ if (mutation.type === 'attributes' && mutation.attributeName === 'style') {
145
+ if (interruptButton.style.display === 'none') {
146
+ generateButton.click();
147
+ observer.disconnect();
148
+ }
149
+ }
150
+ }
151
+ };
152
+ const observer = new MutationObserver(callback);
153
+ observer.observe(interruptButton, {attributes: true});
154
+ } else {
155
+ generateButton.click();
156
+ }
157
+ e.preventDefault();
158
+ }
159
+
160
+ if (isAltKey && isEnter) {
161
+ skipButton.click();
162
+ e.preventDefault();
163
+ }
164
+
165
+ if (isEsc) {
166
+ const globalPopup = document.querySelector('.global-popup');
167
+ const lightboxModal = document.querySelector('#lightboxModal');
168
+ if (!globalPopup || globalPopup.style.display === 'none') {
169
+ if (document.activeElement === lightboxModal) return;
170
+ if (interruptButton.style.display === 'block') {
171
+ interruptButton.click();
172
+ e.preventDefault();
173
+ }
174
+ }
175
+ }
176
+ });
177
+
178
+ /**
179
+ * checks that a UI element is not in another hidden element or tab content
180
+ */
181
+ function uiElementIsVisible(el) {
182
+ if (el === document) {
183
+ return true;
184
+ }
185
+
186
+ const computedStyle = getComputedStyle(el);
187
+ const isVisible = computedStyle.display !== 'none';
188
+
189
+ if (!isVisible) return false;
190
+ return uiElementIsVisible(el.parentNode);
191
+ }
192
+
193
+ function uiElementInSight(el) {
194
+ const clRect = el.getBoundingClientRect();
195
+ const windowHeight = window.innerHeight;
196
+ const isOnScreen = clRect.bottom > 0 && clRect.top < windowHeight;
197
+
198
+ return isOnScreen;
199
+ }