mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-12-29 18:24:02 +01:00
Merge pull request '[UI] Adjust trailing EOL behavior for empty file' (#5013) from gusted/forgejo-adjust-eol into forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5013 Reviewed-by: Otto <otto@codeberg.org>
This commit is contained in:
commit
f28cde134e
3 changed files with 33 additions and 28 deletions
|
@ -562,15 +562,16 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry) {
|
||||||
// empty: 0 lines; "a": 1 line; "a\n": 1 line; "a\nb": 2 lines;
|
// empty: 0 lines; "a": 1 line; "a\n": 1 line; "a\nb": 2 lines;
|
||||||
// When rendering, the last empty line is not rendered in U and isn't counted towards the number of lines.
|
// When rendering, the last empty line is not rendered in U and isn't counted towards the number of lines.
|
||||||
// To tell users that the file not contains a trailing EOL, text with a tooltip is displayed in the file header.
|
// To tell users that the file not contains a trailing EOL, text with a tooltip is displayed in the file header.
|
||||||
|
// Trailing EOL is only considered if the file has content.
|
||||||
// This NumLines is only used for the display on the UI: "xxx lines"
|
// This NumLines is only used for the display on the UI: "xxx lines"
|
||||||
hasTrailingEOL := bytes.HasSuffix(buf, []byte{'\n'})
|
|
||||||
ctx.Data["HasTrailingEOL"] = hasTrailingEOL
|
|
||||||
ctx.Data["HasTrailingEOLSet"] = true
|
|
||||||
if len(buf) == 0 {
|
if len(buf) == 0 {
|
||||||
ctx.Data["NumLines"] = 0
|
ctx.Data["NumLines"] = 0
|
||||||
} else {
|
} else {
|
||||||
|
hasNoTrailingEOL := !bytes.HasSuffix(buf, []byte{'\n'})
|
||||||
|
ctx.Data["HasNoTrailingEOL"] = hasNoTrailingEOL
|
||||||
|
|
||||||
numLines := bytes.Count(buf, []byte{'\n'})
|
numLines := bytes.Count(buf, []byte{'\n'})
|
||||||
if !hasTrailingEOL {
|
if hasNoTrailingEOL {
|
||||||
numLines++
|
numLines++
|
||||||
}
|
}
|
||||||
ctx.Data["NumLines"] = numLines
|
ctx.Data["NumLines"] = numLines
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
{{.NumLines}} {{ctx.Locale.TrN .NumLines "repo.line" "repo.lines"}}
|
{{.NumLines}} {{ctx.Locale.TrN .NumLines "repo.line" "repo.lines"}}
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if and .HasTrailingEOLSet (not .HasTrailingEOL)}}
|
{{if .HasNoTrailingEOL}}
|
||||||
<div class="file-info-entry" data-tooltip-content="{{ctx.Locale.Tr "repo.no_eol.tooltip"}}">
|
<div class="file-info-entry" data-tooltip-content="{{ctx.Locale.Tr "repo.no_eol.tooltip"}}">
|
||||||
{{ctx.Locale.Tr "repo.no_eol.text"}}
|
{{ctx.Locale.Tr "repo.no_eol.text"}}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -179,43 +179,47 @@ func TestRepoViewFileLines(t *testing.T) {
|
||||||
TreePath: "test-4",
|
TreePath: "test-4",
|
||||||
ContentReader: strings.NewReader("Really two\nlines\n"),
|
ContentReader: strings.NewReader("Really two\nlines\n"),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Operation: "create",
|
||||||
|
TreePath: "empty",
|
||||||
|
ContentReader: strings.NewReader(""),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Operation: "create",
|
||||||
|
TreePath: "seemingly-empty",
|
||||||
|
ContentReader: strings.NewReader("\n"),
|
||||||
|
},
|
||||||
})
|
})
|
||||||
defer f()
|
defer f()
|
||||||
|
|
||||||
t.Run("No EOL", func(t *testing.T) {
|
testEOL := func(t *testing.T, filename string, hasEOL bool) {
|
||||||
defer tests.PrintCurrentTest(t)()
|
t.Helper()
|
||||||
|
req := NewRequestf(t, "GET", "%s/src/branch/main/%s", repo.Link(), filename)
|
||||||
req := NewRequest(t, "GET", repo.Link()+"/src/branch/main/test-1")
|
|
||||||
resp := MakeRequest(t, req, http.StatusOK)
|
resp := MakeRequest(t, req, http.StatusOK)
|
||||||
htmlDoc := NewHTMLParser(t, resp.Body)
|
htmlDoc := NewHTMLParser(t, resp.Body)
|
||||||
|
|
||||||
fileInfo := htmlDoc.Find(".file-info").Text()
|
fileInfo := htmlDoc.Find(".file-info").Text()
|
||||||
|
if hasEOL {
|
||||||
|
assert.NotContains(t, fileInfo, "No EOL")
|
||||||
|
} else {
|
||||||
assert.Contains(t, fileInfo, "No EOL")
|
assert.Contains(t, fileInfo, "No EOL")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
req = NewRequest(t, "GET", repo.Link()+"/src/branch/main/test-3")
|
t.Run("No EOL", func(t *testing.T) {
|
||||||
resp = MakeRequest(t, req, http.StatusOK)
|
defer tests.PrintCurrentTest(t)()
|
||||||
htmlDoc = NewHTMLParser(t, resp.Body)
|
|
||||||
|
|
||||||
fileInfo = htmlDoc.Find(".file-info").Text()
|
testEOL(t, "test-1", false)
|
||||||
assert.Contains(t, fileInfo, "No EOL")
|
testEOL(t, "test-3", false)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("With EOL", func(t *testing.T) {
|
t.Run("With EOL", func(t *testing.T) {
|
||||||
defer tests.PrintCurrentTest(t)()
|
defer tests.PrintCurrentTest(t)()
|
||||||
|
|
||||||
req := NewRequest(t, "GET", repo.Link()+"/src/branch/main/test-2")
|
testEOL(t, "test-2", true)
|
||||||
resp := MakeRequest(t, req, http.StatusOK)
|
testEOL(t, "test-4", true)
|
||||||
htmlDoc := NewHTMLParser(t, resp.Body)
|
testEOL(t, "empty", true)
|
||||||
|
testEOL(t, "seemingly-empty", true)
|
||||||
fileInfo := htmlDoc.Find(".file-info").Text()
|
|
||||||
assert.NotContains(t, fileInfo, "No EOL")
|
|
||||||
|
|
||||||
req = NewRequest(t, "GET", repo.Link()+"/src/branch/main/test-4")
|
|
||||||
resp = MakeRequest(t, req, http.StatusOK)
|
|
||||||
htmlDoc = NewHTMLParser(t, resp.Body)
|
|
||||||
|
|
||||||
fileInfo = htmlDoc.Find(".file-info").Text()
|
|
||||||
assert.NotContains(t, fileInfo, "No EOL")
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue