Skip to content

Commit 149a9df

Browse files
blueworrybearlunny
authored andcommitted
Expand/Collapse Files and Blob Excerpt while Reviewing/Comparing code (#8924)
* update #8659 fold/unfold code diffs * add fold button style * update #8659 implement expand up/down codes (blob excerpt) * fix golint errors * fix expand direction * remove debug message * update css style for blob exceprt * fix typo in comment * update style sheet with less * update expect diff (add SectionInfo) * update #8942 accept suggested change (fix typo) * close reader and check file type before get tail section * adjust button position and check file type before insert fold button * move index js to web_src * merge index.js with master * generate index.js * update js coding style
1 parent 42ada74 commit 149a9df

File tree

16 files changed

+460
-36
lines changed

16 files changed

+460
-36
lines changed

modules/git/blob.go

+23
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package git
77

88
import (
9+
"bytes"
910
"encoding/base64"
1011
"io"
1112
"io/ioutil"
@@ -50,6 +51,28 @@ func (b *Blob) GetBlobContent() (string, error) {
5051
return string(buf), nil
5152
}
5253

54+
// GetBlobLineCount gets line count of lob as raw text
55+
func (b *Blob) GetBlobLineCount() (int, error) {
56+
reader, err := b.DataAsync()
57+
if err != nil {
58+
return 0, err
59+
}
60+
defer reader.Close()
61+
buf := make([]byte, 32*1024)
62+
count := 0
63+
lineSep := []byte{'\n'}
64+
for {
65+
c, err := reader.Read(buf)
66+
count += bytes.Count(buf[:c], lineSep)
67+
switch {
68+
case err == io.EOF:
69+
return count, nil
70+
case err != nil:
71+
return count, err
72+
}
73+
}
74+
}
75+
5376
// GetBlobContentBase64 Reads the content of the blob with a base64 encode and returns the encoded string
5477
func (b *Blob) GetBlobContentBase64() (string, error) {
5578
dataRc, err := b.DataAsync()

modules/repofiles/diff_test.go

+9
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,15 @@ func TestGetDiffPreview(t *testing.T) {
5555
Type: 4,
5656
Content: "@@ -1,3 +1,4 @@",
5757
Comments: nil,
58+
SectionInfo: &gitdiff.DiffLineSectionInfo{
59+
Path: "README.md",
60+
LastLeftIdx: 0,
61+
LastRightIdx: 0,
62+
LeftIdx: 1,
63+
RightIdx: 1,
64+
LeftHunkSize: 3,
65+
RightHunkSize: 4,
66+
},
5867
},
5968
{
6069
LeftIdx: 1,

public/css/index.css

+6-1
Original file line numberDiff line numberDiff line change
@@ -898,6 +898,7 @@ tbody.commit-list{vertical-align:baseline}
898898
.repo-buttons .disabled-repo-button a.button:hover{background:0 0!important;color:rgba(0,0,0,.6)!important;box-shadow:0 0 0 1px rgba(34,36,38,.15) inset!important}
899899
.repo-buttons .ui.labeled.button>.label{border-left:0!important;margin:0!important}
900900
.tag-code,.tag-code td{background-color:#f0f0f0!important;border-color:#d3cfcf!important;padding-top:8px;padding-bottom:8px}
901+
td.blob-excerpt{background-color:#fafafa}
901902
.issue-keyword{border-bottom:1px dotted #959da5;display:inline-block}
902903
.file-header{display:flex;justify-content:space-between;align-items:center;padding:8px 12px!important}
903904
.file-info{display:flex;align-items:center}
@@ -1068,4 +1069,8 @@ tbody.commit-list{vertical-align:baseline}
10681069
.comment-code-cloud .footer:after{clear:both;content:"";display:block}
10691070
.comment-code-cloud button.comment-form-reply{margin:.5em .5em .5em 4.5em}
10701071
.comment-code-cloud form.comment-form-reply{margin:0 0 0 4em}
1071-
.file-comment{font:12px 'SF Mono',Consolas,Menlo,'Liberation Mono',Monaco,'Lucida Console',monospace;color:rgba(0,0,0,.87)}
1072+
.file-comment{font:12px 'SF Mono',Consolas,Menlo,'Liberation Mono',Monaco,'Lucida Console',monospace;color:rgba(0,0,0,.87)}
1073+
.ui.fold-code{margin-right:1em;padding-left:5px;cursor:pointer;width:22px;font-size:12px}
1074+
.ui.fold-code:hover{color:#428bca}
1075+
.ui.blob-excerpt{display:block;line-height:20px;font-size:16px;cursor:pointer}
1076+
.ui.blob-excerpt:hover{color:#428bca}

public/js/index.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

public/js/index.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

routers/repo/commit.go

+1
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@ func Diff(ctx *context.Context) {
245245
}
246246

247247
ctx.Data["CommitID"] = commitID
248+
ctx.Data["AfterCommitID"] = commitID
248249
ctx.Data["Username"] = userName
249250
ctx.Data["Reponame"] = repoName
250251

routers/repo/compare.go

+112-1
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,26 @@
55
package repo
66

77
import (
8+
"bufio"
89
"fmt"
10+
"html"
911
"path"
12+
"path/filepath"
1013
"strings"
1114

1215
"code.gitea.io/gitea/models"
1316
"code.gitea.io/gitea/modules/base"
1417
"code.gitea.io/gitea/modules/context"
1518
"code.gitea.io/gitea/modules/git"
19+
"code.gitea.io/gitea/modules/highlight"
1620
"code.gitea.io/gitea/modules/log"
1721
"code.gitea.io/gitea/modules/setting"
1822
"code.gitea.io/gitea/services/gitdiff"
1923
)
2024

2125
const (
22-
tplCompare base.TplName = "repo/diff/compare"
26+
tplCompare base.TplName = "repo/diff/compare"
27+
tplBlobExcerpt base.TplName = "repo/diff/blob_excerpt"
2328
)
2429

2530
// setPathsCompareContext sets context data for source and raw paths
@@ -434,3 +439,109 @@ func CompareDiff(ctx *context.Context) {
434439

435440
ctx.HTML(200, tplCompare)
436441
}
442+
443+
// ExcerptBlob render blob excerpt contents
444+
func ExcerptBlob(ctx *context.Context) {
445+
commitID := ctx.Params("sha")
446+
lastLeft := ctx.QueryInt("last_left")
447+
lastRight := ctx.QueryInt("last_right")
448+
idxLeft := ctx.QueryInt("left")
449+
idxRight := ctx.QueryInt("right")
450+
leftHunkSize := ctx.QueryInt("left_hunk_size")
451+
rightHunkSize := ctx.QueryInt("right_hunk_size")
452+
anchor := ctx.Query("anchor")
453+
direction := ctx.Query("direction")
454+
filePath := ctx.Query("path")
455+
gitRepo := ctx.Repo.GitRepo
456+
chunkSize := gitdiff.BlobExceprtChunkSize
457+
commit, err := gitRepo.GetCommit(commitID)
458+
if err != nil {
459+
ctx.Error(500, "GetCommit")
460+
return
461+
}
462+
section := &gitdiff.DiffSection{
463+
Name: filePath,
464+
}
465+
if direction == "up" && (idxLeft-lastLeft) > chunkSize {
466+
idxLeft -= chunkSize
467+
idxRight -= chunkSize
468+
leftHunkSize += chunkSize
469+
rightHunkSize += chunkSize
470+
section.Lines, err = getExcerptLines(commit, filePath, idxLeft-1, idxRight-1, chunkSize)
471+
} else if direction == "down" && (idxLeft-lastLeft) > chunkSize {
472+
section.Lines, err = getExcerptLines(commit, filePath, lastLeft, lastRight, chunkSize)
473+
lastLeft += chunkSize
474+
lastRight += chunkSize
475+
} else {
476+
section.Lines, err = getExcerptLines(commit, filePath, lastLeft, lastRight, idxRight-lastRight-1)
477+
leftHunkSize = 0
478+
rightHunkSize = 0
479+
idxLeft = lastLeft
480+
idxRight = lastRight
481+
}
482+
if err != nil {
483+
ctx.Error(500, "getExcerptLines")
484+
return
485+
}
486+
if idxRight > lastRight {
487+
lineText := " "
488+
if rightHunkSize > 0 || leftHunkSize > 0 {
489+
lineText = fmt.Sprintf("@@ -%d,%d +%d,%d @@\n", idxLeft, leftHunkSize, idxRight, rightHunkSize)
490+
}
491+
lineText = html.EscapeString(lineText)
492+
lineSection := &gitdiff.DiffLine{
493+
Type: gitdiff.DiffLineSection,
494+
Content: lineText,
495+
SectionInfo: &gitdiff.DiffLineSectionInfo{
496+
Path: filePath,
497+
LastLeftIdx: lastLeft,
498+
LastRightIdx: lastRight,
499+
LeftIdx: idxLeft,
500+
RightIdx: idxRight,
501+
LeftHunkSize: leftHunkSize,
502+
RightHunkSize: rightHunkSize,
503+
}}
504+
if direction == "up" {
505+
section.Lines = append([]*gitdiff.DiffLine{lineSection}, section.Lines...)
506+
} else if direction == "down" {
507+
section.Lines = append(section.Lines, lineSection)
508+
}
509+
}
510+
ctx.Data["section"] = section
511+
ctx.Data["fileName"] = filePath
512+
ctx.Data["highlightClass"] = highlight.FileNameToHighlightClass(filepath.Base(filePath))
513+
ctx.Data["AfterCommitID"] = commitID
514+
ctx.Data["Anchor"] = anchor
515+
ctx.HTML(200, tplBlobExcerpt)
516+
}
517+
518+
func getExcerptLines(commit *git.Commit, filePath string, idxLeft int, idxRight int, chunkSize int) ([]*gitdiff.DiffLine, error) {
519+
blob, err := commit.Tree.GetBlobByPath(filePath)
520+
if err != nil {
521+
return nil, err
522+
}
523+
reader, err := blob.DataAsync()
524+
if err != nil {
525+
return nil, err
526+
}
527+
defer reader.Close()
528+
scanner := bufio.NewScanner(reader)
529+
var diffLines []*gitdiff.DiffLine
530+
for line := 0; line < idxRight+chunkSize; line++ {
531+
if ok := scanner.Scan(); !ok {
532+
break
533+
}
534+
if line < idxRight {
535+
continue
536+
}
537+
lineText := scanner.Text()
538+
diffLine := &gitdiff.DiffLine{
539+
LeftIdx: idxLeft + (line - idxRight) + 1,
540+
RightIdx: line + 1,
541+
Type: gitdiff.DiffLinePlain,
542+
Content: " " + lineText,
543+
}
544+
diffLines = append(diffLines, diffLine)
545+
}
546+
return diffLines, nil
547+
}

routers/repo/pull.go

+1
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,7 @@ func ViewPullFiles(ctx *context.Context) {
552552
ctx.Data["Username"] = pull.MustHeadUserName()
553553
ctx.Data["Reponame"] = pull.HeadRepo.Name
554554
}
555+
ctx.Data["AfterCommitID"] = endCommitID
555556

556557
diff, err := gitdiff.GetDiffRangeWithWhitespaceBehavior(diffRepoPath,
557558
startCommitID, endCommitID, setting.Git.MaxGitDiffLines,

routers/routes/routes.go

+4
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,10 @@ func RegisterRoutes(m *macaron.Macaron) {
864864
m.Get("", repo.Branches)
865865
}, repo.MustBeNotEmpty, context.RepoRef(), reqRepoCodeReader)
866866

867+
m.Group("/blob_excerpt", func() {
868+
m.Get("/:sha", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.ExcerptBlob)
869+
}, repo.MustBeNotEmpty, context.RepoRef(), reqRepoCodeReader)
870+
867871
m.Group("/pulls/:index", func() {
868872
m.Get(".diff", repo.DownloadPullDiff)
869873
m.Get(".patch", repo.DownloadPullPatch)

0 commit comments

Comments
 (0)