CAI Universal Toolbelt Menu

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

Ajankohdalta 12.5.2023. Katso uusin versio.

Tätä skriptiä ei tulisi asentaa suoraan. Se on kirjasto muita skriptejä varten sisällytettäväksi metadirektiivillä // @require https://update.greasyfork.org/scripts/466064/1189751/CAI%20Universal%20Toolbelt%20Menu.js.

// ==UserScript==
// @exclude       *
// @author        notdoingthateither

// ==UserLibrary==
// @name          CAI Universal Toolbelt Menu
// @description   Reusable menu structure for various c.ai TM scripts that require a menu
// @license       MIT


// ==/UserScript==

// ==/UserLibrary==

CAIToolMenu = window.CAIToolMenu || {};

CAIToolMenu = function() {

  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>';
  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>';

  let menuElement;
  let buttons = [];
  
  const observer = new MutationObserver((mutations) => {
    if (menuElement == null && mutations.length > 0) {
      menuElement = document.getElementById('tms-script-cai-universal-toolbelt');
      if (menuElement == null) {
        init();
      } else {
        observer.disconnect();
      }
    }
  });

  observer.observe(document.body, { attributes: true, childList: true, subtree: true });

  init = function() {
    const parentElement = document.createElement('div');
    parentElement.classList.add('cai-tool-root');

    menuElement = document.createElement('div');
    menuElement.setAttribute('id', 'tms-script-cai-universal-toolbelt');
    menuElement.classList.add('cai-tool-menu', 'cai-tool-menu-hide');
    
    const toggleIconSpanL = document.createElement('span');
    toggleIconSpanL.classList.add('cai-tool-toggle');
    toggleIconSpanL.innerHTML = _CAIToolMenu_ArrowUp;
    
    const caitmSpan = document.createElement('span');
    caitmSpan.innerHTML = 'c.ai ToolMenu';

    const toggleIconSpanR = document.createElement('span');
    toggleIconSpanR.classList.add('cai-tool-toggle');
    toggleIconSpanR.innerHTML = _CAIToolMenu_ArrowUp;

    const menuToggleBtn = document.createElement('button');
    menuToggleBtn.classList.add('cai-tool-menu-toggle');
    menuToggleBtn.append(toggleIconSpanL, caitmSpan, toggleIconSpanR);
    menuToggleBtn.dataset.menuHidden = 'true';
    menuToggleBtn.onclick = () => {
      if (menuToggleBtn.dataset.menuHidden === 'true') {
        menuElement.classList.remove('cai-tool-menu-hide');
        toggleIconSpanL.innerHTML = _CAIToolMenu_ArrowDown;
        toggleIconSpanR.innerHTML = _CAIToolMenu_ArrowDown;
        menuToggleBtn.dataset.menuHidden = 'false';
      } else {
        menuElement.classList.add('cai-tool-menu-hide');
        toggleIconSpanL.innerHTML = _CAIToolMenu_ArrowUp;
        toggleIconSpanR.innerHTML = _CAIToolMenu_ArrowUp;
        menuToggleBtn.dataset.menuHidden = 'true';
      }
    };
    parentElement.append(menuElement, menuToggleBtn);
    menuElement.append(buttons); // append buttons that have been added before init finished properly

    const styleHTML = document.createElement('style');
    styleHTML.innerHTML = `
      .cai-tool-btn {
        border-radius: 32px;
        cursor: pointer;
        margin: .25rem .25rem 0 .25rem;
        border: 1px solid;
        width: fit-content;
        min-width: 32px;
        min-height: 32px;
      }

      .cai-tool-root {
        position: fixed;
        bottom: 0;
        z-index: 200;
        width: 100%;
        display: flex;
        align-items: center;
        flex-direction: column;
      }
  
      .cai-tool-menu {
        display: flex;
        flex-wrap: wrap;
        flex-direction: column;
        align-items: center;
        max-width: 300px;
        z-index: 201;
      }
  
      .cai-tool-menu-hide {
        display: none !important;
      }
  
      .cai-tool-menu-toggle {
        cursor: pointer;
        display: flex;
        border: 1px solid transparent;
        background-color: transparent;
        align-items: center;
        justify-content: center;
        width: 100%;
        font-size: 12px;
        font-weight: 600;
        letter-spacing: .05em;
        z-index: 202;
      }
  
      .cai-tool-toggle {
        margin-top: -.5rem;
        margin-bottom: -.5rem;
        padding: .25rem;
        width: 32px;
        flex: 0 0 auto;
        width: auto;
      }
    `;
    document.body.appendChild(styleHTML);
    document.body.appendChild(parentElement);
  };

  addButton = function() {
    const newBtn = document.createElement('button');
    newBtn.classList.add('cai-tool-btn');
    buttons.push(newBtn);
    if (menuElement != null) {
      menuElement.append(newBtn);
      console.log('new button added!');
    }

    return newBtn;
  };

  return {
    "newButton": addButton
  };
}();