diff options
-rw-r--r-- | models/repo.go | 18 | ||||
-rw-r--r-- | models/repo_test.go | 5 | ||||
-rw-r--r-- | modules/markup/html.go | 34 | ||||
-rw-r--r-- | modules/markup/html_internal_test.go | 20 | ||||
-rw-r--r-- | modules/markup/markdown/markdown_test.go | 14 | ||||
-rw-r--r-- | routers/api/v1/api.go | 2 | ||||
-rw-r--r-- | routers/api/v1/misc/markdown.go | 22 | ||||
-rw-r--r-- | templates/repo/diff/box.tmpl | 2 | ||||
-rw-r--r-- | templates/repo/diff/comment_form.tmpl | 2 | ||||
-rw-r--r-- | templates/repo/editor/edit.tmpl | 4 | ||||
-rw-r--r-- | templates/repo/issue/comment_tab.tmpl | 4 | ||||
-rw-r--r-- | templates/repo/issue/view_content.tmpl | 2 | ||||
-rw-r--r-- | templates/repo/wiki/new.tmpl | 2 |
13 files changed, 94 insertions, 37 deletions
diff --git a/models/repo.go b/models/repo.go index 5cdee6c3f9..8b51f14043 100644 --- a/models/repo.go +++ b/models/repo.go @@ -469,19 +469,19 @@ func (repo *Repository) mustOwnerName(e Engine) string { return repo.OwnerName } -// ComposeMetas composes a map of metas for rendering external issue tracker URL. +// ComposeMetas composes a map of metas for properly rendering issue links and external issue trackers. func (repo *Repository) ComposeMetas() map[string]string { - unit, err := repo.GetUnit(UnitTypeExternalTracker) - if err != nil { - return nil - } - if repo.ExternalMetas == nil { repo.ExternalMetas = map[string]string{ - "format": unit.ExternalTrackerConfig().ExternalTrackerFormat, - "user": repo.MustOwner().Name, - "repo": repo.Name, + "user": repo.MustOwner().Name, + "repo": repo.Name, } + unit, err := repo.GetUnit(UnitTypeExternalTracker) + if err != nil { + return repo.ExternalMetas + } + + repo.ExternalMetas["format"] = unit.ExternalTrackerConfig().ExternalTrackerFormat switch unit.ExternalTrackerConfig().ExternalTrackerStyle { case markup.IssueNameStyleAlphanumeric: repo.ExternalMetas["style"] = markup.IssueNameStyleAlphanumeric diff --git a/models/repo_test.go b/models/repo_test.go index 752ffc2dd9..a5b8cce9b9 100644 --- a/models/repo_test.go +++ b/models/repo_test.go @@ -20,7 +20,10 @@ func TestRepo(t *testing.T) { repo.Owner = &User{Name: "testOwner"} repo.Units = nil - assert.Nil(t, repo.ComposeMetas()) + + metas := repo.ComposeMetas() + assert.Equal(t, "testRepo", metas["repo"]) + assert.Equal(t, "testOwner", metas["user"]) externalTracker := RepoUnit{ Type: UnitTypeExternalTracker, diff --git a/modules/markup/html.go b/modules/markup/html.go index 136f76d301..930c6b3a3e 100644 --- a/modules/markup/html.go +++ b/modules/markup/html.go @@ -551,20 +551,37 @@ func shortLinkProcessorFull(ctx *postProcessCtx, node *html.Node, noLink bool) { } func fullIssuePatternProcessor(ctx *postProcessCtx, node *html.Node) { + if ctx.metas == nil { + return + } m := getIssueFullPattern().FindStringSubmatchIndex(node.Data) if m == nil { return } link := node.Data[m[0]:m[1]] id := "#" + node.Data[m[2]:m[3]] - // TODO if m[4]:m[5] is not nil, then link is to a comment, - // and we should indicate that in the text somehow - replaceContent(node, m[0], m[1], createLink(link, id)) + + // extract repo and org name from matched link like + // http://localhost:3000/gituser/myrepo/issues/1 + linkParts := strings.Split(path.Clean(link), "/") + matchOrg := linkParts[len(linkParts)-4] + matchRepo := linkParts[len(linkParts)-3] + + if matchOrg == ctx.metas["user"] && matchRepo == ctx.metas["repo"] { + // TODO if m[4]:m[5] is not nil, then link is to a comment, + // and we should indicate that in the text somehow + replaceContent(node, m[0], m[1], createLink(link, id)) + + } else { + orgRepoID := matchOrg + "/" + matchRepo + id + replaceContent(node, m[0], m[1], createLink(link, orgRepoID)) + } } func issueIndexPatternProcessor(ctx *postProcessCtx, node *html.Node) { - prefix := cutoutVerbosePrefix(ctx.urlPrefix) - + if ctx.metas == nil { + return + } // default to numeric pattern, unless alphanumeric is requested. pattern := issueNumericPattern if ctx.metas["style"] == IssueNameStyleAlphanumeric { @@ -575,11 +592,10 @@ func issueIndexPatternProcessor(ctx *postProcessCtx, node *html.Node) { if match == nil { return } + id := node.Data[match[2]:match[3]] var link *html.Node - if ctx.metas == nil { - link = createLink(util.URLJoin(prefix, "issues", id[1:]), id) - } else { + if _, ok := ctx.metas["format"]; ok { // Support for external issue tracker if ctx.metas["style"] == IssueNameStyleAlphanumeric { ctx.metas["index"] = id @@ -587,6 +603,8 @@ func issueIndexPatternProcessor(ctx *postProcessCtx, node *html.Node) { ctx.metas["index"] = id[1:] } link = createLink(com.Expand(ctx.metas["format"], ctx.metas), id) + } else { + link = createLink(util.URLJoin(setting.AppURL, ctx.metas["user"], ctx.metas["repo"], "issues", id[1:]), id) } replaceContent(node, match[2], match[3], link) } diff --git a/modules/markup/html_internal_test.go b/modules/markup/html_internal_test.go index c71948593d..135a8e103c 100644 --- a/modules/markup/html_internal_test.go +++ b/modules/markup/html_internal_test.go @@ -53,6 +53,12 @@ var alphanumericMetas = map[string]string{ "style": IssueNameStyleAlphanumeric, } +// these values should match the Repo const above +var localMetas = map[string]string{ + "user": "gogits", + "repo": "gogs", +} + func TestRender_IssueIndexPattern(t *testing.T) { // numeric: render inputs without valid mentions test := func(s string) { @@ -91,7 +97,7 @@ func TestRender_IssueIndexPattern2(t *testing.T) { links[i] = numericIssueLink(util.URLJoin(setting.AppSubURL, "issues"), index) } expectedNil := fmt.Sprintf(expectedFmt, links...) - testRenderIssueIndexPattern(t, s, expectedNil, nil) + testRenderIssueIndexPattern(t, s, expectedNil, &postProcessCtx{metas: localMetas}) for i, index := range indices { links[i] = numericIssueLink("https://someurl.com/someUser/someRepo/", index) @@ -171,6 +177,7 @@ func testRenderIssueIndexPattern(t *testing.T, input, expected string, ctx *post if ctx.urlPrefix == "" { ctx.urlPrefix = AppSubURL } + res, err := ctx.postProcess([]byte(input)) assert.NoError(t, err) assert.Equal(t, expected, string(res)) @@ -181,10 +188,10 @@ func TestRender_AutoLink(t *testing.T) { setting.AppSubURL = AppSubURL test := func(input, expected string) { - buffer, err := PostProcess([]byte(input), setting.AppSubURL, nil, false) + buffer, err := PostProcess([]byte(input), setting.AppSubURL, localMetas, false) assert.Equal(t, err, nil) assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(buffer))) - buffer, err = PostProcess([]byte(input), setting.AppSubURL, nil, true) + buffer, err = PostProcess([]byte(input), setting.AppSubURL, localMetas, true) assert.Equal(t, err, nil) assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(buffer))) } @@ -214,6 +221,7 @@ func TestRender_FullIssueURLs(t *testing.T) { if ctx.urlPrefix == "" { ctx.urlPrefix = AppSubURL } + ctx.metas = localMetas result, err := ctx.postProcess([]byte(input)) assert.NoError(t, err) assert.Equal(t, expected, string(result)) @@ -221,9 +229,11 @@ func TestRender_FullIssueURLs(t *testing.T) { test("Here is a link https://git.osgeo.org/gogs/postgis/postgis/pulls/6", "Here is a link https://git.osgeo.org/gogs/postgis/postgis/pulls/6") test("Look here http://localhost:3000/person/repo/issues/4", - `Look here <a href="http://localhost:3000/person/repo/issues/4">#4</a>`) + `Look here <a href="http://localhost:3000/person/repo/issues/4">person/repo#4</a>`) test("http://localhost:3000/person/repo/issues/4#issuecomment-1234", - `<a href="http://localhost:3000/person/repo/issues/4#issuecomment-1234">#4</a>`) + `<a href="http://localhost:3000/person/repo/issues/4#issuecomment-1234">person/repo#4</a>`) + test("http://localhost:3000/gogits/gogs/issues/4", + `<a href="http://localhost:3000/gogits/gogs/issues/4">#4</a>`) } func TestRegExp_issueNumericPattern(t *testing.T) { diff --git a/modules/markup/markdown/markdown_test.go b/modules/markup/markdown/markdown_test.go index 5aa9c3d7d2..8ba51e6a1b 100644 --- a/modules/markup/markdown/markdown_test.go +++ b/modules/markup/markdown/markdown_test.go @@ -19,6 +19,12 @@ const AppURL = "http://localhost:3000/" const Repo = "gogits/gogs" const AppSubURL = AppURL + Repo + "/" +// these values should match the Repo const above +var localMetas = map[string]string{ + "user": "gogits", + "repo": "gogs", +} + func TestRender_StandardLinks(t *testing.T) { setting.AppURL = AppURL setting.AppSubURL = AppSubURL @@ -100,7 +106,8 @@ func testAnswers(baseURLContent, baseURLImages string) []string { <p>Ideas and codes</p> <ul> -<li>Bezier widget (by <a href="` + AppURL + `r-lyeh" rel="nofollow">@r-lyeh</a>) <a href="http://localhost:3000/ocornut/imgui/issues/786" rel="nofollow">#786</a></li> +<li>Bezier widget (by <a href="` + AppURL + `r-lyeh" rel="nofollow">@r-lyeh</a>) <a href="http://localhost:3000/ocornut/imgui/issues/786" rel="nofollow">ocornut/imgui#786</a></li> +<li>Bezier widget (by <a href="` + AppURL + `r-lyeh" rel="nofollow">@r-lyeh</a>) <a href="http://localhost:3000/gogits/gogs/issues/786" rel="nofollow">#786</a></li> <li>Node graph editors <a href="https://github.com/ocornut/imgui/issues/306" rel="nofollow">https://github.com/ocornut/imgui/issues/306</a></li> <li><a href="` + baseURLContent + `/memory_editor_example" rel="nofollow">Memory Editor</a></li> <li><a href="` + baseURLContent + `/plot_var_example" rel="nofollow">Plot var helper</a></li> @@ -188,6 +195,7 @@ var sameCases = []string{ Ideas and codes - Bezier widget (by @r-lyeh) ` + AppURL + `ocornut/imgui/issues/786 +- Bezier widget (by @r-lyeh) ` + AppURL + `gogits/gogs/issues/786 - Node graph editors https://github.com/ocornut/imgui/issues/306 - [[Memory Editor|memory_editor_example]] - [[Plot var helper|plot_var_example]]`, @@ -243,7 +251,7 @@ func TestTotal_RenderWiki(t *testing.T) { answers := testAnswers(util.URLJoin(AppSubURL, "wiki/"), util.URLJoin(AppSubURL, "wiki", "raw/")) for i := 0; i < len(sameCases); i++ { - line := RenderWiki([]byte(sameCases[i]), AppSubURL, nil) + line := RenderWiki([]byte(sameCases[i]), AppSubURL, localMetas) assert.Equal(t, answers[i], line) } @@ -270,7 +278,7 @@ func TestTotal_RenderString(t *testing.T) { answers := testAnswers(util.URLJoin(AppSubURL, "src", "master/"), util.URLJoin(AppSubURL, "raw", "master/")) for i := 0; i < len(sameCases); i++ { - line := RenderString(sameCases[i], util.URLJoin(AppSubURL, "src", "master/"), nil) + line := RenderString(sameCases[i], util.URLJoin(AppSubURL, "src", "master/"), localMetas) assert.Equal(t, answers[i], line) } diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 02c74e5056..4194d98db8 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -584,6 +584,8 @@ func RegisterRoutes(m *macaron.Macaron) { Patch(reqToken(), reqRepoWriter(models.UnitTypeIssues, models.UnitTypePullRequests), bind(api.EditLabelOption{}), repo.EditLabel). Delete(reqToken(), reqRepoWriter(models.UnitTypeIssues, models.UnitTypePullRequests), repo.DeleteLabel) }) + m.Post("/markdown", bind(api.MarkdownOption{}), misc.Markdown) + m.Post("/markdown/raw", misc.MarkdownRaw) m.Group("/milestones", func() { m.Combo("").Get(repo.ListMilestones). Post(reqToken(), reqRepoWriter(models.UnitTypeIssues, models.UnitTypePullRequests), bind(api.CreateMilestoneOption{}), repo.CreateMilestone) diff --git a/routers/api/v1/misc/markdown.go b/routers/api/v1/misc/markdown.go index 633dff98eb..9ae7a6c58c 100644 --- a/routers/api/v1/misc/markdown.go +++ b/routers/api/v1/misc/markdown.go @@ -5,12 +5,16 @@ package misc import ( + "strings" + api "code.gitea.io/sdk/gitea" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/markup/markdown" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" + + "mvdan.cc/xurls/v2" ) // Markdown render markdown document to HTML @@ -45,11 +49,23 @@ func Markdown(ctx *context.APIContext, form api.MarkdownOption) { switch form.Mode { case "gfm": md := []byte(form.Text) - context := util.URLJoin(setting.AppURL, form.Context) + urlPrefix := form.Context + var meta map[string]string + if !strings.HasPrefix(setting.AppSubURL+"/", urlPrefix) { + // check if urlPrefix is already set to a URL + linkRegex, _ := xurls.StrictMatchingScheme("https?://") + m := linkRegex.FindStringIndex(urlPrefix) + if m == nil { + urlPrefix = util.URLJoin(setting.AppURL, form.Context) + } + } + if ctx.Repo != nil && ctx.Repo.Repository != nil { + meta = ctx.Repo.Repository.ComposeMetas() + } if form.Wiki { - ctx.Write([]byte(markdown.RenderWiki(md, context, nil))) + ctx.Write([]byte(markdown.RenderWiki(md, urlPrefix, meta))) } else { - ctx.Write(markdown.Render(md, context, nil)) + ctx.Write(markdown.Render(md, urlPrefix, meta)) } default: ctx.Write(markdown.RenderRaw([]byte(form.Text), "", false)) diff --git a/templates/repo/diff/box.tmpl b/templates/repo/diff/box.tmpl index 331a17a5e9..2bdf9e5881 100644 --- a/templates/repo/diff/box.tmpl +++ b/templates/repo/diff/box.tmpl @@ -202,7 +202,7 @@ <div class="ui comment form"> <div class="ui top attached tabular menu"> <a class="active write item">{{$.i18n.Tr "write"}}</a> - <a class="preview item" data-url="{{AppSubUrl}}/api/v1/markdown" data-context="{{$.RepoLink}}">{{$.i18n.Tr "preview"}}</a> + <a class="preview item" data-url="{{$.Repository.APIURL}}/markdown" data-context="{{$.RepoLink}}">{{$.i18n.Tr "preview"}}</a> </div> <div class="ui bottom attached active write tab segment"> <textarea tabindex="1" name="content"></textarea> diff --git a/templates/repo/diff/comment_form.tmpl b/templates/repo/diff/comment_form.tmpl index 1fb8b963da..38fd3fa7fb 100644 --- a/templates/repo/diff/comment_form.tmpl +++ b/templates/repo/diff/comment_form.tmpl @@ -12,7 +12,7 @@ <input type="hidden" name="diff_base_cid"> <div class="ui top attached tabular menu" {{if not $.hidden}}onload="assingMenuAttributes(this)" {{end}}data-write="write" data-preview="preview"> <a class="active item" data-tab="write">{{$.root.i18n.Tr "write"}}</a> - <a class="item" data-tab="preview" data-url="{{$.root.AppSubUrl}}/api/v1/markdown" data-context="{{$.root.RepoLink}}">{{$.root.i18n.Tr "preview"}}</a> + <a class="item" data-tab="preview" data-url="{{$.root.Repository.APIURL}}/markdown" data-context="{{$.root.RepoLink}}">{{$.root.i18n.Tr "preview"}}</a> </div> <div class="ui bottom attached active tab segment" data-tab="write"> <div class="field"> diff --git a/templates/repo/editor/edit.tmpl b/templates/repo/editor/edit.tmpl index 82656d6557..134dc818d4 100644 --- a/templates/repo/editor/edit.tmpl +++ b/templates/repo/editor/edit.tmpl @@ -30,13 +30,13 @@ <div class="ui top attached tabular menu" data-write="write" data-preview="preview" data-diff="diff"> <a class="active item" data-tab="write"><i class="octicon octicon-code"></i> {{if .IsNewFile}}{{.i18n.Tr "repo.editor.new_file"}}{{else}}{{.i18n.Tr "repo.editor.edit_file"}}{{end}}</a> {{if not .IsNewFile}} - <a class="item" data-tab="preview" data-url="{{AppSubUrl}}/api/v1/markdown" data-context="{{.RepoLink}}/src/{{.BranchNameSubURL | EscapePound}}" data-preview-file-modes="{{.PreviewableFileModes}}"><i class="octicon octicon-eye"></i> {{.i18n.Tr "preview"}}</a> + <a class="item" data-tab="preview" data-url="{{.Repository.APIURL}}/markdown" data-context="{{.RepoLink}}/src/{{.BranchNameSubURL | EscapePound}}" data-preview-file-modes="{{.PreviewableFileModes}}"><i class="octicon octicon-eye"></i> {{.i18n.Tr "preview"}}</a> <a class="item" data-tab="diff" data-url="{{.RepoLink}}/_preview/{{.BranchName | EscapePound}}/{{.TreePath | EscapePound}}" data-context="{{.BranchLink}}"><i class="octicon octicon-diff"></i> {{.i18n.Tr "repo.editor.preview_changes"}}</a> {{end}} </div> <div class="ui bottom attached active tab segment" data-tab="write"> <textarea id="edit_area" name="content" data-id="repo-{{.Repository.Name}}-{{.TreePath}}" - data-url="{{AppSubUrl}}/api/v1/markdown" + data-url="{{.Repository.APIURL}}/markdown" data-context="{{.RepoLink}}" data-markdown-file-exts="{{.MarkdownFileExts}}" data-line-wrap-extensions="{{.LineWrapExtensions}}" diff --git a/templates/repo/issue/comment_tab.tmpl b/templates/repo/issue/comment_tab.tmpl index b1630824e5..be113e539a 100644 --- a/templates/repo/issue/comment_tab.tmpl +++ b/templates/repo/issue/comment_tab.tmpl @@ -1,10 +1,10 @@ <div class="field"> <div class="ui top attached tabular menu" data-write="write" data-preview="preview"> <a class="active item" data-tab="write">{{.i18n.Tr "write"}}</a> - <a class="item" data-tab="preview" data-url="{{AppSubUrl}}/api/v1/markdown" data-context="{{.RepoLink}}">{{.i18n.Tr "preview"}}</a> + <a class="item" data-tab="preview" data-url="{{.Repository.APIURL}}/markdown" data-context="{{.RepoLink}}">{{.i18n.Tr "preview"}}</a> </div> <div class="ui bottom attached active tab segment" data-tab="write"> - <textarea id="content" class="edit_area js-quick-submit" name="content" tabindex="4" data-id="issue-{{.RepoName}}" data-url="{{AppSubUrl}}/api/v1/markdown" data-context="{{.Repo.RepoLink}}"> + <textarea id="content" class="edit_area js-quick-submit" name="content" tabindex="4" data-id="issue-{{.RepoName}}" data-url="{{.Repository.APIURL}}/markdown" data-context="{{.Repo.RepoLink}}"> {{if .BodyQuery}}{{.BodyQuery}}{{else if .IssueTemplate}}{{.IssueTemplate}}{{else if .PullRequestTemplate}}{{.PullRequestTemplate}}{{else}}{{.content}}{{end}}</textarea> </div> <div class="ui bottom attached tab segment markdown" data-tab="preview"> diff --git a/templates/repo/issue/view_content.tmpl b/templates/repo/issue/view_content.tmpl index 7445dcce86..cb58fbef63 100644 --- a/templates/repo/issue/view_content.tmpl +++ b/templates/repo/issue/view_content.tmpl @@ -156,7 +156,7 @@ <div class="ui comment form"> <div class="ui top attached tabular menu"> <a class="active write item">{{$.i18n.Tr "write"}}</a> - <a class="preview item" data-url="{{AppSubUrl}}/api/v1/markdown" data-context="{{$.RepoLink}}">{{$.i18n.Tr "preview"}}</a> + <a class="preview item" data-url="{{$.Repository.APIURL}}/markdown" data-context="{{$.RepoLink}}">{{$.i18n.Tr "preview"}}</a> </div> <div class="ui bottom attached active write tab segment"> <textarea tabindex="1" name="content"></textarea> diff --git a/templates/repo/wiki/new.tmpl b/templates/repo/wiki/new.tmpl index 7dc066ffb8..bf6c24220b 100644 --- a/templates/repo/wiki/new.tmpl +++ b/templates/repo/wiki/new.tmpl @@ -17,7 +17,7 @@ <input name="title" value="{{.title}}" autofocus required> </div> <div class="field"> - <textarea class="js-quick-submit" id="edit_area" name="content" data-id="wiki-{{.title}}" data-url="{{AppSubUrl}}/api/v1/markdown" data-context="{{.RepoLink}}/wiki" required>{{if .PageIsWikiEdit}}{{.content}}{{else}}{{.i18n.Tr "repo.wiki.welcome"}}{{end}}</textarea> + <textarea class="js-quick-submit" id="edit_area" name="content" data-id="wiki-{{.title}}" data-url="{{.Repository.APIURL}}/markdown" data-context="{{.RepoLink}}/wiki" required>{{if .PageIsWikiEdit}}{{.content}}{{else}}{{.i18n.Tr "repo.wiki.welcome"}}{{end}}</textarea> </div> <div class="field"> <input name="message" placeholder="{{.i18n.Tr "repo.wiki.default_commit_message"}}"> |