Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

vole
Clone

Read only, no credentials:

https://rodent.software/git/vole.git

Write over SSH with a registered key:

git clone ssh://git@0.0.0.0:2222/vole.git

A free and open-source forge that lives in your Git repo.

Highlight with Prism in a worker and gzip text responses

306f36fcef89c145abcd0c5331453d0b179f37ce · Keenan Nemetz · 12d ago · parent e5542ac6

Highlight with Prism in a worker and gzip text responses

The code browser now names a blob's language and lets the browser colour it.
Chroma is gone: server/web/highlight.go is an extension table, and
static/prism-worker.js runs Prism — every language Prism ships — off the main
thread. The server sends escaped lines with their numbers and L# anchors, so a
page is complete and scrollable before any script runs and the worker only swaps
the contents of each line cell. The table covers 186 languages; a file it does
not claim stays plain rather than being coloured by a guess.

The bundle those grammars make is 545 KB, so the instance now gzips text
responses itself instead of relying on a proxy, and static assets carry a
content ETag so a browser revalidates with a 304 rather than re-downloading the
bundle on every code page. The raw-download route opts out with
Cache-Control: no-transform because it promises an exact Content-Length.

This also makes JavaScript a requirement rather than a nicety: the label and
assignee token inputs lose their noscript save buttons and their comma-separated
text fallback, and the docs say so.

Measured: release binary 26.08 MB -> 22.70 MB; /r/{repo}/code 11.1 KB -> 2.6 KB
over the wire; the Prism bundle 545 KB -> 206 KB gzipped, fetched once.

scripts/vendor-prism.py regenerates the bundle from Prism's components.json
require graph, and --check fails if the committed assets drift.

server/web/highlight_test.go +76

@@ -0,0 +1,76 @@
1 package web
2
3 import (
4 "os"
5 "strings"
6 "testing"
7 )
8
9 func TestPrismLanguageNamesKnownFiles(t *testing.T) {
10 t.Parallel()
11 for name, want := range map[string]string{
12 "main.go": "go",
13 "internal/run.go": "go",
14 "web/app.tsx": "typescript",
15 "script.mjs": "javascript",
16 "style.scss": "scss",
17 "deploy/nginx.conf": "nginx",
18 "app.conf": "ini",
19 "Makefile": "makefile",
20 "cmake/CMakeLists.txt": "cmake",
21 "Dockerfile": "docker",
22 "Containerfile": "docker",
23 ".editorconfig": "editorconfig",
24 "README.MD": "markdown",
25 "terraform/main.tf": "hcl",
26 // A file the highlighter does not claim stays plain: a wrong grammar is
27 // worse than no grammar.
28 "go.sum": "go-module",
29 "app.py": "python",
30 "lib.rs": "rust",
31 "main.js": "javascript",
32 "component.tsx": "typescript",
33 "deploy.tf": "hcl",
34 "schema.graphql": "graphql",
35 "queries.sql": "sql",
36 "notes.rst": "rest",
37 "LICENSE": "",
38 "notes.txt": "",
39 "image.webp": "",
40 } {
41 if got := prismLanguage(name); got != want {
42 t.Errorf("prismLanguage(%q) = %q, want %q", name, got, want)
43 }
44 }
45 }
46
47 // TestPrismLanguagesAreVendored holds the server's table to the worker's bundle.
48 // A name here with no grammar there colours nothing, and nothing fails at build
49 // time; the blob just quietly stays plain.
50 func TestPrismLanguagesAreVendored(t *testing.T) {
51 t.Parallel()
52 var sources []string
53 for _, path := range []string{"static/prism.min.js", "static/prism-languages.min.js"} {
54 data, err := os.ReadFile(path)
55 if err != nil {
56 t.Fatalf("vendored Prism is missing: %v", err)
57 }
58 sources = append(sources, string(data))
59 }
60 defined := func(lang string) bool {
61 for _, src := range sources {
62 // Prism registers a language as `languages.name=` or, for a name with
63 // punctuation in it, `languages["name"]=`.
64 if strings.Contains(src, "languages."+lang+"=") ||
65 strings.Contains(src, `languages["`+lang+`"]=`) {
66 return true
67 }
68 }
69 return false
70 }
71 for name, lang := range prismLanguages {
72 if !defined(lang) {
73 t.Errorf("%q is mapped to %q, which static/prism-languages.min.js does not define", name, lang)
74 }
75 }
76 }