CAI Universal Toolbelt Menu

Reusable menu structure for various c.ai TM scripts that require a menu

目前为 2023-05-12 提交的版本。查看 最新版本

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.gf.qytechs.cn/scripts/466064/1189757/CAI%20Universal%20Toolbelt%20Menu.js

  1. // ==UserScript==
  2. // @exclude *
  3. // @author notdoingthateither
  4.  
  5. // ==UserLibrary==
  6. // @name CAI Universal Toolbelt Menu
  7. // @description Reusable menu structure for various c.ai TM scripts that require a menu
  8. // @license MIT
  9.  
  10.  
  11. // ==/UserScript==
  12.  
  13. // ==/UserLibrary==
  14.  
  15. CAIToolMenu = window.CAIToolMenu || {};
  16.  
  17. CAIToolMenu = function() {
  18.  
  19. const _CAIToolMenu_ArrowUp = '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-bar-up" viewBox="0 0 16 16"> <path fill-rule="evenodd" d="M8 10a.5.5 0 0 0 .5-.5V3.707l2.146 2.147a.5.5 0 0 0 .708-.708l-3-3a.5.5 0 0 0-.708 0l-3 3a.5.5 0 1 0 .708.708L7.5 3.707V9.5a.5.5 0 0 0 .5.5zm-7 2.5a.5.5 0 0 1 .5-.5h13a.5.5 0 0 1 0 1h-13a.5.5 0 0 1-.5-.5z"/> </svg>';
  20. const _CAIToolMenu_ArrowDown = '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-bar-down" viewBox="0 0 16 16"> <path fill-rule="evenodd" d="M1 3.5a.5.5 0 0 1 .5-.5h13a.5.5 0 0 1 0 1h-13a.5.5 0 0 1-.5-.5zM8 6a.5.5 0 0 1 .5.5v5.793l2.146-2.147a.5.5 0 0 1 .708.708l-3 3a.5.5 0 0 1-.708 0l-3-3a.5.5 0 0 1 .708-.708L7.5 12.293V6.5A.5.5 0 0 1 8 6z"/> </svg>';
  21.  
  22. let menuElement;
  23. let buttons = [];
  24. const observer = new MutationObserver((mutations) => {
  25. if (menuElement == null && mutations.length > 0) {
  26. menuElement = document.getElementById('tms-script-cai-universal-toolbelt');
  27. if (menuElement == null) {
  28. console.log('init menu.');
  29. init();
  30. } else {
  31. console.log('menu already initialized.');
  32. observer.disconnect();
  33. }
  34. }
  35. });
  36.  
  37. observer.observe(document.body, { attributes: true, childList: true, subtree: true });
  38.  
  39. init = function() {
  40. const parentElement = document.createElement('div');
  41. parentElement.classList.add('cai-tool-root');
  42.  
  43. menuElement = document.createElement('div');
  44. menuElement.setAttribute('id', 'tms-script-cai-universal-toolbelt');
  45. menuElement.classList.add('cai-tool-menu', 'cai-tool-menu-hide');
  46. const toggleIconSpanL = document.createElement('span');
  47. toggleIconSpanL.classList.add('cai-tool-toggle');
  48. toggleIconSpanL.innerHTML = _CAIToolMenu_ArrowUp;
  49. const caitmSpan = document.createElement('span');
  50. caitmSpan.innerHTML = 'c.ai ToolMenu';
  51.  
  52. const toggleIconSpanR = document.createElement('span');
  53. toggleIconSpanR.classList.add('cai-tool-toggle');
  54. toggleIconSpanR.innerHTML = _CAIToolMenu_ArrowUp;
  55.  
  56. const menuToggleBtn = document.createElement('button');
  57. menuToggleBtn.classList.add('cai-tool-menu-toggle');
  58. menuToggleBtn.append(toggleIconSpanL, caitmSpan, toggleIconSpanR);
  59. menuToggleBtn.dataset.menuHidden = 'true';
  60. menuToggleBtn.onclick = () => {
  61. if (menuToggleBtn.dataset.menuHidden === 'true') {
  62. menuElement.classList.remove('cai-tool-menu-hide');
  63. toggleIconSpanL.innerHTML = _CAIToolMenu_ArrowDown;
  64. toggleIconSpanR.innerHTML = _CAIToolMenu_ArrowDown;
  65. menuToggleBtn.dataset.menuHidden = 'false';
  66. } else {
  67. menuElement.classList.add('cai-tool-menu-hide');
  68. toggleIconSpanL.innerHTML = _CAIToolMenu_ArrowUp;
  69. toggleIconSpanR.innerHTML = _CAIToolMenu_ArrowUp;
  70. menuToggleBtn.dataset.menuHidden = 'true';
  71. }
  72. };
  73. parentElement.append(menuElement, menuToggleBtn);
  74. menuElement.append(buttons); // append buttons that have been added before init finished properly
  75.  
  76. const styleHTML = document.createElement('style');
  77. styleHTML.innerHTML = `
  78. .cai-tool-btn {
  79. border-radius: 32px;
  80. cursor: pointer;
  81. margin: .25rem .25rem 0 .25rem;
  82. border: 1px solid;
  83. width: fit-content;
  84. min-width: 32px;
  85. min-height: 32px;
  86. }
  87.  
  88. .cai-tool-root {
  89. position: fixed;
  90. bottom: 0;
  91. z-index: 200;
  92. width: 100%;
  93. display: flex;
  94. align-items: center;
  95. flex-direction: column;
  96. }
  97. .cai-tool-menu {
  98. display: flex;
  99. flex-wrap: wrap;
  100. flex-direction: column;
  101. align-items: center;
  102. max-width: 300px;
  103. z-index: 201;
  104. }
  105. .cai-tool-menu-hide {
  106. display: none !important;
  107. }
  108. .cai-tool-menu-toggle {
  109. cursor: pointer;
  110. display: flex;
  111. border: 1px solid transparent;
  112. background-color: transparent;
  113. align-items: center;
  114. justify-content: center;
  115. width: 100%;
  116. font-size: 12px;
  117. font-weight: 600;
  118. letter-spacing: .05em;
  119. z-index: 202;
  120. }
  121. .cai-tool-toggle {
  122. margin-top: -.5rem;
  123. margin-bottom: -.5rem;
  124. padding: .25rem;
  125. width: 32px;
  126. flex: 0 0 auto;
  127. width: auto;
  128. }
  129. `;
  130. document.body.appendChild(styleHTML);
  131. document.body.appendChild(parentElement);
  132.  
  133. console.log('menu initialized.');
  134. };
  135.  
  136. addButton = function() {
  137. const newBtn = document.createElement('button');
  138. newBtn.classList.add('cai-tool-btn');
  139. buttons.push(newBtn);
  140. if (menuElement != null) {
  141. menuElement.append(newBtn);
  142. console.log('new button added!');
  143. }
  144.  
  145. return newBtn;
  146. };
  147.  
  148. return {
  149. "newButton": addButton
  150. };
  151. }();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址