erblint-github 0.2.1 → 0.3.1
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/README.md +5 -2
- data/lib/erblint-github/linters/custom_helpers.rb +1 -1
- data/lib/erblint-github/linters/github/accessibility/aria_label_is_well_formatted.rb +36 -0
- data/lib/erblint-github/linters/github/accessibility/navigation_has_label.rb +33 -0
- metadata +8 -7
- data/lib/erblint-github/linters/github/accessibility/landmark_has_label.rb +0 -68
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 625ce68b5e4d109bc1ddc27921ba6fc52d0d27fab2b23b9ebed9f0af92d1a523
|
4
|
+
data.tar.gz: '08302ed91e755eea56d05d7d1fb7d30403929f7cb943e7042b0ae43ecfb137f6'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 15b5b10a2edd73c90f01a3e803dceee6f2afccf38c2810b4e70327f5b88ffa6d0d0ee4570e5aa190fa6483fcd3d0ee34924b391b4e390ccba2b4ca86319493e4
|
7
|
+
data.tar.gz: 50d4c0c8f6059ed88b66b08d6c4ccbe6e795087ffee0bc5a3fc45327ddacc750178317c355a8e742f0aa2f0d4024b3ce19c00bc9e5eed4408ef20470211f387b
|
data/README.md
CHANGED
@@ -23,6 +23,8 @@ require "erblint-github/linters"
|
|
23
23
|
```yaml
|
24
24
|
---
|
25
25
|
linters:
|
26
|
+
GitHub::Accessibility::AriaLabelIsWellFormatted:
|
27
|
+
enabled: true
|
26
28
|
GitHub::Accessibility::AvoidBothDisabledAndAriaDisabled:
|
27
29
|
enabled: true
|
28
30
|
GitHub::Accessibility::AvoidGenericLinkText:
|
@@ -33,7 +35,7 @@ linters:
|
|
33
35
|
enabled: true
|
34
36
|
GitHub::Accessibility::ImageHasAlt:
|
35
37
|
enabled: true
|
36
|
-
GitHub::Accessibility::
|
38
|
+
GitHub::Accessibility::NavigationHasLabel:
|
37
39
|
enabled: true
|
38
40
|
GitHub::Accessibility::LinkHasHref:
|
39
41
|
enabled: true
|
@@ -55,10 +57,11 @@ linters:
|
|
55
57
|
|
56
58
|
## Rules
|
57
59
|
|
60
|
+
- [GitHub::Accessibility::AriaLabelIsWellFormatted](./docs/rules/accessibility/aria-label-is-well-formatted.md)
|
58
61
|
- [GitHub::Accessibility::AvoidBothDisabledAndAriaDisabled](./docs/rules/accessibility/avoid-both-disabled-and-aria-disabled.md)
|
59
62
|
- [GitHub::Accessibility::AvoidGenericLinkText](./docs/rules/accessibility/avoid-generic-link-text.md)
|
60
63
|
- [GitHub::Accessibility::DisabledAttribute](./docs/rules/accessibility/disabled-attribute.md)
|
61
|
-
- [GitHub::Accessibility::
|
64
|
+
- [GitHub::Accessibility::NavigationHasLabel](./docs/rules/accessibility/navigation-has-label.md)
|
62
65
|
- [GitHub::Accessibility::LinkHasHref](./docs/rules/accessibility/link-has-href.md)
|
63
66
|
- [GitHub::Accessibility::NestedInteractiveElements](./docs/rules/accessibility/nested-interactive-elements.md)
|
64
67
|
- [GitHub::Accessibility::IframeHasTitle](./docs/rules/accessibility/iframe-has-title.md)
|
@@ -0,0 +1,36 @@
|
|
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 AriaLabelIsWellFormatted < Linter
|
10
|
+
include ERBLint::Linters::CustomHelpers
|
11
|
+
include LinterRegistry
|
12
|
+
|
13
|
+
MESSAGE = "[aria-label] text should be formatted the same as you would visual text. Use sentence case, and don't format it like an ID. Additionally, `aria-label` should be concise and should not contain line breaks."
|
14
|
+
|
15
|
+
class ConfigSchema < LinterConfig
|
16
|
+
property :exceptions, accepts: array_of?(String),
|
17
|
+
default: -> { [] }
|
18
|
+
end
|
19
|
+
self.config_schema = ConfigSchema
|
20
|
+
|
21
|
+
def run(processed_source)
|
22
|
+
tags(processed_source).each do |tag|
|
23
|
+
next if tag.closing?
|
24
|
+
|
25
|
+
aria_label = possible_attribute_values(tag, "aria-label").join
|
26
|
+
|
27
|
+
if (aria_label.start_with?(/^[a-z]/) || aria_label.match?(/[\r\n]+/)) && !@config.exceptions.include?(aria_label)
|
28
|
+
generate_offense(self.class, processed_source, tag)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,33 @@
|
|
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 NavigationHasLabel < Linter
|
10
|
+
include ERBLint::Linters::CustomHelpers
|
11
|
+
include LinterRegistry
|
12
|
+
|
13
|
+
MESSAGE = "The navigation landmark should have a unique accessible name via `aria-label` or `aria-labelledby`. Remember that the name does not need to include `navigation` or `nav` since it will already be announced."
|
14
|
+
|
15
|
+
def run(processed_source)
|
16
|
+
tags(processed_source).each do |tag|
|
17
|
+
next if tag.closing?
|
18
|
+
next unless possible_attribute_values(tag, "role").include?("navigation") || tag.name == "nav"
|
19
|
+
if possible_attribute_values(tag, "aria-label").empty? && possible_attribute_values(tag, "aria-labelledby").empty?
|
20
|
+
message = MESSAGE
|
21
|
+
if tag.name != "nav"
|
22
|
+
message += "Additionally, you can safely drop the `role='navigation'` and replace it with the native HTML `nav` element."
|
23
|
+
end
|
24
|
+
generate_offense(self.class, processed_source, tag, message)
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
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.
|
4
|
+
version: 0.3.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-04-
|
11
|
+
date: 2023-04-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: erb_lint
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 5.
|
33
|
+
version: 5.18.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.
|
40
|
+
version: 5.18.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: mocha
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -72,14 +72,14 @@ dependencies:
|
|
72
72
|
requirements:
|
73
73
|
- - '='
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: 1.
|
75
|
+
version: 1.49.0
|
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.
|
82
|
+
version: 1.49.0
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: rubocop-github
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -105,13 +105,14 @@ 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/aria_label_is_well_formatted.rb
|
108
109
|
- lib/erblint-github/linters/github/accessibility/avoid_both_disabled_and_aria_disabled.rb
|
109
110
|
- lib/erblint-github/linters/github/accessibility/avoid_generic_link_text.rb
|
110
111
|
- lib/erblint-github/linters/github/accessibility/disabled_attribute.rb
|
111
112
|
- lib/erblint-github/linters/github/accessibility/iframe_has_title.rb
|
112
113
|
- lib/erblint-github/linters/github/accessibility/image_has_alt.rb
|
113
|
-
- lib/erblint-github/linters/github/accessibility/landmark_has_label.rb
|
114
114
|
- lib/erblint-github/linters/github/accessibility/link_has_href.rb
|
115
|
+
- lib/erblint-github/linters/github/accessibility/navigation_has_label.rb
|
115
116
|
- lib/erblint-github/linters/github/accessibility/nested_interactive_elements.rb
|
116
117
|
- lib/erblint-github/linters/github/accessibility/no_aria_hidden_on_focusable.rb
|
117
118
|
- lib/erblint-github/linters/github/accessibility/no_aria_label_misuse.rb
|
@@ -1,68 +0,0 @@
|
|
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 LandmarkHasLabel < Linter
|
10
|
-
include ERBLint::Linters::CustomHelpers
|
11
|
-
include LinterRegistry
|
12
|
-
|
13
|
-
LANDMARK_ROLES = %w[complementary navigation region search].freeze
|
14
|
-
LANDMARK_TAGS = %w[aside nav section].freeze
|
15
|
-
MESSAGE = "Landmark elements should have an aria-label attribute, or aria-labelledby if a heading elements exists in the landmark."
|
16
|
-
ROLE_TAG_MAPPING = { "complementary" => "aside", "navigation" => "nav", "region" => "section" }.freeze
|
17
|
-
|
18
|
-
def get_additional_message(tag, roles)
|
19
|
-
role_matched = (roles & ROLE_TAG_MAPPING.keys).first
|
20
|
-
if role_matched
|
21
|
-
tag_matched = ROLE_TAG_MAPPING[role_matched]
|
22
|
-
|
23
|
-
if tag.name == tag_matched
|
24
|
-
"The <#{tag_matched}> element will automatically communicate a role of '#{role_matched}'. You can safely drop the role attribute."
|
25
|
-
else
|
26
|
-
replace_message = if tag.name == "div"
|
27
|
-
"If possible replace this tag with a <#{tag_matched}>."
|
28
|
-
else
|
29
|
-
"Wrapping this element in a <#{tag_matched}> and setting a label on it is reccomended."
|
30
|
-
end
|
31
|
-
|
32
|
-
"The <#{tag_matched}> element will automatically communicate a role of '#{role_matched}'. #{replace_message}"
|
33
|
-
end
|
34
|
-
elsif roles.include?("search") && tag.name != "form"
|
35
|
-
"The 'search' role works best when applied to a <form> element. If possible replace this tag with a <form>."
|
36
|
-
end
|
37
|
-
end
|
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
|
-
|
44
|
-
def run(processed_source)
|
45
|
-
tags(processed_source).each do |tag|
|
46
|
-
next if tag.closing?
|
47
|
-
|
48
|
-
possible_roles = possible_attribute_values(tag, "role")
|
49
|
-
next unless LANDMARK_TAGS.include?(tag.name) && (possible_roles & LANDMARK_ROLES).empty?
|
50
|
-
next if tag.attributes["aria-label"]&.value&.present? || tag.attributes["aria-labelledby"]&.value&.present?
|
51
|
-
|
52
|
-
message = get_additional_message(tag, possible_roles)
|
53
|
-
if message
|
54
|
-
generate_offense(self.class, processed_source, tag, "#{MESSAGE}\n#{message}")
|
55
|
-
else
|
56
|
-
generate_offense(self.class, processed_source, tag)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
if @config.counter_enabled?
|
61
|
-
counter_correct?(processed_source)
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|