scss-lint 0.33.0 → 0.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|