2023-10-18 18:59:46 -04:00
< div {{ if .ReadmeInList }} id = "readme" {{ end }} class = " {{ TabSizeClass .Editorconfig .FileName }} non-diff-file-content" >
2022-09-11 18:16:56 -04:00
{{- if .FileError }}
2023-04-06 16:01:20 -04:00
< div class = "ui error message" >
< div class = "text left gt-whitespace-pre" > {{ .FileError }} </ div >
< / div >
{{ end }}
{{- if .FileWarning }}
2022-09-11 18:16:56 -04:00
< div class = "ui warning message" >
2023-04-06 16:01:20 -04:00
< div class = "text left gt-whitespace-pre" > {{ .FileWarning }} </ div >
2022-09-11 18:16:56 -04:00
< / div >
{{ end }}
2023-02-13 12:59:59 -05:00
< h4 class = "file-header ui top attached header gt-df gt-ac gt-sb gt-fw" >
< div class = "file-header-left gt-df gt-ac gt-py-3 gt-pr-4" >
2019-10-07 00:59:17 -04:00
{{ if .ReadmeInList }}
2023-02-13 12:59:59 -05:00
{{ svg "octicon-book" 16 "gt-mr-3" }}
2023-10-18 18:59:46 -04:00
< strong >< a class = "default-link muted" href = "#readme" > {{ .FileName }} </ a ></ strong >
2019-10-07 00:59:17 -04:00
{{ else }}
2022-11-19 06:08:06 -05:00
{{ template "repo/file_info" . }}
2019-10-07 00:59:17 -04:00
{{ end }}
< / div >
2023-02-13 12:59:59 -05:00
< div class = "file-header-right file-actions gt-df gt-ac gt-fw" >
2021-01-12 22:45:19 -05:00
{{ if .HasSourceRenderedToggle }}
2023-09-04 06:22:46 -04:00
< div class = "ui compact icon buttons" >
2023-09-25 04:56:50 -04:00
< a href = " {{ $.Link }} ?display=source" class = "ui mini basic button {{ if .IsDisplayingSource }} active {{ end }} " data-tooltip-content = " {{ ctx .Locale.Tr "repo.file_view_source" }} " > {{ svg "octicon-code" 15 }} </ a >
< a href = " {{ $.Link }} " class = "ui mini basic button {{ if .IsDisplayingRendered }} active {{ end }} " data-tooltip-content = " {{ ctx .Locale.Tr "repo.file_view_rendered" }} " > {{ svg "octicon-file" 15 }} </ a >
2021-01-12 22:45:19 -05:00
< / div >
{{ end }}
2022-01-06 20:18:52 -05:00
{{ if not .ReadmeInList }}
2023-02-13 12:59:59 -05:00
< div class = "ui buttons gt-mr-2" >
2023-09-25 04:56:50 -04:00
< a class = "ui mini basic button" href = " {{ $.RawFileLink }} " > {{ ctx .Locale.Tr "repo.file_raw" }} </ a >
2022-01-06 20:18:52 -05:00
{{ if not .IsViewCommit }}
2023-09-25 04:56:50 -04:00
< a class = "ui mini basic button" href = " {{ .RepoLink }} /src/commit/ {{ PathEscape .CommitID }} / {{ PathEscapeSegments .TreePath }} " > {{ ctx .Locale.Tr "repo.file_permalink" }} </ a >
2022-01-06 20:18:52 -05:00
{{ end }}
{{ if .IsRepresentableAsText }}
2023-09-25 04:56:50 -04:00
< a class = "ui mini basic button" href = " {{ .RepoLink }} /blame/ {{ .BranchNameSubURL }} / {{ PathEscapeSegments .TreePath }} " > {{ ctx .Locale.Tr "repo.blame" }} </ a >
2022-01-06 20:18:52 -05:00
{{ end }}
2023-09-25 04:56:50 -04:00
< a class = "ui mini basic button" href = " {{ .RepoLink }} /commits/ {{ .BranchNameSubURL }} / {{ PathEscapeSegments .TreePath }} " > {{ ctx .Locale.Tr "repo.file_history" }} </ a >
2022-01-06 20:18:52 -05:00
{{ if .EscapeStatus.Escaped }}
2023-09-25 04:56:50 -04:00
< button class = "ui mini basic button unescape-button gt-hidden" > {{ ctx .Locale.Tr "repo.unescape_control_characters" }} </ button >
< button class = "ui mini basic button escape-button" > {{ ctx .Locale.Tr "repo.escape_control_characters" }} </ button >
2022-01-06 20:18:52 -05:00
{{ end }}
< / div >
2023-09-25 04:56:50 -04:00
< a download href = " {{ $.RawFileLink }} " >< span class = "btn-octicon" data-tooltip-content = " {{ ctx .Locale.Tr "repo.download_file" }} " > {{ svg "octicon-download" }} </ span ></ a >
2023-09-25 08:42:40 -04:00
< a id = "copy-content" class = "btn-octicon {{ if not .CanCopyContent }} disabled {{ end }} " {{ if or .IsImageFile ( and .HasSourceRenderedToggle ( not .IsDisplayingSource )) }} data-link = " {{ $.RawFileLink }} " {{ end }} data-tooltip-content = " {{ if .CanCopyContent }}{{ ctx .Locale.Tr "copy_content" }}{{ else }}{{ ctx .Locale.Tr "copy_type_unsupported" }}{{ end }} " > {{ svg "octicon-copy" 14 }} </ a >
2023-04-25 10:08:29 -04:00
{{ if .EnableFeed }}
2023-12-06 15:29:26 -05:00
< a class = "btn-octicon" href = " {{ $.FeedURL }} /rss/ {{ $.BranchNameSubURL }} / {{ PathEscapeSegments .TreePath }} " data-tooltip-content = " {{ ctx .Locale.Tr "rss_feed" }} " >
{{ svg "octicon-rss" 14 }}
< / a >
2023-04-25 10:08:29 -04:00
{{ end }}
2022-01-06 20:18:52 -05:00
{{ if .Repository.CanEnableEditor }}
{{ if .CanEditFile }}
2023-03-24 06:35:38 -04:00
< a href = " {{ .RepoLink }} /_edit/ {{ PathEscapeSegments .BranchName }} / {{ PathEscapeSegments .TreePath }} " >< span class = "btn-octicon" data-tooltip-content = " {{ .EditFileTooltip }} " > {{ svg "octicon-pencil" }} </ span ></ a >
2022-01-06 20:18:52 -05:00
{{ else }}
2023-03-24 06:35:38 -04:00
< span class = "btn-octicon disabled" data-tooltip-content = " {{ .EditFileTooltip }} " > {{ svg "octicon-pencil" }} </ span >
2022-01-06 20:18:52 -05:00
{{ end }}
{{ if .CanDeleteFile }}
2023-03-24 06:35:38 -04:00
< a href = " {{ .RepoLink }} /_delete/ {{ PathEscapeSegments .BranchName }} / {{ PathEscapeSegments .TreePath }} " >< span class = "btn-octicon btn-octicon-danger" data-tooltip-content = " {{ .DeleteFileTooltip }} " > {{ svg "octicon-trash" }} </ span ></ a >
2022-01-06 20:18:52 -05:00
{{ else }}
2023-03-24 06:35:38 -04:00
< span class = "btn-octicon disabled" data-tooltip-content = " {{ .DeleteFileTooltip }} " > {{ svg "octicon-trash" }} </ span >
2022-01-06 20:18:52 -05:00
{{ end }}
2020-11-01 15:04:26 -05:00
{{ end }}
2022-01-06 20:18:52 -05:00
{{ else if .EscapeStatus.Escaped }}
2023-09-25 04:56:50 -04:00
< button class = "ui mini basic button unescape-button gt-mr-2 gt-hidden" > {{ ctx .Locale.Tr "repo.unescape_control_characters" }} </ button >
< button class = "ui mini basic button escape-button gt-mr-2" > {{ ctx .Locale.Tr "repo.escape_control_characters" }} </ button >
2020-11-01 15:04:26 -05:00
{{ end }}
2023-11-20 06:47:55 -05:00
{{ if and .ReadmeInList .CanEditReadmeFile }}
< a class = "btn-octicon" data-tooltip-content = " {{ ctx .Locale.Tr "repo.editor.edit_this_file" }} " href = " {{ .RepoLink }} /_edit/ {{ PathEscapeSegments .BranchName }} / {{ PathEscapeSegments .TreePath }} / {{ PathEscapeSegments .FileName }} " > {{ svg "octicon-pencil" }} </ a >
{{ end }}
2017-12-30 19:47:52 -05:00
< / div >
2015-12-07 17:30:52 -05:00
< / h4 >
2017-12-30 19:47:52 -05:00
< div class = "ui attached table unstackable segment" >
2022-12-03 10:47:00 -05:00
{{ if not ( or .IsMarkup .IsRenderedHTML ) }}
{{ template "repo/unicode_escape_prompt" dict "EscapeStatus" .EscapeStatus "root" $ }}
{{ end }}
2022-12-17 15:22:25 -05:00
< div class = "file-view {{ if .IsMarkup }} markup {{ .MarkupType }}{{ else if .IsPlainText }} plain-text {{ else if .IsTextSource }} code-view {{ end }} " >
2017-10-16 19:17:22 -04:00
{{ if .IsMarkup }}
2023-12-17 09:38:54 -05:00
{{ if .FileContent }}{{ .FileContent }}{{ end }}
2022-12-17 15:22:25 -05:00
{{ else if .IsPlainText }}
2023-12-17 09:38:54 -05:00
< pre > {{ if .FileContent }}{{ .FileContent }}{{ end }} </ pre >
2021-01-12 22:45:19 -05:00
{{ else if not .IsTextSource }}
2023-05-29 08:10:00 -04:00
< div class = "view-raw" >
2015-12-07 17:30:52 -05:00
{{ if .IsImageFile }}
2021-11-16 13:18:25 -05:00
< img src = " {{ $.RawFileLink }} " >
2016-12-20 03:09:11 -05:00
{{ else if .IsVideoFile }}
2021-11-16 13:18:25 -05:00
< video controls src = " {{ $.RawFileLink }} " >
2023-09-25 04:56:50 -04:00
< strong > {{ ctx .Locale.Tr "repo.video_not_supported_in_browser" }} </ strong >
2016-12-20 03:09:11 -05:00
< / video >
2018-10-29 22:17:26 -04:00
{{ else if .IsAudioFile }}
2021-11-16 13:18:25 -05:00
< audio controls src = " {{ $.RawFileLink }} " >
2023-09-25 04:56:50 -04:00
< strong > {{ ctx .Locale.Tr "repo.audio_not_supported_in_browser" }} </ strong >
2018-10-29 22:17:26 -04:00
< / audio >
2016-04-26 21:48:44 -04:00
{{ else if .IsPDFFile }}
2023-09-25 04:56:50 -04:00
< div class = "pdf-content is-loading" data-src = " {{ $.RawFileLink }} " data-fallback-button-text = " {{ ctx .Locale.Tr "repo.diff.view_file" }} " ></ div >
2015-12-07 17:30:52 -05:00
{{ else }}
2023-09-25 04:56:50 -04:00
< a href = " {{ $.RawFileLink }} " rel = "nofollow" class = "btn btn-gray btn-radius" > {{ ctx .Locale.Tr "repo.file_view_raw" }} </ a >
2015-12-07 17:30:52 -05:00
{{ end }}
< / div >
{{ else if .FileSize }}
2020-06-30 17:34:03 -04:00
{{ if .IsFileTooLarge }}
2015-12-07 17:30:52 -05:00
< table >
< tbody >
< tr >
2023-09-25 04:56:50 -04:00
< td >< strong > {{ ctx .Locale.Tr "repo.file_too_large" }} </ strong ></ td >
2015-12-07 17:30:52 -05:00
< / tr >
< / tbody >
< / table >
2020-06-30 17:34:03 -04:00
{{ else }}
< table >
< tbody >
2021-08-23 17:23:39 -04:00
{{ range $idx , $code := .FileContent }}
Use a general Eval function for expressions in templates. (#23927)
One of the proposals in #23328
This PR introduces a simple expression calculator
(templates/eval/eval.go), it can do basic expression calculations.
Many untested template helper functions like `Mul` `Add` can be replaced
by this new approach.
Then these `Add` / `Mul` / `percentage` / `Subtract` / `DiffStatsWidth`
could all use this `Eval`.
And it provides enhancements for Golang templates, and improves
readability.
Some examples:
----
* Before: `{{Add (Mul $glyph.Row 12) 12}}`
* After: `{{Eval $glyph.Row "*" 12 "+" 12}}`
----
* Before: `{{if lt (Add $i 1) (len $.Topics)}}`
* After: `{{if Eval $i "+" 1 "<" (len $.Topics)}}`
## FAQ
### Why not use an existing expression package?
We need a highly customized expression engine:
* do the calculation on the fly, without pre-compiling
* deal with int/int64/float64 types, to make the result could be used in
Golang template.
* make the syntax could be used in the Golang template directly
* do not introduce too much complex or strange syntax, we just need a
simple calculator.
* it needs to strictly follow Golang template's behavior, for example,
Golang template treats all non-zero values as truth, but many 3rd
packages don't do so.
### What's the benefit?
* Developers don't need to add more `Add`/`Mul`/`Sub`-like functions,
they were getting more and more.
Now, only one `Eval` is enough for all cases.
* The new code reads better than old `{{Add (Mul $glyph.Row 12) 12}}`,
the old one isn't familiar to most procedural programming developers
(eg, the Golang expression syntax).
* The `Eval` is fully covered by tests, many old `Add`/`Mul`-like
functions were never tested.
### The performance?
It doesn't use `reflect`, it doesn't need to parse or compile when used
in Golang template, the performance is as fast as native Go template.
### Is it too complex? Could it be unstable?
The expression calculator program is a common homework for computer
science students, and it's widely used as a teaching and practicing
purpose for developers. The algorithm is pretty well-known.
The behavior can be clearly defined, it is stable.
2023-04-07 09:25:49 -04:00
{{ $line := Eval $idx "+" 1 }}
2020-06-30 17:34:03 -04:00
< tr >
2021-11-29 17:01:56 -05:00
< td id = "L {{ $line }} " class = "lines-num" >< span id = "L {{ $line }} " data-line-number = " {{ $line }} " ></ span ></ td >
2022-01-06 20:18:52 -05:00
{{ if $.EscapeStatus.Escaped }}
2023-09-25 04:56:50 -04:00
< td class = "lines-escape" > {{ if ( index $.LineEscapeStatus $idx ) .Escaped }} < button class = "toggle-escape-button btn interact-bg" title = " {{ if ( index $.LineEscapeStatus $idx ) .HasInvisible }}{{ ctx .Locale.Tr "repo.invisible_runes_line" }} {{ end }}{{ if ( index $.LineEscapeStatus $idx ) .HasAmbiguous }}{{ ctx .Locale.Tr "repo.ambiguous_runes_line" }}{{ end }} " ></ button > {{ end }} </ td >
2022-01-06 20:18:52 -05:00
{{ end }}
2023-12-17 09:38:54 -05:00
< td rel = "L {{ $line }} " class = "lines-code chroma" >< code class = "code-inner" > {{ $code }} </ code ></ td >
2020-06-30 17:34:03 -04:00
< / tr >
{{ end }}
< / tbody >
< / table >
2022-08-10 10:47:28 -04:00
< div class = "code-line-menu ui vertical pointing menu tippy-target" >
2022-08-09 08:37:34 -04:00
{{ if $.Permission.CanRead $.UnitTypeIssues }}
2023-09-25 04:56:50 -04:00
< a class = "item ref-in-new-issue" 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 >
2022-08-09 08:37:34 -04:00
{{ end }}
2023-09-25 04:56:50 -04:00
< a class = "item view_git_blame" href = " {{ .Repository.Link }} /blame/commit/ {{ PathEscape .CommitID }} / {{ PathEscapeSegments .TreePath }} " > {{ ctx .Locale.Tr "repo.view_git_blame" }} </ a >
< a class = "item copy-line-permalink" data-url = " {{ .Repository.Link }} /src/commit/ {{ PathEscape .CommitID }} / {{ PathEscapeSegments .TreePath }}{{ if $.HasSourceRenderedToggle }} ?display=source {{ end }} " > {{ ctx .Locale.Tr "repo.file_copy_permalink" }} </ a >
2021-10-02 03:46:43 -04:00
< / div >
2020-06-30 17:34:03 -04:00
{{ end }}
2015-12-07 17:30:52 -05:00
{{ end }}
< / div >
< / div >
< / div >