Sha256: 565cba2cf403d538a006349a975541df70cc9106d47393df8c239c6df73bfbec

Contents?: true

Size: 1.99 KB

Versions: 1

Compression:

Stored size: 1.99 KB

Contents

module SCSSLint
  class Linter::Shorthand < Linter
    include LinterRegistry

    def visit_prop(node)
      property_name = node.name.join
      return unless SHORTHANDABLE_PROPERTIES.include?(property_name)

      case node.value
      when Sass::Script::Tree::Literal
        # HACK: node_parent may not be initialized at this point, so we need to
        # set it ourselves
        node.value.value.node_parent = node.value
        check_script_string(property_name, node.value.value)
      when Sass::Script::Tree::ListLiteral
        check_script_list(property_name, node.value)
      end
    end

  private

    SHORTHANDABLE_PROPERTIES = %w[
      border-color
      border-radius
      border-style
      border-width
      margin
      padding
    ]

    def check_script_list(prop, list)
      check_shorthand(prop, list, list.children.map(&:to_sass))
    end

    def check_script_string(prop, script_string)
      return unless script_string.type == :identifier

      if values = script_string.value.strip[/\A(\S+\s+\S+(\s+\S+){0,2})\z/, 1]
        check_shorthand(prop, script_string, values.split)
      end
    end

    def check_shorthand(prop, node, values)
      return unless (2..4).member?(values.count)

      shortest_form = condensed_shorthand(*values)
      return if values == shortest_form

      add_lint(node, "Shorthand form for property `#{prop}` should be " <<
                     "written more concisely as `#{shortest_form.join(' ')}` " <<
                     "instead of `#{values.join(' ')}`")
    end

    def condensed_shorthand(top, right, bottom = nil, left = nil)
      if top == right && right == bottom && bottom == left
        [top]
      elsif top == right && bottom.nil? && left.nil?
        [top]
      elsif top == bottom && right == left
        [top, right]
      elsif top == bottom && left.nil?
        top == right ? [top] : [top, right]
      elsif right == left
        [top, right, bottom]
      else
        [top, right, bottom, left].compact
      end
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
scss-lint-0.11.1 lib/scss_lint/linter/shorthand.rb