Class: SvgOptimizer::Plugins::CleanupId

Inherits:
Base
  • Object
show all
Defined in:
lib/svg_optimizer/plugins/cleanup_id.rb

Constant Summary collapse

LETTERS =
%w[
  a b c d e f g h i j k l m n o p q r s t u v w x y z
  A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
].freeze
IDS =
LETTERS.dup.concat(LETTERS.combination(2).to_a).freeze
"http://www.w3.org/1999/xlink"

Instance Attribute Summary

Attributes inherited from Base

#xml

Instance Method Summary collapse

Methods inherited from Base

#initialize

Constructor Details

This class inherits a constructor from SvgOptimizer::Plugins::Base

Instance Method Details

#cleanup_id(node) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/svg_optimizer/plugins/cleanup_id.rb', line 30

def cleanup_id(node)
  # Keep ids if there's no available id.
  # This means that 1300+ ids have been used so far. CRAZY!
  return if ids.empty?

  old_id = node[:id]
  new_id = ids.shift
  node[:id] = new_id

  remove_unused_id(
    node,
    replace_url_references(old_id, new_id),
    replace_href_references(old_id, new_id)
  )
end

#idsObject



14
15
16
# File 'lib/svg_optimizer/plugins/cleanup_id.rb', line 14

def ids
  @ids ||= IDS.dup
end

#processObject



18
19
20
21
22
23
24
25
26
27
28
# File 'lib/svg_optimizer/plugins/cleanup_id.rb', line 18

def process
  # If there's a <script> or <style>, don't mess with ids.
  return if xml.css("script, style").any?

  # SVG can have ids as arrays.
  # Skip id optimization if that's the case.
  return if xml.css("[id^='[']").size.nonzero?

  # Replace the ids otherwise.
  xml.css("[id]").each(&method(:cleanup_id))
end

#remove_unused_id(node, has_url_refs, has_href_refs) ⇒ Object



46
47
48
49
50
51
# File 'lib/svg_optimizer/plugins/cleanup_id.rb', line 46

def remove_unused_id(node, has_url_refs, has_href_refs)
  return if has_url_refs
  return if has_href_refs

  node.remove_attribute("id")
end

#replace_href_references(old_id, new_id) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/svg_optimizer/plugins/cleanup_id.rb', line 69

def replace_href_references(old_id, new_id)
  scopes = ["[href='##{old_id}']"]
  scopes << "[xlink|href='##{old_id}']" if xlink_namespace?

  nodes = xml.css(scopes.join(","))

  nodes.each do |node|
    node.attributes.map(&:last).each do |attr|
      attr.value = "##{new_id}" if attr.value == "##{old_id}"
    end
  end

  nodes.any?
end

#replace_url_references(old_id, new_id) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
# File 'lib/svg_optimizer/plugins/cleanup_id.rb', line 53

def replace_url_references(old_id, new_id)
  nodes = xml.xpath(%{//*[@*="url(##{old_id})"]})

  nodes.each do |node|
    node.attributes.map(&:last).each do |attr|
      attr.value = %[url(##{new_id})] if attr.value == %[url(##{old_id})]
    end
  end

  nodes.any?
end

Returns:

  • (Boolean)


65
66
67
# File 'lib/svg_optimizer/plugins/cleanup_id.rb', line 65

def xlink_namespace?
  xml.root.namespace_definitions.map(&:href).include?(XLINK_NAMESPACE)
end