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.

Draw the celebration on the main thread, not in a blocked worker

6b7d6a1897dca7a8f42669a02c3f6981192ccd22 · Keenan Nemetz · 13d ago · parent 0f8054ad

Draw the celebration on the main thread, not in a blocked worker

The burst never painted. canvas-confetti's default export is built with
useWorker: true, and it builds that worker from a blob: URL, which this page's
CSP (default-src 'self', no worker-src) blocks. The library does not fall back:
it transfers its canvas to the worker with transferControlToOffscreen and then
posts to it, so the canvas is created, is full-size, is permanently empty, and
reports no error. reload, shared link and bookmark behaviour, and the address-bar
strip, all worked — which is why the flag looked handled and the burst looked
absent.

Creating our own instance with useWorker: false draws on the main thread, where
120 particles for ~2s cost nothing, and needs no CSP change. Widening the policy
with worker-src blob: to keep the offscreen path would trade a real security
boundary for a party trick.

Verified by clicking Merge in a real Firefox against a scratch instance: the
canvas has 4148 non-transparent pixels and no transferred context. The same
probe against the old build reports getContext failing with InvalidStateError.

docs/ui-plan.md +7

@@ -303,6 +303,13 @@ or a shared link is an ordinary visit; the library honours
303 303 nothing for it, which is why the 25 KB bundle is acceptable where a
304 304 loaded-always library would not be.
305 305
306 The burst always comes from an instance created with `useWorker: false`. The
307 library's default export opts into a Web Worker built from a `blob:` URL, which
308 `default-src 'self'` blocks — and it transfers its canvas to that worker before
309 drawing, so the canvas appears and stays empty with no error. Drawing on the main
310 thread avoids the CSP question entirely instead of widening the policy with
311 `worker-src blob:` for a celebration.
312
306 313 The route table is `server/routes.go`, one function per surface (assets, global,
307 314 auth, admin, repository, git). Routes are grouped by prefix rather than by
308 315 registration order because `ServeMux` ranks by pattern specificity, and the