• removed greentext and pinktext keys
  • instead of hardcoded strings, now uses tags constant
  • added cursor positioning: after inserting tags, positions cursor before the last closing tag
  • added support for inserting tags when nothing is selected

(function () {
  "use strict";

  const tags = {
    spoiler: { tags: ["[spoiler]", "[/spoiler]"], key: "s" },
    bizniz: { tags: ["==", "=="], key: "h" },
    echoes: { tags: ["(((", ")))"], key: "e" },
    moe: { tags: ["[moe]", "[/moe]"], key: "m" },
    doom: { tags: ["[doom]", "[/doom]"], key: "d" },
    italics: { tags: ["''", "''"], key: "i" },
    bold: { tags: ["'''", "'''"], key: "b" },
    underline: { tags: ["__", "__"], key: "u" },
    strikethrough: { tags: ["~~", "~~"], key: "t" },
    slantedText: { tags: ["///", "\\\\\\"], key: "q" },
  };

  function wrapText(currentTag, text) {
    const [startTag, endTag] = currentTag.tags;
    const wrappedText = `${startTag}${text}${endTag}`;
    return wrappedText;
  }

  function wrapSelection(currentTag) {
    const textarea = document.activeElement;

    if (!textarea || textarea.tagName !== "TEXTAREA") return;

    const start = textarea.selectionStart;
    const end = textarea.selectionEnd;
    const selectedText = textarea.value.substring(start, end);
    const beforeText = textarea.value.substring(0, start);
    const afterText = textarea.value.substring(end);

    let wrappedText = "";
    let cursorPosition = 0;

    if (selectedText) {
      const lines = selectedText.split("\n");
      const wrappedLines = lines.map((line) => {
        if (line.trim() === "") return "";
        for (const tag of Object.values(tags))
          if (tag.key === currentTag.key) return wrapText(currentTag, line);
      });

      wrappedText = wrappedLines.join("\n");
      cursorPosition = start + wrappedText.length - currentTag.tags[1].length;
    } else {
      wrappedText = wrapText(currentTag, "");
      cursorPosition = start + currentTag.tags[0].length;
    }

    const value = beforeText + wrappedText + afterText;
    textarea.value = value.trim();
    textarea.selectionStart = textarea.selectionEnd = cursorPosition;
    // make sure the browser recognizes the change
    textarea.dispatchEvent(new Event("input", { bubbles: true }));
  }

  document.addEventListener("keydown", function (event) {
    const textarea = document.activeElement;

    if (!textarea || textarea.tagName !== "TEXTAREA") return;
    if (!event.ctrlKey) return;

    let currentTag = null;
    for (const [, value] of Object.entries(tags)) {
      if (event.key === value.key) {
        currentTag = value;
        break;
      }
    }

    if (!currentTag) return;

    event.preventDefault();
    wrapSelection(currentTag);
  });
})();
Edit Report
Pub: 16 Apr 2025 17:57 UTC
Edit: 16 Apr 2025 18:54 UTC
Views: 16