contextMenus.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. contextMenuInit = function(){
  2. let eventListenerApplied=false;
  3. let menuSpecs = new Map();
  4. const uid = function(){
  5. return Date.now().toString(36) + Math.random().toString(36).substr(2);
  6. }
  7. function showContextMenu(event,element,menuEntries){
  8. let posx = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
  9. let posy = event.clientY + document.body.scrollTop + document.documentElement.scrollTop;
  10. let oldMenu = gradioApp().querySelector('#context-menu')
  11. if(oldMenu){
  12. oldMenu.remove()
  13. }
  14. let tabButton = uiCurrentTab
  15. let baseStyle = window.getComputedStyle(tabButton)
  16. const contextMenu = document.createElement('nav')
  17. contextMenu.id = "context-menu"
  18. contextMenu.style.background = baseStyle.background
  19. contextMenu.style.color = baseStyle.color
  20. contextMenu.style.fontFamily = baseStyle.fontFamily
  21. contextMenu.style.top = posy+'px'
  22. contextMenu.style.left = posx+'px'
  23. const contextMenuList = document.createElement('ul')
  24. contextMenuList.className = 'context-menu-items';
  25. contextMenu.append(contextMenuList);
  26. menuEntries.forEach(function(entry){
  27. let contextMenuEntry = document.createElement('a')
  28. contextMenuEntry.innerHTML = entry['name']
  29. contextMenuEntry.addEventListener("click", function(e) {
  30. entry['func']();
  31. })
  32. contextMenuList.append(contextMenuEntry);
  33. })
  34. gradioApp().appendChild(contextMenu)
  35. let menuWidth = contextMenu.offsetWidth + 4;
  36. let menuHeight = contextMenu.offsetHeight + 4;
  37. let windowWidth = window.innerWidth;
  38. let windowHeight = window.innerHeight;
  39. if ( (windowWidth - posx) < menuWidth ) {
  40. contextMenu.style.left = windowWidth - menuWidth + "px";
  41. }
  42. if ( (windowHeight - posy) < menuHeight ) {
  43. contextMenu.style.top = windowHeight - menuHeight + "px";
  44. }
  45. }
  46. function appendContextMenuOption(targetElementSelector,entryName,entryFunction){
  47. currentItems = menuSpecs.get(targetElementSelector)
  48. if(!currentItems){
  49. currentItems = []
  50. menuSpecs.set(targetElementSelector,currentItems);
  51. }
  52. let newItem = {'id':targetElementSelector+'_'+uid(),
  53. 'name':entryName,
  54. 'func':entryFunction,
  55. 'isNew':true}
  56. currentItems.push(newItem)
  57. return newItem['id']
  58. }
  59. function removeContextMenuOption(uid){
  60. menuSpecs.forEach(function(v,k) {
  61. let index = -1
  62. v.forEach(function(e,ei){if(e['id']==uid){index=ei}})
  63. if(index>=0){
  64. v.splice(index, 1);
  65. }
  66. })
  67. }
  68. function addContextMenuEventListener(){
  69. if(eventListenerApplied){
  70. return;
  71. }
  72. gradioApp().addEventListener("click", function(e) {
  73. let source = e.composedPath()[0]
  74. if(source.id && source.id.indexOf('check_progress')>-1){
  75. return
  76. }
  77. let oldMenu = gradioApp().querySelector('#context-menu')
  78. if(oldMenu){
  79. oldMenu.remove()
  80. }
  81. });
  82. gradioApp().addEventListener("contextmenu", function(e) {
  83. let oldMenu = gradioApp().querySelector('#context-menu')
  84. if(oldMenu){
  85. oldMenu.remove()
  86. }
  87. menuSpecs.forEach(function(v,k) {
  88. if(e.composedPath()[0].matches(k)){
  89. showContextMenu(e,e.composedPath()[0],v)
  90. e.preventDefault()
  91. return
  92. }
  93. })
  94. });
  95. eventListenerApplied=true
  96. }
  97. return [appendContextMenuOption, removeContextMenuOption, addContextMenuEventListener]
  98. }
  99. initResponse = contextMenuInit();
  100. appendContextMenuOption = initResponse[0];
  101. removeContextMenuOption = initResponse[1];
  102. addContextMenuEventListener = initResponse[2];
  103. (function(){
  104. //Start example Context Menu Items
  105. let generateOnRepeat = function(genbuttonid,interruptbuttonid){
  106. let genbutton = gradioApp().querySelector(genbuttonid);
  107. let interruptbutton = gradioApp().querySelector(interruptbuttonid);
  108. if(!interruptbutton.offsetParent){
  109. genbutton.click();
  110. }
  111. clearInterval(window.generateOnRepeatInterval)
  112. window.generateOnRepeatInterval = setInterval(function(){
  113. if(!interruptbutton.offsetParent){
  114. genbutton.click();
  115. }
  116. },
  117. 500)
  118. }
  119. appendContextMenuOption('#txt2img_generate','Generate forever',function(){
  120. generateOnRepeat('#txt2img_generate','#txt2img_interrupt');
  121. })
  122. appendContextMenuOption('#img2img_generate','Generate forever',function(){
  123. generateOnRepeat('#img2img_generate','#img2img_interrupt');
  124. })
  125. let cancelGenerateForever = function(){
  126. clearInterval(window.generateOnRepeatInterval)
  127. }
  128. appendContextMenuOption('#txt2img_interrupt','Cancel generate forever',cancelGenerateForever)
  129. appendContextMenuOption('#txt2img_generate', 'Cancel generate forever',cancelGenerateForever)
  130. appendContextMenuOption('#img2img_interrupt','Cancel generate forever',cancelGenerateForever)
  131. appendContextMenuOption('#img2img_generate', 'Cancel generate forever',cancelGenerateForever)
  132. appendContextMenuOption('#roll','Roll three',
  133. function(){
  134. let rollbutton = get_uiCurrentTabContent().querySelector('#roll');
  135. setTimeout(function(){rollbutton.click()},100)
  136. setTimeout(function(){rollbutton.click()},200)
  137. setTimeout(function(){rollbutton.click()},300)
  138. }
  139. )
  140. })();
  141. //End example Context Menu Items
  142. onUiUpdate(function(){
  143. addContextMenuEventListener()
  144. });