@@ -211,6 +211,40 @@ func RenderCommitMessage(
211
211
return ctx .postProcess (rawHTML )
212
212
}
213
213
214
+ var commitMessageSubjectProcessors = []processor {
215
+ fullIssuePatternProcessor ,
216
+ fullSha1PatternProcessor ,
217
+ linkProcessor ,
218
+ mentionProcessor ,
219
+ issueIndexPatternProcessor ,
220
+ crossReferenceIssueIndexPatternProcessor ,
221
+ sha1CurrentPatternProcessor ,
222
+ }
223
+
224
+ // RenderCommitMessageSubject will use the same logic as PostProcess and
225
+ // RenderCommitMessage, but will disable the shortLinkProcessor and
226
+ // emailAddressProcessor, will add a defaultLinkProcessor if defaultLink is set,
227
+ // which changes every text node into a link to the passed default link.
228
+ func RenderCommitMessageSubject (
229
+ rawHTML []byte ,
230
+ urlPrefix , defaultLink string ,
231
+ metas map [string ]string ,
232
+ ) ([]byte , error ) {
233
+ ctx := & postProcessCtx {
234
+ metas : metas ,
235
+ urlPrefix : urlPrefix ,
236
+ procs : commitMessageSubjectProcessors ,
237
+ }
238
+ if defaultLink != "" {
239
+ // we don't have to fear data races, because being
240
+ // commitMessageSubjectProcessors of fixed len and cap, every time we
241
+ // append something to it the slice is realloc+copied, so append always
242
+ // generates the slice ex-novo.
243
+ ctx .procs = append (ctx .procs , genDefaultLinkProcessor (defaultLink ))
244
+ }
245
+ return ctx .postProcess (rawHTML )
246
+ }
247
+
214
248
// RenderDescriptionHTML will use similar logic as PostProcess, but will
215
249
// use a single special linkProcessor.
216
250
func RenderDescriptionHTML (
@@ -296,12 +330,17 @@ func (ctx *postProcessCtx) textNode(node *html.Node) {
296
330
}
297
331
}
298
332
299
- func createLink (href , content string ) * html.Node {
333
+ func createLink (href , content , class string ) * html.Node {
300
334
a := & html.Node {
301
335
Type : html .ElementNode ,
302
336
Data : atom .A .String (),
303
337
Attr : []html.Attribute {{Key : "href" , Val : href }},
304
338
}
339
+
340
+ if class != "" {
341
+ a .Attr = append (a .Attr , html.Attribute {Key : "class" , Val : class })
342
+ }
343
+
305
344
text := & html.Node {
306
345
Type : html .TextNode ,
307
346
Data : content ,
@@ -311,12 +350,17 @@ func createLink(href, content string) *html.Node {
311
350
return a
312
351
}
313
352
314
- func createCodeLink (href , content string ) * html.Node {
353
+ func createCodeLink (href , content , class string ) * html.Node {
315
354
a := & html.Node {
316
355
Type : html .ElementNode ,
317
356
Data : atom .A .String (),
318
357
Attr : []html.Attribute {{Key : "href" , Val : href }},
319
358
}
359
+
360
+ if class != "" {
361
+ a .Attr = append (a .Attr , html.Attribute {Key : "class" , Val : class })
362
+ }
363
+
320
364
text := & html.Node {
321
365
Type : html .TextNode ,
322
366
Data : content ,
@@ -364,7 +408,7 @@ func mentionProcessor(_ *postProcessCtx, node *html.Node) {
364
408
}
365
409
// Replace the mention with a link to the specified user.
366
410
mention := node .Data [m [2 ]:m [3 ]]
367
- replaceContent (node , m [2 ], m [3 ], createLink (util .URLJoin (setting .AppURL , mention [1 :]), mention ))
411
+ replaceContent (node , m [2 ], m [3 ], createLink (util .URLJoin (setting .AppURL , mention [1 :]), mention , "mention" ))
368
412
}
369
413
370
414
func shortLinkProcessor (ctx * postProcessCtx , node * html.Node ) {
@@ -541,11 +585,11 @@ func fullIssuePatternProcessor(ctx *postProcessCtx, node *html.Node) {
541
585
if matchOrg == ctx .metas ["user" ] && matchRepo == ctx .metas ["repo" ] {
542
586
// TODO if m[4]:m[5] is not nil, then link is to a comment,
543
587
// and we should indicate that in the text somehow
544
- replaceContent (node , m [0 ], m [1 ], createLink (link , id ))
588
+ replaceContent (node , m [0 ], m [1 ], createLink (link , id , "issue" ))
545
589
546
590
} else {
547
591
orgRepoID := matchOrg + "/" + matchRepo + id
548
- replaceContent (node , m [0 ], m [1 ], createLink (link , orgRepoID ))
592
+ replaceContent (node , m [0 ], m [1 ], createLink (link , orgRepoID , "issue" ))
549
593
}
550
594
}
551
595
@@ -573,9 +617,9 @@ func issueIndexPatternProcessor(ctx *postProcessCtx, node *html.Node) {
573
617
} else {
574
618
ctx .metas ["index" ] = id [1 :]
575
619
}
576
- link = createLink (com .Expand (ctx .metas ["format" ], ctx .metas ), id )
620
+ link = createLink (com .Expand (ctx .metas ["format" ], ctx .metas ), id , "issue" )
577
621
} else {
578
- link = createLink (util .URLJoin (setting .AppURL , ctx .metas ["user" ], ctx .metas ["repo" ], "issues" , id [1 :]), id )
622
+ link = createLink (util .URLJoin (setting .AppURL , ctx .metas ["user" ], ctx .metas ["repo" ], "issues" , id [1 :]), id , "issue" )
579
623
}
580
624
replaceContent (node , match [2 ], match [3 ], link )
581
625
}
@@ -591,7 +635,7 @@ func crossReferenceIssueIndexPatternProcessor(ctx *postProcessCtx, node *html.No
591
635
repo , issue := parts [0 ], parts [1 ]
592
636
593
637
replaceContent (node , m [2 ], m [3 ],
594
- createLink (util .URLJoin (setting .AppURL , repo , "issues" , issue ), ref ))
638
+ createLink (util .URLJoin (setting .AppURL , repo , "issues" , issue ), ref , issue ))
595
639
}
596
640
597
641
// fullSha1PatternProcessor renders SHA containing URLs
@@ -642,7 +686,7 @@ func fullSha1PatternProcessor(ctx *postProcessCtx, node *html.Node) {
642
686
text += " (" + hash + ")"
643
687
}
644
688
645
- replaceContent (node , start , end , createCodeLink (urlFull , text ))
689
+ replaceContent (node , start , end , createCodeLink (urlFull , text , "commit" ))
646
690
}
647
691
648
692
// sha1CurrentPatternProcessor renders SHA1 strings to corresponding links that
@@ -672,7 +716,7 @@ func sha1CurrentPatternProcessor(ctx *postProcessCtx, node *html.Node) {
672
716
}
673
717
674
718
replaceContent (node , m [2 ], m [3 ],
675
- createCodeLink (util .URLJoin (setting .AppURL , ctx .metas ["user" ], ctx .metas ["repo" ], "commit" , hash ), base .ShortSha (hash )))
719
+ createCodeLink (util .URLJoin (setting .AppURL , ctx .metas ["user" ], ctx .metas ["repo" ], "commit" , hash ), base .ShortSha (hash ), "commit" ))
676
720
}
677
721
678
722
// emailAddressProcessor replaces raw email addresses with a mailto: link.
@@ -682,7 +726,7 @@ func emailAddressProcessor(ctx *postProcessCtx, node *html.Node) {
682
726
return
683
727
}
684
728
mail := node .Data [m [2 ]:m [3 ]]
685
- replaceContent (node , m [2 ], m [3 ], createLink ("mailto:" + mail , mail ))
729
+ replaceContent (node , m [2 ], m [3 ], createLink ("mailto:" + mail , mail , "mailto" ))
686
730
}
687
731
688
732
// linkProcessor creates links for any HTTP or HTTPS URL not captured by
@@ -693,7 +737,7 @@ func linkProcessor(ctx *postProcessCtx, node *html.Node) {
693
737
return
694
738
}
695
739
uri := node .Data [m [0 ]:m [1 ]]
696
- replaceContent (node , m [0 ], m [1 ], createLink (uri , uri ))
740
+ replaceContent (node , m [0 ], m [1 ], createLink (uri , uri , "link" ))
697
741
}
698
742
699
743
func genDefaultLinkProcessor (defaultLink string ) processor {
@@ -707,7 +751,10 @@ func genDefaultLinkProcessor(defaultLink string) processor {
707
751
node .Type = html .ElementNode
708
752
node .Data = "a"
709
753
node .DataAtom = atom .A
710
- node .Attr = []html.Attribute {{Key : "href" , Val : defaultLink }}
754
+ node .Attr = []html.Attribute {
755
+ {Key : "href" , Val : defaultLink },
756
+ {Key : "class" , Val : "default-link" },
757
+ }
711
758
node .FirstChild , node .LastChild = ch , ch
712
759
}
713
760
}
0 commit comments