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) }, 'background' => lambda {|obj,val| obj.background_swap(val) }, }
Instance Method Summary collapse
-
#background_position_swap(val) ⇒ Object
Given a background-position such as
left center
or0% 50%
return the opposing value e.gright center
or100% 50%
. -
#background_swap(val) ⇒ Object
Given the short-hand background: definition attempt to convert the direction.
-
#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
rtl
orltr
return 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
padding
ormargin
) 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
right
orleft
return 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%
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 |
# File 'lib/r2.rb', line 227 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 |
#background_swap(val) ⇒ Object
Given the short-hand background: definition attempt to convert the direction.
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 |
# File 'lib/r2.rb', line 178 def background_swap(val) parts = val.split(/ /) checked = [] skip = false parts.each_index do |i| p = parts[i] n = parts[i+1] if skip skip = false next end if p.match(/left|right|\d+%/) checked << background_position_swap("#{p} #{n}") skip = true else checked << side_swap(p) end end checked.flatten.join(' ') 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.
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
# File 'lib/r2.rb', line 207 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)
120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/r2.rb', line 120 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.
136 137 138 139 140 141 142 143 144 |
# File 'lib/r2.rb', line 136 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
109 110 111 112 113 114 115 116 117 |
# File 'lib/r2.rb', line 109 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)
160 161 162 163 164 165 166 167 168 169 |
# File 'lib/r2.rb', line 160 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
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 106 |
# File 'lib/r2.rb', line 70 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.
173 174 175 |
# File 'lib/r2.rb', line 173 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.
147 148 149 150 151 152 153 154 155 |
# File 'lib/r2.rb', line 147 def side_swap(val) if val == "right" "left" elsif val == "left" "right" else val end end |