FEATURE: improve support for (whitelisted) SVGs as images

This commit is contained in:
Régis Hanol
2016-06-20 10:22:13 +02:00
parent 41718be67f
commit 5e2545a578
4 changed files with 43 additions and 14 deletions

View File

@@ -61,7 +61,7 @@ gem 'fast_xs'
gem 'fast_xor' gem 'fast_xor'
# while we sort out https://github.com/sdsykes/fastimage/pull/46 # while we sort out https://github.com/sdsykes/fastimage/pull/46
gem 'discourse_fastimage', '2.0.2', require: 'fastimage' gem 'discourse_fastimage', '2.0.3', require: 'fastimage'
gem 'aws-sdk', require: false gem 'aws-sdk', require: false
gem 'excon', require: false gem 'excon', require: false
gem 'unf', require: false gem 'unf', require: false

View File

@@ -73,7 +73,7 @@ GEM
diff-lcs (1.2.5) diff-lcs (1.2.5)
discourse-qunit-rails (0.0.9) discourse-qunit-rails (0.0.9)
railties railties
discourse_fastimage (2.0.2) discourse_fastimage (2.0.3)
docile (1.1.5) docile (1.1.5)
domain_name (0.5.25) domain_name (0.5.25)
unf (>= 0.0.5, < 1.0.0) unf (>= 0.0.5, < 1.0.0)
@@ -410,7 +410,7 @@ DEPENDENCIES
byebug byebug
certified certified
discourse-qunit-rails discourse-qunit-rails
discourse_fastimage (= 2.0.2) discourse_fastimage (= 2.0.3)
email_reply_trimmer (= 0.1.3) email_reply_trimmer (= 0.1.3)
ember-rails (= 0.18.5) ember-rails (= 0.18.5)
ember-source (= 1.12.2) ember-source (= 1.12.2)

View File

@@ -59,6 +59,32 @@ class Upload < ActiveRecord::Base
# list of image types that will be cropped # list of image types that will be cropped
CROPPED_IMAGE_TYPES ||= %w{avatar profile_background card_background} CROPPED_IMAGE_TYPES ||= %w{avatar profile_background card_background}
WHITELISTED_SVG_ELEMENTS ||= %w{
circle
clippath
defs
ellipse
g
line
linearGradient
path
polygon
polyline
radialGradient
rect
stop
svg
text
textpath
tref
tspan
use
}
def self.svg_whitelist_xpath
@@svg_whitelist_xpath ||= "//*[#{WHITELISTED_SVG_ELEMENTS.map { |e| "name()!='#{e}'" }.join(" and ") }]"
end
# options # options
# - content_type # - content_type
# - origin (url) # - origin (url)
@@ -68,18 +94,21 @@ class Upload < ActiveRecord::Base
DistributedMutex.synchronize("upload_#{user_id}_#{filename}") do DistributedMutex.synchronize("upload_#{user_id}_#{filename}") do
# do some work on images # do some work on images
if FileHelper.is_image?(filename) && is_actual_image?(file) if FileHelper.is_image?(filename) && is_actual_image?(file)
if filename =~ /\.svg$/i if filename[/\.svg$/i]
svg = Nokogiri::XML(file).at_css("svg") # whitelist svg elements
w = svg["width"].to_i doc = Nokogiri::XML(file)
h = svg["height"].to_i doc.xpath(svg_whitelist_xpath).remove
File.write(file.path, doc.to_s)
file.rewind
else else
# fix orientation first # fix orientation first
fix_image_orientation(file.path) if should_optimize?(file.path) fix_image_orientation(file.path) if should_optimize?(file.path)
# retrieve image info
image_info = FastImage.new(file) rescue nil
w, h = *(image_info.try(:size) || [0, 0])
end end
# retrieve image info
image_info = FastImage.new(file)
w, h = *(image_info.try(:size) || [0, 0])
# default size # default size
width, height = ImageSizer.resize(w, h) width, height = ImageSizer.resize(w, h)
@@ -107,7 +136,7 @@ class Upload < ActiveRecord::Base
end end
end end
# optimize image (except GIFs and large PNGs) # optimize image (except GIFs, SVGs and large PNGs)
if should_optimize?(file.path) if should_optimize?(file.path)
ImageOptim.new.optimize_image!(file.path) rescue nil ImageOptim.new.optimize_image!(file.path) rescue nil
# update the file size # update the file size
@@ -178,8 +207,8 @@ class Upload < ActiveRecord::Base
LARGE_PNG_SIZE ||= 3.megabytes LARGE_PNG_SIZE ||= 3.megabytes
def self.should_optimize?(path) def self.should_optimize?(path)
# don't optimize GIFs # don't optimize GIFs or SVGs
return false if path =~ /\.gif$/i return false if path =~ /\.(gif|svg)$/i
return true if path !~ /\.png$/i return true if path !~ /\.png$/i
image_info = FastImage.new(path) rescue nil image_info = FastImage.new(path) rescue nil
w, h = *(image_info.try(:size) || [0, 0]) w, h = *(image_info.try(:size) || [0, 0])

View File

@@ -157,7 +157,7 @@ server {
try_files $uri =404; try_files $uri =404;
} }
# this allows us to bypass rails # this allows us to bypass rails
location ~* \.(gif|png|jpg|jpeg|bmp|tif|tiff)$ { location ~* \.(gif|png|jpg|jpeg|bmp|tif|tiff|svg)$ {
try_files $uri =404; try_files $uri =404;
} }
# thumbnails & optimized images # thumbnails & optimized images