Commit 191da4bb52
191da4bb528ee095de7ce47d59ee2c8e456cf483
parent: 8bae67052c
Verified · cmc ci/build: success ci/test: success ci/vuln: success
cmc <hello@cleberg.net> · 2026-09-04 01:43 UTC
web: the pin glyph is decoration, tables have headers, filters say which is current
The pin control read "black star Pin" to a screen reader; the star is
aria-hidden and the word carries the meaning. The refs and release
asset tables had no header row; both have scoped column headers. The
state filters on issues, merge requests and milestones marked the
active one by colour only; it carries aria-current now.
Ref #133
Layout: unified · split
e2e/design_test.go
+2 −2
| @@ -186,14 +186,14 @@ func TestWebInteractions(t *testing.T) { |
| 186 | t.Fatal("pin toggle failed") |
186 | t.Fatal("pin toggle failed") |
| 187 | } |
187 | } |
| 188 | _, body := browserGet(t, browser, inst.base()+"/theorg/webborn") |
188 | _, body := browserGet(t, browser, inst.base()+"/theorg/webborn") |
| 189 | if !strings.Contains(body, "★ Pinned") { |
189 | if !strings.Contains(body, "</span> Pinned</button>") { |
| 190 | t.Fatal("repo header not pinned") |
190 | t.Fatal("repo header not pinned") |
| 191 | } |
191 | } |
| 192 | if _, body = browserGet(t, browser, inst.base()+"/"); !strings.Contains(body, ">theorg/</span>webborn") { |
192 | if _, body = browserGet(t, browser, inst.base()+"/"); !strings.Contains(body, ">theorg/</span>webborn") { |
| 193 | t.Fatal("dashboard missing pinned repo") |
193 | t.Fatal("dashboard missing pinned repo") |
| 194 | } |
194 | } |
| 195 | browserPost(t, browser, inst.base()+"/theorg/webborn/pin", url.Values{}) |
195 | browserPost(t, browser, inst.base()+"/theorg/webborn/pin", url.Values{}) |
| 196 | if _, body = browserGet(t, browser, inst.base()+"/theorg/webborn"); !strings.Contains(body, "☆ Pin") { |
196 | if _, body = browserGet(t, browser, inst.base()+"/theorg/webborn"); !strings.Contains(body, "</span> Pin</button>") { |
| 197 | t.Fatal("unpin failed") |
197 | t.Fatal("unpin failed") |
| 198 | } |
198 | } |
| 199 | |
199 | |
internal/web/static/style.css
+8
| @@ -523,6 +523,14 @@ table.tree td.size { text-align: right; } |
| 523 | table.tree td.empty, table.refs td.empty, li.empty, ul.loglist li.empty { color: var(--muted); } |
523 | table.tree td.empty, table.refs td.empty, li.empty, ul.loglist li.empty { color: var(--muted); } |
| 524 | |
524 | |
| 525 | /* refs page */ |
525 | /* refs page */ |
| |
526 | table.refs th, table.assets th { |
| |
527 | text-align: left; |
| |
528 | font-size: var(--fs-0); |
| |
529 | font-weight: 500; |
| |
530 | color: var(--muted); |
| |
531 | padding: var(--sp-1) var(--sp-2); |
| |
532 | border-bottom: 1px solid var(--line); |
| |
533 | } |
| 526 | table.refs td.name { width: 100%; } |
534 | table.refs td.name { width: 100%; } |
| 527 | table.refs td.sha { color: var(--muted); } |
535 | table.refs td.sha { color: var(--muted); } |
| 528 | |
536 | |
internal/web/templates/issues.html
+3 −3
| @@ -3,9 +3,9 @@ |
| 3 | <div class="listhead"> |
3 | <div class="listhead"> |
| 4 | <h1>Issues</h1> |
4 | <h1>Issues</h1> |
| 5 | <nav class="filters"> |
5 | <nav class="filters"> |
| 6 | <a {{if eq .State "open"}}class="active" {{end}}href="?state=open">open</a> |
6 | <a {{if eq .State "open"}}class="active" aria-current="page" {{end}}href="?state=open">open</a> |
| 7 | <a {{if eq .State "closed"}}class="active" {{end}}href="?state=closed">closed</a> |
7 | <a {{if eq .State "closed"}}class="active" aria-current="page" {{end}}href="?state=closed">closed</a> |
| 8 | <a {{if eq .State "all"}}class="active" {{end}}href="?state=all">all</a> |
8 | <a {{if eq .State "all"}}class="active" aria-current="page" {{end}}href="?state=all">all</a> |
| 9 | </nav> |
9 | </nav> |
| 10 | {{range .Filters}}<p class="meta">{{.Key}}: {{if eq .Key "label"}}<span class="chip label" style="{{index $.LabelColors .Value}}">{{.Value}}</span>{{else}}<b>{{.Value}}</b>{{end}} <a href="{{.Clear}}">clear</a></p>{{end}} |
10 | {{range .Filters}}<p class="meta">{{.Key}}: {{if eq .Key "label"}}<span class="chip label" style="{{index $.LabelColors .Value}}">{{.Value}}</span>{{else}}<b>{{.Value}}</b>{{end}} <a href="{{.Clear}}">clear</a></p>{{end}} |
| 11 | <span class="spacer"></span> |
11 | <span class="spacer"></span> |
internal/web/templates/layout.html
+1 −1
| @@ -59,7 +59,7 @@ |
| 59 | {{if eq .Visibility "private"}}<span class="chip">Private</span>{{end}} |
59 | {{if eq .Visibility "private"}}<span class="chip">Private</span>{{end}} |
| 60 | {{if .Settings.Archived}}<span class="chip">Archived</span>{{end}} |
60 | {{if .Settings.Archived}}<span class="chip">Archived</span>{{end}} |
| 61 | <span class="grow"></span> |
61 | <span class="grow"></span> |
| 62 | {{if $.Viewer}}<form method="post" action="/{{.OwnerName}}/{{.Name}}/pin" class="inline"><button type="submit" class="btn" aria-pressed="{{if field $ "Pinned"}}true{{else}}false{{end}}">{{if field $ "Pinned"}}★ Pinned{{else}}☆ Pin{{end}}</button></form>{{end}} |
62 | {{if $.Viewer}}<form method="post" action="/{{.OwnerName}}/{{.Name}}/pin" class="inline"><button type="submit" class="btn" aria-pressed="{{if field $ "Pinned"}}true{{else}}false{{end}}"><span aria-hidden="true">{{if field $ "Pinned"}}★{{else}}☆{{end}}</span> {{if field $ "Pinned"}}Pinned{{else}}Pin{{end}}</button></form>{{end}} |
| 63 | </div> |
63 | </div> |
| 64 | {{with field $ "Desc"}}<p class="repodesc">{{.}}</p>{{end}} |
64 | {{with field $ "Desc"}}<p class="repodesc">{{.}}</p>{{end}} |
| 65 | {{with field $ "Topics"}}<p class="topics">{{range .}}<a class="chip topic" href="/explore?q={{.}}">{{.}}</a> {{end}}</p>{{end}} |
65 | {{with field $ "Topics"}}<p class="topics">{{range .}}<a class="chip topic" href="/explore?q={{.}}">{{.}}</a> {{end}}</p>{{end}} |
internal/web/templates/milestones.html
+3 −3
| @@ -3,9 +3,9 @@ |
| 3 | <div class="listhead"> |
3 | <div class="listhead"> |
| 4 | <h1>Milestones</h1> |
4 | <h1>Milestones</h1> |
| 5 | <nav class="filters"> |
5 | <nav class="filters"> |
| 6 | <a {{if eq .State "open"}}class="active" {{end}}href="?state=open">open</a> |
6 | <a {{if eq .State "open"}}class="active" aria-current="page" {{end}}href="?state=open">open</a> |
| 7 | <a {{if eq .State "closed"}}class="active" {{end}}href="?state=closed">closed</a> |
7 | <a {{if eq .State "closed"}}class="active" aria-current="page" {{end}}href="?state=closed">closed</a> |
| 8 | <a {{if eq .State "all"}}class="active" {{end}}href="?state=all">all</a> |
8 | <a {{if eq .State "all"}}class="active" aria-current="page" {{end}}href="?state=all">all</a> |
| 9 | </nav> |
9 | </nav> |
| 10 | </div> |
10 | </div> |
| 11 | <ul class="milestonelist"> |
11 | <ul class="milestonelist"> |
internal/web/templates/mrs.html
+4 −4
| @@ -3,10 +3,10 @@ |
| 3 | <div class="listhead"> |
3 | <div class="listhead"> |
| 4 | <h1>Merge requests</h1> |
4 | <h1>Merge requests</h1> |
| 5 | <nav class="filters"> |
5 | <nav class="filters"> |
| 6 | <a {{if eq .State "open"}}class="active" {{end}}href="?state=open">open</a> |
6 | <a {{if eq .State "open"}}class="active" aria-current="page" {{end}}href="?state=open">open</a> |
| 7 | <a {{if eq .State "merged"}}class="active" {{end}}href="?state=merged">merged</a> |
7 | <a {{if eq .State "merged"}}class="active" aria-current="page" {{end}}href="?state=merged">merged</a> |
| 8 | <a {{if eq .State "closed"}}class="active" {{end}}href="?state=closed">closed</a> |
8 | <a {{if eq .State "closed"}}class="active" aria-current="page" {{end}}href="?state=closed">closed</a> |
| 9 | <a {{if eq .State "all"}}class="active" {{end}}href="?state=all">all</a> |
9 | <a {{if eq .State "all"}}class="active" aria-current="page" {{end}}href="?state=all">all</a> |
| 10 | </nav> |
10 | </nav> |
| 11 | {{range .Filters}}<p class="meta">{{.Key}}: <b>{{.Value}}</b> <a href="{{.Clear}}">clear</a></p>{{end}} |
11 | {{range .Filters}}<p class="meta">{{.Key}}: <b>{{.Value}}</b> <a href="{{.Clear}}">clear</a></p>{{end}} |
| 12 | </div> |
12 | </div> |
internal/web/templates/refs.html
+2 −2
| @@ -2,7 +2,7 @@ |
| 2 | {{define "content"}} |
2 | {{define "content"}} |
| 3 | <h1>Refs</h1> |
3 | <h1>Refs</h1> |
| 4 | <h2>Branches</h2> |
4 | <h2>Branches</h2> |
| 5 | <table class="refs">{{range .Branches}}<tr><td class="name">{{template "branchicon"}} <a href="/{{$.Repo.OwnerName}}/{{$.Repo.Name}}/tree/{{.Name}}/">{{.Name}}</a></td><td class="sha"><code>{{short .SHA}}</code></td></tr>{{else}}<tr><td class="empty">none</td></tr>{{end}}</table> |
5 | <table class="refs"><thead><tr><th scope="col">Branch</th><th scope="col">Commit</th></tr></thead>{{range .Branches}}<tr><td class="name">{{template "branchicon"}} <a href="/{{$.Repo.OwnerName}}/{{$.Repo.Name}}/tree/{{.Name}}/">{{.Name}}</a></td><td class="sha"><code>{{short .SHA}}</code></td></tr>{{else}}<tr><td class="empty">none</td></tr>{{end}}</table> |
| 6 | <h2>Tags</h2> |
6 | <h2>Tags</h2> |
| 7 | <table class="refs">{{range .Tags}}<tr><td class="name"><a href="/{{$.Repo.OwnerName}}/{{$.Repo.Name}}/tree/{{.Name}}/">{{.Name}}</a></td><td class="sha"><code>{{short .SHA}}</code></td></tr>{{else}}<tr><td class="empty">none</td></tr>{{end}}</table> |
7 | <table class="refs"><thead><tr><th scope="col">Tag</th><th scope="col">Commit</th></tr></thead>{{range .Tags}}<tr><td class="name"><a href="/{{$.Repo.OwnerName}}/{{$.Repo.Name}}/tree/{{.Name}}/">{{.Name}}</a></td><td class="sha"><code>{{short .SHA}}</code></td></tr>{{else}}<tr><td class="empty">none</td></tr>{{end}}</table> |
| 8 | {{end}} |
8 | {{end}} |
internal/web/templates/releases.html
+1
| @@ -33,6 +33,7 @@ |
| 33 | <p><button type="submit">Save</button></p> |
33 | <p><button type="submit">Save</button></p> |
| 34 | </form></details>{{end}} |
34 | </form></details>{{end}} |
| 35 | {{if $rel.Assets}}<table class="assets"> |
35 | {{if $rel.Assets}}<table class="assets"> |
| |
36 | <thead><tr><th scope="col">File</th><th scope="col">Bytes</th><th scope="col">SHA-256</th></tr></thead> |
| 36 | {{range $rel.Assets}}<tr> |
37 | {{range $rel.Assets}}<tr> |
| 37 | <td class="name"><a href="/{{$.Repo.OwnerName}}/{{$.Repo.Name}}/releases/download/{{$rel.Tag}}/{{.Name}}">{{.Name}}</a></td> |
38 | <td class="name"><a href="/{{$.Repo.OwnerName}}/{{$.Repo.Name}}/releases/download/{{$rel.Tag}}/{{.Name}}">{{.Name}}</a></td> |
| 38 | <td class="size">{{.Size}}</td> |
39 | <td class="size">{{.Size}}</td> |