contextMenus.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. var 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).substring(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 = {
  52. id: targetElementSelector + '_' + uid(),
  53. name: entryName,
  54. func: entryFunction,
  55. isNew: true
  56. };
  57. currentItems.push(newItem);
  58. return newItem['id'];
  59. }
  60. function removeContextMenuOption(uid) {
  61. menuSpecs.forEach(function(v) {
  62. let index = -1;
  63. v.forEach(function(e, ei) {
  64. if (e['id'] == uid) {
  65. index = ei;
  66. }
  67. });
  68. if (index >= 0) {
  69. v.splice(index, 1);
  70. }
  71. });
  72. }
  73. function addContextMenuEventListener() {
  74. if (eventListenerApplied) {
  75. return;
  76. }
  77. gradioApp().addEventListener("click", function(e) {
  78. if (!e.isTrusted) {
  79. return;
  80. }
  81. let oldMenu = gradioApp().querySelector('#context-menu');
  82. if (oldMenu) {
  83. oldMenu.remove();
  84. }
  85. });
  86. gradioApp().addEventListener("contextmenu", function(e) {
  87. let oldMenu = gradioApp().querySelector('#context-menu');
  88. if (oldMenu) {
  89. oldMenu.remove();
  90. }
  91. menuSpecs.forEach(function(v, k) {
  92. if (e.composedPath()[0].matches(k)) {
  93. showContextMenu(e, e.composedPath()[0], v);
  94. e.preventDefault();
  95. }
  96. });
  97. });
  98. eventListenerApplied = true;
  99. }
  100. return [appendContextMenuOption, removeContextMenuOption, addContextMenuEventListener];
  101. };
  102. var initResponse = contextMenuInit();
  103. var appendContextMenuOption = initResponse[0];
  104. var removeContextMenuOption = initResponse[1];
  105. var addContextMenuEventListener = initResponse[2];
  106. (function() {
  107. //Start example Context Menu Items
  108. let generateOnRepeat = function(genbuttonid, interruptbuttonid) {
  109. let genbutton = gradioApp().querySelector(genbuttonid);
  110. let interruptbutton = gradioApp().querySelector(interruptbuttonid);
  111. if (!interruptbutton.offsetParent) {
  112. genbutton.click();
  113. }
  114. clearInterval(window.generateOnRepeatInterval);
  115. window.generateOnRepeatInterval = setInterval(function() {
  116. if (!interruptbutton.offsetParent) {
  117. genbutton.click();
  118. }
  119. },
  120. 500);
  121. };
  122. let generateOnRepeat_txt2img = function() {
  123. generateOnRepeat('#txt2img_generate', '#txt2img_interrupt');
  124. };
  125. let generateOnRepeat_img2img = function() {
  126. generateOnRepeat('#img2img_generate', '#img2img_interrupt');
  127. };
  128. appendContextMenuOption('#txt2img_generate', 'Generate forever', generateOnRepeat_txt2img);
  129. appendContextMenuOption('#txt2img_interrupt', 'Generate forever', generateOnRepeat_txt2img);
  130. appendContextMenuOption('#img2img_generate', 'Generate forever', generateOnRepeat_img2img);
  131. appendContextMenuOption('#img2img_interrupt', 'Generate forever', generateOnRepeat_img2img);
  132. let cancelGenerateForever = function() {
  133. clearInterval(window.generateOnRepeatInterval);
  134. };
  135. appendContextMenuOption('#txt2img_interrupt', 'Cancel generate forever', cancelGenerateForever);
  136. appendContextMenuOption('#txt2img_generate', 'Cancel generate forever', cancelGenerateForever);
  137. appendContextMenuOption('#img2img_interrupt', 'Cancel generate forever', cancelGenerateForever);
  138. appendContextMenuOption('#img2img_generate', 'Cancel generate forever', cancelGenerateForever);
  139. })();
  140. //End example Context Menu Items
  141. onAfterUiUpdate(addContextMenuEventListener);