contextMenuInit = function(){ let eventListenerApplied=false; let menuSpecs = new Map(); const uid = function(){ return Date.now().toString(36) + Math.random().toString(36).substr(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 tabButton = gradioApp().querySelector('button') let baseStyle = window.getComputedStyle(tabButton) 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(e) { entry['func'](); }) contextMenuList.append(contextMenuEntry); }) gradioApp().getRootNode().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(targetEmementSelector,entryName,entryFunction){ currentItems = menuSpecs.get(targetEmementSelector) if(!currentItems){ currentItems = [] menuSpecs.set(targetEmementSelector,currentItems); } let newItem = {'id':targetEmementSelector+'_'+uid(), 'name':entryName, 'func':entryFunction, 'isNew':true} currentItems.push(newItem) return newItem['id'] } function removeContextMenuOption(uid){ } function addContextMenuEventListener(){ if(eventListenerApplied){ return; } gradioApp().addEventListener("click", function(e) { let source = e.composedPath()[0] if(source.id && source.indexOf('check_progress')>-1){ 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() return } }) }); eventListenerApplied=true } return [appendContextMenuOption, removeContextMenuOption, addContextMenuEventListener] } initResponse = contextMenuInit() appendContextMenuOption = initResponse[0] removeContextMenuOption = initResponse[1] addContextMenuEventListener = initResponse[2] //Start example Context Menu Items generateOnRepeatId = appendContextMenuOption('#txt2img_generate','Generate forever',function(){ let genbutton = gradioApp().querySelector('#txt2img_generate'); let interruptbutton = gradioApp().querySelector('#txt2img_interrupt'); if(!interruptbutton.offsetParent){ genbutton.click(); } clearInterval(window.generateOnRepeatInterval) window.generateOnRepeatInterval = setInterval(function(){ if(!interruptbutton.offsetParent){ genbutton.click(); } }, 500)} ) cancelGenerateForever = function(){ clearInterval(window.generateOnRepeatInterval) let interruptbutton = gradioApp().querySelector('#txt2img_interrupt'); if(interruptbutton.offsetParent){ interruptbutton.click(); } } appendContextMenuOption('#txt2img_interrupt','Cancel generate forever',cancelGenerateForever) appendContextMenuOption('#txt2img_generate','Cancel generate forever',cancelGenerateForever) appendContextMenuOption('#roll','Roll three', function(){ let rollbutton = gradioApp().querySelector('#roll'); setTimeout(function(){rollbutton.click()},100) setTimeout(function(){rollbutton.click()},200) setTimeout(function(){rollbutton.click()},300) } ) //End example Context Menu Items onUiUpdate(function(){ addContextMenuEventListener() });