Make link last commit massages in repository home page and commit tables (#8006)
* Make link last commit massages in repository home page and commit tables * Use RenderCommitMessageLink instead surround with a * deleted __debug_bin file * Exclude email to link from latest commit title * Exclude email processor from commit table Co-Authored-By: mrsdizzie <info@mrsdizzie.com> * Add class parameter to a html element creator functions. Make links underline dashed that are not commit * fix tests * Show dashed underline when also not hovered
This commit is contained in:
parent
7eacdcf39a
commit
7e17424c7e
7 changed files with 154 additions and 38 deletions
|
@ -211,6 +211,40 @@ func RenderCommitMessage(
|
|||
return ctx.postProcess(rawHTML)
|
||||
}
|
||||
|
||||
var commitMessageSubjectProcessors = []processor{
|
||||
fullIssuePatternProcessor,
|
||||
fullSha1PatternProcessor,
|
||||
linkProcessor,
|
||||
mentionProcessor,
|
||||
issueIndexPatternProcessor,
|
||||
crossReferenceIssueIndexPatternProcessor,
|
||||
sha1CurrentPatternProcessor,
|
||||
}
|
||||
|
||||
// RenderCommitMessageSubject will use the same logic as PostProcess and
|
||||
// RenderCommitMessage, but will disable the shortLinkProcessor and
|
||||
// emailAddressProcessor, will add a defaultLinkProcessor if defaultLink is set,
|
||||
// which changes every text node into a link to the passed default link.
|
||||
func RenderCommitMessageSubject(
|
||||
rawHTML []byte,
|
||||
urlPrefix, defaultLink string,
|
||||
metas map[string]string,
|
||||
) ([]byte, error) {
|
||||
ctx := &postProcessCtx{
|
||||
metas: metas,
|
||||
urlPrefix: urlPrefix,
|
||||
procs: commitMessageSubjectProcessors,
|
||||
}
|
||||
if defaultLink != "" {
|
||||
// we don't have to fear data races, because being
|
||||
// commitMessageSubjectProcessors of fixed len and cap, every time we
|
||||
// append something to it the slice is realloc+copied, so append always
|
||||
// generates the slice ex-novo.
|
||||
ctx.procs = append(ctx.procs, genDefaultLinkProcessor(defaultLink))
|
||||
}
|
||||
return ctx.postProcess(rawHTML)
|
||||
}
|
||||
|
||||
// RenderDescriptionHTML will use similar logic as PostProcess, but will
|
||||
// use a single special linkProcessor.
|
||||
func RenderDescriptionHTML(
|
||||
|
@ -296,12 +330,17 @@ func (ctx *postProcessCtx) textNode(node *html.Node) {
|
|||
}
|
||||
}
|
||||
|
||||
func createLink(href, content string) *html.Node {
|
||||
func createLink(href, content, class string) *html.Node {
|
||||
a := &html.Node{
|
||||
Type: html.ElementNode,
|
||||
Data: atom.A.String(),
|
||||
Attr: []html.Attribute{{Key: "href", Val: href}},
|
||||
}
|
||||
|
||||
if class != "" {
|
||||
a.Attr = append(a.Attr, html.Attribute{Key: "class", Val: class})
|
||||
}
|
||||
|
||||
text := &html.Node{
|
||||
Type: html.TextNode,
|
||||
Data: content,
|
||||
|
@ -311,12 +350,17 @@ func createLink(href, content string) *html.Node {
|
|||
return a
|
||||
}
|
||||
|
||||
func createCodeLink(href, content string) *html.Node {
|
||||
func createCodeLink(href, content, class string) *html.Node {
|
||||
a := &html.Node{
|
||||
Type: html.ElementNode,
|
||||
Data: atom.A.String(),
|
||||
Attr: []html.Attribute{{Key: "href", Val: href}},
|
||||
}
|
||||
|
||||
if class != "" {
|
||||
a.Attr = append(a.Attr, html.Attribute{Key: "class", Val: class})
|
||||
}
|
||||
|
||||
text := &html.Node{
|
||||
Type: html.TextNode,
|
||||
Data: content,
|
||||
|
@ -364,7 +408,7 @@ func mentionProcessor(_ *postProcessCtx, node *html.Node) {
|
|||
}
|
||||
// Replace the mention with a link to the specified user.
|
||||
mention := node.Data[m[2]:m[3]]
|
||||
replaceContent(node, m[2], m[3], createLink(util.URLJoin(setting.AppURL, mention[1:]), mention))
|
||||
replaceContent(node, m[2], m[3], createLink(util.URLJoin(setting.AppURL, mention[1:]), mention, "mention"))
|
||||
}
|
||||
|
||||
func shortLinkProcessor(ctx *postProcessCtx, node *html.Node) {
|
||||
|
@ -541,11 +585,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))
|
||||
replaceContent(node, m[0], m[1], createLink(link, id, "issue"))
|
||||
|
||||
} else {
|
||||
orgRepoID := matchOrg + "/" + matchRepo + id
|
||||
replaceContent(node, m[0], m[1], createLink(link, orgRepoID))
|
||||
replaceContent(node, m[0], m[1], createLink(link, orgRepoID, "issue"))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -573,9 +617,9 @@ func issueIndexPatternProcessor(ctx *postProcessCtx, node *html.Node) {
|
|||
} else {
|
||||
ctx.metas["index"] = id[1:]
|
||||
}
|
||||
link = createLink(com.Expand(ctx.metas["format"], ctx.metas), id)
|
||||
link = createLink(com.Expand(ctx.metas["format"], ctx.metas), id, "issue")
|
||||
} else {
|
||||
link = createLink(util.URLJoin(setting.AppURL, ctx.metas["user"], ctx.metas["repo"], "issues", id[1:]), id)
|
||||
link = createLink(util.URLJoin(setting.AppURL, ctx.metas["user"], ctx.metas["repo"], "issues", id[1:]), id, "issue")
|
||||
}
|
||||
replaceContent(node, match[2], match[3], link)
|
||||
}
|
||||
|
@ -591,7 +635,7 @@ func crossReferenceIssueIndexPatternProcessor(ctx *postProcessCtx, node *html.No
|
|||
repo, issue := parts[0], parts[1]
|
||||
|
||||
replaceContent(node, m[2], m[3],
|
||||
createLink(util.URLJoin(setting.AppURL, repo, "issues", issue), ref))
|
||||
createLink(util.URLJoin(setting.AppURL, repo, "issues", issue), ref, issue))
|
||||
}
|
||||
|
||||
// fullSha1PatternProcessor renders SHA containing URLs
|
||||
|
@ -642,7 +686,7 @@ func fullSha1PatternProcessor(ctx *postProcessCtx, node *html.Node) {
|
|||
text += " (" + hash + ")"
|
||||
}
|
||||
|
||||
replaceContent(node, start, end, createCodeLink(urlFull, text))
|
||||
replaceContent(node, start, end, createCodeLink(urlFull, text, "commit"))
|
||||
}
|
||||
|
||||
// sha1CurrentPatternProcessor renders SHA1 strings to corresponding links that
|
||||
|
@ -672,7 +716,7 @@ func sha1CurrentPatternProcessor(ctx *postProcessCtx, node *html.Node) {
|
|||
}
|
||||
|
||||
replaceContent(node, m[2], m[3],
|
||||
createCodeLink(util.URLJoin(setting.AppURL, ctx.metas["user"], ctx.metas["repo"], "commit", hash), base.ShortSha(hash)))
|
||||
createCodeLink(util.URLJoin(setting.AppURL, ctx.metas["user"], ctx.metas["repo"], "commit", hash), base.ShortSha(hash), "commit"))
|
||||
}
|
||||
|
||||
// emailAddressProcessor replaces raw email addresses with a mailto: link.
|
||||
|
@ -682,7 +726,7 @@ func emailAddressProcessor(ctx *postProcessCtx, node *html.Node) {
|
|||
return
|
||||
}
|
||||
mail := node.Data[m[2]:m[3]]
|
||||
replaceContent(node, m[2], m[3], createLink("mailto:"+mail, mail))
|
||||
replaceContent(node, m[2], m[3], createLink("mailto:"+mail, mail, "mailto"))
|
||||
}
|
||||
|
||||
// linkProcessor creates links for any HTTP or HTTPS URL not captured by
|
||||
|
@ -693,7 +737,7 @@ func linkProcessor(ctx *postProcessCtx, node *html.Node) {
|
|||
return
|
||||
}
|
||||
uri := node.Data[m[0]:m[1]]
|
||||
replaceContent(node, m[0], m[1], createLink(uri, uri))
|
||||
replaceContent(node, m[0], m[1], createLink(uri, uri, "link"))
|
||||
}
|
||||
|
||||
func genDefaultLinkProcessor(defaultLink string) processor {
|
||||
|
@ -707,7 +751,10 @@ func genDefaultLinkProcessor(defaultLink string) processor {
|
|||
node.Type = html.ElementNode
|
||||
node.Data = "a"
|
||||
node.DataAtom = atom.A
|
||||
node.Attr = []html.Attribute{{Key: "href", Val: defaultLink}}
|
||||
node.Attr = []html.Attribute{
|
||||
{Key: "href", Val: defaultLink},
|
||||
{Key: "class", Val: "default-link"},
|
||||
}
|
||||
node.FirstChild, node.LastChild = ch, ch
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue