From 636b677c0e1b51bc4bcb80e35b17703790d363cd Mon Sep 17 00:00:00 2001 From: jolheiser Date: Wed, 15 Jan 2020 15:51:58 -0600 Subject: [PATCH 01/13] Add data-index attribute to issue anchors Signed-off-by: jolheiser --- modules/markup/html.go | 7 ++++--- modules/markup/sanitizer.go | 3 +++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/modules/markup/html.go b/modules/markup/html.go index 2c6773bce41e7..2da02892f7f8a 100644 --- a/modules/markup/html.go +++ b/modules/markup/html.go @@ -676,7 +676,7 @@ func issueIndexPatternProcessor(ctx *postProcessCtx, node *html.Node) { reftext := node.Data[ref.RefLocation.Start:ref.RefLocation.End] if exttrack && !ref.IsPull { ctx.metas["index"] = ref.Issue - link = createLink(com.Expand(ctx.metas["format"], ctx.metas), reftext, "issue") + link = createLink(com.Expand(ctx.metas["format"], ctx.metas), reftext, "ref-issue") } else { // Path determines the type of link that will be rendered. It's unknown at this point whether // the linked item is actually a PR or an issue. Luckily it's of no real consequence because @@ -686,11 +686,12 @@ func issueIndexPatternProcessor(ctx *postProcessCtx, node *html.Node) { path = "pulls" } if ref.Owner == "" { - link = createLink(util.URLJoin(setting.AppURL, ctx.metas["user"], ctx.metas["repo"], path, ref.Issue), reftext, "issue") + link = createLink(util.URLJoin(setting.AppURL, ctx.metas["user"], ctx.metas["repo"], path, ref.Issue), reftext, "ref-issue") } else { - link = createLink(util.URLJoin(setting.AppURL, ref.Owner, ref.Name, path, ref.Issue), reftext, "issue") + link = createLink(util.URLJoin(setting.AppURL, ref.Owner, ref.Name, path, ref.Issue), reftext, "ref-issue") } } + link.Attr = append(link.Attr, html.Attribute{Key: "data-index", Val: ref.Issue}) if ref.Action == references.XRefActionNone { replaceContent(node, ref.RefLocation.Start, ref.RefLocation.End, link) diff --git a/modules/markup/sanitizer.go b/modules/markup/sanitizer.go index d135d41966d6c..3e9c9a91d37c0 100644 --- a/modules/markup/sanitizer.go +++ b/modules/markup/sanitizer.go @@ -53,6 +53,9 @@ func ReplaceSanitizer() { // Allow tags for keyboard shortcut styling sanitizer.policy.AllowElements("kbd") + // Allow classes for anchors + sanitizer.policy.AllowAttrs("class", "data-index").OnElements("a") + // Custom keyword markup for _, rule := range setting.ExternalSanitizerRules { if rule.Regexp != nil { From 0bb692c4633a9f1a31566780fbf7c1d366723369 Mon Sep 17 00:00:00 2001 From: jolheiser Date: Wed, 15 Jan 2020 16:06:07 -0600 Subject: [PATCH 02/13] Init JS Signed-off-by: jolheiser --- web_src/js/index.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/web_src/js/index.js b/web_src/js/index.js index 7c3749c08b722..a7227debef1db 100644 --- a/web_src/js/index.js +++ b/web_src/js/index.js @@ -2319,6 +2319,16 @@ function initTemplateSearch() { changeOwner(); } +function initIssuePopup() { + $('.ref-issue').hover(function () { + $(this).popup({ + html: '', + }); + }, function () { + $(this).popup('hide'); + }); +} + $(document).ready(() => { csrf = $('meta[name=_csrf]').attr('content'); suburl = $('meta[name=_suburl]').attr('content'); @@ -2556,6 +2566,7 @@ $(document).ready(() => { initPullRequestReview(); initRepoStatusChecker(); initTemplateSearch(); + initIssuePopup(); // Repo clone url. if ($('#repo-clone-url').length > 0) { From 04a1fbdbc9617320327e325eb018dbf790da2f97 Mon Sep 17 00:00:00 2001 From: jolheiser Date: Wed, 15 Jan 2020 22:25:23 -0600 Subject: [PATCH 03/13] Add required data to anchor Signed-off-by: jolheiser --- modules/markup/html.go | 18 +++++++++++++----- modules/markup/sanitizer.go | 2 +- web_src/js/index.js | 11 +++++------ 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/modules/markup/html.go b/modules/markup/html.go index 2da02892f7f8a..83e05d4b6f0ba 100644 --- a/modules/markup/html.go +++ b/modules/markup/html.go @@ -673,6 +673,7 @@ func issueIndexPatternProcessor(ctx *postProcessCtx, node *html.Node) { } var link *html.Node + var owner, repo string reftext := node.Data[ref.RefLocation.Start:ref.RefLocation.End] if exttrack && !ref.IsPull { ctx.metas["index"] = ref.Issue @@ -681,17 +682,24 @@ func issueIndexPatternProcessor(ctx *postProcessCtx, node *html.Node) { // Path determines the type of link that will be rendered. It's unknown at this point whether // the linked item is actually a PR or an issue. Luckily it's of no real consequence because // Gitea will redirect on click as appropriate. - path := "issues" + p := "issues" if ref.IsPull { - path = "pulls" + p = "pulls" } if ref.Owner == "" { - link = createLink(util.URLJoin(setting.AppURL, ctx.metas["user"], ctx.metas["repo"], path, ref.Issue), reftext, "ref-issue") + owner = ctx.metas["user"] + repo = ctx.metas["repo"] } else { - link = createLink(util.URLJoin(setting.AppURL, ref.Owner, ref.Name, path, ref.Issue), reftext, "ref-issue") + owner = ref.Owner + repo = ref.Name } + link = createLink(util.URLJoin(setting.AppURL, owner, repo, p, ref.Issue), reftext, "ref-issue") } - link.Attr = append(link.Attr, html.Attribute{Key: "data-index", Val: ref.Issue}) + link.Attr = append(link.Attr, + html.Attribute{Key: "data-owner", Val: owner}, + html.Attribute{Key: "data-repo", Val: repo}, + html.Attribute{Key: "data-index", Val: ref.Issue}, + ) if ref.Action == references.XRefActionNone { replaceContent(node, ref.RefLocation.Start, ref.RefLocation.End, link) diff --git a/modules/markup/sanitizer.go b/modules/markup/sanitizer.go index 3e9c9a91d37c0..decda81ec6b97 100644 --- a/modules/markup/sanitizer.go +++ b/modules/markup/sanitizer.go @@ -54,7 +54,7 @@ func ReplaceSanitizer() { sanitizer.policy.AllowElements("kbd") // Allow classes for anchors - sanitizer.policy.AllowAttrs("class", "data-index").OnElements("a") + sanitizer.policy.AllowAttrs("class", "data-owner", "data-repo", "data-index").OnElements("a") // Custom keyword markup for _, rule := range setting.ExternalSanitizerRules { diff --git a/web_src/js/index.js b/web_src/js/index.js index a7227debef1db..9305b20f691b2 100644 --- a/web_src/js/index.js +++ b/web_src/js/index.js @@ -2320,12 +2320,11 @@ function initTemplateSearch() { } function initIssuePopup() { - $('.ref-issue').hover(function () { - $(this).popup({ - html: '', - }); - }, function () { - $(this).popup('hide'); + $('.ref-issue').each(function () { + const owner = $(this).data('owner'); + const repo = $(this).data('repo'); + const index = $(this).data('index'); + // TODO popup }); } From 418185c280cebec0f7fbbaa7d46cf346cf58c5a7 Mon Sep 17 00:00:00 2001 From: jolheiser Date: Thu, 16 Jan 2020 22:29:18 -0600 Subject: [PATCH 04/13] Finish popup Signed-off-by: jolheiser --- modules/markup/html.go | 5 --- modules/markup/sanitizer.go | 2 +- web_src/js/index.js | 55 +++++++++++++++++++++++++++--- web_src/less/_base.less | 12 +++++++ web_src/less/themes/arc-green.less | 5 +++ 5 files changed, 69 insertions(+), 10 deletions(-) diff --git a/modules/markup/html.go b/modules/markup/html.go index 83e05d4b6f0ba..2e404d0b1fae5 100644 --- a/modules/markup/html.go +++ b/modules/markup/html.go @@ -695,11 +695,6 @@ func issueIndexPatternProcessor(ctx *postProcessCtx, node *html.Node) { } link = createLink(util.URLJoin(setting.AppURL, owner, repo, p, ref.Issue), reftext, "ref-issue") } - link.Attr = append(link.Attr, - html.Attribute{Key: "data-owner", Val: owner}, - html.Attribute{Key: "data-repo", Val: repo}, - html.Attribute{Key: "data-index", Val: ref.Issue}, - ) if ref.Action == references.XRefActionNone { replaceContent(node, ref.RefLocation.Start, ref.RefLocation.End, link) diff --git a/modules/markup/sanitizer.go b/modules/markup/sanitizer.go index decda81ec6b97..8888360db717b 100644 --- a/modules/markup/sanitizer.go +++ b/modules/markup/sanitizer.go @@ -54,7 +54,7 @@ func ReplaceSanitizer() { sanitizer.policy.AllowElements("kbd") // Allow classes for anchors - sanitizer.policy.AllowAttrs("class", "data-owner", "data-repo", "data-index").OnElements("a") + sanitizer.policy.AllowAttrs("class").Matching(regexp.MustCompile(`ref-issue`)).OnElements("a") // Custom keyword markup for _, rule := range setting.ExternalSanitizerRules { diff --git a/web_src/js/index.js b/web_src/js/index.js index 9305b20f691b2..643d050549de5 100644 --- a/web_src/js/index.js +++ b/web_src/js/index.js @@ -2321,10 +2321,57 @@ function initTemplateSearch() { function initIssuePopup() { $('.ref-issue').each(function () { - const owner = $(this).data('owner'); - const repo = $(this).data('repo'); - const index = $(this).data('index'); - // TODO popup + const href = $(this).attr('href').split('/'); + const index = href.pop(); + href.pop(); // issues + const repo = href.pop(); + const owner = href.pop(); + $.get(`${suburl}/api/v1/repos/${owner}/${repo}/issues/${index}`, (issue) => { + const createdAt = new Date(issue.created_at).toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' }); + + let body = issue.body.replace(/\n+/g, ' '); + if (body.length > 85) { + body = `${body.substring(0, 85)}...`; + } + + let labels = ''; + for (let i = 0; i < issue.labels.length; i++) { + const label = issue.labels[i]; + const red = parseInt(label.color.substring(0, 2), 16); + const green = parseInt(label.color.substring(2, 4), 16); + const blue = parseInt(label.color.substring(4, 6), 16); + let color = '#ffffff'; + if ((red * 0.299 + green * 0.587 + blue * 0.114) > 125) { + color = '#000000'; + } + labels += `
${label.name}
`; + } + if (labels.length > 0) { + labels = `

${labels}

`; + } + + let octicon = 'green octicon-issue-opened'; + if (issue.state === 'closed') { + if (issue.pull_request !== null && issue.pull_request.merged === true) { + octicon = 'purple octicon-git-pull-request'; + } else { + octicon = 'red octicon-issue-closed'; + } + } + + $(this).popup({ + className: { + popup: 'ui popup issue-popup' + }, + variation: 'wide', + html: `
+

${issue.repository.full_name} on ${createdAt}

+

${issue.title} #${index}

+

${body}

+${labels} +
` + }); + }); }); } diff --git a/web_src/less/_base.less b/web_src/less/_base.less index 068b9e8144c4b..254fb1146f015 100644 --- a/web_src/less/_base.less +++ b/web_src/less/_base.less @@ -1185,3 +1185,15 @@ i.icon.centerlock { vertical-align: middle; height: 2.1666em !important; } + +.octicon { + &.green { + color: #21ba45; + } + &.red { + color: #db2828; + } + &.purple { + color: #a333c8; + } +} diff --git a/web_src/less/themes/arc-green.less b/web_src/less/themes/arc-green.less index 69e8963fbb002..841d83b132d4d 100644 --- a/web_src/less/themes/arc-green.less +++ b/web_src/less/themes/arc-green.less @@ -1463,3 +1463,8 @@ a.ui.labels .label:hover { } } } + +.ui.popup.issue-popup { + background-color: #383c4a; + color: #9e9e9e; +} From 7ca20c85453af882789a9717b282238c20ae25a8 Mon Sep 17 00:00:00 2001 From: jolheiser Date: Thu, 16 Jan 2020 22:31:51 -0600 Subject: [PATCH 05/13] Revert changes to html.go Signed-off-by: jolheiser --- modules/markup/html.go | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/modules/markup/html.go b/modules/markup/html.go index 2e404d0b1fae5..02155e2e2deaa 100644 --- a/modules/markup/html.go +++ b/modules/markup/html.go @@ -673,7 +673,6 @@ func issueIndexPatternProcessor(ctx *postProcessCtx, node *html.Node) { } var link *html.Node - var owner, repo string reftext := node.Data[ref.RefLocation.Start:ref.RefLocation.End] if exttrack && !ref.IsPull { ctx.metas["index"] = ref.Issue @@ -682,18 +681,15 @@ func issueIndexPatternProcessor(ctx *postProcessCtx, node *html.Node) { // Path determines the type of link that will be rendered. It's unknown at this point whether // the linked item is actually a PR or an issue. Luckily it's of no real consequence because // Gitea will redirect on click as appropriate. - p := "issues" + path := "issues" if ref.IsPull { - p = "pulls" + path = "pulls" } if ref.Owner == "" { - owner = ctx.metas["user"] - repo = ctx.metas["repo"] + link = createLink(util.URLJoin(setting.AppURL, ctx.metas["user"], ctx.metas["repo"], path, ref.Issue), reftext, "ref-issue") } else { - owner = ref.Owner - repo = ref.Name + link = createLink(util.URLJoin(setting.AppURL, ref.Owner, ref.Name, path, ref.Issue), reftext, "ref-issue") } - link = createLink(util.URLJoin(setting.AppURL, owner, repo, p, ref.Issue), reftext, "ref-issue") } if ref.Action == references.XRefActionNone { From 3a45b8c2862e3f4bcf381fc0c45ee8ba13c8f27b Mon Sep 17 00:00:00 2001 From: jolheiser Date: Thu, 16 Jan 2020 22:52:09 -0600 Subject: [PATCH 06/13] Better octicon contexts Signed-off-by: jolheiser --- web_src/js/index.js | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/web_src/js/index.js b/web_src/js/index.js index 643d050549de5..c6802a86db11f 100644 --- a/web_src/js/index.js +++ b/web_src/js/index.js @@ -2350,13 +2350,19 @@ function initIssuePopup() { labels = `

${labels}

`; } - let octicon = 'green octicon-issue-opened'; - if (issue.state === 'closed') { - if (issue.pull_request !== null && issue.pull_request.merged === true) { - octicon = 'purple octicon-git-pull-request'; + let octicon; + if (issue.pull_request !== null) { + if (issue.state === 'open') { + octicon = 'green octicon-git-pull-request'; // Open PR + } else if (issue.pull_request.merged === true) { + octicon = 'purple octicon-git-merge'; // Merged PR } else { - octicon = 'red octicon-issue-closed'; + octicon = 'red octicon-git-pull-request'; // Closed PR } + } else if (issue.state === 'open') { + octicon = 'green octicon-issue-opened'; // Open Issue + } else { + octicon = 'red octicon-issue-closed'; // Closed Issue } $(this).popup({ @@ -2364,6 +2370,9 @@ function initIssuePopup() { popup: 'ui popup issue-popup' }, variation: 'wide', + delay: { + show: 250 + }, html: `

${issue.repository.full_name} on ${createdAt}

${issue.title} #${index}

From 0335c827243380f314f5686ed08f4327e86a1107 Mon Sep 17 00:00:00 2001 From: jolheiser Date: Thu, 16 Jan 2020 22:56:04 -0600 Subject: [PATCH 07/13] Split out popup function for re-use Signed-off-by: jolheiser --- web_src/js/index.js | 106 +++++++++++++++++++++++--------------------- 1 file changed, 55 insertions(+), 51 deletions(-) diff --git a/web_src/js/index.js b/web_src/js/index.js index c6802a86db11f..3f667a49d7b01 100644 --- a/web_src/js/index.js +++ b/web_src/js/index.js @@ -2319,71 +2319,75 @@ function initTemplateSearch() { changeOwner(); } -function initIssuePopup() { - $('.ref-issue').each(function () { - const href = $(this).attr('href').split('/'); - const index = href.pop(); - href.pop(); // issues - const repo = href.pop(); - const owner = href.pop(); - $.get(`${suburl}/api/v1/repos/${owner}/${repo}/issues/${index}`, (issue) => { - const createdAt = new Date(issue.created_at).toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' }); - - let body = issue.body.replace(/\n+/g, ' '); - if (body.length > 85) { - body = `${body.substring(0, 85)}...`; - } - - let labels = ''; - for (let i = 0; i < issue.labels.length; i++) { - const label = issue.labels[i]; - const red = parseInt(label.color.substring(0, 2), 16); - const green = parseInt(label.color.substring(2, 4), 16); - const blue = parseInt(label.color.substring(4, 6), 16); - let color = '#ffffff'; - if ((red * 0.299 + green * 0.587 + blue * 0.114) > 125) { - color = '#000000'; - } - labels += `
${label.name}
`; - } - if (labels.length > 0) { - labels = `

${labels}

`; +function issuePopup(owner, repo, index, $element) { + $.get(`${suburl}/api/v1/repos/${owner}/${repo}/issues/${index}`, (issue) => { + const createdAt = new Date(issue.created_at).toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' }); + + let body = issue.body.replace(/\n+/g, ' '); + if (body.length > 85) { + body = `${body.substring(0, 85)}...`; + } + + let labels = ''; + for (let i = 0; i < issue.labels.length; i++) { + const label = issue.labels[i]; + const red = parseInt(label.color.substring(0, 2), 16); + const green = parseInt(label.color.substring(2, 4), 16); + const blue = parseInt(label.color.substring(4, 6), 16); + let color = '#ffffff'; + if ((red * 0.299 + green * 0.587 + blue * 0.114) > 125) { + color = '#000000'; } + labels += `
${label.name}
`; + } + if (labels.length > 0) { + labels = `

${labels}

`; + } - let octicon; - if (issue.pull_request !== null) { - if (issue.state === 'open') { - octicon = 'green octicon-git-pull-request'; // Open PR - } else if (issue.pull_request.merged === true) { - octicon = 'purple octicon-git-merge'; // Merged PR - } else { - octicon = 'red octicon-git-pull-request'; // Closed PR - } - } else if (issue.state === 'open') { - octicon = 'green octicon-issue-opened'; // Open Issue + let octicon; + if (issue.pull_request !== null) { + if (issue.state === 'open') { + octicon = 'green octicon-git-pull-request'; // Open PR + } else if (issue.pull_request.merged === true) { + octicon = 'purple octicon-git-merge'; // Merged PR } else { - octicon = 'red octicon-issue-closed'; // Closed Issue + octicon = 'red octicon-git-pull-request'; // Closed PR } + } else if (issue.state === 'open') { + octicon = 'green octicon-issue-opened'; // Open Issue + } else { + octicon = 'red octicon-issue-closed'; // Closed Issue + } - $(this).popup({ - className: { - popup: 'ui popup issue-popup' - }, - variation: 'wide', - delay: { - show: 250 - }, - html: `
+ $element.popup({ + className: { + popup: 'ui popup issue-popup' + }, + variation: 'wide', + delay: { + show: 250 + }, + html: `

${issue.repository.full_name} on ${createdAt}

${issue.title} #${index}

${body}

${labels}
` - }); }); }); } +function initIssuePopup() { + $('.ref-issue').each(function () { + const href = $(this).attr('href').split('/'); + const index = href.pop(); + href.pop(); // issues + const repo = href.pop(); + const owner = href.pop(); + issuePopup(owner, repo, index, $(this)); + }); +} + $(document).ready(() => { csrf = $('meta[name=_csrf]').attr('content'); suburl = $('meta[name=_suburl]').attr('content'); From c1b562ec2428a10a3807d51098e3ef3794da81da Mon Sep 17 00:00:00 2001 From: jolheiser Date: Fri, 17 Jan 2020 09:57:45 -0600 Subject: [PATCH 08/13] Style changes, test fixes, and cross-reference support Signed-off-by: jolheiser --- modules/markup/html.go | 4 ++-- modules/markup/html_internal_test.go | 14 +++++++------- modules/markup/html_test.go | 4 ++-- modules/markup/markdown/markdown_test.go | 4 ++-- web_src/js/index.js | 3 --- web_src/less/themes/arc-green.less | 11 ++++++++++- 6 files changed, 23 insertions(+), 17 deletions(-) diff --git a/modules/markup/html.go b/modules/markup/html.go index 02155e2e2deaa..1c73f03df1fcd 100644 --- a/modules/markup/html.go +++ b/modules/markup/html.go @@ -636,11 +636,11 @@ func fullIssuePatternProcessor(ctx *postProcessCtx, node *html.Node) { 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, "issue")) + replaceContent(node, m[0], m[1], createLink(link, id, "ref-issue")) } else { orgRepoID := matchOrg + "/" + matchRepo + id - replaceContent(node, m[0], m[1], createLink(link, orgRepoID, "issue")) + replaceContent(node, m[0], m[1], createLink(link, orgRepoID, "ref-issue")) } } diff --git a/modules/markup/html_internal_test.go b/modules/markup/html_internal_test.go index 2746dec2cf063..7e4bb6f22f31e 100644 --- a/modules/markup/html_internal_test.go +++ b/modules/markup/html_internal_test.go @@ -106,13 +106,13 @@ func TestRender_IssueIndexPattern2(t *testing.T) { links := make([]interface{}, len(indices)) for i, index := range indices { - links[i] = numericIssueLink(util.URLJoin(setting.AppSubURL, path), "issue", index, marker) + links[i] = numericIssueLink(util.URLJoin(setting.AppSubURL, path), "ref-issue", index, marker) } expectedNil := fmt.Sprintf(expectedFmt, links...) testRenderIssueIndexPattern(t, s, expectedNil, &postProcessCtx{metas: localMetas}) for i, index := range indices { - links[i] = numericIssueLink(prefix, "issue", index, marker) + links[i] = numericIssueLink(prefix, "ref-issue", index, marker) } expectedNum := fmt.Sprintf(expectedFmt, links...) testRenderIssueIndexPattern(t, s, expectedNum, &postProcessCtx{metas: numericMetas}) @@ -178,7 +178,7 @@ func TestRender_IssueIndexPattern4(t *testing.T) { test := func(s, expectedFmt string, names ...string) { links := make([]interface{}, len(names)) for i, name := range names { - links[i] = alphanumIssueLink("https://someurl.com/someUser/someRepo/", "issue", name) + links[i] = alphanumIssueLink("https://someurl.com/someUser/someRepo/", "ref-issue", name) } expected := fmt.Sprintf(expectedFmt, links...) testRenderIssueIndexPattern(t, s, expected, &postProcessCtx{metas: alphanumericMetas}) @@ -217,7 +217,7 @@ func TestRender_AutoLink(t *testing.T) { // render valid issue URLs test(util.URLJoin(setting.AppSubURL, "issues", "3333"), - numericIssueLink(util.URLJoin(setting.AppSubURL, "issues"), "issue", 3333, "#")) + numericIssueLink(util.URLJoin(setting.AppSubURL, "issues"), "ref-issue", 3333, "#")) // render valid commit URLs tmp := util.URLJoin(AppSubURL, "commit", "d8a994ef243349f321568f9e36d5c3f444b99cae") @@ -248,11 +248,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 person/repo#4`) + `Look here person/repo#4`) test("http://localhost:3000/person/repo/issues/4#issuecomment-1234", - `person/repo#4`) + `person/repo#4`) test("http://localhost:3000/gogits/gogs/issues/4", - `#4`) + `#4`) } func TestRegExp_sha1CurrentPattern(t *testing.T) { diff --git a/modules/markup/html_test.go b/modules/markup/html_test.go index 91ef320b40927..45145b40250dc 100644 --- a/modules/markup/html_test.go +++ b/modules/markup/html_test.go @@ -58,10 +58,10 @@ func TestRender_CrossReferences(t *testing.T) { test( "gogits/gogs#12345", - `

gogits/gogs#12345

`) + `

gogits/gogs#12345

`) test( "go-gitea/gitea#12345", - `

go-gitea/gitea#12345

`) + `

go-gitea/gitea#12345

`) test( "/home/gitea/go-gitea/gitea#12345", `

/home/gitea/go-gitea/gitea#12345

`) diff --git a/modules/markup/markdown/markdown_test.go b/modules/markup/markdown/markdown_test.go index 53772ee441365..b2cf529964091 100644 --- a/modules/markup/markdown/markdown_test.go +++ b/modules/markup/markdown/markdown_test.go @@ -105,8 +105,8 @@ func testAnswers(baseURLContent, baseURLImages string) []string {

See commit 65f1bf27bc

Ideas and codes

    -
  • Bezier widget (by @r-lyeh) ocornut/imgui#786
  • -
  • Bezier widget (by @r-lyeh) #786
  • +
  • Bezier widget (by @r-lyeh) ocornut/imgui#786
  • +
  • Bezier widget (by @r-lyeh) #786
  • Node graph editors https://github.com/ocornut/imgui/issues/306
  • Memory Editor
  • Plot var helper
  • diff --git a/web_src/js/index.js b/web_src/js/index.js index 3f667a49d7b01..14c93b4b22cec 100644 --- a/web_src/js/index.js +++ b/web_src/js/index.js @@ -2360,9 +2360,6 @@ function issuePopup(owner, repo, index, $element) { } $element.popup({ - className: { - popup: 'ui popup issue-popup' - }, variation: 'wide', delay: { show: 250 diff --git a/web_src/less/themes/arc-green.less b/web_src/less/themes/arc-green.less index 841d83b132d4d..c13cb96acd483 100644 --- a/web_src/less/themes/arc-green.less +++ b/web_src/less/themes/arc-green.less @@ -1464,7 +1464,16 @@ a.ui.labels .label:hover { } } -.ui.popup.issue-popup { +.ui.popup { background-color: #383c4a; color: #9e9e9e; + border-color: #9e9e9e; + + &.top::before { + background-color: #383c4a; + } + + .ui.label { + margin-bottom: 5px; + } } From dfe77303086cb0b2d7803a265d5339327438dbac Mon Sep 17 00:00:00 2001 From: jolheiser Date: Fri, 17 Jan 2020 10:03:21 -0600 Subject: [PATCH 09/13] Prefer em to px Signed-off-by: jolheiser --- web_src/less/themes/arc-green.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_src/less/themes/arc-green.less b/web_src/less/themes/arc-green.less index c13cb96acd483..5ae3b5c39f0e1 100644 --- a/web_src/less/themes/arc-green.less +++ b/web_src/less/themes/arc-green.less @@ -1474,6 +1474,6 @@ a.ui.labels .label:hover { } .ui.label { - margin-bottom: 5px; + margin-bottom: 0.4em; } } From 9fee588ce016bf9ef54e16d55bac714af4e76008 Mon Sep 17 00:00:00 2001 From: jolheiser Date: Fri, 17 Jan 2020 10:07:08 -0600 Subject: [PATCH 10/13] Move label margin to base CSS Signed-off-by: jolheiser --- web_src/less/_base.less | 4 ++++ web_src/less/themes/arc-green.less | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/web_src/less/_base.less b/web_src/less/_base.less index 254fb1146f015..f34cb71013f75 100644 --- a/web_src/less/_base.less +++ b/web_src/less/_base.less @@ -1197,3 +1197,7 @@ i.icon.centerlock { color: #a333c8; } } + +.ui.popup .ui.label { + margin-bottom: 0.4em; +} diff --git a/web_src/less/themes/arc-green.less b/web_src/less/themes/arc-green.less index 5ae3b5c39f0e1..5aa7c8f2c5db7 100644 --- a/web_src/less/themes/arc-green.less +++ b/web_src/less/themes/arc-green.less @@ -1472,8 +1472,4 @@ a.ui.labels .label:hover { &.top::before { background-color: #383c4a; } - - .ui.label { - margin-bottom: 0.4em; - } } From b9a3121583783cf66ccfb89ba9a131b89477658e Mon Sep 17 00:00:00 2001 From: jolheiser Date: Fri, 17 Jan 2020 10:59:17 -0600 Subject: [PATCH 11/13] Move JS to separate file. Signed-off-by: jolheiser --- templates/pwa/serviceworker_js.tmpl | 1 + web_src/js/contextPopup.js | 73 +++++++++++++++++++++++++++++ web_src/js/index.js | 68 +-------------------------- 3 files changed, 75 insertions(+), 67 deletions(-) create mode 100644 web_src/js/contextPopup.js diff --git a/templates/pwa/serviceworker_js.tmpl b/templates/pwa/serviceworker_js.tmpl index 9595d8f267b0a..8ace0c094905a 100644 --- a/templates/pwa/serviceworker_js.tmpl +++ b/templates/pwa/serviceworker_js.tmpl @@ -7,6 +7,7 @@ var urlsToCache = [ '{{StaticUrlPrefix}}/vendor/plugins/fomantic/semantic.min.js?v={{MD5 AppVer}}', '{{StaticUrlPrefix}}/js/index.js?v={{MD5 AppVer}}', '{{StaticUrlPrefix}}/js/swagger.js?v={{MD5 AppVer}}', + '{{StaticUrlPrefix}}/js/contextPopup.js?v={{MD5 AppVer}}', '{{StaticUrlPrefix}}/js/gitgraph.js?v={{MD5 AppVer}}', '{{StaticUrlPrefix}}/vendor/plugins/clipboard/clipboard.min.js', '{{StaticUrlPrefix}}/vendor/plugins/vue/vue.min.js', diff --git a/web_src/js/contextPopup.js b/web_src/js/contextPopup.js new file mode 100644 index 0000000000000..b9165ef53635a --- /dev/null +++ b/web_src/js/contextPopup.js @@ -0,0 +1,73 @@ +let suburl; + +window.addEventListener('load', () => { + suburl = $('meta[name=_suburl]').attr('content'); + const refIssues = $('.ref-issue'); + if (!refIssues.length) return; + + refIssues.each(function () { + const href = $(this).attr('href').split('/'); + const index = href.pop(); + href.pop(); // issues + const repo = href.pop(); + const owner = href.pop(); + issuePopup(owner, repo, index, $(this)); + }); +}); + +function issuePopup(owner, repo, index, $element) { + $.get(`${suburl}/api/v1/repos/${owner}/${repo}/issues/${index}`, (issue) => { + const createdAt = new Date(issue.created_at).toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' }); + + let body = issue.body.replace(/\n+/g, ' '); + if (body.length > 85) { + body = `${body.substring(0, 85)}...`; + } + + let labels = ''; + for (let i = 0; i < issue.labels.length; i++) { + const label = issue.labels[i]; + const red = parseInt(label.color.substring(0, 2), 16); + const green = parseInt(label.color.substring(2, 4), 16); + const blue = parseInt(label.color.substring(4, 6), 16); + let color = '#ffffff'; + if ((red * 0.299 + green * 0.587 + blue * 0.114) > 125) { + color = '#000000'; + } + labels += `
    ${label.name}
    `; + } + if (labels.length > 0) { + labels = `

    ${labels}

    `; + } + + let octicon; + if (issue.pull_request !== null) { + if (issue.state === 'open') { + octicon = 'green octicon-git-pull-request'; // Open PR + } else if (issue.pull_request.merged === true) { + octicon = 'purple octicon-git-merge'; // Merged PR + } else { + octicon = 'red octicon-git-pull-request'; // Closed PR + } + } else if (issue.state === 'open') { + octicon = 'green octicon-issue-opened'; // Open Issue + } else { + octicon = 'red octicon-issue-closed'; // Closed Issue + } + + $element.popup({ + variation: 'wide', + delay: { + show: 250 + }, + html: ` +
    +

    ${issue.repository.full_name} on ${createdAt}

    +

    ${issue.title} #${index}

    +

    ${body}

    + ${labels} +
    +` + }); + }); +} diff --git a/web_src/js/index.js b/web_src/js/index.js index 14c93b4b22cec..7f1671eef6df8 100644 --- a/web_src/js/index.js +++ b/web_src/js/index.js @@ -5,6 +5,7 @@ import './publicPath.js'; import './gitGraphLoader.js'; import './semanticDropdown.js'; +import './contextPopup.js'; function htmlEncode(text) { return jQuery('
    ').text(text).html(); @@ -2319,72 +2320,6 @@ function initTemplateSearch() { changeOwner(); } -function issuePopup(owner, repo, index, $element) { - $.get(`${suburl}/api/v1/repos/${owner}/${repo}/issues/${index}`, (issue) => { - const createdAt = new Date(issue.created_at).toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' }); - - let body = issue.body.replace(/\n+/g, ' '); - if (body.length > 85) { - body = `${body.substring(0, 85)}...`; - } - - let labels = ''; - for (let i = 0; i < issue.labels.length; i++) { - const label = issue.labels[i]; - const red = parseInt(label.color.substring(0, 2), 16); - const green = parseInt(label.color.substring(2, 4), 16); - const blue = parseInt(label.color.substring(4, 6), 16); - let color = '#ffffff'; - if ((red * 0.299 + green * 0.587 + blue * 0.114) > 125) { - color = '#000000'; - } - labels += `
    ${label.name}
    `; - } - if (labels.length > 0) { - labels = `

    ${labels}

    `; - } - - let octicon; - if (issue.pull_request !== null) { - if (issue.state === 'open') { - octicon = 'green octicon-git-pull-request'; // Open PR - } else if (issue.pull_request.merged === true) { - octicon = 'purple octicon-git-merge'; // Merged PR - } else { - octicon = 'red octicon-git-pull-request'; // Closed PR - } - } else if (issue.state === 'open') { - octicon = 'green octicon-issue-opened'; // Open Issue - } else { - octicon = 'red octicon-issue-closed'; // Closed Issue - } - - $element.popup({ - variation: 'wide', - delay: { - show: 250 - }, - html: `
    -

    ${issue.repository.full_name} on ${createdAt}

    -

    ${issue.title} #${index}

    -

    ${body}

    -${labels} -
    ` - }); - }); -} - -function initIssuePopup() { - $('.ref-issue').each(function () { - const href = $(this).attr('href').split('/'); - const index = href.pop(); - href.pop(); // issues - const repo = href.pop(); - const owner = href.pop(); - issuePopup(owner, repo, index, $(this)); - }); -} - $(document).ready(() => { csrf = $('meta[name=_csrf]').attr('content'); suburl = $('meta[name=_suburl]').attr('content'); @@ -2622,7 +2557,6 @@ $(document).ready(() => { initPullRequestReview(); initRepoStatusChecker(); initTemplateSearch(); - initIssuePopup(); // Repo clone url. if ($('#repo-clone-url').length > 0) { From 9efe7e0b81ef9193108d7404b6049a074484037b Mon Sep 17 00:00:00 2001 From: jolheiser Date: Fri, 17 Jan 2020 11:16:44 -0600 Subject: [PATCH 12/13] Move JS to features and fix module Signed-off-by: jolheiser --- templates/pwa/serviceworker_js.tmpl | 1 - web_src/js/{ => features}/contextPopup.js | 17 +++++------------ web_src/js/index.js | 3 ++- 3 files changed, 7 insertions(+), 14 deletions(-) rename web_src/js/{ => features}/contextPopup.js (83%) diff --git a/templates/pwa/serviceworker_js.tmpl b/templates/pwa/serviceworker_js.tmpl index 8ace0c094905a..9595d8f267b0a 100644 --- a/templates/pwa/serviceworker_js.tmpl +++ b/templates/pwa/serviceworker_js.tmpl @@ -7,7 +7,6 @@ var urlsToCache = [ '{{StaticUrlPrefix}}/vendor/plugins/fomantic/semantic.min.js?v={{MD5 AppVer}}', '{{StaticUrlPrefix}}/js/index.js?v={{MD5 AppVer}}', '{{StaticUrlPrefix}}/js/swagger.js?v={{MD5 AppVer}}', - '{{StaticUrlPrefix}}/js/contextPopup.js?v={{MD5 AppVer}}', '{{StaticUrlPrefix}}/js/gitgraph.js?v={{MD5 AppVer}}', '{{StaticUrlPrefix}}/vendor/plugins/clipboard/clipboard.min.js', '{{StaticUrlPrefix}}/vendor/plugins/vue/vue.min.js', diff --git a/web_src/js/contextPopup.js b/web_src/js/features/contextPopup.js similarity index 83% rename from web_src/js/contextPopup.js rename to web_src/js/features/contextPopup.js index b9165ef53635a..3df601bb6c0c9 100644 --- a/web_src/js/contextPopup.js +++ b/web_src/js/features/contextPopup.js @@ -1,21 +1,14 @@ -let suburl; - -window.addEventListener('load', () => { - suburl = $('meta[name=_suburl]').attr('content'); +export default function initContextPopups(suburl) { const refIssues = $('.ref-issue'); if (!refIssues.length) return; refIssues.each(function () { - const href = $(this).attr('href').split('/'); - const index = href.pop(); - href.pop(); // issues - const repo = href.pop(); - const owner = href.pop(); - issuePopup(owner, repo, index, $(this)); + const [index, _issues, repo, owner] = $(this).attr('href').split('/').reverse(); + issuePopup(suburl, owner, repo, index, $(this)); }); -}); +} -function issuePopup(owner, repo, index, $element) { +function issuePopup(suburl, owner, repo, index, $element) { $.get(`${suburl}/api/v1/repos/${owner}/${repo}/issues/${index}`, (issue) => { const createdAt = new Date(issue.created_at).toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' }); diff --git a/web_src/js/index.js b/web_src/js/index.js index 7f1671eef6df8..3bd4d56f8ddf9 100644 --- a/web_src/js/index.js +++ b/web_src/js/index.js @@ -5,7 +5,7 @@ import './publicPath.js'; import './gitGraphLoader.js'; import './semanticDropdown.js'; -import './contextPopup.js'; +import initContextPopups from './features/contextPopup'; function htmlEncode(text) { return jQuery('
    ').text(text).html(); @@ -2557,6 +2557,7 @@ $(document).ready(() => { initPullRequestReview(); initRepoStatusChecker(); initTemplateSearch(); + initContextPopups(suburl); // Repo clone url. if ($('#repo-clone-url').length > 0) { From bbdc8babc80020fb60b1e637b8a70130f12f5dc6 Mon Sep 17 00:00:00 2001 From: John Olheiser <42128690+jolheiser@users.noreply.github.com> Date: Fri, 17 Jan 2020 11:54:46 -0600 Subject: [PATCH 13/13] Remove query-string and hash Co-Authored-By: silverwind --- web_src/js/features/contextPopup.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_src/js/features/contextPopup.js b/web_src/js/features/contextPopup.js index 3df601bb6c0c9..90b8493666089 100644 --- a/web_src/js/features/contextPopup.js +++ b/web_src/js/features/contextPopup.js @@ -3,7 +3,7 @@ export default function initContextPopups(suburl) { if (!refIssues.length) return; refIssues.each(function () { - const [index, _issues, repo, owner] = $(this).attr('href').split('/').reverse(); + const [index, _issues, repo, owner] = $(this).attr('href').replace(/[#?].*$/, '').split('/').reverse(); issuePopup(suburl, owner, repo, index, $(this)); }); }