-
Notifications
You must be signed in to change notification settings - Fork 465
/
property_units.rb
77 lines (66 loc) · 2.15 KB
/
property_units.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
module SCSSLint
# Check for allowed units
class Linter::PropertyUnits < Linter
include LinterRegistry
NUMBER_WITH_UNITS_REGEX = /
(?:
(["']).+?\1 # [0: quote mark] quoted string, e.g. "hi there"
| # or
(?:^|\s) # beginning of value or whitespace
(?:
\d+ # any number of digits, e.g. 123
| # or
\d*\.?\d+ # any number of digits with decimal, e.g. 1.23 or .123
)
([a-z%]+) # [1: units] letters or percent sign, e.g. px or %
)
/ix.freeze
def visit_root(_node)
@globally_allowed_units = config['global'].to_set
@allowed_units_for_property = config['properties']
yield # Continue linting children
end
def visit_prop(node)
property = node.name.join
# Handle nested properties by ensuring the full name is extracted
if @nested_under
property = "#{@nested_under}-#{property}"
end
if node.value.first.respond_to?(:value)
node.value.first.value.to_s.scan(NUMBER_WITH_UNITS_REGEX).each do |matches|
is_quoted_value = !matches[0].nil?
next if is_quoted_value
units = matches[1]
check_units(node, property, units)
end
end
@nested_under = property
yield # Continue linting nested properties
@nested_under = nil
end
private
# Checks if a property value's units are allowed.
#
# @param node [Sass::Tree::Node]
# @param property [String]
# @param units [String]
def check_units(node, property, units)
allowed_units = allowed_units_for_property(property)
return if allowed_units.include?(units)
add_lint(node,
"#{units} units not allowed on `#{property}`; must be one of " \
"(#{allowed_units.to_a.sort.join(', ')})")
end
# Return the list of allowed units for a property.
#
# @param property [String]
# @return Array<String>
def allowed_units_for_property(property)
if @allowed_units_for_property.key?(property)
@allowed_units_for_property[property]
else
@globally_allowed_units
end
end
end
end