diff options
author | wxiaoguang <wxiaoguang@gmail.com> | 2024-11-14 13:02:11 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-11-14 05:02:11 +0000 |
commit | 3f9c3e7bc394c115ccc4818d6505f1f68de350d2 (patch) | |
tree | e07e4a3dc07ce80104f7949af5cb180b7fce449e /routers | |
parent | 985e2a8af3d6468bac3ab178148c38bdbd8414f5 (diff) | |
download | gitea-3f9c3e7bc394c115ccc4818d6505f1f68de350d2.tar.gz gitea-3f9c3e7bc394c115ccc4818d6505f1f68de350d2.zip |
Refactor render system (#32492)
There were too many patches to the Render system, it's really difficult
to make further improvements.
This PR clears the legacy problems and fix TODOs.
1. Rename `RenderContext.Type` to `RenderContext.MarkupType` to clarify
its usage.
2. Use `ContentMode` to replace `meta["mode"]` and `IsWiki`, to clarify
the rendering behaviors.
3. Use "wiki" mode instead of "mode=gfm + wiki=true"
4. Merge `renderByType` and `renderByFile`
5. Add more comments
----
The problem of "mode=document": in many cases it is not set, so many
non-comment places use comment's hard line break incorrectly
Diffstat (limited to 'routers')
-rw-r--r-- | routers/api/v1/misc/markup.go | 12 | ||||
-rw-r--r-- | routers/api/v1/misc/markup_test.go | 13 | ||||
-rw-r--r-- | routers/common/markup.go | 70 | ||||
-rw-r--r-- | routers/web/feed/convert.go | 1 | ||||
-rw-r--r-- | routers/web/misc/markup.go | 4 | ||||
-rw-r--r-- | routers/web/repo/view.go | 12 | ||||
-rw-r--r-- | routers/web/repo/wiki.go | 6 | ||||
-rw-r--r-- | routers/web/user/profile.go | 1 |
8 files changed, 50 insertions, 69 deletions
diff --git a/routers/api/v1/misc/markup.go b/routers/api/v1/misc/markup.go index 9699c79368..868ed92519 100644 --- a/routers/api/v1/misc/markup.go +++ b/routers/api/v1/misc/markup.go @@ -9,6 +9,7 @@ import ( "code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/markup/markdown" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/common" "code.gitea.io/gitea/services/context" @@ -41,7 +42,8 @@ func Markup(ctx *context.APIContext) { return } - common.RenderMarkup(ctx.Base, ctx.Repo, form.Mode, form.Text, form.Context, form.FilePath, form.Wiki) + mode := util.Iif(form.Wiki, "wiki", form.Mode) //nolint:staticcheck + common.RenderMarkup(ctx.Base, ctx.Repo, mode, form.Text, form.Context, form.FilePath) } // Markdown render markdown document to HTML @@ -71,12 +73,8 @@ func Markdown(ctx *context.APIContext) { return } - mode := "markdown" - if form.Mode == "comment" || form.Mode == "gfm" { - mode = form.Mode - } - - common.RenderMarkup(ctx.Base, ctx.Repo, mode, form.Text, form.Context, "", form.Wiki) + mode := util.Iif(form.Wiki, "wiki", form.Mode) //nolint:staticcheck + common.RenderMarkup(ctx.Base, ctx.Repo, mode, form.Text, form.Context, "") } // MarkdownRaw render raw markdown HTML diff --git a/routers/api/v1/misc/markup_test.go b/routers/api/v1/misc/markup_test.go index abffdf3516..6b8c09034a 100644 --- a/routers/api/v1/misc/markup_test.go +++ b/routers/api/v1/misc/markup_test.go @@ -14,6 +14,7 @@ import ( "code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/test" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/services/contexttest" @@ -24,6 +25,7 @@ const AppURL = "http://localhost:3000/" func testRenderMarkup(t *testing.T, mode string, wiki bool, filePath, text, expectedBody string, expectedCode int) { setting.AppURL = AppURL + defer test.MockVariableValue(&markup.RenderBehaviorForTesting.DisableInternalAttributes, true)() context := "/gogits/gogs" if !wiki { context += path.Join("/src/branch/main", path.Dir(filePath)) @@ -38,13 +40,13 @@ func testRenderMarkup(t *testing.T, mode string, wiki bool, filePath, text, expe ctx, resp := contexttest.MockAPIContext(t, "POST /api/v1/markup") web.SetForm(ctx, &options) Markup(ctx) - actual := strings.ReplaceAll(resp.Body.String(), ` data-markdown-generated-content=""`, "") - assert.Equal(t, expectedBody, actual) + assert.Equal(t, expectedBody, resp.Body.String()) assert.Equal(t, expectedCode, resp.Code) resp.Body.Reset() } func testRenderMarkdown(t *testing.T, mode string, wiki bool, text, responseBody string, responseCode int) { + defer test.MockVariableValue(&markup.RenderBehaviorForTesting.DisableInternalAttributes, true)() setting.AppURL = AppURL context := "/gogits/gogs" if !wiki { @@ -59,8 +61,7 @@ func testRenderMarkdown(t *testing.T, mode string, wiki bool, text, responseBody ctx, resp := contexttest.MockAPIContext(t, "POST /api/v1/markdown") web.SetForm(ctx, &options) Markdown(ctx) - actual := strings.ReplaceAll(resp.Body.String(), ` data-markdown-generated-content=""`, "") - assert.Equal(t, responseBody, actual) + assert.Equal(t, responseBody, resp.Body.String()) assert.Equal(t, responseCode, resp.Code) resp.Body.Reset() } @@ -158,8 +159,8 @@ Here are some links to the most important topics. You can find the full list of <a href="http://localhost:3000/gogits/gogs/media/branch/main/path/image.png" target="_blank" rel="nofollow noopener"><img src="http://localhost:3000/gogits/gogs/media/branch/main/path/image.png" alt="Image"/></a></p> `, http.StatusOK) - testRenderMarkup(t, "file", true, "path/test.unknown", "## Test", "Unsupported render extension: .unknown\n", http.StatusUnprocessableEntity) - testRenderMarkup(t, "unknown", true, "", "## Test", "Unknown mode: unknown\n", http.StatusUnprocessableEntity) + testRenderMarkup(t, "file", false, "path/test.unknown", "## Test", "unsupported file to render: \"path/test.unknown\"\n", http.StatusUnprocessableEntity) + testRenderMarkup(t, "unknown", false, "", "## Test", "Unknown mode: unknown\n", http.StatusUnprocessableEntity) } var simpleCases = []string{ diff --git a/routers/common/markup.go b/routers/common/markup.go index 0a00eac7d4..c8cc1a5ff1 100644 --- a/routers/common/markup.go +++ b/routers/common/markup.go @@ -5,21 +5,22 @@ package common import ( + "errors" "fmt" "net/http" "path" "strings" - repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/httplib" "code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/markup/markdown" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/services/context" ) // RenderMarkup renders markup text for the /markup and /markdown endpoints -func RenderMarkup(ctx *context.Base, repo *context.Repository, mode, text, urlPathContext, filePath string, wiki bool) { +func RenderMarkup(ctx *context.Base, repo *context.Repository, mode, text, urlPathContext, filePath string) { // urlPathContext format is "/subpath/{user}/{repo}/src/{branch, commit, tag}/{identifier/path}/{file/dir}" // filePath is the path of the file to render if the end user is trying to preview a repo file (mode == "file") // filePath will be used as RenderContext.RelativePath @@ -27,32 +28,33 @@ func RenderMarkup(ctx *context.Base, repo *context.Repository, mode, text, urlPa // for example, when previewing file "/gitea/owner/repo/src/branch/features/feat-123/doc/CHANGE.md", then filePath is "doc/CHANGE.md" // and the urlPathContext is "/gitea/owner/repo/src/branch/features/feat-123/doc" - var markupType, relativePath string - - links := markup.Links{AbsolutePrefix: true} + renderCtx := &markup.RenderContext{ + Ctx: ctx, + Links: markup.Links{AbsolutePrefix: true}, + MarkupType: markdown.MarkupName, + } if urlPathContext != "" { - links.Base = fmt.Sprintf("%s%s", httplib.GuessCurrentHostURL(ctx), urlPathContext) + renderCtx.Links.Base = fmt.Sprintf("%s%s", httplib.GuessCurrentHostURL(ctx), urlPathContext) } - switch mode { - case "markdown": - // Raw markdown - if err := markdown.RenderRaw(&markup.RenderContext{ - Ctx: ctx, - Links: links, - }, strings.NewReader(text), ctx.Resp); err != nil { + if mode == "" || mode == "markdown" { + // raw markdown doesn't need any special handling + if err := markdown.RenderRaw(renderCtx, strings.NewReader(text), ctx.Resp); err != nil { ctx.Error(http.StatusInternalServerError, err.Error()) } return + } + switch mode { + case "gfm": // legacy mode, do nothing case "comment": - // Issue & comment content - markupType = markdown.MarkupName - case "gfm": - // GitHub Flavored Markdown - markupType = markdown.MarkupName + renderCtx.ContentMode = markup.RenderContentAsComment + case "wiki": + renderCtx.ContentMode = markup.RenderContentAsWiki case "file": - markupType = "" // render the repo file content by its extension - relativePath = filePath + // render the repo file content by its extension + renderCtx.MarkupType = "" + renderCtx.RelativePath = filePath + renderCtx.InStandalonePage = true default: ctx.Error(http.StatusUnprocessableEntity, fmt.Sprintf("Unknown mode: %s", mode)) return @@ -67,33 +69,19 @@ func RenderMarkup(ctx *context.Base, repo *context.Repository, mode, text, urlPa refPath := strings.Join(fields[3:], "/") // it is "branch/features/feat-12/doc" refPath = strings.TrimSuffix(refPath, "/"+fileDir) // now we get the correct branch path: "branch/features/feat-12" - links = markup.Links{AbsolutePrefix: true, Base: absoluteBasePrefix, BranchPath: refPath, TreePath: fileDir} + renderCtx.Links = markup.Links{AbsolutePrefix: true, Base: absoluteBasePrefix, BranchPath: refPath, TreePath: fileDir} } - meta := map[string]string{} - var repoCtx *repo_model.Repository if repo != nil && repo.Repository != nil { - repoCtx = repo.Repository - if mode == "comment" { - meta = repo.Repository.ComposeMetas(ctx) + renderCtx.Repo = repo.Repository + if renderCtx.ContentMode == markup.RenderContentAsComment { + renderCtx.Metas = repo.Repository.ComposeMetas(ctx) } else { - meta = repo.Repository.ComposeDocumentMetas(ctx) + renderCtx.Metas = repo.Repository.ComposeDocumentMetas(ctx) } } - if mode != "comment" { - meta["mode"] = "document" - } - - if err := markup.Render(&markup.RenderContext{ - Ctx: ctx, - Repo: repoCtx, - Links: links, - Metas: meta, - IsWiki: wiki, - Type: markupType, - RelativePath: relativePath, - }, strings.NewReader(text), ctx.Resp); err != nil { - if markup.IsErrUnsupportedRenderExtension(err) { + if err := markup.Render(renderCtx, strings.NewReader(text), ctx.Resp); err != nil { + if errors.Is(err, util.ErrInvalidArgument) { ctx.Error(http.StatusUnprocessableEntity, err.Error()) } else { ctx.Error(http.StatusInternalServerError, err.Error()) diff --git a/routers/web/feed/convert.go b/routers/web/feed/convert.go index 3f33e9933a..a273515c8a 100644 --- a/routers/web/feed/convert.go +++ b/routers/web/feed/convert.go @@ -56,7 +56,6 @@ func renderMarkdown(ctx *context.Context, act *activities_model.Action, content Links: markup.Links{ Base: act.GetRepoLink(ctx), }, - Type: markdown.MarkupName, Metas: map[string]string{ "user": act.GetRepoUserName(ctx), "repo": act.GetRepoName(ctx), diff --git a/routers/web/misc/markup.go b/routers/web/misc/markup.go index 2dbbd6fc09..0c7ec6c2eb 100644 --- a/routers/web/misc/markup.go +++ b/routers/web/misc/markup.go @@ -6,6 +6,7 @@ package misc import ( api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/common" "code.gitea.io/gitea/services/context" @@ -14,5 +15,6 @@ import ( // Markup render markup document to HTML func Markup(ctx *context.Context) { form := web.GetForm(ctx).(*api.MarkupOption) - common.RenderMarkup(ctx.Base, ctx.Repo, form.Mode, form.Text, form.Context, form.FilePath, form.Wiki) + mode := util.Iif(form.Wiki, "wiki", form.Mode) //nolint:staticcheck + common.RenderMarkup(ctx.Base, ctx.Repo, mode, form.Text, form.Context, form.FilePath) } diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go index 7d9281b397..7030f6d8a9 100644 --- a/routers/web/repo/view.go +++ b/routers/web/repo/view.go @@ -312,6 +312,7 @@ func renderReadmeFile(ctx *context.Context, subfolder string, readmeFile *git.Tr ctx.Data["EscapeStatus"], ctx.Data["FileContent"], err = markupRender(ctx, &markup.RenderContext{ Ctx: ctx, + MarkupType: markupType, RelativePath: path.Join(ctx.Repo.TreePath, readmeFile.Name()), // ctx.Repo.TreePath is the directory not the Readme so we must append the Readme filename (and path). Links: markup.Links{ Base: ctx.Repo.RepoLink, @@ -502,28 +503,20 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry) { ctx.Data["ReadmeExist"] = readmeExist markupType := markup.DetectMarkupTypeByFileName(blob.Name()) - // If the markup is detected by custom markup renderer it should not be reset later on - // to not pass it down to the render context. - detected := false if markupType == "" { - detected = true markupType = markup.DetectRendererType(blob.Name(), bytes.NewReader(buf)) } if markupType != "" { ctx.Data["HasSourceRenderedToggle"] = true } - if markupType != "" && !shouldRenderSource { ctx.Data["IsMarkup"] = true ctx.Data["MarkupType"] = markupType - if !detected { - markupType = "" - } metas := ctx.Repo.Repository.ComposeDocumentMetas(ctx) metas["BranchNameSubURL"] = ctx.Repo.BranchNameSubURL() ctx.Data["EscapeStatus"], ctx.Data["FileContent"], err = markupRender(ctx, &markup.RenderContext{ Ctx: ctx, - Type: markupType, + MarkupType: markupType, RelativePath: ctx.Repo.TreePath, Links: markup.Links{ Base: ctx.Repo.RepoLink, @@ -615,6 +608,7 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry) { ctx.Data["MarkupType"] = markupType ctx.Data["EscapeStatus"], ctx.Data["FileContent"], err = markupRender(ctx, &markup.RenderContext{ Ctx: ctx, + MarkupType: markupType, RelativePath: ctx.Repo.TreePath, Links: markup.Links{ Base: ctx.Repo.RepoLink, diff --git a/routers/web/repo/wiki.go b/routers/web/repo/wiki.go index d2056353d8..2b8312f10a 100644 --- a/routers/web/repo/wiki.go +++ b/routers/web/repo/wiki.go @@ -289,12 +289,12 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) { } rctx := &markup.RenderContext{ - Ctx: ctx, - Metas: ctx.Repo.Repository.ComposeDocumentMetas(ctx), + Ctx: ctx, + ContentMode: markup.RenderContentAsWiki, + Metas: ctx.Repo.Repository.ComposeDocumentMetas(ctx), Links: markup.Links{ Base: ctx.Repo.RepoLink, }, - IsWiki: true, } buf := &strings.Builder{} diff --git a/routers/web/user/profile.go b/routers/web/user/profile.go index d0abf603c3..4fbfc2bd17 100644 --- a/routers/web/user/profile.go +++ b/routers/web/user/profile.go @@ -258,7 +258,6 @@ func prepareUserProfileTabData(ctx *context.Context, showPrivate bool, profileDb Base: profileDbRepo.Link(), BranchPath: path.Join("branch", util.PathEscapeSegments(profileDbRepo.DefaultBranch)), }, - Metas: map[string]string{"mode": "document"}, }, bytes); err != nil { log.Error("failed to RenderString: %v", err) } else { |