135 lines
3.7 KiB
JavaScript
135 lines
3.7 KiB
JavaScript
//v1.0.1
|
|
import { app } from "../../scripts/app.js";
|
|
|
|
const config = {
|
|
newTab: true,
|
|
};
|
|
|
|
// Store references to created elements for cleanup
|
|
let widgetElements = [];
|
|
let observers = [];
|
|
|
|
const createWidget = ({ className, text, tooltip, includeIcon, labelIcon }) => {
|
|
const button = document.createElement('button');
|
|
button.className = className;
|
|
button.setAttribute('aria-label', tooltip);
|
|
button.title = tooltip;
|
|
|
|
if (includeIcon && labelIcon) {
|
|
const iconContainer = document.createElement('span');
|
|
iconContainer.innerHTML = labelIcon;
|
|
iconContainer.style.display = 'flex';
|
|
iconContainer.style.alignItems = 'center';
|
|
iconContainer.style.justifyContent = 'center';
|
|
iconContainer.style.width = '20px';
|
|
iconContainer.style.height = '16px';
|
|
button.appendChild(iconContainer);
|
|
}
|
|
|
|
const textNode = document.createTextNode(text);
|
|
button.appendChild(textNode);
|
|
|
|
button.addEventListener('click', onClick);
|
|
widgetElements.push(button); // Store reference for cleanup
|
|
return button;
|
|
};
|
|
|
|
const onClick = () => {
|
|
const imgExtractUrl = `${window.location.origin}/imgextract`;
|
|
if (config.newTab) {
|
|
window.open(imgExtractUrl, '_blank');
|
|
} else {
|
|
window.location.href = imgExtractUrl;
|
|
}
|
|
};
|
|
|
|
const addWidgetMenuRight = (menuRight) => {
|
|
let buttonGroup = menuRight.querySelector('.comfyui-button-group');
|
|
|
|
if (!buttonGroup) {
|
|
buttonGroup = document.createElement('div');
|
|
buttonGroup.className = 'comfyui-button-group';
|
|
menuRight.appendChild(buttonGroup);
|
|
}
|
|
|
|
const imageinfoButton = createWidget({
|
|
className: 'comfyui-button comfyui-menu-mobile-collapse primary',
|
|
text: '',
|
|
tooltip: 'Launch Metadata Extractor',
|
|
includeIcon: true,
|
|
labelIcon: getExtractorIcon(),
|
|
});
|
|
|
|
buttonGroup.appendChild(imageinfoButton);
|
|
};
|
|
|
|
const addWidgetMenu = (menu) => {
|
|
const resetViewButton = menu.querySelector('#comfy-reset-view-button');
|
|
if (!resetViewButton) {
|
|
return;
|
|
}
|
|
|
|
const imageinfoButton = createWidget({
|
|
className: 'comfy-imginfo-button',
|
|
text: 'Image Info',
|
|
tooltip: 'Launch Metadata Extractor',
|
|
includeIcon: false,
|
|
});
|
|
|
|
resetViewButton.insertAdjacentElement('afterend', imageinfoButton);
|
|
};
|
|
|
|
const addWidget = (selector, callback) => {
|
|
const observer = new MutationObserver((mutations, obs) => {
|
|
const element = document.querySelector(selector);
|
|
if (element) {
|
|
callback(element);
|
|
obs.disconnect();
|
|
}
|
|
});
|
|
|
|
observers.push(observer); // Store reference for cleanup
|
|
observer.observe(document.body, { childList: true, subtree: true });
|
|
};
|
|
|
|
const initializeWidget = () => {
|
|
addWidget('.comfyui-menu-right', addWidgetMenuRight);
|
|
addWidget('.comfy-menu', addWidgetMenu);
|
|
};
|
|
|
|
const getExtractorIcon = () => {
|
|
return `✨`;
|
|
};
|
|
|
|
const cleanupWidgets = () => {
|
|
// Remove all created buttons
|
|
widgetElements.forEach(element => {
|
|
if (element && element.parentNode) {
|
|
element.parentNode.removeChild(element);
|
|
}
|
|
});
|
|
widgetElements = [];
|
|
|
|
// Disconnect all observers
|
|
observers.forEach(observer => observer.disconnect());
|
|
observers = [];
|
|
};
|
|
|
|
app.registerExtension({
|
|
name: "otacoo-imgextract.widget",
|
|
|
|
// Called when the extension is enabled or disabled
|
|
setup(enabled) {
|
|
if (enabled) {
|
|
initializeWidget();
|
|
} else {
|
|
cleanupWidgets();
|
|
}
|
|
},
|
|
|
|
// This is needed to ensure the extension can be toggled on/off
|
|
beforeRegisterNodeDef(nodeType, nodeData, app) {
|
|
return { nodeType, nodeData };
|
|
}
|
|
});
|