aboutsummaryrefslogtreecommitdiff
path: root/page.ts
diff options
context:
space:
mode:
Diffstat (limited to 'page.ts')
-rw-r--r--page.ts80
1 files changed, 80 insertions, 0 deletions
diff --git a/page.ts b/page.ts
new file mode 100644
index 0000000..6370553
--- /dev/null
+++ b/page.ts
@@ -0,0 +1,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)
+ );
+ }
+})();