summaryrefslogtreecommitdiffstats
path: root/templates/repo/diff
diff options
context:
space:
mode:
authorDaniel Baumann <daniel@debian.org>2024-10-18 20:33:49 +0200
committerDaniel Baumann <daniel@debian.org>2024-10-18 20:33:49 +0200
commitdd136858f1ea40ad3c94191d647487fa4f31926c (patch)
tree58fec94a7b2a12510c9664b21793f1ed560c6518 /templates/repo/diff
parentInitial commit. (diff)
downloadforgejo-dd136858f1ea40ad3c94191d647487fa4f31926c.tar.xz
forgejo-dd136858f1ea40ad3c94191d647487fa4f31926c.zip
Adding upstream version 9.0.0.
Signed-off-by: Daniel Baumann <daniel@debian.org>
Diffstat (limited to 'templates/repo/diff')
-rw-r--r--templates/repo/diff/blob_excerpt.tmpl80
-rw-r--r--templates/repo/diff/box.tmpl260
-rw-r--r--templates/repo/diff/comment_form.tmpl49
-rw-r--r--templates/repo/diff/comment_form_datahandler.tmpl7
-rw-r--r--templates/repo/diff/comments.tmpl75
-rw-r--r--templates/repo/diff/compare.tmpl238
-rw-r--r--templates/repo/diff/conversation.tmpl66
-rw-r--r--templates/repo/diff/conversations.tmpl3
-rw-r--r--templates/repo/diff/csv_diff.tmpl58
-rw-r--r--templates/repo/diff/escape_title.tmpl2
-rw-r--r--templates/repo/diff/image_diff.tmpl83
-rw-r--r--templates/repo/diff/new_comment.tmpl5
-rw-r--r--templates/repo/diff/new_review.tmpl52
-rw-r--r--templates/repo/diff/options_dropdown.tmpl33
-rw-r--r--templates/repo/diff/section_code.tmpl1
-rw-r--r--templates/repo/diff/section_split.tmpl156
-rw-r--r--templates/repo/diff/section_unified.tmpl72
-rw-r--r--templates/repo/diff/stats.tmpl5
-rw-r--r--templates/repo/diff/whitespace_dropdown.tmpl30
19 files changed, 1275 insertions, 0 deletions
diff --git a/templates/repo/diff/blob_excerpt.tmpl b/templates/repo/diff/blob_excerpt.tmpl
new file mode 100644
index 0000000..d6ab87f
--- /dev/null
+++ b/templates/repo/diff/blob_excerpt.tmpl
@@ -0,0 +1,80 @@
+{{if $.IsSplitStyle}}
+ {{range $k, $line := $.section.Lines}}
+ <tr class="{{.GetHTMLDiffLineType}}-code nl-{{$k}} ol-{{$k}}">
+ {{if eq .GetType 4}}
+ <td class="lines-num lines-num-old" data-line-num="{{if $line.LeftIdx}}{{$line.LeftIdx}}{{end}}">
+ <div class="tw-flex">
+ {{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 5)}}
+ <button class="code-expander-button" hx-target="closest tr" hx-get="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}?{{$line.GetBlobExcerptQuery}}&style=split&direction=down&wiki={{$.PageIsWiki}}&anchor={{$.Anchor}}">
+ {{svg "octicon-fold-down"}}
+ </button>
+ {{end}}
+ {{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 4)}}
+ <button class="code-expander-button" hx-target="closest tr" hx-get="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}?{{$line.GetBlobExcerptQuery}}&style=split&direction=up&wiki={{$.PageIsWiki}}&anchor={{$.Anchor}}">
+ {{svg "octicon-fold-up"}}
+ </button>
+ {{end}}
+ {{if eq $line.GetExpandDirection 2}}
+ <button class="code-expander-button" hx-target="closest tr" hx-get="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}?{{$line.GetBlobExcerptQuery}}&style=split&direction=&wiki={{$.PageIsWiki}}&anchor={{$.Anchor}}">
+ {{svg "octicon-fold"}}
+ </button>
+ {{end}}
+ </div>
+ </td>
+ <td colspan="7" class="lines-code lines-code-old ">{{$inlineDiff := $.section.GetComputedInlineDiffFor $line ctx.Locale}}{{/*
+ */}}{{template "repo/diff/section_code" dict "diff" $inlineDiff}}</td>
+ {{else}}
+ {{$inlineDiff := $.section.GetComputedInlineDiffFor $line ctx.Locale}}
+ <td class="lines-num lines-num-old" data-line-num="{{if $line.LeftIdx}}{{$line.LeftIdx}}{{end}}"><span rel="{{if $line.LeftIdx}}diff-{{$.FileNameHash}}L{{$line.LeftIdx}}{{end}}"></span></td>
+ <td class="blob-excerpt lines-escape lines-escape-old">{{if and $line.LeftIdx $inlineDiff.EscapeStatus.Escaped}}<button class="toggle-escape-button btn interact-bg" title="{{template "repo/diff/escape_title" dict "diff" $inlineDiff}}"></button>{{end}}</td>
+ <td class="blob-excerpt lines-type-marker lines-type-marker-old">{{if $line.LeftIdx}}<span class="tw-font-mono" data-type-marker=""></span>{{end}}</td>
+ <td class="blob-excerpt lines-code lines-code-old">{{/*
+ */}}{{if $line.LeftIdx}}{{template "repo/diff/section_code" dict "diff" $inlineDiff}}{{else}}{{/*
+ */}}<code class="code-inner"></code>{{/*
+ */}}{{end}}{{/*
+ */}}</td>
+ <td class="lines-num lines-num-new" data-line-num="{{if $line.RightIdx}}{{$line.RightIdx}}{{end}}"><span rel="{{if $line.RightIdx}}diff-{{$.FileNameHash}}R{{$line.RightIdx}}{{end}}"></span></td>
+ <td class="blob-excerpt lines-escape lines-escape-new">{{if and $line.RightIdx $inlineDiff.EscapeStatus.Escaped}}<button class="toggle-escape-button btn interact-bg" title="{{template "repo/diff/escape_title" dict "diff" $inlineDiff}}"></button>{{end}}</td>
+ <td class="blob-excerpt lines-type-marker lines-type-marker-new">{{if $line.RightIdx}}<span class="tw-font-mono" data-type-marker=""></span>{{end}}</td>
+ <td class="blob-excerpt lines-code lines-code-new">{{/*
+ */}}{{if $line.RightIdx}}{{template "repo/diff/section_code" dict "diff" $inlineDiff}}{{else}}{{/*
+ */}}<code class="code-inner"></code>{{/*
+ */}}{{end}}{{/*
+ */}}</td>
+ {{end}}
+ </tr>
+ {{end}}
+{{else}}
+ {{range $k, $line := $.section.Lines}}
+ <tr class="{{.GetHTMLDiffLineType}}-code nl-{{$k}} ol-{{$k}}">
+ {{if eq .GetType 4}}
+ <td colspan="2" class="lines-num">
+ <div class="tw-flex">
+ {{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 5)}}
+ <button class="code-expander-button" hx-target="closest tr" hx-get="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}?{{$line.GetBlobExcerptQuery}}&style=unified&direction=down&wiki={{$.PageIsWiki}}&anchor={{$.Anchor}}">
+ {{svg "octicon-fold-down"}}
+ </button>
+ {{end}}
+ {{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 4)}}
+ <button class="code-expander-button" hx-target="closest tr" hx-get="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}?{{$line.GetBlobExcerptQuery}}&style=unified&direction=up&wiki={{$.PageIsWiki}}&anchor={{$.Anchor}}">
+ {{svg "octicon-fold-up"}}
+ </button>
+ {{end}}
+ {{if eq $line.GetExpandDirection 2}}
+ <button class="code-expander-button" hx-target="closest tr" hx-get="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}?{{$line.GetBlobExcerptQuery}}&style=unified&direction=&wiki={{$.PageIsWiki}}&anchor={{$.Anchor}}">
+ {{svg "octicon-fold"}}
+ </button>
+ {{end}}
+ </div>
+ </td>
+ {{else}}
+ <td class="lines-num lines-num-old" data-line-num="{{if $line.LeftIdx}}{{$line.LeftIdx}}{{end}}"><span rel="{{if $line.LeftIdx}}diff-{{$.FileNameHash}}L{{$line.LeftIdx}}{{end}}"></span></td>
+ <td class="lines-num lines-num-new" data-line-num="{{if $line.RightIdx}}{{$line.RightIdx}}{{end}}"><span rel="{{if $line.RightIdx}}diff-{{$.FileNameHash}}R{{$line.RightIdx}}{{end}}"></span></td>
+ {{end}}
+ {{$inlineDiff := $.section.GetComputedInlineDiffFor $line ctx.Locale}}
+ <td class="blob-excerpt lines-escape">{{if $inlineDiff.EscapeStatus.Escaped}}<button class="toggle-escape-button btn interact-bg" title="{{template "repo/diff/escape_title" dict "diff" $inlineDiff}}"></button>{{end}}</td>
+ <td class="blob-excerpt lines-type-marker"><span class="tw-font-mono" data-type-marker="{{$line.GetLineTypeMarker}}"></span></td>
+ <td class="blob-excerpt lines-code{{if (not $line.RightIdx)}} lines-code-old{{end}}"><code {{if $inlineDiff.EscapeStatus.Escaped}}class="code-inner has-escaped" title="{{template "repo/diff/escape_title" dict "diff" $inlineDiff}}"{{else}}class="code-inner"{{end}}>{{$inlineDiff.Content}}</code></td>
+ </tr>
+ {{end}}
+{{end}}
diff --git a/templates/repo/diff/box.tmpl b/templates/repo/diff/box.tmpl
new file mode 100644
index 0000000..230e497
--- /dev/null
+++ b/templates/repo/diff/box.tmpl
@@ -0,0 +1,260 @@
+{{$showFileTree := (and (not .DiffNotAvailable) (gt .Diff.NumFiles 1))}}
+<div>
+ <div class="diff-detail-box diff-box">
+ <div class="tw-flex tw-items-center tw-flex-wrap tw-gap-2 tw-ml-0.5">
+ {{if $showFileTree}}
+ <button class="diff-toggle-file-tree-button not-mobile btn interact-fg" data-show-text="{{ctx.Locale.Tr "repo.diff.show_file_tree"}}" data-hide-text="{{ctx.Locale.Tr "repo.diff.hide_file_tree"}}">
+ {{/* the icon meaning is reversed here, "octicon-sidebar-collapse" means show the file tree */}}
+ {{svg "octicon-sidebar-collapse" 20 "icon tw-hidden"}}
+ {{svg "octicon-sidebar-expand" 20 "icon tw-hidden"}}
+ </button>
+ <script>
+ // Default to true if unset
+ const diffTreeVisible = localStorage?.getItem('diff_file_tree_visible') !== 'false';
+ const diffTreeBtn = document.querySelector('.diff-toggle-file-tree-button');
+ const diffTreeIcon = `.octicon-sidebar-${diffTreeVisible ? 'expand' : 'collapse'}`;
+ diffTreeBtn.querySelector(diffTreeIcon).classList.remove('tw-hidden');
+ diffTreeBtn.setAttribute('data-tooltip-content', diffTreeBtn.getAttribute(diffTreeVisible ? 'data-hide-text' : 'data-show-text'));
+ </script>
+ {{end}}
+ {{if not .DiffNotAvailable}}
+ <div class="diff-detail-stats tw-flex tw-items-center tw-flex-wrap">
+ {{svg "octicon-diff" 16 "tw-mr-1"}}{{ctx.Locale.Tr "repo.diff.stats_desc" .Diff.NumFiles .Diff.TotalAddition .Diff.TotalDeletion}}
+ </div>
+ {{end}}
+ </div>
+ <div class="diff-detail-actions button-row">
+ {{if and .PageIsPullFiles $.SignedUserID (not .IsArchived) (not .DiffNotAvailable)}}
+ <div class="not-mobile tw-flex tw-items-center tw-flex-col tw-whitespace-nowrap tw-mr-1">
+ <label for="viewed-files-summary" id="viewed-files-summary-label" data-text-changed-template="{{ctx.Locale.Tr "repo.pulls.viewed_files_label"}}">
+ {{ctx.Locale.Tr "repo.pulls.viewed_files_label" .Diff.NumViewedFiles .Diff.NumFiles}}
+ </label>
+ <progress id="viewed-files-summary" value="{{.Diff.NumViewedFiles}}" max="{{.Diff.NumFiles}}"></progress>
+ </div>
+ {{end}}
+ {{template "repo/diff/whitespace_dropdown" .}}
+ {{template "repo/diff/options_dropdown" .}}
+ {{if .PageIsPullFiles}}
+ <div id="diff-commit-select" data-issuelink="{{$.Issue.Link}}" data-queryparams="?style={{if $.IsSplitStyle}}split{{else}}unified{{end}}&whitespace={{$.WhitespaceBehavior}}&show-outdated={{$.ShowOutdatedComments}}" data-filter_changes_by_commit="{{ctx.Locale.Tr "repo.pulls.filter_changes_by_commit"}}">
+ {{/*
+ the following will be replaced by vue component
+ but this avoids any loading artifacts till the vue component is initialized
+ */}}
+ <div class="ui jump dropdown basic button custom">
+ {{svg "octicon-git-commit"}}
+ </div>
+ </div>
+ {{end}}
+ {{if and .PageIsPullFiles $.SignedUserID (not .IsArchived)}}
+ {{template "repo/diff/new_review" .}}
+ {{end}}
+ </div>
+ </div>
+ {{if not .DiffNotAvailable}}
+ {{if and .IsShowingOnlySingleCommit .PageIsPullFiles}}
+ <div class="ui info message">
+ <div>{{ctx.Locale.Tr "repo.pulls.showing_only_single_commit" (ShortSha .AfterCommitID)}} - <a href="{{$.Issue.Link}}/files?style={{if $.IsSplitStyle}}split{{else}}unified{{end}}&whitespace={{$.WhitespaceBehavior}}&show-outdated={{$.ShowOutdatedComments}}">{{ctx.Locale.Tr "repo.pulls.show_all_commits"}}</a></div>
+ </div>
+ {{else if and (not .IsShowingAllCommits) .PageIsPullFiles}}
+ <div class="ui info message">
+ <div>{{ctx.Locale.Tr "repo.pulls.showing_specified_commit_range" (ShortSha .BeforeCommitID) (ShortSha .AfterCommitID)}} - <a href="{{$.Issue.Link}}/files?style={{if $.IsSplitStyle}}split{{else}}unified{{end}}&whitespace={{$.WhitespaceBehavior}}&show-outdated={{$.ShowOutdatedComments}}">{{ctx.Locale.Tr "repo.pulls.show_all_commits"}}</a></div>
+ </div>
+ {{end}}
+ <script id="diff-data-script" type="module">
+ const diffDataFiles = [{{range $i, $file := .Diff.Files}}{Name:"{{$file.Name}}",NameHash:"{{$file.NameHash}}",Type:{{$file.Type}},IsBin:{{$file.IsBin}},Addition:{{$file.Addition}},Deletion:{{$file.Deletion}},IsViewed:{{$file.IsViewed}}},{{end}}];
+ const diffData = {
+ isIncomplete: {{.Diff.IsIncomplete}},
+ tooManyFilesMessage: "{{ctx.Locale.Tr "repo.diff.too_many_files"}}",
+ binaryFileMessage: "{{ctx.Locale.Tr "repo.diff.bin"}}",
+ showMoreMessage: "{{ctx.Locale.Tr "repo.diff.show_more"}}",
+ statisticsMessage: "{{ctx.Locale.Tr "repo.diff.stats_desc_file"}}",
+ linkLoadMore: "?skip-to={{.Diff.End}}&file-only=true",
+ };
+
+ // for first time loading, the diffFileInfo is a plain object
+ // after the Vue component is mounted, the diffFileInfo is a reactive object
+ // keep in mind that this script block would be executed many times when loading more files, by "loadMoreFiles"
+ let diffFileInfo = window.config.pageData.diffFileInfo || {
+ files:[],
+ fileTreeIsVisible: false,
+ fileListIsVisible: false,
+ isLoadingNewData: false,
+ selectedItem: '',
+ };
+ diffFileInfo = Object.assign(diffFileInfo, diffData);
+ diffFileInfo.files.push(...diffDataFiles);
+ window.config.pageData.diffFileInfo = diffFileInfo;
+ </script>
+ <div id="diff-file-list"></div>
+ {{end}}
+ <div id="diff-container">
+ {{if $showFileTree}}
+ <div id="diff-file-tree" class="tw-hidden not-mobile"></div>
+ <script>
+ if (diffTreeVisible) document.getElementById('diff-file-tree').classList.remove('tw-hidden');
+ </script>
+ {{end}}
+ {{if .DiffNotAvailable}}
+ <h4>{{ctx.Locale.Tr "repo.diff.data_not_available"}}</h4>
+ {{else}}
+ <div id="diff-file-boxes" class="sixteen wide column">
+ {{range $i, $file := .Diff.Files}}
+ {{/*notice: the index of Diff.Files should not be used for element ID, because the index will be restarted from 0 when doing load-more for PRs with a lot of files*/}}
+ {{$blobBase := call $.GetBlobByPathForCommit $.BeforeCommit $file.OldName}}
+ {{$blobHead := call $.GetBlobByPathForCommit $.HeadCommit $file.Name}}
+ {{$sniffedTypeBase := call $.GetSniffedTypeForBlob $blobBase}}
+ {{$sniffedTypeHead := call $.GetSniffedTypeForBlob $blobHead}}
+ {{$isImage:= or (call $.IsSniffedTypeAnImage $sniffedTypeBase) (call $.IsSniffedTypeAnImage $sniffedTypeHead)}}
+ {{$isCsv := (call $.IsCsvFile $file)}}
+ {{$showFileViewToggle := or $isImage (and (not $file.IsIncomplete) $isCsv)}}
+ {{$isExpandable := or (gt $file.Addition 0) (gt $file.Deletion 0) $file.IsBin}}
+ {{$isReviewFile := and $.IsSigned $.PageIsPullFiles (not $.IsArchived) $.IsShowingAllCommits}}
+ <div class="diff-file-box diff-box file-content {{TabSizeClass $.Editorconfig $file.Name}} tw-mt-0" id="diff-{{$file.NameHash}}" data-old-filename="{{$file.OldName}}" data-new-filename="{{$file.Name}}" {{if or ($file.ShouldBeHidden) (not $isExpandable)}}data-folded="true"{{end}}>
+ <h4 class="diff-file-header sticky-2nd-row ui top attached header tw-font-normal tw-flex tw-items-center tw-justify-between tw-flex-wrap">
+ <div class="diff-file-name tw-flex tw-flex-1 tw-items-center tw-gap-1 tw-flex-wrap">
+ <button class="fold-file btn interact-bg tw-p-1{{if not $isExpandable}} tw-invisible{{end}}">
+ {{if $file.ShouldBeHidden}}
+ {{svg "octicon-chevron-right" 18}}
+ {{else}}
+ {{svg "octicon-chevron-down" 18}}
+ {{end}}
+ </button>
+ <div class="tw-font-semibold tw-flex tw-items-center tw-font-mono">
+ {{if $file.IsBin}}
+ <span class="tw-ml-0.5 tw-mr-2">
+ {{ctx.Locale.Tr "repo.diff.bin"}}
+ </span>
+ {{else}}
+ {{template "repo/diff/stats" dict "file" . "root" $}}
+ {{end}}
+ </div>
+ <span class="file tw-flex tw-items-center tw-font-mono tw-flex-1"><a class="muted file-link" title="{{if $file.IsRenamed}}{{$file.OldName}} → {{end}}{{$file.Name}}" href="#diff-{{$file.NameHash}}">{{if $file.IsRenamed}}{{$file.OldName}} → {{end}}{{$file.Name}}</a>
+ {{if .IsLFSFile}} ({{ctx.Locale.Tr "repo.stored_lfs"}}){{end}}
+ <button class="btn interact-fg tw-p-2" data-clipboard-text="{{$file.Name}}" data-tooltip-content="{{ctx.Locale.Tr "copy_generic"}}" aria-label="{{ctx.Locale.Tr "copy_generic"}}">{{svg "octicon-copy" 14}}</button>
+ {{if $file.IsGenerated}}
+ <span class="ui label">{{ctx.Locale.Tr "repo.diff.generated"}}</span>
+ {{end}}
+ {{if $file.IsVendored}}
+ <span class="ui label">{{ctx.Locale.Tr "repo.diff.vendored"}}</span>
+ {{end}}
+ {{if and $file.Mode $file.OldMode}}
+ {{$old := ctx.Locale.Tr ($file.ModeTranslationKey $file.OldMode)}}
+ {{$new := ctx.Locale.Tr ($file.ModeTranslationKey $file.Mode)}}
+ <span class="tw-mx-2 tw-font-mono tw-whitespace-nowrap">{{ctx.Locale.Tr "git.filemode.changed_filemode" $old $new}}</span>
+ {{else if $file.Mode}}
+ <span class="tw-mx-2 tw-font-mono tw-whitespace-nowrap">{{ctx.Locale.Tr ($file.ModeTranslationKey $file.Mode)}}</span>
+ {{end}}
+ </span>
+ </div>
+ <div class="diff-file-header-actions tw-flex tw-items-center button-row tw-flex-wrap">
+ {{if $showFileViewToggle}}
+ <div class="ui compact icon buttons">
+ <button class="ui tiny basic button file-view-toggle" data-toggle-selector="#diff-source-{{$file.NameHash}}" data-tooltip-content="{{ctx.Locale.Tr "repo.file_view_source"}}">{{svg "octicon-code"}}</button>
+ <button class="ui tiny basic button file-view-toggle active" data-toggle-selector="#diff-rendered-{{$file.NameHash}}" data-tooltip-content="{{ctx.Locale.Tr "repo.file_view_rendered"}}">{{svg "octicon-file"}}</button>
+ </div>
+ {{end}}
+ {{if $file.IsProtected}}
+ <span class="ui basic label">{{ctx.Locale.Tr "repo.diff.protected"}}</span>
+ {{end}}
+ {{if and $isReviewFile $file.HasChangedSinceLastReview}}
+ <span class="changed-since-last-review unselectable not-mobile">{{ctx.Locale.Tr "repo.pulls.has_changed_since_last_review"}}</span>
+ {{end}}
+ {{if not (or $file.IsIncomplete $file.IsBin $file.IsSubmodule)}}
+ <button class="ui basic tiny button unescape-button not-mobile">{{ctx.Locale.Tr "repo.unescape_control_characters"}}</button>
+ <button class="ui basic tiny button escape-button tw-hidden">{{ctx.Locale.Tr "repo.escape_control_characters"}}</button>
+ {{end}}
+ {{if and (not $file.IsSubmodule) (not $.PageIsWiki)}}
+ {{if $file.IsDeleted}}
+ <a class="ui basic tiny button" rel="nofollow" href="{{$.BeforeSourcePath}}/{{PathEscapeSegments .Name}}">{{ctx.Locale.Tr "repo.diff.view_file"}}</a>
+ {{else}}
+ <a class="ui basic tiny button" rel="nofollow" href="{{$.SourcePath}}/{{PathEscapeSegments .Name}}">{{ctx.Locale.Tr "repo.diff.view_file"}}</a>
+ {{if and $.HeadBranchIsEditable (not $file.IsLFSFile)}}
+ <a class="ui basic tiny button" rel="nofollow" href="{{$.SourceRepoLink}}/_edit/{{PathEscapeSegments $.HeadBranch}}/{{PathEscapeSegments .Name}}">{{ctx.Locale.Tr "repo.editor.edit_this_file"}}</a>
+ {{end}}
+ {{end}}
+ {{end}}
+ {{if $isReviewFile}}
+ <label data-link="{{$.Issue.Link}}/viewed-files" data-headcommit="{{$.AfterCommitID}}" class="viewed-file-form unselectable{{if $file.IsViewed}} viewed-file-checked-form{{end}}">
+ <input type="checkbox" name="{{$file.GetDiffFileName}}" autocomplete="off"{{if $file.IsViewed}} checked{{end}}> {{ctx.Locale.Tr "repo.pulls.has_viewed_file"}}
+ </label>
+ {{end}}
+ </div>
+ </h4>
+ <div class="diff-file-body ui attached unstackable table segment" {{if and $file.IsViewed $.IsShowingAllCommits}}data-folded="true"{{end}}>
+ <div id="diff-source-{{$file.NameHash}}" class="file-body file-code unicode-escaped code-diff{{if $.IsSplitStyle}} code-diff-split{{else}} code-diff-unified{{end}}{{if $showFileViewToggle}} tw-hidden{{end}}">
+ {{if or $file.IsIncomplete $file.IsBin}}
+ <div class="diff-file-body binary">
+ {{if $file.IsIncomplete}}
+ {{if $file.IsIncompleteLineTooLong}}
+ {{ctx.Locale.Tr "repo.diff.file_suppressed_line_too_long"}}
+ {{else}}
+ {{ctx.Locale.Tr "repo.diff.file_suppressed"}}
+ <a class="ui basic tiny button diff-load-button" data-href="?file-only=true&files={{$file.Name}}&files={{$file.OldName}}">{{ctx.Locale.Tr "repo.diff.load"}}</a>
+ {{end}}
+ {{else}}
+ {{ctx.Locale.Tr "repo.diff.bin_not_shown"}}
+ {{end}}
+ </div>
+ {{else}}
+ <table class="chroma" data-new-comment-url="{{$.Issue.Link}}/files/reviews/new_comment" data-path="{{$file.Name}}">
+ {{if $.IsSplitStyle}}
+ {{template "repo/diff/section_split" dict "file" . "root" $}}
+ {{else}}
+ {{template "repo/diff/section_unified" dict "file" . "root" $}}
+ {{end}}
+ </table>
+ {{end}}
+ </div>
+ {{if $showFileViewToggle}}
+ {{/* for image or CSV, it can have a horizontal scroll bar, there won't be review comment context menu (position absolute) which would be clipped by "overflow" */}}
+ <div id="diff-rendered-{{$file.NameHash}}" class="file-body file-code {{if $.IsSplitStyle}}code-diff-split{{else}}code-diff-unified{{end}} tw-overflow-x-scroll">
+ <table class="chroma tw-w-full">
+ {{if $isImage}}
+ {{template "repo/diff/image_diff" dict "file" . "root" $ "blobBase" $blobBase "blobHead" $blobHead "sniffedTypeBase" $sniffedTypeBase "sniffedTypeHead" $sniffedTypeHead}}
+ {{else}}
+ {{template "repo/diff/csv_diff" dict "file" . "root" $ "blobBase" $blobBase "blobHead" $blobHead "sniffedTypeBase" $sniffedTypeBase "sniffedTypeHead" $sniffedTypeHead}}
+ {{end}}
+ </table>
+ </div>
+ {{end}}
+ </div>
+ </div>
+ {{end}}
+
+ {{if .Diff.IsIncomplete}}
+ <div class="diff-file-box diff-box file-content tw-mt-2" id="diff-incomplete">
+ <h4 class="ui top attached header tw-font-normal tw-flex tw-items-center tw-justify-between">
+ {{ctx.Locale.Tr "repo.diff.too_many_files"}}
+ <a class="ui basic tiny button" id="diff-show-more-files" data-href="?skip-to={{.Diff.End}}&file-only=true">{{ctx.Locale.Tr "repo.diff.show_more"}}</a>
+ </h4>
+ </div>
+ {{end}}
+ </div>
+ {{end}}
+ </div>
+
+ {{if and (not $.Repository.IsArchived) (not .DiffNotAvailable)}}
+ <template id="issue-comment-editor-template">
+ <div class="ui comment form">
+ {{template "shared/combomarkdowneditor" (dict
+ "MarkdownPreviewUrl" (print $.Repository.Link "/markup")
+ "MarkdownPreviewContext" $.RepoLink
+ "TextareaName" "content"
+ "DropzoneParentContainer" ".ui.form"
+ )}}
+ {{if .IsAttachmentEnabled}}
+ <div class="field">
+ {{template "repo/upload" .}}
+ </div>
+ {{end}}
+ <div class="text right edit buttons">
+ <button class="ui cancel button">{{ctx.Locale.Tr "repo.issues.cancel"}}</button>
+ <button class="ui primary save button">{{ctx.Locale.Tr "repo.issues.save"}}</button>
+ </div>
+ </div>
+ </template>
+ {{end}}
+ {{if (not .DiffNotAvailable)}}
+ {{template "repo/issue/view_content/reference_issue_dialog" .}}
+ {{end}}
+</div>
diff --git a/templates/repo/diff/comment_form.tmpl b/templates/repo/diff/comment_form.tmpl
new file mode 100644
index 0000000..856b3da
--- /dev/null
+++ b/templates/repo/diff/comment_form.tmpl
@@ -0,0 +1,49 @@
+{{if and $.root.SignedUserID (not $.Repository.IsArchived)}}
+ <form class="ui form {{if $.hidden}}tw-hidden comment-form{{end}}" action="{{$.root.Issue.Link}}/files/reviews/comments" method="post">
+ {{$.root.CsrfTokenHtml}}
+ <input type="hidden" name="origin" value="{{if $.root.PageIsPullFiles}}diff{{else}}timeline{{end}}">
+ <input type="hidden" name="latest_commit_id" value="{{$.root.AfterCommitID}}">
+ <input type="hidden" name="side" value="{{if $.Side}}{{$.Side}}{{end}}">
+ <input type="hidden" name="line" value="{{if $.Line}}{{$.Line}}{{end}}">
+ <input type="hidden" name="path" value="{{if $.File}}{{$.File}}{{end}}">
+ <input type="hidden" name="diff_start_cid">
+ <input type="hidden" name="diff_end_cid">
+ <input type="hidden" name="diff_base_cid">
+
+ {{template "shared/combomarkdowneditor" (dict
+ "MarkdownPreviewUrl" (print $.root.Repository.Link "/markup")
+ "MarkdownPreviewContext" $.root.RepoLink
+ "TextareaName" "content"
+ "TextareaPlaceholder" (ctx.Locale.Tr "repo.diff.comment.placeholder")
+ "DropzoneParentContainer" "form"
+ "DisableAutosize" "true"
+ )}}
+
+ {{if $.root.IsAttachmentEnabled}}
+ <div class="field">
+ {{template "repo/upload" $.root}}
+ </div>
+ {{end}}
+
+ <div class="field footer tw-mx-2">
+ <span class="markup-info">{{svg "octicon-markdown"}} {{ctx.Locale.Tr "repo.diff.comment.markdown_info"}}</span>
+ <div class="tw-text-right">
+ {{if $.reply}}
+ <button class="ui submit primary tiny button btn-reply" type="submit">{{ctx.Locale.Tr "repo.diff.comment.reply"}}</button>
+ <input type="hidden" name="reply" value="{{$.reply}}">
+ <input type="hidden" name="single_review" value="true">
+ {{else}}
+ {{if $.root.CurrentReview}}
+ <button name="pending_review" type="submit" class="ui submit primary tiny button btn-add-comment">{{ctx.Locale.Tr "repo.diff.comment.add_review_comment"}}</button>
+ {{else}}
+ <button name="pending_review" type="submit" class="ui submit primary tiny button btn-start-review">{{ctx.Locale.Tr "repo.diff.comment.start_review"}}</button>
+ <button name="single_review" value="true" type="submit" class="ui submit tiny basic button btn-add-single">{{ctx.Locale.Tr "repo.diff.comment.add_single_comment"}}</button>
+ {{end}}
+ {{end}}
+ {{if or (not $.HasComments) $.hidden}}
+ <button type="button" class="ui submit tiny basic button btn-cancel cancel-code-comment">{{ctx.Locale.Tr "cancel"}}</button>
+ {{end}}
+ </div>
+ </div>
+ </form>
+{{end}}
diff --git a/templates/repo/diff/comment_form_datahandler.tmpl b/templates/repo/diff/comment_form_datahandler.tmpl
new file mode 100644
index 0000000..d0e4934
--- /dev/null
+++ b/templates/repo/diff/comment_form_datahandler.tmpl
@@ -0,0 +1,7 @@
+{{if $.comment}}
+ {{template "repo/diff/comment_form" dict "root" $.root "hidden" $.hidden "reply" $.reply "Line" $.comment.UnsignedLine "File" $.comment.TreePath "Side" $.comment.DiffSide "HasComments" true}}
+{{else if $.root}}
+ {{template "repo/diff/comment_form" $}}
+{{else}}
+ {{template "repo/diff/comment_form" dict "root" $}}
+{{end}}
diff --git a/templates/repo/diff/comments.tmpl b/templates/repo/diff/comments.tmpl
new file mode 100644
index 0000000..2e0c85d
--- /dev/null
+++ b/templates/repo/diff/comments.tmpl
@@ -0,0 +1,75 @@
+{{range .comments}}
+
+{{$createdStr:= TimeSinceUnix .CreatedUnix ctx.Locale}}
+<div class="comment" id="{{.HashTag}}">
+ {{if .OriginalAuthor}}
+ <span class="avatar">{{ctx.AvatarUtils.Avatar nil}}</span>
+ {{else}}
+ {{template "shared/user/avatarlink" dict "user" .Poster}}
+ {{end}}
+ <div class="content comment-container">
+ <div class="ui top attached header comment-header tw-flex tw-items-center tw-justify-between">
+ <div class="comment-header-left tw-flex tw-items-center">
+ {{if .OriginalAuthor}}
+ <span class="text black tw-font-semibold tw-mr-1">
+ {{svg (MigrationIcon $.root.Repository.GetOriginalURLHostname)}}
+ {{.OriginalAuthor}}
+ </span>
+ <span class="text grey muted-links">
+ {{ctx.Locale.Tr "repo.issues.commented_at" .HashTag $createdStr}}
+ </span>
+ <span class="text migrate">
+ {{if $.root.Repository.OriginalURL}}
+ ({{ctx.Locale.Tr "repo.migrated_from" $.root.Repository.OriginalURL $.root.Repository.GetOriginalURLHostname}})
+ {{end}}
+ </span>
+ {{else}}
+ <span class="text grey muted-links">
+ {{template "shared/user/namelink" .Poster}}
+ {{ctx.Locale.Tr "repo.issues.commented_at" .HashTag $createdStr}}
+ </span>
+ {{end}}
+ </div>
+ <div class="comment-header-right actions tw-flex tw-items-center">
+ {{if .Invalidated}}
+ {{$referenceUrl := printf "%s#%s" $.root.Issue.Link .HashTag}}
+ <a href="{{AppSubUrl}}{{$referenceUrl}}" class="ui label basic small" data-tooltip-content="{{ctx.Locale.Tr "repo.issues.review.outdated_description"}}">
+ {{ctx.Locale.Tr "repo.issues.review.outdated"}}
+ </a>
+ {{end}}
+ {{if and .Review}}
+ {{if eq .Review.Type 0}}
+ <div class="ui label basic small yellow pending-label" data-tooltip-content="{{ctx.Locale.Tr "repo.issues.review.pending.tooltip" (ctx.Locale.Tr "repo.diff.review") (ctx.Locale.Tr "repo.diff.review.approve") (ctx.Locale.Tr "repo.diff.review.comment") (ctx.Locale.Tr "repo.diff.review.reject")}}">
+ {{ctx.Locale.Tr "repo.issues.review.pending"}}
+ </div>
+ {{else}}
+ <div class="ui label basic small">
+ {{ctx.Locale.Tr "repo.issues.review.review"}}
+ </div>
+ {{end}}
+ {{end}}
+ {{template "repo/issue/view_content/add_reaction" dict "ctxData" $.root "ActionURL" (printf "%s/comments/%d/reactions" $.root.RepoLink .ID)}}
+ {{template "repo/issue/view_content/context_menu" dict "ctxData" $.root "item" . "delete" true "issue" false "diff" true "IsCommentPoster" (and $.root.IsSigned (eq $.root.SignedUserID .PosterID))}}
+ </div>
+ </div>
+ <div class="ui attached segment comment-body">
+ <div class="render-content markup" {{if or $.Permission.IsAdmin $.HasIssuesOrPullsWritePermission (and $.root.IsSigned (eq $.root.SignedUserID .PosterID))}}data-can-edit="true"{{end}}>
+ {{if .RenderedContent}}
+ {{.RenderedContent}}
+ {{else}}
+ <span class="no-content">{{ctx.Locale.Tr "repo.issues.no_content"}}</span>
+ {{end}}
+ </div>
+ <div id="issuecomment-{{.ID}}-raw" class="raw-content tw-hidden">{{.Content}}</div>
+ <div class="edit-content-zone tw-hidden" data-update-url="{{$.root.RepoLink}}/comments/{{.ID}}" data-content-version="{{.ContentVersion}}" data-context="{{$.root.RepoLink}}" data-attachment-url="{{$.root.RepoLink}}/comments/{{.ID}}/attachments"></div>
+ {{if .Attachments}}
+ {{template "repo/issue/view_content/attachments" dict "Attachments" .Attachments "RenderedContent" .RenderedContent}}
+ {{end}}
+ </div>
+ {{$reactions := .Reactions.GroupByType}}
+ {{if $reactions}}
+ {{template "repo/issue/view_content/reactions" dict "ctxData" $.root "ActionURL" (printf "%s/comments/%d/reactions" $.root.RepoLink .ID) "Reactions" $reactions}}
+ {{end}}
+ </div>
+</div>
+{{end}}
diff --git a/templates/repo/diff/compare.tmpl b/templates/repo/diff/compare.tmpl
new file mode 100644
index 0000000..110f8ac
--- /dev/null
+++ b/templates/repo/diff/compare.tmpl
@@ -0,0 +1,238 @@
+{{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>
+ {{$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="tw-mr-2" 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 "tw-mr-1"}}{{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 "tw-mr-1"}}{{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 and (not .PullRequestCtx.SameRepo) ($.HeadRepo.AllowsPulls ctx)}}
+ {{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 and .OwnForkRepo (.OwnForkRepo.AllowsPulls ctx)}}
+ {{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 tw-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 and (not .PullRequestCtx.SameRepo) ($.HeadRepo.AllowsPulls ctx)}}
+ {{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 and .OwnForkRepo (.OwnForkRepo.AllowsPulls ctx)}}
+ {{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 and .RootRepo (.RootRepo.AllowsPulls ctx)}}
+ {{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 "tw-mr-1"}}{{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 "tw-mr-1"}}{{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 tw-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) .PageIsComparePull}}
+ <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}}tw-hidden{{end}}">
+ <button class="ui button primary show-form">{{ctx.Locale.Tr "repo.pulls.new"}}</button>
+ </div>
+ <div class="pullrequest-form {{if not .Flash}}tw-hidden{{end}}">
+ {{template "repo/issue/new_form" .}}
+ </div>
+ {{else if and .HeadIsBranch .BaseIsBranch}}
+ <div class="ui segment">{{ctx.Locale.Tr "repo.pulls.nothing_to_compare"}}</div>
+ {{else}}
+ <div class="ui segment">{{ctx.Locale.Tr "repo.pulls.nothing_to_compare_have_tag"}}</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 $.RepoLink "/pulls/" .PullRequest.Issue.Index) $.RepoRelPath .PullRequest.Index}}
+ <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="{{$.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="{{$.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="{{$.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}}tw-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 tw-text-center">
+ {{if .Repository.ArchivedUnix.IsZero}}
+ {{ctx.Locale.Tr "repo.archive.title"}}
+ {{else}}
+ {{ctx.Locale.Tr "repo.archive.title_date" (DateTime "long" .Repository.ArchivedUnix)}}
+ {{end}}
+ </div>
+ {{end}}
+ {{if $.IsSigned}}
+ <div class="pullrequest-form {{if not .Flash}}tw-hidden{{end}}">
+ {{template "repo/issue/new_form" .}}
+ </div>
+ {{end}}
+ {{$showDiffBox = true}}
+ {{end}}
+ {{else if not .IsNothingToCompare}}
+ {{$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" .}}
diff --git a/templates/repo/diff/conversation.tmpl b/templates/repo/diff/conversation.tmpl
new file mode 100644
index 0000000..c80d999
--- /dev/null
+++ b/templates/repo/diff/conversation.tmpl
@@ -0,0 +1,66 @@
+{{$resolved := (index .comments 0).IsResolved}}
+{{$invalid := (index .comments 0).Invalidated}}
+{{$resolveDoer := (index .comments 0).ResolveDoer}}
+{{$isNotPending := (not (eq (index .comments 0).Review.Type 0))}}
+{{$referenceUrl := printf "%s#%s" $.Issue.Link (index .comments 0).HashTag}}
+<div class="conversation-holder" data-path="{{(index .comments 0).TreePath}}" data-side="{{if lt (index .comments 0).Line 0}}left{{else}}right{{end}}" data-idx="{{(index .comments 0).UnsignedLine}}">
+ {{if $resolved}}
+ <div class="ui attached header resolved-placeholder tw-flex tw-items-center tw-justify-between">
+ <div class="ui grey text tw-flex tw-items-center tw-flex-wrap tw-gap-1">
+ {{svg "octicon-check" 16 "icon tw-mr-1"}}
+ <b>{{$resolveDoer.Name}}</b> {{ctx.Locale.Tr "repo.issues.review.resolved_by"}}
+ {{if $invalid}}
+ <!--
+ We only handle the case $resolved=true and $invalid=true in this template because if the comment is not resolved it has the outdated label in the comments area (not the header above).
+ The case $resolved=false and $invalid=true is handled in repo/diff/comments.tmpl
+ -->
+ <a href="{{AppSubUrl}}{{$referenceUrl}}" class="ui label basic small tw-ml-2" data-tooltip-content="{{ctx.Locale.Tr "repo.issues.review.outdated_description"}}">
+ {{ctx.Locale.Tr "repo.issues.review.outdated"}}
+ </a>
+ {{end}}
+ </div>
+ <div class="tw-flex tw-items-center tw-gap-2">
+ <button id="show-outdated-{{(index .comments 0).ID}}" data-comment="{{(index .comments 0).ID}}" class="ui tiny labeled button show-outdated tw-flex tw-items-center">
+ {{svg "octicon-unfold" 16 "tw-mr-2"}}
+ {{ctx.Locale.Tr "repo.issues.review.show_resolved"}}
+ </button>
+ <button id="hide-outdated-{{(index .comments 0).ID}}" data-comment="{{(index .comments 0).ID}}" class="ui tiny labeled button hide-outdated tw-flex tw-items-center tw-hidden">
+ {{svg "octicon-fold" 16 "tw-mr-2"}}
+ {{ctx.Locale.Tr "repo.issues.review.hide_resolved"}}
+ </button>
+ </div>
+ </div>
+ {{end}}
+ <div id="code-comments-{{(index .comments 0).ID}}" class="field comment-code-cloud {{if $resolved}}tw-hidden{{end}}">
+ <div class="comment-list">
+ <ui class="ui comments">
+ {{template "repo/diff/comments" dict "root" $ "comments" .comments}}
+ </ui>
+ </div>
+ <div class="button-row tw-flex tw-justify-end tw-items-center tw-flex-wrap tw-mt-2">
+ <div class="ui buttons">
+ <button class="ui icon tiny basic button previous-conversation">
+ {{svg "octicon-arrow-up" 12 "icon"}} {{ctx.Locale.Tr "repo.issues.previous"}}
+ </button>
+ <button class="ui icon tiny basic button next-conversation">
+ {{svg "octicon-arrow-down" 12 "icon"}} {{ctx.Locale.Tr "repo.issues.next"}}
+ </button>
+ </div>
+ {{if and $.CanMarkConversation $isNotPending}}
+ <button class="ui icon tiny basic button resolve-conversation" data-origin="diff" data-action="{{if not $resolved}}Resolve{{else}}UnResolve{{end}}" data-comment-id="{{(index .comments 0).ID}}" data-update-url="{{$.RepoLink}}/issues/resolve_conversation">
+ {{if $resolved}}
+ {{ctx.Locale.Tr "repo.issues.review.un_resolve_conversation"}}
+ {{else}}
+ {{ctx.Locale.Tr "repo.issues.review.resolve_conversation"}}
+ {{end}}
+ </button>
+ {{end}}
+ {{if and $.SignedUserID (not $.Repository.IsArchived)}}
+ <button class="comment-form-reply ui primary tiny labeled icon button">
+ {{svg "octicon-reply" 16 "reply icon tw-mr-1"}}{{ctx.Locale.Tr "repo.diff.comment.reply"}}
+ </button>
+ {{end}}
+ </div>
+ {{template "repo/diff/comment_form_datahandler" dict "hidden" true "reply" (index .comments 0).ReviewID "root" $ "comment" (index .comments 0)}}
+ </div>
+</div>
diff --git a/templates/repo/diff/conversations.tmpl b/templates/repo/diff/conversations.tmpl
new file mode 100644
index 0000000..5945337
--- /dev/null
+++ b/templates/repo/diff/conversations.tmpl
@@ -0,0 +1,3 @@
+{{range .conversations}}
+ {{template "repo/diff/conversation" dict "." $ "comments" .}}
+{{end}}
diff --git a/templates/repo/diff/csv_diff.tmpl b/templates/repo/diff/csv_diff.tmpl
new file mode 100644
index 0000000..0f46da3
--- /dev/null
+++ b/templates/repo/diff/csv_diff.tmpl
@@ -0,0 +1,58 @@
+<tr>
+ <td>
+ {{$result := call .root.CreateCsvDiff .file .blobBase .blobHead}}
+ {{if $result.Error}}
+ <div class="ui center">{{$result.Error}}</div>
+ {{else if $result.Sections}}
+ <table class="data-table">
+ {{range $i, $section := $result.Sections}}
+ <tbody {{if gt $i 0}}class="section"{{end}}>
+ {{range $j, $row := $section.Rows}}
+ <tr>
+ {{if and (eq $i 0) (eq $j 0)}}
+ <th class="line-num">{{.RowIdx}}</th>
+ {{range $j, $cell := $row.Cells}}
+ {{if not $cell}}
+ <th></th>
+ {{else if eq $cell.Type 2}}
+ <th class="modified"><span class="removed-code">{{.LeftCell}}</span> <span class="added-code">{{.RightCell}}</span></th>
+ {{else if eq $cell.Type 3}}
+ <th class="added"><span class="added-code">{{.RightCell}}</span></th>
+ {{else if eq $cell.Type 4}}
+ <th class="removed"><span class="removed-code">{{.LeftCell}}</span></th>
+ {{else if eq $cell.Type 5}}
+ <th class="moved">{{.RightCell}}</th>
+ {{else if eq $cell.Type 6}}
+ <th class="moved"><span class="removed-code">{{.LeftCell}}</span> <span class="added-code">{{.RightCell}}</span></th>
+ {{else}}
+ <th>{{.RightCell}}</th>
+ {{end}}
+ {{end}}
+ {{else}}
+ <td class="line-num">{{if .RowIdx}}{{.RowIdx}}{{end}}</td>
+ {{range $j, $cell := $row.Cells}}
+ {{if not $cell}}
+ <td></td>
+ {{else if eq $cell.Type 2}}
+ <td class="modified"><span class="removed-code">{{.LeftCell}}</span> <span class="added-code">{{.RightCell}}</span></td>
+ {{else if eq $cell.Type 3}}
+ <td class="added"><span class="added-code">{{.RightCell}}</span></td>
+ {{else if eq $cell.Type 4}}
+ <td class="removed"><span class="removed-code">{{.LeftCell}}</span></td>
+ {{else if eq $cell.Type 5}}
+ <td class="moved">{{.RightCell}}</td>
+ {{else if eq $cell.Type 6}}
+ <td class="moved"><span class="removed-code">{{.LeftCell}}</span> <span class="added-code">{{.RightCell}}</span></td>
+ {{else}}
+ <td>{{.RightCell}}</td>
+ {{end}}
+ {{end}}
+ {{end}}
+ </tr>
+ {{end}}
+ </tbody>
+ {{end}}
+ </table>
+ {{end}}
+ </td>
+</tr>
diff --git a/templates/repo/diff/escape_title.tmpl b/templates/repo/diff/escape_title.tmpl
new file mode 100644
index 0000000..e70f402
--- /dev/null
+++ b/templates/repo/diff/escape_title.tmpl
@@ -0,0 +1,2 @@
+{{if .diff.EscapeStatus.HasInvisible}}{{ctx.Locale.Tr "repo.invisible_runes_line"}} {{end}}{{/*
+*/}}{{if .diff.EscapeStatus.HasAmbiguous}}{{ctx.Locale.Tr "repo.ambiguous_runes_line"}}{{end}}
diff --git a/templates/repo/diff/image_diff.tmpl b/templates/repo/diff/image_diff.tmpl
new file mode 100644
index 0000000..0612854
--- /dev/null
+++ b/templates/repo/diff/image_diff.tmpl
@@ -0,0 +1,83 @@
+{{if or .blobBase .blobHead}}
+<tr>
+ <td colspan="2">
+ <div class="image-diff"
+ data-path-before="{{.root.BeforeRawPath}}/{{PathEscapeSegments .file.OldName}}"
+ data-path-after="{{.root.RawPath}}/{{PathEscapeSegments .file.Name}}"
+ data-mime-before="{{.sniffedTypeBase.GetMimeType}}"
+ data-mime-after="{{.sniffedTypeHead.GetMimeType}}"
+ >
+ <overflow-menu class="ui secondary pointing tabular top attached borderless menu">
+ <div class="overflow-menu-items tw-justify-center">
+ <a class="item active" data-tab="diff-side-by-side-{{.file.Index}}">{{ctx.Locale.Tr "repo.diff.image.side_by_side"}}</a>
+ {{if and .blobBase .blobHead}}
+ <a class="item" data-tab="diff-swipe-{{.file.Index}}">{{ctx.Locale.Tr "repo.diff.image.swipe"}}</a>
+ <a class="item" data-tab="diff-overlay-{{.file.Index}}">{{ctx.Locale.Tr "repo.diff.image.overlay"}}</a>
+ {{end}}
+ </div>
+ </overflow-menu>
+ <div class="image-diff-tabs is-loading">
+ <div class="ui bottom attached tab image-diff-container active" data-tab="diff-side-by-side-{{.file.Index}}">
+ <div class="diff-side-by-side">
+ {{if .blobBase}}
+ <span class="side">
+ <p class="side-header">{{ctx.Locale.Tr "repo.diff.file_before"}}</p>
+ <span class="before-container"><img class="image-before"></span>
+ <p>
+ <span class="bounds-info-before">
+ {{ctx.Locale.Tr "repo.diff.file_image_width"}}: <span class="text bounds-info-width"></span>
+ &nbsp;|&nbsp;
+ {{ctx.Locale.Tr "repo.diff.file_image_height"}}: <span class="text bounds-info-height"></span>
+ &nbsp;|&nbsp;
+ </span>
+ {{ctx.Locale.Tr "repo.diff.file_byte_size"}}: <span class="text">{{ctx.Locale.TrSize .blobBase.Size}}</span>
+ </p>
+ </span>
+ {{end}}
+ {{if .blobHead}}
+ <span class="side">
+ <p class="side-header">{{ctx.Locale.Tr "repo.diff.file_after"}}</p>
+ <span class="after-container"><img class="image-after"></span>
+ <p>
+ <span class="bounds-info-after">
+ {{ctx.Locale.Tr "repo.diff.file_image_width"}}: <span class="text bounds-info-width"></span>
+ &nbsp;|&nbsp;
+ {{ctx.Locale.Tr "repo.diff.file_image_height"}}: <span class="text bounds-info-height"></span>
+ &nbsp;|&nbsp;
+ </span>
+ {{ctx.Locale.Tr "repo.diff.file_byte_size"}}: <span class="text">{{ctx.Locale.TrSize .blobHead.Size}}</span>
+ </p>
+ </span>
+ {{end}}
+ </div>
+ </div>
+ {{if and .blobBase .blobHead}}
+ <div class="ui bottom attached tab image-diff-container" data-tab="diff-swipe-{{.file.Index}}">
+ <div class="diff-swipe">
+ <div class="swipe-frame">
+ <span class="before-container"><img class="image-before"></span>
+ <span class="swipe-container">
+ <span class="after-container"><img class="image-after"></span>
+ </span>
+ <span class="swipe-bar">
+ <span class="handle top-handle"></span>
+ <span class="handle bottom-handle"></span>
+ </span>
+ </div>
+ </div>
+ </div>
+ <div class="ui bottom attached tab image-diff-container" data-tab="diff-overlay-{{.file.Index}}">
+ <div class="diff-overlay">
+ <input type="range" min="0" max="100" value="50">
+ <div class="overlay-frame">
+ <span class="before-container"><img class="image-before"></span>
+ <span class="after-container"><img class="image-after"></span>
+ </div>
+ </div>
+ </div>
+ {{end}}
+ </div>
+ </div>
+ </td>
+</tr>
+{{end}}
diff --git a/templates/repo/diff/new_comment.tmpl b/templates/repo/diff/new_comment.tmpl
new file mode 100644
index 0000000..6a71539
--- /dev/null
+++ b/templates/repo/diff/new_comment.tmpl
@@ -0,0 +1,5 @@
+<div class="conversation-holder">
+ <div class="field comment-code-cloud">
+ {{template "repo/diff/comment_form_datahandler" .}}
+ </div>
+</div>
diff --git a/templates/repo/diff/new_review.tmpl b/templates/repo/diff/new_review.tmpl
new file mode 100644
index 0000000..a2eae00
--- /dev/null
+++ b/templates/repo/diff/new_review.tmpl
@@ -0,0 +1,52 @@
+<div id="review-box">
+ <button class="ui tiny primary button tw-pr-1 tw-flex js-btn-review {{if not $.IsShowingAllCommits}}disabled{{end}}" {{if not $.IsShowingAllCommits}}data-tooltip-content="{{ctx.Locale.Tr "repo.pulls.review_only_possible_for_full_diff"}}"{{end}}>
+ {{ctx.Locale.Tr "repo.diff.review"}}
+ <span class="ui small label review-comments-counter" data-pending-comment-number="{{.PendingCodeCommentNumber}}">{{.PendingCodeCommentNumber}}</span>
+ {{svg "octicon-triangle-down" 14 "dropdown icon"}}
+ </button>
+ {{if $.IsShowingAllCommits}}
+ <div class="review-box-panel tippy-target">
+ <div class="ui segment">
+ <form class="ui form form-fetch-action" action="{{.Link}}/reviews/submit" method="post">
+ {{.CsrfTokenHtml}}
+ <input type="hidden" name="commit_id" value="{{.AfterCommitID}}">
+ <div class="field tw-flex tw-items-center">
+ <div class="tw-flex-1">{{ctx.Locale.Tr "repo.diff.review.header"}}</div>
+ <a class="muted close">{{svg "octicon-x" 16}}</a>
+ </div>
+ <div class="field">
+ {{template "shared/combomarkdowneditor" (dict
+ "MarkdownPreviewUrl" (print .Repository.Link "/markup")
+ "MarkdownPreviewContext" .RepoLink
+ "TextareaName" "content"
+ "TextareaPlaceholder" (ctx.Locale.Tr "repo.diff.review.placeholder")
+ "DropzoneParentContainer" "form"
+ )}}
+ </div>
+ {{if .IsAttachmentEnabled}}
+ <div class="field">
+ {{template "repo/upload" .}}
+ </div>
+ {{end}}
+ <div class="divider"></div>
+ {{$showSelfTooltip := (and $.IsSigned ($.Issue.IsPoster $.SignedUser.ID))}}
+ {{if $showSelfTooltip}}
+ <span class="tw-inline-block" data-tooltip-content="{{ctx.Locale.Tr "repo.diff.review.self_approve"}}">
+ <button type="submit" name="type" value="approve" disabled class="ui submit primary tiny button btn-submit">{{ctx.Locale.Tr "repo.diff.review.approve"}}</button>
+ </span>
+ {{else}}
+ <button type="submit" name="type" value="approve" class="ui submit primary tiny button btn-submit">{{ctx.Locale.Tr "repo.diff.review.approve"}}</button>
+ {{end}}
+ <button type="submit" name="type" value="comment" class="ui submit tiny basic button btn-submit">{{ctx.Locale.Tr "repo.diff.review.comment"}}</button>
+ {{if $showSelfTooltip}}
+ <span class="tw-inline-block" data-tooltip-content="{{ctx.Locale.Tr "repo.diff.review.self_reject"}}">
+ <button type="submit" name="type" value="reject" disabled class="ui submit red tiny button btn-submit">{{ctx.Locale.Tr "repo.diff.review.reject"}}</button>
+ </span>
+ {{else}}
+ <button type="submit" name="type" value="reject" class="ui submit red tiny button btn-submit">{{ctx.Locale.Tr "repo.diff.review.reject"}}</button>
+ {{end}}
+ </form>
+ </div>
+ </div>
+ {{end}}
+</div>
diff --git a/templates/repo/diff/options_dropdown.tmpl b/templates/repo/diff/options_dropdown.tmpl
new file mode 100644
index 0000000..09b7b80
--- /dev/null
+++ b/templates/repo/diff/options_dropdown.tmpl
@@ -0,0 +1,33 @@
+<div class="ui dropdown tiny basic button" data-tooltip-content="{{ctx.Locale.Tr "repo.diff.options_button"}}">
+ {{svg "octicon-kebab-horizontal"}}
+ <div class="menu">
+ <a class="item" id="show-file-list-btn">{{ctx.Locale.Tr "repo.diff.show_diff_stats"}}</a>
+ {{if .Issue.Index}}
+ <a class="item" href="{{$.RepoLink}}/pulls/{{.Issue.Index}}.patch" download="{{.Issue.Index}}.patch">{{ctx.Locale.Tr "repo.diff.download_patch"}}</a>
+ <a class="item" href="{{$.RepoLink}}/pulls/{{.Issue.Index}}.diff" download="{{.Issue.Index}}.diff">{{ctx.Locale.Tr "repo.diff.download_diff"}}</a>
+ {{else if $.PageIsWiki}}
+ <a class="item" href="{{$.RepoLink}}/wiki/commit/{{PathEscape .Commit.ID.String}}.patch" download="{{ShortSha .Commit.ID.String}}.patch">{{ctx.Locale.Tr "repo.diff.download_patch"}}</a>
+ <a class="item" href="{{$.RepoLink}}/wiki/commit/{{PathEscape .Commit.ID.String}}.diff" download="{{ShortSha .Commit.ID.String}}.diff">{{ctx.Locale.Tr "repo.diff.download_diff"}}</a>
+ {{else if .Commit.ID.String}}
+ <a class="item" href="{{$.RepoLink}}/commit/{{PathEscape .Commit.ID.String}}.patch" download="{{ShortSha .Commit.ID.String}}.patch">{{ctx.Locale.Tr "repo.diff.download_patch"}}</a>
+ <a class="item" href="{{$.RepoLink}}/commit/{{PathEscape .Commit.ID.String}}.diff" download="{{ShortSha .Commit.ID.String}}.diff">{{ctx.Locale.Tr "repo.diff.download_diff"}}</a>
+ {{end}}
+ <a id="expand-files-btn" class="item">{{ctx.Locale.Tr "repo.pulls.expand_files"}}</a>
+ <a id="collapse-files-btn" class="item">{{ctx.Locale.Tr "repo.pulls.collapse_files"}}</a>
+ {{if .Issue.Index}}
+ {{if .ShowOutdatedComments}}
+ <a class="item" href="?style={{if $.IsSplitStyle}}split{{else}}unified{{end}}&whitespace={{$.WhitespaceBehavior}}&show-outdated=false">
+ <label class="tw-pointer-events-none">
+ {{ctx.Locale.Tr "repo.issues.review.option.hide_outdated_comments"}}
+ </label>
+ </a>
+ {{else}}
+ <a class="item" href="?style={{if $.IsSplitStyle}}split{{else}}unified{{end}}&whitespace={{$.WhitespaceBehavior}}&show-outdated=true">
+ <label class="tw-pointer-events-none">
+ {{ctx.Locale.Tr "repo.issues.review.option.show_outdated_comments"}}
+ </label>
+ </a>
+ {{end}}
+ {{end}}
+ </div>
+</div>
diff --git a/templates/repo/diff/section_code.tmpl b/templates/repo/diff/section_code.tmpl
new file mode 100644
index 0000000..3e8303e
--- /dev/null
+++ b/templates/repo/diff/section_code.tmpl
@@ -0,0 +1 @@
+<code class="code-inner{{if .diff.EscapeStatus.Escaped}} has-escaped{{end}}"{{if .diff.EscapeStatus.Escaped}} title="{{template "repo/diff/escape_title" .}}"{{end}}>{{.diff.Content}}</code>
diff --git a/templates/repo/diff/section_split.tmpl b/templates/repo/diff/section_split.tmpl
new file mode 100644
index 0000000..50522d9
--- /dev/null
+++ b/templates/repo/diff/section_split.tmpl
@@ -0,0 +1,156 @@
+{{$file := .file}}
+{{$blobExcerptRepoLink := or $.root.CommitRepoLink $.root.RepoLink}}
+<colgroup>
+ <col width="50">
+ <col width="10">
+ <col width="10">
+ <col>
+ <col width="50">
+ <col width="10">
+ <col width="10">
+ <col>
+</colgroup>
+{{range $j, $section := $file.Sections}}
+ {{range $k, $line := $section.Lines}}
+ {{$hasmatch := ne $line.Match -1}}
+ {{if or (ne .GetType 2) (not $hasmatch)}}
+ <tr class="{{.GetHTMLDiffLineType}}-code nl-{{$k}} ol-{{$k}}" data-line-type="{{.GetHTMLDiffLineType}}">
+ {{if eq .GetType 4}}
+ <td class="lines-num lines-num-old">
+ <div class="tw-flex">
+ {{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 5)}}
+ <button class="code-expander-button" hx-target="closest tr" hx-get="{{$blobExcerptRepoLink}}/blob_excerpt/{{PathEscape $.root.AfterCommitID}}?{{$line.GetBlobExcerptQuery}}&style=split&direction=down&wiki={{$.root.PageIsWiki}}&anchor=diff-{{$file.NameHash}}K{{$line.SectionInfo.RightIdx}}">
+ {{svg "octicon-fold-down"}}
+ </button>
+ {{end}}
+ {{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 4)}}
+ <button class="code-expander-button" hx-target="closest tr" hx-get="{{$blobExcerptRepoLink}}/blob_excerpt/{{PathEscape $.root.AfterCommitID}}?{{$line.GetBlobExcerptQuery}}&style=split&direction=up&wiki={{$.root.PageIsWiki}}&anchor=diff-{{$file.NameHash}}K{{$line.SectionInfo.RightIdx}}">
+ {{svg "octicon-fold-up"}}
+ </button>
+ {{end}}
+ {{if eq $line.GetExpandDirection 2}}
+ <button class="code-expander-button" hx-target="closest tr" hx-get="{{$blobExcerptRepoLink}}/blob_excerpt/{{PathEscape $.root.AfterCommitID}}?{{$line.GetBlobExcerptQuery}}&style=split&direction=&wiki={{$.root.PageIsWiki}}&anchor=diff-{{$file.NameHash}}K{{$line.SectionInfo.RightIdx}}">
+ {{svg "octicon-fold"}}
+ </button>
+ {{end}}
+ </div>
+ </td>{{$inlineDiff := $section.GetComputedInlineDiffFor $line ctx.Locale}}
+ <td class="lines-escape lines-escape-old">{{if $inlineDiff.EscapeStatus.Escaped}}<button class="toggle-escape-button btn interact-bg" title="{{template "repo/diff/escape_title" dict "diff" $inlineDiff}}"></button>{{end}}</td>
+ <td colspan="6" class="lines-code lines-code-old ">{{/*
+ */}}{{template "repo/diff/section_code" dict "diff" $inlineDiff}}{{/*
+ */}}</td>
+ {{else if and (eq .GetType 3) $hasmatch}}{{/* DEL */}}
+ {{$match := index $section.Lines $line.Match}}
+ {{- $leftDiff := ""}}{{if $line.LeftIdx}}{{$leftDiff = $section.GetComputedInlineDiffFor $line ctx.Locale}}{{end}}
+ {{- $rightDiff := ""}}{{if $match.RightIdx}}{{$rightDiff = $section.GetComputedInlineDiffFor $match ctx.Locale}}{{end}}
+ <td class="lines-num lines-num-old del-code" data-line-num="{{$line.LeftIdx}}"><span rel="diff-{{$file.NameHash}}L{{$line.LeftIdx}}"></span></td>
+ <td class="lines-escape del-code lines-escape-old">{{if $line.LeftIdx}}{{if $leftDiff.EscapeStatus.Escaped}}<button class="toggle-escape-button btn interact-bg" title="{{template "repo/diff/escape_title" dict "diff" $leftDiff}}"></button>{{end}}{{end}}</td>
+ <td class="lines-type-marker lines-type-marker-old del-code"><span class="tw-font-mono" data-type-marker="{{$line.GetLineTypeMarker}}"></span></td>
+ <td class="lines-code lines-code-old del-code">{{/*
+ */}}{{if and $.root.SignedUserID $.root.PageIsPullFiles}}{{/*
+ */}}<button type="button" aria-label="{{ctx.Locale.Tr "repo.diff.comment.add_line_comment"}}" class="ui primary button add-code-comment add-code-comment-left{{if (not $line.CanComment)}} tw-invisible{{end}}" data-side="left" data-idx="{{$line.LeftIdx}}">{{/*
+ */}}{{svg "octicon-plus"}}{{/*
+ */}}</button>{{/*
+ */}}{{end}}{{/*
+ */}}{{if $line.LeftIdx}}{{/*
+ */}}{{template "repo/diff/section_code" dict "diff" $leftDiff}}{{/*
+ */}}{{else}}{{/*
+ */}}<code class="code-inner"></code>{{/*
+ */}}{{end}}{{/*
+ */}}</td>
+ <td class="lines-num lines-num-new add-code" data-line-num="{{if $match.RightIdx}}{{$match.RightIdx}}{{end}}"><span rel="{{if $match.RightIdx}}diff-{{$file.NameHash}}R{{$match.RightIdx}}{{end}}"></span></td>
+ <td class="lines-escape add-code lines-escape-new">{{if $match.RightIdx}}{{if $rightDiff.EscapeStatus.Escaped}}<button class="toggle-escape-button btn interact-bg" title="{{template "repo/diff/escape_title" dict "diff" $rightDiff}}"></button>{{end}}{{end}}</td>
+ <td class="lines-type-marker lines-type-marker-new add-code">{{if $match.RightIdx}}<span class="tw-font-mono" data-type-marker="{{$match.GetLineTypeMarker}}"></span>{{end}}</td>
+ <td class="lines-code lines-code-new add-code">{{/*
+ */}}{{if and $.root.SignedUserID $.root.PageIsPullFiles}}{{/*
+ */}}<button type="button" aria-label="{{ctx.Locale.Tr "repo.diff.comment.add_line_comment"}}" class="ui primary button add-code-comment add-code-comment-right{{if (not $match.CanComment)}} tw-invisible{{end}}" data-side="right" data-idx="{{$match.RightIdx}}">{{/*
+ */}}{{svg "octicon-plus"}}{{/*
+ */}}</button>{{/*
+ */}}{{end}}{{/*
+ */}}{{if $match.RightIdx}}{{/*
+ */}}{{template "repo/diff/section_code" dict "diff" $rightDiff}}{{/*
+ */}}{{else}}{{/*
+ */}}<code class="code-inner"></code>{{/*
+ */}}{{end}}{{/*
+ */}}</td>
+ {{else}}
+ {{$inlineDiff := $section.GetComputedInlineDiffFor $line ctx.Locale}}
+ <td class="lines-num lines-num-old" data-line-num="{{if $line.LeftIdx}}{{$line.LeftIdx}}{{end}}"><span rel="{{if $line.LeftIdx}}diff-{{$file.NameHash}}L{{$line.LeftIdx}}{{end}}"></span></td>
+ <td class="lines-escape lines-escape-old">{{if $line.LeftIdx}}{{if $inlineDiff.EscapeStatus.Escaped}}<button class="toggle-escape-button btn interact-bg" title="{{template "repo/diff/escape_title" dict "diff" $inlineDiff}}"></button>{{end}}{{end}}</td>
+ <td class="lines-type-marker lines-type-marker-old">{{if $line.LeftIdx}}<span class="tw-font-mono" data-type-marker="{{$line.GetLineTypeMarker}}"></span>{{end}}</td>
+ <td class="lines-code lines-code-old">{{/*
+ */}}{{if and $.root.SignedUserID $.root.PageIsPullFiles (not (eq .GetType 2))}}{{/*
+ */}}<button type="button" aria-label="{{ctx.Locale.Tr "repo.diff.comment.add_line_comment"}}" class="ui primary button add-code-comment add-code-comment-left{{if (not $line.CanComment)}} tw-invisible{{end}}" data-side="left" data-idx="{{$line.LeftIdx}}">{{/*
+ */}}{{svg "octicon-plus"}}{{/*
+ */}}</button>{{/*
+ */}}{{end}}{{/*
+ */}}{{if $line.LeftIdx}}{{/*
+ */}}{{template "repo/diff/section_code" dict "diff" $inlineDiff}}{{/*
+ */}}{{else}}{{/*
+ */}}<code class="code-inner"></code>{{/*
+ */}}{{end}}{{/*
+ */}}</td>
+ <td class="lines-num lines-num-new" data-line-num="{{if $line.RightIdx}}{{$line.RightIdx}}{{end}}"><span rel="{{if $line.RightIdx}}diff-{{$file.NameHash}}R{{$line.RightIdx}}{{end}}"></span></td>
+ <td class="lines-escape lines-escape-new">{{if $line.RightIdx}}{{if $inlineDiff.EscapeStatus.Escaped}}<button class="toggle-escape-button btn interact-bg" title="{{template "repo/diff/escape_title" dict "diff" $inlineDiff}}"></button>{{end}}{{end}}</td>
+ <td class="lines-type-marker lines-type-marker-new">{{if $line.RightIdx}}<span class="tw-font-mono" data-type-marker="{{$line.GetLineTypeMarker}}"></span>{{end}}</td>
+ <td class="lines-code lines-code-new">{{/*
+ */}}{{if and $.root.SignedUserID $.root.PageIsPullFiles (not (eq .GetType 3))}}{{/*
+ */}}<button type="button" aria-label="{{ctx.Locale.Tr "repo.diff.comment.add_line_comment"}}" class="ui primary button add-code-comment add-code-comment-right{{if (not $line.CanComment)}} tw-invisible{{end}}" data-side="right" data-idx="{{$line.RightIdx}}">{{/*
+ */}}{{svg "octicon-plus"}}{{/*
+ */}}</button>{{/*
+ */}}{{end}}{{/*
+ */}}{{if $line.RightIdx}}{{/*
+ */}}{{template "repo/diff/section_code" dict "diff" $inlineDiff}}{{/*
+ */}}{{else}}{{/*
+ */}}<code class="code-inner"></code>{{/*
+ */}}{{end}}{{/*
+ */}}</td>
+ {{end}}
+ </tr>
+ {{if and (eq .GetType 3) $hasmatch}}
+ {{$match := index $section.Lines $line.Match}}
+ {{if or $line.Conversations $match.Conversations}}
+ <tr class="add-comment" data-line-type="{{.GetHTMLDiffLineType}}">
+ <td class="add-comment-left" colspan="4">
+ {{if $line.Conversations}}
+ {{if eq $line.GetCommentSide "previous"}}
+ {{template "repo/diff/conversations" dict "." $.root "conversations" $line.Conversations}}
+ {{end}}
+ {{end}}
+ {{if $match.Conversations}}
+ {{if eq $match.GetCommentSide "previous"}}
+ {{template "repo/diff/conversations" dict "." $.root "conversations" $match.Conversations}}
+ {{end}}
+ {{end}}
+ </td>
+ <td class="add-comment-right" colspan="4">
+ {{if $line.Conversations}}
+ {{if eq $line.GetCommentSide "proposed"}}
+ {{template "repo/diff/conversations" dict "." $.root "conversations" $line.Conversations}}
+ {{end}}
+ {{end}}
+ {{if $match.Conversations}}
+ {{if eq $match.GetCommentSide "proposed"}}
+ {{template "repo/diff/conversations" dict "." $.root "conversations" $match.Conversations}}
+ {{end}}
+ {{end}}
+ </td>
+ </tr>
+ {{end}}
+ {{else if $line.Conversations}}
+ <tr class="add-comment" data-line-type="{{.GetHTMLDiffLineType}}">
+ <td class="add-comment-left" colspan="4">
+ {{if eq $line.GetCommentSide "previous"}}
+ {{template "repo/diff/conversations" dict "." $.root "conversations" $line.Conversations}}
+ {{end}}
+ </td>
+ <td class="add-comment-right" colspan="4">
+ {{if eq $line.GetCommentSide "proposed"}}
+ {{template "repo/diff/conversations" dict "." $.root "conversations" $line.Conversations}}
+ {{end}}
+ </td>
+ </tr>
+ {{end}}
+ {{end}}
+ {{end}}
+{{end}}
diff --git a/templates/repo/diff/section_unified.tmpl b/templates/repo/diff/section_unified.tmpl
new file mode 100644
index 0000000..ab78097
--- /dev/null
+++ b/templates/repo/diff/section_unified.tmpl
@@ -0,0 +1,72 @@
+{{$file := .file}}
+{{$blobExcerptRepoLink := or $.root.CommitRepoLink $.root.RepoLink}}
+<colgroup>
+ <col width="50">
+ <col width="50">
+ <col width="10">
+ <col width="10">
+ <col>
+</colgroup>
+{{range $j, $section := $file.Sections}}
+ {{range $k, $line := $section.Lines}}
+ <tr class="{{.GetHTMLDiffLineType}}-code nl-{{$k}} ol-{{$k}}" data-line-type="{{.GetHTMLDiffLineType}}">
+ {{if eq .GetType 4}}
+ {{if $.root.AfterCommitID}}
+ <td colspan="2" class="lines-num">
+ <div class="tw-flex">
+ {{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 5)}}
+ <button class="code-expander-button" hx-target="closest tr" hx-get="{{$blobExcerptRepoLink}}/blob_excerpt/{{PathEscape $.root.AfterCommitID}}?{{$line.GetBlobExcerptQuery}}&style=unified&direction=down&wiki={{$.root.PageIsWiki}}&anchor=diff-{{$file.NameHash}}K{{$line.SectionInfo.RightIdx}}">
+ {{svg "octicon-fold-down"}}
+ </button>
+ {{end}}
+ {{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 4)}}
+ <button class="code-expander-button" hx-target="closest tr" hx-get="{{$blobExcerptRepoLink}}/blob_excerpt/{{PathEscape $.root.AfterCommitID}}?{{$line.GetBlobExcerptQuery}}&style=unified&direction=up&wiki={{$.root.PageIsWiki}}&anchor=diff-{{$file.NameHash}}K{{$line.SectionInfo.RightIdx}}">
+ {{svg "octicon-fold-up"}}
+ </button>
+ {{end}}
+ {{if eq $line.GetExpandDirection 2}}
+ <button class="code-expander-button" hx-target="closest tr" hx-get="{{$blobExcerptRepoLink}}/blob_excerpt/{{PathEscape $.root.AfterCommitID}}?{{$line.GetBlobExcerptQuery}}&style=unified&direction=&wiki={{$.root.PageIsWiki}}&anchor=diff-{{$file.NameHash}}K{{$line.SectionInfo.RightIdx}}">
+ {{svg "octicon-fold"}}
+ </button>
+ {{end}}
+ </div>
+ </td>
+ {{else}}
+ {{/* for code file preview page or comment diffs on pull comment pages, do not show the expansion arrows */}}
+ <td colspan="2" class="lines-num"></td>
+ {{end}}
+ {{else}}
+ <td class="lines-num lines-num-old" data-line-num="{{if $line.LeftIdx}}{{$line.LeftIdx}}{{end}}"><span rel="{{if $line.LeftIdx}}diff-{{$file.NameHash}}L{{$line.LeftIdx}}{{end}}"></span></td>
+ <td class="lines-num lines-num-new" data-line-num="{{if $line.RightIdx}}{{$line.RightIdx}}{{end}}"><span rel="{{if $line.RightIdx}}diff-{{$file.NameHash}}R{{$line.RightIdx}}{{end}}"></span></td>
+ {{end}}
+ {{$inlineDiff := $section.GetComputedInlineDiffFor $line ctx.Locale -}}
+ <td class="lines-escape">
+ {{- if $inlineDiff.EscapeStatus.Escaped -}}
+ <button class="toggle-escape-button btn interact-bg" title="{{template "repo/diff/escape_title" dict "diff" $inlineDiff}}"></button>
+ {{- end -}}
+ </td>
+ <td class="lines-type-marker"><span class="tw-font-mono" data-type-marker="{{$line.GetLineTypeMarker}}"></span></td>
+ {{if eq .GetType 4}}
+ <td class="chroma lines-code blob-hunk">{{/*
+ */}}{{template "repo/diff/section_code" dict "diff" $inlineDiff}}{{/*
+ */}}</td>
+ {{else}}
+ <td class="chroma lines-code{{if (not $line.RightIdx)}} lines-code-old{{end}}">{{/*
+ */}}{{if and $.root.SignedUserID $.root.PageIsPullFiles}}{{/*
+ */}}<button type="button" aria-label="{{ctx.Locale.Tr "repo.diff.comment.add_line_comment"}}" class="ui primary button add-code-comment add-code-comment-{{if $line.RightIdx}}right{{else}}left{{end}}{{if (not $line.CanComment)}} tw-invisible{{end}}" data-side="{{if $line.RightIdx}}right{{else}}left{{end}}" data-idx="{{if $line.RightIdx}}{{$line.RightIdx}}{{else}}{{$line.LeftIdx}}{{end}}">{{/*
+ */}}{{svg "octicon-plus"}}{{/*
+ */}}</button>{{/*
+ */}}{{end}}{{/*
+ */}}{{template "repo/diff/section_code" dict "diff" $inlineDiff}}{{/*
+ */}}</td>
+ {{end}}
+ </tr>
+ {{if $line.Conversations}}
+ <tr class="add-comment" data-line-type="{{.GetHTMLDiffLineType}}">
+ <td class="add-comment-left add-comment-right" colspan="5">
+ {{template "repo/diff/conversations" dict "." $.root "conversations" $line.Conversations}}
+ </td>
+ </tr>
+ {{end}}
+ {{end}}
+{{end}}
diff --git a/templates/repo/diff/stats.tmpl b/templates/repo/diff/stats.tmpl
new file mode 100644
index 0000000..d0dff1b
--- /dev/null
+++ b/templates/repo/diff/stats.tmpl
@@ -0,0 +1,5 @@
+{{Eval .file.Addition "+" .file.Deletion}}
+<span class="diff-stats-bar tw-mx-2" data-tooltip-content="{{ctx.Locale.Tr "repo.diff.stats_desc_file" (Eval .file.Addition "+" .file.Deletion) .file.Addition .file.Deletion}}">
+ {{/* if the denominator is zero, then the float result is "width: NaNpx", as before, it just works */}}
+ <div class="diff-stats-add-bar" style="width: {{Eval 100 "*" .file.Addition "/" "(" .file.Addition "+" .file.Deletion "+" 0.0 ")"}}%"></div>
+</span>
diff --git a/templates/repo/diff/whitespace_dropdown.tmpl b/templates/repo/diff/whitespace_dropdown.tmpl
new file mode 100644
index 0000000..c54de16
--- /dev/null
+++ b/templates/repo/diff/whitespace_dropdown.tmpl
@@ -0,0 +1,30 @@
+<div class="ui dropdown tiny basic button" data-tooltip-content="{{ctx.Locale.Tr "repo.diff.whitespace_button"}}">
+ {{svg "gitea-whitespace"}}
+ <div class="menu">
+ <a class="item" href="?style={{if .IsSplitStyle}}split{{else}}unified{{end}}&whitespace=show-all&show-outdated={{$.ShowOutdatedComments}}">
+ <label class="tw-pointer-events-none">
+ <input class="tw-mr-2 tw-pointer-events-none" type="radio"{{if eq .WhitespaceBehavior "show-all"}} checked{{end}}>
+ {{ctx.Locale.Tr "repo.diff.whitespace_show_everything"}}
+ </label>
+ </a>
+ <a class="item" href="?style={{if .IsSplitStyle}}split{{else}}unified{{end}}&whitespace=ignore-all&show-outdated={{$.ShowOutdatedComments}}">
+ <label class="tw-pointer-events-none">
+ <input class="tw-mr-2 tw-pointer-events-none" type="radio"{{if eq .WhitespaceBehavior "ignore-all"}} checked{{end}}>
+ {{ctx.Locale.Tr "repo.diff.whitespace_ignore_all_whitespace"}}
+ </label>
+ </a>
+ <a class="item" href="?style={{if .IsSplitStyle}}split{{else}}unified{{end}}&whitespace=ignore-change&show-outdated={{$.ShowOutdatedComments}}">
+ <label class="tw-pointer-events-none">
+ <input class="tw-mr-2 tw-pointer-events-none" type="radio"{{if eq .WhitespaceBehavior "ignore-change"}} checked{{end}}>
+ {{ctx.Locale.Tr "repo.diff.whitespace_ignore_amount_changes"}}
+ </label>
+ </a>
+ <a class="item" href="?style={{if .IsSplitStyle}}split{{else}}unified{{end}}&whitespace=ignore-eol&show-outdated={{$.ShowOutdatedComments}}">
+ <label class="tw-pointer-events-none">
+ <input class="tw-mr-2 tw-pointer-events-none" type="radio"{{if eq .WhitespaceBehavior "ignore-eol"}} checked{{end}}>
+ {{ctx.Locale.Tr "repo.diff.whitespace_ignore_at_eol"}}
+ </label>
+ </a>
+ </div>
+</div>
+<a class="ui tiny basic button" href="?style={{if .IsSplitStyle}}unified{{else}}split{{end}}&whitespace={{$.WhitespaceBehavior}}&show-outdated={{$.ShowOutdatedComments}}" data-tooltip-content="{{if .IsSplitStyle}}{{ctx.Locale.Tr "repo.diff.show_unified_view"}}{{else}}{{ctx.Locale.Tr "repo.diff.show_split_view"}}{{end}}">{{if .IsSplitStyle}}{{svg "gitea-join"}}{{else}}{{svg "gitea-split"}}{{end}}</a>