oficina / estilo Public

Clone
git clone https://amadan.net/oficina/estilo

Plain git — no account needed to clone.

Download

Download this file

1package theme
2
3import (
4 "embed"
5 "net/http"
6 "strings"
7)
8
9// Onest is Calma's typeface: the Latin subset of the variable font
10// (weights 300-800), SIL Open Font License 1.1. Provenance and the
11// licence are in credits/notices/onest-*; list them on the app's credits
12// page with credits.Onest().
13
14//go:embed fonts/onest-latin.woff2
15var fontFS embed.FS
16
17// FontPrefix is the URL path FontHandler serves under. Its version moves
18// whenever either file's bytes do (a new subset, a newer Onest, a changed
19// unicode-range): browsers hold both for a year under this path.
20const FontPrefix = "/static/estilo/fonts/v1/"
21
22// fontCSS declares Onest for the Latin range; a character outside it
23// falls through to the system face in --rst-font, glyph by glyph.
24const fontCSS = `/* Onest, Calma's typeface (estilo theme/fonts.go). */
25@font-face {
26 font-family: "Onest";
27 font-style: normal;
28 font-weight: 300 800;
29 font-display: swap;
30 src: url("` + FontPrefix + `onest-latin.woff2") format("woff2");
31 unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
32}
33`
34
35// FontCSS is the @font-face stylesheet, served by FontHandler as
36// FontPrefix + "fonts.css". Link it before theme.css. Without it the
37// theme still works, in the system face.
38func FontCSS() []byte { return []byte(fontCSS) }
39
40// FontHandler serves GET and HEAD for FontPrefix + "fonts.css" and
41// FontPrefix + "onest-latin.woff2". Mount it at FontPrefix; anything else
42// under it is 404. Public, sessionless, and the bytes never change under
43// a name, so both are cached for a year.
44func FontHandler() http.Handler {
45 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
46 name := strings.TrimPrefix(r.URL.Path, FontPrefix)
47 var body []byte
48 var kind string
49 switch {
50 case !strings.HasPrefix(r.URL.Path, FontPrefix):
51 case name == "fonts.css":
52 body, kind = FontCSS(), "text/css; charset=utf-8"
53 case name == "onest-latin.woff2":
54 body, _ = fontFS.ReadFile("fonts/onest-latin.woff2")
55 kind = "font/woff2"
56 }
57 if body == nil {
58 http.NotFound(w, r)
59 return
60 }
61 if r.Method != http.MethodGet && r.Method != http.MethodHead {
62 w.Header().Set("Allow", "GET, HEAD")
63 http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
64 return
65 }
66 w.Header().Set("Content-Type", kind)
67 w.Header().Set("Cache-Control", "public, max-age=31536000, immutable")
68 w.Header().Set("X-Content-Type-Options", "nosniff")
69 if r.Method == http.MethodHead {
70 return
71 }
72 _, _ = w.Write(body)
73 })
74}
75