annotate mrjunejune/src/tools/latex_editor/index.js @ 245:3843bb6253ac

[tools] Debounce live LaTeX preview Co-authored-by: Copilot <[email protected]>
author MrJuneJune <me@mrjunejune.com>
date Mon, 03 Aug 2026 18:23:36 -0700
parents b8aa08503378
children
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";
245
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
6 const AUTO_COMPILE_DELAY = 500;
244
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 compileGeneration = 0;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
34 let controller = null;
245
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
35 let compilePending = false;
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
36 let retryDelay = 0;
244
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
37
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
38 const byteLength = value => new TextEncoder().encode(value).byteLength;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
39
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
40 const setStatus = (message, state) => {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
41 status.textContent = message;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
42 status.dataset.state = state;
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
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
45 const updateSize = () => {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
46 const size = byteLength(source.value);
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
47 sourceSize.textContent = `${size.toLocaleString()} / ${SOURCE_LIMIT.toLocaleString()} bytes`;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
48 sourceSize.dataset.overLimit = size > SOURCE_LIMIT ? "true" : "false";
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
49 return size;
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
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
52 const clearPdf = () => {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
53 if (currentPdfUrl) URL.revokeObjectURL(currentPdfUrl);
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
54 currentPdfUrl = null;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
55 preview.src = "about:blank";
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
56 download.removeAttribute("href");
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
57 download.removeAttribute("download");
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
58 download.classList.add("disabled");
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
59 download.setAttribute("aria-disabled", "true");
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
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
62 const showDiagnostics = message => {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
63 clearPdf();
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
64 diagnostics.textContent = message;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
65 diagnostics.hidden = false;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
66 preview.hidden = true;
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
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
69 const showPdf = blob => {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
70 if (currentPdfUrl) URL.revokeObjectURL(currentPdfUrl);
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
71 currentPdfUrl = URL.createObjectURL(blob);
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
72 diagnostics.hidden = true;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
73 preview.hidden = false;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
74 preview.src = currentPdfUrl;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
75 download.href = currentPdfUrl;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
76 download.download = "document.pdf";
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
77 download.classList.remove("disabled");
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
78 download.setAttribute("aria-disabled", "false");
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
245
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
81 const createDebouncer = (callback, delay) => {
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
82 let timer = null;
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
83 const schedule = (nextDelay = delay) => {
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
84 clearTimeout(timer);
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
85 timer = setTimeout(() => {
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
86 timer = null;
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
87 callback();
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
88 }, nextDelay);
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
89 };
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
90 schedule.cancel = () => {
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
91 clearTimeout(timer);
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
92 timer = null;
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
93 };
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
94 return schedule;
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
95 };
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
96
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
97 let queueCompile;
244
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
98 const compile = async () => {
245
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
99 queueCompile.cancel();
244
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
100 const generation = ++compileGeneration;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
101 const text = source.value;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
102 const size = updateSize();
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
103 if (!text.trim()) {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
104 showDiagnostics("Write some LaTeX before compiling.");
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
105 setStatus("Nothing to compile.", "error");
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
106 return;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
107 }
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
108 if (size > SOURCE_LIMIT) {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
109 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
110 setStatus("Source is too large.", "error");
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
111 return;
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
245
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
114 if (controller) {
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
115 compilePending = true;
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
116 setStatus("Finishing the current PDF, then compiling your latest changes...", "working");
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
117 return;
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
118 }
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
119
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
120 compilePending = false;
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
121 const requestController = new AbortController();
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
122 controller = requestController;
244
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
123 compileButton.disabled = true;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
124 setStatus("Compiling on the server...", "working");
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 try {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
127 const response = await fetch("/api/latex/render", {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
128 method: "POST",
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
129 headers: {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
130 "Content-Type": "text/plain; charset=utf-8",
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
131 },
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
132 body: text,
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
133 cache: "no-store",
245
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
134 signal: requestController.signal,
244
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
135 });
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
136 if (generation !== compileGeneration) return;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
137
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
138 if (!response.ok) {
245
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
139 if (response.status === 429) {
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
140 compilePending = true;
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
141 retryDelay = 1000;
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
142 setStatus("The compiler is busy. Your latest changes are queued.", "working");
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
143 return;
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
144 }
244
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
145 const message = await response.text();
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
146 showDiagnostics(message || `Compilation failed (${response.status}).`);
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
147 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
148 return;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
149 }
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
150
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
151 const blob = await response.blob();
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
152 if (blob.type !== "application/pdf" || blob.size < 5) {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
153 throw new Error("The server returned an invalid PDF.");
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 showPdf(blob);
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
156 setStatus(
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
157 `PDF ready (${Math.ceil(blob.size / 1024).toLocaleString()} KiB).`,
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
158 "ready",
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
159 );
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
160 } catch (error) {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
161 if (error.name === "AbortError" || generation !== compileGeneration) return;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
162 showDiagnostics(error.message || "Unable to compile this document.");
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
163 setStatus("The PDF request failed.", "error");
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
164 } finally {
245
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
165 if (controller === requestController) {
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
166 controller = null;
244
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
167 compileButton.disabled = false;
245
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
168 }
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
169 if (compilePending && !controller) {
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
170 compilePending = false;
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
171 const delay = retryDelay;
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
172 retryDelay = 0;
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
173 queueCompile(delay);
244
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
174 }
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 };
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
177
245
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
178 queueCompile = createDebouncer(compile, AUTO_COMPILE_DELAY);
244
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
179
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
180 const invalidateCompile = () => {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
181 compileGeneration++;
245
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
182 compilePending = false;
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
183 retryDelay = 0;
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
184 queueCompile.cancel();
244
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
185 };
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
186
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
187 source.addEventListener("input", () => {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
188 localStorage.setItem(STORAGE_KEY, source.value);
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
189 invalidateCompile();
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
190 const size = updateSize();
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
191 if (!source.value.trim()) {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
192 showDiagnostics("Write some LaTeX before compiling.");
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
193 setStatus("Nothing to compile.", "error");
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
194 return;
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 if (size > SOURCE_LIMIT) {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
197 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
198 setStatus("Source is too large.", "error");
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
199 return;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
200 }
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
201 setStatus(
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
202 autoCompile.checked ? "Waiting to compile..." : "Changes ready to compile.",
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
203 "working",
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
204 );
245
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
205 if (autoCompile.checked) queueCompile();
244
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
206 });
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
207 source.addEventListener("keydown", event => {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
208 if ((event.ctrlKey || event.metaKey) && event.key === "Enter") {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
209 event.preventDefault();
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
210 compile();
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
211 }
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
212 });
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
213 compileButton.addEventListener("click", compile);
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
214 resetButton.addEventListener("click", () => {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
215 source.value = defaultSource;
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
216 localStorage.removeItem(STORAGE_KEY);
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
217 updateSize();
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
218 compile();
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
219 });
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
220 autoCompile.addEventListener("change", () => {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
221 if (autoCompile.checked) queueCompile();
245
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
222 else {
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
223 queueCompile.cancel();
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
224 compilePending = false;
3843bb6253ac [tools] Debounce live LaTeX preview
MrJuneJune <me@mrjunejune.com>
parents: 244
diff changeset
225 }
244
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
226 });
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
227 window.addEventListener("beforeunload", () => {
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
228 if (controller) controller.abort();
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
229 if (currentPdfUrl) URL.revokeObjectURL(currentPdfUrl);
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
230 });
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
231
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
232 updateSize();
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
233 compile();
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
234 });
b8aa08503378 [tools] Add sandboxed online LaTeX editor
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
235 })();