aboutsummaryrefslogtreecommitdiff
path: root/page.ts
blob: 63705530ae2d62809939b7c5ee99e993e091ac71 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// SPDX-License-Identifier: GPL-2.0-only

import "./public-path";

import * as lowlight from "lowlight";
import latex from "highlight.js/lib/languages/latex";
import rehypeHighlight from "rehype-highlight";
import rehypeKatex from "rehype-katex";
import rehypeSanitize from "rehype-sanitize";
import rehypeStringify from "rehype-stringify";
import remarkGfm from "remark-gfm";
import remarkMath from "remark-math";
import remarkParse from "remark-parse";
import remarkRehype from "remark-rehype";
import { unified } from "unified";

import "highlight.js/styles/default.min.css";
import "katex/dist/katex.min.css";

import "./manifest.json";
import "./styles.css";

(async () => {
  console.log("ASAP: Loaded");

  // Wait for message list to appear
  const msgListCb = new MutationObserver(handleMsgList);
  msgListCb.observe(document.body, { childList: true, subtree: true });
  handleMsgList();

  function handleMsgList() {
    const list = document.querySelector(".message-list");
    if (list) {
      console.log("ASAP: Found message list");
      msgListCb.disconnect();
      // Monitor only message list for changes to reduce load
      const msgCb = new MutationObserver(handleMsg);
      msgCb.observe(list, { childList: true, subtree: true });
      handleMsg();
    }
  }

  function handleMsg() {
    const msgs = document.querySelectorAll(
      ".message-parts-container:not(.zbyffrly-done), .parent-text:not(.zbyffrly-done)"
    );
    msgs.forEach(async (msg) => {
      msg.classList.add("zbyffrly-done");

      // Replace all but '(edited)' indicator
      let text = "";
      while (msg.firstChild) {
        const node = msg.firstChild;
        if (node instanceof HTMLElement && node.classList.contains("edited"))
          break;
        else {
          msg.removeChild(node);
          text += node.textContent!;
        }
      }
      text = text.slice(0, -1); // Remove trailing space before potential '(edited)'
      msg.innerHTML = (await toHtml(text)) + msg.innerHTML;
    });
  }

  async function toHtml(s: string) {
    return String(
      await unified()
        .use(remarkParse)
        .use(remarkGfm)
        .use(remarkMath)
        .use(remarkRehype)
        .use(rehypeSanitize, { required: { code: { class: "hljs" } } }) // Style unhighlighted code
        .use(rehypeHighlight, { languages: { ...lowlight.common, latex } })
        .use(rehypeKatex, { macros: {} }) // Share macros within message
        .use(rehypeStringify)
        .process(s)
    );
  }
})();