Sha256: a7dec483bb507a4b11eae1d2093d0febd61e1636ef794bc4ebc3a89ef5ad0835

Contents?: true

Size: 1.96 KB

Versions: 1

Compression:

Stored size: 1.96 KB

Contents

module SCSSLint
  # Checks the order of nested items within a rule set.
  class Linter::DeclarationOrder < Linter
    include LinterRegistry

    def check_order(node)
      check_node(node)
      yield # Continue linting children
    end

    alias_method :visit_rule, :check_order
    alias_method :visit_mixin, :check_order

  private

    MESSAGE =
      'Rule sets should be ordered as follows: '\
      '`@extends`, `@includes` without `@content`, ' \
      'properties, `@includes` with `@content`, ' \
      'nested rule sets'

    MIXIN_WITH_CONTENT = 'mixin_with_content'

    DECLARATION_ORDER = [
      Sass::Tree::ExtendNode,
      Sass::Tree::MixinNode,
      Sass::Tree::PropNode,
      MIXIN_WITH_CONTENT,
      Sass::Tree::RuleNode,
    ]

    def important_node?(node)
      DECLARATION_ORDER.include?(node.class)
    end

    def check_node(node)
      children = node.children.select { |n| important_node?(n) }
                              .map { |n| [n, node_declaration_type(n)] }

      sorted_children = children.sort do |(_, a_type), (_, b_type)|
        DECLARATION_ORDER.index(a_type) <=> DECLARATION_ORDER.index(b_type)
      end

      check_children_order(sorted_children, children)
    end

    # Find the child that is out of place
    def check_children_order(sorted_children, children)
      sorted_children.each_with_index do |sorted_item, index|
        next if sorted_item == children[index]

        add_lint(sorted_item.first.line,
                 "Expected item on line #{sorted_item.first.line} to appear " \
                 "before line #{children[index].first.line}. #{MESSAGE}")
        break
      end
    end

    def node_declaration_type(node)
      # If the node has no children, return the class.
      return node.class unless node.has_children

      # If the node is a mixin with children, indicate that;
      # otherwise, just return the class.
      return node.class unless node.is_a?(Sass::Tree::MixinNode)
      MIXIN_WITH_CONTENT
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
scss-lint-0.36.0 lib/scss_lint/linter/declaration_order.rb