Skip to content

Commit 540d07c

Browse files
committed
add escape status support
1 parent e082a4f commit 540d07c

File tree

7 files changed

+58
-29
lines changed

7 files changed

+58
-29
lines changed

modules/indexer/code/search.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ type Result struct {
2222
UpdatedUnix timeutil.TimeStamp
2323
Language string
2424
Color string
25-
Lines []ResultLine
25+
Lines []*ResultLine
2626
}
2727

2828
type ResultLine struct {
@@ -70,16 +70,18 @@ func writeStrings(buf *bytes.Buffer, strs ...string) error {
7070
return nil
7171
}
7272

73-
func HighlightSearchResultCode(filename, language string, lineNums []int, code string) []ResultLine {
73+
func HighlightSearchResultCode(filename, language string, lineNums []int, code string) []*ResultLine {
7474
// we should highlight the whole code block first, otherwise it doesn't work well with multiple line highlighting
7575
hl, _ := highlight.Code(filename, language, code)
7676
highlightedLines := strings.Split(string(hl), "\n")
7777

7878
// The lineNums outputted by highlight.Code might not match the original lineNums, because "highlight" removes the last `\n`
79-
lines := make([]ResultLine, min(len(highlightedLines), len(lineNums)))
79+
lines := make([]*ResultLine, min(len(highlightedLines), len(lineNums)))
8080
for i := 0; i < len(lines); i++ {
81-
lines[i].Num = lineNums[i]
82-
lines[i].FormattedContent = template.HTML(highlightedLines[i])
81+
lines[i] = &ResultLine{
82+
Num: lineNums[i],
83+
FormattedContent: template.HTML(highlightedLines[i]),
84+
}
8385
}
8486
return lines
8587
}

modules/markup/html_codepreview.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"strings"
1212

1313
"code.gitea.io/gitea/modules/httplib"
14+
"code.gitea.io/gitea/modules/log"
1415

1516
"golang.org/x/net/html"
1617
)
@@ -62,6 +63,9 @@ func codePreviewPatternProcessor(ctx *RenderContext, node *html.Node) {
6263
for node != nil {
6364
urlPosStart, urlPosEnd, h, err := renderCodeBlock(ctx, node)
6465
if err != nil || h == "" {
66+
if err != nil {
67+
log.Error("Unable to render code preview: %v", err)
68+
}
6569
node = node.NextSibling
6670
continue
6771
}

modules/markup/sanitizer.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,21 @@ func createDefaultPolicy() *bluemonday.Policy {
5858
policy := bluemonday.UGCPolicy()
5959

6060
// For JS code copy and Mermaid loading state
61-
policy.AllowAttrs("class").Matching(regexp.MustCompile(`^code-block( is-loading)?$`)).Globally()
61+
policy.AllowAttrs("class").Matching(regexp.MustCompile(`^code-block( is-loading)?$`)).OnElements("pre")
6262

6363
// For code preview
64-
policy.AllowAttrs("class").Matching(regexp.MustCompile(`^code-preview-[-\w]+$`)).Globally()
65-
policy.AllowAttrs("class").Matching(regexp.MustCompile(`^lines-num$`)).Globally()
66-
policy.AllowAttrs("class").Matching(regexp.MustCompile(`^lines-code chroma$`)).Globally()
64+
policy.AllowAttrs("class").Matching(regexp.MustCompile(`^code-preview-[-\w]+( file-content)?$`)).Globally()
65+
policy.AllowAttrs("class").Matching(regexp.MustCompile(`^lines-num$`)).OnElements("td")
6766
policy.AllowAttrs("data-line-number").OnElements("span")
67+
policy.AllowAttrs("class").Matching(regexp.MustCompile(`^lines-code chroma$`)).OnElements("td")
68+
69+
// For code preview (unicode escape)
70+
policy.AllowAttrs("class").Matching(regexp.MustCompile(`^file-view( unicode-escaped)?$`)).OnElements("table")
71+
policy.AllowAttrs("class").Matching(regexp.MustCompile(`^lines-escape$`)).OnElements("td")
72+
policy.AllowAttrs("class").Matching(regexp.MustCompile(`^toggle-escape-button btn interact-bg$`)).OnElements("a") // don't use button, button might submit a form
73+
policy.AllowAttrs("class").Matching(regexp.MustCompile(`^(ambiguous-code-point|escaped-code-point|broken-code-point)$`)).OnElements("span")
74+
policy.AllowAttrs("class").Matching(regexp.MustCompile(`^char$`)).OnElements("span")
75+
policy.AllowAttrs("data-tooltip-content", "data-escaped").OnElements("span")
6876

6977
// For color preview
7078
policy.AllowAttrs("class").Matching(regexp.MustCompile(`^color-preview$`)).OnElements("span")

services/markup/processorhelper_codepreview.go

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"code.gitea.io/gitea/models/perm/access"
1414
"code.gitea.io/gitea/models/repo"
1515
"code.gitea.io/gitea/models/unit"
16+
"code.gitea.io/gitea/modules/charset"
1617
"code.gitea.io/gitea/modules/gitrepo"
1718
"code.gitea.io/gitea/modules/indexer/code"
1819
"code.gitea.io/gitea/modules/markup"
@@ -22,7 +23,7 @@ import (
2223
)
2324

2425
func renderRepoFileCodePreview(ctx context.Context, opts markup.RenderCodePreviewOptions) (template.HTML, error) {
25-
opts.LineStop = max(opts.LineStop, 1)
26+
opts.LineStop = max(opts.LineStop, opts.LineStart)
2627
lineCount := opts.LineStop - opts.LineStart + 1
2728
if lineCount <= 0 || lineCount > 140 /* GitHub at most show 140 lines */ {
2829
lineCount = 10
@@ -76,7 +77,6 @@ func renderRepoFileCodePreview(ctx context.Context, opts markup.RenderCodePrevie
7677
defer dataRc.Close()
7778

7879
reader := bufio.NewReader(dataRc)
79-
8080
for i := 1; i < opts.LineStart; i++ {
8181
if _, err = reader.ReadBytes('\n'); err != nil {
8282
return "", err
@@ -86,21 +86,32 @@ func renderRepoFileCodePreview(ctx context.Context, opts markup.RenderCodePrevie
8686
lineNums := make([]int, 0, lineCount)
8787
lineCodes := make([]string, 0, lineCount)
8888
for i := opts.LineStart; i <= opts.LineStop; i++ {
89-
if line, err := reader.ReadString('\n'); err != nil {
89+
if line, err := reader.ReadString('\n'); err != nil && line == "" {
9090
break
9191
} else {
9292
lineNums = append(lineNums, i)
9393
lineCodes = append(lineCodes, line)
9494
}
9595
}
96+
realLineStop := max(opts.LineStart, opts.LineStart+len(lineNums)-1)
9697
highlightLines := code.HighlightSearchResultCode(opts.FilePath, language, lineNums, strings.Join(lineCodes, ""))
98+
99+
escapeStatus := &charset.EscapeStatus{}
100+
lineEscapeStatus := make([]*charset.EscapeStatus, len(highlightLines))
101+
for i, hl := range highlightLines {
102+
lineEscapeStatus[i], hl.FormattedContent = charset.EscapeControlHTML(hl.FormattedContent, webCtx.Base.Locale, charset.RuneNBSP)
103+
escapeStatus = escapeStatus.Or(lineEscapeStatus[i])
104+
}
105+
97106
return webCtx.RenderToHTML("base/markup_codepreview", map[string]any{
98-
"FullURL": opts.FullURL,
99-
"FilePath": opts.FilePath,
100-
"LineStart": opts.LineStart,
101-
"LineStop": opts.LineStop,
102-
"RepoLink": dbRepo.Link(),
103-
"CommitID": opts.CommitID,
104-
"HighlightLines": highlightLines,
107+
"FullURL": opts.FullURL,
108+
"FilePath": opts.FilePath,
109+
"LineStart": opts.LineStart,
110+
"LineStop": realLineStop,
111+
"RepoLink": dbRepo.Link(),
112+
"CommitID": opts.CommitID,
113+
"HighlightLines": highlightLines,
114+
"EscapeStatus": escapeStatus,
115+
"LineEscapeStatus": lineEscapeStatus,
105116
})
106117
}

services/markup/processorhelper_codepreview_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,16 @@ func TestProcessorHelperCodePreview(t *testing.T) {
2525
CommitID: "65f1bf27bc3bf70f64657658635e66094edbcb4d",
2626
FilePath: "/README.md",
2727
LineStart: 1,
28-
LineStop: 10,
28+
LineStop: 2,
2929
})
3030
assert.NoError(t, err)
31-
assert.Equal(t, `<div class="code-preview-container">
31+
assert.Equal(t, `<div class="code-preview-container file-content">
3232
<div class="code-preview-header">
3333
<a href="http://full" class="muted" rel="nofollow">/README.md</a>
34-
Lines 1 to 10 in
34+
Lines 1 to 2 in
3535
<a href="/user2/repo1/src/commit/65f1bf27bc3bf70f64657658635e66094edbcb4d" rel="nofollow">65f1bf27bc</a>
3636
</div>
37-
<table>
37+
<table class="file-view">
3838
<tbody><tr>
3939
<td class="lines-num"><span data-line-number="1"></span></td>
4040
<td class="lines-code chroma"><span class="gh"># repo1</td>

templates/base/markup_codepreview.tmpl

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
1-
<div class="code-preview-container">
1+
<div class="code-preview-container file-content">
22
<div class="code-preview-header">
33
<a href="{{.FullURL}}" class="muted" rel="nofollow">{{.FilePath}}</a>
44
Lines {{.LineStart}} to {{.LineStop}} in
55
<a href="{{.RepoLink}}/src/commit/{{.CommitID}}" rel="nofollow">{{.CommitID | ShortSha}}</a>
66
</div>
7-
<table>
7+
<table class="file-view">
88
<tbody>
9-
{{- range .HighlightLines -}}
9+
{{- range $idx, $line := .HighlightLines -}}
1010
<tr>
11-
<td class="lines-num"><span data-line-number="{{.Num}}"></span></td>
12-
<td class="lines-code chroma">{{.FormattedContent}}</td>
11+
<td class="lines-num"><span data-line-number="{{$line.Num}}"></span></td>
12+
{{- if $.EscapeStatus.Escaped -}}
13+
{{- $lineEscapeStatus := index $.LineEscapeStatus $idx -}}
14+
<td class="lines-escape">{{if $lineEscapeStatus.Escaped}}<a href="#" class="toggle-escape-button btn interact-bg" title="{{if $lineEscapeStatus.HasInvisible}}{{ctx.Locale.Tr "repo.invisible_runes_line"}} {{end}}{{if $lineEscapeStatus.HasAmbiguous}}{{ctx.Locale.Tr "repo.ambiguous_runes_line"}}{{end}}"></a>{{end}}</td>
15+
{{- end}}
16+
<td class="lines-code chroma">{{$line.FormattedContent}}</td>
1317
</tr>
1418
{{- end -}}
1519
</tbody>

web_src/css/markup/codepreview.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
.markup .code-preview-container {
22
border: 1px solid var(--color-secondary);
3+
margin: 0.25em 0;
34
}
45

56
.markup .code-preview-container .code-preview-header {
@@ -10,7 +11,6 @@
1011

1112
.markup .code-preview-container table {
1213
width: 100%;
13-
margin: 0.25em 0;
1414
max-height: 100px;
1515
overflow-y: auto;
1616
}

0 commit comments

Comments
 (0)