mirror of https://github.com/go-gitea/gitea.git
Refactor file view & render (#30227)
The old code is inconsistent and fragile, and the UI isn't right.
This commit is contained in:
parent
a008486f5c
commit
751997ad34
|
@ -16,6 +16,7 @@ import (
|
||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/git"
|
||||||
"code.gitea.io/gitea/modules/highlight"
|
"code.gitea.io/gitea/modules/highlight"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
"code.gitea.io/gitea/modules/setting"
|
||||||
"code.gitea.io/gitea/modules/templates"
|
"code.gitea.io/gitea/modules/templates"
|
||||||
"code.gitea.io/gitea/modules/timeutil"
|
"code.gitea.io/gitea/modules/timeutil"
|
||||||
"code.gitea.io/gitea/modules/util"
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
@ -87,9 +88,16 @@ func RefBlame(ctx *context.Context) {
|
||||||
|
|
||||||
ctx.Data["IsBlame"] = true
|
ctx.Data["IsBlame"] = true
|
||||||
|
|
||||||
ctx.Data["FileSize"] = blob.Size()
|
fileSize := blob.Size()
|
||||||
|
ctx.Data["FileSize"] = fileSize
|
||||||
ctx.Data["FileName"] = blob.Name()
|
ctx.Data["FileName"] = blob.Name()
|
||||||
|
|
||||||
|
if fileSize >= setting.UI.MaxDisplayFileSize {
|
||||||
|
ctx.Data["IsFileTooLarge"] = true
|
||||||
|
ctx.HTML(http.StatusOK, tplRepoHome)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
ctx.Data["NumLines"], err = blob.GetBlobLineCount()
|
ctx.Data["NumLines"], err = blob.GetBlobLineCount()
|
||||||
ctx.Data["NumLinesSet"] = true
|
ctx.Data["NumLinesSet"] = true
|
||||||
|
|
||||||
|
|
|
@ -287,22 +287,19 @@ func LFSFileGet(ctx *context.Context) {
|
||||||
|
|
||||||
st := typesniffer.DetectContentType(buf)
|
st := typesniffer.DetectContentType(buf)
|
||||||
ctx.Data["IsTextFile"] = st.IsText()
|
ctx.Data["IsTextFile"] = st.IsText()
|
||||||
isRepresentableAsText := st.IsRepresentableAsText()
|
|
||||||
|
|
||||||
fileSize := meta.Size
|
|
||||||
ctx.Data["FileSize"] = meta.Size
|
ctx.Data["FileSize"] = meta.Size
|
||||||
ctx.Data["RawFileLink"] = fmt.Sprintf("%s%s/%s.git/info/lfs/objects/%s/%s", setting.AppURL, url.PathEscape(ctx.Repo.Repository.OwnerName), url.PathEscape(ctx.Repo.Repository.Name), url.PathEscape(meta.Oid), "direct")
|
ctx.Data["RawFileLink"] = fmt.Sprintf("%s%s/%s.git/info/lfs/objects/%s/%s", setting.AppURL, url.PathEscape(ctx.Repo.Repository.OwnerName), url.PathEscape(ctx.Repo.Repository.Name), url.PathEscape(meta.Oid), "direct")
|
||||||
switch {
|
switch {
|
||||||
case isRepresentableAsText:
|
case st.IsRepresentableAsText():
|
||||||
if st.IsSvgImage() {
|
if meta.Size >= setting.UI.MaxDisplayFileSize {
|
||||||
ctx.Data["IsImageFile"] = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if fileSize >= setting.UI.MaxDisplayFileSize {
|
|
||||||
ctx.Data["IsFileTooLarge"] = true
|
ctx.Data["IsFileTooLarge"] = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if st.IsSvgImage() {
|
||||||
|
ctx.Data["IsImageFile"] = true
|
||||||
|
}
|
||||||
|
|
||||||
rd := charset.ToUTF8WithFallbackReader(io.MultiReader(bytes.NewReader(buf), dataRc), charset.ConvertOpts{})
|
rd := charset.ToUTF8WithFallbackReader(io.MultiReader(bytes.NewReader(buf), dataRc), charset.ConvertOpts{})
|
||||||
|
|
||||||
// Building code view blocks with line number on server side.
|
// Building code view blocks with line number on server side.
|
||||||
|
@ -338,6 +335,8 @@ func LFSFileGet(ctx *context.Context) {
|
||||||
ctx.Data["IsAudioFile"] = true
|
ctx.Data["IsAudioFile"] = true
|
||||||
case st.IsImage() && (setting.UI.SVG.Enabled || !st.IsSvgImage()):
|
case st.IsImage() && (setting.UI.SVG.Enabled || !st.IsSvgImage()):
|
||||||
ctx.Data["IsImageFile"] = true
|
ctx.Data["IsImageFile"] = true
|
||||||
|
default:
|
||||||
|
// TODO: the logic is not the same as "renderFile" in "view.go"
|
||||||
}
|
}
|
||||||
ctx.HTML(http.StatusOK, tplSettingsLFSFile)
|
ctx.HTML(http.StatusOK, tplSettingsLFSFile)
|
||||||
}
|
}
|
||||||
|
|
|
@ -482,17 +482,17 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry) {
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case isRepresentableAsText:
|
case isRepresentableAsText:
|
||||||
|
if fInfo.fileSize >= setting.UI.MaxDisplayFileSize {
|
||||||
|
ctx.Data["IsFileTooLarge"] = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
if fInfo.st.IsSvgImage() {
|
if fInfo.st.IsSvgImage() {
|
||||||
ctx.Data["IsImageFile"] = true
|
ctx.Data["IsImageFile"] = true
|
||||||
ctx.Data["CanCopyContent"] = true
|
ctx.Data["CanCopyContent"] = true
|
||||||
ctx.Data["HasSourceRenderedToggle"] = true
|
ctx.Data["HasSourceRenderedToggle"] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if fInfo.fileSize >= setting.UI.MaxDisplayFileSize {
|
|
||||||
ctx.Data["IsFileTooLarge"] = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
rd := charset.ToUTF8WithFallbackReader(io.MultiReader(bytes.NewReader(buf), dataRc), charset.ConvertOpts{})
|
rd := charset.ToUTF8WithFallbackReader(io.MultiReader(bytes.NewReader(buf), dataRc), charset.ConvertOpts{})
|
||||||
|
|
||||||
shouldRenderSource := ctx.FormString("display") == "source"
|
shouldRenderSource := ctx.FormString("display") == "source"
|
||||||
|
@ -606,6 +606,8 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: this logic seems strange, it duplicates with "isRepresentableAsText=true", it is not the same as "LFSFileGet" in "lfs.go"
|
||||||
|
// maybe for this case, the file is a binary file, and shouldn't be rendered?
|
||||||
if markupType := markup.Type(blob.Name()); markupType != "" {
|
if markupType := markup.Type(blob.Name()); markupType != "" {
|
||||||
rd := io.MultiReader(bytes.NewReader(buf), dataRc)
|
rd := io.MultiReader(bytes.NewReader(buf), dataRc)
|
||||||
ctx.Data["IsMarkup"] = true
|
ctx.Data["IsMarkup"] = true
|
||||||
|
|
|
@ -30,6 +30,9 @@
|
||||||
</h4>
|
</h4>
|
||||||
<div class="ui attached table unstackable segment">
|
<div class="ui attached table unstackable segment">
|
||||||
<div class="file-view code-view unicode-escaped">
|
<div class="file-view code-view unicode-escaped">
|
||||||
|
{{if .IsFileTooLarge}}
|
||||||
|
{{template "shared/filetoolarge" dict "RawFileLink" .RawFileLink}}
|
||||||
|
{{else}}
|
||||||
<table>
|
<table>
|
||||||
<tbody>
|
<tbody>
|
||||||
{{range $row := .BlameRows}}
|
{{range $row := .BlameRows}}
|
||||||
|
@ -75,6 +78,7 @@
|
||||||
{{end}}
|
{{end}}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
{{end}}{{/* end if .IsFileTooLarge */}}
|
||||||
<div class="code-line-menu tippy-target">
|
<div class="code-line-menu tippy-target">
|
||||||
{{if $.Permission.CanRead $.UnitTypeIssues}}
|
{{if $.Permission.CanRead $.UnitTypeIssues}}
|
||||||
<a class="item ref-in-new-issue" role="menuitem" data-url-issue-new="{{.RepoLink}}/issues/new" data-url-param-body-link="{{.Repository.Link}}/src/commit/{{PathEscape .CommitID}}/{{PathEscapeSegments .TreePath}}{{if $.HasSourceRenderedToggle}}?display=source{{end}}" rel="nofollow noindex">{{ctx.Locale.Tr "repo.issues.context.reference_issue"}}</a>
|
<a class="item ref-in-new-issue" role="menuitem" data-url-issue-new="{{.RepoLink}}/issues/new" data-url-param-body-link="{{.Repository.Link}}/src/commit/{{PathEscape .CommitID}}/{{PathEscapeSegments .TreePath}}{{if $.HasSourceRenderedToggle}}?display=source{{end}}" rel="nofollow noindex">{{ctx.Locale.Tr "repo.issues.context.reference_issue"}}</a>
|
||||||
|
|
|
@ -14,7 +14,9 @@
|
||||||
<div class="ui attached table unstackable segment">
|
<div class="ui attached table unstackable segment">
|
||||||
{{template "repo/unicode_escape_prompt" dict "EscapeStatus" .EscapeStatus "root" $}}
|
{{template "repo/unicode_escape_prompt" dict "EscapeStatus" .EscapeStatus "root" $}}
|
||||||
<div class="file-view{{if .IsMarkup}} markup {{.MarkupType}}{{else if .IsPlainText}} plain-text{{else if .IsTextFile}} code-view{{end}}">
|
<div class="file-view{{if .IsMarkup}} markup {{.MarkupType}}{{else if .IsPlainText}} plain-text{{else if .IsTextFile}} code-view{{end}}">
|
||||||
{{if .IsMarkup}}
|
{{if .IsFileTooLarge}}
|
||||||
|
{{template "shared/filetoolarge" dict "RawFileLink" .RawFileLink}}
|
||||||
|
{{else if .IsMarkup}}
|
||||||
{{if .FileContent}}{{.FileContent | SafeHTML}}{{end}}
|
{{if .FileContent}}{{.FileContent | SafeHTML}}{{end}}
|
||||||
{{else if .IsPlainText}}
|
{{else if .IsPlainText}}
|
||||||
<pre>{{if .FileContent}}{{.FileContent | SafeHTML}}{{end}}</pre>
|
<pre>{{if .FileContent}}{{.FileContent | SafeHTML}}{{end}}</pre>
|
||||||
|
@ -33,19 +35,15 @@
|
||||||
{{else if .IsPDFFile}}
|
{{else if .IsPDFFile}}
|
||||||
<div class="pdf-content is-loading" data-src="{{$.RawFileLink}}" data-fallback-button-text="{{ctx.Locale.Tr "diff.view_file"}}"></div>
|
<div class="pdf-content is-loading" data-src="{{$.RawFileLink}}" data-fallback-button-text="{{ctx.Locale.Tr "diff.view_file"}}"></div>
|
||||||
{{else}}
|
{{else}}
|
||||||
<a href="{{$.RawFileLink}}" rel="nofollow">{{ctx.Locale.Tr "repo.file_view_raw"}}</a>
|
<a href="{{$.RawFileLink}}" rel="nofollow" class="tw-p-4">{{ctx.Locale.Tr "repo.file_view_raw"}}</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
{{else if .FileSize}}
|
{{else if .FileSize}}
|
||||||
<table>
|
<table>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
{{if .IsFileTooLarge}}
|
|
||||||
<td><strong>{{ctx.Locale.Tr "repo.file_too_large"}}</strong></td>
|
|
||||||
{{else}}
|
|
||||||
<td class="lines-num">{{.LineNums}}</td>
|
<td class="lines-num">{{.LineNums}}</td>
|
||||||
<td class="lines-code"><pre><code class="{{.HighlightClass}}"><ol>{{.FileContent}}</ol></code></pre></td>
|
<td class="lines-code"><pre><code class="{{.HighlightClass}}"><ol>{{.FileContent}}</ol></code></pre></td>
|
||||||
{{end}}
|
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -89,7 +89,9 @@
|
||||||
{{template "repo/unicode_escape_prompt" dict "EscapeStatus" .EscapeStatus "root" $}}
|
{{template "repo/unicode_escape_prompt" dict "EscapeStatus" .EscapeStatus "root" $}}
|
||||||
{{end}}
|
{{end}}
|
||||||
<div class="file-view{{if .IsMarkup}} markup {{.MarkupType}}{{else if .IsPlainText}} plain-text{{else if .IsTextSource}} code-view{{end}}">
|
<div class="file-view{{if .IsMarkup}} markup {{.MarkupType}}{{else if .IsPlainText}} plain-text{{else if .IsTextSource}} code-view{{end}}">
|
||||||
{{if .IsMarkup}}
|
{{if .IsFileTooLarge}}
|
||||||
|
{{template "shared/filetoolarge" dict "RawFileLink" .RawFileLink}}
|
||||||
|
{{else if .IsMarkup}}
|
||||||
{{if .FileContent}}{{.FileContent}}{{end}}
|
{{if .FileContent}}{{.FileContent}}{{end}}
|
||||||
{{else if .IsPlainText}}
|
{{else if .IsPlainText}}
|
||||||
<pre>{{if .FileContent}}{{.FileContent}}{{end}}</pre>
|
<pre>{{if .FileContent}}{{.FileContent}}{{end}}</pre>
|
||||||
|
@ -108,19 +110,10 @@
|
||||||
{{else if .IsPDFFile}}
|
{{else if .IsPDFFile}}
|
||||||
<div class="pdf-content is-loading" data-src="{{$.RawFileLink}}" data-fallback-button-text="{{ctx.Locale.Tr "repo.diff.view_file"}}"></div>
|
<div class="pdf-content is-loading" data-src="{{$.RawFileLink}}" data-fallback-button-text="{{ctx.Locale.Tr "repo.diff.view_file"}}"></div>
|
||||||
{{else}}
|
{{else}}
|
||||||
<a href="{{$.RawFileLink}}" rel="nofollow">{{ctx.Locale.Tr "repo.file_view_raw"}}</a>
|
<a href="{{$.RawFileLink}}" rel="nofollow" class="tw-p-4">{{ctx.Locale.Tr "repo.file_view_raw"}}</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
{{else if .FileSize}}
|
{{else if .FileSize}}
|
||||||
{{if .IsFileTooLarge}}
|
|
||||||
<table>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td><strong>{{ctx.Locale.Tr "repo.file_too_large"}}</strong></td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
{{else}}
|
|
||||||
<table>
|
<table>
|
||||||
<tbody>
|
<tbody>
|
||||||
{{range $idx, $code := .FileContent}}
|
{{range $idx, $code := .FileContent}}
|
||||||
|
@ -142,7 +135,6 @@
|
||||||
<a class="item view_git_blame" role="menuitem" href="{{.Repository.Link}}/blame/commit/{{PathEscape .CommitID}}/{{PathEscapeSegments .TreePath}}">{{ctx.Locale.Tr "repo.view_git_blame"}}</a>
|
<a class="item view_git_blame" role="menuitem" href="{{.Repository.Link}}/blame/commit/{{PathEscape .CommitID}}/{{PathEscapeSegments .TreePath}}">{{ctx.Locale.Tr "repo.view_git_blame"}}</a>
|
||||||
<a class="item copy-line-permalink" role="menuitem" data-url="{{.Repository.Link}}/src/commit/{{PathEscape .CommitID}}/{{PathEscapeSegments .TreePath}}{{if $.HasSourceRenderedToggle}}?display=source{{end}}">{{ctx.Locale.Tr "repo.file_copy_permalink"}}</a>
|
<a class="item copy-line-permalink" role="menuitem" data-url="{{.Repository.Link}}/src/commit/{{PathEscape .CommitID}}/{{PathEscapeSegments .TreePath}}{{if $.HasSourceRenderedToggle}}?display=source{{end}}">{{ctx.Locale.Tr "repo.file_copy_permalink"}}</a>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
<div class="tw-p-4">
|
||||||
|
{{ctx.Locale.Tr "repo.file_too_large"}}
|
||||||
|
{{if .RawFileLink}}<a href="{{.RawFileLink}}" rel="nofollow">{{ctx.Locale.Tr "repo.file_view_raw"}}</a>{{end}}
|
||||||
|
</div>
|
Loading…
Reference in New Issue