Class/Module Index [+]

Quicksearch

Sass::Tree::Visitors::Cssize

A visitor for converting a static Sass tree into a static CSS tree.

Constants

Extend

A simple struct wrapping up information about a single `@extend` instance. A single [ExtendNode] can have multiple Extends if either the parent node or the extended selector is a comma sequence.

@attr extender [Sass::Selector::Sequence]

The selector of the CSS rule containing the `@extend`.

@attr target [Array<Sass::Selector::Simple>] The selector being `@extend`ed. @attr node [Sass::Tree::ExtendNode] The node that produced this extend. @attr directives [Array<Sass::Tree::DirectiveNode>]

The directives containing the `@extend`.

@attr result [Symbol]

The result of this extend. One of `:not_found` (the target doesn't exist
in the document), `:failed_to_unify` (the target exists but cannot be
unified with the extender), or `:succeeded`.
MERGEABLE_DIRECTIVES

Attributes

parent[R]

Returns the immediate parent of the current node. @return [Tree::Node]

Public Class Methods

new() click to toggle source
# File lib/sass/tree/visitors/cssize.rb, line 14
def initialize
  @parent_directives = []
  @extends = Sass::Util::SubsetMap.new
end
visit(root) click to toggle source

@param root [Tree::Node] The root node of the tree to visit. @return [(Tree::Node, Sass::Util::SubsetMap)] The resulting tree of static nodes

*and* the extensions defined for this tree
# File lib/sass/tree/visitors/cssize.rb, line 6
def self.visit(root); super; end

Protected Instance Methods

visit(node) click to toggle source

If an exception is raised, this adds proper metadata to the backtrace.

# File lib/sass/tree/visitors/cssize.rb, line 20
def visit(node)
  super(node)
rescue Sass::SyntaxError => e
  e.modify_backtrace(:filename => node.filename, :line => node.line)
  raise e
end
visit_children(parent) click to toggle source

Keeps track of the current parent node.

# File lib/sass/tree/visitors/cssize.rb, line 28
def visit_children(parent)
  with_parent parent do
    parent.children = super.flatten
    parent
  end
end
visit_extend(node) click to toggle source

Registers an extension in the `@extends` subset map.

# File lib/sass/tree/visitors/cssize.rb, line 113
def visit_extend(node)
  node.resolved_selector.members.each do |seq|
    if seq.members.size > 1
      raise Sass::SyntaxError.new("Can't extend #{seq.to_a.join}: can't extend nested selectors")
    end

    sseq = seq.members.first
    if !sseq.is_a?(Sass::Selector::SimpleSequence)
      raise Sass::SyntaxError.new("Can't extend #{seq.to_a.join}: invalid selector")
    elsif sseq.members.any? {|ss| ss.is_a?(Sass::Selector::Parent)}
      raise Sass::SyntaxError.new("Can't extend #{seq.to_a.join}: can't extend parent selectors")
    end

    sel = sseq.members
    parent.resolved_rules.members.each do |member|
      if !member.members.last.is_a?(Sass::Selector::SimpleSequence)
        raise Sass::SyntaxError.new("#{member} can't extend: invalid selector")
      end

      @extends[sel] = Extend.new(member, sel, node, @parent_directives.dup, :not_found)
    end
  end

  []
end
visit_import(node) click to toggle source

Modifies exception backtraces to include the imported file.

# File lib/sass/tree/visitors/cssize.rb, line 140
def visit_import(node)
  # Don't use #visit_children to avoid adding the import node to the list of parents.
  node.children.map {|c| visit(c)}.flatten
rescue Sass::SyntaxError => e
  e.modify_backtrace(:filename => node.children.first.filename)
  e.add_backtrace(:filename => node.filename, :line => node.line)
  raise e
end
visit_media(node) click to toggle source

Bubbles the `@media` directive up through RuleNodes and merges it with other `@media` directives.

# File lib/sass/tree/visitors/cssize.rb, line 151
def visit_media(node)
  yield unless bubble(node)
  media = node.children.select {|c| c.is_a?(Sass::Tree::MediaNode)}
  node.children.reject! {|c| c.is_a?(Sass::Tree::MediaNode)}
  media = media.select {|n| n.resolved_query = n.resolved_query.merge(node.resolved_query)}
  (node.children.empty? ? [] : [node]) + media
end
visit_prop(node) click to toggle source

Converts nested properties into flat properties and updates the indentation of the prop node based on the nesting level.

# File lib/sass/tree/visitors/cssize.rb, line 177
def visit_prop(node)
  if parent.is_a?(Sass::Tree::PropNode)
    node.resolved_name = "#{parent.resolved_name}-#{node.resolved_name}"
    node.tabs = parent.tabs + (parent.resolved_value.empty? ? 0 : 1) if node.style == :nested
  end

  yield

  result = node.children.dup
  if !node.resolved_value.empty? || node.children.empty?
    node.send(:check!)
    result.unshift(node)
  end

  result
end
visit_root(node) click to toggle source

In Ruby 1.8, ensures that there's only one `@charset` directive and that it's at the top of the document.

@return [(Tree::Node, Sass::Util::SubsetMap)] The resulting tree of static nodes

*and* the extensions defined for this tree
# File lib/sass/tree/visitors/cssize.rb, line 64
def visit_root(node)
  yield

  if parent.nil?
    # In Ruby 1.9 we can make all @charset nodes invisible
    # and infer the final @charset from the encoding of the final string.
    if Sass::Util.ruby1_8?
      charset = node.children.find {|c| c.is_a?(Sass::Tree::CharsetNode)}
      node.children.reject! {|c| c.is_a?(Sass::Tree::CharsetNode)}
      node.children.unshift charset if charset
    end

    imports = Sass::Util.extract!(node.children) do |c|
      c.is_a?(Sass::Tree::DirectiveNode) && !c.is_a?(Sass::Tree::MediaNode) &&
        c.resolved_value =~ /^@import /
    end
    charset_and_index = Sass::Util.ruby1_8? &&
      node.children.each_with_index.find {|c, _| c.is_a?(Sass::Tree::CharsetNode)}
    if charset_and_index
      index = charset_and_index.last
      node.children = node.children[0..index] + imports + node.children[index+1..-1]
    else
      node.children = imports + node.children
    end
  end

  return node, @extends
rescue Sass::SyntaxError => e
  e.sass_template ||= node.template
  raise e
end
visit_rule(node) click to toggle source

Resolves parent references and nested selectors, and updates the indentation of the rule node based on the nesting level.

# File lib/sass/tree/visitors/cssize.rb, line 196
def visit_rule(node)
  parent_resolved_rules = parent.is_a?(Sass::Tree::RuleNode) ? parent.resolved_rules : nil
  # It's possible for resolved_rules to be set if we've duplicated this node during @media bubbling
  node.resolved_rules ||= node.parsed_rules.resolve_parent_refs(parent_resolved_rules)

  yield

  rules = node.children.select {|c| c.is_a?(Sass::Tree::RuleNode) || c.bubbles?}
  props = node.children.reject {|c| c.is_a?(Sass::Tree::RuleNode) || c.bubbles? || c.invisible?}

  unless props.empty?
    node.children = props
    rules.each {|r| r.tabs += 1} if node.style == :nested
    rules.unshift(node)
  end

  rules.last.group_end = true unless parent.is_a?(Sass::Tree::RuleNode) || rules.empty?

  rules
end
visit_supports(node) click to toggle source

Bubbles the `@supports` directive up through RuleNodes.

# File lib/sass/tree/visitors/cssize.rb, line 160
def visit_supports(node)
  yield unless bubble(node)
  node
end
visit_trace(node) click to toggle source

Asserts that all the traced children are valid in their new location.

# File lib/sass/tree/visitors/cssize.rb, line 166
def visit_trace(node)
  # Don't use #visit_children to avoid adding the trace node to the list of parents.
  node.children.map {|c| visit(c)}.flatten
rescue Sass::SyntaxError => e
  e.modify_backtrace(:mixin => node.name, :filename => node.filename, :line => node.line)
  e.add_backtrace(:filename => node.filename, :line => node.line)
  raise e
end
with_parent(parent) click to toggle source

Runs a block of code with the current parent node replaced with the given node.

@param parent [Tree::Node] The new parent for the duration of the block. @yield A block in which the parent is set to `parent`. @return [Object] The return value of the block.

# File lib/sass/tree/visitors/cssize.rb, line 43
def with_parent(parent)
  if parent.is_a?(Sass::Tree::DirectiveNode)
    if MERGEABLE_DIRECTIVES.any? {|klass| parent.is_a?(klass)}
      old_parent_directive = @parent_directives.pop
    end
    @parent_directives.push parent
  end

  old_parent, @parent = @parent, parent
  yield
ensure
  @parent_directives.pop if parent.is_a?(Sass::Tree::DirectiveNode)
  @parent_directives.push old_parent_directive if old_parent_directive
  @parent = old_parent
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.