-
-
Save mguterl/18343 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Nav | |
def self.padded_selector(sel, max_len) | |
sel.ljust(max_len) | |
end | |
attr_accessor :id, :height, :items, :image | |
def initialize(attrs={}) | |
attrs.each { |k,v| send("#{k}=", v) } | |
end | |
def id | |
@id || 'nav' | |
end | |
def items | |
@items || [] | |
end | |
def generate | |
raise 'Height undefined' if height.nil? | |
declaration + @items.collect { |item| item.declaration }.join("\n") | |
end | |
def declaration | |
declaration = <<-CSS | |
#{padded_selector(selector)} {float:left; width:#{width}px; height:#{height}px; margin:0; padding:0;} | |
#{padded_selector(selector + ' li')} {float:left; list-style-type:none; margin:0; padding:0;} | |
#{padded_selector(selector + ' li a')} {float:left; display:block; height:#{height}px; background:url(#{image}) no-repeat; text-indent:-9999px; overflow:hidden;} | |
CSS | |
end | |
def padded_selector(sel) | |
self.class.padded_selector(sel, max_item_selector_length) | |
end | |
def max_item_selector_length | |
@items.max { |a, b| a.selector_size <=> b.selector_size }.selector_size | |
end | |
def selector | |
"ul##{id}" | |
end | |
def width | |
@items.inject(0) { |sum, item| sum += item.width; sum } | |
end | |
def <<(item) | |
@items ||= [] | |
item.nav = self | |
@items << item | |
end | |
end | |
class Item | |
def self.pretty_offset(offset) | |
prefix = postfix = '' | |
unless offset.zero? | |
prefix = '-' | |
postfix = 'px' | |
end | |
"#{prefix}#{offset}#{postfix}" | |
end | |
attr_accessor :name, :width, :nav, :body_id | |
def initialize(attrs={}) | |
attrs.each { |k,v| send("#{k}=", v) } | |
end | |
def body_id | |
@body_id || "b_#{name.downcase.gsub(' ', '_')}" | |
end | |
def declaration | |
declaration = <<-CSS | |
#{nav.padded_selector(full_selector)} {background-position:#{offset} 0; width:#{width}px;} | |
#{nav.padded_selector(full_selector_hover)} {background-position:#{offset} -#{nav.height}px;} | |
#{nav.padded_selector(full_selector_with_body)} {background-position:#{offset} -#{nav.height*2}px;} | |
CSS | |
end | |
def full_selector | |
"#{nav.selector} #{selector}" | |
end | |
def full_selector_hover | |
"#{full_selector}:hover" | |
end | |
def full_selector_with_body | |
"body##{body_id} #{full_selector}" | |
end | |
def selector_size | |
full_selector_with_body.size | |
end | |
def selector | |
len = name.size > 3 ? 3 : name.size | |
"li#nav_#{name.downcase[0, len]} a" | |
end | |
def offset | |
unless @offset | |
offset = nav.items[0, position].inject(0) { |sum, item| sum += item.width; sum } | |
@offset = self.class.pretty_offset(offset) | |
end | |
@offset | |
end | |
def position | |
nav.items.index(self) | |
end | |
end | |
if $0 == __FILE__ | |
nav = Nav.new(:height => 52, :image => 'images/nav.jpg') | |
nav << Item.new(:name => 'Home', :width => 135) | |
nav << Item.new(:name => 'Features', :width => 175) | |
nav << Item.new(:name => 'Pricing', :width => 155) | |
nav << Item.new(:name => 'Questions', :width => 181) | |
nav << Item.new(:name => 'Sign Up', :width => 156) | |
puts nav.generate | |
end | |
# OUTPUTS: | |
# ul#nav {float:left; width:802px; height:52px; margin:0; padding:0;} | |
# ul#nav li {float:left; list-style-type:none; margin:0; padding:0;} | |
# ul#nav li a {float:left; display:block; height:52px; background:url(images/nav.jpg) no-repeat; text-indent:-9999px; overflow:hidden;} | |
# ul#nav li#nav_hom a {background-position:0 0; width:135px;} | |
# ul#nav li#nav_hom a:hover {background-position:0 -52px;} | |
# body#b_home ul#nav li#nav_hom a {background-position:0 -104px;} | |
# | |
# ul#nav li#nav_fea a {background-position:-135px 0; width:175px;} | |
# ul#nav li#nav_fea a:hover {background-position:-135px -52px;} | |
# body#b_features ul#nav li#nav_fea a {background-position:-135px -104px;} | |
# | |
# ul#nav li#nav_pri a {background-position:-310px 0; width:155px;} | |
# ul#nav li#nav_pri a:hover {background-position:-310px -52px;} | |
# body#b_pricing ul#nav li#nav_pri a {background-position:-310px -104px;} | |
# | |
# ul#nav li#nav_que a {background-position:-465px 0; width:181px;} | |
# ul#nav li#nav_que a:hover {background-position:-465px -52px;} | |
# body#b_questions ul#nav li#nav_que a {background-position:-465px -104px;} | |
# | |
# ul#nav li#nav_sig a {background-position:-646px 0; width:156px;} | |
# ul#nav li#nav_sig a:hover {background-position:-646px -52px;} | |
# body#b_sign_up ul#nav li#nav_sig a {background-position:-646px -104px;} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment