erblint-github 0.1.3 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +33 -33
- data/lib/erblint-github/linters/custom_helpers.rb +2 -20
- data/lib/erblint-github/linters/github/accessibility/{avoid_both_disabled_and_aria_disabled_counter.rb → avoid_both_disabled_and_aria_disabled.rb} +8 -15
- data/lib/erblint-github/linters/github/accessibility/{avoid_generic_link_text_counter.rb → avoid_generic_link_text.rb} +8 -15
- data/lib/erblint-github/linters/github/accessibility/{disabled_attribute_counter.rb → disabled_attribute.rb} +13 -15
- data/lib/erblint-github/linters/github/accessibility/{iframe_has_title_counter.rb → iframe_has_title.rb} +8 -15
- data/lib/erblint-github/linters/github/accessibility/{image_has_alt_counter.rb → image_has_alt.rb} +8 -15
- data/lib/erblint-github/linters/github/accessibility/{landmark_has_label_counter.rb → landmark_has_label.rb} +8 -15
- data/lib/erblint-github/linters/github/accessibility/{link_has_href_counter.rb → link_has_href.rb} +8 -15
- data/lib/erblint-github/linters/github/accessibility/{nested_interactive_elements_counter.rb → nested_interactive_elements.rb} +7 -15
- data/lib/erblint-github/linters/github/accessibility/{no_aria_hidden_on_focusable_counter.rb → no_aria_hidden_on_focusable.rb} +8 -15
- data/lib/erblint-github/linters/github/accessibility/{no_aria_label_misuse_counter.rb → no_aria_label_misuse.rb} +8 -15
- data/lib/erblint-github/linters/github/accessibility/{no_positive_tab_index_counter.rb → no_positive_tab_index.rb} +8 -15
- data/lib/erblint-github/linters/github/accessibility/{no_redundant_image_alt_counter.rb → no_redundant_image_alt.rb} +8 -15
- data/lib/erblint-github/linters/github/accessibility/{no_title_attribute_counter.rb → no_title_attribute.rb} +8 -15
- data/lib/erblint-github/linters/github/accessibility/{svg_has_accessible_text_counter.rb → svg_has_accessible_text.rb} +8 -15
- metadata +17 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 241e053b11c2e8e99f2393e5810b8bf9206e9db587a579c7ba20f67575f07874
|
4
|
+
data.tar.gz: 60470f738221eda4e5ee04d230cbdb63f80aa9098e87381cf75b4a6f732c4dbc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 267422c819129ea1e6eca8cc66ef95448345f3278cdd2ee036cc04303c8b9ef3628757808c9edc2dae815f30d56b9dceafa10670f0a60b492cb8c1df9e5254cf
|
7
|
+
data.tar.gz: 30566b29367c5991e4e6229c98f85f217467f8cbd7dd15c03a3f8f270c11da6d2439a699e9133f707d0b4a256f38e611a83e32774decbe4f35fa09647fde7d78
|
data/README.md
CHANGED
@@ -23,56 +23,56 @@ require "erblint-github/linters"
|
|
23
23
|
```yaml
|
24
24
|
---
|
25
25
|
linters:
|
26
|
-
GitHub::Accessibility::
|
26
|
+
GitHub::Accessibility::AvoidBothDisabledAndAriaDisabled:
|
27
27
|
enabled: true
|
28
|
-
GitHub::Accessibility::
|
28
|
+
GitHub::Accessibility::AvoidGenericLinkText:
|
29
29
|
enabled: true
|
30
|
-
GitHub::Accessibility::
|
30
|
+
GitHub::Accessibility::DisabledAttribute:
|
31
31
|
enabled: true
|
32
|
-
GitHub::Accessibility::
|
32
|
+
GitHub::Accessibility::IframeHasTitle:
|
33
33
|
enabled: true
|
34
|
-
GitHub::Accessibility::
|
34
|
+
GitHub::Accessibility::ImageHasAlt:
|
35
35
|
enabled: true
|
36
|
-
GitHub::Accessibility::
|
36
|
+
GitHub::Accessibility::LandmarkHasLabel:
|
37
37
|
enabled: true
|
38
|
-
GitHub::Accessibility::
|
38
|
+
GitHub::Accessibility::LinkHasHref:
|
39
39
|
enabled: true
|
40
|
-
GitHub::Accessibility::
|
40
|
+
GitHub::Accessibility::NestedInteractiveElements:
|
41
41
|
enabled: true
|
42
|
-
GitHub::Accessibility::
|
42
|
+
GitHub::Accessibility::NoAriaHiddenOnFocusable:
|
43
43
|
enabled: true
|
44
|
-
GitHub::Accessibility::
|
44
|
+
GitHub::Accessibility::NoAriaLabelMisuse:
|
45
45
|
enabled: true
|
46
|
-
GitHub::Accessibility::
|
46
|
+
GitHub::Accessibility::NoPositiveTabIndex:
|
47
47
|
enabled: true
|
48
|
-
GitHub::Accessibility::
|
48
|
+
GitHub::Accessibility::NoRedundantImageAlt:
|
49
49
|
enabled: true
|
50
|
-
GitHub::Accessibility::
|
50
|
+
GitHub::Accessibility::NoTitleAttribute:
|
51
51
|
enabled: true
|
52
|
-
GitHub::Accessibility::
|
52
|
+
GitHub::Accessibility::SvgHasAccessibleText:
|
53
53
|
enabled: true
|
54
54
|
```
|
55
55
|
|
56
56
|
## Rules
|
57
57
|
|
58
|
-
- [GitHub::Accessibility::
|
59
|
-
- [GitHub::Accessibility::
|
60
|
-
- [GitHub::Accessibility::
|
61
|
-
- [GitHub::Accessibility::
|
62
|
-
- [GitHub::Accessibility::
|
63
|
-
- [GitHub::Accessibility::
|
64
|
-
- [GitHub::Accessibility::
|
65
|
-
- [GitHub::Accessibility::
|
66
|
-
- [GitHub::Accessibility::
|
67
|
-
- [GitHub::Accessibility::
|
68
|
-
- [GitHub::Accessibility::
|
69
|
-
- [GitHub::Accessibility::
|
70
|
-
- [GitHub::Accessibility::
|
71
|
-
- [GitHub::Accessibility::
|
72
|
-
|
73
|
-
## Disabling a rule (
|
74
|
-
|
75
|
-
_This is
|
58
|
+
- [GitHub::Accessibility::AvoidBothDisabledAndAriaDisabled](./docs/rules/accessibility/avoid-both-disabled-and-aria-disabled.md)
|
59
|
+
- [GitHub::Accessibility::AvoidGenericLinkText](./docs/rules/accessibility/avoid-generic-link-text.md)
|
60
|
+
- [GitHub::Accessibility::DisabledAttribute](./docs/rules/accessibility/disabled-attribute.md)
|
61
|
+
- [GitHub::Accessibility::LandmarkHasLabel](./docs/rules/accessibility/landmark-has-label.md)
|
62
|
+
- [GitHub::Accessibility::LinkHasHref](./docs/rules/accessibility/link-has-href.md)
|
63
|
+
- [GitHub::Accessibility::NestedInteractiveElements](./docs/rules/accessibility/nested-interactive-elements.md)
|
64
|
+
- [GitHub::Accessibility::IframeHasTitle](./docs/rules/accessibility/iframe-has-title.md)
|
65
|
+
- [GitHub::Accessibility::ImageHasAlt](./docs/rules/accessibility/image-has-alt.md)
|
66
|
+
- [GitHub::Accessibility::NoAriaHiddenOnFocusable](./docs/rules/accessibility/no-aria-hidden-on-focusable.md)
|
67
|
+
- [GitHub::Accessibility::NoAriaLabelMisuse](./docs/rules/accessibility/no-aria-label-misuse.md)
|
68
|
+
- [GitHub::Accessibility::NoPositiveTabIndex](./docs/rules/accessibility/no-positive-tab-index.md)
|
69
|
+
- [GitHub::Accessibility::NoRedundantImageAlt](./docs/rules/accessibility/no-redundant-image-alt.md)
|
70
|
+
- [GitHub::Accessibility::NoTitleAttribute](./docs/rules/accessibility/no-title-attribute.md)
|
71
|
+
- [GitHub::Accessibility::SvgHasAccessibleText](./docs/rules/accessibility/svg-has-accessible-text.md)
|
72
|
+
|
73
|
+
## Disabling a rule (Deprecated)
|
74
|
+
|
75
|
+
_This is a soon-to-be deprecated feature. Do not use. See [migration guide](./docs/counter-migration-guide.md)_
|
76
76
|
|
77
77
|
`erblint` does not natively support rule disables. At GitHub, we've implemented these rules in a way to allow rules to be disabled at an offense-level via counters or disabled at a file-level because often times, we want to enable a rule but aren't able to address all offenses at once. We achieve this in one of two ways.
|
78
78
|
|
@@ -82,7 +82,7 @@ Rules that are marked as `Counter` can be disabled by adding a comment with the
|
|
82
82
|
<%# erblint:counter GitHub::Accessibility::LinkHasHrefCounter 1 %>
|
83
83
|
```
|
84
84
|
|
85
|
-
In this comment example, when a new `
|
85
|
+
In this comment example, when a new `LinkHasHref` offense has been added, the counter will need to be bumped up to 2. More recent rules use a `Counter` format.
|
86
86
|
|
87
87
|
If you are enabling a rule for the first time and your codebase has a lot of offenses, you can use the `-a` command to automatically add these counter comments in the appropriate places.
|
88
88
|
|
@@ -8,24 +8,6 @@ module ERBLint
|
|
8
8
|
module CustomHelpers
|
9
9
|
INTERACTIVE_ELEMENTS = %w[button summary input select textarea a].freeze
|
10
10
|
|
11
|
-
def rule_disabled?(processed_source)
|
12
|
-
processed_source.parser.ast.descendants(:erb).each do |node|
|
13
|
-
indicator_node, _, code_node, = *node
|
14
|
-
indicator = indicator_node&.loc&.source
|
15
|
-
comment = code_node&.loc&.source&.strip
|
16
|
-
rule_name = simple_class_name
|
17
|
-
|
18
|
-
if indicator == "#" && comment.start_with?("erblint:disable") && comment.match(rule_name)
|
19
|
-
if @offenses.any?
|
20
|
-
clear_offenses
|
21
|
-
else
|
22
|
-
add_offense(processed_source.to_source_range(code_node.loc),
|
23
|
-
"Unused erblint:disable comment for #{rule_name}")
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
11
|
def counter_correct?(processed_source)
|
30
12
|
comment_node = nil
|
31
13
|
expected_count = 0
|
@@ -52,10 +34,10 @@ module ERBLint
|
|
52
34
|
first_offense = @offenses[0]
|
53
35
|
|
54
36
|
if comment_node.nil?
|
55
|
-
add_offense(processed_source.to_source_range(first_offense.source_range), "#{rule_name}: If you must, add <%# erblint:
|
37
|
+
add_offense(processed_source.to_source_range(first_offense.source_range), "#{rule_name}: If you must, add <%# erblint:disable #{rule_name} %> at the end of the offending line to bypass this check. See https://github.com/shopify/erb-lint#disable-rule-at-offense-level", "<%# erblint:disable #{rule_name} %>")
|
56
38
|
else
|
57
39
|
clear_offenses
|
58
|
-
add_offense(processed_source.to_source_range(comment_node.loc), "Incorrect erblint:counter number for #{rule_name}. Expected: #{expected_count}, actual: #{offenses_count}.", "<%# erblint:counter #{rule_name} #{offenses_count} %>") if expected_count != offenses_count
|
40
|
+
add_offense(processed_source.to_source_range(comment_node.loc), "Incorrect erblint:counter number for #{rule_name}. Expected: #{expected_count}, actual: #{offenses_count}.", "<%# erblint:counter #{rule_name}Counter #{offenses_count} %>") if expected_count != offenses_count
|
59
41
|
end
|
60
42
|
end
|
61
43
|
|
@@ -6,13 +6,18 @@ module ERBLint
|
|
6
6
|
module Linters
|
7
7
|
module GitHub
|
8
8
|
module Accessibility
|
9
|
-
class
|
9
|
+
class AvoidBothDisabledAndAriaDisabled < Linter
|
10
10
|
include ERBLint::Linters::CustomHelpers
|
11
11
|
include LinterRegistry
|
12
12
|
|
13
13
|
ELEMENTS_WITH_NATIVE_DISABLED_ATTRIBUTE_SUPPORT = %w[button fieldset input optgroup option select textarea].freeze
|
14
14
|
MESSAGE = "[aria-disabled] may be used in place of native HTML [disabled] to allow tab-focus on an otherwise ignored element. Setting both attributes is contradictory."
|
15
15
|
|
16
|
+
class ConfigSchema < LinterConfig
|
17
|
+
property :counter_enabled, accepts: [true, false], default: false, reader: :counter_enabled?
|
18
|
+
end
|
19
|
+
self.config_schema = ConfigSchema
|
20
|
+
|
16
21
|
def run(processed_source)
|
17
22
|
tags(processed_source).each do |tag|
|
18
23
|
next if tag.closing?
|
@@ -22,20 +27,8 @@ module ERBLint
|
|
22
27
|
generate_offense(self.class, processed_source, tag)
|
23
28
|
end
|
24
29
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
def autocorrect(processed_source, offense)
|
29
|
-
return unless offense.context
|
30
|
-
|
31
|
-
lambda do |corrector|
|
32
|
-
if processed_source.file_content.include?("erblint:counter #{simple_class_name}")
|
33
|
-
# update the counter if exists
|
34
|
-
corrector.replace(offense.source_range, offense.context)
|
35
|
-
else
|
36
|
-
# add comment with counter if none
|
37
|
-
corrector.insert_before(processed_source.source_buffer.source_range, "#{offense.context}\n")
|
38
|
-
end
|
30
|
+
if @config.counter_enabled?
|
31
|
+
counter_correct?(processed_source)
|
39
32
|
end
|
40
33
|
end
|
41
34
|
end
|
@@ -6,7 +6,7 @@ module ERBLint
|
|
6
6
|
module Linters
|
7
7
|
module GitHub
|
8
8
|
module Accessibility
|
9
|
-
class
|
9
|
+
class AvoidGenericLinkText < Linter
|
10
10
|
include ERBLint::Linters::CustomHelpers
|
11
11
|
include LinterRegistry
|
12
12
|
|
@@ -22,6 +22,11 @@ module ERBLint
|
|
22
22
|
|
23
23
|
MESSAGE = "Avoid using generic link text such as #{BANNED_GENERIC_TEXT.join(', ')} which do not make sense in isolation."
|
24
24
|
|
25
|
+
class ConfigSchema < LinterConfig
|
26
|
+
property :counter_enabled, accepts: [true, false], default: false, reader: :counter_enabled?
|
27
|
+
end
|
28
|
+
self.config_schema = ConfigSchema
|
29
|
+
|
25
30
|
def run(processed_source)
|
26
31
|
processed_source.ast.children.each_with_index do |node, index|
|
27
32
|
next unless node.methods.include?(:type) && node.type == :text
|
@@ -93,20 +98,8 @@ module ERBLint
|
|
93
98
|
banned_text = nil
|
94
99
|
end
|
95
100
|
end
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
def autocorrect(processed_source, offense)
|
100
|
-
return unless offense.context
|
101
|
-
|
102
|
-
lambda do |corrector|
|
103
|
-
if processed_source.file_content.include?("erblint:counter #{simple_class_name}")
|
104
|
-
# update the counter if exists
|
105
|
-
corrector.replace(offense.source_range, offense.context)
|
106
|
-
else
|
107
|
-
# add comment with counter if none
|
108
|
-
corrector.insert_before(processed_source.source_buffer.source_range, "#{offense.context}\n")
|
109
|
-
end
|
101
|
+
if @config.counter_enabled?
|
102
|
+
counter_correct?(processed_source)
|
110
103
|
end
|
111
104
|
end
|
112
105
|
|
@@ -6,13 +6,23 @@ module ERBLint
|
|
6
6
|
module Linters
|
7
7
|
module GitHub
|
8
8
|
module Accessibility
|
9
|
-
class
|
9
|
+
class DisabledAttribute < Linter
|
10
10
|
include ERBLint::Linters::CustomHelpers
|
11
11
|
include LinterRegistry
|
12
12
|
|
13
13
|
VALID_DISABLED_TAGS = %w[button input textarea option select fieldset optgroup task-lists].freeze
|
14
14
|
MESSAGE = "`disabled` is only valid on #{VALID_DISABLED_TAGS.join(', ')}."
|
15
15
|
|
16
|
+
class ConfigSchema < LinterConfig
|
17
|
+
property :counter_enabled, accepts: [true, false], default: false, reader: :counter_enabled?
|
18
|
+
end
|
19
|
+
self.config_schema = ConfigSchema
|
20
|
+
|
21
|
+
class ConfigSchema < LinterConfig
|
22
|
+
property :counter_enabled, accepts: [true, false], default: false, reader: :counter_enabled?
|
23
|
+
end
|
24
|
+
self.config_schema = ConfigSchema
|
25
|
+
|
16
26
|
def run(processed_source)
|
17
27
|
tags(processed_source).each do |tag|
|
18
28
|
next if tag.closing?
|
@@ -22,20 +32,8 @@ module ERBLint
|
|
22
32
|
generate_offense(self.class, processed_source, tag)
|
23
33
|
end
|
24
34
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
def autocorrect(processed_source, offense)
|
29
|
-
return unless offense.context
|
30
|
-
|
31
|
-
lambda do |corrector|
|
32
|
-
if processed_source.file_content.include?("erblint:counter #{simple_class_name}")
|
33
|
-
# update the counter if exists
|
34
|
-
corrector.replace(offense.source_range, offense.context)
|
35
|
-
else
|
36
|
-
# add comment with counter if none
|
37
|
-
corrector.insert_before(processed_source.source_buffer.source_range, "#{offense.context}\n")
|
38
|
-
end
|
35
|
+
if @config.counter_enabled?
|
36
|
+
counter_correct?(processed_source)
|
39
37
|
end
|
40
38
|
end
|
41
39
|
end
|
@@ -6,13 +6,18 @@ module ERBLint
|
|
6
6
|
module Linters
|
7
7
|
module GitHub
|
8
8
|
module Accessibility
|
9
|
-
class
|
9
|
+
class IframeHasTitle < Linter
|
10
10
|
include ERBLint::Linters::CustomHelpers
|
11
11
|
include LinterRegistry
|
12
12
|
|
13
13
|
MESSAGE = "`<iframe>` with meaningful content should have a title attribute that identifies the content."\
|
14
14
|
" If `<iframe>` has no meaningful content, hide it from assistive technology with `aria-hidden='true'`."\
|
15
15
|
|
16
|
+
class ConfigSchema < LinterConfig
|
17
|
+
property :counter_enabled, accepts: [true, false], default: false, reader: :counter_enabled?
|
18
|
+
end
|
19
|
+
self.config_schema = ConfigSchema
|
20
|
+
|
16
21
|
def run(processed_source)
|
17
22
|
tags(processed_source).each do |tag|
|
18
23
|
next if tag.name != "iframe"
|
@@ -23,20 +28,8 @@ module ERBLint
|
|
23
28
|
generate_offense(self.class, processed_source, tag) if title.empty? && !aria_hidden?(tag)
|
24
29
|
end
|
25
30
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
def autocorrect(processed_source, offense)
|
30
|
-
return unless offense.context
|
31
|
-
|
32
|
-
lambda do |corrector|
|
33
|
-
if processed_source.file_content.include?("erblint:counter #{simple_class_name}")
|
34
|
-
# update the counter if exists
|
35
|
-
corrector.replace(offense.source_range, offense.context)
|
36
|
-
else
|
37
|
-
# add comment with counter if none
|
38
|
-
corrector.insert_before(processed_source.source_buffer.source_range, "#{offense.context}\n")
|
39
|
-
end
|
31
|
+
if @config.counter_enabled?
|
32
|
+
counter_correct?(processed_source)
|
40
33
|
end
|
41
34
|
end
|
42
35
|
|
data/lib/erblint-github/linters/github/accessibility/{image_has_alt_counter.rb → image_has_alt.rb}
RENAMED
@@ -6,12 +6,17 @@ module ERBLint
|
|
6
6
|
module Linters
|
7
7
|
module GitHub
|
8
8
|
module Accessibility
|
9
|
-
class
|
9
|
+
class ImageHasAlt < Linter
|
10
10
|
include ERBLint::Linters::CustomHelpers
|
11
11
|
include LinterRegistry
|
12
12
|
|
13
13
|
MESSAGE = "<img> should have an alt prop with meaningful text or an empty string for decorative images"
|
14
14
|
|
15
|
+
class ConfigSchema < LinterConfig
|
16
|
+
property :counter_enabled, accepts: [true, false], default: false, reader: :counter_enabled?
|
17
|
+
end
|
18
|
+
self.config_schema = ConfigSchema
|
19
|
+
|
15
20
|
def run(processed_source)
|
16
21
|
tags(processed_source).each do |tag|
|
17
22
|
next if tag.name != "img"
|
@@ -22,20 +27,8 @@ module ERBLint
|
|
22
27
|
generate_offense(self.class, processed_source, tag) if alt.empty?
|
23
28
|
end
|
24
29
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
def autocorrect(processed_source, offense)
|
29
|
-
return unless offense.context
|
30
|
-
|
31
|
-
lambda do |corrector|
|
32
|
-
if processed_source.file_content.include?("erblint:counter #{simple_class_name}")
|
33
|
-
# update the counter if exists
|
34
|
-
corrector.replace(offense.source_range, offense.context)
|
35
|
-
else
|
36
|
-
# add comment with counter if none
|
37
|
-
corrector.insert_before(processed_source.source_buffer.source_range, "#{offense.context}\n")
|
38
|
-
end
|
30
|
+
if @config.counter_enabled?
|
31
|
+
counter_correct?(processed_source)
|
39
32
|
end
|
40
33
|
end
|
41
34
|
end
|
@@ -6,7 +6,7 @@ module ERBLint
|
|
6
6
|
module Linters
|
7
7
|
module GitHub
|
8
8
|
module Accessibility
|
9
|
-
class
|
9
|
+
class LandmarkHasLabel < Linter
|
10
10
|
include ERBLint::Linters::CustomHelpers
|
11
11
|
include LinterRegistry
|
12
12
|
|
@@ -36,6 +36,11 @@ module ERBLint
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
+
class ConfigSchema < LinterConfig
|
40
|
+
property :counter_enabled, accepts: [true, false], default: false, reader: :counter_enabled?
|
41
|
+
end
|
42
|
+
self.config_schema = ConfigSchema
|
43
|
+
|
39
44
|
def run(processed_source)
|
40
45
|
tags(processed_source).each do |tag|
|
41
46
|
next if tag.closing?
|
@@ -52,20 +57,8 @@ module ERBLint
|
|
52
57
|
end
|
53
58
|
end
|
54
59
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
def autocorrect(processed_source, offense)
|
59
|
-
return unless offense.context
|
60
|
-
|
61
|
-
lambda do |corrector|
|
62
|
-
if processed_source.file_content.include?("erblint:counter #{simple_class_name}")
|
63
|
-
# update the counter if exists
|
64
|
-
corrector.replace(offense.source_range, offense.context)
|
65
|
-
else
|
66
|
-
# add comment with counter if none
|
67
|
-
corrector.insert_before(processed_source.source_buffer.source_range, "#{offense.context}\n")
|
68
|
-
end
|
60
|
+
if @config.counter_enabled?
|
61
|
+
counter_correct?(processed_source)
|
69
62
|
end
|
70
63
|
end
|
71
64
|
end
|
data/lib/erblint-github/linters/github/accessibility/{link_has_href_counter.rb → link_has_href.rb}
RENAMED
@@ -6,12 +6,17 @@ module ERBLint
|
|
6
6
|
module Linters
|
7
7
|
module GitHub
|
8
8
|
module Accessibility
|
9
|
-
class
|
9
|
+
class LinkHasHref < Linter
|
10
10
|
include ERBLint::Linters::CustomHelpers
|
11
11
|
include LinterRegistry
|
12
12
|
|
13
13
|
MESSAGE = "Links should go somewhere, you probably want to use a `<button>` instead."
|
14
14
|
|
15
|
+
class ConfigSchema < LinterConfig
|
16
|
+
property :counter_enabled, accepts: [true, false], default: false, reader: :counter_enabled?
|
17
|
+
end
|
18
|
+
self.config_schema = ConfigSchema
|
19
|
+
|
15
20
|
def run(processed_source)
|
16
21
|
tags(processed_source).each do |tag|
|
17
22
|
next if tag.name != "a"
|
@@ -22,20 +27,8 @@ module ERBLint
|
|
22
27
|
generate_offense(self.class, processed_source, tag) if (!name && href.empty?) || href.include?("#")
|
23
28
|
end
|
24
29
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
def autocorrect(processed_source, offense)
|
29
|
-
return unless offense.context
|
30
|
-
|
31
|
-
lambda do |corrector|
|
32
|
-
if processed_source.file_content.include?("erblint:counter #{simple_class_name}")
|
33
|
-
# update the counter if exists
|
34
|
-
corrector.replace(offense.source_range, offense.context)
|
35
|
-
else
|
36
|
-
# add comment with counter if none
|
37
|
-
corrector.insert_before(processed_source.source_buffer.source_range, "#{offense.context}\n")
|
38
|
-
end
|
30
|
+
if @config.counter_enabled?
|
31
|
+
counter_correct?(processed_source)
|
39
32
|
end
|
40
33
|
end
|
41
34
|
end
|
@@ -6,12 +6,16 @@ module ERBLint
|
|
6
6
|
module Linters
|
7
7
|
module GitHub
|
8
8
|
module Accessibility
|
9
|
-
class
|
9
|
+
class NestedInteractiveElements < Linter
|
10
10
|
include ERBLint::Linters::CustomHelpers
|
11
11
|
include LinterRegistry
|
12
12
|
|
13
13
|
MESSAGE = "Nesting interactive elements produces invalid HTML, and ssistive technologies, such as screen readers, might ignore or respond unexpectedly to such nested controls."
|
14
14
|
|
15
|
+
class ConfigSchema < LinterConfig
|
16
|
+
property :counter_enabled, accepts: [true, false], default: false, reader: :counter_enabled?
|
17
|
+
end
|
18
|
+
self.config_schema = ConfigSchema
|
15
19
|
def run(processed_source)
|
16
20
|
last_interactive_element = nil
|
17
21
|
tags(processed_source).each do |tag|
|
@@ -31,20 +35,8 @@ module ERBLint
|
|
31
35
|
last_interactive_element = tag unless tag&.name == "input"
|
32
36
|
end
|
33
37
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
def autocorrect(processed_source, offense)
|
38
|
-
return unless offense.context
|
39
|
-
|
40
|
-
lambda do |corrector|
|
41
|
-
if processed_source.file_content.include?("erblint:counter #{simple_class_name}")
|
42
|
-
# update the counter if exists
|
43
|
-
corrector.replace(offense.source_range, offense.context)
|
44
|
-
else
|
45
|
-
# add comment with counter if none
|
46
|
-
corrector.insert_before(processed_source.source_buffer.source_range, "#{offense.context}\n")
|
47
|
-
end
|
38
|
+
if @config.counter_enabled?
|
39
|
+
counter_correct?(processed_source)
|
48
40
|
end
|
49
41
|
end
|
50
42
|
end
|
@@ -6,32 +6,25 @@ module ERBLint
|
|
6
6
|
module Linters
|
7
7
|
module GitHub
|
8
8
|
module Accessibility
|
9
|
-
class
|
9
|
+
class NoAriaHiddenOnFocusable < Linter
|
10
10
|
include ERBLint::Linters::CustomHelpers
|
11
11
|
include LinterRegistry
|
12
12
|
|
13
13
|
MESSAGE = "Elements that are focusable should not have `aria-hidden='true' because it will cause confusion for assistive technology users."
|
14
14
|
|
15
|
+
class ConfigSchema < LinterConfig
|
16
|
+
property :counter_enabled, accepts: [true, false], default: false, reader: :counter_enabled?
|
17
|
+
end
|
18
|
+
self.config_schema = ConfigSchema
|
19
|
+
|
15
20
|
def run(processed_source)
|
16
21
|
tags(processed_source).each do |tag|
|
17
22
|
aria_hidden = possible_attribute_values(tag, "aria-hidden")
|
18
23
|
generate_offense(self.class, processed_source, tag) if aria_hidden.include?("true") && focusable?(tag)
|
19
24
|
end
|
20
25
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
def autocorrect(processed_source, offense)
|
25
|
-
return unless offense.context
|
26
|
-
|
27
|
-
lambda do |corrector|
|
28
|
-
if processed_source.file_content.include?("erblint:counter #{simple_class_name}")
|
29
|
-
# update the counter if exists
|
30
|
-
corrector.replace(offense.source_range, offense.context)
|
31
|
-
else
|
32
|
-
# add comment with counter if none
|
33
|
-
corrector.insert_before(processed_source.source_buffer.source_range, "#{offense.context}\n")
|
34
|
-
end
|
26
|
+
if @config.counter_enabled?
|
27
|
+
counter_correct?(processed_source)
|
35
28
|
end
|
36
29
|
end
|
37
30
|
end
|
@@ -6,7 +6,7 @@ module ERBLint
|
|
6
6
|
module Linters
|
7
7
|
module GitHub
|
8
8
|
module Accessibility
|
9
|
-
class
|
9
|
+
class NoAriaLabelMisuse < Linter
|
10
10
|
include ERBLint::Linters::CustomHelpers
|
11
11
|
include LinterRegistry
|
12
12
|
|
@@ -18,6 +18,11 @@ module ERBLint
|
|
18
18
|
|
19
19
|
MESSAGE = "[aria-label] and [aria-labelledby] usage are only reliably supported on interactive elements and a subset of ARIA roles"
|
20
20
|
|
21
|
+
class ConfigSchema < LinterConfig
|
22
|
+
property :counter_enabled, accepts: [true, false], default: false, reader: :counter_enabled?
|
23
|
+
end
|
24
|
+
self.config_schema = ConfigSchema
|
25
|
+
|
21
26
|
def run(processed_source)
|
22
27
|
tags(processed_source).each do |tag|
|
23
28
|
next if tag.closing?
|
@@ -34,20 +39,8 @@ module ERBLint
|
|
34
39
|
end
|
35
40
|
end
|
36
41
|
end
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
def autocorrect(processed_source, offense)
|
41
|
-
return unless offense.context
|
42
|
-
|
43
|
-
lambda do |corrector|
|
44
|
-
if processed_source.file_content.include?("erblint:counter #{simple_class_name}")
|
45
|
-
# update the counter if exists
|
46
|
-
corrector.replace(offense.source_range, offense.context)
|
47
|
-
else
|
48
|
-
# add comment with counter if none
|
49
|
-
corrector.insert_before(processed_source.source_buffer.source_range, "#{offense.context}\n")
|
50
|
-
end
|
42
|
+
if @config.counter_enabled?
|
43
|
+
counter_correct?(processed_source)
|
51
44
|
end
|
52
45
|
end
|
53
46
|
end
|
@@ -6,12 +6,17 @@ module ERBLint
|
|
6
6
|
module Linters
|
7
7
|
module GitHub
|
8
8
|
module Accessibility
|
9
|
-
class
|
9
|
+
class NoPositiveTabIndex < Linter
|
10
10
|
include ERBLint::Linters::CustomHelpers
|
11
11
|
include LinterRegistry
|
12
12
|
|
13
13
|
MESSAGE = "Do not use positive tabindex as it is error prone and can severely disrupt navigation experience for keyboard users"
|
14
14
|
|
15
|
+
class ConfigSchema < LinterConfig
|
16
|
+
property :counter_enabled, accepts: [true, false], default: false, reader: :counter_enabled?
|
17
|
+
end
|
18
|
+
self.config_schema = ConfigSchema
|
19
|
+
|
15
20
|
def run(processed_source)
|
16
21
|
tags(processed_source).each do |tag|
|
17
22
|
next if tag.closing?
|
@@ -20,20 +25,8 @@ module ERBLint
|
|
20
25
|
generate_offense(self.class, processed_source, tag)
|
21
26
|
end
|
22
27
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
def autocorrect(processed_source, offense)
|
27
|
-
return unless offense.context
|
28
|
-
|
29
|
-
lambda do |corrector|
|
30
|
-
if processed_source.file_content.include?("erblint:counter #{simple_class_name}")
|
31
|
-
# update the counter if exists
|
32
|
-
corrector.replace(offense.source_range, offense.context)
|
33
|
-
else
|
34
|
-
# add comment with counter if none
|
35
|
-
corrector.insert_before(processed_source.source_buffer.source_range, "#{offense.context}\n")
|
36
|
-
end
|
28
|
+
if @config.counter_enabled?
|
29
|
+
counter_correct?(processed_source)
|
37
30
|
end
|
38
31
|
end
|
39
32
|
end
|
@@ -6,13 +6,18 @@ module ERBLint
|
|
6
6
|
module Linters
|
7
7
|
module GitHub
|
8
8
|
module Accessibility
|
9
|
-
class
|
9
|
+
class NoRedundantImageAlt < Linter
|
10
10
|
include ERBLint::Linters::CustomHelpers
|
11
11
|
include LinterRegistry
|
12
12
|
|
13
13
|
MESSAGE = "<img> alt prop should not contain `image` or `picture` as screen readers already announce the element as an image"
|
14
14
|
REDUNDANT_ALT_WORDS = %w[image picture].freeze
|
15
15
|
|
16
|
+
class ConfigSchema < LinterConfig
|
17
|
+
property :counter_enabled, accepts: [true, false], default: false, reader: :counter_enabled?
|
18
|
+
end
|
19
|
+
self.config_schema = ConfigSchema
|
20
|
+
|
16
21
|
def run(processed_source)
|
17
22
|
tags(processed_source).each do |tag|
|
18
23
|
next if tag.name != "img"
|
@@ -24,20 +29,8 @@ module ERBLint
|
|
24
29
|
generate_offense(self.class, processed_source, tag) if (alt.downcase.split & REDUNDANT_ALT_WORDS).any?
|
25
30
|
end
|
26
31
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
def autocorrect(processed_source, offense)
|
31
|
-
return unless offense.context
|
32
|
-
|
33
|
-
lambda do |corrector|
|
34
|
-
if processed_source.file_content.include?("erblint:counter #{simple_class_name}")
|
35
|
-
# update the counter if exists
|
36
|
-
corrector.replace(offense.source_range, offense.context)
|
37
|
-
else
|
38
|
-
# add comment with counter if none
|
39
|
-
corrector.insert_before(processed_source.source_buffer.source_range, "#{offense.context}\n")
|
40
|
-
end
|
32
|
+
if @config.counter_enabled?
|
33
|
+
counter_correct?(processed_source)
|
41
34
|
end
|
42
35
|
end
|
43
36
|
end
|
@@ -6,12 +6,17 @@ module ERBLint
|
|
6
6
|
module Linters
|
7
7
|
module GitHub
|
8
8
|
module Accessibility
|
9
|
-
class
|
9
|
+
class NoTitleAttribute < Linter
|
10
10
|
include ERBLint::Linters::CustomHelpers
|
11
11
|
include LinterRegistry
|
12
12
|
|
13
13
|
MESSAGE = "The title attribute should never be used unless for an `<iframe>` as it is inaccessible for several groups of users."
|
14
14
|
|
15
|
+
class ConfigSchema < LinterConfig
|
16
|
+
property :counter_enabled, accepts: [true, false], default: false, reader: :counter_enabled?
|
17
|
+
end
|
18
|
+
self.config_schema = ConfigSchema
|
19
|
+
|
15
20
|
def run(processed_source)
|
16
21
|
tags(processed_source).each do |tag|
|
17
22
|
next if tag.name == "iframe"
|
@@ -21,20 +26,8 @@ module ERBLint
|
|
21
26
|
generate_offense(self.class, processed_source, tag) if title.present?
|
22
27
|
end
|
23
28
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
def autocorrect(processed_source, offense)
|
28
|
-
return unless offense.context
|
29
|
-
|
30
|
-
lambda do |corrector|
|
31
|
-
if processed_source.file_content.include?("erblint:counter #{simple_class_name}")
|
32
|
-
# update the counter if exists
|
33
|
-
corrector.replace(offense.source_range, offense.context)
|
34
|
-
else
|
35
|
-
# add comment with counter if none
|
36
|
-
corrector.insert_before(processed_source.source_buffer.source_range, "#{offense.context}\n")
|
37
|
-
end
|
29
|
+
if @config.counter_enabled?
|
30
|
+
counter_correct?(processed_source)
|
38
31
|
end
|
39
32
|
end
|
40
33
|
end
|
@@ -6,12 +6,17 @@ module ERBLint
|
|
6
6
|
module Linters
|
7
7
|
module GitHub
|
8
8
|
module Accessibility
|
9
|
-
class
|
9
|
+
class SvgHasAccessibleText < Linter
|
10
10
|
include ERBLint::Linters::CustomHelpers
|
11
11
|
include LinterRegistry
|
12
12
|
|
13
13
|
MESSAGE = "`<svg>` must have accessible text. Set `aria-label`, or `aria-labelledby`, or nest a `<title>` element. However, if the `<svg>` is purely decorative, hide it with `aria-hidden='true'.\nFor more info, see https://css-tricks.com/accessible-svgs/."
|
14
14
|
|
15
|
+
class ConfigSchema < LinterConfig
|
16
|
+
property :counter_enabled, accepts: [true, false], default: false, reader: :counter_enabled?
|
17
|
+
end
|
18
|
+
self.config_schema = ConfigSchema
|
19
|
+
|
15
20
|
def run(processed_source)
|
16
21
|
current_svg = nil
|
17
22
|
has_accessible_label = false
|
@@ -37,20 +42,8 @@ module ERBLint
|
|
37
42
|
end
|
38
43
|
end
|
39
44
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
def autocorrect(processed_source, offense)
|
44
|
-
return unless offense.context
|
45
|
-
|
46
|
-
lambda do |corrector|
|
47
|
-
if processed_source.file_content.include?("erblint:counter #{simple_class_name}")
|
48
|
-
# update the counter if exists
|
49
|
-
corrector.replace(offense.source_range, offense.context)
|
50
|
-
else
|
51
|
-
# add comment with counter if none
|
52
|
-
corrector.insert_before(processed_source.source_buffer.source_range, "#{offense.context}\n")
|
53
|
-
end
|
45
|
+
if @config.counter_enabled?
|
46
|
+
counter_correct?(processed_source)
|
54
47
|
end
|
55
48
|
end
|
56
49
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: erblint-github
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- GitHub Open Source
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-04-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: erb_lint
|
@@ -105,20 +105,20 @@ files:
|
|
105
105
|
- README.md
|
106
106
|
- lib/erblint-github/linters.rb
|
107
107
|
- lib/erblint-github/linters/custom_helpers.rb
|
108
|
-
- lib/erblint-github/linters/github/accessibility/
|
109
|
-
- lib/erblint-github/linters/github/accessibility/
|
110
|
-
- lib/erblint-github/linters/github/accessibility/
|
111
|
-
- lib/erblint-github/linters/github/accessibility/
|
112
|
-
- lib/erblint-github/linters/github/accessibility/
|
113
|
-
- lib/erblint-github/linters/github/accessibility/
|
114
|
-
- lib/erblint-github/linters/github/accessibility/
|
115
|
-
- lib/erblint-github/linters/github/accessibility/
|
116
|
-
- lib/erblint-github/linters/github/accessibility/
|
117
|
-
- lib/erblint-github/linters/github/accessibility/
|
118
|
-
- lib/erblint-github/linters/github/accessibility/
|
119
|
-
- lib/erblint-github/linters/github/accessibility/
|
120
|
-
- lib/erblint-github/linters/github/accessibility/
|
121
|
-
- lib/erblint-github/linters/github/accessibility/
|
108
|
+
- lib/erblint-github/linters/github/accessibility/avoid_both_disabled_and_aria_disabled.rb
|
109
|
+
- lib/erblint-github/linters/github/accessibility/avoid_generic_link_text.rb
|
110
|
+
- lib/erblint-github/linters/github/accessibility/disabled_attribute.rb
|
111
|
+
- lib/erblint-github/linters/github/accessibility/iframe_has_title.rb
|
112
|
+
- lib/erblint-github/linters/github/accessibility/image_has_alt.rb
|
113
|
+
- lib/erblint-github/linters/github/accessibility/landmark_has_label.rb
|
114
|
+
- lib/erblint-github/linters/github/accessibility/link_has_href.rb
|
115
|
+
- lib/erblint-github/linters/github/accessibility/nested_interactive_elements.rb
|
116
|
+
- lib/erblint-github/linters/github/accessibility/no_aria_hidden_on_focusable.rb
|
117
|
+
- lib/erblint-github/linters/github/accessibility/no_aria_label_misuse.rb
|
118
|
+
- lib/erblint-github/linters/github/accessibility/no_positive_tab_index.rb
|
119
|
+
- lib/erblint-github/linters/github/accessibility/no_redundant_image_alt.rb
|
120
|
+
- lib/erblint-github/linters/github/accessibility/no_title_attribute.rb
|
121
|
+
- lib/erblint-github/linters/github/accessibility/svg_has_accessible_text.rb
|
122
122
|
- lib/tasks/docs.rake
|
123
123
|
- lib/tasks/tests.rake
|
124
124
|
homepage: https://github.com/github/erblint-github
|
@@ -141,7 +141,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
141
141
|
- !ruby/object:Gem::Version
|
142
142
|
version: '0'
|
143
143
|
requirements: []
|
144
|
-
rubygems_version: 3.
|
144
|
+
rubygems_version: 3.3.7
|
145
145
|
signing_key:
|
146
146
|
specification_version: 4
|
147
147
|
summary: erblint GitHub
|