| | (function () { |
| | async function checkEditorAvailable() { |
| | const LOCAL_EDITOR_PATH = '/openpose_editor_index'; |
| | const REMOTE_EDITOR_PATH = 'https://huchenlei.github.io/sd-webui-openpose-editor/'; |
| |
|
| | async function testEditorPath(path) { |
| | const res = await fetch(path); |
| | return res.status === 200 ? path : null; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | return await testEditorPath(LOCAL_EDITOR_PATH) || await testEditorPath(REMOTE_EDITOR_PATH); |
| | } |
| |
|
| | const cnetOpenposeEditorRegisteredElements = new Set(); |
| | let editorURL = null; |
| | function loadOpenposeEditor() { |
| | |
| | |
| | function updateInput(target) { |
| | let e = new Event("input", { bubbles: true }) |
| | Object.defineProperty(e, "target", { value: target }) |
| | target.dispatchEvent(e); |
| | } |
| |
|
| | function navigateIframe(iframe, editorURL) { |
| | function getPathname(rawURL) { |
| | try { |
| | return new URL(rawURL).pathname; |
| | } catch (e) { |
| | return rawURL; |
| | } |
| | } |
| |
|
| | return new Promise((resolve) => { |
| | const darkThemeParam = document.body.classList.contains('dark') ? |
| | new URLSearchParams({ theme: 'dark' }).toString() : |
| | ''; |
| |
|
| | window.addEventListener('message', (event) => { |
| | const message = event.data; |
| | if (message['ready']) resolve(); |
| | }, { once: true }); |
| |
|
| | if ((editorURL.startsWith("http") ? iframe.src : getPathname(iframe.src)) !== editorURL) { |
| | iframe.src = `${editorURL}?${darkThemeParam}`; |
| | |
| | |
| | setTimeout(resolve, 5000); |
| | } else { |
| | |
| | resolve(); |
| | } |
| | }); |
| | } |
| | const tabs = gradioApp().querySelectorAll('#controlnet .input-accordion'); |
| | tabs.forEach(tab => { |
| | if (cnetOpenposeEditorRegisteredElements.has(tab)) return; |
| | cnetOpenposeEditorRegisteredElements.add(tab); |
| |
|
| | const generatedImageGroup = tab.querySelector('.cnet-generated-image-group'); |
| | const editButton = generatedImageGroup.querySelector('.cnet-edit-pose'); |
| |
|
| | editButton.addEventListener('click', async () => { |
| | const inputImageGroup = tab.querySelector('.cnet-input-image-group'); |
| | const inputImage = inputImageGroup.querySelector('.cnet-image img'); |
| | const downloadLink = generatedImageGroup.querySelector('.cnet-download-pose a'); |
| | const modalId = editButton.id.replace('cnet-modal-open-', ''); |
| | const modalIframe = generatedImageGroup.querySelector('.cnet-modal iframe'); |
| |
|
| | if (!editorURL) { |
| | editorURL = await checkEditorAvailable(); |
| | if (!editorURL) { |
| | alert("No openpose editor available.") |
| | } |
| | } |
| |
|
| | await navigateIframe(modalIframe, editorURL); |
| | modalIframe.contentWindow.postMessage({ |
| | modalId, |
| | imageURL: inputImage ? inputImage.src : undefined, |
| | poseURL: downloadLink.href, |
| | }, '*'); |
| | |
| | |
| | |
| | modalIframe.contentWindow.focus(); |
| | }); |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | function updatePreviewPose(poseURL) { |
| | const downloadLink = generatedImageGroup.querySelector('.cnet-download-pose a'); |
| | const renderButton = generatedImageGroup.querySelector('.cnet-render-pose'); |
| | const poseTextbox = generatedImageGroup.querySelector('.cnet-pose-json textarea'); |
| | const allowPreviewCheckbox = tab.querySelector('.cnet-allow-preview input'); |
| |
|
| | if (!allowPreviewCheckbox.checked) |
| | allowPreviewCheckbox.click(); |
| |
|
| | |
| | |
| | |
| | if (downloadLink !== null) |
| | downloadLink.href = poseURL; |
| |
|
| | poseTextbox.value = poseURL; |
| | updateInput(poseTextbox); |
| | renderButton.click(); |
| | } |
| |
|
| | |
| | window.addEventListener('message', (event) => { |
| | const message = event.data; |
| | const modalId = editButton.id.replace('cnet-modal-open-', ''); |
| | if (message.modalId !== modalId) return; |
| | updatePreviewPose(message.poseURL); |
| |
|
| | const closeModalButton = generatedImageGroup.querySelector('.cnet-modal .cnet-modal-close'); |
| | closeModalButton.click(); |
| | }); |
| |
|
| | const inputImageGroup = tab.querySelector('.cnet-input-image-group'); |
| | const uploadButton = inputImageGroup.querySelector('.cnet-upload-pose input'); |
| | |
| | uploadButton.addEventListener('change', (event) => { |
| | const file = event.target.files[0]; |
| | if (!file) |
| | return; |
| |
|
| | const reader = new FileReader(); |
| | reader.onload = function (e) { |
| | const contents = e.target.result; |
| | const poseURL = `data:application/json;base64,${btoa(contents)}`; |
| | updatePreviewPose(poseURL); |
| | }; |
| | reader.readAsText(file); |
| | |
| | event.target.value = ''; |
| | }); |
| | }); |
| | } |
| |
|
| | onUiUpdate(loadOpenposeEditor); |
| | })(); |