erblint-github 0.0.7 → 0.1.0

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: 2e31129554b451397cf438dc56e52ce9f0e21b7df4cecb59f92324b7ca0c7e5c
4
- data.tar.gz: a17e3f541f4975cdfafb0d046a312581fe6481ba4e113f49f7cb9ed67a09d477
3
+ metadata.gz: 0e372a7e49311d6c270ff943ca1ec446c1f20ad06ac47fc784ce60c23f51b1d1
4
+ data.tar.gz: ac136d5460abc4d8fef0229036486b57565425bc4660ca252b6344378a6d1629
5
5
  SHA512:
6
- metadata.gz: 2aba7d9263d58382aabef89e3688993dc7bbf230199ae8b952159bc0c3287402107562537095b7184f55fa192a7bf0366ff43875f3f85fcf73ca57cb45a9ee21
7
- data.tar.gz: 69a2e3fb5a40d79120655ba41bb38c2120f01b941b73ce888bc7e29e57fc9c31c119770f3b719fedb9cf1a8cef4db341696eea54c4b658320e80ff540dec4e64
6
+ metadata.gz: 42290941d5f2d0b2643842e62a1e5f759d8387294f829a01b52c354103c42aade10fcf0d30571fd4b5a061b9a6cd968aaf6f5204189b0049971ac99f1baae71e
7
+ data.tar.gz: 557bbc994d0fb8a3e0a49a129f22c9a209be7219fa9b0812b77fbe4ba2ce66265cd36c42674572db33f7729d50dbc00c0388d06899a2ec0aadcd141e4a3e9a74
data/README.md CHANGED
@@ -25,10 +25,16 @@ require "erblint-github/linters"
25
25
  linters:
26
26
  GitHub::Accessibility::AvoidBothDisabledAndAriaDisabled:
27
27
  enabled: true
28
+ GitHub::Accessibility::AvoidGenericLinkTextCounter:
29
+ enabled: true
30
+ GitHub::Accessibility::DisabledAttributeCounter:
31
+ enabled: true
28
32
  GitHub::Accessibility::IframeHasTitle:
29
33
  enabled: true
30
34
  GitHub::Accessibility::ImageHasAlt:
31
35
  enabled: true
36
+ GitHub::Accessibility::LinkHasHrefCounter:
37
+ enabled: true
32
38
  GitHub::Accessibility::NoAriaLabelMisuseCounter:
33
39
  enabled: true
34
40
  GitHub::Accessibility::NoPositiveTabIndex:
@@ -37,18 +43,23 @@ linters:
37
43
  enabled: true
38
44
  GitHub::Accessibility::NoTitleAttributeCounter:
39
45
  enabled: true
46
+ GitHub::Accessibility::SvgHasAccessibleTextCounter:
47
+ enabled: true
40
48
  ```
41
49
 
42
50
  ## Rules
43
51
 
44
52
  - [GitHub::Accessibility::AvoidBothDisabledAndAriaDisabled](./docs/rules/accessibility/avoid-both-disabled-and-aria-disabled.md)
45
53
  - [GitHub::Accessibility::AvoidGenericLinkTextCounter](./docs/rules/accessibility/avoid-generic-link-text-counter.md)
54
+ - [GitHub::Accessibility::DisabledAttributeCounter](./docs/rules/accessibility/disabled-attribute-counter-test)
46
55
  - [GitHub::Accessibility::IframeHasTitle](./docs/rules/accessibility/iframe-has-title.md)
47
56
  - [GitHub::Accessibility::ImageHasAlt](./docs/rules/accessibility/image-has-alt.md)
57
+ - [GitHub::Accessibility::LinkHasHrefCounter](./docs/rules/accessibility/link_has_href-counter.md)
48
58
  - [GitHub::Accessibility::NoAriaLabelMisuseCounter](./docs/rules/accessibility/no-aria-label-misuse-counter.md)
49
59
  - [GitHub::Accessibility::NoPositiveTabIndex](./docs/rules/accessibility/no-positive-tab-index.md)
50
60
  - [GitHub::Accessibility::NoRedundantImageAlt](./docs/rules/accessibility/no-redundant-image-alt.md)
51
61
  - [GitHub::Accessibility::NoTitleAttributeCounter](./docs/rules/accessibility/no-title-attribute-counter.md)
62
+ - [GitHub::Accessibility::SvgHasAccessibleTextCounter](./docs/rules/accessibility/svg_has_accessible_text_counter.md)
52
63
 
53
64
  ## Testing
54
65
 
@@ -56,3 +67,12 @@ linters:
56
67
  bundle install
57
68
  bundle exec rake
58
69
  ```
70
+
71
+ ## Recommended extension
72
+
73
+ 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.
74
+
75
+ ## Note
76
+
77
+ 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,
78
+ 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.
@@ -112,12 +112,17 @@ module ERBLint
112
112
 
113
113
  private
114
114
 
115
+ # Downcase and strip punctuation and extra whitespaces.
116
+ def stripped_text(text)
117
+ text.downcase.gsub(/\W+/, " ").strip
118
+ end
119
+
115
120
  def banned_text?(text)
116
- BANNED_GENERIC_TEXT.map(&:downcase).include?(text.downcase)
121
+ BANNED_GENERIC_TEXT.map(&:downcase).include?(stripped_text(text))
117
122
  end
118
123
 
119
124
  def valid_accessible_name?(aria_label, text)
120
- aria_label.downcase.include?(text.downcase)
125
+ stripped_text(aria_label).include?(stripped_text(text))
121
126
  end
122
127
 
123
128
  def extract_ruby_node(source)
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../../custom_helpers"
4
+
5
+ module ERBLint
6
+ module Linters
7
+ module GitHub
8
+ module Accessibility
9
+ class DisabledAttributeCounter < Linter
10
+ include ERBLint::Linters::CustomHelpers
11
+ include LinterRegistry
12
+
13
+ VALID_DISABLED_TAGS = %w[button input textarea option select fieldset optgroup task-lists].freeze
14
+ MESSAGE = "`disabled` is only valid on #{VALID_DISABLED_TAGS.join(', ')}."
15
+
16
+ def run(processed_source)
17
+ tags(processed_source).each do |tag|
18
+ next if tag.closing?
19
+ next if VALID_DISABLED_TAGS.include?(tag.name)
20
+ next if tag.attributes["disabled"].nil?
21
+
22
+ generate_offense(self.class, processed_source, tag)
23
+ end
24
+
25
+ counter_correct?(processed_source)
26
+ end
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
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../../custom_helpers"
4
+
5
+ module ERBLint
6
+ module Linters
7
+ module GitHub
8
+ module Accessibility
9
+ class LinkHasHrefCounter < Linter
10
+ include ERBLint::Linters::CustomHelpers
11
+ include LinterRegistry
12
+
13
+ MESSAGE = "Links should go somewhere, you probably want to use a `<button>` instead."
14
+
15
+ def run(processed_source)
16
+ tags(processed_source).each do |tag|
17
+ next if tag.name != "a"
18
+ next if tag.closing?
19
+
20
+ href = possible_attribute_values(tag, "href")
21
+ name = tag.attributes["name"]
22
+ generate_offense(self.class, processed_source, tag) if (!name && href.empty?) || href.include?("#")
23
+ end
24
+
25
+ counter_correct?(processed_source)
26
+ end
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
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../../custom_helpers"
4
+
5
+ module ERBLint
6
+ module Linters
7
+ module GitHub
8
+ module Accessibility
9
+ class SvgHasAccessibleTextCounter < Linter
10
+ include ERBLint::Linters::CustomHelpers
11
+ include LinterRegistry
12
+
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
+
15
+ def run(processed_source)
16
+ current_svg = nil
17
+ has_accessible_label = false
18
+
19
+ tags(processed_source).each do |tag|
20
+ # Checks whether tag is a <title> nested in an <svg>
21
+ has_accessible_label = true if current_svg && tag.name == "title" && !tag.closing?
22
+
23
+ next if tag.name != "svg"
24
+
25
+ if tag.closing?
26
+ generate_offense(self.class, processed_source, current_svg) unless has_accessible_label
27
+ current_svg = nil
28
+ elsif possible_attribute_values(tag, "aria-hidden").join == "true"
29
+ has_accessible_label = true
30
+ current_svg = tag
31
+ else
32
+ current_svg = tag
33
+ aria_label = possible_attribute_values(tag, "aria-label").join
34
+ aria_labelledby = possible_attribute_values(tag, "aria-labelledby").join
35
+
36
+ has_accessible_label = aria_label.present? || aria_labelledby.present?
37
+ end
38
+ end
39
+
40
+ counter_correct?(processed_source)
41
+ end
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
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ 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.0.7
4
+ version: 0.1.0
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-06-20 00:00:00.000000000 Z
11
+ date: 2022-07-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: erb_lint
@@ -107,12 +107,15 @@ files:
107
107
  - lib/erblint-github/linters/custom_helpers.rb
108
108
  - lib/erblint-github/linters/github/accessibility/avoid_both_disabled_and_aria_disabled.rb
109
109
  - lib/erblint-github/linters/github/accessibility/avoid_generic_link_text_counter.rb
110
+ - lib/erblint-github/linters/github/accessibility/disabled_attribute_counter.rb
110
111
  - lib/erblint-github/linters/github/accessibility/iframe_has_title.rb
111
112
  - lib/erblint-github/linters/github/accessibility/image_has_alt.rb
113
+ - lib/erblint-github/linters/github/accessibility/link_has_href_counter.rb
112
114
  - lib/erblint-github/linters/github/accessibility/no_aria_label_misuse_counter.rb
113
115
  - lib/erblint-github/linters/github/accessibility/no_positive_tab_index.rb
114
116
  - lib/erblint-github/linters/github/accessibility/no_redundant_image_alt.rb
115
117
  - lib/erblint-github/linters/github/accessibility/no_title_attribute_counter.rb
118
+ - lib/erblint-github/linters/github/accessibility/svg_has_accessible_text_counter.rb
116
119
  - lib/tasks/docs.rake
117
120
  - lib/tasks/tests.rake
118
121
  homepage: https://github.com/github/erblint-github
@@ -135,7 +138,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
135
138
  - !ruby/object:Gem::Version
136
139
  version: '0'
137
140
  requirements: []
138
- rubygems_version: 3.2.32
141
+ rubygems_version: 3.2.9
139
142
  signing_key:
140
143
  specification_version: 4
141
144
  summary: erblint GitHub