forgejo/templates/repo/diff/compare.tmpl
KN4CK3R 637451a45e
Rework markup link rendering (#26745)
Fixes #26548

This PR refactors the rendering of markup links. The old code uses
`strings.Replace` to change some urls while the new code uses more
context to decide which link should be generated.

The added tests should ensure the same output for the old and new
behaviour (besides the bug).

We may need to refactor the rendering a bit more to make it clear how
the different helper methods render the input string. There are lots of
options (resolve links / images / mentions / git hashes / emojis / ...)
but you don't really know what helper uses which options. For example,
we currently support images in the user description which should not be
allowed I think:

<details>
  <summary>Profile</summary> 

https://try.gitea.io/KN4CK3R

![grafik](https://github.com/go-gitea/gitea/assets/1666336/109ae422-496d-4200-b52e-b3a528f553e5)

</details>

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2024-01-15 08:49:24 +00:00

245 lines
13 KiB
Go HTML Template

{{template "base/head" .}}
<div role="main" aria-label="{{.Title}}" class="page-content repository diff {{if .PageIsComparePull}}compare pull{{end}}">
{{template "repo/header" .}}
{{$showDiffBox := false}}
<div class="ui container fluid padded">
<h2 class="ui header">
{{if and $.PageIsComparePull $.IsSigned (not .Repository.IsArchived)}}
{{ctx.Locale.Tr "repo.pulls.compare_changes"}}
<div class="sub header">{{ctx.Locale.Tr "repo.pulls.compare_changes_desc"}}</div>
{{else}}
{{ctx.Locale.Tr "action.compare_commits_general"}}
{{end}}
</h2>
{{if .Flash.WarningMsg}}
{{/*
There's already an importing of alert.tmpl in new_form.tmpl,
but only the negative message will be displayed within forms for some reasons, see semantic.css:10659.
To avoid repeated negative messages, the importing here if for .Flash.WarningMsg only.
*/}}
{{template "base/alert" .}}
{{end}}
{{$BaseCompareName := $.BaseName -}}
{{- $HeadCompareName := $.HeadRepo.OwnerName -}}
{{- if and (eq $.BaseName $.HeadRepo.OwnerName) (ne $.Repository.Name $.HeadRepo.Name) -}}
{{- $HeadCompareName = printf "%s/%s" $.HeadRepo.OwnerName $.HeadRepo.Name -}}
{{- end -}}
{{- $OwnForkCompareName := "" -}}
{{- if .OwnForkRepo -}}
{{- $OwnForkCompareName = .OwnForkRepo.OwnerName -}}
{{- end -}}
{{- $RootRepoCompareName := "" -}}
{{- if .RootRepo -}}
{{- $RootRepoCompareName = .RootRepo.OwnerName -}}
{{- if eq $.HeadRepo.OwnerName .RootRepo.OwnerName -}}
{{- $HeadCompareName = printf "%s/%s" $.HeadRepo.OwnerName $.HeadRepo.Name -}}
{{- end -}}
{{- end -}}
<div class="ui segment choose branch">
<a class="gt-mr-3" href="{{$.HeadRepo.Link}}/compare/{{PathEscapeSegments $.HeadBranch}}{{$.CompareSeparator}}{{if not $.PullRequestCtx.SameRepo}}{{PathEscape $.BaseName}}/{{PathEscape $.Repository.Name}}:{{end}}{{PathEscapeSegments $.BaseBranch}}" title="{{ctx.Locale.Tr "repo.pulls.switch_head_and_base"}}">{{svg "octicon-git-compare"}}</a>
<div class="ui floating filter dropdown" data-no-results="{{ctx.Locale.Tr "repo.pulls.no_results"}}">
<div class="ui basic small button">
<span class="text">{{if $.PageIsComparePull}}{{ctx.Locale.Tr "repo.pulls.compare_base"}}{{else}}{{ctx.Locale.Tr "repo.compare.compare_base"}}{{end}}: {{$BaseCompareName}}:{{$.BaseBranch}}</span>
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
</div>
<div class="menu">
<div class="ui icon search input">
<i class="icon">{{svg "octicon-filter" 16}}</i>
<input name="search" placeholder="{{ctx.Locale.Tr "repo.filter_branch_and_tag"}}...">
</div>
<div class="header">
<div class="ui grid">
<div class="two column row">
<a class="reference column" href="#" data-target=".base-branch-list">
<span class="text black">
{{svg "octicon-git-branch" 16 "gt-mr-2"}}{{ctx.Locale.Tr "repo.branches"}}
</span>
</a>
<a class="reference column" href="#" data-target=".base-tag-list">
<span class="text black">
{{svg "octicon-tag" 16 "gt-mr-2"}}{{ctx.Locale.Tr "repo.tags"}}
</span>
</a>
</div>
</div>
</div>
<div class="scrolling menu reference-list-menu base-branch-list">
{{range .Branches}}
<div class="item {{if eq $.BaseBranch .}}selected{{end}}" data-url="{{$.RepoLink}}/compare/{{PathEscapeSegments .}}{{$.CompareSeparator}}{{if not $.PullRequestCtx.SameRepo}}{{PathEscape $.HeadUser.Name}}/{{PathEscape $.HeadRepo.Name}}:{{end}}{{PathEscapeSegments $.HeadBranch}}">{{$BaseCompareName}}:{{.}}</div>
{{end}}
{{if not .PullRequestCtx.SameRepo}}
{{range .HeadBranches}}
<div class="item" data-url="{{$.HeadRepo.Link}}/compare/{{PathEscapeSegments .}}{{$.CompareSeparator}}{{PathEscape $.HeadUser.Name}}/{{PathEscape $.HeadRepo.Name}}:{{PathEscapeSegments $.HeadBranch}}">{{$HeadCompareName}}:{{.}}</div>
{{end}}
{{end}}
{{if .OwnForkRepo}}
{{range .OwnForkRepoBranches}}
<div class="item" data-url="{{$.OwnForkRepo.Link}}/compare/{{PathEscapeSegments .}}{{$.CompareSeparator}}{{PathEscape $.HeadUser.Name}}/{{PathEscape $.HeadRepo.Name}}:{{PathEscapeSegments $.HeadBranch}}">{{$OwnForkCompareName}}:{{.}}</div>
{{end}}
{{end}}
{{if and .RootRepo (.RootRepo.AllowsPulls ctx)}}
{{range .RootRepoBranches}}
<div class="item" data-url="{{$.RootRepo.Link}}/compare/{{PathEscapeSegments .}}{{$.CompareSeparator}}{{PathEscape $.HeadUser.Name}}/{{PathEscape $.HeadRepo.Name}}:{{PathEscapeSegments $.HeadBranch}}">{{$RootRepoCompareName}}:{{.}}</div>
{{end}}
{{end}}
</div>
<div class="scrolling menu reference-list-menu base-tag-list gt-hidden">
{{range .Tags}}
<div class="item {{if eq $.BaseBranch .}}selected{{end}}" data-url="{{$.RepoLink}}/compare/{{PathEscapeSegments .}}{{$.CompareSeparator}}{{if not $.PullRequestCtx.SameRepo}}{{PathEscape $.HeadUser.Name}}/{{PathEscape $.HeadRepo.Name}}:{{end}}{{PathEscapeSegments $.HeadBranch}}">{{$BaseCompareName}}:{{.}}</div>
{{end}}
{{if not .PullRequestCtx.SameRepo}}
{{range .HeadTags}}
<div class="item" data-url="{{$.HeadRepo.Link}}/compare/{{PathEscapeSegments .}}{{$.CompareSeparator}}{{PathEscape $.HeadUser.Name}}/{{PathEscape $.HeadRepo.Name}}:{{PathEscapeSegments $.HeadBranch}}">{{$HeadCompareName}}:{{.}}</div>
{{end}}
{{end}}
{{if .OwnForkRepo}}
{{range .OwnForkRepoTags}}
<div class="item" data-url="{{$.OwnForkRepo.Link}}/compare/{{PathEscapeSegments .}}{{$.CompareSeparator}}{{PathEscape $.HeadUser.Name}}/{{PathEscape $.HeadRepo.Name}}:{{PathEscapeSegments $.HeadBranch}}">{{$OwnForkCompareName}}:{{.}}</div>
{{end}}
{{end}}
{{if .RootRepo}}
{{range .RootRepoTags}}
<div class="item" data-url="{{$.RootRepo.Link}}/compare/{{PathEscapeSegments .}}{{$.CompareSeparator}}{{PathEscape $.HeadUser.Name}}/{{PathEscape $.HeadRepo.Name}}:{{PathEscapeSegments $.HeadBranch}}">{{$RootRepoCompareName}}:{{.}}</div>
{{end}}
{{end}}
</div>
</div>
</div>
<a href="{{.RepoLink}}/compare/{{PathEscapeSegments .BaseBranch}}{{.OtherCompareSeparator}}{{if not $.PullRequestCtx.SameRepo}}{{PathEscape $.HeadUser.Name}}/{{PathEscape $.HeadRepo.Name}}:{{end}}{{PathEscapeSegments $.HeadBranch}}" title="{{ctx.Locale.Tr "repo.pulls.switch_comparison_type"}}">{{svg "octicon-arrow-left" 16}}<div class="compare-separator">{{.CompareSeparator}}</div></a>
<div class="ui floating filter dropdown">
<div class="ui basic small button">
<span class="text">{{if $.PageIsComparePull}}{{ctx.Locale.Tr "repo.pulls.compare_compare"}}{{else}}{{ctx.Locale.Tr "repo.compare.compare_head"}}{{end}}: {{$HeadCompareName}}:{{$.HeadBranch}}</span>
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
</div>
<div class="menu">
<div class="ui icon search input">
<i class="icon">{{svg "octicon-filter" 16}}</i>
<input name="search" placeholder="{{ctx.Locale.Tr "repo.filter_branch_and_tag"}}...">
</div>
<div class="header">
<div class="ui grid">
<div class="two column row">
<a class="reference column" href="#" data-target=".head-branch-list">
<span class="text black">
{{svg "octicon-git-branch" 16 "gt-mr-2"}}{{ctx.Locale.Tr "repo.branches"}}
</span>
</a>
<a class="reference column" href="#" data-target=".head-tag-list">
<span class="text black">
{{svg "octicon-tag" 16 "gt-mr-2"}}{{ctx.Locale.Tr "repo.tags"}}
</span>
</a>
</div>
</div>
</div>
<div class="scrolling menu reference-list-menu head-branch-list">
{{range .HeadBranches}}
<div class="{{if eq $.HeadBranch .}}selected{{end}} item" data-url="{{$.RepoLink}}/compare/{{PathEscapeSegments $.BaseBranch}}{{$.CompareSeparator}}{{if not $.PullRequestCtx.SameRepo}}{{PathEscape $.HeadUser.Name}}/{{PathEscape $.HeadRepo.Name}}:{{end}}{{PathEscapeSegments .}}">{{$HeadCompareName}}:{{.}}</div>
{{end}}
{{if not .PullRequestCtx.SameRepo}}
{{range .Branches}}
<div class="item" data-url="{{$.RepoLink}}/compare/{{PathEscapeSegments $.BaseBranch}}{{$.CompareSeparator}}{{PathEscape $.BaseName}}/{{PathEscape $.Repository.Name}}:{{PathEscapeSegments .}}">{{$BaseCompareName}}:{{.}}</div>
{{end}}
{{end}}
{{if .OwnForkRepo}}
{{range .OwnForkRepoBranches}}
<div class="item" data-url="{{$.RepoLink}}/compare/{{PathEscapeSegments $.BaseBranch}}{{$.CompareSeparator}}{{PathEscape $.OwnForkRepo.OwnerName}}/{{PathEscape $.OwnForkRepo.Name}}:{{PathEscapeSegments .}}">{{$OwnForkCompareName}}:{{.}}</div>
{{end}}
{{end}}
{{if .RootRepo}}
{{range .RootRepoBranches}}
<div class="item" data-url="{{$.RepoLink}}/compare/{{PathEscapeSegments $.BaseBranch}}{{$.CompareSeparator}}{{PathEscape $.RootRepo.OwnerName}}/{{PathEscape $.RootRepo.Name}}:{{PathEscapeSegments .}}">{{$RootRepoCompareName}}:{{.}}</div>
{{end}}
{{end}}
</div>
<div class="scrolling menu reference-list-menu head-tag-list gt-hidden">
{{range .HeadTags}}
<div class="{{if eq $.HeadBranch .}}selected{{end}} item" data-url="{{$.RepoLink}}/compare/{{PathEscapeSegments $.BaseBranch}}{{$.CompareSeparator}}{{if not $.PullRequestCtx.SameRepo}}{{PathEscape $.HeadUser.Name}}/{{PathEscape $.HeadRepo.Name}}:{{end}}{{PathEscapeSegments .}}">{{$HeadCompareName}}:{{.}}</div>
{{end}}
{{if not .PullRequestCtx.SameRepo}}
{{range .Tags}}
<div class="item" data-url="{{$.RepoLink}}/compare/{{PathEscapeSegments $.BaseBranch}}{{$.CompareSeparator}}{{PathEscape $.BaseName}}/{{PathEscape $.Repository.Name}}:{{PathEscapeSegments .}}">{{$BaseCompareName}}:{{.}}</div>
{{end}}
{{end}}
{{if .OwnForkRepo}}
{{range .OwnForkRepoTags}}
<div class="item" data-url="{{$.RepoLink}}/compare/{{PathEscapeSegments $.BaseBranch}}{{$.CompareSeparator}}{{PathEscape $.OwnForkRepo.OwnerName}}/{{PathEscape $.OwnForkRepo.Name}}:{{PathEscapeSegments .}}">{{$OwnForkCompareName}}:{{.}}</div>
{{end}}
{{end}}
{{if .RootRepo}}
{{range .RootRepoTags}}
<div class="item" data-url="{{$.RepoLink}}/compare/{{PathEscapeSegments $.BaseBranch}}{{$.CompareSeparator}}{{PathEscape $.RootRepo.OwnerName}}/{{PathEscape $.RootRepo.Name}}:{{PathEscapeSegments .}}">{{$RootRepoCompareName}}:{{.}}</div>
{{end}}
{{end}}
</div>
</div>
</div>
</div>
{{if .IsNothingToCompare}}
{{if and $.IsSigned $.AllowEmptyPr (not .Repository.IsArchived)}}
<div class="ui segment">{{ctx.Locale.Tr "repo.pulls.nothing_to_compare_and_allow_empty_pr"}}</div>
<div class="ui info message show-form-container {{if .Flash}}gt-hidden{{end}}">
<button class="ui button primary show-form">{{ctx.Locale.Tr "repo.pulls.new"}}</button>
</div>
<div class="pullrequest-form {{if not .Flash}}gt-hidden{{end}}">
{{template "repo/issue/new_form" .}}
</div>
{{else}}
<div class="ui segment">{{ctx.Locale.Tr "repo.pulls.nothing_to_compare"}}</div>
{{end}}
{{else if and .PageIsComparePull (gt .CommitCount 0)}}
{{if .HasPullRequest}}
<div class="ui segment grid title">
<div class="twelve wide column issue-title">
{{ctx.Locale.Tr "repo.pulls.has_pull_request" (print (Escape $.RepoLink) "/pulls/" .PullRequest.Issue.Index) (Escape $.RepoRelPath) .PullRequest.Index | Safe}}
<h1>
<span id="issue-title">{{RenderIssueTitle $.Context .PullRequest.Issue.Title ($.Repository.ComposeMetas ctx)}}</span>
<span class="index">#{{.PullRequest.Issue.Index}}</span>
</h1>
</div>
<div class="four wide column middle aligned text right">
{{- if .PullRequest.HasMerged -}}
<a href="{{Escape $.RepoLink}}/pulls/{{.PullRequest.Issue.Index}}" class="ui button purple show-form">{{svg "octicon-git-merge" 16}} {{ctx.Locale.Tr "repo.pulls.view"}}</a>
{{else if .Issue.IsClosed}}
<a href="{{Escape $.RepoLink}}/pulls/{{.PullRequest.Issue.Index}}" class="ui button red show-form">{{svg "octicon-issue-closed" 16}} {{ctx.Locale.Tr "repo.pulls.view"}}</a>
{{else}}
<a href="{{Escape $.RepoLink}}/pulls/{{.PullRequest.Issue.Index}}" class="ui button primary show-form">{{svg "octicon-git-pull-request" 16}} {{ctx.Locale.Tr "repo.pulls.view"}}</a>
{{end}}
</div>
</div>
{{else}}
{{if and $.IsSigned (not .Repository.IsArchived)}}
<div class="ui info message show-form-container {{if .Flash}}gt-hidden{{end}}">
<button class="ui button primary show-form">{{ctx.Locale.Tr "repo.pulls.new"}}</button>
</div>
{{else if .Repository.IsArchived}}
<div class="ui warning message gt-text-center">
{{if .Repository.ArchivedUnix.IsZero}}
{{ctx.Locale.Tr "repo.archive.title"}}
{{else}}
{{ctx.Locale.Tr "repo.archive.title_date" (DateTime "long" .Repository.ArchivedUnix) | Safe}}
{{end}}
</div>
{{end}}
{{if $.IsSigned}}
<div class="pullrequest-form {{if not .Flash}}gt-hidden{{end}}">
{{template "repo/issue/new_form" .}}
</div>
{{end}}
{{$showDiffBox = true}}
{{end}}
{{else}}
{{$showDiffBox = true}}
{{end}}
</div>
{{if $showDiffBox}}
<div class="ui container fluid padded">
{{template "repo/commits_table" .}}
{{template "repo/diff/box" .}}
</div>
{{end}}
</div>
{{template "base/footer" .}}