contextMenus.js 5.5 KB

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