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
Direct Known Subclasses
Instance Attribute Summary collapse
-
#file ⇒ Object
Returns the value of attribute file.
-
#imported ⇒ Object
Returns the value of attribute imported.
-
#name ⇒ Object
Returns the value of attribute name.
-
#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.
- #==(other) ⇒ Object
-
#[](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
- #eql?(other) ⇒ Boolean
- #equiv?(other) ⇒ 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
- #mixins ⇒ Object
-
#nearest(ident, type = nil) ⇒ Object
Find the nearest node in the hierarchy or raise a NameError.
- #parameters ⇒ Object
- #properties ⇒ Object
-
#root? ⇒ Boolean
Top-most node?.
- #tag? ⇒ Boolean
-
#to_css(path = [], env = nil) ⇒ Object
Entry point for the css conversion.
- #to_s ⇒ Object
- #universal? ⇒ Boolean
- #variables ⇒ Object
Methods included from Entity
Constructor Details
#initialize(name = "", selector = '') ⇒ Element
Returns a new instance of Element.
18 19 20 21 22 23 |
# File 'lib/less/engine/nodes/element.rb', line 18 def initialize name = "", selector = '' @name = name @set, @imported = [], [] @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 |
#imported ⇒ Object
Returns the value of attribute imported.
15 16 17 |
# File 'lib/less/engine/nodes/element.rb', line 15 def imported @imported end |
#name ⇒ Object
Returns the value of attribute name.
15 16 17 |
# File 'lib/less/engine/nodes/element.rb', line 15 def name @name 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
127 128 129 130 131 132 133 134 |
# File 'lib/less/engine/nodes/element.rb', line 127 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 |
#==(other) ⇒ Object
96 97 98 |
# File 'lib/less/engine/nodes/element.rb', line 96 def == other name == other.name end |
#[](key) ⇒ Object
Select a child element TODO: Implement full selector syntax & merge with descend()
86 87 88 89 90 91 92 93 94 |
# File 'lib/less/engine/nodes/element.rb', line 86 def [] key case key when Entity @rules.find {|i| i.eql? key } when String @rules.find {|i| i.to_s == key } else raise ArgumentError end end |
#class? ⇒ Boolean
25 |
# File 'lib/less/engine/nodes/element.rb', line 25 def class?; name =~ /^\./ end |
#descend(selector, element) ⇒ Object
Same as above, except with a specific selector TODO: clean this up or implement it differently
113 114 115 116 117 118 119 120 121 122 |
# File 'lib/less/engine/nodes/element.rb', line 113 def descend selector, element if selector.is_a? Child s = self[element.name].selector self[element.name] if s.is_a? Child or s.is_a? Descendant elsif selector.is_a? Descendant self[element.name] else self[element.name] if self[element.name].selector.class == selector.class end end |
#each(path = [], &blk) ⇒ Object
Traverse the whole tree, returning each leaf (recursive)
186 187 188 189 190 191 192 193 194 |
# File 'lib/less/engine/nodes/element.rb', line 186 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
80 |
# File 'lib/less/engine/nodes/element.rb', line 80 def elements; @rules.select {|r| r.kind_of? Element } end |
#empty? ⇒ Boolean
38 39 40 |
# File 'lib/less/engine/nodes/element.rb', line 38 def empty? @rules.empty? end |
#eql?(other) ⇒ Boolean
100 101 102 |
# File 'lib/less/engine/nodes/element.rb', line 100 def eql? other super and self.equiv? other end |
#equiv?(other) ⇒ Boolean
104 105 106 107 108 109 |
# File 'lib/less/engine/nodes/element.rb', line 104 def equiv? other rules.size == other.rules.size and !rules.zip(other.rules).map do |a, b| a.to_css == b.to_css end.include?(false) end |
#first ⇒ Object
137 |
# File 'lib/less/engine/nodes/element.rb', line 137 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 |
# File 'lib/less/engine/nodes/element.rb', line 50 def group elements = self.elements.reject {|e| e.is_a?(Mixin::Def) } return self unless elements.size > 1 stack, result, matched = elements.dup, [], false elements.each do e = stack.first result << e unless matched matched = stack[1..-1].each do |ee| if e.equiv? ee and e.elements.size == 0 self[e].set << ee 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?; name =~ /^#/ end |
#identifiers ⇒ Object
Accessors for the different nodes in @rules
77 |
# File 'lib/less/engine/nodes/element.rb', line 77 def identifiers; @rules.select {|r| r.kind_of? Property } end |
#inspect(depth = 0) ⇒ Object
196 197 198 199 200 201 202 203 204 205 206 207 |
# File 'lib/less/engine/nodes/element.rb', line 196 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.to_s, put[ variables ], put[ properties ], put[ mixins ], elements.map {|i| i.inspect( depth + 1 ) } * "\n" ].reject(&:empty?).join("\n") + "\n" + indent[ depth ] end |
#last ⇒ Object
136 |
# File 'lib/less/engine/nodes/element.rb', line 136 def last; elements.last end |
#leaf? ⇒ Boolean
42 43 44 |
# File 'lib/less/engine/nodes/element.rb', line 42 def leaf? elements.empty? end |
#mixins ⇒ Object
81 |
# File 'lib/less/engine/nodes/element.rb', line 81 def mixins; @rules.select {|r| r.instance_of? Mixin::Call} end |
#nearest(ident, type = nil) ⇒ Object
Find the nearest node in the hierarchy or raise a NameError
174 175 176 177 178 179 180 181 |
# File 'lib/less/engine/nodes/element.rb', line 174 def nearest ident, type = nil ary = type || 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} in #{self.to_s}") if result.nil? && type != :mixin end end |
#parameters ⇒ Object
82 |
# File 'lib/less/engine/nodes/element.rb', line 82 def parameters; [] end |
#properties ⇒ Object
78 |
# File 'lib/less/engine/nodes/element.rb', line 78 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 = [], env = nil) ⇒ Object
Entry point for the css conversion
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/less/engine/nodes/element.rb', line 143 def to_css path = [], env = nil path << @selector.to_css << name unless root? # puts "to_css env: #{env ? env.variables : "nil"}" content = @rules.select do |r| r.is_a?(Mixin::Call) || r.instance_of?(Property) end.map do |i| ' ' * 2 + i.to_css(env) end.compact.reject(&:empty?) * "\n" content = content.include?("\n") ? "\n#{content}\n" : " #{content.strip} " ruleset = if is_a?(Mixin::Def) content.strip else !content.strip.empty?? "#{[path.reject(&:empty?).join.strip, *@set.map(&:name)].uniq * ', '} {#{content}}\n" : "" end ruleset + elements.reject {|e| e.is_a?(Mixin::Def) }.map do |i| i.to_css(path, env) end.reject(&:empty?).join ensure 2.times { path.pop } end |
#to_s ⇒ Object
138 |
# File 'lib/less/engine/nodes/element.rb', line 138 def to_s; root?? '*' : name end |
#universal? ⇒ Boolean
27 |
# File 'lib/less/engine/nodes/element.rb', line 27 def universal?; name == '*' end |