Commit b9abf938 authored by connorshea's avatar connorshea

Wrap images in discussions and wikis with a link to the image source using ImageLinkFilter.

Resolves #14411.

See merge request !3464
parent 67136007
Please view this file on the master branch, on stable branches it's out of date. Please view this file on the master branch, on stable branches it's out of date.
v 8.7.0 (unreleased) v 8.7.0 (unreleased)
- All images in discussions and wikis now link to their source files !3464 (Connor Shea).
- Improved Markdown rendering performance !3389 (Yorick Peterse) - Improved Markdown rendering performance !3389 (Yorick Peterse)
- Don't attempt to look up an avatar in repo if repo directory does not exist (Stan hu) - Don't attempt to look up an avatar in repo if repo directory does not exist (Stan hu)
- Preserve time notes/comments have been updated at when moving issue - Preserve time notes/comments have been updated at when moving issue
......
...@@ -138,6 +138,12 @@ ...@@ -138,6 +138,12 @@
} }
} }
a.no-attachment-icon {
&:before {
display: none;
}
}
/* Link to current header. */ /* Link to current header. */
h1, h2, h3, h4, h5, h6 { h1, h2, h3, h4, h5, h6 {
position: relative; position: relative;
......
...@@ -85,7 +85,7 @@ class Spinach::Features::ProjectWiki < Spinach::FeatureSteps ...@@ -85,7 +85,7 @@ class Spinach::Features::ProjectWiki < Spinach::FeatureSteps
end end
step 'I have an existing Wiki page with images linked on page' do step 'I have an existing Wiki page with images linked on page' do
wiki.create_page("pictures", "Look at this [image](image.jpg)\n\n ![image](image.jpg)", :markdown, "first commit") wiki.create_page("pictures", "Look at this [image](image.jpg)\n\n ![alt text](image.jpg)", :markdown, "first commit")
@wiki_page = wiki.find_page("pictures") @wiki_page = wiki.find_page("pictures")
end end
......
module Banzai
module Filter
# HTML filter that wraps links around inline images.
class ImageLinkFilter < HTML::Pipeline::Filter
# Find every image that isn't already wrapped in an `a` tag, create
# a new node (a link to the image source), copy the image as a child
# of the anchor, and then replace the img with the link-wrapped version.
def call
doc.xpath('descendant-or-self::img[not(ancestor::a)]').each do |img|
link = doc.document.create_element(
'a',
class: 'no-attachment-icon',
href: img['src'],
target: '_blank'
)
link.children = img.clone
img.replace(link)
end
doc
end
end
end
end
...@@ -7,6 +7,7 @@ module Banzai ...@@ -7,6 +7,7 @@ module Banzai
Filter::SanitizationFilter, Filter::SanitizationFilter,
Filter::UploadLinkFilter, Filter::UploadLinkFilter,
Filter::ImageLinkFilter,
Filter::EmojiFilter, Filter::EmojiFilter,
Filter::TableOfContentsFilter, Filter::TableOfContentsFilter,
Filter::AutolinkFilter, Filter::AutolinkFilter,
......
...@@ -61,7 +61,7 @@ describe "User Feed", feature: true do ...@@ -61,7 +61,7 @@ describe "User Feed", feature: true do
end end
it 'should have XHTML summaries in merge request descriptions' do it 'should have XHTML summaries in merge request descriptions' do
expect(body).to match /Here is the fix: <img[^>]*\/>/ expect(body).to match /Here is the fix: <a[^>]*><img[^>]*\/><\/a>/
end end
end end
end end
......
require 'spec_helper'
describe Banzai::Filter::ImageLinkFilter, lib: true do
include FilterSpecHelper
def image(path)
%(<img src="#{path}" />)
end
it 'wraps the image with a link to the image src' do
doc = filter(image('/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg'))
expect(doc.at_css('img')['src']).to eq doc.at_css('a')['href']
end
it 'does not wrap a duplicate link' do
exp = act = %q(<a href="/whatever">#{image('/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg')}</a>)
expect(filter(act).to_html).to eq exp
end
it 'works with external images' do
doc = filter(image('https://i.imgur.com/DfssX9C.jpg'))
expect(doc.at_css('img')['src']).to eq doc.at_css('a')['href']
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment