forked from sds/scss-lint
-
Notifications
You must be signed in to change notification settings - Fork 0
/
space_after_property_colon.rb
91 lines (74 loc) · 2.7 KB
/
space_after_property_colon.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
module SCSSLint
# Checks for spaces following the colon that separates a property's name from
# its value.
class Linter::SpaceAfterPropertyColon < Linter
include LinterRegistry
def visit_rule(node)
if config['style'] == 'aligned'
check_properties_alignment(node)
end
yield # Continue linting children
end
def visit_prop(node)
whitespace = whitespace_after_colon(node)
case config['style']
when 'no_space'
check_for_no_spaces(node, whitespace)
when 'one_space'
check_for_one_space(node, whitespace)
when 'at_least_one_space'
check_for_at_least_one_space(node, whitespace)
when 'one_space_or_newline'
check_for_one_space_or_newline(node, whitespace)
end
yield # Continue linting children
end
private
def check_for_no_spaces(node, whitespace)
return if whitespace == []
add_lint(node, 'Colon after property should not be followed by any spaces')
end
def check_for_one_space(node, whitespace)
return if whitespace == [' ']
add_lint(node, 'Colon after property should be followed by one space')
end
def check_for_at_least_one_space(node, whitespace)
return if whitespace.uniq == [' ']
add_lint(node, 'Colon after property should be followed by at least one space')
end
def check_for_one_space_or_newline(node, whitespace)
return if whitespace == [' '] || whitespace == ["\n"]
return if whitespace[0] == "\n" && whitespace[1..-1].uniq == [' ']
add_lint(node, 'Colon after property should be followed by one space or a newline')
end
def check_properties_alignment(rule_node)
properties = rule_node.children.select { |node| node.is_a?(Sass::Tree::PropNode) }
properties.each_slice(2) do |prop1, prop2|
next unless prop2
next unless value_offset(prop1) != value_offset(prop2)
add_lint(prop1, 'Property values should be aligned')
break
end
end
# Offset of value for property
def value_offset(prop)
src_range = prop.name_source_range
src_range.start_pos.offset +
(src_range.end_pos.offset - src_range.start_pos.offset) +
whitespace_after_colon(prop).take_while { |w| w == ' ' }.size
end
def whitespace_after_colon(node)
whitespace = []
offset = 0
start_pos = node.name_source_range.start_pos
# Find the colon after the property name
offset = offset_to(start_pos, ':', offset) + 1
# Count spaces after the colon
while [' ', "\t", "\n"].include? character_at(start_pos, offset)
whitespace << character_at(start_pos, offset)
offset += 1
end
whitespace
end
end
end