Class: CssSplitter::Splitter

Inherits:
Object
  • Object
show all
Defined in:
lib/css_splitter/splitter.rb

Constant Summary collapse

MAX_SELECTORS_DEFAULT =
4095

Class Method Summary collapse

Class Method Details

.count_selectors(css_file) ⇒ Object

count selectors of a CSS stylesheet (not used by SprocketsEngine)



78
79
80
81
82
83
84
85
# File 'lib/css_splitter/splitter.rb', line 78

def self.count_selectors(css_file)
  raise "file could not be found" unless File.exists? css_file

  rules = split_string_into_rules(File.read css_file)
  return if rules.first.nil?

  rules.sum{ |rule| count_selectors_of_rule(rule) }
end

.count_selectors_of_rule(rule) ⇒ Object

count selectors of one individual CSS rule



70
71
72
73
# File 'lib/css_splitter/splitter.rb', line 70

def self.count_selectors_of_rule(rule)
  parts = strip_comments(rule).partition(/\{/)
  parts.second.empty? ? 0 : parts.first.scan(/,/).count.to_i + 1
end

.extract_part(rules, part = 1, max_selectors = MAX_SELECTORS_DEFAULT) ⇒ Object

extracts the specified part of an overlong CSS string



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
# File 'lib/css_splitter/splitter.rb', line 19

def self.extract_part(rules, part = 1, max_selectors = MAX_SELECTORS_DEFAULT)
  return if rules.first.nil?

  charset_statement, rules[0] = extract_charset(rules.first)
  return if rules.nil?

  output = charset_statement || ""
  selectors_count = 0
  selector_range = max_selectors * (part - 1) + 1 .. max_selectors * part # e.g (4096..8190)

  current_media = nil
  selectors_in_media = 0
  first_hit = true
  rules.each do |rule|
    media_part = extract_media(rule)
    if media_part
      current_media = media_part
      selectors_in_media = 0
    end

    rule_selectors_count = count_selectors_of_rule rule
    selectors_count += rule_selectors_count

    if rule =~ /\A\s*}\z$/
      current_media = nil
      # skip the line if the close bracket is the first rule for the new file
      next if first_hit
    end

    if selector_range.cover? selectors_count # add rule to current output if within selector_range
      if media_part
        output << media_part
      elsif first_hit && current_media
        output << current_media
      end
      selectors_in_media += rule_selectors_count if current_media.present?
      output << rule
      first_hit = false
    elsif selectors_count > selector_range.end # stop writing to output
      break
    end
  end

  if current_media.present? and selectors_in_media > 0
    output << '}'
  end

  output
end

.split_string(css_string, split = 1, max_selectors = MAX_SELECTORS_DEFAULT) ⇒ Object

returns the specified split of the passed css_string



8
9
10
11
# File 'lib/css_splitter/splitter.rb', line 8

def self.split_string(css_string, split = 1, max_selectors = MAX_SELECTORS_DEFAULT)
  rules = split_string_into_rules(css_string)
  extract_part rules, split, max_selectors
end

.split_string_into_rules(css_string) ⇒ Object

splits string into array of rules (also strips comments)



14
15
16
# File 'lib/css_splitter/splitter.rb', line 14

def self.split_string_into_rules(css_string)
  strip_comments(css_string).chomp.scan /[^}]*}/
end