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.

fix: Preview picture not visible on Markdown file (#5781)

Extend API MarkupOptions to contain branch path.

The `api.MarkupOptions{}` to have `BranchPath` which contains the
current branch. The `RenderMarkup` function utilizes a struct since there
are too many variables passed as arguments and that is not a good sign
for readability.

And `repo-editor.js` will contain a new form data which is `branch-path`
which will then be utilized by `edit.tmpl` as `data-branch-path`.

Closes: #4510

## Checklist

The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org).

### Tests

- I added test coverage for Go changes...
- [ ] in their respective `*_test.go` for unit tests.
- [ ] in the `tests/integration` directory if it involves interactions with a live Forgejo server.
- I added test coverage for JavaScript changes...
- [ ] in `web_src/js/*.test.js` if it can be unit tested.
- [x] in `tests/e2e/*.test.e2e.js` if it requires interactions with a live Forgejo server (see also the [developer guide for JavaScript testing](https://codeberg.org/forgejo/forgejo/src/branch/forgejo/tests/e2e/README.md#end-to-end-tests)).

### Documentation

- [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change.
- [ ] I did not document these changes and I do not expect someone else to do it.

### Release notes

- [ ] I do not want this change to show in the release notes.
- [x] I want the title to show in the release notes with a link to this pull request.
- [ ] I want the content of the `release-notes/<pull request number>.md` to be be used for the release notes instead of the title.

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5781
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Co-authored-by: Nirmal Kumar R <tildezero@gmail.com>
Co-committed-by: Nirmal Kumar R <tildezero@gmail.com>

authored by

Nirmal Kumar R
Nirmal Kumar R
and committed by
Earl Warren
90571001 d3f442a2

+92 -19
+4
modules/structs/miscellaneous.go
··· 37 37 // 38 38 // in: body 39 39 FilePath string 40 + // The current branch path where the form gets posted 41 + // 42 + // in: body 43 + BranchPath string 40 44 } 41 45 42 46 // MarkupRender is a rendered markup document
+18 -2
routers/api/v1/misc/markup.go
··· 41 41 return 42 42 } 43 43 44 - common.RenderMarkup(ctx.Base, ctx.Repo, form.Mode, form.Text, form.Context, form.FilePath, form.Wiki) 44 + re := common.Renderer{ 45 + Mode: form.Mode, 46 + Text: form.Text, 47 + URLPrefix: form.Context, 48 + FilePath: form.FilePath, 49 + BranchPath: form.BranchPath, 50 + IsWiki: form.Wiki, 51 + } 52 + 53 + re.RenderMarkup(ctx.Base, ctx.Repo) 45 54 } 46 55 47 56 // Markdown render markdown document to HTML ··· 76 85 mode = form.Mode 77 86 } 78 87 79 - common.RenderMarkup(ctx.Base, ctx.Repo, mode, form.Text, form.Context, "", form.Wiki) 88 + re := common.Renderer{ 89 + Mode: mode, 90 + Text: form.Text, 91 + URLPrefix: form.Context, 92 + IsWiki: form.Wiki, 93 + } 94 + 95 + re.RenderMarkup(ctx.Base, ctx.Repo) 80 96 } 81 97 82 98 // MarkdownRaw render raw markdown HTML
+21 -15
routers/common/markup.go
··· 18 18 "mvdan.cc/xurls/v2" 19 19 ) 20 20 21 + type Renderer struct { 22 + Mode, Text, URLPrefix, FilePath, BranchPath string 23 + IsWiki bool 24 + } 25 + 21 26 // RenderMarkup renders markup text for the /markup and /markdown endpoints 22 - func RenderMarkup(ctx *context.Base, repo *context.Repository, mode, text, urlPrefix, filePath string, wiki bool) { 27 + func (re *Renderer) RenderMarkup(ctx *context.Base, repo *context.Repository) { 23 28 var markupType string 24 29 relativePath := "" 25 30 26 - if len(text) == 0 { 31 + if len(re.Text) == 0 { 27 32 _, _ = ctx.Write([]byte("")) 28 33 return 29 34 } 30 35 31 - switch mode { 36 + switch re.Mode { 32 37 case "markdown": 33 38 // Raw markdown 34 39 if err := markdown.RenderRaw(&markup.RenderContext{ 35 40 Ctx: ctx, 36 41 Links: markup.Links{ 37 42 AbsolutePrefix: true, 38 - Base: urlPrefix, 43 + Base: re.URLPrefix, 39 44 }, 40 - }, strings.NewReader(text), ctx.Resp); err != nil { 45 + }, strings.NewReader(re.Text), ctx.Resp); err != nil { 41 46 ctx.Error(http.StatusInternalServerError, err.Error()) 42 47 } 43 48 return ··· 50 55 case "file": 51 56 // File as document based on file extension 52 57 markupType = "" 53 - relativePath = filePath 58 + relativePath = re.FilePath 54 59 default: 55 - ctx.Error(http.StatusUnprocessableEntity, fmt.Sprintf("Unknown mode: %s", mode)) 60 + ctx.Error(http.StatusUnprocessableEntity, fmt.Sprintf("Unknown mode: %s", re.Mode)) 56 61 return 57 62 } 58 63 59 - if !strings.HasPrefix(setting.AppSubURL+"/", urlPrefix) { 64 + if !strings.HasPrefix(setting.AppSubURL+"/", re.URLPrefix) { 60 65 // check if urlPrefix is already set to a URL 61 66 linkRegex, _ := xurls.StrictMatchingScheme("https?://") 62 - m := linkRegex.FindStringIndex(urlPrefix) 67 + m := linkRegex.FindStringIndex(re.URLPrefix) 63 68 if m == nil { 64 - urlPrefix = util.URLJoin(setting.AppURL, urlPrefix) 69 + re.URLPrefix = util.URLJoin(setting.AppURL, re.URLPrefix) 65 70 } 66 71 } 67 72 68 73 meta := map[string]string{} 69 74 if repo != nil && repo.Repository != nil { 70 - if mode == "comment" { 75 + if re.Mode == "comment" { 71 76 meta = repo.Repository.ComposeMetas(ctx) 72 77 } else { 73 78 meta = repo.Repository.ComposeDocumentMetas(ctx) 74 79 } 75 80 } 76 - if mode != "comment" { 81 + if re.Mode != "comment" { 77 82 meta["mode"] = "document" 78 83 } 79 84 ··· 81 86 Ctx: ctx, 82 87 Links: markup.Links{ 83 88 AbsolutePrefix: true, 84 - Base: urlPrefix, 89 + Base: re.URLPrefix, 90 + BranchPath: re.BranchPath, 85 91 }, 86 92 Metas: meta, 87 - IsWiki: wiki, 93 + IsWiki: re.IsWiki, 88 94 Type: markupType, 89 95 RelativePath: relativePath, 90 - }, strings.NewReader(text), ctx.Resp); err != nil { 96 + }, strings.NewReader(re.Text), ctx.Resp); err != nil { 91 97 if markup.IsErrUnsupportedRenderExtension(err) { 92 98 ctx.Error(http.StatusUnprocessableEntity, err.Error()) 93 99 } else {
+11 -1
routers/web/misc/markup.go
··· 14 14 // Markup render markup document to HTML 15 15 func Markup(ctx *context.Context) { 16 16 form := web.GetForm(ctx).(*api.MarkupOption) 17 - common.RenderMarkup(ctx.Base, ctx.Repo, form.Mode, form.Text, form.Context, form.FilePath, form.Wiki) 17 + 18 + re := common.Renderer{ 19 + Mode: form.Mode, 20 + Text: form.Text, 21 + URLPrefix: form.Context, 22 + FilePath: form.FilePath, 23 + BranchPath: form.BranchPath, 24 + IsWiki: form.Wiki, 25 + } 26 + 27 + re.RenderMarkup(ctx.Base, ctx.Repo) 18 28 }
+1
routers/web/repo/editor.go
··· 211 211 ctx.Data["TreeNames"] = treeNames 212 212 ctx.Data["TreePaths"] = treePaths 213 213 ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL() 214 + ctx.Data["BranchPath"] = ctx.Repo.BranchNameSubURL() 214 215 ctx.Data["commit_summary"] = "" 215 216 ctx.Data["commit_message"] = "" 216 217 if canCommit {
+1 -1
templates/repo/editor/edit.tmpl
··· 28 28 <div class="field"> 29 29 <div class="ui top attached tabular menu" data-write="write" data-preview="preview" data-diff="diff"> 30 30 <a class="active item" data-tab="write">{{svg "octicon-code"}} {{if .IsNewFile}}{{ctx.Locale.Tr "repo.editor.new_file"}}{{else}}{{ctx.Locale.Tr "repo.editor.edit_file"}}{{end}}</a> 31 - <a class="item" data-tab="preview" data-url="{{.Repository.Link}}/markup" data-context="{{.RepoLink}}/src/{{.BranchNameSubURL}}" data-markup-mode="file">{{svg "octicon-eye"}} {{ctx.Locale.Tr "preview"}}</a> 31 + <a class="item" data-tab="preview" data-url="{{.Repository.Link}}/markup" data-context="{{.RepoLink}}" data-branch-path="{{.BranchNameSubURL}}" data-markup-mode="file">{{svg "octicon-eye"}} {{ctx.Locale.Tr "preview"}}</a> 32 32 {{if not .IsNewFile}} 33 33 <a class="item" data-tab="diff" hx-params="context,content" hx-vals='{"context":"{{.BranchLink}}"}' hx-include="#edit_area" hx-swap="innerHTML" hx-target=".tab[data-tab='diff']" hx-indicator=".tab[data-tab='diff']" hx-post="{{.RepoLink}}/_preview/{{.BranchName | PathEscapeSegments}}/{{.TreePath | PathEscapeSegments}}">{{svg "octicon-diff"}} {{ctx.Locale.Tr "repo.editor.preview_changes"}}</a> 34 34 {{end}}
+4
templates/swagger/v1_json.tmpl
··· 24322 24322 "description": "MarkupOption markup options", 24323 24323 "type": "object", 24324 24324 "properties": { 24325 + "BranchPath": { 24326 + "description": "The current branch path where the form gets posted\n\nin: body", 24327 + "type": "string" 24328 + }, 24325 24329 "Context": { 24326 24330 "description": "Context to render\n\nin: body", 24327 24331 "type": "string"
+31
tests/e2e/markdown-editor.test.e2e.ts
··· 11 11 await login_user(browser, workerInfo, 'user2'); 12 12 }); 13 13 14 + test('Markdown image preview behaviour', async ({browser}, workerInfo) => { 15 + test.skip(workerInfo.project.name === 'Mobile Safari', 'Flaky behaviour on mobile safari;'); 16 + 17 + const context = await load_logged_in_context(browser, workerInfo, 'user2'); 18 + 19 + // Editing the root README.md file for image preview 20 + const editPath = '/user2/repo1/src/branch/master/README.md'; 21 + 22 + const page = await context.newPage(); 23 + const response = await page.goto(editPath, {waitUntil: 'domcontentloaded'}); 24 + expect(response?.status()).toBe(200); 25 + 26 + // Click 'Edit file' tab 27 + await page.locator('[data-tooltip-content="Edit file"]').click(); 28 + 29 + // This yields the monaco editor 30 + const editor = page.getByRole('presentation').nth(0); 31 + await editor.click(); 32 + // Clear all the content 33 + await page.keyboard.press('ControlOrMeta+KeyA'); 34 + // Add the image 35 + await page.keyboard.type('![Logo of Forgejo](./assets/logo.svg "Logo of Forgejo")'); 36 + 37 + // Click 'Preview' tab 38 + await page.locator('a[data-tab="preview"]').click(); 39 + 40 + // Check for the image preview via the expected attribute 41 + const preview = page.locator('div[data-tab="preview"] p[dir="auto"] a'); 42 + await expect(preview).toHaveAttribute('href', 'http://localhost:3003/user2/repo1/media/branch/master/assets/logo.svg'); 43 + }); 44 + 14 45 test('markdown indentation', async ({browser}, workerInfo) => { 15 46 const context = await load_logged_in_context(browser, workerInfo, 'user2'); 16 47
+1
web_src/js/features/repo-editor.js
··· 26 26 const formData = new FormData(); 27 27 formData.append('mode', mode); 28 28 formData.append('context', context); 29 + formData.append('branch_path', $this.data('branch-path')); 29 30 formData.append( 30 31 'text', 31 32 $form.find(`.tab[data-tab="${$tabMenu.data('write')}"] textarea`).val(),