contextMenus.js 5.1 KB

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