class Sass::Tree::Visitors::Extend

A visitor for performing selector inheritance on a static CSS tree.

Destructively modifies the tree.

Public Class Methods

new(extends) click to toggle source
# File lib/sass/tree/visitors/extend.rb, line 21
def initialize(extends)
  @parent_directives = []
  @extends = extends
end
visit(root, extends) click to toggle source

Performs the given extensions on the static CSS tree based in ‘root`, then validates that all extends matched some selector.

@param root [Tree::Node] The root node of the tree to visit. @param extends [Sass::Util::SubsetMap{Selector::Simple =>

                                    Sass::Tree::Visitors::Cssize::Extend}]
The extensions to perform on this tree.

@return [Object] The return value of {#visit} for the root node.

# File lib/sass/tree/visitors/extend.rb, line 13
def self.visit(root, extends)
  return if extends.empty?
  new(extends).send(:visit, root)
  check_extends_fired! extends
end

Private Class Methods

check_extends_fired!(extends) click to toggle source
# File lib/sass/tree/visitors/extend.rb, line 50
    def check_extends_fired!(extends)
      extends.each_value do |ex|
        next if ex.success || ex.node.optional?
        message = "\"#{ex.extender}\" failed to @extend \"#{ex.target.join}\"."

        # TODO(nweiz): this should use the Sass stack trace of the extend node.
        raise Sass::SyntaxError.new(<<MESSAGE, :filename => ex.node.filename, :line => ex.node.line)
#{message}
The selector "#{ex.target.join}" was not found.
Use "@extend #{ex.target.join} !optional" if the extend should be able to fail.
MESSAGE
      end
    end

Protected Instance Methods

visit(node) click to toggle source

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

Calls superclass method Sass::Tree::Visitors::Base::visit
# File lib/sass/tree/visitors/extend.rb, line 27
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 directives.

# File lib/sass/tree/visitors/extend.rb, line 35
def visit_children(parent)
  @parent_directives.push parent if parent.is_a?(Sass::Tree::DirectiveNode)
  super
ensure
  @parent_directives.pop if parent.is_a?(Sass::Tree::DirectiveNode)
end
visit_rule(node) click to toggle source

Applies the extend to a single rule’s selector.

# File lib/sass/tree/visitors/extend.rb, line 43
def visit_rule(node)
  node.resolved_rules = node.resolved_rules.do_extend(@extends, @parent_directives)
end