lib/esvg/symbol.rb in esvg-4.3.0 vs lib/esvg/symbol.rb in esvg-4.3.1
- old
+ new
@@ -1,10 +1,10 @@
require 'open3'
module Esvg
class Symbol
- attr_reader :name, :id, :path, :content, :optimized, :size, :group, :mtime
+ attr_reader :name, :id, :path, :content, :optimized, :size, :group, :mtime, :defs
include Esvg::Utils
def initialize(path, config={})
@config = config
@@ -15,29 +15,28 @@
def read
return if !File.exist?(@path)
time = last_modified
- if @mtime != time
- @mtime = time
- @content = pre_optimize File.read(@path)
- @size = dimensions
- @optimized = nil
- @optimized_at = nil
- end
# Ensure that cache optimization matches current optimization settings
# If config has changed name, reset optimized build (name gets baked in)
- if @svgo_optimized != svgo? || name != file_name
+ if @mtime != time || @svgo_optimized != svgo? || name != file_name
@optimized = nil
@optimized_at = nil
end
-
+
@group = dir_key
@name = file_name
@id = file_id file_key
+ if @mtime != time
+ @content = prep_defs pre_optimize File.read(@path)
+ @mtime = time
+ @size = dimensions
+ end
+
self
end
def width
@size[:width]
@@ -54,10 +53,11 @@
name: @name,
group: @group,
mtime: @mtime,
size: @size,
content: @content,
+ defs: @defs,
optimized: @optimized,
optimized_at: @optimized_at,
svgo_optimized: svgo? && @svgo_optimized
}
end
@@ -136,12 +136,10 @@
def optimize
# Only optimize again if the file has changed
return @optimized if @optimized && @optimized_at > @mtime
@optimized = @content
- sub_def_ids
- move_defs
if svgo?
response = Open3.capture3(%Q{#{Esvg.node_module('svgo')} --disable=removeUselessDefs -s '#{@optimized}' -o -})
if !response[0].empty? && response[2].success?
@optimized = response[0]
@@ -225,10 +223,11 @@
{}
end
end
def pre_optimize(svg)
+
# Generate a regex of attributes to be removed
att = Regexp.new %w(xmlns xmlns:xlink xml:space version).map { |m| "#{m}=\".+?\"" }.join('|')
svg.strip
.gsub(att, '') # Remove unwanted attributes
@@ -242,11 +241,10 @@
end
def post_optimize
@optimized = set_attributes
.gsub(/<\/svg/,'</symbol') # Replace svgs with symbols
- .gsub(/class="def-/,'id="def-') # Replace <def> classes with ids (classes are generated in sub_def_ids)
.gsub(/\w+=""/,'') # Remove empty attributes
end
def set_attributes
attr.keys.each do |key|
@@ -259,38 +257,30 @@
# Scans <def> blocks for IDs
# If urls(#id) are used, ensure these IDs are unique to this file
# Only replace IDs if urls exist to avoid replacing defs
# used in other svg files
#
- def sub_def_ids
- @optimized.scan(/<defs>.+<\/defs>/m).flatten.each do |defs|
- defs.scan(/id="(.+?)"/).flatten.uniq.each_with_index do |id, index|
+ def prep_defs(svg)
- # If there are urls which refer to
- # ids be sure to update both
- #
- if @optimized.match(/url\(##{id}\)/)
- new_id = "def-#{@id}-#{index}"
+ # <defs> should be moved to the beginning of the SVG file for braod browser support. Ahem, Firefox ಠ_ಠ
+ # When symbols are reassembled, @defs will be added back
+
+ if @defs = svg.scan(/<defs>(.+)<\/defs>/m).flatten[0]
+ svg.sub!("<defs>#{@defs}</defs>", '')
+ @defs.gsub!(/(\n|\s{2,})/,'')
- @optimized = @optimized.gsub(/id="#{id}"/, %Q{class="#{new_id}"})
- .gsub(/url\(##{id}\)/, "url(##{new_id})")
+ @defs.scan(/id="(.+?)"/).flatten.uniq.each_with_index do |id, index|
- # Otherwise just leave the IDs of the
- # defs and change them to classes to
- # avoid SVGO ID mangling
- #
- else
- @optimized = @optimized.gsub /id="#{id}"/, %Q{class="#{id}"}
+ # If there are urls matching def ids
+ if svg.match(/url\(##{id}\)/)
+
+ new_id = "def-#{@id}-#{index}" # Generate a unique id
+ @defs.gsub!(/id="#{id}"/, %Q{id="#{new_id}"}) # Replace the def ids
+ svg.gsub!(/url\(##{id}\)/, "url(##{new_id})") # Replace url references to these old def ids
end
end
end
- end
- # <defs> should be moved to the beginning of the SVG file for braod browser support. Ahem, Firefox ಠ_ಠ
- def move_defs
- if defs = @optimized.scan(/(\s*<defs>.+<\/defs>\s*)/m).flatten[0]
- @optimized.sub!(defs, '')
- @optimized.sub!(/(<svg.+?>)/, "\1#{defs}")
- end
+ svg
end
end
end