Remove visitLinksForShortLinks features (#6257)

The visitLinksForShortLinks feature would look inside of an <a> tag and
run shortLinkProcessorFull on any text, which attempts to create links
out of potential 'short links' like [[test]] [[link|example]] etc...
This makes no sense because you can't have nested links within an <a>
tag. Specifically, the html5 standard says <a> tags can't include
interactive content if they contain the href attribute:

 http://w3c.github.io/html/single-page.html#the-a-element

And also defines an <a> element with a href attribute as interactive:

 http://w3c.github.io/html/single-page.html#interactive-content

Therefore you can't really put a link inside of another link. In
practice none of this works anyways since browsers won't render it, it
would probably be broken if they tried, and it is causing a bug
(#4946). No current tests rely on this behavior either.

This removes the feature and also explicitly excludes the
current visitNodeForShortLinks from looking in <a> tags.
tokarchuk/v1.17
mrsdizzie 6 years ago committed by techknowlogick
parent ad86b843e1
commit 020075e12f
  1. 11
      modules/markup/html.go
  2. 4
      modules/markup/html_test.go

@ -171,11 +171,6 @@ type postProcessCtx struct {
// processors used by this context. // processors used by this context.
procs []processor procs []processor
// if set to true, when an <a> is found, instead of just returning during
// visitNode, it will recursively visit the node exclusively running
// shortLinkProcessorFull with true.
visitLinksForShortLinks bool
} }
// PostProcess does the final required transformations to the passed raw HTML // PostProcess does the final required transformations to the passed raw HTML
@ -195,7 +190,6 @@ func PostProcess(
urlPrefix: urlPrefix, urlPrefix: urlPrefix,
isWikiMarkdown: isWikiMarkdown, isWikiMarkdown: isWikiMarkdown,
procs: defaultProcessors, procs: defaultProcessors,
visitLinksForShortLinks: true,
} }
return ctx.postProcess(rawHTML) return ctx.postProcess(rawHTML)
} }
@ -285,9 +279,6 @@ func (ctx *postProcessCtx) visitNode(node *html.Node) {
ctx.textNode(node) ctx.textNode(node)
case html.ElementNode: case html.ElementNode:
if node.Data == "a" || node.Data == "code" || node.Data == "pre" { if node.Data == "a" || node.Data == "code" || node.Data == "pre" {
if node.Data == "a" && ctx.visitLinksForShortLinks {
ctx.visitNodeForShortLinks(node)
}
return return
} }
for n := node.FirstChild; n != nil; n = n.NextSibling { for n := node.FirstChild; n != nil; n = n.NextSibling {
@ -302,7 +293,7 @@ func (ctx *postProcessCtx) visitNodeForShortLinks(node *html.Node) {
case html.TextNode: case html.TextNode:
shortLinkProcessorFull(ctx, node, true) shortLinkProcessorFull(ctx, node, true)
case html.ElementNode: case html.ElementNode:
if node.Data == "code" || node.Data == "pre" { if node.Data == "code" || node.Data == "pre" || node.Data == "a" {
return return
} }
for n := node.FirstChild; n != nil; n = n.NextSibling { for n := node.FirstChild; n != nil; n = n.NextSibling {

@ -222,4 +222,8 @@ func TestRender_ShortLinks(t *testing.T) {
"[[some/path/Link #.jpg]]", "[[some/path/Link #.jpg]]",
`<p><a href="`+notencodedImgurl+`" rel="nofollow"><img src="`+notencodedImgurl+`"/></a></p>`, `<p><a href="`+notencodedImgurl+`" rel="nofollow"><img src="`+notencodedImgurl+`"/></a></p>`,
`<p><a href="`+notencodedImgurlWiki+`" rel="nofollow"><img src="`+notencodedImgurlWiki+`"/></a></p>`) `<p><a href="`+notencodedImgurlWiki+`" rel="nofollow"><img src="`+notencodedImgurlWiki+`"/></a></p>`)
test(
"<p><a href=\"https://example.org\">[[foobar]]</a></p>",
`<p><a href="https://example.org" rel="nofollow">[[foobar]]</a></p>`,
`<p><a href="https://example.org" rel="nofollow">[[foobar]]</a></p>`)
} }

Loading…
Cancel
Save