mirror of
https://github.com/go-gitea/gitea.git
synced 2025-06-24 15:23:22 +00:00
parent
0990eb44ce
commit
81adb01713
@ -63,8 +63,11 @@ func processNodeA(ctx *RenderContext, node *html.Node) {
|
||||
|
||||
func visitNodeImg(ctx *RenderContext, img *html.Node) (next *html.Node) {
|
||||
next = img.NextSibling
|
||||
attrSrc, hasLazy := "", false
|
||||
for i, imgAttr := range img.Attr {
|
||||
hasLazy = hasLazy || imgAttr.Key == "loading" && imgAttr.Val == "lazy"
|
||||
if imgAttr.Key != "src" {
|
||||
attrSrc = imgAttr.Val
|
||||
continue
|
||||
}
|
||||
|
||||
@ -72,8 +75,8 @@ func visitNodeImg(ctx *RenderContext, img *html.Node) (next *html.Node) {
|
||||
isLinkable := imgSrcOrigin != "" && !strings.HasPrefix(imgSrcOrigin, "data:")
|
||||
|
||||
// By default, the "<img>" tag should also be clickable,
|
||||
// because frontend use `<img>` to paste the re-scaled image into the markdown,
|
||||
// so it must match the default markdown image behavior.
|
||||
// because frontend uses `<img>` to paste the re-scaled image into the Markdown,
|
||||
// so it must match the default Markdown image behavior.
|
||||
cnt := 0
|
||||
for p := img.Parent; isLinkable && p != nil && cnt < 2; p = p.Parent {
|
||||
if hasParentAnchor := p.Type == html.ElementNode && p.Data == "a"; hasParentAnchor {
|
||||
@ -98,6 +101,9 @@ func visitNodeImg(ctx *RenderContext, img *html.Node) (next *html.Node) {
|
||||
imgAttr.Val = camoHandleLink(imgAttr.Val)
|
||||
img.Attr[i] = imgAttr
|
||||
}
|
||||
if !RenderBehaviorForTesting.DisableAdditionalAttributes && !hasLazy && !strings.HasPrefix(attrSrc, "data:") {
|
||||
img.Attr = append(img.Attr, html.Attribute{Key: "loading", Val: "lazy"})
|
||||
}
|
||||
return next
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@ func TestRender_StandardLinks(t *testing.T) {
|
||||
func TestRender_Images(t *testing.T) {
|
||||
setting.AppURL = AppURL
|
||||
|
||||
test := func(input, expected string) {
|
||||
render := func(input, expected string) {
|
||||
buffer, err := markdown.RenderString(markup.NewTestRenderContext(FullURL), input)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(buffer)))
|
||||
@ -59,27 +59,32 @@ func TestRender_Images(t *testing.T) {
|
||||
result := util.URLJoin(FullURL, url)
|
||||
// hint: With Markdown v2.5.2, there is a new syntax: [link](URL){:target="_blank"} , but we do not support it now
|
||||
|
||||
test(
|
||||
render(
|
||||
"",
|
||||
`<p><a href="`+result+`" target="_blank" rel="nofollow noopener"><img src="`+result+`" alt="`+title+`"/></a></p>`)
|
||||
|
||||
test(
|
||||
render(
|
||||
"[["+title+"|"+url+"]]",
|
||||
`<p><a href="`+result+`" rel="nofollow"><img src="`+result+`" title="`+title+`" alt="`+title+`"/></a></p>`)
|
||||
test(
|
||||
render(
|
||||
"[]("+href+")",
|
||||
`<p><a href="`+href+`" rel="nofollow"><img src="`+result+`" alt="`+title+`"/></a></p>`)
|
||||
|
||||
test(
|
||||
render(
|
||||
"",
|
||||
`<p><a href="`+result+`" target="_blank" rel="nofollow noopener"><img src="`+result+`" alt="`+title+`"/></a></p>`)
|
||||
|
||||
test(
|
||||
render(
|
||||
"[["+title+"|"+url+"]]",
|
||||
`<p><a href="`+result+`" rel="nofollow"><img src="`+result+`" title="`+title+`" alt="`+title+`"/></a></p>`)
|
||||
test(
|
||||
render(
|
||||
"[]("+href+")",
|
||||
`<p><a href="`+href+`" rel="nofollow"><img src="`+result+`" alt="`+title+`"/></a></p>`)
|
||||
|
||||
defer test.MockVariableValue(&markup.RenderBehaviorForTesting.DisableAdditionalAttributes, false)()
|
||||
render(
|
||||
"<a><img src='a.jpg'></a>", // by the way, empty "a" tag will be removed
|
||||
`<p dir="auto"><img src="http://localhost:3000/user13/repo11/a.jpg" loading="lazy"/></p>`)
|
||||
}
|
||||
|
||||
func TestTotal_RenderString(t *testing.T) {
|
||||
|
@ -52,6 +52,8 @@ func (st *Sanitizer) createDefaultPolicy() *bluemonday.Policy {
|
||||
|
||||
policy.AllowAttrs("src", "autoplay", "controls").OnElements("video")
|
||||
|
||||
policy.AllowAttrs("loading").OnElements("img")
|
||||
|
||||
// Allow generally safe attributes (reference: https://github.com/jch/html-pipeline)
|
||||
generalSafeAttrs := []string{
|
||||
"abbr", "accept", "accept-charset",
|
||||
|
@ -528,7 +528,7 @@ func TestEmbedBase64Images(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
mailBody := msgs[0].Body
|
||||
assert.Regexp(t, `MSG-BEFORE <a[^>]+><img src="data:image/png;base64,iVBORw0KGgo="/></a> MSG-AFTER`, mailBody)
|
||||
assert.Regexp(t, `MSG-BEFORE <a[^>]+><img src="data:image/png;base64,iVBORw0KGgo=".*/></a> MSG-AFTER`, mailBody)
|
||||
})
|
||||
|
||||
t.Run("EmbedInstanceImageSkipExternalImage", func(t *testing.T) {
|
||||
|
@ -4,7 +4,7 @@
|
||||
{{if $attachments}}
|
||||
<div class="card-attachment-images">
|
||||
{{range $attachments}}
|
||||
<img src="{{.DownloadURL}}" alt="{{.Name}}" />
|
||||
<img loading="lazy" src="{{.DownloadURL}}" alt="{{.Name}}" />
|
||||
{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
|
@ -31,7 +31,7 @@
|
||||
{{if FilenameIsImage .Name}}
|
||||
{{if not (StringUtils.Contains (StringUtils.ToString $.RenderedContent) .UUID)}}
|
||||
<a target="_blank" rel="noopener noreferrer" href="{{.DownloadURL}}">
|
||||
<img alt="{{.Name}}" src="{{.DownloadURL}}" title="{{ctx.Locale.Tr "repo.issues.attachment.open_tab" .Name}}">
|
||||
<img loading="lazy" alt="{{.Name}}" src="{{.DownloadURL}}" title="{{ctx.Locale.Tr "repo.issues.attachment.open_tab" .Name}}">
|
||||
</a>
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
@ -615,7 +615,7 @@
|
||||
<div class="timeline-item-group">
|
||||
<div class="timeline-item event" id="{{.HashTag}}">
|
||||
<a class="timeline-avatar"{{if gt .Poster.ID 0}} href="{{.Poster.HomeLink}}"{{end}}>
|
||||
<img alt src="{{.Poster.AvatarLink ctx}}" width="40" height="40">
|
||||
<img loading="lazy" alt src="{{.Poster.AvatarLink ctx}}" width="40" height="40">
|
||||
</a>
|
||||
<span class="badge grey">{{svg "octicon-x" 16}}</span>
|
||||
<span class="text grey muted-links">
|
||||
|
@ -21,7 +21,7 @@
|
||||
{{else if not .IsTextFile}}
|
||||
<div class="view-raw">
|
||||
{{if .IsImageFile}}
|
||||
<img alt="{{$.RawFileLink}}" src="{{$.RawFileLink}}">
|
||||
<img loading="lazy" alt="{{$.RawFileLink}}" src="{{$.RawFileLink}}">
|
||||
{{else if .IsVideoFile}}
|
||||
<video controls src="{{$.RawFileLink}}">
|
||||
<strong>{{ctx.Locale.Tr "repo.video_not_supported_in_browser"}}</strong>
|
||||
|
@ -103,7 +103,7 @@
|
||||
<ul class="user-badges">
|
||||
{{range .Badges}}
|
||||
<li>
|
||||
<img width="64" height="64" src="{{.ImageURL}}" alt="{{.Description}}" data-tooltip-content="{{.Description}}">
|
||||
<img loading="lazy" width="64" height="64" src="{{.ImageURL}}" alt="{{.Description}}" data-tooltip-content="{{.Description}}">
|
||||
</li>
|
||||
{{end}}
|
||||
</ul>
|
||||
|
@ -91,7 +91,7 @@
|
||||
{{range $push.Commits}}
|
||||
{{$commitLink := printf "%s/commit/%s" $repoLink .Sha1}}
|
||||
<div class="flex-text-block">
|
||||
<img alt class="ui avatar" src="{{$push.AvatarLink ctx .AuthorEmail}}" title="{{.AuthorName}}" width="16" height="16">
|
||||
<img loading="lazy" alt class="ui avatar" src="{{$push.AvatarLink ctx .AuthorEmail}}" title="{{.AuthorName}}" width="16" height="16">
|
||||
<a class="ui sha label" href="{{$commitLink}}">{{ShortSha .Sha1}}</a>
|
||||
<span class="text truncate">
|
||||
{{ctx.RenderUtils.RenderCommitMessage .Message $repo}}
|
||||
|
@ -397,7 +397,7 @@ export default defineComponent({
|
||||
<div class="ui top attached header tw-flex tw-flex-1">
|
||||
<b class="ui right">#{{ index + 1 }}</b>
|
||||
<a :href="contributor.home_link">
|
||||
<img class="ui avatar tw-align-middle" height="40" width="40" :src="contributor.avatar_link" alt="">
|
||||
<img loading="lazy" class="ui avatar tw-align-middle" height="40" width="40" :src="contributor.avatar_link" alt="">
|
||||
</a>
|
||||
<div class="tw-ml-2">
|
||||
<a v-if="contributor.home_link !== ''" :href="contributor.home_link"><h4>{{ contributor.name }}</h4></a>
|
||||
|
Loading…
Reference in New Issue
Block a user