From 13f4c62ba3870f172e6fdb26d4f33576f7f60f7e Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Wed, 17 May 2023 13:23:01 +0300 Subject: [PATCH 1/5] Add basic ESLint configuration for formatting This doesn't enable any of ESLint's actual possible-issue linting, but just style normalization based on the Prettier configuration (but without line length limits). --- .eslintignore | 4 ++++ .eslintrc.js | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ .gitignore | 2 ++ package.json | 11 +++++++++++ 4 files changed, 66 insertions(+) create mode 100644 .eslintignore create mode 100644 .eslintrc.js create mode 100644 package.json diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 000000000..1cfd94876 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,4 @@ +extensions +extensions-disabled +repositories +venv \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 000000000..48f9df7d4 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,49 @@ +module.exports = { + env: { + browser: true, + es2021: true, + }, + // "extends": "eslint:recommended", + parserOptions: { + ecmaVersion: "latest", + }, + rules: { + "arrow-spacing": "error", + "block-spacing": "error", + "brace-style": "error", + "comma-dangle": ["error", "only-multiline"], + "comma-spacing": "error", + "comma-style": ["error", "last"], + "curly": ["error", "multi-line", "consistent"], + "eol-last": "error", + "func-call-spacing": "error", + "function-call-argument-newline": ["error", "consistent"], + "function-paren-newline": ["error", "consistent"], + "indent": ["error", 4], + "key-spacing": "error", + "keyword-spacing": "error", + "linebreak-style": ["error", "unix"], + "no-extra-semi": "error", + "no-mixed-spaces-and-tabs": "error", + "no-trailing-spaces": "error", + "no-whitespace-before-property": "error", + "object-curly-newline": ["error", {consistent: true, multiline: true}], + "quote-props": ["error", "consistent-as-needed"], + "semi": ["error", "always"], + "semi-spacing": "error", + "semi-style": ["error", "last"], + "space-before-blocks": "error", + "space-before-function-paren": ["error", "never"], + "space-in-parens": ["error", "never"], + "space-infix-ops": "error", + "space-unary-ops": "error", + "switch-colon-spacing": "error", + "template-curly-spacing": ["error", "never"], + "unicode-bom": "error", + // "no-multi-spaces": "error", // TODO: enable? + // "object-curly-spacing": "off", // TODO: enable? + // "object-property-newline": "off", // TODO: enable? + // "operator-linebreak": "off", // TODO: enable? + // "quotes": ["error", "double", {avoidEscape: true}], // TODO: enable? + }, +}; diff --git a/.gitignore b/.gitignore index 7328401f5..46654d835 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,5 @@ notification.mp3 /test/stderr.txt /cache.json* /config_states/ +/node_modules +/package-lock.json \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 000000000..c0ba40678 --- /dev/null +++ b/package.json @@ -0,0 +1,11 @@ +{ + "name": "stable-diffusion-webui", + "version": "0.0.0", + "devDependencies": { + "eslint": "^8.40.0" + }, + "scripts": { + "lint": "eslint .", + "fix": "eslint --fix ." + } +} From 4f11f285f912fd48bc85a650a0384b6044d68b86 Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Wed, 17 May 2023 13:31:01 +0300 Subject: [PATCH 2/5] Add ESLint to CI --- .github/workflows/on_pull_request.yaml | 36 +++++++++----------------- 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/.github/workflows/on_pull_request.yaml b/.github/workflows/on_pull_request.yaml index d42965b15..7b7219fd6 100644 --- a/.github/workflows/on_pull_request.yaml +++ b/.github/workflows/on_pull_request.yaml @@ -1,19 +1,11 @@ -# See https://github.com/actions/starter-workflows/blob/1067f16ad8a1eac328834e4b0ae24f7d206f810d/ci/pylint.yml for original reference file name: Run Linting/Formatting on Pull Requests on: - push - pull_request - # See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#onpull_requestpull_request_targetbranchesbranches-ignore for syntax docs - # if you want to filter out branches, delete the `- pull_request` and uncomment these lines : - # pull_request: - # branches: - # - master - # branches-ignore: - # - development jobs: - lint: + lint-python: runs-on: ubuntu-latest steps: - name: Checkout Code @@ -29,18 +21,14 @@ jobs: run: pip install ruff==0.0.265 - name: Run Ruff run: ruff . - -# The rest are currently disabled pending fixing of e.g. installing the torch dependency. - -# - name: Install PyLint -# run: | -# python -m pip install --upgrade pip -# pip install pylint -# # This lets PyLint check to see if it can resolve imports -# - name: Install dependencies -# run: | -# export COMMANDLINE_ARGS="--skip-torch-cuda-test --exit" -# python launch.py -# - name: Analysing the code with pylint -# run: | -# pylint $(git ls-files '*.py') + lint-js: + runs-on: ubuntu-latest + steps: + - name: Checkout Code + uses: actions/checkout@v3 + - name: Install Node.js + uses: actions/setup-node@v3 + with: + node-version: 18 + - run: npm i --ci + - run: npm run lint From 9c54b78d9dde5601e916f308d9a9d6953ec39430 Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Wed, 17 May 2023 15:46:58 +0300 Subject: [PATCH 3/5] Run `eslint --fix` (and normalize tabs to spaces) --- .../javascript/prompt-bracket-checker.js | 52 +-- javascript/aspectRatioOverlay.js | 224 +++++----- javascript/contextMenus.js | 338 +++++++------- javascript/dragdrop.js | 47 +- javascript/edit-attention.js | 240 +++++----- javascript/extensions.js | 145 +++--- javascript/extraNetworks.js | 420 +++++++++--------- javascript/generationParams.js | 48 +- javascript/hints.js | 70 +-- javascript/hires_fix.js | 36 +- javascript/imageMaskFix.js | 20 +- javascript/imageParams.js | 4 +- javascript/imageviewer.js | 221 ++++----- javascript/imageviewerGamepad.js | 4 +- javascript/localization.js | 354 +++++++-------- javascript/notification.js | 12 +- javascript/progressbar.js | 176 ++++---- javascript/textualInversion.js | 34 +- javascript/ui.js | 413 ++++++++--------- javascript/ui_settings_hints.js | 124 +++--- script.js | 74 +-- 21 files changed, 1549 insertions(+), 1507 deletions(-) diff --git a/extensions-builtin/prompt-bracket-checker/javascript/prompt-bracket-checker.js b/extensions-builtin/prompt-bracket-checker/javascript/prompt-bracket-checker.js index 5c7a836a2..ed9baf9d0 100644 --- a/extensions-builtin/prompt-bracket-checker/javascript/prompt-bracket-checker.js +++ b/extensions-builtin/prompt-bracket-checker/javascript/prompt-bracket-checker.js @@ -4,39 +4,39 @@ // If there's a mismatch, the keyword counter turns red and if you hover on it, a tooltip tells you what's wrong. function checkBrackets(textArea, counterElt) { - var counts = {}; - (textArea.value.match(/[(){}\[\]]/g) || []).forEach(bracket => { - counts[bracket] = (counts[bracket] || 0) + 1; - }); - var errors = []; + var counts = {}; + (textArea.value.match(/[(){}\[\]]/g) || []).forEach(bracket => { + counts[bracket] = (counts[bracket] || 0) + 1; + }); + var errors = []; - function checkPair(open, close, kind) { - if (counts[open] !== counts[close]) { - errors.push( - `${open}...${close} - Detected ${counts[open] || 0} opening and ${counts[close] || 0} closing ${kind}.` - ); + function checkPair(open, close, kind) { + if (counts[open] !== counts[close]) { + errors.push( + `${open}...${close} - Detected ${counts[open] || 0} opening and ${counts[close] || 0} closing ${kind}.` + ); + } } - } - checkPair('(', ')', 'round brackets'); - checkPair('[', ']', 'square brackets'); - checkPair('{', '}', 'curly brackets'); - counterElt.title = errors.join('\n'); - counterElt.classList.toggle('error', errors.length !== 0); + checkPair('(', ')', 'round brackets'); + checkPair('[', ']', 'square brackets'); + checkPair('{', '}', 'curly brackets'); + counterElt.title = errors.join('\n'); + counterElt.classList.toggle('error', errors.length !== 0); } function setupBracketChecking(id_prompt, id_counter) { - var textarea = gradioApp().querySelector("#" + id_prompt + " > label > textarea"); - var counter = gradioApp().getElementById(id_counter) + var textarea = gradioApp().querySelector("#" + id_prompt + " > label > textarea"); + var counter = gradioApp().getElementById(id_counter); - if (textarea && counter) { - textarea.addEventListener("input", () => checkBrackets(textarea, counter)); - } + if (textarea && counter) { + textarea.addEventListener("input", () => checkBrackets(textarea, counter)); + } } -onUiLoaded(function () { - setupBracketChecking('txt2img_prompt', 'txt2img_token_counter'); - setupBracketChecking('txt2img_neg_prompt', 'txt2img_negative_token_counter'); - setupBracketChecking('img2img_prompt', 'img2img_token_counter'); - setupBracketChecking('img2img_neg_prompt', 'img2img_negative_token_counter'); +onUiLoaded(function() { + setupBracketChecking('txt2img_prompt', 'txt2img_token_counter'); + setupBracketChecking('txt2img_neg_prompt', 'txt2img_negative_token_counter'); + setupBracketChecking('img2img_prompt', 'img2img_token_counter'); + setupBracketChecking('img2img_neg_prompt', 'img2img_negative_token_counter'); }); diff --git a/javascript/aspectRatioOverlay.js b/javascript/aspectRatioOverlay.js index 5160081d2..059338d69 100644 --- a/javascript/aspectRatioOverlay.js +++ b/javascript/aspectRatioOverlay.js @@ -1,111 +1,113 @@ - -let currentWidth = null; -let currentHeight = null; -let arFrameTimeout = setTimeout(function(){},0); - -function dimensionChange(e, is_width, is_height){ - - if(is_width){ - currentWidth = e.target.value*1.0 - } - if(is_height){ - currentHeight = e.target.value*1.0 - } - - var inImg2img = gradioApp().querySelector("#tab_img2img").style.display == "block"; - - if(!inImg2img){ - return; - } - - var targetElement = null; - - var tabIndex = get_tab_index('mode_img2img') - if(tabIndex == 0){ // img2img - targetElement = gradioApp().querySelector('#img2img_image div[data-testid=image] img'); - } else if(tabIndex == 1){ //Sketch - targetElement = gradioApp().querySelector('#img2img_sketch div[data-testid=image] img'); - } else if(tabIndex == 2){ // Inpaint - targetElement = gradioApp().querySelector('#img2maskimg div[data-testid=image] img'); - } else if(tabIndex == 3){ // Inpaint sketch - targetElement = gradioApp().querySelector('#inpaint_sketch div[data-testid=image] img'); - } - - - if(targetElement){ - - var arPreviewRect = gradioApp().querySelector('#imageARPreview'); - if(!arPreviewRect){ - arPreviewRect = document.createElement('div') - arPreviewRect.id = "imageARPreview"; - gradioApp().appendChild(arPreviewRect) - } - - - - var viewportOffset = targetElement.getBoundingClientRect(); - - var viewportscale = Math.min( targetElement.clientWidth/targetElement.naturalWidth, targetElement.clientHeight/targetElement.naturalHeight ) - - var scaledx = targetElement.naturalWidth*viewportscale - var scaledy = targetElement.naturalHeight*viewportscale - - var cleintRectTop = (viewportOffset.top+window.scrollY) - var cleintRectLeft = (viewportOffset.left+window.scrollX) - var cleintRectCentreY = cleintRectTop + (targetElement.clientHeight/2) - var cleintRectCentreX = cleintRectLeft + (targetElement.clientWidth/2) - - var arscale = Math.min( scaledx/currentWidth, scaledy/currentHeight ) - var arscaledx = currentWidth*arscale - var arscaledy = currentHeight*arscale - - var arRectTop = cleintRectCentreY-(arscaledy/2) - var arRectLeft = cleintRectCentreX-(arscaledx/2) - var arRectWidth = arscaledx - var arRectHeight = arscaledy - - arPreviewRect.style.top = arRectTop+'px'; - arPreviewRect.style.left = arRectLeft+'px'; - arPreviewRect.style.width = arRectWidth+'px'; - arPreviewRect.style.height = arRectHeight+'px'; - - clearTimeout(arFrameTimeout); - arFrameTimeout = setTimeout(function(){ - arPreviewRect.style.display = 'none'; - },2000); - - arPreviewRect.style.display = 'block'; - - } - -} - - -onUiUpdate(function(){ - var arPreviewRect = gradioApp().querySelector('#imageARPreview'); - if(arPreviewRect){ - arPreviewRect.style.display = 'none'; - } - var tabImg2img = gradioApp().querySelector("#tab_img2img"); - if (tabImg2img) { - var inImg2img = tabImg2img.style.display == "block"; - if(inImg2img){ - let inputs = gradioApp().querySelectorAll('input'); - inputs.forEach(function(e){ - var is_width = e.parentElement.id == "img2img_width" - var is_height = e.parentElement.id == "img2img_height" - - if((is_width || is_height) && !e.classList.contains('scrollwatch')){ - e.addEventListener('input', function(e){dimensionChange(e, is_width, is_height)} ) - e.classList.add('scrollwatch') - } - if(is_width){ - currentWidth = e.value*1.0 - } - if(is_height){ - currentHeight = e.value*1.0 - } - }) - } - } -}); + +let currentWidth = null; +let currentHeight = null; +let arFrameTimeout = setTimeout(function() {}, 0); + +function dimensionChange(e, is_width, is_height) { + + if (is_width) { + currentWidth = e.target.value * 1.0; + } + if (is_height) { + currentHeight = e.target.value * 1.0; + } + + var inImg2img = gradioApp().querySelector("#tab_img2img").style.display == "block"; + + if (!inImg2img) { + return; + } + + var targetElement = null; + + var tabIndex = get_tab_index('mode_img2img'); + if (tabIndex == 0) { // img2img + targetElement = gradioApp().querySelector('#img2img_image div[data-testid=image] img'); + } else if (tabIndex == 1) { //Sketch + targetElement = gradioApp().querySelector('#img2img_sketch div[data-testid=image] img'); + } else if (tabIndex == 2) { // Inpaint + targetElement = gradioApp().querySelector('#img2maskimg div[data-testid=image] img'); + } else if (tabIndex == 3) { // Inpaint sketch + targetElement = gradioApp().querySelector('#inpaint_sketch div[data-testid=image] img'); + } + + + if (targetElement) { + + var arPreviewRect = gradioApp().querySelector('#imageARPreview'); + if (!arPreviewRect) { + arPreviewRect = document.createElement('div'); + arPreviewRect.id = "imageARPreview"; + gradioApp().appendChild(arPreviewRect); + } + + + + var viewportOffset = targetElement.getBoundingClientRect(); + + var viewportscale = Math.min(targetElement.clientWidth / targetElement.naturalWidth, targetElement.clientHeight / targetElement.naturalHeight); + + var scaledx = targetElement.naturalWidth * viewportscale; + var scaledy = targetElement.naturalHeight * viewportscale; + + var cleintRectTop = (viewportOffset.top + window.scrollY); + var cleintRectLeft = (viewportOffset.left + window.scrollX); + var cleintRectCentreY = cleintRectTop + (targetElement.clientHeight / 2); + var cleintRectCentreX = cleintRectLeft + (targetElement.clientWidth / 2); + + var arscale = Math.min(scaledx / currentWidth, scaledy / currentHeight); + var arscaledx = currentWidth * arscale; + var arscaledy = currentHeight * arscale; + + var arRectTop = cleintRectCentreY - (arscaledy / 2); + var arRectLeft = cleintRectCentreX - (arscaledx / 2); + var arRectWidth = arscaledx; + var arRectHeight = arscaledy; + + arPreviewRect.style.top = arRectTop + 'px'; + arPreviewRect.style.left = arRectLeft + 'px'; + arPreviewRect.style.width = arRectWidth + 'px'; + arPreviewRect.style.height = arRectHeight + 'px'; + + clearTimeout(arFrameTimeout); + arFrameTimeout = setTimeout(function() { + arPreviewRect.style.display = 'none'; + }, 2000); + + arPreviewRect.style.display = 'block'; + + } + +} + + +onUiUpdate(function() { + var arPreviewRect = gradioApp().querySelector('#imageARPreview'); + if (arPreviewRect) { + arPreviewRect.style.display = 'none'; + } + var tabImg2img = gradioApp().querySelector("#tab_img2img"); + if (tabImg2img) { + var inImg2img = tabImg2img.style.display == "block"; + if (inImg2img) { + let inputs = gradioApp().querySelectorAll('input'); + inputs.forEach(function(e) { + var is_width = e.parentElement.id == "img2img_width"; + var is_height = e.parentElement.id == "img2img_height"; + + if ((is_width || is_height) && !e.classList.contains('scrollwatch')) { + e.addEventListener('input', function(e) { + dimensionChange(e, is_width, is_height); + }); + e.classList.add('scrollwatch'); + } + if (is_width) { + currentWidth = e.value * 1.0; + } + if (is_height) { + currentHeight = e.value * 1.0; + } + }); + } + } +}); diff --git a/javascript/contextMenus.js b/javascript/contextMenus.js index b2bdf0532..f7a15cae1 100644 --- a/javascript/contextMenus.js +++ b/javascript/contextMenus.js @@ -1,166 +1,172 @@ - -contextMenuInit = function(){ - let eventListenerApplied=false; - let menuSpecs = new Map(); - - const uid = function(){ - return Date.now().toString(36) + Math.random().toString(36).substring(2); - } - - function showContextMenu(event,element,menuEntries){ - let posx = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; - let posy = event.clientY + document.body.scrollTop + document.documentElement.scrollTop; - - let oldMenu = gradioApp().querySelector('#context-menu') - if(oldMenu){ - oldMenu.remove() - } - - let baseStyle = window.getComputedStyle(uiCurrentTab) - - const contextMenu = document.createElement('nav') - contextMenu.id = "context-menu" - contextMenu.style.background = baseStyle.background - contextMenu.style.color = baseStyle.color - 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(function(entry){ - let contextMenuEntry = document.createElement('a') - contextMenuEntry.innerHTML = entry['name'] - contextMenuEntry.addEventListener("click", function() { - entry['func'](); - }) - contextMenuList.append(contextMenuEntry); - - }) - - gradioApp().appendChild(contextMenu) - - let menuWidth = contextMenu.offsetWidth + 4; - let menuHeight = contextMenu.offsetHeight + 4; - - let windowWidth = window.innerWidth; - let windowHeight = window.innerHeight; - - 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){ - - var currentItems = menuSpecs.get(targetElementSelector) - - if(!currentItems){ - currentItems = [] - menuSpecs.set(targetElementSelector,currentItems); - } - let newItem = {'id':targetElementSelector+'_'+uid(), - 'name':entryName, - 'func':entryFunction, - 'isNew':true} - - currentItems.push(newItem) - return newItem['id'] - } - - function removeContextMenuOption(uid){ - menuSpecs.forEach(function(v) { - let index = -1 - v.forEach(function(e,ei){if(e['id']==uid){index=ei}}) - if(index>=0){ - v.splice(index, 1); - } - }) - } - - function addContextMenuEventListener(){ - if(eventListenerApplied){ - return; - } - gradioApp().addEventListener("click", function(e) { - if(! e.isTrusted){ - return - } - - let oldMenu = gradioApp().querySelector('#context-menu') - if(oldMenu){ - oldMenu.remove() - } - }); - gradioApp().addEventListener("contextmenu", function(e) { - let oldMenu = gradioApp().querySelector('#context-menu') - if(oldMenu){ - oldMenu.remove() - } - menuSpecs.forEach(function(v,k) { - if(e.composedPath()[0].matches(k)){ - showContextMenu(e,e.composedPath()[0],v) - e.preventDefault() - } - }) - }); - eventListenerApplied=true - - } - - return [appendContextMenuOption, removeContextMenuOption, addContextMenuEventListener] -} - -initResponse = contextMenuInit(); -appendContextMenuOption = initResponse[0]; -removeContextMenuOption = initResponse[1]; -addContextMenuEventListener = initResponse[2]; - -(function(){ - //Start example Context Menu Items - let generateOnRepeat = function(genbuttonid,interruptbuttonid){ - let genbutton = gradioApp().querySelector(genbuttonid); - let interruptbutton = gradioApp().querySelector(interruptbuttonid); - if(!interruptbutton.offsetParent){ - genbutton.click(); - } - clearInterval(window.generateOnRepeatInterval) - window.generateOnRepeatInterval = setInterval(function(){ - if(!interruptbutton.offsetParent){ - genbutton.click(); - } - }, - 500) - } - - appendContextMenuOption('#txt2img_generate','Generate forever',function(){ - generateOnRepeat('#txt2img_generate','#txt2img_interrupt'); - }) - appendContextMenuOption('#img2img_generate','Generate forever',function(){ - generateOnRepeat('#img2img_generate','#img2img_interrupt'); - }) - - let cancelGenerateForever = function(){ - clearInterval(window.generateOnRepeatInterval) - } - - appendContextMenuOption('#txt2img_interrupt','Cancel generate forever',cancelGenerateForever) - appendContextMenuOption('#txt2img_generate', 'Cancel generate forever',cancelGenerateForever) - appendContextMenuOption('#img2img_interrupt','Cancel generate forever',cancelGenerateForever) - appendContextMenuOption('#img2img_generate', 'Cancel generate forever',cancelGenerateForever) - -})(); -//End example Context Menu Items - -onUiUpdate(function(){ - addContextMenuEventListener() -}); + +contextMenuInit = function() { + let eventListenerApplied = false; + let menuSpecs = new Map(); + + const uid = function() { + return Date.now().toString(36) + Math.random().toString(36).substring(2); + }; + + function showContextMenu(event, element, menuEntries) { + let posx = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; + let posy = event.clientY + document.body.scrollTop + document.documentElement.scrollTop; + + let oldMenu = gradioApp().querySelector('#context-menu'); + if (oldMenu) { + oldMenu.remove(); + } + + let baseStyle = window.getComputedStyle(uiCurrentTab); + + const contextMenu = document.createElement('nav'); + contextMenu.id = "context-menu"; + contextMenu.style.background = baseStyle.background; + contextMenu.style.color = baseStyle.color; + 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(function(entry) { + let contextMenuEntry = document.createElement('a'); + contextMenuEntry.innerHTML = entry['name']; + contextMenuEntry.addEventListener("click", function() { + entry['func'](); + }); + contextMenuList.append(contextMenuEntry); + + }); + + gradioApp().appendChild(contextMenu); + + let menuWidth = contextMenu.offsetWidth + 4; + let menuHeight = contextMenu.offsetHeight + 4; + + let windowWidth = window.innerWidth; + let windowHeight = window.innerHeight; + + 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) { + + var currentItems = menuSpecs.get(targetElementSelector); + + if (!currentItems) { + currentItems = []; + menuSpecs.set(targetElementSelector, currentItems); + } + let newItem = { + id: targetElementSelector + '_' + uid(), + name: entryName, + func: entryFunction, + isNew: true + }; + + currentItems.push(newItem); + return newItem['id']; + } + + function removeContextMenuOption(uid) { + menuSpecs.forEach(function(v) { + let index = -1; + v.forEach(function(e, ei) { + if (e['id'] == uid) { + index = ei; + } + }); + if (index >= 0) { + v.splice(index, 1); + } + }); + } + + function addContextMenuEventListener() { + if (eventListenerApplied) { + return; + } + gradioApp().addEventListener("click", function(e) { + if (!e.isTrusted) { + return; + } + + let oldMenu = gradioApp().querySelector('#context-menu'); + if (oldMenu) { + oldMenu.remove(); + } + }); + gradioApp().addEventListener("contextmenu", function(e) { + let oldMenu = gradioApp().querySelector('#context-menu'); + if (oldMenu) { + oldMenu.remove(); + } + menuSpecs.forEach(function(v, k) { + if (e.composedPath()[0].matches(k)) { + showContextMenu(e, e.composedPath()[0], v); + e.preventDefault(); + } + }); + }); + eventListenerApplied = true; + + } + + return [appendContextMenuOption, removeContextMenuOption, addContextMenuEventListener]; +}; + +initResponse = contextMenuInit(); +appendContextMenuOption = initResponse[0]; +removeContextMenuOption = initResponse[1]; +addContextMenuEventListener = initResponse[2]; + +(function() { + //Start example Context Menu Items + let generateOnRepeat = function(genbuttonid, interruptbuttonid) { + let genbutton = gradioApp().querySelector(genbuttonid); + let interruptbutton = gradioApp().querySelector(interruptbuttonid); + if (!interruptbutton.offsetParent) { + genbutton.click(); + } + clearInterval(window.generateOnRepeatInterval); + window.generateOnRepeatInterval = setInterval(function() { + if (!interruptbutton.offsetParent) { + genbutton.click(); + } + }, + 500); + }; + + appendContextMenuOption('#txt2img_generate', 'Generate forever', function() { + generateOnRepeat('#txt2img_generate', '#txt2img_interrupt'); + }); + appendContextMenuOption('#img2img_generate', 'Generate forever', function() { + generateOnRepeat('#img2img_generate', '#img2img_interrupt'); + }); + + let cancelGenerateForever = function() { + clearInterval(window.generateOnRepeatInterval); + }; + + appendContextMenuOption('#txt2img_interrupt', 'Cancel generate forever', cancelGenerateForever); + appendContextMenuOption('#txt2img_generate', 'Cancel generate forever', cancelGenerateForever); + appendContextMenuOption('#img2img_interrupt', 'Cancel generate forever', cancelGenerateForever); + appendContextMenuOption('#img2img_generate', 'Cancel generate forever', cancelGenerateForever); + +})(); +//End example Context Menu Items + +onUiUpdate(function() { + addContextMenuEventListener(); +}); diff --git a/javascript/dragdrop.js b/javascript/dragdrop.js index fe0089248..e316a3650 100644 --- a/javascript/dragdrop.js +++ b/javascript/dragdrop.js @@ -1,11 +1,11 @@ // allows drag-dropping files into gradio image elements, and also pasting images from clipboard -function isValidImageList( files ) { +function isValidImageList(files) { return files && files?.length === 1 && ['image/png', 'image/gif', 'image/jpeg'].includes(files[0].type); } -function dropReplaceImage( imgWrap, files ) { - if ( ! isValidImageList( files ) ) { +function dropReplaceImage(imgWrap, files) { + if (!isValidImageList(files)) { return; } @@ -14,44 +14,44 @@ function dropReplaceImage( imgWrap, files ) { imgWrap.querySelector('.modify-upload button + button, .touch-none + div button + button')?.click(); const callback = () => { const fileInput = imgWrap.querySelector('input[type="file"]'); - if ( fileInput ) { - if ( files.length === 0 ) { + if (fileInput) { + if (files.length === 0) { files = new DataTransfer(); files.items.add(tmpFile); fileInput.files = files.files; } else { fileInput.files = files; } - fileInput.dispatchEvent(new Event('change')); + fileInput.dispatchEvent(new Event('change')); } }; - - if ( imgWrap.closest('#pnginfo_image') ) { + + if (imgWrap.closest('#pnginfo_image')) { // special treatment for PNG Info tab, wait for fetch request to finish const oldFetch = window.fetch; - window.fetch = async (input, options) => { + window.fetch = async(input, options) => { const response = await oldFetch(input, options); - if ( 'api/predict/' === input ) { + if ('api/predict/' === input) { const content = await response.text(); window.fetch = oldFetch; - window.requestAnimationFrame( () => callback() ); + window.requestAnimationFrame(() => callback()); return new Response(content, { status: response.status, statusText: response.statusText, headers: response.headers - }) + }); } return response; - }; + }; } else { - window.requestAnimationFrame( () => callback() ); + window.requestAnimationFrame(() => callback()); } } 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 (!imgWrap && target.placeholder && target.placeholder.indexOf("Prompt") == -1) { return; } e.stopPropagation(); @@ -65,33 +65,34 @@ window.document.addEventListener('drop', e => { return; } const imgWrap = target.closest('[data-testid="image"]'); - if ( !imgWrap ) { + if (!imgWrap) { return; } e.stopPropagation(); e.preventDefault(); const files = e.dataTransfer.files; - dropReplaceImage( imgWrap, files ); + dropReplaceImage(imgWrap, files); }); window.addEventListener('paste', e => { const files = e.clipboardData.files; - if ( ! isValidImageList( files ) ) { + if (!isValidImageList(files)) { return; } const visibleImageFields = [...gradioApp().querySelectorAll('[data-testid="image"]')] .filter(el => uiElementIsVisible(el)); - if ( ! visibleImageFields.length ) { + if (!visibleImageFields.length) { return; } - + const firstFreeImageField = visibleImageFields .filter(el => el.querySelector('input[type=file]'))?.[0]; dropReplaceImage( firstFreeImageField ? - firstFreeImageField : - visibleImageFields[visibleImageFields.length - 1] - , files ); + firstFreeImageField : + visibleImageFields[visibleImageFields.length - 1] + , files + ); }); diff --git a/javascript/edit-attention.js b/javascript/edit-attention.js index d2c2f1905..fdf00b4d2 100644 --- a/javascript/edit-attention.js +++ b/javascript/edit-attention.js @@ -1,120 +1,120 @@ -function keyupEditAttention(event){ - let target = event.originalTarget || event.composedPath()[0]; - if (! target.matches("[id*='_toprow'] [id*='_prompt'] textarea")) return; - if (! (event.metaKey || event.ctrlKey)) return; - - let isPlus = event.key == "ArrowUp" - let isMinus = event.key == "ArrowDown" - if (!isPlus && !isMinus) return; - - let selectionStart = target.selectionStart; - let selectionEnd = target.selectionEnd; - let text = target.value; - - function selectCurrentParenthesisBlock(OPEN, CLOSE){ - if (selectionStart !== selectionEnd) return false; - - // Find opening parenthesis around current cursor - const before = text.substring(0, selectionStart); - let beforeParen = before.lastIndexOf(OPEN); - if (beforeParen == -1) return false; - let beforeParenClose = before.lastIndexOf(CLOSE); - while (beforeParenClose !== -1 && beforeParenClose > beforeParen) { - beforeParen = before.lastIndexOf(OPEN, beforeParen - 1); - beforeParenClose = before.lastIndexOf(CLOSE, beforeParenClose - 1); - } - - // Find closing parenthesis around current cursor - const after = text.substring(selectionStart); - let afterParen = after.indexOf(CLOSE); - if (afterParen == -1) return false; - let afterParenOpen = after.indexOf(OPEN); - while (afterParenOpen !== -1 && afterParen > afterParenOpen) { - afterParen = after.indexOf(CLOSE, afterParen + 1); - afterParenOpen = after.indexOf(OPEN, afterParenOpen + 1); - } - if (beforeParen === -1 || afterParen === -1) return false; - - // Set the selection to the text between the parenthesis - const parenContent = text.substring(beforeParen + 1, selectionStart + afterParen); - const lastColon = parenContent.lastIndexOf(":"); - selectionStart = beforeParen + 1; - selectionEnd = selectionStart + lastColon; - target.setSelectionRange(selectionStart, selectionEnd); - return true; - } - - function selectCurrentWord(){ - if (selectionStart !== selectionEnd) return false; - const delimiters = opts.keyedit_delimiters + " \r\n\t"; - - // seek backward until to find beggining - while (!delimiters.includes(text[selectionStart - 1]) && selectionStart > 0) { - selectionStart--; - } - - // seek forward to find end - while (!delimiters.includes(text[selectionEnd]) && selectionEnd < text.length) { - selectionEnd++; - } - - target.setSelectionRange(selectionStart, selectionEnd); - return true; - } - - // If the user hasn't selected anything, let's select their current parenthesis block or word - if (!selectCurrentParenthesisBlock('<', '>') && !selectCurrentParenthesisBlock('(', ')')) { - selectCurrentWord(); - } - - event.preventDefault(); - - var closeCharacter = ')' - var delta = opts.keyedit_precision_attention - - if (selectionStart > 0 && text[selectionStart - 1] == '<'){ - closeCharacter = '>' - delta = opts.keyedit_precision_extra - } else if (selectionStart == 0 || text[selectionStart - 1] != "(") { - - // do not include spaces at the end - while(selectionEnd > selectionStart && text[selectionEnd-1] == ' '){ - selectionEnd -= 1; - } - if(selectionStart == selectionEnd){ - return - } - - text = text.slice(0, selectionStart) + "(" + text.slice(selectionStart, selectionEnd) + ":1.0)" + text.slice(selectionEnd); - - selectionStart += 1; - selectionEnd += 1; - } - - var end = text.slice(selectionEnd + 1).indexOf(closeCharacter) + 1; - var weight = parseFloat(text.slice(selectionEnd + 1, selectionEnd + 1 + end)); - if (isNaN(weight)) return; - - weight += isPlus ? delta : -delta; - weight = parseFloat(weight.toPrecision(12)); - if(String(weight).length == 1) weight += ".0" - - if (closeCharacter == ')' && weight == 1) { - text = text.slice(0, selectionStart - 1) + text.slice(selectionStart, selectionEnd) + text.slice(selectionEnd + 5); - selectionStart--; - selectionEnd--; - } else { - text = text.slice(0, selectionEnd + 1) + weight + text.slice(selectionEnd + 1 + end - 1); - } - - target.focus(); - target.value = text; - target.selectionStart = selectionStart; - target.selectionEnd = selectionEnd; - - updateInput(target) -} - -addEventListener('keydown', (event) => { - keyupEditAttention(event); -}); +function keyupEditAttention(event) { + let target = event.originalTarget || event.composedPath()[0]; + if (!target.matches("[id*='_toprow'] [id*='_prompt'] textarea")) return; + if (!(event.metaKey || event.ctrlKey)) return; + + let isPlus = event.key == "ArrowUp"; + let isMinus = event.key == "ArrowDown"; + if (!isPlus && !isMinus) return; + + let selectionStart = target.selectionStart; + let selectionEnd = target.selectionEnd; + let text = target.value; + + function selectCurrentParenthesisBlock(OPEN, CLOSE) { + if (selectionStart !== selectionEnd) return false; + + // Find opening parenthesis around current cursor + const before = text.substring(0, selectionStart); + let beforeParen = before.lastIndexOf(OPEN); + if (beforeParen == -1) return false; + let beforeParenClose = before.lastIndexOf(CLOSE); + while (beforeParenClose !== -1 && beforeParenClose > beforeParen) { + beforeParen = before.lastIndexOf(OPEN, beforeParen - 1); + beforeParenClose = before.lastIndexOf(CLOSE, beforeParenClose - 1); + } + + // Find closing parenthesis around current cursor + const after = text.substring(selectionStart); + let afterParen = after.indexOf(CLOSE); + if (afterParen == -1) return false; + let afterParenOpen = after.indexOf(OPEN); + while (afterParenOpen !== -1 && afterParen > afterParenOpen) { + afterParen = after.indexOf(CLOSE, afterParen + 1); + afterParenOpen = after.indexOf(OPEN, afterParenOpen + 1); + } + if (beforeParen === -1 || afterParen === -1) return false; + + // Set the selection to the text between the parenthesis + const parenContent = text.substring(beforeParen + 1, selectionStart + afterParen); + const lastColon = parenContent.lastIndexOf(":"); + selectionStart = beforeParen + 1; + selectionEnd = selectionStart + lastColon; + target.setSelectionRange(selectionStart, selectionEnd); + return true; + } + + function selectCurrentWord() { + if (selectionStart !== selectionEnd) return false; + const delimiters = opts.keyedit_delimiters + " \r\n\t"; + + // seek backward until to find beggining + while (!delimiters.includes(text[selectionStart - 1]) && selectionStart > 0) { + selectionStart--; + } + + // seek forward to find end + while (!delimiters.includes(text[selectionEnd]) && selectionEnd < text.length) { + selectionEnd++; + } + + target.setSelectionRange(selectionStart, selectionEnd); + return true; + } + + // If the user hasn't selected anything, let's select their current parenthesis block or word + if (!selectCurrentParenthesisBlock('<', '>') && !selectCurrentParenthesisBlock('(', ')')) { + selectCurrentWord(); + } + + event.preventDefault(); + + var closeCharacter = ')'; + var delta = opts.keyedit_precision_attention; + + if (selectionStart > 0 && text[selectionStart - 1] == '<') { + closeCharacter = '>'; + delta = opts.keyedit_precision_extra; + } else if (selectionStart == 0 || text[selectionStart - 1] != "(") { + + // do not include spaces at the end + while (selectionEnd > selectionStart && text[selectionEnd - 1] == ' ') { + selectionEnd -= 1; + } + if (selectionStart == selectionEnd) { + return; + } + + text = text.slice(0, selectionStart) + "(" + text.slice(selectionStart, selectionEnd) + ":1.0)" + text.slice(selectionEnd); + + selectionStart += 1; + selectionEnd += 1; + } + + var end = text.slice(selectionEnd + 1).indexOf(closeCharacter) + 1; + var weight = parseFloat(text.slice(selectionEnd + 1, selectionEnd + 1 + end)); + if (isNaN(weight)) return; + + weight += isPlus ? delta : -delta; + weight = parseFloat(weight.toPrecision(12)); + if (String(weight).length == 1) weight += ".0"; + + if (closeCharacter == ')' && weight == 1) { + text = text.slice(0, selectionStart - 1) + text.slice(selectionStart, selectionEnd) + text.slice(selectionEnd + 5); + selectionStart--; + selectionEnd--; + } else { + text = text.slice(0, selectionEnd + 1) + weight + text.slice(selectionEnd + 1 + end - 1); + } + + target.focus(); + target.value = text; + target.selectionStart = selectionStart; + target.selectionEnd = selectionEnd; + + updateInput(target); +} + +addEventListener('keydown', (event) => { + keyupEditAttention(event); +}); diff --git a/javascript/extensions.js b/javascript/extensions.js index 2a2d2f8e7..efeaf3a5b 100644 --- a/javascript/extensions.js +++ b/javascript/extensions.js @@ -1,71 +1,74 @@ - -function extensions_apply(_disabled_list, _update_list, disable_all){ - var disable = [] - var update = [] - - gradioApp().querySelectorAll('#extensions input[type="checkbox"]').forEach(function(x){ - if(x.name.startsWith("enable_") && ! x.checked) - disable.push(x.name.substring(7)) - - if(x.name.startsWith("update_") && x.checked) - update.push(x.name.substring(7)) - }) - - restart_reload() - - return [JSON.stringify(disable), JSON.stringify(update), disable_all] -} - -function extensions_check(){ - var disable = [] - - gradioApp().querySelectorAll('#extensions input[type="checkbox"]').forEach(function(x){ - if(x.name.startsWith("enable_") && ! x.checked) - disable.push(x.name.substring(7)) - }) - - gradioApp().querySelectorAll('#extensions .extension_status').forEach(function(x){ - x.innerHTML = "Loading..." - }) - - - var id = randomId() - requestProgress(id, gradioApp().getElementById('extensions_installed_top'), null, function(){ - - }) - - return [id, JSON.stringify(disable)] -} - -function install_extension_from_index(button, url){ - button.disabled = "disabled" - button.value = "Installing..." - - var textarea = gradioApp().querySelector('#extension_to_install textarea') - textarea.value = url - updateInput(textarea) - - gradioApp().querySelector('#install_extension_button').click() -} - -function config_state_confirm_restore(_, config_state_name, config_restore_type) { - if (config_state_name == "Current") { - return [false, config_state_name, config_restore_type]; - } - let restored = ""; - if (config_restore_type == "extensions") { - restored = "all saved extension versions"; - } else if (config_restore_type == "webui") { - restored = "the webui version"; - } else { - restored = "the webui version and all saved extension versions"; - } - let confirmed = confirm("Are you sure you want to restore from this state?\nThis will reset " + restored + "."); - if (confirmed) { - restart_reload(); - gradioApp().querySelectorAll('#extensions .extension_status').forEach(function(x){ - x.innerHTML = "Loading..." - }) - } - return [confirmed, config_state_name, config_restore_type]; -} + +function extensions_apply(_disabled_list, _update_list, disable_all) { + var disable = []; + var update = []; + + gradioApp().querySelectorAll('#extensions input[type="checkbox"]').forEach(function(x) { + if (x.name.startsWith("enable_") && !x.checked) { + disable.push(x.name.substring(7)); + } + + if (x.name.startsWith("update_") && x.checked) { + update.push(x.name.substring(7)); + } + }); + + restart_reload(); + + return [JSON.stringify(disable), JSON.stringify(update), disable_all]; +} + +function extensions_check() { + var disable = []; + + gradioApp().querySelectorAll('#extensions input[type="checkbox"]').forEach(function(x) { + if (x.name.startsWith("enable_") && !x.checked) { + disable.push(x.name.substring(7)); + } + }); + + gradioApp().querySelectorAll('#extensions .extension_status').forEach(function(x) { + x.innerHTML = "Loading..."; + }); + + + var id = randomId(); + requestProgress(id, gradioApp().getElementById('extensions_installed_top'), null, function() { + + }); + + return [id, JSON.stringify(disable)]; +} + +function install_extension_from_index(button, url) { + button.disabled = "disabled"; + button.value = "Installing..."; + + var textarea = gradioApp().querySelector('#extension_to_install textarea'); + textarea.value = url; + updateInput(textarea); + + gradioApp().querySelector('#install_extension_button').click(); +} + +function config_state_confirm_restore(_, config_state_name, config_restore_type) { + if (config_state_name == "Current") { + return [false, config_state_name, config_restore_type]; + } + let restored = ""; + if (config_restore_type == "extensions") { + restored = "all saved extension versions"; + } else if (config_restore_type == "webui") { + restored = "the webui version"; + } else { + restored = "the webui version and all saved extension versions"; + } + let confirmed = confirm("Are you sure you want to restore from this state?\nThis will reset " + restored + "."); + if (confirmed) { + restart_reload(); + gradioApp().querySelectorAll('#extensions .extension_status').forEach(function(x) { + x.innerHTML = "Loading..."; + }); + } + return [confirmed, config_state_name, config_restore_type]; +} diff --git a/javascript/extraNetworks.js b/javascript/extraNetworks.js index 4d9a522cd..0c80fa74c 100644 --- a/javascript/extraNetworks.js +++ b/javascript/extraNetworks.js @@ -1,205 +1,215 @@ -function setupExtraNetworksForTab(tabname){ - gradioApp().querySelector('#'+tabname+'_extra_tabs').classList.add('extra-networks') - - var tabs = gradioApp().querySelector('#'+tabname+'_extra_tabs > div') - var search = gradioApp().querySelector('#'+tabname+'_extra_search textarea') - var refresh = gradioApp().getElementById(tabname+'_extra_refresh') - - search.classList.add('search') - tabs.appendChild(search) - tabs.appendChild(refresh) - - var applyFilter = function(){ - var searchTerm = search.value.toLowerCase() - - gradioApp().querySelectorAll('#'+tabname+'_extra_tabs div.card').forEach(function(elem){ - var searchOnly = elem.querySelector('.search_only') - var text = elem.querySelector('.name').textContent.toLowerCase() + " " + elem.querySelector('.search_term').textContent.toLowerCase() - - var visible = text.indexOf(searchTerm) != -1 - - if(searchOnly && searchTerm.length < 4){ - visible = false - } - - elem.style.display = visible ? "" : "none" - }) - } - - search.addEventListener("input", applyFilter); - applyFilter(); - - extraNetworksApplyFilter[tabname] = applyFilter; -} - -function applyExtraNetworkFilter(tabname){ - setTimeout(extraNetworksApplyFilter[tabname], 1); -} - -var extraNetworksApplyFilter = {} -var activePromptTextarea = {}; - -function setupExtraNetworks(){ - setupExtraNetworksForTab('txt2img') - setupExtraNetworksForTab('img2img') - - function registerPrompt(tabname, id){ - var textarea = gradioApp().querySelector("#" + id + " > label > textarea"); - - if (! activePromptTextarea[tabname]){ - activePromptTextarea[tabname] = textarea - } - - textarea.addEventListener("focus", function(){ - activePromptTextarea[tabname] = textarea; - }); - } - - registerPrompt('txt2img', 'txt2img_prompt') - registerPrompt('txt2img', 'txt2img_neg_prompt') - registerPrompt('img2img', 'img2img_prompt') - registerPrompt('img2img', 'img2img_neg_prompt') -} - -onUiLoaded(setupExtraNetworks) - -var re_extranet = /<([^:]+:[^:]+):[\d\.]+>/; -var re_extranet_g = /\s+<([^:]+:[^:]+):[\d\.]+>/g; - -function tryToRemoveExtraNetworkFromPrompt(textarea, text){ - var m = text.match(re_extranet) - var replaced = false - var newTextareaText - if(m) { - var partToSearch = m[1] - newTextareaText = textarea.value.replaceAll(re_extranet_g, function(found){ - m = found.match(re_extranet); - if(m[1] == partToSearch){ - replaced = true; - return "" - } - return found; - }) - } else { - newTextareaText = textarea.value.replaceAll(new RegExp(text, "g"), function(found){ - if(found == text) { - replaced = true; - return "" - } - return found; - }) - } - - if(replaced){ - textarea.value = newTextareaText - return true; - } - - return false -} - -function cardClicked(tabname, textToAdd, allowNegativePrompt){ - var textarea = allowNegativePrompt ? activePromptTextarea[tabname] : gradioApp().querySelector("#" + tabname + "_prompt > label > textarea") - - if(! tryToRemoveExtraNetworkFromPrompt(textarea, textToAdd)){ - textarea.value = textarea.value + opts.extra_networks_add_text_separator + textToAdd - } - - updateInput(textarea) -} - -function saveCardPreview(event, tabname, filename){ - var textarea = gradioApp().querySelector("#" + tabname + '_preview_filename > label > textarea') - var button = gradioApp().getElementById(tabname + '_save_preview') - - textarea.value = filename - updateInput(textarea) - - button.click() - - event.stopPropagation() - event.preventDefault() -} - -function extraNetworksSearchButton(tabs_id, event){ - var searchTextarea = gradioApp().querySelector("#" + tabs_id + ' > div > textarea') - var button = event.target - var text = button.classList.contains("search-all") ? "" : button.textContent.trim() - - searchTextarea.value = text - updateInput(searchTextarea) -} - -var globalPopup = null; -var globalPopupInner = null; -function popup(contents){ - if(! globalPopup){ - globalPopup = document.createElement('div') - globalPopup.onclick = function(){ globalPopup.style.display = "none"; }; - globalPopup.classList.add('global-popup'); - - var close = document.createElement('div') - close.classList.add('global-popup-close'); - close.onclick = function(){ globalPopup.style.display = "none"; }; - close.title = "Close"; - globalPopup.appendChild(close) - - globalPopupInner = document.createElement('div') - globalPopupInner.onclick = function(event){ event.stopPropagation(); return false; }; - globalPopupInner.classList.add('global-popup-inner'); - globalPopup.appendChild(globalPopupInner) - - gradioApp().appendChild(globalPopup); - } - - globalPopupInner.innerHTML = ''; - globalPopupInner.appendChild(contents); - - globalPopup.style.display = "flex"; -} - -function extraNetworksShowMetadata(text){ - var elem = document.createElement('pre') - elem.classList.add('popup-metadata'); - elem.textContent = text; - - popup(elem); -} - -function requestGet(url, data, handler, errorHandler){ - var xhr = new XMLHttpRequest(); - var args = Object.keys(data).map(function(k){ return encodeURIComponent(k) + '=' + encodeURIComponent(data[k]) }).join('&') - xhr.open("GET", url + "?" + args, true); - - 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() - } - } - }; - var js = JSON.stringify(data); - xhr.send(js); -} - -function extraNetworksRequestMetadata(event, extraPage, cardName){ - var showError = function(){ extraNetworksShowMetadata("there was an error getting metadata"); } - - requestGet("./sd_extra_networks/metadata", {"page": extraPage, "item": cardName}, function(data){ - if(data && data.metadata){ - extraNetworksShowMetadata(data.metadata) - } else{ - showError() - } - }, showError) - - event.stopPropagation() -} +function setupExtraNetworksForTab(tabname) { + gradioApp().querySelector('#' + tabname + '_extra_tabs').classList.add('extra-networks'); + + var tabs = gradioApp().querySelector('#' + tabname + '_extra_tabs > div'); + var search = gradioApp().querySelector('#' + tabname + '_extra_search textarea'); + var refresh = gradioApp().getElementById(tabname + '_extra_refresh'); + + search.classList.add('search'); + tabs.appendChild(search); + tabs.appendChild(refresh); + + var applyFilter = function() { + var searchTerm = search.value.toLowerCase(); + + gradioApp().querySelectorAll('#' + tabname + '_extra_tabs div.card').forEach(function(elem) { + var searchOnly = elem.querySelector('.search_only'); + var text = elem.querySelector('.name').textContent.toLowerCase() + " " + elem.querySelector('.search_term').textContent.toLowerCase(); + + var visible = text.indexOf(searchTerm) != -1; + + if (searchOnly && searchTerm.length < 4) { + visible = false; + } + + elem.style.display = visible ? "" : "none"; + }); + }; + + search.addEventListener("input", applyFilter); + applyFilter(); + + extraNetworksApplyFilter[tabname] = applyFilter; +} + +function applyExtraNetworkFilter(tabname) { + setTimeout(extraNetworksApplyFilter[tabname], 1); +} + +var extraNetworksApplyFilter = {}; +var activePromptTextarea = {}; + +function setupExtraNetworks() { + setupExtraNetworksForTab('txt2img'); + setupExtraNetworksForTab('img2img'); + + function registerPrompt(tabname, id) { + var textarea = gradioApp().querySelector("#" + id + " > label > textarea"); + + if (!activePromptTextarea[tabname]) { + activePromptTextarea[tabname] = textarea; + } + + textarea.addEventListener("focus", function() { + activePromptTextarea[tabname] = textarea; + }); + } + + registerPrompt('txt2img', 'txt2img_prompt'); + registerPrompt('txt2img', 'txt2img_neg_prompt'); + registerPrompt('img2img', 'img2img_prompt'); + registerPrompt('img2img', 'img2img_neg_prompt'); +} + +onUiLoaded(setupExtraNetworks); + +var re_extranet = /<([^:]+:[^:]+):[\d\.]+>/; +var re_extranet_g = /\s+<([^:]+:[^:]+):[\d\.]+>/g; + +function tryToRemoveExtraNetworkFromPrompt(textarea, text) { + var m = text.match(re_extranet); + var replaced = false; + var newTextareaText; + if (m) { + var partToSearch = m[1]; + newTextareaText = textarea.value.replaceAll(re_extranet_g, function(found) { + m = found.match(re_extranet); + if (m[1] == partToSearch) { + replaced = true; + return ""; + } + return found; + }); + } else { + newTextareaText = textarea.value.replaceAll(new RegExp(text, "g"), function(found) { + if (found == text) { + replaced = true; + return ""; + } + return found; + }); + } + + if (replaced) { + textarea.value = newTextareaText; + return true; + } + + return false; +} + +function cardClicked(tabname, textToAdd, allowNegativePrompt) { + var textarea = allowNegativePrompt ? activePromptTextarea[tabname] : gradioApp().querySelector("#" + tabname + "_prompt > label > textarea"); + + if (!tryToRemoveExtraNetworkFromPrompt(textarea, textToAdd)) { + textarea.value = textarea.value + opts.extra_networks_add_text_separator + textToAdd; + } + + updateInput(textarea); +} + +function saveCardPreview(event, tabname, filename) { + var textarea = gradioApp().querySelector("#" + tabname + '_preview_filename > label > textarea'); + var button = gradioApp().getElementById(tabname + '_save_preview'); + + textarea.value = filename; + updateInput(textarea); + + button.click(); + + event.stopPropagation(); + event.preventDefault(); +} + +function extraNetworksSearchButton(tabs_id, event) { + var searchTextarea = gradioApp().querySelector("#" + tabs_id + ' > div > textarea'); + var button = event.target; + var text = button.classList.contains("search-all") ? "" : button.textContent.trim(); + + searchTextarea.value = text; + updateInput(searchTextarea); +} + +var globalPopup = null; +var globalPopupInner = null; +function popup(contents) { + if (!globalPopup) { + globalPopup = document.createElement('div'); + globalPopup.onclick = function() { + globalPopup.style.display = "none"; + }; + globalPopup.classList.add('global-popup'); + + var close = document.createElement('div'); + close.classList.add('global-popup-close'); + close.onclick = function() { + globalPopup.style.display = "none"; + }; + close.title = "Close"; + globalPopup.appendChild(close); + + globalPopupInner = document.createElement('div'); + globalPopupInner.onclick = function(event) { + event.stopPropagation(); return false; + }; + globalPopupInner.classList.add('global-popup-inner'); + globalPopup.appendChild(globalPopupInner); + + gradioApp().appendChild(globalPopup); + } + + globalPopupInner.innerHTML = ''; + globalPopupInner.appendChild(contents); + + globalPopup.style.display = "flex"; +} + +function extraNetworksShowMetadata(text) { + var elem = document.createElement('pre'); + elem.classList.add('popup-metadata'); + elem.textContent = text; + + popup(elem); +} + +function requestGet(url, data, handler, errorHandler) { + var xhr = new XMLHttpRequest(); + var args = Object.keys(data).map(function(k) { + return encodeURIComponent(k) + '=' + encodeURIComponent(data[k]); + }).join('&'); + xhr.open("GET", url + "?" + args, true); + + 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(); + } + } + }; + var js = JSON.stringify(data); + xhr.send(js); +} + +function extraNetworksRequestMetadata(event, extraPage, cardName) { + var showError = function() { + extraNetworksShowMetadata("there was an error getting metadata"); + }; + + requestGet("./sd_extra_networks/metadata", {page: extraPage, item: cardName}, function(data) { + if (data && data.metadata) { + extraNetworksShowMetadata(data.metadata); + } else { + showError(); + } + }, showError); + + event.stopPropagation(); +} diff --git a/javascript/generationParams.js b/javascript/generationParams.js index ef64ee2e5..f9e84e706 100644 --- a/javascript/generationParams.js +++ b/javascript/generationParams.js @@ -1,33 +1,35 @@ // 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(){ - if (!txt2img_gallery) { - txt2img_gallery = attachGalleryListeners("txt2img") - } - if (!img2img_gallery) { - img2img_gallery = attachGalleryListeners("img2img") - } - if (!modal) { - modal = gradioApp().getElementById('lightboxModal') - modalObserver.observe(modal, { attributes : true, attributeFilter : ['style'] }); - } +onUiUpdate(function() { + if (!txt2img_gallery) { + txt2img_gallery = attachGalleryListeners("txt2img"); + } + if (!img2img_gallery) { + img2img_gallery = attachGalleryListeners("img2img"); + } + if (!modal) { + modal = gradioApp().getElementById('lightboxModal'); + modalObserver.observe(modal, { attributes: true, attributeFilter: ['style'] }); + } }); let modalObserver = new MutationObserver(function(mutations) { - mutations.forEach(function(mutationRecord) { - let selectedTab = gradioApp().querySelector('#tabs div button.selected')?.innerText - if (mutationRecord.target.style.display === 'none' && (selectedTab === 'txt2img' || selectedTab === 'img2img')) - gradioApp().getElementById(selectedTab+"_generation_info_button")?.click() - }); + mutations.forEach(function(mutationRecord) { + let selectedTab = gradioApp().querySelector('#tabs div button.selected')?.innerText; + if (mutationRecord.target.style.display === 'none' && (selectedTab === 'txt2img' || selectedTab === 'img2img')) { + gradioApp().getElementById(selectedTab + "_generation_info_button")?.click(); + } + }); }); function attachGalleryListeners(tab_name) { - var gallery = gradioApp().querySelector('#'+tab_name+'_gallery') - gallery?.addEventListener('click', () => gradioApp().getElementById(tab_name+"_generation_info_button").click()); - gallery?.addEventListener('keydown', (e) => { - if (e.keyCode == 37 || e.keyCode == 39) // left or right arrow - gradioApp().getElementById(tab_name+"_generation_info_button").click() - }); - return gallery; + var gallery = gradioApp().querySelector('#' + tab_name + '_gallery'); + gallery?.addEventListener('click', () => gradioApp().getElementById(tab_name + "_generation_info_button").click()); + gallery?.addEventListener('keydown', (e) => { + if (e.keyCode == 37 || e.keyCode == 39) { // left or right arrow + gradioApp().getElementById(tab_name + "_generation_info_button").click(); + } + }); + return gallery; } diff --git a/javascript/hints.js b/javascript/hints.js index 3746df99f..477b7d809 100644 --- a/javascript/hints.js +++ b/javascript/hints.js @@ -3,14 +3,14 @@ titles = { "Sampling steps": "How many times to improve the generated image iteratively; higher values take longer; very low values can produce bad results", "Sampling method": "Which algorithm to use to produce the image", - "GFPGAN": "Restore low quality faces using GFPGAN neural network", - "Euler a": "Euler Ancestral - very creative, each can get a completely different picture depending on step count, setting steps higher than 30-40 does not help", - "DDIM": "Denoising Diffusion Implicit Models - best at inpainting", - "UniPC": "Unified Predictor-Corrector Framework for Fast Sampling of Diffusion Models", - "DPM adaptive": "Ignores step count - uses a number of steps determined by the CFG and resolution", + "GFPGAN": "Restore low quality faces using GFPGAN neural network", + "Euler a": "Euler Ancestral - very creative, each can get a completely different picture depending on step count, setting steps higher than 30-40 does not help", + "DDIM": "Denoising Diffusion Implicit Models - best at inpainting", + "UniPC": "Unified Predictor-Corrector Framework for Fast Sampling of Diffusion Models", + "DPM adaptive": "Ignores step count - uses a number of steps determined by the CFG and resolution", - "Batch count": "How many batches of images to create (has no impact on generation performance or VRAM usage)", - "Batch size": "How many image to create in a single batch (increases generation performance at cost of higher VRAM usage)", + "Batch count": "How many batches of images to create (has no impact on generation performance or VRAM usage)", + "Batch size": "How many image to create in a single batch (increases generation performance at cost of higher VRAM usage)", "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", @@ -40,7 +40,7 @@ titles = { "Inpaint at full resolution": "Upscale masked region to target resolution, do inpainting, downscale back and paste into original image", "Denoising strength": "Determines how little respect the algorithm should have for image's content. At 0, nothing will change, and at 1 you'll get an unrelated image. With values below 1.0, processing will take less steps than the Sampling Steps slider specifies.", - + "Skip": "Stop processing current image and continue processing.", "Interrupt": "Stop processing images and return any results accumulated so far.", "Save": "Write image to a directory (default - log/images) and generation parameters into csv file.", @@ -96,7 +96,7 @@ titles = { "Add difference": "Result = A + (B - C) * M", "No interpolation": "Result = A", - "Initialization text": "If the number of tokens is more than the number of vectors, some may be skipped.\nLeave the textbox empty to start with zeroed out vectors", + "Initialization text": "If the number of tokens is more than the number of vectors, some may be skipped.\nLeave the textbox empty to start with zeroed out vectors", "Learning rate": "How fast should training go. Low values will take longer to train, high values may fail to converge (not generate accurate results) and/or may break the embedding (This has happened if you see Loss: nan in the training info textbox. If this happens, you need to manually restore your embedding from an older not-broken backup).\n\nYou can set a single numeric value, or multiple learning rates using the syntax:\n\n rate_1:max_steps_1, rate_2:max_steps_2, ...\n\nEG: 0.005:100, 1e-3:1000, 1e-5\n\nWill train with rate of 0.005 for first 100 steps, then 1e-3 until 1000 steps, then 1e-5 for all remaining steps.", "Clip skip": "Early stopping parameter for CLIP model; 1 is stop at last layer as usual, 2 is stop at penultimate layer, etc.", @@ -113,38 +113,38 @@ titles = { "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.", "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." -} +}; -onUiUpdate(function(){ - gradioApp().querySelectorAll('span, button, select, p').forEach(function(span){ - if (span.title) return; // already has a title +onUiUpdate(function() { + gradioApp().querySelectorAll('span, button, select, p').forEach(function(span) { + if (span.title) return; // already has a title - let tooltip = localization[titles[span.textContent]] || titles[span.textContent]; + let tooltip = localization[titles[span.textContent]] || titles[span.textContent]; - if(!tooltip){ - tooltip = localization[titles[span.value]] || titles[span.value]; - } + if (!tooltip) { + tooltip = localization[titles[span.value]] || titles[span.value]; + } - if(!tooltip){ - for (const c of span.classList) { - if (c in titles) { - tooltip = localization[titles[c]] || titles[c]; - break; - } - } - } + if (!tooltip) { + for (const c of span.classList) { + if (c in titles) { + tooltip = localization[titles[c]] || titles[c]; + break; + } + } + } - if(tooltip){ - span.title = tooltip; - } - }) + if (tooltip) { + span.title = tooltip; + } + }); - gradioApp().querySelectorAll('select').forEach(function(select){ - if (select.onchange != null) return; + gradioApp().querySelectorAll('select').forEach(function(select) { + if (select.onchange != null) return; - select.onchange = function(){ + select.onchange = function() { select.title = localization[titles[select.value]] || titles[select.value] || ""; - } - }) -}) + }; + }); +}); diff --git a/javascript/hires_fix.js b/javascript/hires_fix.js index 48196be40..0d04ab3b4 100644 --- a/javascript/hires_fix.js +++ b/javascript/hires_fix.js @@ -1,18 +1,18 @@ - -function onCalcResolutionHires(enable, width, height, hr_scale, hr_resize_x, hr_resize_y){ - function setInactive(elem, inactive){ - elem.classList.toggle('inactive', !!inactive) - } - - var hrUpscaleBy = gradioApp().getElementById('txt2img_hr_scale') - var hrResizeX = gradioApp().getElementById('txt2img_hr_resize_x') - var 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] -} + +function onCalcResolutionHires(enable, width, height, hr_scale, hr_resize_x, hr_resize_y) { + function setInactive(elem, inactive) { + elem.classList.toggle('inactive', !!inactive); + } + + var hrUpscaleBy = gradioApp().getElementById('txt2img_hr_scale'); + var hrResizeX = gradioApp().getElementById('txt2img_hr_resize_x'); + var 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]; +} diff --git a/javascript/imageMaskFix.js b/javascript/imageMaskFix.js index a612705d2..91a6377b5 100644 --- a/javascript/imageMaskFix.js +++ b/javascript/imageMaskFix.js @@ -4,17 +4,17 @@ */ function imageMaskResize() { const canvases = gradioApp().querySelectorAll('#img2maskimg .touch-none canvas'); - if ( ! canvases.length ) { - canvases_fixed = false; // TODO: this is unused..? - window.removeEventListener( 'resize', imageMaskResize ); - return; + if (!canvases.length) { + canvases_fixed = false; // TODO: this is unused..? + window.removeEventListener('resize', imageMaskResize); + return; } const wrapper = canvases[0].closest('.touch-none'); const previewImage = wrapper.previousElementSibling; - if ( ! previewImage.complete ) { - previewImage.addEventListener( 'load', imageMaskResize); + if (!previewImage.complete) { + previewImage.addEventListener('load', imageMaskResize); return; } @@ -24,15 +24,15 @@ function imageMaskResize() { const nh = previewImage.naturalHeight; const portrait = nh > nw; - const wW = Math.min(w, portrait ? h/nh*nw : w/nw*nw); - const wH = Math.min(h, portrait ? h/nh*nh : w/nw*nh); + const wW = Math.min(w, portrait ? h / nh * nw : w / nw * nw); + const wH = Math.min(h, portrait ? h / nh * nh : w / nw * nh); wrapper.style.width = `${wW}px`; wrapper.style.height = `${wH}px`; wrapper.style.left = `0px`; wrapper.style.top = `0px`; - canvases.forEach( c => { + canvases.forEach(c => { c.style.width = c.style.height = ''; c.style.maxWidth = '100%'; c.style.maxHeight = '100%'; @@ -41,4 +41,4 @@ function imageMaskResize() { } onUiUpdate(imageMaskResize); -window.addEventListener( 'resize', imageMaskResize); +window.addEventListener('resize', imageMaskResize); diff --git a/javascript/imageParams.js b/javascript/imageParams.js index 64aee93b7..057e2d392 100644 --- a/javascript/imageParams.js +++ b/javascript/imageParams.js @@ -1,4 +1,4 @@ -window.onload = (function(){ +window.onload = (function() { window.addEventListener('drop', e => { const target = e.composedPath()[0]; if (target.placeholder.indexOf("Prompt") == -1) return; @@ -10,7 +10,7 @@ window.onload = (function(){ const imgParent = gradioApp().getElementById(prompt_target); const files = e.dataTransfer.files; const fileInput = imgParent.querySelector('input[type="file"]'); - if ( fileInput ) { + if (fileInput) { fileInput.files = files; fileInput.dispatchEvent(new Event('change')); } diff --git a/javascript/imageviewer.js b/javascript/imageviewer.js index 32066ab8f..ecd123793 100644 --- a/javascript/imageviewer.js +++ b/javascript/imageviewer.js @@ -5,24 +5,24 @@ function closeModal() { function showModal(event) { const source = event.target || event.srcElement; - const modalImage = gradioApp().getElementById("modalImage") - const lb = gradioApp().getElementById("lightboxModal") - modalImage.src = source.src + const modalImage = gradioApp().getElementById("modalImage"); + const lb = gradioApp().getElementById("lightboxModal"); + modalImage.src = source.src; if (modalImage.style.display === 'none') { lb.style.setProperty('background-image', 'url(' + source.src + ')'); } lb.style.display = "flex"; - lb.focus() + lb.focus(); - const tabTxt2Img = gradioApp().getElementById("tab_txt2img") - const tabImg2Img = gradioApp().getElementById("tab_img2img") + const tabTxt2Img = gradioApp().getElementById("tab_txt2img"); + const tabImg2Img = gradioApp().getElementById("tab_img2img"); // show the save button in modal only on txt2img or img2img tabs if (tabTxt2Img.style.display != "none" || tabImg2Img.style.display != "none") { - gradioApp().getElementById("modal_save").style.display = "inline" + gradioApp().getElementById("modal_save").style.display = "inline"; } else { - gradioApp().getElementById("modal_save").style.display = "none" + gradioApp().getElementById("modal_save").style.display = "none"; } - event.stopPropagation() + event.stopPropagation(); } function negmod(n, m) { @@ -30,14 +30,14 @@ function negmod(n, m) { } function updateOnBackgroundChange() { - const modalImage = gradioApp().getElementById("modalImage") + const modalImage = gradioApp().getElementById("modalImage"); if (modalImage && modalImage.offsetParent) { let currentButton = selected_gallery_button(); if (currentButton?.children?.length > 0 && modalImage.src != currentButton.children[0].src) { modalImage.src = currentButton.children[0].src; if (modalImage.style.display === 'none') { - modal.style.setProperty('background-image', `url(${modalImage.src})`) + modal.style.setProperty('background-image', `url(${modalImage.src})`); } } } @@ -49,108 +49,109 @@ function modalImageSwitch(offset) { if (galleryButtons.length > 1) { var currentButton = selected_gallery_button(); - var result = -1 + var result = -1; galleryButtons.forEach(function(v, i) { if (v == currentButton) { - result = i + result = i; } - }) + }); if (result != -1) { - var nextButton = galleryButtons[negmod((result + offset), galleryButtons.length)] - nextButton.click() + var nextButton = galleryButtons[negmod((result + offset), galleryButtons.length)]; + nextButton.click(); const modalImage = gradioApp().getElementById("modalImage"); const modal = gradioApp().getElementById("lightboxModal"); modalImage.src = nextButton.children[0].src; if (modalImage.style.display === 'none') { - modal.style.setProperty('background-image', `url(${modalImage.src})`) + modal.style.setProperty('background-image', `url(${modalImage.src})`); } setTimeout(function() { - modal.focus() - }, 10) + modal.focus(); + }, 10); } } } -function saveImage(){ - const tabTxt2Img = gradioApp().getElementById("tab_txt2img") - const tabImg2Img = gradioApp().getElementById("tab_img2img") - const saveTxt2Img = "save_txt2img" - const saveImg2Img = "save_img2img" +function saveImage() { + const tabTxt2Img = gradioApp().getElementById("tab_txt2img"); + const tabImg2Img = gradioApp().getElementById("tab_img2img"); + const saveTxt2Img = "save_txt2img"; + const saveImg2Img = "save_img2img"; if (tabTxt2Img.style.display != "none") { - gradioApp().getElementById(saveTxt2Img).click() + gradioApp().getElementById(saveTxt2Img).click(); } else if (tabImg2Img.style.display != "none") { - gradioApp().getElementById(saveImg2Img).click() + gradioApp().getElementById(saveImg2Img).click(); } else { - console.error("missing implementation for saving modal of this type") + console.error("missing implementation for saving modal of this type"); } } function modalSaveImage(event) { - saveImage() - event.stopPropagation() + saveImage(); + event.stopPropagation(); } function modalNextImage(event) { - modalImageSwitch(1) - event.stopPropagation() + modalImageSwitch(1); + event.stopPropagation(); } function modalPrevImage(event) { - modalImageSwitch(-1) - event.stopPropagation() + modalImageSwitch(-1); + event.stopPropagation(); } function modalKeyHandler(event) { switch (event.key) { - case "s": - saveImage() - break; - case "ArrowLeft": - modalPrevImage(event) - break; - case "ArrowRight": - modalNextImage(event) - break; - case "Escape": - closeModal(); - break; + case "s": + saveImage(); + break; + case "ArrowLeft": + modalPrevImage(event); + break; + case "ArrowRight": + modalNextImage(event); + break; + case "Escape": + closeModal(); + break; } } function setupImageForLightbox(e) { - if (e.dataset.modded) - return; + if (e.dataset.modded) { + return; + } - e.dataset.modded = true; - e.style.cursor='pointer' - e.style.userSelect='none' + e.dataset.modded = true; + e.style.cursor = 'pointer'; + e.style.userSelect = 'none'; - var isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1 + var isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1; - // For Firefox, listening on click first switched to next image then shows the lightbox. - // If you know how to fix this without switching to mousedown event, please. - // For other browsers the event is click to make it possiblr to drag picture. - var event = isFirefox ? 'mousedown' : 'click' + // For Firefox, listening on click first switched to next image then shows the lightbox. + // If you know how to fix this without switching to mousedown event, please. + // For other browsers the event is click to make it possiblr to drag picture. + var event = isFirefox ? 'mousedown' : 'click'; - e.addEventListener(event, function (evt) { - if(!opts.js_modal_lightbox || evt.button != 0) return; + e.addEventListener(event, function(evt) { + if (!opts.js_modal_lightbox || evt.button != 0) return; - modalZoomSet(gradioApp().getElementById('modalImage'), opts.js_modal_lightbox_initially_zoomed) - evt.preventDefault() - showModal(evt) - }, true); + modalZoomSet(gradioApp().getElementById('modalImage'), opts.js_modal_lightbox_initially_zoomed); + evt.preventDefault(); + showModal(evt); + }, true); } function modalZoomSet(modalImage, enable) { - if(modalImage) modalImage.classList.toggle('modalImageFullscreen', !!enable); + if (modalImage) modalImage.classList.toggle('modalImageFullscreen', !!enable); } function modalZoomToggle(event) { var modalImage = gradioApp().getElementById("modalImage"); - modalZoomSet(modalImage, !modalImage.classList.contains('modalImageFullscreen')) - event.stopPropagation() + modalZoomSet(modalImage, !modalImage.classList.contains('modalImageFullscreen')); + event.stopPropagation(); } function modalTileImageToggle(event) { @@ -159,99 +160,99 @@ function modalTileImageToggle(event) { const isTiling = modalImage.style.display === 'none'; if (isTiling) { modalImage.style.display = 'block'; - modal.style.setProperty('background-image', 'none') + modal.style.setProperty('background-image', 'none'); } else { modalImage.style.display = 'none'; - modal.style.setProperty('background-image', `url(${modalImage.src})`) + modal.style.setProperty('background-image', `url(${modalImage.src})`); } - event.stopPropagation() + event.stopPropagation(); } function galleryImageHandler(e) { //if (e && e.parentElement.tagName == 'BUTTON') { - e.onclick = showGalleryImage; + e.onclick = showGalleryImage; //} } onUiUpdate(function() { - var fullImg_preview = gradioApp().querySelectorAll('.gradio-gallery > div > img') + var fullImg_preview = gradioApp().querySelectorAll('.gradio-gallery > div > img'); if (fullImg_preview != null) { fullImg_preview.forEach(setupImageForLightbox); } updateOnBackgroundChange(); -}) +}); document.addEventListener("DOMContentLoaded", function() { //const modalFragment = document.createDocumentFragment(); - const modal = document.createElement('div') + const modal = document.createElement('div'); modal.onclick = closeModal; modal.id = "lightboxModal"; - modal.tabIndex = 0 - modal.addEventListener('keydown', modalKeyHandler, true) + modal.tabIndex = 0; + modal.addEventListener('keydown', modalKeyHandler, true); - const modalControls = document.createElement('div') + const modalControls = document.createElement('div'); modalControls.className = 'modalControls gradio-container'; modal.append(modalControls); - const modalZoom = document.createElement('span') + const modalZoom = document.createElement('span'); modalZoom.className = 'modalZoom cursor'; - modalZoom.innerHTML = '⤡' - modalZoom.addEventListener('click', modalZoomToggle, true) + modalZoom.innerHTML = '⤡'; + modalZoom.addEventListener('click', modalZoomToggle, true); modalZoom.title = "Toggle zoomed view"; - modalControls.appendChild(modalZoom) + modalControls.appendChild(modalZoom); - const modalTileImage = document.createElement('span') + const modalTileImage = document.createElement('span'); modalTileImage.className = 'modalTileImage cursor'; - modalTileImage.innerHTML = '⊞' - modalTileImage.addEventListener('click', modalTileImageToggle, true) + modalTileImage.innerHTML = '⊞'; + modalTileImage.addEventListener('click', modalTileImageToggle, true); modalTileImage.title = "Preview tiling"; - modalControls.appendChild(modalTileImage) + modalControls.appendChild(modalTileImage); - const modalSave = document.createElement("span") - modalSave.className = "modalSave cursor" - modalSave.id = "modal_save" - modalSave.innerHTML = "🖫" - modalSave.addEventListener("click", modalSaveImage, true) - modalSave.title = "Save Image(s)" - modalControls.appendChild(modalSave) + const modalSave = document.createElement("span"); + modalSave.className = "modalSave cursor"; + modalSave.id = "modal_save"; + modalSave.innerHTML = "🖫"; + modalSave.addEventListener("click", modalSaveImage, true); + modalSave.title = "Save Image(s)"; + modalControls.appendChild(modalSave); - const modalClose = document.createElement('span') + const modalClose = document.createElement('span'); modalClose.className = 'modalClose cursor'; - modalClose.innerHTML = '×' + modalClose.innerHTML = '×'; modalClose.onclick = closeModal; modalClose.title = "Close image viewer"; - modalControls.appendChild(modalClose) + modalControls.appendChild(modalClose); - const modalImage = document.createElement('img') + const modalImage = document.createElement('img'); modalImage.id = 'modalImage'; modalImage.onclick = closeModal; - modalImage.tabIndex = 0 - modalImage.addEventListener('keydown', modalKeyHandler, true) - modal.appendChild(modalImage) + modalImage.tabIndex = 0; + modalImage.addEventListener('keydown', modalKeyHandler, true); + modal.appendChild(modalImage); - const modalPrev = document.createElement('a') + const modalPrev = document.createElement('a'); modalPrev.className = 'modalPrev'; - modalPrev.innerHTML = '❮' - modalPrev.tabIndex = 0 + modalPrev.innerHTML = '❮'; + modalPrev.tabIndex = 0; modalPrev.addEventListener('click', modalPrevImage, true); - modalPrev.addEventListener('keydown', modalKeyHandler, true) - modal.appendChild(modalPrev) + modalPrev.addEventListener('keydown', modalKeyHandler, true); + modal.appendChild(modalPrev); - const modalNext = document.createElement('a') + const modalNext = document.createElement('a'); modalNext.className = 'modalNext'; - modalNext.innerHTML = '❯' - modalNext.tabIndex = 0 + modalNext.innerHTML = '❯'; + modalNext.tabIndex = 0; modalNext.addEventListener('click', modalNextImage, true); - modalNext.addEventListener('keydown', modalKeyHandler, true) + modalNext.addEventListener('keydown', modalKeyHandler, true); - modal.appendChild(modalNext) + modal.appendChild(modalNext); try { - gradioApp().appendChild(modal); - } catch (e) { - gradioApp().body.appendChild(modal); - } + gradioApp().appendChild(modal); + } catch (e) { + gradioApp().body.appendChild(modal); + } document.body.appendChild(modal); diff --git a/javascript/imageviewerGamepad.js b/javascript/imageviewerGamepad.js index 6297a12bc..31d226dee 100644 --- a/javascript/imageviewerGamepad.js +++ b/javascript/imageviewerGamepad.js @@ -1,7 +1,7 @@ window.addEventListener('gamepadconnected', (e) => { const index = e.gamepad.index; let isWaiting = false; - setInterval(async () => { + setInterval(async() => { if (!opts.js_modal_lightbox_gamepad || isWaiting) return; const gamepad = navigator.getGamepads()[index]; const xValue = gamepad.axes[0]; @@ -14,7 +14,7 @@ window.addEventListener('gamepadconnected', (e) => { } if (isWaiting) { await sleepUntil(() => { - const xValue = navigator.getGamepads()[index].axes[0] + const xValue = navigator.getGamepads()[index].axes[0]; if (xValue < 0.3 && xValue > -0.3) { return true; } diff --git a/javascript/localization.js b/javascript/localization.js index 86e5ca67c..3d043a9ad 100644 --- a/javascript/localization.js +++ b/javascript/localization.js @@ -1,177 +1,177 @@ - -// localization = {} -- the dict with translations is created by the backend - -ignore_ids_for_localization={ - setting_sd_hypernetwork: 'OPTION', - setting_sd_model_checkpoint: 'OPTION', - setting_realesrgan_enabled_models: 'OPTION', - modelmerger_primary_model_name: 'OPTION', - modelmerger_secondary_model_name: 'OPTION', - modelmerger_tertiary_model_name: 'OPTION', - train_embedding: 'OPTION', - train_hypernetwork: 'OPTION', - txt2img_styles: 'OPTION', - img2img_styles: 'OPTION', - setting_random_artist_categories: 'SPAN', - setting_face_restoration_model: 'SPAN', - setting_realesrgan_enabled_models: 'SPAN', - extras_upscaler_1: 'SPAN', - extras_upscaler_2: 'SPAN', -} - -re_num = /^[\.\d]+$/ -re_emoji = /[\p{Extended_Pictographic}\u{1F3FB}-\u{1F3FF}\u{1F9B0}-\u{1F9B3}]/u - -original_lines = {} -translated_lines = {} - -function hasLocalization() { - return window.localization && Object.keys(window.localization).length > 0; -} - -function textNodesUnder(el){ - var n, a=[], walk=document.createTreeWalker(el,NodeFilter.SHOW_TEXT,null,false); - while(n=walk.nextNode()) a.push(n); - return a; -} - -function canBeTranslated(node, text){ - if(! text) return false; - if(! node.parentElement) return false; - - var parentType = node.parentElement.nodeName - if(parentType=='SCRIPT' || parentType=='STYLE' || parentType=='TEXTAREA') return false; - - if (parentType=='OPTION' || parentType=='SPAN'){ - var pnode = node - for(var level=0; level<4; level++){ - pnode = pnode.parentElement - if(! pnode) break; - - if(ignore_ids_for_localization[pnode.id] == parentType) return false; - } - } - - if(re_num.test(text)) return false; - if(re_emoji.test(text)) return false; - return true -} - -function getTranslation(text){ - if(! text) return undefined - - if(translated_lines[text] === undefined){ - original_lines[text] = 1 - } - - tl = localization[text] - if(tl !== undefined){ - translated_lines[tl] = 1 - } - - return tl -} - -function processTextNode(node){ - var text = node.textContent.trim() - - if(! canBeTranslated(node, text)) return - - tl = getTranslation(text) - if(tl !== undefined){ - node.textContent = tl - } -} - -function processNode(node){ - if(node.nodeType == 3){ - processTextNode(node) - return - } - - if(node.title){ - tl = getTranslation(node.title) - if(tl !== undefined){ - node.title = tl - } - } - - if(node.placeholder){ - tl = getTranslation(node.placeholder) - if(tl !== undefined){ - node.placeholder = tl - } - } - - textNodesUnder(node).forEach(function(node){ - processTextNode(node) - }) -} - -function dumpTranslations(){ - if(!hasLocalization()) { - // If we don't have any localization, - // we will not have traversed the app to find - // original_lines, so do that now. - processNode(gradioApp()); - } - var dumped = {} - if (localization.rtl) { - dumped.rtl = true; - } - - for (const text in original_lines) { - if(dumped[text] !== undefined) continue; - dumped[text] = localization[text] || text; - } - - return dumped; -} - -function download_localization() { - var text = JSON.stringify(dumpTranslations(), null, 4) - - var element = document.createElement('a'); - element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text)); - element.setAttribute('download', "localization.json"); - element.style.display = 'none'; - document.body.appendChild(element); - - element.click(); - - document.body.removeChild(element); -} - -document.addEventListener("DOMContentLoaded", function () { - if (!hasLocalization()) { - return; - } - - onUiUpdate(function (m) { - m.forEach(function (mutation) { - mutation.addedNodes.forEach(function (node) { - processNode(node) - }) - }); - }) - - processNode(gradioApp()) - - if (localization.rtl) { // if the language is from right to left, - (new MutationObserver((mutations, observer) => { // wait for the style to load - mutations.forEach(mutation => { - mutation.addedNodes.forEach(node => { - if (node.tagName === 'STYLE') { - observer.disconnect(); - - for (const x of node.sheet.rules) { // find all rtl media rules - if (Array.from(x.media || []).includes('rtl')) { - x.media.appendMedium('all'); // enable them - } - } - } - }) - }); - })).observe(gradioApp(), { childList: true }); - } -}) + +// localization = {} -- the dict with translations is created by the backend + +ignore_ids_for_localization = { + setting_sd_hypernetwork: 'OPTION', + setting_sd_model_checkpoint: 'OPTION', + setting_realesrgan_enabled_models: 'OPTION', + modelmerger_primary_model_name: 'OPTION', + modelmerger_secondary_model_name: 'OPTION', + modelmerger_tertiary_model_name: 'OPTION', + train_embedding: 'OPTION', + train_hypernetwork: 'OPTION', + txt2img_styles: 'OPTION', + img2img_styles: 'OPTION', + setting_random_artist_categories: 'SPAN', + setting_face_restoration_model: 'SPAN', + setting_realesrgan_enabled_models: 'SPAN', + extras_upscaler_1: 'SPAN', + extras_upscaler_2: 'SPAN', +}; + +re_num = /^[\.\d]+$/; +re_emoji = /[\p{Extended_Pictographic}\u{1F3FB}-\u{1F3FF}\u{1F9B0}-\u{1F9B3}]/u; + +original_lines = {}; +translated_lines = {}; + +function hasLocalization() { + return window.localization && Object.keys(window.localization).length > 0; +} + +function textNodesUnder(el) { + var n, a = [], walk = document.createTreeWalker(el, NodeFilter.SHOW_TEXT, null, false); + while (n = walk.nextNode()) a.push(n); + return a; +} + +function canBeTranslated(node, text) { + if (!text) return false; + if (!node.parentElement) return false; + + var parentType = node.parentElement.nodeName; + if (parentType == 'SCRIPT' || parentType == 'STYLE' || parentType == 'TEXTAREA') return false; + + if (parentType == 'OPTION' || parentType == 'SPAN') { + var pnode = node; + for (var level = 0; level < 4; level++) { + pnode = pnode.parentElement; + if (!pnode) break; + + if (ignore_ids_for_localization[pnode.id] == parentType) return false; + } + } + + if (re_num.test(text)) return false; + if (re_emoji.test(text)) return false; + return true; +} + +function getTranslation(text) { + if (!text) return undefined; + + if (translated_lines[text] === undefined) { + original_lines[text] = 1; + } + + tl = localization[text]; + if (tl !== undefined) { + translated_lines[tl] = 1; + } + + return tl; +} + +function processTextNode(node) { + var text = node.textContent.trim(); + + if (!canBeTranslated(node, text)) return; + + tl = getTranslation(text); + if (tl !== undefined) { + node.textContent = tl; + } +} + +function processNode(node) { + if (node.nodeType == 3) { + processTextNode(node); + return; + } + + if (node.title) { + tl = getTranslation(node.title); + if (tl !== undefined) { + node.title = tl; + } + } + + if (node.placeholder) { + tl = getTranslation(node.placeholder); + if (tl !== undefined) { + node.placeholder = tl; + } + } + + textNodesUnder(node).forEach(function(node) { + processTextNode(node); + }); +} + +function dumpTranslations() { + if (!hasLocalization()) { + // If we don't have any localization, + // we will not have traversed the app to find + // original_lines, so do that now. + processNode(gradioApp()); + } + var dumped = {}; + if (localization.rtl) { + dumped.rtl = true; + } + + for (const text in original_lines) { + if (dumped[text] !== undefined) continue; + dumped[text] = localization[text] || text; + } + + return dumped; +} + +function download_localization() { + var text = JSON.stringify(dumpTranslations(), null, 4); + + var element = document.createElement('a'); + element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text)); + element.setAttribute('download', "localization.json"); + element.style.display = 'none'; + document.body.appendChild(element); + + element.click(); + + document.body.removeChild(element); +} + +document.addEventListener("DOMContentLoaded", function() { + if (!hasLocalization()) { + return; + } + + onUiUpdate(function(m) { + m.forEach(function(mutation) { + mutation.addedNodes.forEach(function(node) { + processNode(node); + }); + }); + }); + + processNode(gradioApp()); + + if (localization.rtl) { // if the language is from right to left, + (new MutationObserver((mutations, observer) => { // wait for the style to load + mutations.forEach(mutation => { + mutation.addedNodes.forEach(node => { + if (node.tagName === 'STYLE') { + observer.disconnect(); + + for (const x of node.sheet.rules) { // find all rtl media rules + if (Array.from(x.media || []).includes('rtl')) { + x.media.appendMedium('all'); // enable them + } + } + } + }); + }); + })).observe(gradioApp(), { childList: true }); + } +}); diff --git a/javascript/notification.js b/javascript/notification.js index 83fce1f86..a68a76f25 100644 --- a/javascript/notification.js +++ b/javascript/notification.js @@ -4,14 +4,14 @@ let lastHeadImg = null; let notificationButton = null; -onUiUpdate(function(){ - if(notificationButton == null){ - notificationButton = gradioApp().getElementById('request_notifications') +onUiUpdate(function() { + if (notificationButton == null) { + notificationButton = gradioApp().getElementById('request_notifications'); - if(notificationButton != null){ + if (notificationButton != null) { notificationButton.addEventListener('click', () => { void Notification.requestPermission(); - },true); + }, true); } } @@ -42,7 +42,7 @@ onUiUpdate(function(){ } ); - notification.onclick = function(_){ + notification.onclick = function(_) { parent.focus(); this.close(); }; diff --git a/javascript/progressbar.js b/javascript/progressbar.js index 8d2c34924..cd273e480 100644 --- a/javascript/progressbar.js +++ b/javascript/progressbar.js @@ -1,29 +1,29 @@ // code related to showing and updating progressbar shown as the image is being made -function rememberGallerySelection(){ +function rememberGallerySelection() { } -function getGallerySelectedIndex(){ +function getGallerySelectedIndex() { } -function request(url, data, handler, errorHandler){ +function request(url, data, handler, errorHandler) { var xhr = new XMLHttpRequest(); xhr.open("POST", url, true); xhr.setRequestHeader("Content-Type", "application/json"); - xhr.onreadystatechange = function () { + xhr.onreadystatechange = function() { if (xhr.readyState === 4) { if (xhr.status === 200) { try { var js = JSON.parse(xhr.responseText); - handler(js) + handler(js); } catch (error) { console.error(error); - errorHandler() + errorHandler(); } - } else{ - errorHandler() + } else { + errorHandler(); } } }; @@ -31,147 +31,147 @@ function request(url, data, handler, errorHandler){ xhr.send(js); } -function pad2(x){ - return x<10 ? '0'+x : x +function pad2(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" +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"; } } -function setTitle(progress){ - var title = 'Stable Diffusion' +function setTitle(progress) { + var title = 'Stable Diffusion'; - if(opts.show_progress_in_title && progress){ + if (opts.show_progress_in_title && progress) { title = '[' + progress.trim() + '] ' + title; } - if(document.title != title){ + 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)+")" +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) + ")"; } // 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, onProgress, inactivityTimeout=40){ - var dateStart = new Date() - var wasEverActive = false - var parentProgressbar = progressbarContainer.parentNode - var parentGallery = gallery ? gallery.parentNode : null +function requestProgress(id_task, progressbarContainer, gallery, atEnd, onProgress, inactivityTimeout = 40) { + var dateStart = new Date(); + var wasEverActive = false; + var parentProgressbar = progressbarContainer.parentNode; + var parentGallery = gallery ? gallery.parentNode : null; - var divProgress = document.createElement('div') - divProgress.className='progressDiv' - divProgress.style.display = opts.show_progressbar ? "block" : "none" - var divInner = document.createElement('div') - divInner.className='progress' + var divProgress = document.createElement('div'); + divProgress.className = 'progressDiv'; + divProgress.style.display = opts.show_progressbar ? "block" : "none"; + var divInner = document.createElement('div'); + divInner.className = 'progress'; - divProgress.appendChild(divInner) - parentProgressbar.insertBefore(divProgress, progressbarContainer) + divProgress.appendChild(divInner); + parentProgressbar.insertBefore(divProgress, progressbarContainer); - if(parentGallery){ - var livePreview = document.createElement('div') - livePreview.className='livePreview' - parentGallery.insertBefore(livePreview, gallery) + if (parentGallery) { + var livePreview = document.createElement('div'); + livePreview.className = 'livePreview'; + parentGallery.insertBefore(livePreview, gallery); } - var removeProgressBar = function(){ - setTitle("") - parentProgressbar.removeChild(divProgress) - if(parentGallery) parentGallery.removeChild(livePreview) - atEnd() - } + var removeProgressBar = function() { + setTitle(""); + parentProgressbar.removeChild(divProgress); + if (parentGallery) parentGallery.removeChild(livePreview); + atEnd(); + }; - var fun = function(id_task, id_live_preview){ - request("./internal/progress", {"id_task": id_task, "id_live_preview": id_live_preview}, function(res){ - if(res.completed){ - removeProgressBar() - return + var fun = function(id_task, id_live_preview) { + request("./internal/progress", {id_task: id_task, id_live_preview: id_live_preview}, function(res) { + if (res.completed) { + removeProgressBar(); + return; } - var rect = progressbarContainer.getBoundingClientRect() + var rect = progressbarContainer.getBoundingClientRect(); - if(rect.width){ + if (rect.width) { divProgress.style.width = rect.width + "px"; } - let progressText = "" + let progressText = ""; - divInner.style.width = ((res.progress || 0) * 100.0) + '%' - divInner.style.background = res.progress ? "" : "transparent" + 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.progress > 0) { + progressText = ((res.progress || 0) * 100.0).toFixed(0) + '%'; } - if(res.eta){ - progressText += " ETA: " + formatTime(res.eta) + if (res.eta) { + progressText += " ETA: " + formatTime(res.eta); } - setTitle(progressText) + setTitle(progressText); - if(res.textinfo && res.textinfo.indexOf("\n") == -1){ - progressText = res.textinfo + " " + progressText + if (res.textinfo && res.textinfo.indexOf("\n") == -1) { + progressText = res.textinfo + " " + progressText; } - divInner.textContent = progressText + divInner.textContent = progressText; - var elapsedFromStart = (new Date() - dateStart) / 1000 + var elapsedFromStart = (new Date() - dateStart) / 1000; - if(res.active) wasEverActive = true; + if (res.active) wasEverActive = true; - if(! res.active && wasEverActive){ - removeProgressBar() - return + if (!res.active && wasEverActive) { + removeProgressBar(); + return; } - if(elapsedFromStart > inactivityTimeout && !res.queued && !res.active){ - removeProgressBar() - return + if (elapsedFromStart > inactivityTimeout && !res.queued && !res.active) { + 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" + 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) + livePreview.appendChild(img); + if (livePreview.childElementCount > 2) { + livePreview.removeChild(livePreview.firstElementChild); } - } + }; img.src = res.live_preview; } - if(onProgress){ - onProgress(res) + if (onProgress) { + onProgress(res); } setTimeout(() => { fun(id_task, res.id_live_preview); - }, opts.live_preview_refresh_period || 500) - }, function(){ - removeProgressBar() - }) - } + }, opts.live_preview_refresh_period || 500); + }, function() { + removeProgressBar(); + }); + }; - fun(id_task, 0) + fun(id_task, 0); } diff --git a/javascript/textualInversion.js b/javascript/textualInversion.js index 0354b860c..37e3d0756 100644 --- a/javascript/textualInversion.js +++ b/javascript/textualInversion.js @@ -1,17 +1,17 @@ - - - -function start_training_textual_inversion(){ - gradioApp().querySelector('#ti_error').innerHTML='' - - var id = randomId() - requestProgress(id, gradioApp().getElementById('ti_output'), gradioApp().getElementById('ti_gallery'), function(){}, function(progress){ - gradioApp().getElementById('ti_progress').innerHTML = progress.textinfo - }) - - var res = args_to_array(arguments) - - res[0] = id - - return res -} + + + +function start_training_textual_inversion() { + gradioApp().querySelector('#ti_error').innerHTML = ''; + + var id = randomId(); + requestProgress(id, gradioApp().getElementById('ti_output'), gradioApp().getElementById('ti_gallery'), function() {}, function(progress) { + gradioApp().getElementById('ti_progress').innerHTML = progress.textinfo; + }); + + var res = args_to_array(arguments); + + res[0] = id; + + return res; +} diff --git a/javascript/ui.js b/javascript/ui.js index ed9673d64..f4727ca3a 100644 --- a/javascript/ui.js +++ b/javascript/ui.js @@ -1,9 +1,9 @@ // various functions for interaction with ui.py not large enough to warrant putting them in separate files -function set_theme(theme){ - var gradioURL = window.location.href +function set_theme(theme) { + var gradioURL = window.location.href; if (!gradioURL.includes('?__theme=')) { - window.location.replace(gradioURL + '?__theme=' + theme); + window.location.replace(gradioURL + '?__theme=' + theme); } } @@ -14,7 +14,7 @@ function all_gallery_buttons() { if (elem.parentElement.offsetParent) { visibleGalleryButtons.push(elem); } - }) + }); return visibleGalleryButtons; } @@ -25,31 +25,35 @@ function selected_gallery_button() { if (elem.parentElement.offsetParent) { visibleCurrentButton = elem; } - }) + }); return visibleCurrentButton; } -function selected_gallery_index(){ +function selected_gallery_index() { var buttons = all_gallery_buttons(); var button = selected_gallery_button(); - var result = -1 - buttons.forEach(function(v, i){ if(v==button) { result = i } }) + var result = -1; + buttons.forEach(function(v, i) { + if (v == button) { + result = i; + } + }); - return result + return result; } -function extract_image_from_gallery(gallery){ - if (gallery.length == 0){ +function extract_image_from_gallery(gallery) { + if (gallery.length == 0) { return [null]; } - if (gallery.length == 1){ + if (gallery.length == 1) { return [gallery[0]]; } - var index = selected_gallery_index() + var index = selected_gallery_index(); - if (index < 0 || index >= gallery.length){ + if (index < 0 || index >= gallery.length) { // Use the first image in the gallery as the default index = 0; } @@ -57,248 +61,249 @@ function extract_image_from_gallery(gallery){ return [gallery[index]]; } -function args_to_array(args){ - var res = [] - for(var i=0;i label > textarea"); - if(counter.parentElement == prompt.parentElement){ - return + if (counter.parentElement == prompt.parentElement) { + return; } - prompt.parentElement.insertBefore(counter, prompt) - prompt.parentElement.style.position = "relative" + prompt.parentElement.insertBefore(counter, prompt); + prompt.parentElement.style.position = "relative"; - promptTokecountUpdateFuncs[id] = function(){ update_token_counter(id_button); } - textarea.addEventListener("input", promptTokecountUpdateFuncs[id]); + 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') + 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'); - var show_all_pages = gradioApp().getElementById('settings_show_all_pages') - var settings_tabs = gradioApp().querySelector('#settings div') - if(show_all_pages && settings_tabs){ - settings_tabs.appendChild(show_all_pages) - show_all_pages.onclick = function(){ - gradioApp().querySelectorAll('#settings > div').forEach(function(elem){ - if(elem.id == "settings_tab_licenses") + var show_all_pages = gradioApp().getElementById('settings_show_all_pages'); + var settings_tabs = gradioApp().querySelector('#settings div'); + if (show_all_pages && settings_tabs) { + settings_tabs.appendChild(show_all_pages); + show_all_pages.onclick = function() { + gradioApp().querySelectorAll('#settings > div').forEach(function(elem) { + if (elem.id == "settings_tab_licenses") { return; + } elem.style.display = "block"; - }) - } + }); + }; } -}) +}); -onOptionsChanged(function(){ - var elem = gradioApp().getElementById('sd_checkpoint_hash') - var sd_checkpoint_hash = opts.sd_checkpoint_hash || "" - var shorthash = sd_checkpoint_hash.substring(0,10) +onOptionsChanged(function() { + var elem = gradioApp().getElementById('sd_checkpoint_hash'); + var sd_checkpoint_hash = opts.sd_checkpoint_hash || ""; + var shorthash = sd_checkpoint_hash.substring(0, 10); - if(elem && elem.textContent != shorthash){ - elem.textContent = shorthash - elem.title = sd_checkpoint_hash - elem.href = "https://google.com/search?q=" + sd_checkpoint_hash - } -}) + if (elem && elem.textContent != shorthash) { + elem.textContent = shorthash; + elem.title = sd_checkpoint_hash; + elem.href = "https://google.com/search?q=" + sd_checkpoint_hash; + } +}); let txt2img_textarea, img2img_textarea = undefined; -let wait_time = 800 +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; + 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; + 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); + 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...

'; +function restart_reload() { + document.body.innerHTML = '

Reloading...

'; - var requestPing = function(){ - requestGet("./internal/ping", {}, function(data){ + var requestPing = function() { + requestGet("./internal/ping", {}, function(data) { location.reload(); - }, function(){ + }, function() { setTimeout(requestPing, 500); - }) - } + }); + }; setTimeout(requestPing, 2000); - return [] + return []; } // Simulate an `input` DOM event for Gradio Textbox component. Needed after you edit its contents in javascript, otherwise your edits // will only visible on web page and not sent to python. -function updateInput(target){ - let e = new Event("input", { bubbles: true }) - Object.defineProperty(e, "target", {value: target}) - target.dispatchEvent(e); +function updateInput(target) { + let e = new Event("input", { bubbles: true }); + Object.defineProperty(e, "target", {value: target}); + target.dispatchEvent(e); } var desiredCheckpointName = null; -function selectCheckpoint(name){ +function selectCheckpoint(name) { desiredCheckpointName = name; - gradioApp().getElementById('change_checkpoint').click() + gradioApp().getElementById('change_checkpoint').click(); } -function currentImg2imgSourceResolution(_, _, scaleBy){ - var img = gradioApp().querySelector('#mode_img2img > div[style="display: block;"] img') - return img ? [img.naturalWidth, img.naturalHeight, scaleBy] : [0, 0, scaleBy] +function currentImg2imgSourceResolution(_, _, scaleBy) { + var img = gradioApp().querySelector('#mode_img2img > div[style="display: block;"] img'); + return img ? [img.naturalWidth, img.naturalHeight, scaleBy] : [0, 0, scaleBy]; } -function updateImg2imgResizeToTextAfterChangingImage(){ +function updateImg2imgResizeToTextAfterChangingImage() { // At the time this is called from gradio, the image has no yet been replaced. // There may be a better solution, but this is simple and straightforward so I'm going with it. setTimeout(function() { - gradioApp().getElementById('img2img_update_resize_to').click() + gradioApp().getElementById('img2img_update_resize_to').click(); }, 500); - return [] + return []; } diff --git a/javascript/ui_settings_hints.js b/javascript/ui_settings_hints.js index 6d1933dc8..0db41b116 100644 --- a/javascript/ui_settings_hints.js +++ b/javascript/ui_settings_hints.js @@ -1,62 +1,62 @@ -// various hints and extra info for the settings tab - -settingsHintsSetup = false - -onOptionsChanged(function(){ - if(settingsHintsSetup) return - settingsHintsSetup = true - - gradioApp().querySelectorAll('#settings [id^=setting_]').forEach(function(div){ - var name = div.id.substr(8) - var commentBefore = opts._comments_before[name] - var commentAfter = opts._comments_after[name] - - if(! commentBefore && !commentAfter) return - - var span = null - if(div.classList.contains('gradio-checkbox')) span = div.querySelector('label span') - else if(div.classList.contains('gradio-checkboxgroup')) span = div.querySelector('span').firstChild - else if(div.classList.contains('gradio-radio')) span = div.querySelector('span').firstChild - else span = div.querySelector('label span').firstChild - - if(!span) return - - if(commentBefore){ - var comment = document.createElement('DIV') - comment.className = 'settings-comment' - comment.innerHTML = commentBefore - span.parentElement.insertBefore(document.createTextNode('\xa0'), span) - span.parentElement.insertBefore(comment, span) - span.parentElement.insertBefore(document.createTextNode('\xa0'), span) - } - if(commentAfter){ - var comment = document.createElement('DIV') - comment.className = 'settings-comment' - comment.innerHTML = commentAfter - span.parentElement.insertBefore(comment, span.nextSibling) - span.parentElement.insertBefore(document.createTextNode('\xa0'), span.nextSibling) - } - }) -}) - -function settingsHintsShowQuicksettings(){ - requestGet("./internal/quicksettings-hint", {}, function(data){ - var table = document.createElement('table') - table.className = 'settings-value-table' - - data.forEach(function(obj){ - var tr = document.createElement('tr') - var td = document.createElement('td') - td.textContent = obj.name - tr.appendChild(td) - - var td = document.createElement('td') - td.textContent = obj.label - tr.appendChild(td) - - table.appendChild(tr) - }) - - popup(table); - }) -} +// various hints and extra info for the settings tab + +settingsHintsSetup = false; + +onOptionsChanged(function() { + if (settingsHintsSetup) return; + settingsHintsSetup = true; + + gradioApp().querySelectorAll('#settings [id^=setting_]').forEach(function(div) { + var name = div.id.substr(8); + var commentBefore = opts._comments_before[name]; + var commentAfter = opts._comments_after[name]; + + if (!commentBefore && !commentAfter) return; + + var span = null; + if (div.classList.contains('gradio-checkbox')) span = div.querySelector('label span'); + else if (div.classList.contains('gradio-checkboxgroup')) span = div.querySelector('span').firstChild; + else if (div.classList.contains('gradio-radio')) span = div.querySelector('span').firstChild; + else span = div.querySelector('label span').firstChild; + + if (!span) return; + + if (commentBefore) { + var comment = document.createElement('DIV'); + comment.className = 'settings-comment'; + comment.innerHTML = commentBefore; + span.parentElement.insertBefore(document.createTextNode('\xa0'), span); + span.parentElement.insertBefore(comment, span); + span.parentElement.insertBefore(document.createTextNode('\xa0'), span); + } + if (commentAfter) { + var comment = document.createElement('DIV'); + comment.className = 'settings-comment'; + comment.innerHTML = commentAfter; + span.parentElement.insertBefore(comment, span.nextSibling); + span.parentElement.insertBefore(document.createTextNode('\xa0'), span.nextSibling); + } + }); +}); + +function settingsHintsShowQuicksettings() { + requestGet("./internal/quicksettings-hint", {}, function(data) { + var table = document.createElement('table'); + table.className = 'settings-value-table'; + + data.forEach(function(obj) { + var tr = document.createElement('tr'); + var td = document.createElement('td'); + td.textContent = obj.name; + tr.appendChild(td); + + var td = document.createElement('td'); + td.textContent = obj.label; + tr.appendChild(td); + + table.appendChild(tr); + }); + + popup(table); + }); +} diff --git a/script.js b/script.js index 03afe8445..f6a3883af 100644 --- a/script.js +++ b/script.js @@ -1,66 +1,72 @@ function gradioApp() { - const elems = document.getElementsByTagName('gradio-app') - const elem = elems.length == 0 ? document : elems[0] + 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 + if (elem !== document) { + elem.getElementById = function(id) { + return document.getElementById(id); + }; + } + return elem.shadowRoot ? elem.shadowRoot : elem; } function get_uiCurrentTab() { - return gradioApp().querySelector('#tabs button.selected') + return gradioApp().querySelector('#tabs button.selected'); } function get_uiCurrentTabContent() { - return gradioApp().querySelector('.tabitem[id^=tab_]:not([style*="display: none"])') + return gradioApp().querySelector('.tabitem[id^=tab_]:not([style*="display: none"])'); } -uiUpdateCallbacks = [] -uiLoadedCallbacks = [] -uiTabChangeCallbacks = [] -optionsChangedCallbacks = [] -let uiCurrentTab = null +uiUpdateCallbacks = []; +uiLoadedCallbacks = []; +uiTabChangeCallbacks = []; +optionsChangedCallbacks = []; +let uiCurrentTab = null; -function onUiUpdate(callback){ - uiUpdateCallbacks.push(callback) +function onUiUpdate(callback) { + uiUpdateCallbacks.push(callback); } -function onUiLoaded(callback){ - uiLoadedCallbacks.push(callback) +function onUiLoaded(callback) { + uiLoadedCallbacks.push(callback); } -function onUiTabChange(callback){ - uiTabChangeCallbacks.push(callback) +function onUiTabChange(callback) { + uiTabChangeCallbacks.push(callback); } -function onOptionsChanged(callback){ - optionsChangedCallbacks.push(callback) +function onOptionsChanged(callback) { + optionsChangedCallbacks.push(callback); } -function runCallback(x, m){ +function runCallback(x, m) { try { - x(m) + x(m); } catch (e) { (console.error || console.log).call(console, e.message, e); } } function executeCallbacks(queue, m) { - queue.forEach(function(x){runCallback(x, m)}) + queue.forEach(function(x) { + runCallback(x, m); + }); } var executedOnLoaded = false; document.addEventListener("DOMContentLoaded", function() { - var mutationObserver = new MutationObserver(function(m){ - if(!executedOnLoaded && gradioApp().querySelector('#txt2img_prompt')){ + var mutationObserver = new MutationObserver(function(m) { + if (!executedOnLoaded && gradioApp().querySelector('#txt2img_prompt')) { executedOnLoaded = true; executeCallbacks(uiLoadedCallbacks); } executeCallbacks(uiUpdateCallbacks, m); const newTab = get_uiCurrentTab(); - if ( newTab && ( newTab !== uiCurrentTab ) ) { + if (newTab && (newTab !== uiCurrentTab)) { uiCurrentTab = newTab; executeCallbacks(uiTabChangeCallbacks); } }); - mutationObserver.observe( gradioApp(), { childList:true, subtree:true }) + mutationObserver.observe(gradioApp(), { childList: true, subtree: true }); }); /** @@ -69,9 +75,9 @@ document.addEventListener("DOMContentLoaded", function() { document.addEventListener('keydown', function(e) { var handled = false; if (e.key !== undefined) { - if((e.key == "Enter" && (e.metaKey || e.ctrlKey || e.altKey))) handled = true; + 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 ((e.keyCode == 13 && (e.metaKey || e.ctrlKey || e.altKey))) handled = true; } if (handled) { button = get_uiCurrentTabContent().querySelector('button[id$=_generate]'); @@ -80,22 +86,22 @@ document.addEventListener('keydown', function(e) { } e.preventDefault(); } -}) +}); /** * checks that a UI element is not in another hidden element or tab content */ function uiElementIsVisible(el) { let isVisible = !el.closest('.\\!hidden'); - if ( ! isVisible ) { + if (!isVisible) { return false; } - while( isVisible = el.closest('.tabitem')?.style.display !== 'none' ) { - if ( ! isVisible ) { + while (isVisible = el.closest('.tabitem')?.style.display !== 'none') { + if (!isVisible) { return false; - } else if ( el.parentElement ) { - el = el.parentElement + } else if (el.parentElement) { + el = el.parentElement; } else { break; } From f88169a9e74066892221b6c8c74c85afb7c1fe57 Mon Sep 17 00:00:00 2001 From: AUTOMATIC <16777216c@gmail.com> Date: Thu, 18 May 2023 09:58:49 +0300 Subject: [PATCH 4/5] extend eslint config --- .eslintrc.js | 52 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 48f9df7d4..782755549 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -3,7 +3,7 @@ module.exports = { browser: true, es2021: true, }, - // "extends": "eslint:recommended", + extends: "eslint:recommended", parserOptions: { ecmaVersion: "latest", }, @@ -40,10 +40,50 @@ module.exports = { "switch-colon-spacing": "error", "template-curly-spacing": ["error", "never"], "unicode-bom": "error", - // "no-multi-spaces": "error", // TODO: enable? - // "object-curly-spacing": "off", // TODO: enable? - // "object-property-newline": "off", // TODO: enable? - // "operator-linebreak": "off", // TODO: enable? - // "quotes": ["error", "double", {avoidEscape: true}], // TODO: enable? + "no-multi-spaces": "error", + "object-curly-spacing": ["error", "never"], + "operator-linebreak": ["error", "after"], + "no-unused-vars": "off", + "no-redeclare": "off", }, + globals: { + // this file + module: "writable", + //script.js + gradioApp: "writable", + onUiLoaded: "writable", + onUiUpdate: "writable", + onOptionsChanged: "writable", + uiCurrentTab: "writable", + uiElementIsVisible: "writable", + executeCallbacks: "writable", + //ui.js + opts: "writable", + all_gallery_buttons: "writable", + selected_gallery_button: "writable", + selected_gallery_index: "writable", + args_to_array: "writable", + switch_to_txt2img: "writable", + switch_to_img2img_tab: "writable", + switch_to_img2img: "writable", + switch_to_sketch: "writable", + switch_to_inpaint: "writable", + switch_to_inpaint_sketch: "writable", + switch_to_extras: "writable", + get_tab_index: "writable", + create_submit_args: "writable", + restart_reload: "writable", + updateInput: "writable", + //extraNetworks.js + requestGet: "writable", + popup: "writable", + // from python + localization: "writable", + // progrssbar.js + randomId: "writable", + requestProgress: "writable", + // imageviewer.js + modalPrevImage: "writable", + modalNextImage: "writable", + } }; From 57b75f4a037658c1122aa092d1775ac52036b2cf Mon Sep 17 00:00:00 2001 From: AUTOMATIC <16777216c@gmail.com> Date: Thu, 18 May 2023 09:59:10 +0300 Subject: [PATCH 5/5] eslint related file edits --- .../javascript/prompt-bracket-checker.js | 2 +- javascript/aspectRatioOverlay.js | 14 ++++----- javascript/contextMenus.js | 10 +++---- javascript/extraNetworks.js | 4 +-- javascript/generationParams.js | 2 +- javascript/hints.js | 4 +-- javascript/imageMaskFix.js | 1 - javascript/imageviewer.js | 7 +---- javascript/localization.js | 29 +++++++++---------- javascript/progressbar.js | 4 +-- javascript/ui.js | 22 +++++--------- javascript/ui_settings_hints.js | 6 ++-- script.js | 16 +++++----- 13 files changed, 54 insertions(+), 67 deletions(-) diff --git a/extensions-builtin/prompt-bracket-checker/javascript/prompt-bracket-checker.js b/extensions-builtin/prompt-bracket-checker/javascript/prompt-bracket-checker.js index ed9baf9d0..114cf94cc 100644 --- a/extensions-builtin/prompt-bracket-checker/javascript/prompt-bracket-checker.js +++ b/extensions-builtin/prompt-bracket-checker/javascript/prompt-bracket-checker.js @@ -5,7 +5,7 @@ function checkBrackets(textArea, counterElt) { var counts = {}; - (textArea.value.match(/[(){}\[\]]/g) || []).forEach(bracket => { + (textArea.value.match(/[(){}[\]]/g) || []).forEach(bracket => { counts[bracket] = (counts[bracket] || 0) + 1; }); var errors = []; diff --git a/javascript/aspectRatioOverlay.js b/javascript/aspectRatioOverlay.js index 059338d69..1c08a1a97 100644 --- a/javascript/aspectRatioOverlay.js +++ b/javascript/aspectRatioOverlay.js @@ -50,21 +50,21 @@ function dimensionChange(e, is_width, is_height) { var scaledx = targetElement.naturalWidth * viewportscale; var scaledy = targetElement.naturalHeight * viewportscale; - var cleintRectTop = (viewportOffset.top + window.scrollY); - var cleintRectLeft = (viewportOffset.left + window.scrollX); - var cleintRectCentreY = cleintRectTop + (targetElement.clientHeight / 2); + var cleintRectTop = (viewportOffset.top + window.scrollY); + var cleintRectLeft = (viewportOffset.left + window.scrollX); + var cleintRectCentreY = cleintRectTop + (targetElement.clientHeight / 2); var cleintRectCentreX = cleintRectLeft + (targetElement.clientWidth / 2); var arscale = Math.min(scaledx / currentWidth, scaledy / currentHeight); var arscaledx = currentWidth * arscale; var arscaledy = currentHeight * arscale; - var arRectTop = cleintRectCentreY - (arscaledy / 2); - var arRectLeft = cleintRectCentreX - (arscaledx / 2); - var arRectWidth = arscaledx; + var arRectTop = cleintRectCentreY - (arscaledy / 2); + var arRectLeft = cleintRectCentreX - (arscaledx / 2); + var arRectWidth = arscaledx; var arRectHeight = arscaledy; - arPreviewRect.style.top = arRectTop + 'px'; + arPreviewRect.style.top = arRectTop + 'px'; arPreviewRect.style.left = arRectLeft + 'px'; arPreviewRect.style.width = arRectWidth + 'px'; arPreviewRect.style.height = arRectHeight + 'px'; diff --git a/javascript/contextMenus.js b/javascript/contextMenus.js index f7a15cae1..f14af1d42 100644 --- a/javascript/contextMenus.js +++ b/javascript/contextMenus.js @@ -1,5 +1,5 @@ -contextMenuInit = function() { +var contextMenuInit = function() { let eventListenerApplied = false; let menuSpecs = new Map(); @@ -126,10 +126,10 @@ contextMenuInit = function() { return [appendContextMenuOption, removeContextMenuOption, addContextMenuEventListener]; }; -initResponse = contextMenuInit(); -appendContextMenuOption = initResponse[0]; -removeContextMenuOption = initResponse[1]; -addContextMenuEventListener = initResponse[2]; +var initResponse = contextMenuInit(); +var appendContextMenuOption = initResponse[0]; +var removeContextMenuOption = initResponse[1]; +var addContextMenuEventListener = initResponse[2]; (function() { //Start example Context Menu Items diff --git a/javascript/extraNetworks.js b/javascript/extraNetworks.js index 0c80fa74c..aafe0a005 100644 --- a/javascript/extraNetworks.js +++ b/javascript/extraNetworks.js @@ -63,8 +63,8 @@ function setupExtraNetworks() { onUiLoaded(setupExtraNetworks); -var re_extranet = /<([^:]+:[^:]+):[\d\.]+>/; -var re_extranet_g = /\s+<([^:]+:[^:]+):[\d\.]+>/g; +var re_extranet = /<([^:]+:[^:]+):[\d.]+>/; +var re_extranet_g = /\s+<([^:]+:[^:]+):[\d.]+>/g; function tryToRemoveExtraNetworkFromPrompt(textarea, text) { var m = text.match(re_extranet); diff --git a/javascript/generationParams.js b/javascript/generationParams.js index f9e84e706..a877f8a54 100644 --- a/javascript/generationParams.js +++ b/javascript/generationParams.js @@ -10,7 +10,7 @@ onUiUpdate(function() { } if (!modal) { modal = gradioApp().getElementById('lightboxModal'); - modalObserver.observe(modal, { attributes: true, attributeFilter: ['style'] }); + modalObserver.observe(modal, {attributes: true, attributeFilter: ['style']}); } }); diff --git a/javascript/hints.js b/javascript/hints.js index 477b7d809..88e550eff 100644 --- a/javascript/hints.js +++ b/javascript/hints.js @@ -1,6 +1,6 @@ // mouseover tooltips for various UI elements -titles = { +var titles = { "Sampling steps": "How many times to improve the generated image iteratively; higher values take longer; very low values can produce bad results", "Sampling method": "Which algorithm to use to produce the image", "GFPGAN": "Restore low quality faces using GFPGAN neural network", @@ -118,7 +118,7 @@ titles = { onUiUpdate(function() { gradioApp().querySelectorAll('span, button, select, p').forEach(function(span) { - if (span.title) return; // already has a title + if (span.title) return; // already has a title let tooltip = localization[titles[span.textContent]] || titles[span.textContent]; diff --git a/javascript/imageMaskFix.js b/javascript/imageMaskFix.js index 91a6377b5..3c9b8a6fd 100644 --- a/javascript/imageMaskFix.js +++ b/javascript/imageMaskFix.js @@ -5,7 +5,6 @@ function imageMaskResize() { const canvases = gradioApp().querySelectorAll('#img2maskimg .touch-none canvas'); if (!canvases.length) { - canvases_fixed = false; // TODO: this is unused..? window.removeEventListener('resize', imageMaskResize); return; } diff --git a/javascript/imageviewer.js b/javascript/imageviewer.js index ecd123793..78e24eb9e 100644 --- a/javascript/imageviewer.js +++ b/javascript/imageviewer.js @@ -37,6 +37,7 @@ function updateOnBackgroundChange() { if (currentButton?.children?.length > 0 && modalImage.src != currentButton.children[0].src) { modalImage.src = currentButton.children[0].src; if (modalImage.style.display === 'none') { + const modal = gradioApp().getElementById("lightboxModal"); modal.style.setProperty('background-image', `url(${modalImage.src})`); } } @@ -169,12 +170,6 @@ function modalTileImageToggle(event) { event.stopPropagation(); } -function galleryImageHandler(e) { - //if (e && e.parentElement.tagName == 'BUTTON') { - e.onclick = showGalleryImage; - //} -} - onUiUpdate(function() { var fullImg_preview = gradioApp().querySelectorAll('.gradio-gallery > div > img'); if (fullImg_preview != null) { diff --git a/javascript/localization.js b/javascript/localization.js index 3d043a9ad..eb22b8a7e 100644 --- a/javascript/localization.js +++ b/javascript/localization.js @@ -1,10 +1,9 @@ // localization = {} -- the dict with translations is created by the backend -ignore_ids_for_localization = { +var ignore_ids_for_localization = { setting_sd_hypernetwork: 'OPTION', setting_sd_model_checkpoint: 'OPTION', - setting_realesrgan_enabled_models: 'OPTION', modelmerger_primary_model_name: 'OPTION', modelmerger_secondary_model_name: 'OPTION', modelmerger_tertiary_model_name: 'OPTION', @@ -19,11 +18,11 @@ ignore_ids_for_localization = { extras_upscaler_2: 'SPAN', }; -re_num = /^[\.\d]+$/; -re_emoji = /[\p{Extended_Pictographic}\u{1F3FB}-\u{1F3FF}\u{1F9B0}-\u{1F9B3}]/u; +var re_num = /^[.\d]+$/; +var re_emoji = /[\p{Extended_Pictographic}\u{1F3FB}-\u{1F3FF}\u{1F9B0}-\u{1F9B3}]/u; -original_lines = {}; -translated_lines = {}; +var original_lines = {}; +var translated_lines = {}; function hasLocalization() { return window.localization && Object.keys(window.localization).length > 0; @@ -31,7 +30,7 @@ function hasLocalization() { function textNodesUnder(el) { var n, a = [], walk = document.createTreeWalker(el, NodeFilter.SHOW_TEXT, null, false); - while (n = walk.nextNode()) a.push(n); + while ((n = walk.nextNode())) a.push(n); return a; } @@ -64,7 +63,7 @@ function getTranslation(text) { original_lines[text] = 1; } - tl = localization[text]; + var tl = localization[text]; if (tl !== undefined) { translated_lines[tl] = 1; } @@ -77,7 +76,7 @@ function processTextNode(node) { if (!canBeTranslated(node, text)) return; - tl = getTranslation(text); + var tl = getTranslation(text); if (tl !== undefined) { node.textContent = tl; } @@ -90,14 +89,14 @@ function processNode(node) { } if (node.title) { - tl = getTranslation(node.title); + let tl = getTranslation(node.title); if (tl !== undefined) { node.title = tl; } } if (node.placeholder) { - tl = getTranslation(node.placeholder); + let tl = getTranslation(node.placeholder); if (tl !== undefined) { node.placeholder = tl; } @@ -157,21 +156,21 @@ document.addEventListener("DOMContentLoaded", function() { processNode(gradioApp()); - if (localization.rtl) { // if the language is from right to left, + if (localization.rtl) { // if the language is from right to left, (new MutationObserver((mutations, observer) => { // wait for the style to load mutations.forEach(mutation => { mutation.addedNodes.forEach(node => { if (node.tagName === 'STYLE') { observer.disconnect(); - for (const x of node.sheet.rules) { // find all rtl media rules + for (const x of node.sheet.rules) { // find all rtl media rules if (Array.from(x.media || []).includes('rtl')) { - x.media.appendMedium('all'); // enable them + x.media.appendMedium('all'); // enable them } } } }); }); - })).observe(gradioApp(), { childList: true }); + })).observe(gradioApp(), {childList: true}); } }); diff --git a/javascript/progressbar.js b/javascript/progressbar.js index cd273e480..29299787e 100644 --- a/javascript/progressbar.js +++ b/javascript/progressbar.js @@ -53,7 +53,7 @@ function setTitle(progress) { } if (document.title != title) { - document.title = title; + document.title = title; } } @@ -144,7 +144,7 @@ function requestProgress(id_task, progressbarContainer, gallery, atEnd, onProgre if (res.live_preview && gallery) { - var rect = gallery.getBoundingClientRect(); + rect = gallery.getBoundingClientRect(); if (rect.width) { livePreview.style.width = rect.width + "px"; livePreview.style.height = rect.height + "px"; diff --git a/javascript/ui.js b/javascript/ui.js index f4727ca3a..133d6ff3d 100644 --- a/javascript/ui.js +++ b/javascript/ui.js @@ -99,13 +99,6 @@ function switch_to_inpaint_sketch() { return args_to_array(arguments); } -function switch_to_inpaint() { - gradioApp().querySelector('#tabs').querySelectorAll('button')[1].click(); - gradioApp().getElementById('mode_img2img').querySelectorAll('button')[2].click(); - - return args_to_array(arguments); -} - function switch_to_extras() { gradioApp().querySelector('#tabs').querySelectorAll('button')[2].click(); @@ -172,7 +165,6 @@ function showRestoreProgressButton(tabname, show) { } function submit() { - rememberGallerySelection('txt2img_gallery'); showSubmitButtons('txt2img', false); var id = randomId(); @@ -192,7 +184,6 @@ function submit() { } function submit_img2img() { - rememberGallerySelection('img2img_gallery'); showSubmitButtons('img2img', false); var id = randomId(); @@ -273,7 +264,7 @@ function confirm_clear_prompt(prompt, negative_prompt) { } -promptTokecountUpdateFuncs = {}; +var promptTokecountUpdateFuncs = {}; function recalculatePromptTokens(name) { if (promptTokecountUpdateFuncs[name]) { @@ -304,7 +295,8 @@ onUiUpdate(function() { var textarea = json_elem.querySelector('textarea'); var jsdata = textarea.value; opts = JSON.parse(jsdata); - executeCallbacks(optionsChangedCallbacks); + + executeCallbacks(optionsChangedCallbacks); /*global optionsChangedCallbacks*/ Object.defineProperty(textarea, 'value', { set: function(newValue) { @@ -390,7 +382,9 @@ function update_txt2img_tokens(...args) { } function update_img2img_tokens(...args) { - update_token_counter("img2img_token_button"); + update_token_counter( + "img2img_token_button" + ); if (args.length == 2) { return args[0]; } @@ -423,7 +417,7 @@ function restart_reload() { // Simulate an `input` DOM event for Gradio Textbox component. Needed after you edit its contents in javascript, otherwise your edits // will only visible on web page and not sent to python. function updateInput(target) { - let e = new Event("input", { bubbles: true }); + let e = new Event("input", {bubbles: true}); Object.defineProperty(e, "target", {value: target}); target.dispatchEvent(e); } @@ -435,7 +429,7 @@ function selectCheckpoint(name) { gradioApp().getElementById('change_checkpoint').click(); } -function currentImg2imgSourceResolution(_, _, scaleBy) { +function currentImg2imgSourceResolution(w, h, scaleBy) { var img = gradioApp().querySelector('#mode_img2img > div[style="display: block;"] img'); return img ? [img.naturalWidth, img.naturalHeight, scaleBy] : [0, 0, scaleBy]; } diff --git a/javascript/ui_settings_hints.js b/javascript/ui_settings_hints.js index 0db41b116..e216852b5 100644 --- a/javascript/ui_settings_hints.js +++ b/javascript/ui_settings_hints.js @@ -1,6 +1,6 @@ // various hints and extra info for the settings tab -settingsHintsSetup = false; +var settingsHintsSetup = false; onOptionsChanged(function() { if (settingsHintsSetup) return; @@ -30,7 +30,7 @@ onOptionsChanged(function() { span.parentElement.insertBefore(document.createTextNode('\xa0'), span); } if (commentAfter) { - var comment = document.createElement('DIV'); + comment = document.createElement('DIV'); comment.className = 'settings-comment'; comment.innerHTML = commentAfter; span.parentElement.insertBefore(comment, span.nextSibling); @@ -50,7 +50,7 @@ function settingsHintsShowQuicksettings() { td.textContent = obj.name; tr.appendChild(td); - var td = document.createElement('td'); + td = document.createElement('td'); td.textContent = obj.label; tr.appendChild(td); diff --git a/script.js b/script.js index f6a3883af..db4d91576 100644 --- a/script.js +++ b/script.js @@ -18,11 +18,11 @@ function get_uiCurrentTabContent() { return gradioApp().querySelector('.tabitem[id^=tab_]:not([style*="display: none"])'); } -uiUpdateCallbacks = []; -uiLoadedCallbacks = []; -uiTabChangeCallbacks = []; -optionsChangedCallbacks = []; -let uiCurrentTab = null; +var uiUpdateCallbacks = []; +var uiLoadedCallbacks = []; +var uiTabChangeCallbacks = []; +var optionsChangedCallbacks = []; +var uiCurrentTab = null; function onUiUpdate(callback) { uiUpdateCallbacks.push(callback); @@ -66,7 +66,7 @@ document.addEventListener("DOMContentLoaded", function() { executeCallbacks(uiTabChangeCallbacks); } }); - mutationObserver.observe(gradioApp(), { childList: true, subtree: true }); + mutationObserver.observe(gradioApp(), {childList: true, subtree: true}); }); /** @@ -80,7 +80,7 @@ document.addEventListener('keydown', function(e) { if ((e.keyCode == 13 && (e.metaKey || e.ctrlKey || e.altKey))) handled = true; } if (handled) { - button = get_uiCurrentTabContent().querySelector('button[id$=_generate]'); + var button = get_uiCurrentTabContent().querySelector('button[id$=_generate]'); if (button) { button.click(); } @@ -97,7 +97,7 @@ function uiElementIsVisible(el) { return false; } - while (isVisible = el.closest('.tabitem')?.style.display !== 'none') { + while ((isVisible = el.closest('.tabitem')?.style.display) !== 'none') { if (!isVisible) { return false; } else if (el.parentElement) {