let new_menu_options = []; let new_submenu_options = []; let new_menu_options_callback = []; let new_submenu_options_callback = []; const settingsStyle = ` #comfy-settings-dialog input{ background: var(--comfy-input-bg); color: var(--input-text); border: 1px solid var(--border-color); padding: 5px; } #comfy-settings-dialog tr > td:first-child { text-align: left; } #comfy-settings-dialog select{ background: var(--bg-color); color: var(--drag-text); padding: 5px; } #comfy-settings-dialog { background: var(--bg-color); } #comfy-settings-dialog::-webkit-scrollbar { margin-top: 0.5rem; height: 1rem; width: .6rem; top: 10px; background-color: transparent; } #comfy-settings-dialog::-webkit-scrollbar:horizontal { height: .5rem; width: 2.5rem } #comfy-settings-dialog::-webkit-scrollbar-track { background-color: var(--comfy-input-bg); border-radius: 9999px } #comfy-settings-dialog::-webkit-scrollbar-thumb { --tw-border-opacity: 1; background-color: var(--border-color); border: 0; border-radius: 9999px; } #comfy-settings-dialog::-webkit-scrollbar-thumb:hover { --tw-bg-opacity: 1; background-color: var(--border-color); } .comfy-table td, .comfy-table th { border: 0px solid var(--border-color); padding: 8px; } ` async function api_get(url) { var response = await api.fetchApi(url, { cache: "no-store" }) return await response.json() } function getDynamicCSSRule(selector, property) { const styleId = 'dynamic-styles'; const customStyle = document.getElementById(styleId); if (!customStyle) { return null; } const existingRule = Array.from(customStyle.sheet.cssRules).find(rule => rule.selectorText === selector); if (existingRule) { return existingRule.style.getPropertyValue(property); } return null; } function addDynamicCSSRule(selector, property, value) { const styleId = 'dynamic-styles'; let customStyle = document.getElementById(styleId); if (!customStyle) { customStyle = document.createElement('style'); customStyle.type = 'text/css'; customStyle.id = styleId; document.head.appendChild(customStyle); } const existingRule = Array.from(customStyle.sheet.cssRules).find(rule => rule.selectorText === selector); if (existingRule) { existingRule.style.setProperty(property, value, 'important'); } else { customStyle.sheet.insertRule(`${selector} { ${property}: ${value} !important; }`, customStyle.sheet.cssRules.length); } } function addJavascriptVar(name, value) { const scripta = document.createElement('script'); scripta.type = 'text/javascript'; scripta.innerHTML = "var "+name+" = "+value; document.head.appendChild(scripta); } function getVar(name) { var varValue = localStorage.getItem(name); if (varValue === null) { if (name=="pinnedItems") { //get cookie pinnedItems var cookies = document.cookie.split('; '); cookies.forEach(cookie => { const [cookieName, cookieValue] = cookie.split('='); if (cookieName === name) { setVar(name, cookieValue) } }) //delete cookie pinnedItems document.cookie = name + '=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;'; } else { return null; } }else { return varValue; } return null; } function setVar(name, value) { /*migration to localstorage*/ localStorage.setItem(name, value); } function removeVar(name) { localStorage.removeItem(name); } function renameVar(oldName, newName) { const oldValue = getVar(oldName); setVar(newName, oldValue); removeVar(oldName); } function getElementPosition(element) { const rect = element.getBoundingClientRect(); return { top: rect.top, left: rect.left }; } function reverseAndAppend(originalName) { let words; let lastWord; let reversedWords; let reversedString; let finalName; if (originalName.includes(' ')) { const words = originalName.split(' '); lastWord = words.pop(); reversedWords = words.reverse(); reversedString = reversedWords.join(' '); finalName = originalName + ' ' + reversedString; return finalName; } else { words = originalName.split(/(?=[A-Z])/); lastWord = words.pop(); reversedWords = words.reverse(); reversedString = reversedWords.join(''); finalName = originalName + reversedString; return finalName; } } function cleanText(text) { let cleanedText = text.replace(/[^a-zA-Z0-9\s\n\-]/g, ''); cleanedText = cleanedText.replace(/\s+/g, ' '); cleanedText = cleanedText.replace(/\n/g, ''); return cleanedText; } function calcSBTop() { let sb = document.getElementById('sidebar'); let sbtop = window.getComputedStyle(sb).getPropertyValue('top').replace('px', ''); if (getVar('Comfy.Settings.Comfy.UseNewMenu') === '"Top"') { return parseInt(sbtop) + 35; } else{ return sbtop; } } //CONTEXT MENU function createContextMenu(event, subMenus,settingsData) { event.preventDefault(); hideAllSubMenus(); const sbcontextMenu = document.getElementById('customMenu'); const menuOptions = document.getElementById('menu-options'); // Clear existing menu items menuOptions.innerHTML = ''; // Populate main options settingsData.menuctx_options.forEach((option, index) => { const li = document.createElement('li'); li.textContent = option; li.addEventListener('mouseenter', () => { hideAllSubMenus(); showSubMenu(subMenus[index], li); }); try { if (settingsData.menuctx_opt_callback[index].indexOf(".") !== -1) { // Handle sub menu option var mainfunc = settingsData.menuctx_opt_callback[index].split(".")[0]; var subfunc = settingsData.menuctx_opt_callback[index].split(".")[1]; if (typeof (window[mainfunc][subfunc]) === 'function') { li.addEventListener('click', () => { // Handle sub menu click window[mainfunc][subfunc](event); }); } } else{ if (typeof (window[settingsData.menuctx_opt_callback[index]]) === 'function') { li.addEventListener('click', () => { // Handle main option click window[settingsData.menuctx_opt_callback[index]](event); }); } } } catch (error) { console.log(error); } menuOptions.appendChild(li); }); // Show context menu sbcontextMenu.style.display = 'block'; let sbtop = calcSBTop(); sbcontextMenu.style.top = (event.clientY - sbtop) + 'px'; if (sbPosition === "left") { sbcontextMenu.style.left = event.clientX + 'px'; } else { // const sidebar_width = getVar("sidebarWidth"); //console.log(parseInt(sidebar_width)) //console.log(event) //console.log(event.clientX - parseInt(sidebar_width) ) //temp bugfix sbcontextMenu.style.left = event.layerX + 'px'; } // Hide context menu on body click document.body.addEventListener('click', hideContextMenu); } function showSubMenu(subMenu, element) { try{ if (subMenu) { subMenu.style.display = 'block'; const rect = element.getBoundingClientRect(); subMenu.style.top = element.offsetTop + 'px'; subMenuVisible = true; } } catch (error) { console.log(error); } } function hideAllSubMenus() { const subMenus = document.querySelectorAll('.sub-menu'); subMenus.forEach(subMenu => { subMenu.style.display = 'none'; }); subMenuVisible = false; } function hideContextMenu() { const sbcontextMenu = document.getElementById('customMenu'); sbcontextMenu.style.display = 'none'; document.body.removeEventListener('click', hideContextMenu); } let subMenuVisible = false; let lastTargetClicked = null; async function setContextMenu(settingsData,class_menu_item,main=0,exluded_class=null,included_class = null) { if (main==1){ settingsData.menuctx_options = settingsData.menuctx_options.concat(new_menu_options); settingsData.menuctx_subOptions = settingsData.menuctx_subOptions.concat(new_submenu_options); settingsData.menuctx_opt_callback = settingsData.menuctx_opt_callback.concat(new_menu_options_callback); settingsData.menuctx_sub_opt_callback = settingsData.menuctx_sub_opt_callback.concat(new_submenu_options_callback); } const sbcontextMenu = document.getElementById('customMenu'); const menuOptions = document.createElement("ul"); menuOptions.id = "menu-options"; sbcontextMenu.appendChild(menuOptions); const subMenus = []; for (let i = 0; i < settingsData.menuctx_subOptions.length; i++) { const subMenu = document.createElement("ul"); subMenu.id = `sub-menu-op${i + 1}`; subMenu.classList.add("sub-menu"); if (settingsData.menuctx_subOptions[i].length == 0) { subMenu.classList.add("cat_empty"); } sbcontextMenu.appendChild(subMenu); subMenus.push(subMenu); for (let j = 0; j < settingsData.menuctx_subOptions[i].length; j++) { const li = document.createElement("li"); li.textContent = settingsData.menuctx_subOptions[i][j]; subMenu.appendChild(li); try { if (settingsData.menuctx_sub_opt_callback[i][j].indexOf(".") !== -1) { // Handle sub menu option var mainfunc = settingsData.menuctx_sub_opt_callback[i][j].split(".")[0]; var subfunc = settingsData.menuctx_sub_opt_callback[i][j].split(".")[1]; if (typeof (window[mainfunc][subfunc]) === 'function') { li.addEventListener('click', () => { // Handle sub menu click window[mainfunc][subfunc](lastTargetClicked,settingsData.menuctx_subOptions[i][j]); }); } } else{ if (typeof (window[settingsData.menuctx_sub_opt_callback[i][j]]) === 'function') { li.addEventListener('click', () => { // Handle main option click window[settingsData.menuctx_sub_opt_callback[i][j]](lastTargetClicked,settingsData.menuctx_subOptions[i][j]); }); } } } catch (error) { console.log(error); } } } const sidebarItems = document.querySelectorAll(class_menu_item); //const sb =document.getElementById('panel_home'); for (const sidebarItem of sidebarItems) { sidebarItem.addEventListener('contextmenu', (event) => { if(!event.target.classList.contains(exluded_class)){ if (included_class != null && !event.target.classList.contains(included_class)){ return; } createContextMenu (event, subMenus,settingsData); lastTargetClicked = event; } }); } //ContextMenu //sb.addEventListener("contextmenu", function(event) { // event.preventDefault(); // // const customMenu = document.getElementById("customMenu"); // customMenu.style.display = "block"; // customMenu.style.left = event.pageX + "px"; // customMenu.style.top = event.pageY + "px"; //}); // window.addEventListener("click", function(event) { const customMenu = document.getElementById("customMenu"); customMenu.style.display = "none"; }); } // Function to check for special characters function containsSpecialCharacters(name, level=0) { // Define a regular expression pattern to match special characters if (level == 0) { var specialCharacters = /[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/; } else if (level == 1) { var specialCharacters = /[\*':"\\|,<>\/?]/g; } else{ var specialCharacters = /['"]/gi; } // Return true if the name contains any special characters, false otherwise return specialCharacters.test(name); } async function reloadCtxMenu() { //load folder name var nameRequest = await fetch('sidebar/current'); var nameFolder = await nameRequest.json(); const cnPath = `../extensions/${nameFolder}/` const response3 = await fetch(cnPath +'settings.json'); const settingsData = await response3.json(); setContextMenu(settingsData,"#panel_home .sidebarItem",1); } function setNodeStatus(varname,node,status) { try{//'sb_categoryNodeStatus' const categoryNodeStatus = JSON.parse(localStorage.getItem(varname)) || {}; categoryNodeStatus[node] = [status]; localStorage.setItem(varname, JSON.stringify(categoryNodeStatus)); }catch(err){ } } function getNodeStatus(varname,node) { try{ const categoryNodeStatus = JSON.parse(localStorage.getItem(varname)) || {}; return categoryNodeStatus[node] || "none"; }catch(err){ } return "none"; } function getNodesStatus() { let categoryNodeStatus = JSON.parse(localStorage.getItem(varname)) || {}; return categoryNodeStatus; } // MODAL function setModalContext(addon=null) { if (addon==null) { return `