Class: R2::Swapper
- Inherits:
-
Object
- Object
- R2::Swapper
- Defined in:
- lib/r2.rb
Overview
Reuable class for CSS alterations
Constant Summary collapse
- PROPERTY_MAP =
{ 'margin-left' => 'margin-right', 'margin-right' => 'margin-left', 'padding-left' => 'padding-right', 'padding-right' => 'padding-left', 'border-left' => 'border-right', 'border-right' => 'border-left', 'border-left-width' => 'border-right-width', 'border-right-width' => 'border-left-width', 'border-radius-bottomleft' => 'border-radius-bottomright', 'border-radius-bottomright' => 'border-radius-bottomleft', 'border-radius-topleft' => 'border-radius-topright', 'border-radius-topright' => 'border-radius-topleft', '-moz-border-radius-bottomright' => '-moz-border-radius-bottomleft', '-moz-border-radius-bottomleft' => '-moz-border-radius-bottomright', '-moz-border-radius-topright' => '-moz-border-radius-topleft', '-moz-border-radius-topleft' => '-moz-border-radius-topright', '-webkit-border-top-right-radius' => '-webkit-border-top-left-radius', '-webkit-border-top-left-radius' => '-webkit-border-top-right-radius', '-webkit-border-bottom-right-radius' => '-webkit-border-bottom-left-radius', '-webkit-border-bottom-left-radius' => '-webkit-border-bottom-right-radius', 'left' => 'right', 'right' => 'left' }
- VALUE_PROCS =
{ 'padding' => lambda {|obj,val| obj.quad_swap(val) }, 'margin' => lambda {|obj,val| obj.quad_swap(val) }, 'border-radius' => lambda {|obj,val| obj.border_radius_swap(val) }, '-moz-border-radius' => lambda {|obj,val| obj.border_radius_swap(val) }, '-webkit-border-radius' => lambda {|obj,val| obj.border_radius_swap(val) }, 'text-align' => lambda {|obj,val| obj.side_swap(val) }, 'float' => lambda {|obj,val| obj.side_swap(val) }, 'box-shadow' => lambda {|obj,val| obj.shadow_swap(val) }, '-webkit-box-shadow' => lambda {|obj,val| obj.shadow_swap(val) }, '-moz-box-shadow' => lambda {|obj,val| obj.shadow_swap(val) }, 'direction' => lambda {|obj,val| obj.direction_swap(val) }, 'clear' => lambda {|obj,val| obj.side_swap(val) }, 'background-position' => lambda {|obj,val| obj.background_position_swap(val) } }
Instance Method Summary collapse
-
#background_position_swap(val) ⇒ Object
Given a background-position such as
left centeror0% 50%return the opposing value e.gright centeror100% 50%. -
#border_radius_swap(val) ⇒ Object
Border radius uses top-left, top-right, bottom-left, bottom-right, so all values need to be swapped.
-
#declaration_swap(decl) ⇒ Object
Given a single CSS declaration rule (e.g.
padding-left: 4px) return the opposing rule (so,padding-right:4px;in this example). -
#direction_swap(val) ⇒ Object
Given a value of
rtlorltrreturn the opposing value. -
#minimize(css) ⇒ Object
Minimize the provided CSS by removing comments, and extra specs.
-
#quad_swap(val) ⇒ Object
Given a 4-argument CSS declaration value (like that of
paddingormargin) return the opposing value. -
#r2(original_css) ⇒ Object
Given a String of CSS perform the full directionality change.
-
#shadow_swap(val) ⇒ Object
Given the 2-6 variable declaration for box-shadow convert the direction.
-
#side_swap(val) ⇒ Object
Given a value of
rightorleftreturn the opposing value.
Instance Method Details
#background_position_swap(val) ⇒ Object
Given a background-position such as left center or 0% 50% return the opposing value e.g right center or 100% 50%
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 |
# File 'lib/r2.rb', line 200 def background_position_swap(val) if val =~ /left/ val.gsub!('left', 'right') elsif val =~ /right/ val.gsub!('right', 'left') end points = val.strip.split(/\s+/) # If first point is a percentage-value if match = points[0].match(/(\d+)%/) inv = 100 - match[1].to_i # 30% => 70% (100 - x) val = ["#{inv}%", points[1]].compact.join(' ') end # If first point is a unit-value if match = points[0].match(/^(\d+[a-z]{2,3})/) val = ["right", match[1], points[1] || "center"].compact.join(' ') end val end |
#border_radius_swap(val) ⇒ Object
Border radius uses top-left, top-right, bottom-left, bottom-right, so all values need to be swapped. Additionally, two and three value border-radius declarations need to be swapped as well. Vertical radius, specified with a /, should be left alone.
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 |
# File 'lib/r2.rb', line 180 def border_radius_swap(val) # 1px 2px 3px 4px => 1px 4px 3px 2px points = val.to_s.split(/\s+/) if points && points.length > 1 && !val.to_s.include?('/') case points.length when 4 [points[1], points[0], points[3], points[2]].join(' ') when 3 [points[1], points[0], points[1], points[2]].join(' ') when 2 [points[1], points[0]].join(' ') else val end else val end end |
#declaration_swap(decl) ⇒ Object
Given a single CSS declaration rule (e.g. padding-left: 4px) return the opposing rule (so, padding-right:4px; in this example)
119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/r2.rb', line 119 def declaration_swap(decl) return '' unless decl matched = decl.match(/([^:]+):(.+)$/) return '' unless matched property = matched[1] value = matched[2] property = PROPERTY_MAP[property] if PROPERTY_MAP.has_key?(property) value = VALUE_PROCS[property].call(self, value) if VALUE_PROCS.has_key?(property) return property + ':' + value + ';' end |
#direction_swap(val) ⇒ Object
Given a value of rtl or ltr return the opposing value. All other arguments are ignored and returned unmolested.
135 136 137 138 139 140 141 142 143 |
# File 'lib/r2.rb', line 135 def direction_swap(val) if val == "rtl" "ltr" elsif val == "ltr" "rtl" else val end end |
#minimize(css) ⇒ Object
Minimize the provided CSS by removing comments, and extra specs
108 109 110 111 112 113 114 115 116 |
# File 'lib/r2.rb', line 108 def minimize(css) return '' unless css css.gsub(/\/\*[\s\S]+?\*\//, ''). # comments gsub(/[\n\r]/, ''). # line breaks and carriage returns gsub(/\s*([:;,\{\}])\s*/, '\1'). # space between selectors, declarations, properties and values gsub(/\s+/, ' '). # replace multiple spaces with single spaces gsub(/(\A\s+|\s+\z)/, '') # leading or trailing spaces end |
#quad_swap(val) ⇒ Object
Given a 4-argument CSS declaration value (like that of padding or margin) return the opposing value. The opposing value swaps the left and right but not the top or bottom. Any unrecognized argument is returned unmolested (for example, 2-argument values)
159 160 161 162 163 164 165 166 167 168 |
# File 'lib/r2.rb', line 159 def quad_swap(val) # 1px 2px 3px 4px => 1px 4px 3px 2px points = val.to_s.split(/\s+/) if points && points.length == 4 [points[0], points[3], points[2], points[1]].join(' ') else val end end |
#r2(original_css) ⇒ Object
Given a String of CSS perform the full directionality change
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/r2.rb', line 69 def r2(original_css) css = minimize(original_css) result = css.gsub(/([^\{\}]+[^\}]|[\}])+?/) do |rule| # +rule+ can represent a selector (".foo {"), the closing "}" for a selector, or the complete # body of a a selector if rule.match(/[\{\}]/) # it is a selector with "{" or a closing "}", insert as it is. This is # things like ".foo {" and its matching "}" rule_str = rule else # It is a declaration body, like "padding-left:4px;margin-left:5px;" rule_str = "" # Split up the individual rules in the body and process each swap. To handle the # possible ";" in the url() definitions, like # url("data;base64") and url("data:image/svg+xml;charset=...") # a state machine is constructed. url_rule = nil rule.split(/;/).each do |part| # A rule body that contains a "url(" and a ";" before the closing ")" if part.match(/url\([^\)]+$/) url_rule = part elsif url_rule != nil url_rule << ";" + part if part.match(/\)( |$)/) rule_str << declaration_swap(url_rule) url_rule = nil end else rule_str << declaration_swap(part) end end end rule_str end return result end |
#shadow_swap(val) ⇒ Object
Given the 2-6 variable declaration for box-shadow convert the direction. Conversion requires inverting the horizontal measure only.
172 173 174 |
# File 'lib/r2.rb', line 172 def shadow_swap(val) ShadowFlipper::flip(val) end |
#side_swap(val) ⇒ Object
Given a value of right or left return the opposing value. All other arguments are ignored and returned unmolested.
146 147 148 149 150 151 152 153 154 |
# File 'lib/r2.rb', line 146 def side_swap(val) if val == "right" "left" elsif val == "left" "right" else val end end |