Class: Csscss::RedundancyAnalyzer
- Inherits:
-
Object
- Object
- Csscss::RedundancyAnalyzer
- Defined in:
- lib/csscss/redundancy_analyzer.rb
Instance Method Summary collapse
-
#initialize(raw_css) ⇒ RedundancyAnalyzer
constructor
A new instance of RedundancyAnalyzer.
- #redundancies(opts = {}) ⇒ Object
Constructor Details
#initialize(raw_css) ⇒ RedundancyAnalyzer
Returns a new instance of RedundancyAnalyzer.
4 5 6 |
# File 'lib/csscss/redundancy_analyzer.rb', line 4 def initialize(raw_css) @raw_css = raw_css end |
Instance Method Details
#redundancies(opts = {}) ⇒ Object
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/csscss/redundancy_analyzer.rb', line 8 def redundancies(opts = {}) minimum = opts[:minimum] ignored_properties = opts[:ignored_properties] || [] ignored_selectors = opts[:ignored_selectors] || [] match_shorthand = opts.fetch(:match_shorthand, true) rule_sets = Parser::Css.parse(@raw_css) matches = {} parents = {} rule_sets.each do |rule_set| next if ignored_selectors.include?(rule_set.selectors.selectors) sel = rule_set.selectors rule_set.declarations.each do |dec| next if ignored_properties.include?(dec.property) if match_shorthand && parser = shorthand_parser(dec.property) if new_decs = parser.parse(dec.property, dec.value) if dec.property == "border" %w(border-top border-right border-bottom border-left).each do |property| border_dec = Declaration.new(property, dec.value) parents[border_dec] ||= [] (parents[border_dec] << dec).uniq! border_dec.parents = parents[border_dec] matches[border_dec] ||= [] matches[border_dec] << sel matches[border_dec].uniq! end end new_decs.each do |new_dec| # replace any non-derivatives with derivatives existing = matches.delete(new_dec) || [] existing << sel parents[new_dec] ||= [] (parents[new_dec] << dec).uniq! new_dec.parents = parents[new_dec] matches[new_dec] = existing matches[new_dec].uniq! end end end matches[dec] ||= [] matches[dec] << sel matches[dec].uniq! end end inverted_matches = {} matches.each do |declaration, selector_groups| if selector_groups.size > 1 selector_groups.combination(2).each do |two_selectors| inverted_matches[two_selectors] ||= [] inverted_matches[two_selectors] << declaration end end end # trims any derivative declarations alongside shorthand inverted_matches.each do |selectors, declarations| redundant_derivatives = declarations.select do |dec| dec.derivative? && declarations.detect {|dec2| dec2 > dec } end unless redundant_derivatives.empty? inverted_matches[selectors] = declarations - redundant_derivatives end # border needs to be reduced even more %w(width style color).each do |property| decs = inverted_matches[selectors].select do |dec| dec.derivative? && dec.property =~ /border-\w+-#{property}/ end if decs.size == 4 && decs.map(&:value).uniq.size == 1 inverted_matches[selectors] -= decs inverted_matches[selectors] << Declaration.new("border-#{property}", decs.first.value) end end end if minimum inverted_matches.delete_if do |key, declarations| declarations.size < minimum end end # combines selector keys by common declarations final_inverted_matches = inverted_matches.dup inverted_matches.to_a.each_with_index do |(selector_group1, declarations1), index| keys = [selector_group1] inverted_matches.to_a[(index + 1)..-1].each do |selector_group2, declarations2| if declarations1 == declarations2 && final_inverted_matches[selector_group2] keys << selector_group2 final_inverted_matches.delete(selector_group2) end end if keys.size > 1 final_inverted_matches.delete(selector_group1) key = keys.flatten.sort.uniq final_inverted_matches[key] = declarations1 end end # sort hash by number of matches sorted_array = final_inverted_matches.sort {|(_, v1), (_, v2)| v2.size <=> v1.size } {}.tap do |sorted_hash| sorted_array.each do |key, value| sorted_hash[key.sort] = value.sort end end end |