Class: Less::Node::Element
- Includes:
- Enumerable, Entity
- Defined in:
- lib/less/engine/nodes/element.rb
Overview
Element
div …
TODO: Look into making @rules its own hash-like class TODO: Look into whether selector should be child by default
Instance Attribute Summary collapse
-
#file ⇒ Object
Returns the value of attribute file.
-
#partial ⇒ Object
Returns the value of attribute partial.
-
#rules ⇒ Object
Returns the value of attribute rules.
-
#selector ⇒ Object
Returns the value of attribute selector.
-
#set ⇒ Object
Returns the value of attribute set.
Attributes included from Entity
Instance Method Summary collapse
-
#<<(obj) ⇒ Object
Add an arbitrary node to this element.
-
#[](key) ⇒ Object
Select a child element TODO: Implement full selector syntax & merge with descend().
- #class? ⇒ Boolean
-
#descend(selector, element) ⇒ Object
Same as above, except with a specific selector TODO: clean this up or implement it differently.
-
#each(path = [], &blk) ⇒ Object
Traverse the whole tree, returning each leaf (recursive).
- #elements ⇒ Object
- #empty? ⇒ Boolean
- #first ⇒ Object
-
#group ⇒ Object
Group similar rulesets together This is horrible, horrible code, but it’ll have to do until I find a proper way to do it.
- #id? ⇒ Boolean
-
#identifiers ⇒ Object
Accessors for the different nodes in @rules.
-
#initialize(name = "", selector = '') ⇒ Element
constructor
A new instance of Element.
- #inspect(depth = 0) ⇒ Object
- #last ⇒ Object
- #leaf? ⇒ Boolean
-
#nearest(ident) ⇒ Object
Find the nearest variable in the hierarchy or raise a NameError.
- #properties ⇒ Object
-
#root? ⇒ Boolean
Top-most node?.
- #tag? ⇒ Boolean
-
#to_css(path = []) ⇒ Object
Entry point for the css conversion.
- #to_s ⇒ Object
- #universal? ⇒ Boolean
- #variables ⇒ Object
Methods included from Entity
Methods inherited from String
#blank?, #column_of, #indent, #line_of, #tabto, #treetop_camelize
Constructor Details
#initialize(name = "", selector = '') ⇒ Element
Returns a new instance of Element.
17 18 19 20 21 22 23 |
# File 'lib/less/engine/nodes/element.rb', line 17 def initialize name = "", selector = '' super name @set = [] @rules = [] # Holds all the nodes under this element's hierarchy @selector = Selector[selector.strip].new # descendant | child | adjacent end |
Instance Attribute Details
#file ⇒ Object
Returns the value of attribute file.
15 16 17 |
# File 'lib/less/engine/nodes/element.rb', line 15 def file @file end |
#partial ⇒ Object
Returns the value of attribute partial.
15 16 17 |
# File 'lib/less/engine/nodes/element.rb', line 15 def partial @partial end |
#rules ⇒ Object
Returns the value of attribute rules.
15 16 17 |
# File 'lib/less/engine/nodes/element.rb', line 15 def rules @rules end |
#selector ⇒ Object
Returns the value of attribute selector.
15 16 17 |
# File 'lib/less/engine/nodes/element.rb', line 15 def selector @selector end |
#set ⇒ Object
Returns the value of attribute set.
15 16 17 |
# File 'lib/less/engine/nodes/element.rb', line 15 def set @set end |
Instance Method Details
#<<(obj) ⇒ Object
Add an arbitrary node to this element
113 114 115 116 117 118 119 120 |
# File 'lib/less/engine/nodes/element.rb', line 113 def << obj if obj.kind_of? Node::Entity obj.parent = self @rules << obj else raise ArgumentError, "argument can't be a #{obj.class}" end end |
#[](key) ⇒ Object
Select a child element TODO: Implement full selector syntax & merge with descend()
93 94 95 |
# File 'lib/less/engine/nodes/element.rb', line 93 def [] key @rules.find {|i| i.to_s == key } end |
#class? ⇒ Boolean
25 |
# File 'lib/less/engine/nodes/element.rb', line 25 def class?; self =~ /^\./ end |
#descend(selector, element) ⇒ Object
Same as above, except with a specific selector TODO: clean this up or implement it differently
99 100 101 102 103 104 105 106 107 108 |
# File 'lib/less/engine/nodes/element.rb', line 99 def descend selector, element if selector.is_a? Child s = self[element].selector self[element] if s.is_a? Child or s.is_a? Descendant elsif selector.is_a? Descendant self[element] else self[element] if self[element].selector.class == selector.class end end |
#each(path = [], &blk) ⇒ Object
Traverse the whole tree, returning each leaf (recursive)
163 164 165 166 167 168 169 170 171 |
# File 'lib/less/engine/nodes/element.rb', line 163 def each path = [], &blk elements.each do |element| path << element yield element, path if element.leaf? element.each path, &blk path.pop end self end |
#elements ⇒ Object
89 |
# File 'lib/less/engine/nodes/element.rb', line 89 def elements; @rules.select {|r| r.instance_of? Element } end |
#empty? ⇒ Boolean
38 39 40 |
# File 'lib/less/engine/nodes/element.rb', line 38 def empty? @rules.empty? end |
#first ⇒ Object
123 |
# File 'lib/less/engine/nodes/element.rb', line 123 def first; elements.first end |
#group ⇒ Object
Group similar rulesets together This is horrible, horrible code, but it’ll have to do until I find a proper way to do it.
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/less/engine/nodes/element.rb', line 50 def group matched = false stack, result = elements.dup, [] return self unless elements.size > 1 elements.each do e = stack.first result << e unless matched matched = stack[1..-1].each do |ee| if e.rules.size == ee.rules.size and e.elements.size == 0 and !e.rules.zip(ee.rules).map {|a, b| a.to_css == b.to_css }.include?(false) # Add to set unless it's a duplicate if e == ee # Do something with dups else self[e].set << ee end stack.shift else stack.shift break false end end if stack.size > 1 end @rules -= (elements - result) self end |
#id? ⇒ Boolean
26 |
# File 'lib/less/engine/nodes/element.rb', line 26 def id?; self =~ /^#/ end |
#identifiers ⇒ Object
Accessors for the different nodes in @rules
86 |
# File 'lib/less/engine/nodes/element.rb', line 86 def identifiers; @rules.select {|r| r.kind_of? Property } end |
#inspect(depth = 0) ⇒ Object
173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/less/engine/nodes/element.rb', line 173 def inspect depth = 0 indent = lambda {|i| '. ' * i } put = lambda {|ary| ary.map {|i| indent[ depth + 1 ] + i.inspect } * "\n"} (root?? "\n" : "") + [ indent[ depth ] + (self == '' ? '*' : self.to_s), put[ properties ], put[ variables ], elements.map {|i| i.inspect( depth + 1 ) } * "\n" ].reject(&:empty?).join("\n") + "\n" + indent[ depth ] end |
#last ⇒ Object
122 |
# File 'lib/less/engine/nodes/element.rb', line 122 def last; elements.last end |
#leaf? ⇒ Boolean
42 43 44 |
# File 'lib/less/engine/nodes/element.rb', line 42 def leaf? elements.empty? end |
#nearest(ident) ⇒ Object
Find the nearest variable in the hierarchy or raise a NameError
151 152 153 154 155 156 157 158 |
# File 'lib/less/engine/nodes/element.rb', line 151 def nearest ident ary = ident =~ /^[.#]/ ? :elements : :variables path.map do |node| node.send(ary).find {|i| i.to_s == ident } end.compact.first.tap do |result| raise VariableNameError, ident unless result end end |
#properties ⇒ Object
87 |
# File 'lib/less/engine/nodes/element.rb', line 87 def properties; @rules.select {|r| r.instance_of? Property } end |
#root? ⇒ Boolean
Top-most node?
34 35 36 |
# File 'lib/less/engine/nodes/element.rb', line 34 def root? parent.nil? end |
#tag? ⇒ Boolean
29 30 31 |
# File 'lib/less/engine/nodes/element.rb', line 29 def tag? not id? || class? || universal? end |
#to_css(path = []) ⇒ Object
Entry point for the css conversion
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/less/engine/nodes/element.rb', line 129 def to_css path = [] path << @selector.to_css << self unless root? content = properties.map do |i| ' ' * 2 + i.to_css end.compact.reject(&:empty?) * "\n" content = content.include?("\n") ? "\n#{content}\n" : " #{content.strip} " ruleset = !content.strip.empty?? "#{[path.reject(&:empty?).join.strip, *@set] * ', '} {#{content}}\n" : "" css = ruleset + elements.map do |i| i.to_css(path) end.reject(&:empty?).join path.pop; path.pop css end |
#to_s ⇒ Object
124 |
# File 'lib/less/engine/nodes/element.rb', line 124 def to_s; root?? '*' : super end |
#universal? ⇒ Boolean
27 |
# File 'lib/less/engine/nodes/element.rb', line 27 def universal?; self == '*' end |