Mercurial
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 |
| 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 })(); |