mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
FEATURE: improve support for (whitelisted) SVGs as images
This commit is contained in:
2
Gemfile
2
Gemfile
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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])
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user