Class: Cassy
Overview
Markaby-ish way to declare CSS This code is based on code written by automatthew:
http://github.com/automatthew/cassandra/tree/master
Constant Summary collapse
- HTML_TAGS =
%w( a abbr acronym address area b base bdo big blockquote body br button caption cite code col colgroup dd del dfn div dl dt em fieldset form h1 h2 h3 h4 h5 h6 head hr html i img input ins kbd label legend li link map meta noscript object ol optgroup option p param pre q samp script select small span strong style sub sup table tbody td textarea tfoot th thead title tr tt ul var )
- CSS_PROPERTIES =
%w( azimuth background background_attachment background_color background_image background_position background_repeat border border_left border_top border_right border_bottom border_collapse border_color border_spacing border_style border_top border_top_color border_top_style border_top_width border_width bottom caption_side clear clip color content counter_increment counter_reset cue cue_after cue_before cursor direction display elevation empty_cells float font font_family font_size font_size_adjust font_stretch font_style font_variant font_weight height left letter_spacing line_height list_style list_style_image list_style_position list_style_type margin margin_left margin_top margin_right margin_bottom marker_offset marks max_height max_width min_height min_width orphans outline outline_color outline_style outline_width overflow padding padding_left padding_top padding_right padding_bottom page page_break_after page_break_before page_break_inside pause pause_after pause_before pitch pitch_range play_during position quotes richness right size speak speak_header speak_numeral speak_punctuation speech_rate stress table_layout text_align text_decoration text_indent text_shadow text_transform top unicode_bidi vertical_align visibility voice_family volume white_space widows width word_spacing z_index )
- METHODS =
%w( class include extend instance_eval send __send__ __id__ respond_to? )
Instance Attribute Summary collapse
-
#data ⇒ Object
readonly
Returns the value of attribute data.
Class Method Summary collapse
Instance Method Summary collapse
-
#chain(new_selector) ⇒ Object
Pushes accumulated selector on the stack without generating a new properties array.
-
#closed_block ⇒ Object
Pop the selector string and property array for the closing block off of their respective stacks.
-
#initialize(sel = nil) ⇒ Cassy
constructor
A new instance of Cassy.
-
#method_missing(name, &block) ⇒ Object
Catch unknown methods and treat them as CSS class or id selectors.
-
#new_property_set ⇒ Object
Pushes an empty array on the properties stack and registers that array (against the current selector) in @data.
-
#open_block(new_selector) ⇒ Object
Push the accumulated selector and a new property array onto the tops of their respected stacks.
- #process(*args, &block) ⇒ Object
-
#property(css_attr, *args) ⇒ Object
Add a property declaration string to the current selector’s properties array.
-
#selectify(method_name) ⇒ Object
bang methods represent CSS ids.
-
#selector(sel) ⇒ Object
Declare a CSS selector using a block.
- #to_s ⇒ Object
Constructor Details
#initialize(sel = nil) ⇒ Cassy
Returns a new instance of Cassy.
30 31 32 33 34 35 36 37 38 |
# File 'lib/waves/views/cassy.rb', line 30 def initialize(sel=nil) @data = [] @selectors = [ sel ] @properties = [] # Primitive state machine # possible states are :closed_block, :chain, :open_block @state = :closed_block end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, &block) ⇒ Object
Catch unknown methods and treat them as CSS class or id selectors.
83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/waves/views/cassy.rb', line 83 def method_missing(name, &block) sel = selectify(name) if block_given? open_block(sel) yield closed_block else chain(sel) end self end |
Instance Attribute Details
#data ⇒ Object (readonly)
Returns the value of attribute data.
28 29 30 |
# File 'lib/waves/views/cassy.rb', line 28 def data @data end |
Class Method Details
.process(*args, &block) ⇒ Object
40 41 42 |
# File 'lib/waves/views/cassy.rb', line 40 def self.process(*args,&block) self.new.process(*args,&block) end |
Instance Method Details
#chain(new_selector) ⇒ Object
Pushes accumulated selector on the stack without generating a new properties array.
145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/waves/views/cassy.rb', line 145 def chain(new_selector) case @state when :closed_block, :open_block combined_selector = [@selectors[-1], new_selector].compact.join(" ") @selectors.push( combined_selector) when :chain @selectors[-1] = "#{@selectors[-1]}#{new_selector}" else raise "You can't get to :chain from #{@state.inspect}" end @state = :chain end |
#closed_block ⇒ Object
Pop the selector string and property array for the closing block off of their respective stacks
161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/waves/views/cassy.rb', line 161 def closed_block case @state when :open_block, :closed_block @selectors.pop @properties.pop else raise "You can't get to :closed_block from #{@state.inspect}" end @state = :closed_block end |
#new_property_set ⇒ Object
Pushes an empty array on the properties stack and registers that array (against the current selector) in @data
64 65 66 67 |
# File 'lib/waves/views/cassy.rb', line 64 def new_property_set @properties.push [] @data << [@selectors[-1], @properties[-1] ] end |
#open_block(new_selector) ⇒ Object
Push the accumulated selector and a new property array onto the tops of their respected stacks
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/waves/views/cassy.rb', line 128 def open_block(new_selector) case @state when :closed_block, :open_block combined_selector = [@selectors[-1], new_selector].compact.join(" ") @selectors.push combined_selector new_property_set when :chain @selectors[-1] = "#{@selectors[-1]}#{new_selector}" new_property_set else raise "You can't get to :open_block from #{@state.inspect}" end @state = :open_block end |
#process(*args, &block) ⇒ Object
44 45 46 47 48 49 50 51 |
# File 'lib/waves/views/cassy.rb', line 44 def process(*args, &block) if block instance_eval(&block) else instance_eval(args.join("\n")) end self end |
#property(css_attr, *args) ⇒ Object
Add a property declaration string to the current selector’s properties array.
120 121 122 |
# File 'lib/waves/views/cassy.rb', line 120 def property(css_attr, *args) @properties[-1] << "#{css_attr}: #{args.join(' ')};" end |
#selectify(method_name) ⇒ Object
bang methods represent CSS ids. Otherwise CSS classes.
96 97 98 99 |
# File 'lib/waves/views/cassy.rb', line 96 def selectify(method_name) matches = method_name.to_s.match( /([\w_]+)!$/) matches ? "##{matches[1]}" : ".#{method_name}" end |
#selector(sel) ⇒ Object
Declare a CSS selector using a block. May be chained and nested.
71 72 73 74 75 76 77 78 79 80 |
# File 'lib/waves/views/cassy.rb', line 71 def selector(sel) if block_given? open_block(sel) yield closed_block else chain(sel) end self end |
#to_s ⇒ Object
53 54 55 56 57 58 |
# File 'lib/waves/views/cassy.rb', line 53 def to_s @data.map do |sel| properties = sel.last.join("\n ") "#{sel.first} {\n #{properties}\n}\n" end.join end |