{{define "layout"}} {{template "title" .}} {{with field . "Feed"}} {{end}}
{{with field . "Repo"}}
{{$top := topTab (str $ "Tab")}}
{{if field $ "RepoHome"}}

{{.OwnerName}}/{{.Name}}

{{else}}

{{.OwnerName}}/{{.Name}}

{{end}} {{if eq .Visibility "private"}}Private{{end}} {{if .Settings.Archived}}Archived{{end}} {{/* Description, topics and website belong to the code tab, inline with the name so the header is two rows on every page. */}} {{if eq $top "code"}}{{if or (field $ "Desc") (field $ "Topics") $.Repo.Settings.Website}}

{{with field $ "Desc"}}{{.}}{{end}} {{with field $ "Topics"}}{{range .}}{{.}} {{end}}{{end}}{{with $.Repo.Settings.Website}}{{.}}{{end}}

{{end}}{{end}} {{if $.Viewer}}
Fork{{end}}
{{if eq $top "code"}}{{if field $ "Mirrors"}}

{{range $i, $m := field $ "Mirrors"}}{{if $i}} · {{end}}{{if eq $m.Direction "push"}}mirrors to{{else}}mirrors from{{end}} {{$m.Target}}{{if $m.Error}}, sync error: {{$m.Error}}{{else if $m.Synced}}, synced {{$m.Synced}}{{end}}{{end}}

{{end}}{{end}} {{/* A tab's own count badge is omitted at zero (an empty reads as stray punctuation next to the tab word); the dashboard pin row's count chip always shows its number, zero included, the same as every other count chip in the app. Two elements, two rules, decided once here (#270). */}}
{{end}}
{{template "content" .}}
{{end}} {{/* icon draws one 16px glyph for the rail. The argument names it. The paths are stroked with currentColor, so a link's own colour and the current marker carry through, and every one is hidden from the accessibility tree — the link around it carries the name. */}} {{define "icon"}}{{end}} {{/* raillink draws one square in the rail: the icon, the name for a screen reader and in the tooltip, and the bell's unread badge. */}} {{define "raillink"}}{{template "icon" .Icon}}{{.Name}}{{with .Count}}{{.}}{{end}}{{end}} {{define "mark"}}{{end}} {{define "width"}}reading{{end}} {{define "reporow"}}
  • {{.OwnerName}}/{{.Name}}{{if eq .Visibility "private"}} Private{{end}}{{if .Archived}} Archived{{end}}

    {{if .Desc}}

    {{.Desc}}

    {{end}} {{if .Topics}}

    {{range .Topics}}{{.}} {{end}}

    {{end}}

    {{template "branchicon"}} {{.DefaultBranch}}{{if .License}} · {{.License}}{{end}}{{if .Updated}} · updated {{.Updated}}{{end}}

  • {{end}} {{define "refmenu"}}{{if .Branches}}
    {{template "branchicon"}} {{.Ref}}
    {{range .Branches}}{{.Name}} {{end}}All refs →
    {{else}}{{template "branchicon"}} {{.Ref}}{{end}}{{end}} {{define "filenav"}}{{end}} {{/* Every side column's groups sit in a details.sidedrop. Below 62rem that disclosure is what the reader sees of the column: one closed line they open. Above it style.css hides the summary and shows the content whatever the open state, so the column reads as it always has (#237). The facet columns name the filters in force in the summary; the section navs head with the word alone. */}} {{define "sidecol"}}{{end}} {{define "branchicon"}}{{end}} {{define "sigbadge"}}{{sigLabel .State}}{{if .Signer}} · {{.Signer}}{{end}}{{end}} {{define "authorname"}}{{if .User}}{{.Name}}{{else}}{{.Name}}{{end}}{{end}} {{/* formatpicker is the md/org choice on a body: issue and MR create. The argument is the currently selected format; empty selects Markdown, today's default. */}} {{define "formatpicker"}}

    {{end}} {{/* previewbtn is the Preview submit beside a markup form's own submit. It posts the form to its usual action, which renders the body and hands the page back instead of writing (#235). */}} {{/* reactions is one item's reaction bar (reactionBar in httpd). A signed-in viewer gets a button per reaction; anyone else the counts. */}} {{define "reactions"}}{{if .Items}}{{if .Signed}}
    {{if .Comment}}{{end}} {{range .Items}} {{end}}
    {{else}}

    {{range .Items}}{{.Emoji}} {{.Count}} {{end}}

    {{end}}{{end}}{{end}} {{define "previewbtn"}}{{end}} {{/* previewblock shows a draft as it will read. The argument is the rendered HTML; it sits above the textarea it came from. */}} {{define "previewblock"}}

    Preview

    {{.}}
    {{end}} {{/* confirmfield is the typed-name check beside a destructive control. The argument is the text the person must type. */}} {{define "confirmfield"}}{{end}} {{/* difffiles renders a parsed diff: one foldable section per file, with line-number gutters and review threads inline. Base is the MR's endpoint and Viewer the signed-in account; the commit page passes neither and gets the same diff without review controls. */}} {{define "difffiles"}}{{$base := .Base}}{{$viewer := .Viewer}}{{$L := .L}}{{$split := false}}{{with $L}}{{$split = .Split}}{{end}} {{with $L}}{{if .UnifiedURL}}

    Layout: {{if .Split}}unified · split{{else}}unified · split{{end}}

    {{end}}{{end}} {{range $fi, $f := .Files}}
    {{if eq .Status "renamed"}}{{.OldPath}} → {{end}}{{.Path}} {{if ne .Status "modified"}}{{.Status}}{{end}} {{if .Adds}}+{{.Adds}}{{end}}{{if .Dels}} −{{.Dels}}{{end}} {{if .Binary}}

    Binary file not shown.

    {{else if $split}}
    {{range .Rows}}{{if eq .Kind "hunk"}} {{else if eq .Kind "meta"}} {{else}}{{$r := .}} {{with .Old}}{{if eq .Class "del"}}{{else}}{{end}}{{else}}{{end}} {{with .New}}{{else}}{{end}} {{with .Compose}} {{end}}{{range .Threads}} {{end}}{{end}}{{end}}
    {{.Text}}
    {{.Text}}
    {{template "cmtln" dict "N" .OldLine "Path" .Path "Side" "old" "Base" $base "Viewer" $viewer "Carry" $L.Carry}}{{if .Code}}{{.Code}}{{else}}{{.Content}}{{end}}{{with $r.OldNote}}{{.}}{{end}}{{.OldLine}}{{if .Code}}{{.Code}}{{else}}{{.Content}}{{end}}{{with $r.OldNote}}{{.}}{{end}}{{template "cmtln" dict "N" .NewLine "Path" .Path "Side" "new" "Base" $base "Viewer" $viewer "Carry" $L.Carry}}{{if .Code}}{{.Code}}{{else}}{{.Content}}{{end}}{{with $r.NewNote}}{{.}}{{end}}
    {{if ne .Class "del"}}

    to {{.NewLine}}; a ```suggestion block proposes replacement lines

    {{end}}

    Cancel

    {{template "thread" dict "T" . "Base" $base "Viewer" $viewer "Class" ""}}
    {{else}}
    {{range .Lines}}{{if eq .Class "hunk"}} {{else if eq .Class "meta"}} {{else}} {{if .Compose}} {{end}}{{end}}{{range .Threads}} {{end}}{{end}}
    {{.Text}}
    {{.Text}}
    {{if .OldLine}}{{if eq .Class "del"}}{{template "cmtln" dict "N" .OldLine "Path" .Path "Side" "old" "Base" $base "Viewer" $viewer "Carry" $L.Carry}}{{else}}{{.OldLine}}{{end}}{{end}}{{if .NewLine}}{{template "cmtln" dict "N" .NewLine "Path" .Path "Side" "new" "Base" $base "Viewer" $viewer "Carry" $L.Carry}}{{end}}{{if .Code}}{{.Code}}{{else}}{{.Content}}{{end}}
    {{if ne .Class "del"}}

    to {{.NewLine}}; a ```suggestion block proposes replacement lines

    {{end}}

    Cancel

    {{template "thread" dict "T" . "Base" $base "Viewer" $viewer "Class" ""}}
    {{end}}
    {{end}}{{end}} {{/* cmtln turns a line number into the link that opens the comment form on that line. No JavaScript: the anchor travels in the query. */}} {{define "cmtln"}}{{if and .Viewer .Base}}{{.N}}{{else}}{{.N}}{{end}}{{end}} {{/* thread renders one review thread with its reply and resolve controls. Class carries "stale" for threads whose anchor is gone. */}} {{define "thread"}}{{$t := .T}}
    {{if $t.Pending}}

    pending — only you can see this until you submit your review

    {{end}} {{if or $t.Resolved (and .Class $t.Stale)}}

    {{if and .Class $t.Stale}}stale{{end}}{{if $t.Resolved}}{{if and .Class $t.Stale}} · {{end}}resolved by {{$t.Resolved}}{{end}}

    {{end}} {{range $i, $c := $t.Comments}}

    {{.Author}} {{when .CreatedAt}}

    {{.BodyHTML}}
    {{if and (eq $i 0) $t.Suggestion}}{{template "suggestion" dict "S" $t.Suggestion "T" $t.ID "Base" $.Base}}{{end}}{{end}} {{if .Viewer}}
    Reply

    {{end}} {{if $t.CanResolve}}
    {{end}}
    {{end}} {{/* suggestion renders the lines a thread's suggestion replaces and the ones it proposes, with the apply button, or the command to run where the server cannot sign the commit. */}} {{define "suggestion"}}{{$s := .S}}

    {{if $s.Outdated}}outdated suggestion: {{$s.Reason}}{{else}}suggested change{{end}}

    {{range $s.Old}} {{end}}{{range $s.New}} {{end}}
    {{.N}}{{.Text}}
    {{.N}}{{.Text}}
    {{if and $s.CanApply (not $s.Outdated)}}{{if $s.Local}}

    This repository requires signed commits, which the server cannot make. Apply it from a clone: {{$s.Command}}

    {{else}}
    {{end}}{{end}}
    {{end}}