mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 08:30:25 +08:00 
			
		
		
		
	Fixed emoji alias not parsed in links (#16221)
* Do not skip links. * Restrict text in links to emojis. Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com> Co-authored-by: zeripath <art27@cantab.net>
This commit is contained in:
		@@ -322,7 +322,7 @@ func postProcess(ctx *RenderContext, procs []processor, input io.Reader, output
 | 
				
			|||||||
		node = node.FirstChild
 | 
							node = node.FirstChild
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	visitNode(ctx, procs, node, true)
 | 
						visitNode(ctx, procs, procs, node)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	newNodes := make([]*html.Node, 0, 5)
 | 
						newNodes := make([]*html.Node, 0, 5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -354,7 +354,7 @@ func postProcess(ctx *RenderContext, procs []processor, input io.Reader, output
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func visitNode(ctx *RenderContext, procs []processor, node *html.Node, visitText bool) {
 | 
					func visitNode(ctx *RenderContext, procs, textProcs []processor, node *html.Node) {
 | 
				
			||||||
	// Add user-content- to IDs if they don't already have them
 | 
						// Add user-content- to IDs if they don't already have them
 | 
				
			||||||
	for idx, attr := range node.Attr {
 | 
						for idx, attr := range node.Attr {
 | 
				
			||||||
		if attr.Key == "id" && !(strings.HasPrefix(attr.Val, "user-content-") || blackfridayExtRegex.MatchString(attr.Val)) {
 | 
							if attr.Key == "id" && !(strings.HasPrefix(attr.Val, "user-content-") || blackfridayExtRegex.MatchString(attr.Val)) {
 | 
				
			||||||
@@ -362,16 +362,14 @@ func visitNode(ctx *RenderContext, procs []processor, node *html.Node, visitText
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if attr.Key == "class" && attr.Val == "emoji" {
 | 
							if attr.Key == "class" && attr.Val == "emoji" {
 | 
				
			||||||
			visitText = false
 | 
								textProcs = nil
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// We ignore code, pre and already generated links.
 | 
						// We ignore code and pre.
 | 
				
			||||||
	switch node.Type {
 | 
						switch node.Type {
 | 
				
			||||||
	case html.TextNode:
 | 
						case html.TextNode:
 | 
				
			||||||
		if visitText {
 | 
							textNode(ctx, textProcs, node)
 | 
				
			||||||
			textNode(ctx, procs, node)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	case html.ElementNode:
 | 
						case html.ElementNode:
 | 
				
			||||||
		if node.Data == "img" {
 | 
							if node.Data == "img" {
 | 
				
			||||||
			for i, attr := range node.Attr {
 | 
								for i, attr := range node.Attr {
 | 
				
			||||||
@@ -390,7 +388,8 @@ func visitNode(ctx *RenderContext, procs []processor, node *html.Node, visitText
 | 
				
			|||||||
				node.Attr[i] = attr
 | 
									node.Attr[i] = attr
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} else if node.Data == "a" {
 | 
							} else if node.Data == "a" {
 | 
				
			||||||
			visitText = false
 | 
								// Restrict text in links to emojis
 | 
				
			||||||
 | 
								textProcs = emojiProcessors
 | 
				
			||||||
		} else if node.Data == "code" || node.Data == "pre" {
 | 
							} else if node.Data == "code" || node.Data == "pre" {
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		} else if node.Data == "i" {
 | 
							} else if node.Data == "i" {
 | 
				
			||||||
@@ -416,7 +415,7 @@ func visitNode(ctx *RenderContext, procs []processor, node *html.Node, visitText
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		for n := node.FirstChild; n != nil; n = n.NextSibling {
 | 
							for n := node.FirstChild; n != nil; n = n.NextSibling {
 | 
				
			||||||
			visitNode(ctx, procs, n, visitText)
 | 
								visitNode(ctx, procs, textProcs, n)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// ignore everything else
 | 
						// ignore everything else
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -391,5 +391,13 @@ func TestRenderSiblingImages_Issue12925(t *testing.T) {
 | 
				
			|||||||
	res, err := RenderRawString(&markup.RenderContext{}, testcase)
 | 
						res, err := RenderRawString(&markup.RenderContext{}, testcase)
 | 
				
			||||||
	assert.NoError(t, err)
 | 
						assert.NoError(t, err)
 | 
				
			||||||
	assert.Equal(t, expected, res)
 | 
						assert.Equal(t, expected, res)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestRenderEmojiInLinks_Issue12331(t *testing.T) {
 | 
				
			||||||
 | 
						testcase := `[Link with emoji :moon: in text](https://gitea.io)`
 | 
				
			||||||
 | 
						expected := `<p><a href="https://gitea.io" rel="nofollow">Link with emoji <span class="emoji" aria-label="waxing gibbous moon">🌔</span> in text</a></p>
 | 
				
			||||||
 | 
					`
 | 
				
			||||||
 | 
						res, err := RenderString(&markup.RenderContext{}, testcase)
 | 
				
			||||||
 | 
						assert.NoError(t, err)
 | 
				
			||||||
 | 
						assert.Equal(t, expected, res)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user