class SCSSLint::Linter::ColorVariable

Ensures color literals are used only in variable declarations.

Constants

COLOR_FUNCTIONS

Public Instance Methods

visit_script_color(node) click to toggle source
# File lib/scss_lint/linter/color_variable.rb, line 8
def visit_script_color(node)
  return if in_variable_declaration?(node) ||
            in_map_declaration?(node) ||
            in_rgba_function_call?(node)

  # Source range sometimes includes closing parenthesis, so extract it
  color = source_from_range(node.source_range)[/(#?[a-z0-9]+)/i, 1]

  record_lint(node, color) if color?(color)
end
visit_script_funcall(node) { || ... } click to toggle source
# File lib/scss_lint/linter/color_variable.rb, line 27
def visit_script_funcall(node)
  if literal_color_function?(node)
    record_lint node, node.to_sass
  else
    yield
  end
end
visit_script_string(node) click to toggle source
# File lib/scss_lint/linter/color_variable.rb, line 19
def visit_script_string(node)
  return if literal_string?(node)
  remove_quoted_strings(node.value)
    .scan(/(^|\s)(#[a-f0-9]+|[a-z]+)(?=\s|$)/i)
    .select { |_, word| color?(word) }
    .each   { |_, color| record_lint(node, color) }
end

Private Instance Methods

all_arguments_are_literals?(node) click to toggle source
# File lib/scss_lint/linter/color_variable.rb, line 75
def all_arguments_are_literals?(node)
  node.args.all? do |arg|
    arg.is_a?(Sass::Script::Tree::Literal)
  end
end
color_function?(node) click to toggle source
# File lib/scss_lint/linter/color_variable.rb, line 81
def color_function?(node)
  COLOR_FUNCTIONS.include?(node.name)
end
function_in_variable_declaration?(node) click to toggle source
# File lib/scss_lint/linter/color_variable.rb, line 59
def function_in_variable_declaration?(node)
  node.node_parent.is_a?(Sass::Tree::VariableNode) ||
    node.node_parent.node_parent.is_a?(Sass::Tree::VariableNode)
end
in_map_declaration?(node) click to toggle source
# File lib/scss_lint/linter/color_variable.rb, line 71
def in_map_declaration?(node)
  node_ancestor(node, 2).is_a?(Sass::Script::Tree::MapLiteral)
end
in_rgba_function_call?(node) click to toggle source
# File lib/scss_lint/linter/color_variable.rb, line 64
def in_rgba_function_call?(node)
  grandparent = node_ancestor(node, 2)

  grandparent.is_a?(Sass::Script::Tree::Funcall) &&
    grandparent.name == 'rgba'
end
in_variable_declaration?(node) click to toggle source
# File lib/scss_lint/linter/color_variable.rb, line 52
def in_variable_declaration?(node)
  parent = node.node_parent
  parent.is_a?(Sass::Script::Tree::Literal) &&
    (parent.node_parent.is_a?(Sass::Tree::VariableNode) ||
     parent.node_parent.node_parent.is_a?(Sass::Tree::VariableNode))
end
literal_color_function?(node) click to toggle source
# File lib/scss_lint/linter/color_variable.rb, line 85
def literal_color_function?(node)
  color_function?(node) &&
    all_arguments_are_literals?(node) &&
    !function_in_variable_declaration?(node)
end
literal_string?(script_string) click to toggle source
# File lib/scss_lint/linter/color_variable.rb, line 43
def literal_string?(script_string)
  return unless script_string.respond_to?(:source_range) &&
    source_range = script_string.source_range

  # If original source starts with a quote character, it's a string, not a
  # color
  %w[' "].include?(source_from_range(source_range)[0])
end
record_lint(node, color) click to toggle source
# File lib/scss_lint/linter/color_variable.rb, line 37
def record_lint(node, color)
  add_lint node, "Color literals like `#{color}` should only be used in " \
                 'variable declarations; they should be referred to via ' \
                 'variable everywhere else.'
end