From b9abf938edf52e762d320b1eb8732155e23d7b72 Mon Sep 17 00:00:00 2001 From: connorshea Date: Wed, 30 Mar 2016 16:03:49 -0600 Subject: Wrap images in discussions and wikis with a link to the image source using ImageLinkFilter. Resolves #14411. See merge request !3464 --- CHANGELOG | 1 + app/assets/stylesheets/framework/typography.scss | 6 ++++++ features/steps/project/wiki.rb | 2 +- lib/banzai/filter/image_link_filter.rb | 27 ++++++++++++++++++++++++ lib/banzai/pipeline/gfm_pipeline.rb | 1 + spec/features/atom/users_spec.rb | 2 +- spec/lib/banzai/filter/image_link_filter_spec.rb | 24 +++++++++++++++++++++ 7 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 lib/banzai/filter/image_link_filter.rb create mode 100644 spec/lib/banzai/filter/image_link_filter_spec.rb diff --git a/CHANGELOG b/CHANGELOG index f72bb670ece..39239bebcfb 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ Please view this file on the master branch, on stable branches it's out of date. 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) - 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 diff --git a/app/assets/stylesheets/framework/typography.scss b/app/assets/stylesheets/framework/typography.scss index b1886fbe67b..c3c7bc9fdbe 100644 --- a/app/assets/stylesheets/framework/typography.scss +++ b/app/assets/stylesheets/framework/typography.scss @@ -138,6 +138,12 @@ } } + a.no-attachment-icon { + &:before { + display: none; + } + } + /* Link to current header. */ h1, h2, h3, h4, h5, h6 { position: relative; diff --git a/features/steps/project/wiki.rb b/features/steps/project/wiki.rb index 223b7277b51..9f6aed1c5b9 100644 --- a/features/steps/project/wiki.rb +++ b/features/steps/project/wiki.rb @@ -85,7 +85,7 @@ class Spinach::Features::ProjectWiki < Spinach::FeatureSteps end 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") end diff --git a/lib/banzai/filter/image_link_filter.rb b/lib/banzai/filter/image_link_filter.rb new file mode 100644 index 00000000000..ccd106860bd --- /dev/null +++ b/lib/banzai/filter/image_link_filter.rb @@ -0,0 +1,27 @@ +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 diff --git a/lib/banzai/pipeline/gfm_pipeline.rb b/lib/banzai/pipeline/gfm_pipeline.rb index 8cd4b50e65a..ed3cfd6b023 100644 --- a/lib/banzai/pipeline/gfm_pipeline.rb +++ b/lib/banzai/pipeline/gfm_pipeline.rb @@ -7,6 +7,7 @@ module Banzai Filter::SanitizationFilter, Filter::UploadLinkFilter, + Filter::ImageLinkFilter, Filter::EmojiFilter, Filter::TableOfContentsFilter, Filter::AutolinkFilter, diff --git a/spec/features/atom/users_spec.rb b/spec/features/atom/users_spec.rb index dc41be8246f..de6aed74fb4 100644 --- a/spec/features/atom/users_spec.rb +++ b/spec/features/atom/users_spec.rb @@ -61,7 +61,7 @@ describe "User Feed", feature: true do end it 'should have XHTML summaries in merge request descriptions' do - expect(body).to match /Here is the fix: ]*\/>/ + expect(body).to match /Here is the fix: ]*>]*\/><\/a>/ end end end diff --git a/spec/lib/banzai/filter/image_link_filter_spec.rb b/spec/lib/banzai/filter/image_link_filter_spec.rb new file mode 100644 index 00000000000..dd5594750c8 --- /dev/null +++ b/spec/lib/banzai/filter/image_link_filter_spec.rb @@ -0,0 +1,24 @@ +require 'spec_helper' + +describe Banzai::Filter::ImageLinkFilter, lib: true do + include FilterSpecHelper + + def image(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(#{image('/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg')}) + 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 -- cgit v1.2.1