class CssSplitter::Splitter
Constants
- MAX_SELECTORS_DEFAULT
Public Class Methods
count_selectors(css_file)
click to toggle source
count selectors of a CSS stylesheet (not used by SprocketsEngine
)
# File lib/css_splitter/splitter.rb, line 99 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)
click to toggle source
count selectors of one individual CSS rule
# File lib/css_splitter/splitter.rb, line 91 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)
click to toggle source
extracts the specified part of an overlong CSS string
# File lib/css_splitter/splitter.rb, line 40 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)
click to toggle source
returns the specified split of the passed css_string
# 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)
click to toggle source
splits string into array of rules (also strips comments)
# File lib/css_splitter/splitter.rb, line 14 def self.split_string_into_rules(css_string) partial_rules = strip_comments(css_string).chomp.scan /[^}]*}/ whole_rules = [] bracket_balance = 0 in_media_query = false partial_rules.each do |rule| if rule =~ /^\s*@media/ in_media_query = true elsif bracket_balance == 0 in_media_query = false end if bracket_balance == 0 || in_media_query whole_rules << rule else whole_rules.last << rule end bracket_balance += get_rule_bracket_balance rule end whole_rules end
Private Class Methods
extract_charset(rule)
click to toggle source
extracts potential charset declaration from the first rule
# File lib/css_splitter/splitter.rb, line 119 def self.extract_charset(rule) if rule.include?('charset') rule.partition(/^\@charset[^;]+;/)[1,2] else [nil, rule] end end
extract_media(rule)
click to toggle source
# File lib/css_splitter/splitter.rb, line 112 def self.extract_media(rule) if rule.sub!(/^\s*(@media[^{]*{)([^{}]*{[^}]*})$/) { $2 } $1 end end
get_rule_bracket_balance( rule )
click to toggle source
# File lib/css_splitter/splitter.rb, line 131 def self.get_rule_bracket_balance ( rule ) rule.scan( /}/ ).size - rule.scan( /{/ ).size end
strip_comments(s)
click to toggle source
# File lib/css_splitter/splitter.rb, line 127 def self.strip_comments(s) s.gsub(/\/\*.*?\*\//m, "") end