erblint-github 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (18) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +34 -31
  3. data/lib/erblint-github/linters/custom_helpers.rb +11 -0
  4. data/lib/erblint-github/linters/github/accessibility/{avoid_both_disabled_and_aria_disabled_counter.rb → avoid_both_disabled_and_aria_disabled.rb} +8 -15
  5. data/lib/erblint-github/linters/github/accessibility/{avoid_generic_link_text_counter.rb → avoid_generic_link_text.rb} +8 -15
  6. data/lib/erblint-github/linters/github/accessibility/{disabled_attribute_counter.rb → disabled_attribute.rb} +13 -15
  7. data/lib/erblint-github/linters/github/accessibility/{iframe_has_title_counter.rb → iframe_has_title.rb} +8 -15
  8. data/lib/erblint-github/linters/github/accessibility/{image_has_alt_counter.rb → image_has_alt.rb} +8 -15
  9. data/lib/erblint-github/linters/github/accessibility/{landmark_has_label_counter.rb → landmark_has_label.rb} +8 -15
  10. data/lib/erblint-github/linters/github/accessibility/{link_has_href_counter.rb → link_has_href.rb} +8 -15
  11. data/lib/erblint-github/linters/github/accessibility/{nested_interactive_elements_counter.rb → nested_interactive_elements.rb} +7 -16
  12. data/lib/erblint-github/linters/github/accessibility/no_aria_hidden_on_focusable.rb +34 -0
  13. data/lib/erblint-github/linters/github/accessibility/{no_aria_label_misuse_counter.rb → no_aria_label_misuse.rb} +8 -15
  14. data/lib/erblint-github/linters/github/accessibility/{no_positive_tab_index_counter.rb → no_positive_tab_index.rb} +8 -15
  15. data/lib/erblint-github/linters/github/accessibility/{no_redundant_image_alt_counter.rb → no_redundant_image_alt.rb} +8 -15
  16. data/lib/erblint-github/linters/github/accessibility/{no_title_attribute_counter.rb → no_title_attribute.rb} +8 -15
  17. data/lib/erblint-github/linters/github/accessibility/{svg_has_accessible_text_counter.rb → svg_has_accessible_text.rb} +8 -15
  18. metadata +31 -30
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c3e42bd7e46e4628deda31d1657890c3ccc9e683d85943f2540629d36962b114
4
- data.tar.gz: '099d8957fbc44e9739296d60c6f4436d7cf96ad0731bf69aca6edd5663acf98f'
3
+ metadata.gz: ae2332b3396f7d9533f5a13c71cce75e048308f5d1ebf7a351dca556408652d2
4
+ data.tar.gz: a491e50f3c4c1da08e570514bba69f11f5631c1d82a241e236269ebed1a86f0b
5
5
  SHA512:
6
- metadata.gz: e41f3c103e9b0c57cd9706706605d26e25aafdae1359d0d123d6dd05b32904a91e0609fcf42d0551bf871d904610c2e38b65e47b2cb10637424426714902394c
7
- data.tar.gz: 6969aff49edec2d4f9d6768eb94d20c5ffc24b01495ea9ad68d134900a1351b7c7a5afcb5896c6b14da3212e36c1bf29c1a308c8fd5215a4bb055e9d303cdcc2
6
+ metadata.gz: d2e983445be5d46bdb88ffc2a8cf3be88aa09dfe1745eca84736ec98830e13b5da606c5b0022b9595b4f5c8435313267d948651d11ea6d64f465700600fcc794
7
+ data.tar.gz: 31671c8e895599bf10659d9978676c532b87fed47f7deec5e977866e457a347d8c5041d029e49448a2f86348967f5aa0ce8c5ada910015bc583dd1b8b60a6d4e
data/README.md CHANGED
@@ -23,53 +23,56 @@ require "erblint-github/linters"
23
23
  ```yaml
24
24
  ---
25
25
  linters:
26
- GitHub::Accessibility::AvoidBothDisabledAndAriaDisabledCounter:
26
+ GitHub::Accessibility::AvoidBothDisabledAndAriaDisabled:
27
27
  enabled: true
28
- GitHub::Accessibility::AvoidGenericLinkTextCounter:
28
+ GitHub::Accessibility::AvoidGenericLinkText:
29
29
  enabled: true
30
- GitHub::Accessibility::DisabledAttributeCounter:
30
+ GitHub::Accessibility::DisabledAttribute:
31
31
  enabled: true
32
- GitHub::Accessibility::IframeHasTitleCounter:
32
+ GitHub::Accessibility::IframeHasTitle:
33
33
  enabled: true
34
- GitHub::Accessibility::ImageHasAltCounter:
34
+ GitHub::Accessibility::ImageHasAlt:
35
35
  enabled: true
36
- GitHub::Accessibility::LandmarkHasLabelCounter:
36
+ GitHub::Accessibility::LandmarkHasLabel:
37
37
  enabled: true
38
- GitHub::Accessibility::LinkHasHrefCounter:
38
+ GitHub::Accessibility::LinkHasHref:
39
39
  enabled: true
40
- GitHub::Accessibility::NestedInteractiveElementsCounter:
40
+ GitHub::Accessibility::NestedInteractiveElements:
41
41
  enabled: true
42
- GitHub::Accessibility::NoAriaLabelMisuseCounter:
42
+ GitHub::Accessibility::NoAriaHiddenOnFocusable:
43
43
  enabled: true
44
- GitHub::Accessibility::NoPositiveTabIndexCounter:
44
+ GitHub::Accessibility::NoAriaLabelMisuse:
45
45
  enabled: true
46
- GitHub::Accessibility::NoRedundantImageAltCounter:
46
+ GitHub::Accessibility::NoPositiveTabIndex:
47
47
  enabled: true
48
- GitHub::Accessibility::NoTitleAttributeCounter:
48
+ GitHub::Accessibility::NoRedundantImageAlt:
49
49
  enabled: true
50
- GitHub::Accessibility::SvgHasAccessibleTextCounter:
50
+ GitHub::Accessibility::NoTitleAttribute:
51
+ enabled: true
52
+ GitHub::Accessibility::SvgHasAccessibleText:
51
53
  enabled: true
52
54
  ```
53
55
 
54
56
  ## Rules
55
57
 
56
- - [GitHub::Accessibility::AvoidBothDisabledAndAriaDisabledCounter](./docs/rules/accessibility/avoid-both-disabled-and-aria-disabled-counter.md)
57
- - [GitHub::Accessibility::AvoidGenericLinkTextCounter](./docs/rules/accessibility/avoid-generic-link-text-counter.md)
58
- - [GitHub::Accessibility::DisabledAttributeCounter](./docs/rules/accessibility/disabled-attribute-counter.md)
59
- - [GitHub::Accessibility::LandmarkHasLabelCounter](./docs/rules/accessibility/landmark-has-label-counter.md)
60
- - [GitHub::Accessibility::LinkHasHrefCounter](./docs/rules/accessibility/link-has-href-counter.md)
61
- - [GitHub::Accessibility::NestedInteractiveElementsCounter](./docs/rules/accessibility/nested-interactive-elements-counter.md)
62
- - [GitHub::Accessibility::IframeHasTitleCounter](./docs/rules/accessibility/iframe-has-title-counter.md)
63
- - [GitHub::Accessibility::ImageHasAltCounter](./docs/rules/accessibility/image-has-alt-counter.md)
64
- - [GitHub::Accessibility::NoAriaLabelMisuseCounter](./docs/rules/accessibility/no-aria-label-misuse-counter.md)
65
- - [GitHub::Accessibility::NoPositiveTabIndexCounter](./docs/rules/accessibility/no-positive-tab-index-counter.md)
66
- - [GitHub::Accessibility::NoRedundantImageAltCounter](./docs/rules/accessibility/no-redundant-image-alt-counter.md)
67
- - [GitHub::Accessibility::NoTitleAttributeCounter](./docs/rules/accessibility/no-title-attribute-counter.md)
68
- - [GitHub::Accessibility::SvgHasAccessibleTextCounter](./docs/rules/accessibility/svg-has-accessible-text-counter.md)
69
-
70
- ## Disabling a rule (experimental)
71
-
72
- _This is an experimental feature which should ideally be upstreamed to erblint_
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)_
73
76
 
74
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.
75
78
 
@@ -79,7 +82,7 @@ Rules that are marked as `Counter` can be disabled by adding a comment with the
79
82
  <%# erblint:counter GitHub::Accessibility::LinkHasHrefCounter 1 %>
80
83
  ```
81
84
 
82
- In this comment example, when a new `LinkHasHrefCounter` offense has been added, the counter will need to be bumped up to 2. More recent rules use a `Counter` format.
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.
83
86
 
84
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.
85
88
 
@@ -6,6 +6,8 @@ require "openssl"
6
6
  module ERBLint
7
7
  module Linters
8
8
  module CustomHelpers
9
+ INTERACTIVE_ELEMENTS = %w[button summary input select textarea a].freeze
10
+
9
11
  def rule_disabled?(processed_source)
10
12
  processed_source.parser.ast.descendants(:erb).each do |node|
11
13
  indicator_node, _, code_node, = *node
@@ -89,6 +91,15 @@ module ERBLint
89
91
  def simple_class_name
90
92
  self.class.name.gsub("ERBLint::Linters::", "")
91
93
  end
94
+
95
+ def focusable?(tag)
96
+ tabindex = possible_attribute_values(tag, "tabindex")
97
+ if INTERACTIVE_ELEMENTS.include?(tag.name)
98
+ tabindex.empty? || tabindex.first.to_i >= 0
99
+ else
100
+ tabindex.any? && tabindex.first.to_i >= 0
101
+ end
102
+ end
92
103
  end
93
104
  end
94
105
  end
@@ -6,13 +6,18 @@ module ERBLint
6
6
  module Linters
7
7
  module GitHub
8
8
  module Accessibility
9
- class AvoidBothDisabledAndAriaDisabledCounter < Linter
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
- 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
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 AvoidGenericLinkTextCounter < Linter
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
- counter_correct?(processed_source)
97
- end
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 DisabledAttributeCounter < Linter
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
- 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
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 IframeHasTitleCounter < Linter
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
- counter_correct?(processed_source)
27
- end
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
 
@@ -6,12 +6,17 @@ module ERBLint
6
6
  module Linters
7
7
  module GitHub
8
8
  module Accessibility
9
- class ImageHasAltCounter < Linter
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
- 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
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 LandmarkHasLabelCounter < Linter
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
- counter_correct?(processed_source)
56
- end
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
@@ -6,12 +6,17 @@ module ERBLint
6
6
  module Linters
7
7
  module GitHub
8
8
  module Accessibility
9
- class LinkHasHrefCounter < Linter
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
- 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
30
+ if @config.counter_enabled?
31
+ counter_correct?(processed_source)
39
32
  end
40
33
  end
41
34
  end
@@ -6,13 +6,16 @@ module ERBLint
6
6
  module Linters
7
7
  module GitHub
8
8
  module Accessibility
9
- class NestedInteractiveElementsCounter < Linter
9
+ class NestedInteractiveElements < Linter
10
10
  include ERBLint::Linters::CustomHelpers
11
11
  include LinterRegistry
12
12
 
13
- INTERACTIVE_ELEMENTS = %w[button summary input select textarea a].freeze
14
13
  MESSAGE = "Nesting interactive elements produces invalid HTML, and ssistive technologies, such as screen readers, might ignore or respond unexpectedly to such nested controls."
15
14
 
15
+ class ConfigSchema < LinterConfig
16
+ property :counter_enabled, accepts: [true, false], default: false, reader: :counter_enabled?
17
+ end
18
+ self.config_schema = ConfigSchema
16
19
  def run(processed_source)
17
20
  last_interactive_element = nil
18
21
  tags(processed_source).each do |tag|
@@ -32,20 +35,8 @@ module ERBLint
32
35
  last_interactive_element = tag unless tag&.name == "input"
33
36
  end
34
37
 
35
- counter_correct?(processed_source)
36
- end
37
-
38
- def autocorrect(processed_source, offense)
39
- return unless offense.context
40
-
41
- lambda do |corrector|
42
- if processed_source.file_content.include?("erblint:counter #{simple_class_name}")
43
- # update the counter if exists
44
- corrector.replace(offense.source_range, offense.context)
45
- else
46
- # add comment with counter if none
47
- corrector.insert_before(processed_source.source_buffer.source_range, "#{offense.context}\n")
48
- end
38
+ if @config.counter_enabled?
39
+ counter_correct?(processed_source)
49
40
  end
50
41
  end
51
42
  end
@@ -0,0 +1,34 @@
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 NoAriaHiddenOnFocusable < Linter
10
+ include ERBLint::Linters::CustomHelpers
11
+ include LinterRegistry
12
+
13
+ MESSAGE = "Elements that are focusable should not have `aria-hidden='true' because it will cause confusion for assistive technology users."
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
+
20
+ def run(processed_source)
21
+ tags(processed_source).each do |tag|
22
+ aria_hidden = possible_attribute_values(tag, "aria-hidden")
23
+ generate_offense(self.class, processed_source, tag) if aria_hidden.include?("true") && focusable?(tag)
24
+ end
25
+
26
+ if @config.counter_enabled?
27
+ counter_correct?(processed_source)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -6,7 +6,7 @@ module ERBLint
6
6
  module Linters
7
7
  module GitHub
8
8
  module Accessibility
9
- class NoAriaLabelMisuseCounter < Linter
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
- counter_correct?(processed_source)
38
- end
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 NoPositiveTabIndexCounter < Linter
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
- counter_correct?(processed_source)
24
- end
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 NoRedundantImageAltCounter < Linter
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
- counter_correct?(processed_source)
28
- end
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 NoTitleAttributeCounter < Linter
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
- counter_correct?(processed_source)
25
- end
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 SvgHasAccessibleTextCounter < Linter
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
- 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
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.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitHub Open Source
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-09-05 00:00:00.000000000 Z
11
+ date: 2023-04-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: erb_lint
@@ -16,42 +16,42 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.1.1
19
+ version: 0.3.0
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.1.1
26
+ version: 0.3.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: minitest
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '5.15'
33
+ version: 5.17.0
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '5.15'
40
+ version: 5.17.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: mocha
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '1.14'
47
+ version: 2.0.2
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '1.14'
54
+ version: 2.0.2
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rake
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -72,28 +72,28 @@ dependencies:
72
72
  requirements:
73
73
  - - '='
74
74
  - !ruby/object:Gem::Version
75
- version: 1.30.0
75
+ version: 1.44.1
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - '='
81
81
  - !ruby/object:Gem::Version
82
- version: 1.30.0
82
+ version: 1.44.1
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rubocop-github
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: 0.17.0
89
+ version: 0.20.0
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: 0.17.0
96
+ version: 0.20.0
97
97
  description: Template style checking for GitHub Ruby repositories
98
98
  email:
99
99
  - opensource+erblint-github@github.com
@@ -105,19 +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/avoid_both_disabled_and_aria_disabled_counter.rb
109
- - lib/erblint-github/linters/github/accessibility/avoid_generic_link_text_counter.rb
110
- - lib/erblint-github/linters/github/accessibility/disabled_attribute_counter.rb
111
- - lib/erblint-github/linters/github/accessibility/iframe_has_title_counter.rb
112
- - lib/erblint-github/linters/github/accessibility/image_has_alt_counter.rb
113
- - lib/erblint-github/linters/github/accessibility/landmark_has_label_counter.rb
114
- - lib/erblint-github/linters/github/accessibility/link_has_href_counter.rb
115
- - lib/erblint-github/linters/github/accessibility/nested_interactive_elements_counter.rb
116
- - lib/erblint-github/linters/github/accessibility/no_aria_label_misuse_counter.rb
117
- - lib/erblint-github/linters/github/accessibility/no_positive_tab_index_counter.rb
118
- - lib/erblint-github/linters/github/accessibility/no_redundant_image_alt_counter.rb
119
- - lib/erblint-github/linters/github/accessibility/no_title_attribute_counter.rb
120
- - lib/erblint-github/linters/github/accessibility/svg_has_accessible_text_counter.rb
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
121
122
  - lib/tasks/docs.rake
122
123
  - lib/tasks/tests.rake
123
124
  homepage: https://github.com/github/erblint-github
@@ -125,7 +126,7 @@ licenses:
125
126
  - MIT
126
127
  metadata:
127
128
  rubygems_mfa_required: 'true'
128
- post_install_message:
129
+ post_install_message:
129
130
  rdoc_options: []
130
131
  require_paths:
131
132
  - lib
@@ -133,15 +134,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
133
134
  requirements:
134
135
  - - ">="
135
136
  - !ruby/object:Gem::Version
136
- version: 2.6.0
137
+ version: 2.7.0
137
138
  required_rubygems_version: !ruby/object:Gem::Requirement
138
139
  requirements:
139
140
  - - ">="
140
141
  - !ruby/object:Gem::Version
141
142
  version: '0'
142
143
  requirements: []
143
- rubygems_version: 3.3.10
144
- signing_key:
144
+ rubygems_version: 3.3.7
145
+ signing_key:
145
146
  specification_version: 4
146
147
  summary: erblint GitHub
147
148
  test_files: []