erblint-github 0.0.6 → 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cfd39a72bcefe35b0231242045b4aca7cfdf6468b795d2703528655039b9e7be
|
4
|
+
data.tar.gz: 4331758cf201fe621f5510554766a6d300f46b43ef36d272e82f53d2ffaf420d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ea54a4d64005d7be039a3f9ed620447ca673db7113e821f303cce4c35da74835c6f124afa84f3b7e8eb35e2adb278394aef1f6326a10f73ebfb3a9a342c956a1
|
7
|
+
data.tar.gz: 942f3526203855f2a58c37f54b5d2775cc0de910a0adf057889dba2c4e60a1553276b640c7ba6c8fd6ed91d3b3af597ab86c0aa49e84f49ed47005feafcec59a
|
data/README.md
CHANGED
@@ -25,6 +25,8 @@ require "erblint-github/linters"
|
|
25
25
|
linters:
|
26
26
|
GitHub::Accessibility::AvoidBothDisabledAndAriaDisabled:
|
27
27
|
enabled: true
|
28
|
+
GitHub::Accessibility::AvoidGenericLinkTextCounter:
|
29
|
+
enabled: true
|
28
30
|
GitHub::Accessibility::IframeHasTitle:
|
29
31
|
enabled: true
|
30
32
|
GitHub::Accessibility::ImageHasAlt:
|
@@ -56,3 +58,12 @@ linters:
|
|
56
58
|
bundle install
|
57
59
|
bundle exec rake
|
58
60
|
```
|
61
|
+
|
62
|
+
## Recommended extension
|
63
|
+
|
64
|
+
If you use VS Code, we highly encourage [ERB Linter extension](https://marketplace.visualstudio.com/items?itemName=manuelpuyol.erb-linter) to see immediate feedback in your editor.
|
65
|
+
|
66
|
+
## Note
|
67
|
+
|
68
|
+
This repo contains several accessibility-related linting rules to help surface accessibility issues that would otherwise go undetected until a later stage. Please note that due to the limitations of static code analysis,
|
69
|
+
these ERB accessibility checks are NOT enough for ensuring the accessibility of your app. This shouldn't be the only tool you use to catch accessibility issues and should be supplemented with other tools that can check the runtime browser DOM output, as well as processes like accessibility design reviews, manual audits, user testing, etc.
|
@@ -18,6 +18,8 @@ module ERBLint
|
|
18
18
|
"Link",
|
19
19
|
"Here"
|
20
20
|
].freeze
|
21
|
+
ARIA_LABEL_ATTRIBUTES = %w[aria-labelledby aria-label].freeze
|
22
|
+
|
21
23
|
MESSAGE = "Avoid using generic link text such as #{BANNED_GENERIC_TEXT.join(', ')} which do not make sense in isolation."
|
22
24
|
|
23
25
|
def run(processed_source)
|
@@ -25,6 +27,7 @@ module ERBLint
|
|
25
27
|
next unless node.methods.include?(:type) && node.type == :text
|
26
28
|
|
27
29
|
text = node.children.join.strip
|
30
|
+
|
28
31
|
# Checks HTML tags
|
29
32
|
if banned_text?(text)
|
30
33
|
prev_node = processed_source.ast.children[index - 1]
|
@@ -36,8 +39,17 @@ module ERBLint
|
|
36
39
|
prev_node_tag = BetterHtml::Tree::Tag.from_node(prev_node)
|
37
40
|
next_node_tag = BetterHtml::Tree::Tag.from_node(next_node)
|
38
41
|
|
39
|
-
|
42
|
+
aria_label = possible_attribute_values(prev_node_tag, "aria-label")
|
43
|
+
aria_labelledby = possible_attribute_values(prev_node_tag, "aria-labelledby")
|
44
|
+
|
45
|
+
# Checks if nested between two link tags.
|
40
46
|
if link_tag?(prev_node_tag) && link_tag?(next_node_tag) && next_node_tag.closing?
|
47
|
+
# Skip because we cannot reliably check accessible name from aria-labelledby, or an aria-label that is set to a variable
|
48
|
+
# with static code analysis.
|
49
|
+
next if aria_labelledby.present? || (aria_label.present? && aria_label.join.include?("<%="))
|
50
|
+
# Skip because aria-label starts with visible text which we allow. Related to Success Criterion 2.5.3: Label in Name
|
51
|
+
next if aria_label.present? && valid_accessible_name?(aria_label.join, text)
|
52
|
+
|
41
53
|
range = prev_node_tag.loc.begin_pos...text_node_tag.loc.end_pos
|
42
54
|
source_range = processed_source.to_source_range(range)
|
43
55
|
generate_offense_from_source_range(self.class, source_range)
|
@@ -45,20 +57,40 @@ module ERBLint
|
|
45
57
|
end
|
46
58
|
|
47
59
|
# Checks Rails link helpers like `link_to`
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
60
|
+
node.descendants(:erb).each do |erb_node|
|
61
|
+
_, _, code_node = *erb_node
|
62
|
+
source = code_node.loc.source
|
63
|
+
ruby_node = extract_ruby_node(source)
|
64
|
+
send_node = ruby_node&.descendants(:send)&.first
|
65
|
+
next unless send_node.methods.include?(:method_name) && send_node.method_name == :link_to
|
66
|
+
|
67
|
+
banned_text = nil
|
68
|
+
|
69
|
+
send_node.child_nodes.each do |child_node|
|
70
|
+
banned_text = child_node.children.join if child_node.methods.include?(:type) && child_node.type == :str && banned_text?(child_node.children.join)
|
71
|
+
next if banned_text.blank?
|
72
|
+
next unless child_node.methods.include?(:type) && child_node.type == :hash
|
73
|
+
|
74
|
+
child_node.descendants(:pair).each do |pair_node|
|
75
|
+
next unless pair_node.children.first.type?(:sym)
|
76
|
+
|
77
|
+
# Skips if `link_to` has `aria-labelledby` or `aria-label` which cannot be evaluated accurately with ERB lint alone.
|
78
|
+
# ERB lint removes Ruby string interpolation so the `aria-label` for "<%= link_to 'Learn more', "aria-label": "Learn #{@some_variable}" %>" will
|
79
|
+
# only be `Learn` which is unreliable so we can't do checks :(
|
80
|
+
key_value = pair_node.children.first.children.join
|
81
|
+
banned_text = nil if ARIA_LABEL_ATTRIBUTES.include?(key_value)
|
82
|
+
next unless key_value == "aria"
|
83
|
+
|
84
|
+
pair_node.children[1].descendants(:sym).each do |sym_node|
|
85
|
+
banned_text = nil if sym_node.children.join == "label" || sym_node.children.join == "labelledby"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
if banned_text.present?
|
59
90
|
tag = BetterHtml::Tree::Tag.from_node(code_node)
|
60
91
|
generate_offense(self.class, processed_source, tag)
|
61
|
-
|
92
|
+
end
|
93
|
+
banned_text = nil
|
62
94
|
end
|
63
95
|
end
|
64
96
|
counter_correct?(processed_source)
|
@@ -80,8 +112,17 @@ module ERBLint
|
|
80
112
|
|
81
113
|
private
|
82
114
|
|
115
|
+
# Downcase and strip punctuation and extra whitespaces.
|
116
|
+
def stripped_text(text)
|
117
|
+
text.downcase.gsub(/\W+/, " ").strip
|
118
|
+
end
|
119
|
+
|
83
120
|
def banned_text?(text)
|
84
|
-
BANNED_GENERIC_TEXT.map(&:downcase).include?(text
|
121
|
+
BANNED_GENERIC_TEXT.map(&:downcase).include?(stripped_text(text))
|
122
|
+
end
|
123
|
+
|
124
|
+
def valid_accessible_name?(aria_label, text)
|
125
|
+
stripped_text(aria_label).include?(stripped_text(text))
|
85
126
|
end
|
86
127
|
|
87
128
|
def extract_ruby_node(source)
|
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.0.
|
4
|
+
version: 0.0.9
|
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: 2022-
|
11
|
+
date: 2022-07-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: erb_lint
|