# Ah... CSSes... require 'csses_helpers' # The CSSes class takes some files, figures out what HTML is referenced # or generated in them, and puts those all into an array called elements. class CSSes VERSION = '1.0.0' UNFASHIONABLE_ELEMENTS = %w(html head meta title) RAILS_HELPERS = { /\blink_to\w*\b/ => 'a', /\bimage_tag\b/ => 'img', /\blabel\b/ => 'label', /\bform(?:_(?:for|tag))\b/ => 'form', /\btext_area(?:_tag)?\b/ => 'textarea', /\btext_field(?:_tag)?\b/ => 'input', /\bcheck_box_tag\b/ => 'input', /\bfield_set_tag\b/ => 'fieldset', /\bfile_field_tag\b/ => 'input', /\bimage_submit_tag\b/ => 'input', /\bpassword_field_tag\b/ => 'input', /\bradio_button_tag\b/ => 'input', /\bselect_tag\b/ => 'select', /\bsubmit_tag\b/ => 'input' } RAILS_HTML_ID_OR_CLASS = /(?::(id|class))\s*=>\s*['"](\w+)['"]/ attr_reader :elements # Give it a list of files as an array (not splatted), get back, well, # a CSS object, but one with an array of CSS elements as an attribute. def initialize(files) @elements = [] files.each do |file| source = File.read(file) @elements << source.scan(/<(\w+)/) source.scan(/<(\w+)\s+[^>]*(class|id)="(\w+)"/).each do |elem| @elements << "#{elem[0]}#{css_sym_for_attribute(elem[1])}#{elem[2]}" end RAILS_HELPERS.each do |regex, tag| source.scan(/#{regex}.*/).each do |line| if line.match(RAILS_HTML_ID_OR_CLASS) @elements << "#{tag}#{css_sym_for_attribute($1)}#{$2}" end @elements << tag end end end @elements.flatten! @elements.uniq! @elements.sort! @elements -= UNFASHIONABLE_ELEMENTS apply_pseudo_classes! end private # Generates the typical pseudo-classes for anchors (visited, hover, active). def apply_pseudo_classes! @elements.each_with_index do |e, i| if e.match(/\Aa(?:[#\.]\w+)?/) @elements[i] = [e, "#{e}:visited", "#{e}:hover", "#{e}:active"] end end @elements.flatten! end end