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/ui_test.go +4−4
| @@ -254,7 +254,7 @@ func TestCodeBrowserTreeAndFragments(t *testing.T) { | |||
| 254 | 254 | !strings.Contains(fragment, `data-mode="blob"`) || | |
| 255 | 255 | strings.Contains(fragment, "<!doctype html>") || | |
| 256 | 256 | strings.Contains(fragment, `id="file-tree"`) || | |
| 257 | !strings.Contains(fragment, `class="chroma"`) { | ||
| 257 | !strings.Contains(fragment, `data-highlight="go"`) { | ||
| 258 | 258 | t.Fatalf("blob fragment = %d:\n%s", resp.StatusCode, fragment) | |
| 259 | 259 | } | |
| 260 | 260 | ||
| @@ -293,7 +293,7 @@ func TestCodeBrowserTreeAndFragments(t *testing.T) { | |||
| 293 | 293 | } | |
| 294 | 294 | } | |
| 295 | 295 | ||
| 296 | func TestSourceBlobIsHighlightedAndEscaped(t *testing.T) { | ||
| 296 | func TestSourceBlobNamesItsLanguageAndEscapes(t *testing.T) { | ||
| 297 | 297 | t.Parallel() | |
| 298 | 298 | f := newFixture(t) | |
| 299 | 299 | f.publish(f.repo) | |
| @@ -307,8 +307,8 @@ func TestSourceBlobIsHighlightedAndEscaped(t *testing.T) { | |||
| 307 | 307 | if code != 200 { | |
| 308 | 308 | t.Fatalf("blob = %d", code) | |
| 309 | 309 | } | |
| 310 | if !strings.Contains(body, `class="chroma"`) { | ||
| 311 | t.Fatalf("source was not highlighted:\n%s", body[:min(len(body), 500)]) | ||
| 310 | if !strings.Contains(body, `data-highlight="go"`) { | ||
| 311 | t.Fatalf("source did not name its language:\n%s", body[:min(len(body), 500)]) | ||
| 312 | 312 | } | |
| 313 | 313 | if strings.Contains(body, "<script>alert(1)</script>") { | |
| 314 | 314 | t.Fatalf("source blob executed a tag:\n%s", body) | |