class Sass::Tree::Visitors::CheckNesting

A visitor for checking that all nodes are properly nested.

Constants

CONTROL_NODES
INVALID_IMPORT_PARENTS
SCRIPT_NODES
VALID_EXTEND_PARENTS
VALID_FUNCTION_CHILDREN
VALID_PROP_CHILDREN
VALID_PROP_PARENTS

Public Class Methods

new() click to toggle source
# File lib/sass/tree/visitors/check_nesting.rb, line 5
def initialize
  @parents = []
end

Protected Instance Methods

invalid_charset_parent?(parent, child) click to toggle source
# File lib/sass/tree/visitors/check_nesting.rb, line 66
def invalid_charset_parent?(parent, child)
  "@charset may only be used at the root of a document." unless parent.is_a?(Sass::Tree::RootNode)
end
invalid_content_parent?(parent, child) click to toggle source
# File lib/sass/tree/visitors/check_nesting.rb, line 57
def invalid_content_parent?(parent, child)
  if @current_mixin_def
    @current_mixin_def.has_content = true
    nil
  else
    "@content may only be used within a mixin."
  end
end
invalid_extend_parent?(parent, child) click to toggle source
# File lib/sass/tree/visitors/check_nesting.rb, line 71
def invalid_extend_parent?(parent, child)
  unless is_any_of?(parent, VALID_EXTEND_PARENTS)
    return "Extend directives may only be used within rules."
  end
end
invalid_function_child?(parent, child) click to toggle source
# File lib/sass/tree/visitors/check_nesting.rb, line 107
def invalid_function_child?(parent, child)
  unless is_any_of?(child, VALID_FUNCTION_CHILDREN)
    "Functions can only contain variable declarations and control directives."
  end
end
invalid_function_parent?(parent, child) click to toggle source
# File lib/sass/tree/visitors/check_nesting.rb, line 97
def invalid_function_parent?(parent, child)
  unless (@parents.map {|p| p.class} & INVALID_IMPORT_PARENTS).empty?
    return "Functions may not be defined within control directives or other mixins."
  end
end
invalid_import_parent?(parent, child) click to toggle source
# File lib/sass/tree/visitors/check_nesting.rb, line 79
def invalid_import_parent?(parent, child)
  unless (@parents.map {|p| p.class} & INVALID_IMPORT_PARENTS).empty?
    return "Import directives may not be used within control directives or mixins."
  end
  return if parent.is_a?(Sass::Tree::RootNode)
  return "CSS import directives may only be used at the root of a document." if child.css_import?
rescue Sass::SyntaxError => e
  e.modify_backtrace(:filename => child.imported_file.options[:filename])
  e.add_backtrace(:filename => child.filename, :line => child.line)
  raise e
end
invalid_mixindef_parent?(parent, child) click to toggle source
# File lib/sass/tree/visitors/check_nesting.rb, line 91
def invalid_mixindef_parent?(parent, child)
  unless (@parents.map {|p| p.class} & INVALID_IMPORT_PARENTS).empty?
    return "Mixins may not be defined within control directives or other mixins."
  end
end
invalid_prop_child?(parent, child) click to toggle source
# File lib/sass/tree/visitors/check_nesting.rb, line 114
def invalid_prop_child?(parent, child)
  unless is_any_of?(child, VALID_PROP_CHILDREN)
    "Illegal nesting: Only properties may be nested beneath properties."
  end
end
invalid_prop_parent?(parent, child) click to toggle source
# File lib/sass/tree/visitors/check_nesting.rb, line 123
def invalid_prop_parent?(parent, child)
  unless is_any_of?(parent, VALID_PROP_PARENTS)
    "Properties are only allowed within rules, directives, mixin includes, or other properties." + child.pseudo_class_selector_message
  end
end
invalid_return_parent?(parent, child) click to toggle source
# File lib/sass/tree/visitors/check_nesting.rb, line 129
def invalid_return_parent?(parent, child)
  "@return may only be used within a function." unless parent.is_a?(Sass::Tree::FunctionNode)
end
visit(node) click to toggle source
Calls superclass method Sass::Tree::Visitors::Base.visit
# File lib/sass/tree/visitors/check_nesting.rb, line 9
def visit(node)
  if error = @parent && (
      try_send("invalid_#{node_name @parent}_child?", @parent, node) ||
      try_send("invalid_#{node_name node}_parent?", @parent, node))
    raise Sass::SyntaxError.new(error)
  end
  super
rescue Sass::SyntaxError => e
  e.modify_backtrace(:filename => node.filename, :line => node.line)
  raise e
end
visit_children(parent) click to toggle source
# File lib/sass/tree/visitors/check_nesting.rb, line 24
def visit_children(parent)
  old_parent = @parent
  @parent = parent unless is_any_of?(parent, SCRIPT_NODES) ||
    (parent.bubbles? && !old_parent.is_a?(Sass::Tree::RootNode))
  @parents.push parent
  super
ensure
  @parent = old_parent
  @parents.pop
end
visit_import(node) { || ... } click to toggle source
# File lib/sass/tree/visitors/check_nesting.rb, line 42
def visit_import(node)
  yield
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_mixindef(node) { || ... } click to toggle source
# File lib/sass/tree/visitors/check_nesting.rb, line 50
def visit_mixindef(node)
  @current_mixin_def, old_mixin_def = node, @current_mixin_def
  yield
ensure
  @current_mixin_def = old_mixin_def
end
visit_root(node) { || ... } click to toggle source
# File lib/sass/tree/visitors/check_nesting.rb, line 35
def visit_root(node)
  yield
rescue Sass::SyntaxError => e
  e.sass_template ||= node.template
  raise e
end

Private Instance Methods

is_any_of?(val, classes) click to toggle source
# File lib/sass/tree/visitors/check_nesting.rb, line 135
def is_any_of?(val, classes)
  for c in classes
    return true if val.is_a?(c)
  end
  return false
end
try_send(method, *args) click to toggle source
# File lib/sass/tree/visitors/check_nesting.rb, line 142
def try_send(method, *args)
  return unless respond_to?(method, true)
  send(method, *args)
end