loading up the forgejo repo on tangled to test page performance
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add setting to restrict count of lines being displayed & only highlight those lines

+116 -27
+2
custom/conf/app.example.ini
··· 2338 2338 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2339 2339 ;; Set the maximum number of characters in a mermaid source. (Set to -1 to disable limits) 2340 2340 ;MERMAID_MAX_SOURCE_CHARACTERS = 5000 2341 + ;; Set the maximum number of lines allowed for a filepreview. (Set to -1 to disable limits; set to 0 to disable the feature) 2342 + ;FILEPREVIEW_MAX_LINES = 50 2341 2343 2342 2344 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2343 2345 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+86 -15
modules/markup/file_preview.go
··· 4 4 package markup 5 5 6 6 import ( 7 + "bufio" 7 8 "bytes" 8 9 "html/template" 9 10 "regexp" ··· 12 13 "strings" 13 14 14 15 "code.gitea.io/gitea/modules/charset" 16 + "code.gitea.io/gitea/modules/highlight" 15 17 "code.gitea.io/gitea/modules/log" 16 18 "code.gitea.io/gitea/modules/setting" 17 19 "code.gitea.io/gitea/modules/translation" ··· 31 33 filePath string 32 34 start int 33 35 end int 36 + isTruncated bool 34 37 } 35 38 36 39 func NewFilePreview(ctx *RenderContext, node *html.Node, locale translation.Locale) *FilePreview { 40 + if (setting.FilePreviewMaxLines == 0) { 41 + // Feature is disabled 42 + return nil 43 + } 44 + 37 45 preview := &FilePreview{} 38 46 39 47 m := filePreviewPattern.FindStringSubmatchIndex(node.Data) ··· 63 71 preview.end = m[1] 64 72 65 73 projPathSegments := strings.Split(projPath, "/") 66 - fileContent, err := DefaultProcessorHelper.GetRepoFileContent( 74 + var language string 75 + fileBlob, err := DefaultProcessorHelper.GetRepoFileBlob( 67 76 ctx.Ctx, 68 77 projPathSegments[len(projPathSegments)-2], 69 78 projPathSegments[len(projPathSegments)-1], 70 79 commitSha, preview.filePath, 80 + &language, 71 81 ) 72 82 if err != nil { 73 83 return nil 74 84 } 75 85 76 86 lineSpecs := strings.Split(hash, "-") 77 - lineCount := len(fileContent) 87 + // lineCount := len(fileContent) 78 88 79 89 commitLinkBuffer := new(bytes.Buffer) 80 90 err = html.Render(commitLinkBuffer, createLink(node.Data[m[0]:m[5]], commitSha[0:7], "text black")) ··· 82 92 log.Error("failed to render commitLink: %v", err) 83 93 } 84 94 95 + var startLine, endLine int 96 + 85 97 if len(lineSpecs) == 1 { 86 - line, _ := strconv.Atoi(strings.TrimPrefix(lineSpecs[0], "L")) 87 - if line < 1 || line > lineCount { 88 - return nil 89 - } 98 + startLine, _ = strconv.Atoi(strings.TrimPrefix(lineSpecs[0], "L")) 99 + endLine = startLine 100 + // if line < 1 || line > lineCount { 101 + // return nil 102 + // } 90 103 91 - preview.fileContent = fileContent[line-1 : line] 104 + // preview.fileContent = fileContent[line-1 : line] 92 105 preview.subTitle = locale.Tr( 93 - "markup.filepreview.line", line, 106 + "markup.filepreview.line", startLine, 94 107 template.HTML(commitLinkBuffer.String()), 95 108 ) 96 109 97 - preview.lineOffset = line - 1 110 + preview.lineOffset = startLine - 1 98 111 } else { 99 - startLine, _ := strconv.Atoi(strings.TrimPrefix(lineSpecs[0], "L")) 100 - endLine, _ := strconv.Atoi(strings.TrimPrefix(lineSpecs[1], "L")) 112 + startLine, _ = strconv.Atoi(strings.TrimPrefix(lineSpecs[0], "L")) 113 + endLine, _ = strconv.Atoi(strings.TrimPrefix(lineSpecs[1], "L")) 101 114 102 - if startLine < 1 || endLine < 1 || startLine > lineCount || endLine > lineCount || endLine < startLine { 103 - return nil 104 - } 115 + // if startLine < 1 || endLine < 1 || startLine > lineCount || endLine > lineCount || endLine < startLine { 116 + // return nil 117 + // } 105 118 106 - preview.fileContent = fileContent[startLine-1 : endLine] 119 + // preview.fileContent = fileContent[startLine-1 : endLine] 107 120 preview.subTitle = locale.Tr( 108 121 "markup.filepreview.lines", startLine, endLine, 109 122 template.HTML(commitLinkBuffer.String()), ··· 112 125 preview.lineOffset = startLine - 1 113 126 } 114 127 128 + lineCount := endLine - (startLine-1) 129 + if startLine < 1 || endLine < 1 || lineCount < 1 { 130 + return nil 131 + } 132 + 133 + if setting.FilePreviewMaxLines > 0 && lineCount > setting.FilePreviewMaxLines { 134 + preview.isTruncated = true 135 + lineCount = setting.FilePreviewMaxLines 136 + } 137 + 138 + dataRc, err := fileBlob.DataAsync() 139 + if err != nil { 140 + return nil 141 + } 142 + defer dataRc.Close() 143 + 144 + reader := bufio.NewReader(dataRc) 145 + 146 + // skip all lines until we find our startLine 147 + for i := 1; i < startLine; i++ { 148 + _, err := reader.ReadBytes('\n') 149 + if err != nil { 150 + return nil 151 + } 152 + } 153 + 154 + // capture the lines we're interested in 155 + lineBuffer := new(bytes.Buffer) 156 + for i := 0; i < lineCount; i++ { 157 + buf, err := reader.ReadBytes('\n') 158 + if err != nil { 159 + break; 160 + } 161 + lineBuffer.Write(buf) 162 + } 163 + 164 + // highlight the file... 165 + fileContent, _, err := highlight.File(fileBlob.Name(), language, lineBuffer.Bytes()) 166 + if err != nil { 167 + log.Error("highlight.File failed, fallback to plain text: %v", err) 168 + fileContent = highlight.PlainText(lineBuffer.Bytes()) 169 + } 170 + preview.fileContent = fileContent 171 + 115 172 return preview 116 173 } 117 174 ··· 258 315 Attr: []html.Attribute{{Key: "class", Val: "file-preview-box"}}, 259 316 } 260 317 node.AppendChild(header) 318 + 319 + if (p.isTruncated) { 320 + warning := &html.Node{ 321 + Type: html.ElementNode, 322 + Data: atom.Div.String(), 323 + Attr: []html.Attribute{{Key: "class", Val: "ui warning message tw-text-left"}}, 324 + } 325 + warning.AppendChild(&html.Node{ 326 + Type: html.TextNode, 327 + Data: locale.TrString("markup.filepreview.truncated"), 328 + }) 329 + node.AppendChild(warning) 330 + } 331 + 261 332 node.AppendChild(twrapper) 262 333 263 334 return node
+1 -1
modules/markup/html.go
··· 1059 1059 if ctx.Metas == nil { 1060 1060 return 1061 1061 } 1062 - if DefaultProcessorHelper.GetRepoFileContent == nil { 1062 + if DefaultProcessorHelper.GetRepoFileBlob == nil { 1063 1063 return 1064 1064 } 1065 1065
+2 -2
modules/markup/renderer.go
··· 8 8 "context" 9 9 "errors" 10 10 "fmt" 11 - "html/template" 11 + // "html/template" 12 12 "io" 13 13 "net/url" 14 14 "path/filepath" ··· 32 32 33 33 type ProcessorHelper struct { 34 34 IsUsernameMentionable func(ctx context.Context, username string) bool 35 - GetRepoFileContent func(ctx context.Context, ownerName, repoName, commitSha, filePath string) ([]template.HTML, error) 35 + GetRepoFileBlob func(ctx context.Context, ownerName, repoName, commitSha, filePath string, language *string) (*git.Blob, error) 36 36 37 37 ElementDir string // the direction of the elements, eg: "ltr", "rtl", "auto", default to no direction attribute 38 38 }
+1
modules/markup/sanitizer.go
··· 135 135 policy.AllowAttrs("class").Matching(regexp.MustCompile("^ambiguous-code-point$")).OnElements("span") 136 136 policy.AllowAttrs("data-tooltip-content").OnElements("span") 137 137 policy.AllowAttrs("class").Matching(regexp.MustCompile("muted|(text black)")).OnElements("a") 138 + policy.AllowAttrs("class").Matching(regexp.MustCompile("^ui warning message tw-text-left$")).OnElements("div") 138 139 139 140 // Allow generally safe attributes 140 141 generalSafeAttrs := []string{
+2
modules/setting/markup.go
··· 15 15 ExternalMarkupRenderers []*MarkupRenderer 16 16 ExternalSanitizerRules []MarkupSanitizerRule 17 17 MermaidMaxSourceCharacters int 18 + FilePreviewMaxLines int 18 19 ) 19 20 20 21 const ( ··· 62 63 mustMapSetting(rootCfg, "markdown", &Markdown) 63 64 64 65 MermaidMaxSourceCharacters = rootCfg.Section("markup").Key("MERMAID_MAX_SOURCE_CHARACTERS").MustInt(5000) 66 + FilePreviewMaxLines = rootCfg.Section("markup").Key("FILEPREVIEW_MAX_LINES").MustInt(50) 65 67 ExternalMarkupRenderers = make([]*MarkupRenderer, 0, 10) 66 68 ExternalSanitizerRules = make([]MarkupSanitizerRule, 0, 10) 67 69
+1
options/locale/locale_en-US.ini
··· 3711 3711 [markup] 3712 3712 filepreview.line = Line %[1]d in %[2]s 3713 3713 filepreview.lines = Lines %[1]d to %[2]d in %[3]s 3714 + filepreview.truncated = Preview has been truncated
+15 -9
services/markup/processorhelper.go
··· 6 6 import ( 7 7 "context" 8 8 "fmt" 9 - "html/template" 10 - "io" 9 + 10 + // "html/template" 11 + // "io" 11 12 12 13 "code.gitea.io/gitea/models/perm/access" 13 14 "code.gitea.io/gitea/models/repo" 14 15 "code.gitea.io/gitea/models/unit" 15 16 "code.gitea.io/gitea/models/user" 17 + "code.gitea.io/gitea/modules/git" 16 18 "code.gitea.io/gitea/modules/gitrepo" 17 - "code.gitea.io/gitea/modules/highlight" 19 + // "code.gitea.io/gitea/modules/highlight" 18 20 "code.gitea.io/gitea/modules/log" 19 21 "code.gitea.io/gitea/modules/markup" 20 22 gitea_context "code.gitea.io/gitea/services/context" ··· 39 41 // when using gitea context (web context), use user's visibility and user's permission to check 40 42 return user.IsUserVisibleToViewer(giteaCtx, mentionedUser, giteaCtx.Doer) 41 43 }, 42 - GetRepoFileContent: func(ctx context.Context, ownerName, repoName, commitSha, filePath string) ([]template.HTML, error) { 44 + GetRepoFileBlob: func(ctx context.Context, ownerName, repoName, commitSha, filePath string, language *string) (*git.Blob, error) { 43 45 repo, err := repo.GetRepositoryByOwnerAndName(ctx, ownerName, repoName) 44 46 if err != nil { 45 47 return nil, err ··· 70 72 return nil, err 71 73 } 72 74 73 - language, err := file_service.TryGetContentLanguage(gitRepo, commitSha, filePath) 74 - if err != nil { 75 - log.Error("Unable to get file language for %-v:%s. Error: %v", repo, filePath, err) 75 + if language != nil { 76 + *language, err = file_service.TryGetContentLanguage(gitRepo, commitSha, filePath) 77 + if err != nil { 78 + log.Error("Unable to get file language for %-v:%s. Error: %v", repo, filePath, err) 79 + } 76 80 } 77 81 78 82 blob, err := commit.GetBlobByPath(filePath) ··· 80 84 return nil, err 81 85 } 82 86 83 - dataRc, err := blob.DataAsync() 87 + return blob, nil 88 + 89 + /*dataRc, err := blob.DataAsync() 84 90 if err != nil { 85 91 return nil, err 86 92 } ··· 97 103 fileContent = highlight.PlainText(buf) 98 104 } 99 105 100 - return fileContent, nil 106 + return fileContent, nil*/ 101 107 }, 102 108 } 103 109 }
+6
web_src/css/markup/filepreview.css
··· 25 25 background: var(--color-box-header); 26 26 } 27 27 28 + .markup .file-preview-box .warning { 29 + border-radius: 0; 30 + margin: 0; 31 + padding: .5rem .5rem .5rem 1rem; 32 + } 33 + 28 34 .markup .file-preview-box .header > a { 29 35 display: block; 30 36 }