class Less::Node::Element

Element

div {…}

TODO: Look into making @rules its own hash-like class TODO: Look into whether selector should be child by default

Attributes

file[RW]
imported[RW]
name[RW]
rules[RW]
selector[RW]
set[RW]

Public Class Methods

new(name = "", selector = '') click to toggle source
# 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

Public Instance Methods

<<(obj) click to toggle source

Add an arbitrary node to this element

# 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) click to toggle source
# File lib/less/engine/nodes/element.rb, line 96
def == other
  name == other.name
end
[](key) click to toggle source

Select a child element TODO: Implement full selector syntax & merge with descend()

# 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?() click to toggle source
# File lib/less/engine/nodes/element.rb, line 25
def class?;     name =~ /^\./ end
descend(selector, element) click to toggle source

Same as above, except with a specific selector TODO: clean this up or implement it differently

# 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 = []) { |element, path| ... } click to toggle source

Traverse the whole tree, returning each leaf (recursive)

# 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() click to toggle source
# File lib/less/engine/nodes/element.rb, line 80
def elements;    @rules.select {|r| r.kind_of?     Element    } end
empty?() click to toggle source
# File lib/less/engine/nodes/element.rb, line 38
def empty?
  @rules.empty?
end
eql?(other) click to toggle source
Calls superclass method
# File lib/less/engine/nodes/element.rb, line 100
def eql? other
  super and self.equiv? other
end
equiv?(other) click to toggle source
# 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() click to toggle source
# File lib/less/engine/nodes/element.rb, line 137
def first; elements.first end
group() click to toggle source

Group similar rulesets together This is horrible, horrible code, but it'll have to do until I find a proper way to do it.

# 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?() click to toggle source
# File lib/less/engine/nodes/element.rb, line 26
def id?;        name =~ /^#/  end
identifiers() click to toggle source

Accessors for the different nodes in @rules

# File lib/less/engine/nodes/element.rb, line 77
def identifiers; @rules.select {|r| r.kind_of?     Property   } end
inspect(depth = 0) click to toggle source
# 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() click to toggle source
# File lib/less/engine/nodes/element.rb, line 136
def last;  elements.last  end
leaf?() click to toggle source
# File lib/less/engine/nodes/element.rb, line 42
def leaf?
  elements.empty?
end
mixins() click to toggle source
# File lib/less/engine/nodes/element.rb, line 81
def mixins;      @rules.select {|r| r.instance_of? Mixin::Call} end
nearest(ident, type = nil) click to toggle source

Find the nearest node in the hierarchy or raise a NameError

# 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() click to toggle source
# File lib/less/engine/nodes/element.rb, line 82
def parameters;  []                                             end
properties() click to toggle source
# File lib/less/engine/nodes/element.rb, line 78
def properties;  @rules.select {|r| r.instance_of? Property   } end
root?() click to toggle source

Top-most node?

# File lib/less/engine/nodes/element.rb, line 34
def root?
  parent.nil?
end
tag?() click to toggle source
# File lib/less/engine/nodes/element.rb, line 29
def tag?
  not id? || class? || universal?
end
to_css(path = [], env = nil) click to toggle source

Entry point for the css conversion

# 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() click to toggle source
# File lib/less/engine/nodes/element.rb, line 138
def to_s; root?? '*' : name end
universal?() click to toggle source
# File lib/less/engine/nodes/element.rb, line 27
def universal?; name == '*'   end
variables() click to toggle source
# File lib/less/engine/nodes/element.rb, line 79
def variables;   @rules.select {|r| r.instance_of? Variable   } end