annotate mrjunejune/src/tools/latex_editor/index.js @ 244:b8aa08503378

[tools] Add sandboxed online LaTeX editor Co-authored-by: Copilot <[email protected]>
author MrJuneJune <me@mrjunejune.com>
date Mon, 03 Aug 2026 16:56:25 -0700
parents
children 3843bb6253ac
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
244
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1 (function latexEditor() {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2 "use strict";
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
3
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
4 const SOURCE_LIMIT = 64 * 1024;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
5 const STORAGE_KEY = "mrjunejune-latex-source";
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
6 const AUTO_COMPILE_DELAY = 700;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
7
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
8 window.addEventListener("DOMContentLoaded", () => {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
9 const source = document.querySelector("#latexSource");
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
10 const compileButton = document.querySelector("#compileButton");
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
11 const resetButton = document.querySelector("#resetButton");
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
12 const autoCompile = document.querySelector("#autoCompile");
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
13 const status = document.querySelector("#latexStatus");
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
14 const sourceSize = document.querySelector("#sourceSize");
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
15 const preview = document.querySelector("#pdfPreview");
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
16 const diagnostics = document.querySelector("#latexDiagnostics");
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
17 const download = document.querySelector("#downloadButton");
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
18 if (!source ||
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
19 !compileButton ||
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
20 !resetButton ||
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
21 !autoCompile ||
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
22 !status ||
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
23 !sourceSize ||
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
24 !preview ||
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
25 !diagnostics ||
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
26 !download) return;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
27
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
28 const defaultSource = source.value;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
29 const savedSource = localStorage.getItem(STORAGE_KEY);
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
30 if (savedSource) source.value = savedSource;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
31
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
32 let currentPdfUrl = null;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
33 let compileTimer = null;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
34 let compileGeneration = 0;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
35 let controller = null;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
36
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
37 const byteLength = value => new TextEncoder().encode(value).byteLength;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
38
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
39 const setStatus = (message, state) => {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
40 status.textContent = message;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
41 status.dataset.state = state;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
42 };
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
43
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
44 const updateSize = () => {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
45 const size = byteLength(source.value);
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
46 sourceSize.textContent = `${size.toLocaleString()} / ${SOURCE_LIMIT.toLocaleString()} bytes`;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
47 sourceSize.dataset.overLimit = size > SOURCE_LIMIT ? "true" : "false";
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
48 return size;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
49 };
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
50
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
51 const clearPdf = () => {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
52 if (currentPdfUrl) URL.revokeObjectURL(currentPdfUrl);
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
53 currentPdfUrl = null;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
54 preview.src = "about:blank";
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
55 download.removeAttribute("href");
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
56 download.removeAttribute("download");
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
57 download.classList.add("disabled");
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
58 download.setAttribute("aria-disabled", "true");
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
59 };
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
60
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
61 const showDiagnostics = message => {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
62 clearPdf();
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
63 diagnostics.textContent = message;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
64 diagnostics.hidden = false;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
65 preview.hidden = true;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
66 };
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
67
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
68 const showPdf = blob => {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
69 if (currentPdfUrl) URL.revokeObjectURL(currentPdfUrl);
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
70 currentPdfUrl = URL.createObjectURL(blob);
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
71 diagnostics.hidden = true;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
72 preview.hidden = false;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
73 preview.src = currentPdfUrl;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
74 download.href = currentPdfUrl;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
75 download.download = "document.pdf";
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
76 download.classList.remove("disabled");
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
77 download.setAttribute("aria-disabled", "false");
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
78 };
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
79
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
80 const compile = async () => {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
81 clearTimeout(compileTimer);
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
82 const generation = ++compileGeneration;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
83 if (controller) controller.abort();
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
84 controller = null;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
85 compileButton.disabled = false;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
86 const text = source.value;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
87 const size = updateSize();
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
88 if (!text.trim()) {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
89 showDiagnostics("Write some LaTeX before compiling.");
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
90 setStatus("Nothing to compile.", "error");
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
91 return;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
92 }
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
93 if (size > SOURCE_LIMIT) {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
94 showDiagnostics("The server accepts at most 64 KiB of LaTeX source.");
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
95 setStatus("Source is too large.", "error");
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
96 return;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
97 }
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
98
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
99 controller = new AbortController();
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
100 compileButton.disabled = true;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
101 setStatus("Compiling on the server...", "working");
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
102
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
103 try {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
104 const response = await fetch("/api/latex/render", {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
105 method: "POST",
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
106 headers: {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
107 "Content-Type": "text/plain; charset=utf-8",
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
108 },
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
109 body: text,
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
110 cache: "no-store",
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
111 signal: controller.signal,
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
112 });
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
113 if (generation !== compileGeneration) return;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
114
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
115 if (!response.ok) {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
116 const message = await response.text();
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
117 showDiagnostics(message || `Compilation failed (${response.status}).`);
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
118 setStatus("Fix the LaTeX errors shown in the preview pane.", "error");
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
119 return;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
120 }
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
121
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
122 const blob = await response.blob();
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
123 if (blob.type !== "application/pdf" || blob.size < 5) {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
124 throw new Error("The server returned an invalid PDF.");
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
125 }
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
126 showPdf(blob);
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
127 setStatus(
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
128 `PDF ready (${Math.ceil(blob.size / 1024).toLocaleString()} KiB).`,
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
129 "ready",
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
130 );
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
131 } catch (error) {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
132 if (error.name === "AbortError" || generation !== compileGeneration) return;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
133 showDiagnostics(error.message || "Unable to compile this document.");
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
134 setStatus("The PDF request failed.", "error");
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
135 } finally {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
136 if (generation === compileGeneration) {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
137 compileButton.disabled = false;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
138 controller = null;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
139 }
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
140 }
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
141 };
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
142
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
143 const queueCompile = () => {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
144 clearTimeout(compileTimer);
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
145 if (!autoCompile.checked) return;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
146 compileTimer = setTimeout(compile, AUTO_COMPILE_DELAY);
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
147 };
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
148
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
149 const invalidateCompile = () => {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
150 compileGeneration++;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
151 if (controller) controller.abort();
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
152 controller = null;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
153 compileButton.disabled = false;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
154 };
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
155
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
156 source.addEventListener("input", () => {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
157 localStorage.setItem(STORAGE_KEY, source.value);
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
158 invalidateCompile();
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
159 const size = updateSize();
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
160 if (!source.value.trim()) {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
161 showDiagnostics("Write some LaTeX before compiling.");
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
162 setStatus("Nothing to compile.", "error");
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
163 return;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
164 }
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
165 if (size > SOURCE_LIMIT) {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
166 showDiagnostics("The server accepts at most 64 KiB of LaTeX source.");
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
167 setStatus("Source is too large.", "error");
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
168 return;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
169 }
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
170 setStatus(
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
171 autoCompile.checked ? "Waiting to compile..." : "Changes ready to compile.",
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
172 "working",
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
173 );
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
174 queueCompile();
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
175 });
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
176 source.addEventListener("keydown", event => {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
177 if ((event.ctrlKey || event.metaKey) && event.key === "Enter") {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
178 event.preventDefault();
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
179 compile();
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
180 }
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
181 });
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
182 compileButton.addEventListener("click", compile);
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
183 resetButton.addEventListener("click", () => {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
184 source.value = defaultSource;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
185 localStorage.removeItem(STORAGE_KEY);
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
186 updateSize();
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
187 compile();
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
188 });
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
189 autoCompile.addEventListener("change", () => {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
190 if (autoCompile.checked) queueCompile();
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
191 });
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
192 window.addEventListener("beforeunload", () => {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
193 if (controller) controller.abort();
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
194 if (currentPdfUrl) URL.revokeObjectURL(currentPdfUrl);
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
195 });
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
196
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
197 updateSize();
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
198 compile();
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
199 });
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
200 })();