scss-lint 0.9.0 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/sass/script.rb +36 -0
- data/lib/sass/tree.rb +9 -2
- data/lib/scss_lint/linter/capitalization_in_selector.rb +30 -5
- data/lib/scss_lint/linter/color_keyword.rb +19 -0
- data/lib/scss_lint/linter/declared_name.rb +10 -15
- data/lib/scss_lint/linter/hex_format.rb +29 -21
- data/lib/scss_lint/linter/id_with_extraneous_selector.rb +15 -0
- data/lib/scss_lint/linter/usage_name.rb +23 -11
- data/lib/scss_lint/linter/zero_unit.rb +17 -4
- data/lib/scss_lint/linter.rb +16 -4
- data/lib/scss_lint/selector_visitor.rb +32 -0
- data/lib/scss_lint/utils.rb +0 -8
- data/lib/scss_lint/version.rb +1 -1
- data/lib/scss_lint.rb +1 -0
- metadata +9 -6
- data/lib/scss_lint/linter/type_in_id_selector.rb +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c4c60cb7b446fd21b69324b554345c0d2fbb63af
|
4
|
+
data.tar.gz: c12498e673473f6305b6216fa0151ef755121b5a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ba86ab4dc998719d5f11e26cb6d842c3bf9aec9535f3742a93fd8cbb975b4ff300f0aaefc8f127b99ab9ff642b5ee15a4aa0320c82b003805ba3edca5cb84408
|
7
|
+
data.tar.gz: b1e5c3b72ab4300347138727dc13963fefbde3be4c9adb88c9bc8c3791c43a695f070268b2ca20f4b9a921a662aec822df1983587bc50341e6c22eecba700bd7
|
data/lib/sass/script.rb
CHANGED
@@ -9,4 +9,40 @@ module Sass::Script
|
|
9
9
|
@name
|
10
10
|
end
|
11
11
|
end
|
12
|
+
|
13
|
+
# When linting colors, it's convenient to be able to inspect the original
|
14
|
+
# color string. This adds an attribute to the Color to keep track of the
|
15
|
+
# original string and provides a method which the modified lexer can use to
|
16
|
+
# set it.
|
17
|
+
class Color
|
18
|
+
attr_accessor :original
|
19
|
+
|
20
|
+
def self.from_string(string)
|
21
|
+
rgb = string.scan(/^#(..?)(..?)(..?)$/).
|
22
|
+
first.
|
23
|
+
map { |hex| hex.ljust(2, hex).to_i(16) }
|
24
|
+
|
25
|
+
color = Color.new(rgb, false)
|
26
|
+
color.original = string
|
27
|
+
color
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class Lexer
|
32
|
+
# We redefine the color lexer to store the original string with the created
|
33
|
+
# `Color` object so that we can inspect the original string before it is
|
34
|
+
# normalized.
|
35
|
+
#
|
36
|
+
# This is an adapted version from the original Sass source code.
|
37
|
+
def color
|
38
|
+
return unless color_string = scan(REGULAR_EXPRESSIONS[:color])
|
39
|
+
|
40
|
+
unless [4, 7].include?(color_string.length)
|
41
|
+
raise ::Sass::SyntaxError,
|
42
|
+
"Colors must have either three or six digits: '#{color_string}'"
|
43
|
+
end
|
44
|
+
|
45
|
+
[:color, Color.from_string(color_string)]
|
46
|
+
end
|
47
|
+
end
|
12
48
|
end
|
data/lib/sass/tree.rb
CHANGED
@@ -10,10 +10,17 @@ module Sass::Tree
|
|
10
10
|
# numbers back in so lint reporting works for those nodes.
|
11
11
|
def add_line_numbers_to_args(arg_list)
|
12
12
|
arg_list.each do |variable, default_expr|
|
13
|
-
variable
|
13
|
+
add_line_number(variable)
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
+
# The Sass parser sometimes doesn't assign line numbers in cases where it
|
18
|
+
# should. This is a helper to easily correct that.
|
19
|
+
def add_line_number(node)
|
20
|
+
node.line ||= line if node.is_a?(Sass::Script::Node)
|
21
|
+
node
|
22
|
+
end
|
23
|
+
|
17
24
|
# Sometimes the parse tree doesn't return a Sass::Script::Variable, but just
|
18
25
|
# the name of the variable. This helper takes that name and turns it back
|
19
26
|
# into a Sass::Script::Variable that supports lint reporting.
|
@@ -117,7 +124,7 @@ module Sass::Tree
|
|
117
124
|
|
118
125
|
class PropNode
|
119
126
|
def children
|
120
|
-
concat_expr_lists super, extract_script_nodes(name), value
|
127
|
+
concat_expr_lists super, extract_script_nodes(name), add_line_number(value)
|
121
128
|
end
|
122
129
|
end
|
123
130
|
|
@@ -2,14 +2,39 @@ module SCSSLint
|
|
2
2
|
class Linter::CapitalizationInSelector < Linter
|
3
3
|
include LinterRegistry
|
4
4
|
|
5
|
-
def
|
6
|
-
|
5
|
+
def visit_attribute(attribute)
|
6
|
+
check(attribute)
|
7
|
+
end
|
8
|
+
|
9
|
+
def visit_class(klass)
|
10
|
+
check(klass)
|
11
|
+
end
|
12
|
+
|
13
|
+
def visit_element(element)
|
14
|
+
check(element)
|
15
|
+
end
|
7
16
|
|
8
|
-
|
17
|
+
def visit_id(id)
|
18
|
+
check(id)
|
9
19
|
end
|
10
20
|
|
11
|
-
def
|
12
|
-
|
21
|
+
def visit_placeholder(placeholder)
|
22
|
+
check(placeholder)
|
23
|
+
end
|
24
|
+
|
25
|
+
def visit_pseudo(pseudo)
|
26
|
+
check(pseudo, 'Pseudo-selector')
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def check(node, selector_name = nil)
|
32
|
+
name = node.name.join
|
33
|
+
if name =~ /[A-Z]/
|
34
|
+
selector_name ||= node.class.name.split('::').last
|
35
|
+
add_lint(node, "#{selector_name} `#{name}` in selector should be " <<
|
36
|
+
"written in all lowercase as `#{name.downcase}`")
|
37
|
+
end
|
13
38
|
end
|
14
39
|
end
|
15
40
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module SCSSLint
|
2
|
+
class Linter::ColorKeyword < Linter
|
3
|
+
include LinterRegistry
|
4
|
+
|
5
|
+
def visit_script_string(node)
|
6
|
+
add_lint(node) if color_keyword?(node.value)
|
7
|
+
end
|
8
|
+
|
9
|
+
def description
|
10
|
+
'Colors should be specified as hexadecimal values, not names'
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def color_keyword?(string)
|
16
|
+
!!Sass::Script::Color::COLOR_NAMES[string]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -3,34 +3,29 @@ module SCSSLint
|
|
3
3
|
include LinterRegistry
|
4
4
|
|
5
5
|
def visit_function(node)
|
6
|
-
check(node)
|
6
|
+
check(node, 'function')
|
7
7
|
yield # Continue into content block of this function definition
|
8
8
|
end
|
9
9
|
|
10
10
|
def visit_mixindef(node)
|
11
|
-
check(node)
|
11
|
+
check(node, 'mixin')
|
12
12
|
yield # Continue into content block of this mixin definition
|
13
13
|
end
|
14
14
|
|
15
|
-
def visit_rule(node)
|
16
|
-
add_lint(node) if selector_has_bad_placeholder?(node.rule)
|
17
|
-
yield # Continue linting into content block of this rule definition
|
18
|
-
end
|
19
|
-
|
20
15
|
def visit_variable(node)
|
21
|
-
check(node)
|
16
|
+
check(node, 'variable')
|
22
17
|
yield # Continue into expression tree for this variable definition
|
23
18
|
end
|
24
19
|
|
25
|
-
def description
|
26
|
-
'Names of variables, functions, mixins, and placeholders should be ' <<
|
27
|
-
'lowercase and use hyphens instead of underscores.'
|
28
|
-
end
|
29
|
-
|
30
20
|
private
|
31
21
|
|
32
|
-
def check(node)
|
33
|
-
|
22
|
+
def check(node, node_type)
|
23
|
+
if node_has_bad_name?(node)
|
24
|
+
fixed_name = node.name.downcase.gsub(/_/, '-')
|
25
|
+
|
26
|
+
add_lint(node, "Name of #{node_type} `#{node.name}` should " <<
|
27
|
+
"be written in lowercase as `#{fixed_name}`")
|
28
|
+
end
|
34
29
|
end
|
35
30
|
end
|
36
31
|
end
|
@@ -2,37 +2,45 @@ module SCSSLint
|
|
2
2
|
class Linter::HexFormat < Linter
|
3
3
|
include LinterRegistry
|
4
4
|
|
5
|
-
def
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
line.scan /#(\h{3,6})/ do |match|
|
12
|
-
unless valid_hex?(match.first)
|
13
|
-
@lints << Lint.new(engine.filename, index + 1, description)
|
14
|
-
end
|
5
|
+
def visit_prop(node)
|
6
|
+
if node.value.is_a?(Sass::Script::String) &&
|
7
|
+
node.value.type == :identifier
|
8
|
+
|
9
|
+
node.value.value.scan(HEX_REGEX) do |match|
|
10
|
+
add_hex_lint(node, match.first) unless valid_hex_format?(match.first)
|
15
11
|
end
|
16
12
|
end
|
13
|
+
|
14
|
+
yield # Continue visiting children
|
17
15
|
end
|
18
16
|
|
19
|
-
def
|
20
|
-
|
17
|
+
def visit_script_color(node)
|
18
|
+
unless valid_hex_format?(node.original[HEX_REGEX, 1])
|
19
|
+
add_hex_lint(node, node.original)
|
20
|
+
end
|
21
21
|
end
|
22
22
|
|
23
23
|
private
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
25
|
+
HEX_REGEX = /(#\h{3,6})/
|
26
|
+
|
27
|
+
def add_hex_lint(node, hex)
|
28
|
+
add_lint(node, "Color `#{hex}` should be written as `#{shortest_form(hex)}`")
|
29
|
+
end
|
30
|
+
|
31
|
+
def valid_hex_format?(hex)
|
32
|
+
hex == shortest_form(hex)
|
33
|
+
end
|
34
|
+
|
35
|
+
def shortest_form(hex)
|
36
|
+
(can_be_condensed?(hex) ? (hex[0..1] + hex[3] + hex[5]) : hex).downcase
|
29
37
|
end
|
30
38
|
|
31
|
-
def can_be_condensed(hex)
|
32
|
-
hex.length ==
|
33
|
-
hex[
|
34
|
-
hex[
|
35
|
-
hex[
|
39
|
+
def can_be_condensed?(hex)
|
40
|
+
hex.length == 7 &&
|
41
|
+
hex[1] == hex[2] &&
|
42
|
+
hex[3] == hex[4] &&
|
43
|
+
hex[5] == hex[6]
|
36
44
|
end
|
37
45
|
end
|
38
46
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module SCSSLint
|
2
|
+
class Linter::IdWithExtraneousSelector < Linter
|
3
|
+
include LinterRegistry
|
4
|
+
|
5
|
+
def visit_simple_sequence(seq)
|
6
|
+
id_sel = seq.members.find { |simple| simple.is_a?(Sass::Selector::Id) }
|
7
|
+
return unless id_sel
|
8
|
+
|
9
|
+
if seq.members.any? { |simple| !simple.is_a?(Sass::Selector::Id) }
|
10
|
+
add_lint(seq, "Selector `#{seq}` can be simplified to `#{id_sel}`, " <<
|
11
|
+
'since IDs should be uniquely identifying')
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -3,25 +3,22 @@ module SCSSLint
|
|
3
3
|
include LinterRegistry
|
4
4
|
|
5
5
|
def visit_extend(node)
|
6
|
-
|
6
|
+
if selector_has_bad_placeholder?(node.selector)
|
7
|
+
add_name_lint(node, node.selector.join, 'placeholder')
|
8
|
+
end
|
7
9
|
end
|
8
10
|
|
9
11
|
def visit_mixin(node)
|
10
|
-
check(node)
|
12
|
+
check(node, 'mixin')
|
11
13
|
yield # Continue into content block of this mixin's block
|
12
14
|
end
|
13
15
|
|
14
16
|
def visit_script_funcall(node)
|
15
|
-
check(node) unless FUNCTION_WHITELIST.include?(node.name)
|
17
|
+
check(node, 'function') unless FUNCTION_WHITELIST.include?(node.name)
|
16
18
|
end
|
17
19
|
|
18
20
|
def visit_script_variable(node)
|
19
|
-
check(node)
|
20
|
-
end
|
21
|
-
|
22
|
-
def description
|
23
|
-
'Usages of variables, functions, mixins, and placeholders should be ' <<
|
24
|
-
'lowercase and use hyphens instead of underscores.'
|
21
|
+
check(node, 'variable')
|
25
22
|
end
|
26
23
|
|
27
24
|
private
|
@@ -33,8 +30,23 @@ module SCSSLint
|
|
33
30
|
translateX translateY translateZ
|
34
31
|
].to_set
|
35
32
|
|
36
|
-
def check(node)
|
37
|
-
|
33
|
+
def check(node, node_type)
|
34
|
+
add_name_lint(node, node.name, node_type) if node_has_bad_name?(node)
|
35
|
+
end
|
36
|
+
|
37
|
+
def add_name_lint(node, name, node_type)
|
38
|
+
fixed_name = name.downcase.gsub(/_/, '-')
|
39
|
+
|
40
|
+
add_lint(node, "All uses of #{node_type} `#{name}` should be written " <<
|
41
|
+
"in lowercase as `#{fixed_name}`")
|
42
|
+
end
|
43
|
+
|
44
|
+
# Given a selector array, returns whether it contains any placeholder
|
45
|
+
# selectors with invalid names.
|
46
|
+
def selector_has_bad_placeholder?(selector_array)
|
47
|
+
extract_string_selectors(selector_array).any? do |selector_str|
|
48
|
+
selector_str =~ /%\w*#{INVALID_NAME_CHARS}/
|
49
|
+
end
|
38
50
|
end
|
39
51
|
end
|
40
52
|
end
|
@@ -3,12 +3,25 @@ module SCSSLint
|
|
3
3
|
include LinterRegistry
|
4
4
|
|
5
5
|
def visit_prop(node)
|
6
|
-
|
7
|
-
|
6
|
+
if node.value.is_a?(Sass::Script::String) &&
|
7
|
+
node.value.type == :identifier
|
8
|
+
|
9
|
+
node.value.value.scan(/\b(0[a-z]+)\b/i) do |match|
|
10
|
+
add_lint(node, MESSAGE_FORMAT % match.first)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
yield # Continue visiting children
|
8
15
|
end
|
9
16
|
|
10
|
-
def
|
11
|
-
|
17
|
+
def visit_script_number(node)
|
18
|
+
if node.value == 0 && !node.unitless?
|
19
|
+
add_lint(node, MESSAGE_FORMAT % node.original)
|
20
|
+
end
|
12
21
|
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
MESSAGE_FORMAT = '`%s` should be written without units as `0`'
|
13
26
|
end
|
14
27
|
end
|
data/lib/scss_lint/linter.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
module SCSSLint
|
2
2
|
class Linter < Sass::Tree::Visitors::Base
|
3
|
+
include SelectorVisitor
|
3
4
|
include Utils
|
4
5
|
|
5
6
|
attr_reader :engine, :lints
|
@@ -13,15 +14,16 @@ module SCSSLint
|
|
13
14
|
visit(engine.tree)
|
14
15
|
end
|
15
16
|
|
17
|
+
# Define if you want a default message for your linter
|
16
18
|
def description
|
17
19
|
nil
|
18
20
|
end
|
19
21
|
|
20
|
-
protected
|
21
|
-
|
22
22
|
# Helper for creating lint from a parse tree node
|
23
|
-
def add_lint(node)
|
24
|
-
@lints << Lint.new(engine.filename,
|
23
|
+
def add_lint(node, message = nil)
|
24
|
+
@lints << Lint.new(engine.filename,
|
25
|
+
node.line,
|
26
|
+
message || description)
|
25
27
|
end
|
26
28
|
|
27
29
|
# Monkey-patched implementation that adds support for traversing
|
@@ -34,5 +36,15 @@ module SCSSLint
|
|
34
36
|
super
|
35
37
|
end
|
36
38
|
end
|
39
|
+
|
40
|
+
# Modified so we can also visit selectors in linters
|
41
|
+
def visit(node)
|
42
|
+
# Visit the selector of a rule if parsed rules are available
|
43
|
+
if node.is_a?(Sass::Tree::RuleNode) && node.parsed_rules
|
44
|
+
visit_selector(node.parsed_rules)
|
45
|
+
end
|
46
|
+
|
47
|
+
super
|
48
|
+
end
|
37
49
|
end
|
38
50
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module SCSSLint
|
2
|
+
# Provides functionality for conveniently visiting a Selector sequence.
|
3
|
+
module SelectorVisitor
|
4
|
+
def visit_selector(node)
|
5
|
+
visit_selector_node(node)
|
6
|
+
end
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def visit_selector_node(node)
|
11
|
+
method = "visit_#{selector_node_name(node)}"
|
12
|
+
send(method, node) if respond_to?(method, true)
|
13
|
+
|
14
|
+
visit_members(node) if node.is_a?(Sass::Selector::AbstractSequence)
|
15
|
+
end
|
16
|
+
|
17
|
+
def visit_members(sequence)
|
18
|
+
sequence.members.each do |member|
|
19
|
+
visit_selector(member)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def selector_node_name(node)
|
24
|
+
# Converts the class name of a node into snake_case form, e.g.
|
25
|
+
# `Sass::Selector::SimpleSequence` -> `simple_sequence`
|
26
|
+
node.class.name.gsub(/.*::(.*?)$/, '\\1').
|
27
|
+
gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').
|
28
|
+
gsub(/([a-z\d])([A-Z])/, '\1_\2').
|
29
|
+
downcase
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/scss_lint/utils.rb
CHANGED
@@ -19,14 +19,6 @@ module SCSSLint
|
|
19
19
|
split
|
20
20
|
end
|
21
21
|
|
22
|
-
# Given a selector array, returns whether it contains any placeholder
|
23
|
-
# selectors with invalid names.
|
24
|
-
def selector_has_bad_placeholder?(selector_array)
|
25
|
-
extract_string_selectors(selector_array).any? do |selector_str|
|
26
|
-
selector_str =~ /%\w*#{INVALID_NAME_CHARS}/
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
22
|
def node_has_bad_name?(node)
|
31
23
|
node.name =~ /#{INVALID_NAME_CHARS}/
|
32
24
|
end
|
data/lib/scss_lint/version.rb
CHANGED
data/lib/scss_lint.rb
CHANGED
@@ -8,6 +8,7 @@ module SCSSLint
|
|
8
8
|
autoload :Linter, 'scss_lint/linter'
|
9
9
|
autoload :Reporter, 'scss_lint/reporter'
|
10
10
|
autoload :Runner, 'scss_lint/runner'
|
11
|
+
autoload :SelectorVisitor, 'scss_lint/selector_visitor'
|
11
12
|
autoload :Utils, 'scss_lint/utils'
|
12
13
|
autoload :VERSION, 'scss_lint/version'
|
13
14
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scss-lint
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Causes Engineering
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-09-
|
11
|
+
date: 2013-09-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: colorize
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - '='
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 3.2.
|
33
|
+
version: 3.2.10
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - '='
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 3.2.
|
40
|
+
version: 3.2.10
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: nokogiri
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,7 +66,7 @@ dependencies:
|
|
66
66
|
- - '>='
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
-
description: Opinionated tool
|
69
|
+
description: Opinionated tool to help write clean and consistent SCSS
|
70
70
|
email:
|
71
71
|
- eng@causes.com
|
72
72
|
- shane@causes.com
|
@@ -83,13 +83,14 @@ files:
|
|
83
83
|
- lib/scss_lint/reporter.rb
|
84
84
|
- lib/scss_lint/lint.rb
|
85
85
|
- lib/scss_lint/linter.rb
|
86
|
+
- lib/scss_lint/selector_visitor.rb
|
86
87
|
- lib/scss_lint/linter/property_format.rb
|
87
88
|
- lib/scss_lint/linter/space_before_brace.rb
|
88
89
|
- lib/scss_lint/linter/capitalization_in_selector.rb
|
89
90
|
- lib/scss_lint/linter/declared_name.rb
|
90
91
|
- lib/scss_lint/linter/sorted_properties.rb
|
91
|
-
- lib/scss_lint/linter/type_in_id_selector.rb
|
92
92
|
- lib/scss_lint/linter/shorthand.rb
|
93
|
+
- lib/scss_lint/linter/id_with_extraneous_selector.rb
|
93
94
|
- lib/scss_lint/linter/declaration_order.rb
|
94
95
|
- lib/scss_lint/linter/no_zero_before_decimal.rb
|
95
96
|
- lib/scss_lint/linter/zero_unit.rb
|
@@ -98,6 +99,7 @@ files:
|
|
98
99
|
- lib/scss_lint/linter/border_zero.rb
|
99
100
|
- lib/scss_lint/linter/debug_statement.rb
|
100
101
|
- lib/scss_lint/linter/hex_format.rb
|
102
|
+
- lib/scss_lint/linter/color_keyword.rb
|
101
103
|
- lib/scss_lint/linter/comment.rb
|
102
104
|
- lib/scss_lint/linter/empty_rule.rb
|
103
105
|
- lib/scss_lint/linter/single_line_per_selector.rb
|
@@ -133,3 +135,4 @@ signing_key:
|
|
133
135
|
specification_version: 4
|
134
136
|
summary: SCSS lint tool
|
135
137
|
test_files: []
|
138
|
+
has_rdoc:
|
@@ -1,18 +0,0 @@
|
|
1
|
-
module SCSSLint
|
2
|
-
class Linter::TypeInIdSelector < Linter
|
3
|
-
include LinterRegistry
|
4
|
-
|
5
|
-
def visit_rule(node)
|
6
|
-
selectors = node.rule.first.to_s.split(',')
|
7
|
-
selectors.each do |selector|
|
8
|
-
add_lint(node) if selector.strip =~ /^[a-z0-9]+#.*/i
|
9
|
-
end
|
10
|
-
|
11
|
-
yield # Continue linting children
|
12
|
-
end
|
13
|
-
|
14
|
-
def description
|
15
|
-
'Avoid ID names with unnecessary type selectors (e.g. prefer `#id` over `p#id`)'
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|