[376] | 1 | module Blueprint |
---|
| 2 | # parses a hash of key/value pairs, key being output CSS selectors, value |
---|
| 3 | # being a list of CSS selectors to draw from |
---|
| 4 | class SemanticClassNames |
---|
| 5 | attr_accessor :class_assignments |
---|
| 6 | attr_reader :namespace, :source_file |
---|
| 7 | |
---|
| 8 | # ==== Options |
---|
| 9 | # * <tt>options</tt> |
---|
| 10 | # * <tt>:namespace</tt> -- Namespace to be used when matching CSS selectors to draw from |
---|
| 11 | # * <tt>:source_file</tt> -- Source file to use as reference of CSS selectors. Defaults to Blueprint's generated screen.css |
---|
| 12 | # * <tt>:class_assignments</tt> -- Hash of key/value pairs, key being output CSS selectors, value being a list of CSS selectors to draw from |
---|
| 13 | def initialize(options = {}) |
---|
| 14 | @namespace = options[:namespace] || "" |
---|
| 15 | @source_file = options[:source_file] || File.join(Blueprint::BLUEPRINT_ROOT_PATH, "screen.css") |
---|
| 16 | self.class_assignments = options[:class_assignments] || {} |
---|
| 17 | end |
---|
| 18 | |
---|
| 19 | # Returns a CSS string of semantic selectors and associated styles |
---|
| 20 | # ==== Options |
---|
| 21 | # * <tt>assignments</tt> -- Hash of key/value pairs, key being output CSS selectors, value being a list of CSS selectors to draw from; defaults to what was passed in constructor or empty hash |
---|
| 22 | def css_from_assignments(assignments = {}) |
---|
| 23 | assignments ||= self.class_assignments |
---|
| 24 | |
---|
| 25 | # define a wrapper hash to hold all the new CSS assignments |
---|
| 26 | output_css = {} |
---|
| 27 | |
---|
| 28 | #loads full stylesheet into an array of hashes |
---|
| 29 | blueprint_assignments = CSSParser.new(File.path_to_string(self.source_file)).parse |
---|
| 30 | |
---|
| 31 | # iterates through each class assignment ('#footer' => '.span-24', '#header' => '.span-24') |
---|
| 32 | assignments.each do |semantic_class, blueprint_classes| |
---|
| 33 | # gathers all BP classes we're going to be mimicing |
---|
| 34 | blueprint_classes = blueprint_classes.split(/,|\s/).select {|c| !c.blank? }.flatten.map {|c| c.strip } |
---|
| 35 | classes = [] |
---|
| 36 | # loop through each BP class, grabbing the full hash (containing tags, index, and CSS rules) |
---|
| 37 | blueprint_classes.each do |bp_class| |
---|
| 38 | match = if bp_class.include?(".") |
---|
| 39 | bp_class.gsub(".", ".#{self.namespace}") |
---|
| 40 | else |
---|
| 41 | ".#{self.namespace}#{bp_class}" |
---|
| 42 | end |
---|
| 43 | classes << blueprint_assignments.select do |line| |
---|
| 44 | line[:tags] =~ Regexp.new(/^([\w\.\-\:]+, ?)*#{match}(, ?[\w\.\-\:]+)*$/) |
---|
| 45 | end.uniq |
---|
| 46 | end |
---|
| 47 | |
---|
| 48 | # clean up the array |
---|
| 49 | classes = classes.flatten.uniq |
---|
| 50 | |
---|
| 51 | # set the semantic class to the rules gathered in classes, sorted by index |
---|
| 52 | # this way, the styles will be applied in the correct order from top of file to bottom |
---|
| 53 | output_css[semantic_class] = "#{classes.sort_by {|i| i[:idx] }.map {|i| i[:rules] }}" |
---|
| 54 | end |
---|
| 55 | |
---|
| 56 | # return the css in proper format |
---|
| 57 | css = "" |
---|
| 58 | output_css.each do |tags, rules| |
---|
| 59 | css += "#{tags} {#{rules}}\n" |
---|
| 60 | end |
---|
| 61 | css |
---|
| 62 | end |
---|
| 63 | end |
---|
| 64 | end |
---|