// SPDX-License-Identifier: AGPL-3.0-or-later package web // Commit is a commit: the message and facts, the diff tools, the diff. templ Commit(l Layout, p CommitPage) { @Shell(l, commitRail(p)) {

{ p.Subject }

if p.Body != "" {
{ p.Body }
}
commit
{ p.SHA }
author
@personView(p.Author)
if p.Committer != nil {
committer
@personView(*p.Committer)
}
if p.Merge { merge of } else { parent }
if p.Root { none (root commit) } for i, par := range p.Parents { if i > 0 { { " + " } } { par.Label } } if p.Merge { { " · diff against the first parent" } }
if len(p.Refs) > 0 {
refs
for _, r := range p.Refs { { r } }
}
if p.Invisible {

this diff holds invisible characters (direction controls, zero-width characters). They are shown as <U+XXXX> markers, never applied.

} if p.Note != "" {

{ p.Note }

}
for _, f := range p.Files { @DiffFileView(f, p.DiffView) } if len(p.Files) == 0 {

no changed files{ " " } if p.Merge { against the first parent. } else { in this commit. }

}
} } // viewLink is a button of the diff tools. It is a link, so that the split // layout works without JavaScript; with it, and when both layouts are in the // page, a click only flips the layout. templ viewLink(p DiffView, view, label, key, href string) { { label } } // collapseButton folds every file of the diff, or opens them all again when // none is open; its label follows the state. templ collapseButton() { } templ personView(pr Person) { { pr.Name } if pr.WhenAt != "" { { " · " }{ " · " + pr.Abs } } } templ commitRail(p CommitPage) {

Files { itoa(len(p.Files)) }

@FileList(p.Files)
} // FileList is the table of contents of a diff: status letter, path, +n -m // and an ASCII bar. The row of the file in view is marked. templ FileList(files []DiffFile) {
    for _, f := range files {
  1. { let all = q('.dfile').arr(); let cur = all.filter(f => f.getBoundingClientRect().top < innerHeight / 3).at(-1) || all[0]; return cur?.id === '" + f.ID + "' ? 'true' : false })()" } hx-on:click="document.getElementById(this.hash.slice(1)).open = true" > { f.Status } { f.Path } +{ itoa(f.Add) } -{ itoa(f.Del) }
  2. }
} // DiffFileView is one file of the diff: a
(per-file collapse). The // unified and the split tables are both in it; #diffs[data-diff] shows one. // Every changed line keeps its +/- marker, so a change is never conveyed by // colour alone. templ DiffFileView(f DiffFile, p DiffView) {
{ f.Status }{ " " }{ f.Path }{ " " }+{ itoa(f.Add) }{ " " }-{ itoa(f.Del) } if f.Note != "" { { " " }{ f.Note } } if len(f.Hunks) > 0 {
if p.ShowUnified { for _, h := range f.Hunks { for _, ln := range h.Lines { if len(ln.Notes) > 0 || ln.Form != nil { } } }
{ h.Header }
@gutter(ln.Old, ln.OldHref) @gutter(ln.New, ln.NewHref) { ln.Mark } @codeLine(ln)
@lineNotes(ln.Notes, ln.Form, "")
} if p.ShowSplit { for _, h := range f.Hunks { for _, row := range h.Split { @splitSide(row.L, true) @splitSide(row.R, false) if notes, form := row.Notes(), row.Form(); len(notes) > 0 || form != nil { } } }
{ h.Header }
@lineNotes(notes, form, "-s")
}
} else {

if f.Note != "" { { f.Note } } else { no textual change. }

}
} // splitSide is one half of a row of the split view; a side without a line is // an empty cell. templ splitSide(ln *DiffLine, old bool) { if ln == nil { } else { if old { @gutter(ln.Old, ln.OldHref) } else { @gutter(ln.New, ln.NewHref) } { ln.Mark } @codeLine(*ln) } } // gutter is a line number of the gutter. On a merge request that can be // commented on, it links to the form that comments on that line. templ gutter(n, href string) { if href != "" { { n } } else { { n } } }