scss-lint 0.33.0 → 0.34.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/config/default.yml +19 -1
- data/data/properties.txt +4 -0
- data/lib/scss_lint.rb +1 -0
- data/lib/scss_lint/cli.rb +4 -42
- data/lib/scss_lint/config.rb +1 -45
- data/lib/scss_lint/control_comment_processor.rb +47 -15
- data/lib/scss_lint/file_finder.rb +57 -0
- data/lib/scss_lint/linter/bang_format.rb +1 -1
- data/lib/scss_lint/linter/border_zero.rb +25 -9
- data/lib/scss_lint/linter/color_keyword.rb +3 -13
- data/lib/scss_lint/linter/color_variable.rb +36 -0
- data/lib/scss_lint/linter/declaration_order.rb +2 -2
- data/lib/scss_lint/linter/important_rule.rb +12 -0
- data/lib/scss_lint/linter/indentation.rb +7 -1
- data/lib/scss_lint/linter/property_count.rb +44 -0
- data/lib/scss_lint/linter/property_sort_order.rb +73 -19
- data/lib/scss_lint/linter/string_quotes.rb +9 -0
- data/lib/scss_lint/linter/variable_for_property.rb +20 -0
- data/lib/scss_lint/linter/vendor_prefixes.rb +3 -3
- data/lib/scss_lint/runner.rb +5 -7
- data/lib/scss_lint/utils.rb +34 -0
- data/lib/scss_lint/version.rb +1 -1
- data/spec/scss_lint/cli_spec.rb +1 -1
- data/spec/scss_lint/config_spec.rb +4 -203
- data/spec/scss_lint/engine_spec.rb +4 -4
- data/spec/scss_lint/file_finder_spec.rb +110 -0
- data/spec/scss_lint/linter/bang_format_spec.rb +28 -18
- data/spec/scss_lint/linter/border_zero_spec.rb +50 -16
- data/spec/scss_lint/linter/color_keyword_spec.rb +16 -16
- data/spec/scss_lint/linter/color_variable_spec.rb +102 -0
- data/spec/scss_lint/linter/comment_spec.rb +9 -9
- data/spec/scss_lint/linter/compass/property_with_mixin_spec.rb +10 -10
- data/spec/scss_lint/linter/debug_statement_spec.rb +4 -4
- data/spec/scss_lint/linter/declaration_order_spec.rb +80 -80
- data/spec/scss_lint/linter/duplicate_property_spec.rb +30 -30
- data/spec/scss_lint/linter/else_placement_spec.rb +16 -16
- data/spec/scss_lint/linter/empty_line_between_blocks_spec.rb +38 -38
- data/spec/scss_lint/linter/empty_rule_spec.rb +4 -4
- data/spec/scss_lint/linter/final_newline_spec.rb +6 -6
- data/spec/scss_lint/linter/hex_length_spec.rb +16 -16
- data/spec/scss_lint/linter/hex_notation_spec.rb +16 -16
- data/spec/scss_lint/linter/hex_validation_spec.rb +6 -6
- data/spec/scss_lint/linter/id_selector_spec.rb +10 -10
- data/spec/scss_lint/linter/import_path_spec.rb +45 -45
- data/spec/scss_lint/linter/important_rule_spec.rb +43 -0
- data/spec/scss_lint/linter/indentation_spec.rb +103 -43
- data/spec/scss_lint/linter/leading_zero_spec.rb +45 -45
- data/spec/scss_lint/linter/mergeable_selector_spec.rb +32 -32
- data/spec/scss_lint/linter/name_format_spec.rb +75 -41
- data/spec/scss_lint/linter/nesting_depth_spec.rb +14 -14
- data/spec/scss_lint/linter/placeholder_in_extend_spec.rb +12 -12
- data/spec/scss_lint/linter/property_count_spec.rb +104 -0
- data/spec/scss_lint/linter/property_sort_order_spec.rb +138 -48
- data/spec/scss_lint/linter/property_spelling_spec.rb +14 -14
- data/spec/scss_lint/linter/qualifying_element_spec.rb +26 -26
- data/spec/scss_lint/linter/selector_depth_spec.rb +26 -26
- data/spec/scss_lint/linter/selector_format_spec.rb +114 -114
- data/spec/scss_lint/linter/shorthand_spec.rb +32 -32
- data/spec/scss_lint/linter/single_line_per_property_spec.rb +10 -10
- data/spec/scss_lint/linter/single_line_per_selector_spec.rb +24 -24
- data/spec/scss_lint/linter/space_after_comma_spec.rb +60 -60
- data/spec/scss_lint/linter/space_after_property_colon_spec.rb +44 -44
- data/spec/scss_lint/linter/space_after_property_name_spec.rb +6 -6
- data/spec/scss_lint/linter/space_before_brace_spec.rb +119 -119
- data/spec/scss_lint/linter/space_between_parens_spec.rb +48 -48
- data/spec/scss_lint/linter/string_quotes_spec.rb +74 -62
- data/spec/scss_lint/linter/trailing_semicolon_spec.rb +53 -54
- data/spec/scss_lint/linter/trailing_zero_spec.rb +34 -34
- data/spec/scss_lint/linter/unnecessary_mantissa_spec.rb +10 -10
- data/spec/scss_lint/linter/unnecessary_parent_reference_spec.rb +18 -18
- data/spec/scss_lint/linter/url_format_spec.rb +4 -4
- data/spec/scss_lint/linter/url_quotes_spec.rb +14 -14
- data/spec/scss_lint/linter/variable_for_property_spec.rb +115 -0
- data/spec/scss_lint/linter/vendor_prefixes_spec.rb +66 -56
- data/spec/scss_lint/linter/zero_unit_spec.rb +22 -22
- data/spec/scss_lint/linter_spec.rb +72 -28
- data/spec/scss_lint/runner_spec.rb +0 -1
- data/spec/scss_lint/selector_visitor_spec.rb +23 -23
- data/spec/spec_helper.rb +2 -2
- metadata +27 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d9d896111a17640c23d31de062d34329fd52a56a
|
4
|
+
data.tar.gz: 6f34a07866cd4b7c77a18137f2bec2570e9f31e5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d100dfddcde8591cbff342d88bc37f685ac337eb32b9193b87f09c46cf50dc61c04717a4e67fe843f6135fb186f8c5e43b7c6711680d67e766e56e71bb04ff94
|
7
|
+
data.tar.gz: 65e67618d2e00e428a38adb5243236dea6464f17df75914937da60afbf3eded4f3b0e7be4d526b4d05c264c9a0ef5f5ed1cc13cbab3dac4a5cde3673f4e991d0
|
data/config/default.yml
CHANGED
@@ -10,10 +10,14 @@ linters:
|
|
10
10
|
|
11
11
|
BorderZero:
|
12
12
|
enabled: true
|
13
|
+
convention: zero # or `none`
|
13
14
|
|
14
15
|
ColorKeyword:
|
15
16
|
enabled: true
|
16
17
|
|
18
|
+
ColorVariable:
|
19
|
+
enabled: true
|
20
|
+
|
17
21
|
Comment:
|
18
22
|
enabled: true
|
19
23
|
|
@@ -55,6 +59,9 @@ linters:
|
|
55
59
|
IdSelector:
|
56
60
|
enabled: true
|
57
61
|
|
62
|
+
ImportantRule:
|
63
|
+
enabled: true
|
64
|
+
|
58
65
|
ImportPath:
|
59
66
|
enabled: true
|
60
67
|
leading_underscore: false
|
@@ -62,6 +69,7 @@ linters:
|
|
62
69
|
|
63
70
|
Indentation:
|
64
71
|
enabled: true
|
72
|
+
allow_non_nested_indentation: false
|
65
73
|
character: space # or 'tab'
|
66
74
|
width: 2
|
67
75
|
|
@@ -85,9 +93,15 @@ linters:
|
|
85
93
|
PlaceholderInExtend:
|
86
94
|
enabled: true
|
87
95
|
|
96
|
+
PropertyCount:
|
97
|
+
enabled: false
|
98
|
+
include_nested: false
|
99
|
+
max_properties: 10
|
100
|
+
|
88
101
|
PropertySortOrder:
|
89
102
|
enabled: true
|
90
103
|
ignore_unspecified: false
|
104
|
+
separate_groups: false
|
91
105
|
|
92
106
|
PropertySpelling:
|
93
107
|
enabled: true
|
@@ -129,7 +143,7 @@ linters:
|
|
129
143
|
|
130
144
|
SpaceBeforeBrace:
|
131
145
|
enabled: true
|
132
|
-
style: space
|
146
|
+
style: space # or 'new_line'
|
133
147
|
allow_single_line_padding: false
|
134
148
|
|
135
149
|
SpaceBetweenParens:
|
@@ -158,6 +172,10 @@ linters:
|
|
158
172
|
UrlQuotes:
|
159
173
|
enabled: true
|
160
174
|
|
175
|
+
VariableForProperty:
|
176
|
+
enabled: false
|
177
|
+
properties: []
|
178
|
+
|
161
179
|
VendorPrefixes:
|
162
180
|
enabled: true
|
163
181
|
identifier_list: base
|
data/data/properties.txt
CHANGED
@@ -102,6 +102,9 @@ box-pack
|
|
102
102
|
box-reflect
|
103
103
|
box-shadow
|
104
104
|
box-sizing
|
105
|
+
break-after
|
106
|
+
break-before
|
107
|
+
break-inside
|
105
108
|
buffered-rendering
|
106
109
|
caption-side
|
107
110
|
clear
|
@@ -418,6 +421,7 @@ text-overline-style
|
|
418
421
|
text-overline-width
|
419
422
|
text-rendering
|
420
423
|
text-security
|
424
|
+
text-size-adjust
|
421
425
|
text-shadow
|
422
426
|
text-stroke
|
423
427
|
text-stroke-color
|
data/lib/scss_lint.rb
CHANGED
@@ -5,6 +5,7 @@ require 'scss_lint/engine'
|
|
5
5
|
require 'scss_lint/location'
|
6
6
|
require 'scss_lint/lint'
|
7
7
|
require 'scss_lint/linter_registry'
|
8
|
+
require 'scss_lint/file_finder'
|
8
9
|
require 'scss_lint/runner'
|
9
10
|
require 'scss_lint/selector_visitor'
|
10
11
|
require 'scss_lint/control_comment_processor'
|
data/lib/scss_lint/cli.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'find'
|
2
1
|
require 'rainbow'
|
3
2
|
require 'rainbow/ext/string'
|
4
3
|
require 'scss_lint/options'
|
@@ -49,7 +48,7 @@ module SCSSLint
|
|
49
48
|
|
50
49
|
def scan_for_lints(options, config)
|
51
50
|
runner = Runner.new(config)
|
52
|
-
runner.run(
|
51
|
+
runner.run(FileFinder.new(config).find(options[:files]))
|
53
52
|
report_lints(options, runner.lints)
|
54
53
|
|
55
54
|
if runner.lints.any?(&:error?)
|
@@ -87,9 +86,9 @@ module SCSSLint
|
|
87
86
|
def setup_configuration(options)
|
88
87
|
config =
|
89
88
|
if options[:config_file]
|
90
|
-
Config.load(options[:config_file])
|
91
|
-
|
92
|
-
|
89
|
+
Config.load(options[:config_file])
|
90
|
+
elsif File.exist?(Config::FILE_NAME)
|
91
|
+
Config.load(Config::FILE_NAME)
|
93
92
|
else
|
94
93
|
Config.default
|
95
94
|
end
|
@@ -123,43 +122,6 @@ module SCSSLint
|
|
123
122
|
config
|
124
123
|
end
|
125
124
|
|
126
|
-
def files_to_lint(options, config)
|
127
|
-
if options[:files].empty?
|
128
|
-
options[:files] = config.scss_files
|
129
|
-
end
|
130
|
-
|
131
|
-
extract_files_from(options[:files]).reject do |file|
|
132
|
-
actual_config =
|
133
|
-
if !config.preferred && (config_for_file = Config.for_file(file))
|
134
|
-
merge_options_with_config(options, config_for_file.dup)
|
135
|
-
else
|
136
|
-
config
|
137
|
-
end
|
138
|
-
|
139
|
-
actual_config.excluded_file?(file)
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
# @param list [Array]
|
144
|
-
def extract_files_from(list)
|
145
|
-
files = []
|
146
|
-
list.each do |file|
|
147
|
-
Find.find(file) do |f|
|
148
|
-
files << f if scssish_file?(f)
|
149
|
-
end
|
150
|
-
end
|
151
|
-
files.uniq
|
152
|
-
end
|
153
|
-
|
154
|
-
VALID_EXTENSIONS = %w[.css .scss]
|
155
|
-
# @param file [String]
|
156
|
-
# @return [Boolean]
|
157
|
-
def scssish_file?(file)
|
158
|
-
return false unless FileTest.file?(file)
|
159
|
-
|
160
|
-
VALID_EXTENSIONS.include?(File.extname(file))
|
161
|
-
end
|
162
|
-
|
163
125
|
# @param options [Hash]
|
164
126
|
# @param lints [Array<Lint>]
|
165
127
|
def report_lints(options, lints)
|
data/lib/scss_lint/config.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'pathname'
|
2
1
|
require 'yaml'
|
3
2
|
|
4
3
|
module SCSSLint
|
@@ -7,7 +6,6 @@ module SCSSLint
|
|
7
6
|
FILE_NAME = '.scss-lint.yml'
|
8
7
|
DEFAULT_FILE = File.join(SCSS_LINT_HOME, 'config', 'default.yml')
|
9
8
|
|
10
|
-
attr_accessor :preferred # If this config should be preferred over others
|
11
9
|
attr_reader :options, :warnings
|
12
10
|
|
13
11
|
class << self
|
@@ -27,17 +25,6 @@ module SCSSLint
|
|
27
25
|
Config.new(config_options)
|
28
26
|
end
|
29
27
|
|
30
|
-
# Loads the configuration for a given file.
|
31
|
-
def for_file(file_path)
|
32
|
-
directory = File.dirname(File.expand_path(file_path))
|
33
|
-
@dir_to_config ||= {}
|
34
|
-
@dir_to_config[directory] ||=
|
35
|
-
begin
|
36
|
-
config_file = possible_config_files(directory).find(&:file?)
|
37
|
-
Config.load(config_file.to_s) if config_file
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
28
|
def linter_name(linter)
|
42
29
|
linter = linter.is_a?(Class) ? linter : linter.class
|
43
30
|
linter.name.split('::')[2..-1].join('::')
|
@@ -45,13 +32,6 @@ module SCSSLint
|
|
45
32
|
|
46
33
|
private
|
47
34
|
|
48
|
-
def possible_config_files(directory)
|
49
|
-
files = Pathname.new(directory)
|
50
|
-
.enum_for(:ascend)
|
51
|
-
.map { |path| path + FILE_NAME }
|
52
|
-
files << Pathname.new(FILE_NAME)
|
53
|
-
end
|
54
|
-
|
55
35
|
def default_options_hash
|
56
36
|
@default_options_hash ||= load_options_hash_from_file(DEFAULT_FILE)
|
57
37
|
end
|
@@ -74,7 +54,6 @@ module SCSSLint
|
|
74
54
|
end
|
75
55
|
|
76
56
|
options = convert_single_options_to_arrays(options)
|
77
|
-
options = extend_inherited_configs(options, file)
|
78
57
|
options = merge_wildcard_linter_options(options)
|
79
58
|
options = ensure_exclude_paths_are_absolute(options, file)
|
80
59
|
options = ensure_linter_exclude_paths_are_absolute(options, file)
|
@@ -88,31 +67,13 @@ module SCSSLint
|
|
88
67
|
|
89
68
|
if options['exclude']
|
90
69
|
# Ensure exclude is an array, since we allow user to specify a single
|
91
|
-
# string.
|
92
|
-
# inherit_from since this allows us to merge the excludes from that,
|
93
|
-
# rather than overwriting them.
|
70
|
+
# string.
|
94
71
|
options['exclude'] = [options['exclude']].flatten
|
95
72
|
end
|
96
73
|
|
97
74
|
options
|
98
75
|
end
|
99
76
|
|
100
|
-
# Loads and extends a list of inherited options with the given options.
|
101
|
-
def extend_inherited_configs(options, original_file)
|
102
|
-
return options unless options['inherit_from']
|
103
|
-
options = options.dup
|
104
|
-
|
105
|
-
includes = [options.delete('inherit_from')].flatten.map do |include_file|
|
106
|
-
load_options_hash_from_file(path_relative_to_config(include_file, original_file))
|
107
|
-
end
|
108
|
-
|
109
|
-
merged_includes = includes[1..-1].inject(includes.first) do |merged, include_file|
|
110
|
-
smart_merge(merged, include_file)
|
111
|
-
end
|
112
|
-
|
113
|
-
smart_merge(merged_includes, options)
|
114
|
-
end
|
115
|
-
|
116
77
|
# Merge options from wildcard linters into individual linter configs
|
117
78
|
def merge_wildcard_linter_options(options)
|
118
79
|
options = options.dup
|
@@ -211,11 +172,6 @@ module SCSSLint
|
|
211
172
|
validate_linters
|
212
173
|
end
|
213
174
|
|
214
|
-
def ==(other)
|
215
|
-
super || @options == other.options
|
216
|
-
end
|
217
|
-
alias_method :eql?, :==
|
218
|
-
|
219
175
|
def enabled_linters
|
220
176
|
LinterRegistry.extract_linters_from(@options['linters'].keys).select do |linter|
|
221
177
|
linter_options(linter)['enabled']
|
@@ -20,25 +20,18 @@ module SCSSLint
|
|
20
20
|
#
|
21
21
|
# @param node [Sass::Tree::Node]
|
22
22
|
def before_node_visit(node)
|
23
|
-
return unless node
|
23
|
+
return unless command = extract_command(node)
|
24
24
|
|
25
|
-
|
26
|
-
\*\s* # Comment line start marker
|
27
|
-
scss-lint:
|
28
|
-
(?<command>disable|enable)\s+
|
29
|
-
(?<linters>.*?)
|
30
|
-
\s*(?:\*\/|\n) # Comment end marker or end of line
|
31
|
-
/.match(node.value.first)
|
32
|
-
|
33
|
-
linters = match[:linters].split(/\s*,\s*|\s+/)
|
25
|
+
linters = command[:linters]
|
34
26
|
return unless linters.include?('all') || linters.include?(@linter.name)
|
35
27
|
|
36
|
-
process_command(
|
28
|
+
process_command(command[:action], node)
|
37
29
|
|
38
30
|
# Is the control comment the only thing on this line?
|
39
|
-
return if
|
31
|
+
return if node.is_a?(Sass::Tree::RuleNode) ||
|
32
|
+
%r{^\s*(//|/\*)}.match(@linter.engine.lines[node.line - 1])
|
40
33
|
|
41
|
-
#
|
34
|
+
# Otherwise, pop since we only want comment to apply to the single line
|
42
35
|
pop_control_comment_stack(node)
|
43
36
|
end
|
44
37
|
|
@@ -53,6 +46,29 @@ module SCSSLint
|
|
53
46
|
|
54
47
|
private
|
55
48
|
|
49
|
+
def extract_command(node)
|
50
|
+
comment =
|
51
|
+
case node
|
52
|
+
when Sass::Tree::CommentNode
|
53
|
+
node.value.first
|
54
|
+
when Sass::Tree::RuleNode
|
55
|
+
node.rule.select { |chunk| chunk.is_a?(String) }.join
|
56
|
+
end
|
57
|
+
|
58
|
+
return unless match = %r{
|
59
|
+
(/|\*)\s* # Comment start marker
|
60
|
+
scss-lint:
|
61
|
+
(?<action>disable|enable)\s+
|
62
|
+
(?<linters>.*?)
|
63
|
+
\s*(?:\*/|\n) # Comment end marker or end of line
|
64
|
+
}x.match(comment)
|
65
|
+
|
66
|
+
{
|
67
|
+
action: match[:action],
|
68
|
+
linters: match[:linters].split(/\s*,\s*|\s+/),
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
56
72
|
def process_command(command, node)
|
57
73
|
case command
|
58
74
|
when 'disable'
|
@@ -71,13 +87,29 @@ module SCSSLint
|
|
71
87
|
# apply (if it is a control comment enable node, it will be the line of
|
72
88
|
# the comment itself).
|
73
89
|
child = node
|
74
|
-
|
75
|
-
|
90
|
+
prev_child = node
|
91
|
+
while (child = last_child(child)) != prev_child
|
92
|
+
prev_child = child
|
76
93
|
end
|
77
94
|
|
78
95
|
end_line = child.line
|
79
96
|
|
80
97
|
@disabled_lines.merge(start_line..end_line)
|
81
98
|
end
|
99
|
+
|
100
|
+
# Gets the child of the node that resides on the lowest line in the file.
|
101
|
+
#
|
102
|
+
# This is necessary due to the fact that our monkey patching of the parse
|
103
|
+
# tree's {#children} method does not return nodes sorted by their line
|
104
|
+
# number.
|
105
|
+
#
|
106
|
+
# @param node [Sass::Tree::Node, Sass::Script::Tree::Node]
|
107
|
+
# @return [Sass::Tree::Node, Sass::Script::Tree::Node]
|
108
|
+
def last_child(node)
|
109
|
+
node.children.inject(node) do |lowest, child|
|
110
|
+
return lowest unless child.respond_to?(:line)
|
111
|
+
lowest.line < child.line ? child : lowest
|
112
|
+
end
|
113
|
+
end
|
82
114
|
end
|
83
115
|
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'find'
|
2
|
+
|
3
|
+
module SCSSLint
|
4
|
+
# Finds all SCSS files that should be linted given a set of paths, globs, and
|
5
|
+
# configuration.
|
6
|
+
class FileFinder
|
7
|
+
# List of extensions of files to include when only a directory is specified
|
8
|
+
# as a path.
|
9
|
+
VALID_EXTENSIONS = %w[.css .scss]
|
10
|
+
|
11
|
+
# Create a {FileFinder}.
|
12
|
+
#
|
13
|
+
# @param config [SCSSLint::Config]
|
14
|
+
def initialize(config)
|
15
|
+
@config = config
|
16
|
+
end
|
17
|
+
|
18
|
+
# Find all files that match given the specified options.
|
19
|
+
#
|
20
|
+
# @param patterns [Array<String>] a list of file paths and glob patterns
|
21
|
+
def find(patterns)
|
22
|
+
# If no explicit patterns given, use patterns listed in config
|
23
|
+
patterns = @config.scss_files if patterns.empty?
|
24
|
+
|
25
|
+
extract_files_from(patterns).reject do |file|
|
26
|
+
@config.excluded_file?(file)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
# @param list [Array]
|
33
|
+
def extract_files_from(list)
|
34
|
+
files = []
|
35
|
+
|
36
|
+
list.each do |file|
|
37
|
+
if File.directory?(file)
|
38
|
+
Find.find(file) do |f|
|
39
|
+
files << f if scssish_file?(f)
|
40
|
+
end
|
41
|
+
else
|
42
|
+
files << file # Otherwise include file as-is
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
files.uniq
|
47
|
+
end
|
48
|
+
|
49
|
+
# @param file [String]
|
50
|
+
# @return [true,false]
|
51
|
+
def scssish_file?(file)
|
52
|
+
return false unless FileTest.file?(file)
|
53
|
+
|
54
|
+
VALID_EXTENSIONS.include?(File.extname(file))
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -6,7 +6,7 @@ module SCSSLint
|
|
6
6
|
STOPPING_CHARACTERS = ['!', "'", '"', nil]
|
7
7
|
|
8
8
|
def visit_prop(node)
|
9
|
-
return unless node.
|
9
|
+
return unless source_from_range(node.source_range).include?('!')
|
10
10
|
return unless check_spacing(node)
|
11
11
|
|
12
12
|
before_qualifier = config['space_before_bang'] ? '' : 'not '
|
@@ -1,16 +1,12 @@
|
|
1
1
|
module SCSSLint
|
2
|
-
#
|
2
|
+
# Enforce a particular value for empty borders.
|
3
3
|
class Linter::BorderZero < Linter
|
4
4
|
include LinterRegistry
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
add_lint(node, '`border: 0;` is preferred over `border: none;`')
|
11
|
-
end
|
12
|
-
|
13
|
-
private
|
6
|
+
CONVENTION_TO_PREFERENCE = {
|
7
|
+
'zero' => %w[0 none],
|
8
|
+
'none' => %w[none 0],
|
9
|
+
}
|
14
10
|
|
15
11
|
BORDER_PROPERTIES = %w[
|
16
12
|
border
|
@@ -19,5 +15,25 @@ module SCSSLint
|
|
19
15
|
border-bottom
|
20
16
|
border-left
|
21
17
|
]
|
18
|
+
|
19
|
+
def visit_root(_node)
|
20
|
+
@preference = CONVENTION_TO_PREFERENCE[config['convention']]
|
21
|
+
yield # Continue linting children
|
22
|
+
end
|
23
|
+
|
24
|
+
def visit_prop(node)
|
25
|
+
return unless BORDER_PROPERTIES.include?(node.name.first.to_s)
|
26
|
+
check_border(node, node.value.to_sass.strip)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def check_border(node, border)
|
32
|
+
return unless %w[0 none].include?(border)
|
33
|
+
return if @preference[0] == border
|
34
|
+
|
35
|
+
add_lint(node, "`border: #{@preference[0]} is preferred over " \
|
36
|
+
"`border: #{@preference[1]}`")
|
37
|
+
end
|
22
38
|
end
|
23
39
|
end
|