Class: Less::Node::Element

Inherits:
String show all
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

Attributes included from Entity

#parent

Instance Method Summary collapse

Methods included from Entity

#path, #root

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

#fileObject

Returns the value of attribute file.



15
16
17
# File 'lib/less/engine/nodes/element.rb', line 15

def file
  @file
end

#partialObject

Returns the value of attribute partial.



15
16
17
# File 'lib/less/engine/nodes/element.rb', line 15

def partial
  @partial
end

#rulesObject

Returns the value of attribute rules.



15
16
17
# File 'lib/less/engine/nodes/element.rb', line 15

def rules
  @rules
end

#selectorObject

Returns the value of attribute selector.



15
16
17
# File 'lib/less/engine/nodes/element.rb', line 15

def selector
  @selector
end

#setObject

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

Returns:

  • (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

#elementsObject



89
# File 'lib/less/engine/nodes/element.rb', line 89

def elements;    @rules.select {|r| r.instance_of? Element  } end

#empty?Boolean

Returns:

  • (Boolean)


38
39
40
# File 'lib/less/engine/nodes/element.rb', line 38

def empty?
  @rules.empty?
end

#firstObject



123
# File 'lib/less/engine/nodes/element.rb', line 123

def first; elements.first end

#groupObject

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

Returns:

  • (Boolean)


26
# File 'lib/less/engine/nodes/element.rb', line 26

def id?;        self =~ /^#/  end

#identifiersObject

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

#lastObject



122
# File 'lib/less/engine/nodes/element.rb', line 122

def last;  elements.last  end

#leaf?Boolean

Returns:

  • (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

#propertiesObject



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?

Returns:

  • (Boolean)


34
35
36
# File 'lib/less/engine/nodes/element.rb', line 34

def root?
  parent.nil?
end

#tag?Boolean

Returns:

  • (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_sObject



124
# File 'lib/less/engine/nodes/element.rb', line 124

def to_s; root?? '*' : super end

#universal?Boolean

Returns:

  • (Boolean)


27
# File 'lib/less/engine/nodes/element.rb', line 27

def universal?; self == '*'   end

#variablesObject



88
# File 'lib/less/engine/nodes/element.rb', line 88

def variables;   @rules.select {|r| r.instance_of? Variable } end