a11y-lint 0.2.0 → 0.3.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e12c6c589719fa574aecc86ff23ba8f3c2f9b3ae7f5d4da88bae60bbd3035735
4
- data.tar.gz: c107e0d511e57a1cbbbb61ec62a28d3f704bb11e3dbea32851000146f3053a4c
3
+ metadata.gz: c669543def8cb0173342e7399bebd99e9b51ae325e9a81323c3ee3cffe16b3b5
4
+ data.tar.gz: 9e1822681da394ecc9246998a403f05bb09d928303c4282185600f02a6688fa5
5
5
  SHA512:
6
- metadata.gz: 81a64d2d5a348f5341636124859d31a61f65d6e4fce0d4712bafae17092d7749d5b629aa7f2a7e4269bc54f6e5ce3ff4cbf60225b1ccbcf7f44375104eaa773c
7
- data.tar.gz: bda106347b59bb146e5acc02937eae5d54c0649833c86e86982f6759b128c5fc7b8885b632ee00d6d0848c3746d8d7eb5e4a041b74e1916cc39e6921a57d3ab3
6
+ metadata.gz: 337c2cb2bbd729cc2f8fa14889cdb48aedbb83a0d755ecd294667a977a91055ad09f26ca14f180c56dbfdf67f158a40a81ef962b79dfcab4bf5df3e496bcf611
7
+ data.tar.gz: c5a9ba84ff944b7750e2ac6d90d9d5ebfb5b460317d4b400f93869ff87e9a636ba6efdbd1c11357cc3e3c85fad1a25adc9b30ce8f00b910c4fc5710ec4526947
data/CHANGELOG.md CHANGED
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.3.0] - 2026-03-27
11
+
12
+ ### Added
13
+
14
+ - `ImageTagMissingAlt` rule: detects `image_tag` calls without an `alt` option
15
+
10
16
  ## [0.2.0] - 2026-03-27
11
17
 
12
18
  ### Added
@@ -15,6 +15,12 @@ module A11y
15
15
  @sexp[2]
16
16
  end
17
17
 
18
+ def ruby_code
19
+ return unless @sexp[0] == :slim && @sexp[1] == :output
20
+
21
+ @sexp[3]
22
+ end
23
+
18
24
  def attribute?(name)
19
25
  attributes.key?(name)
20
26
  end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "ripper"
4
+
5
+ module A11y
6
+ module Lint
7
+ module Rules
8
+ # Checks that image_tag calls include an alt option (WCAG 1.1.1).
9
+ class ImageTagMissingAlt < Rule
10
+ def check(node)
11
+ return unless an_image_tag_without_an_alt_attribute?(node)
12
+
13
+ "image_tag is missing an alt option (WCAG 1.1.1)"
14
+ end
15
+
16
+ private
17
+
18
+ def an_image_tag_without_an_alt_attribute?(node)
19
+ code = node.ruby_code
20
+ return false unless code
21
+
22
+ sexp = Ripper.sexp(code)
23
+ return false unless sexp
24
+
25
+ call = extract_image_tag_call(sexp)
26
+ call && !alt_key_within?(call)
27
+ end
28
+
29
+ def extract_image_tag_call(sexp)
30
+ statement = sexp.dig(1, 0)
31
+ return unless statement.is_a?(Array)
32
+
33
+ case statement
34
+ in [:command, [:@ident, "image_tag", *], *]
35
+ statement
36
+ in [:method_add_arg, [:fcall, [:@ident, "image_tag", *]], *]
37
+ statement
38
+ else
39
+ nil
40
+ end
41
+ end
42
+
43
+ def alt_key_within?(sexp)
44
+ return true if alt_key?(sexp)
45
+ return false unless sexp.is_a?(Array)
46
+
47
+ sexp.any? { |child| alt_key_within?(child) }
48
+ end
49
+
50
+ def alt_key?(sexp)
51
+ return false unless sexp.is_a?(Array) && sexp[0] == :assoc_new
52
+
53
+ key = sexp[1]
54
+ (key in [:@label, "alt:", *]) ||
55
+ (key in [:string_literal, [:string_content, [:@tstring_content, "alt", *]]])
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -26,7 +26,7 @@ module A11y
26
26
 
27
27
  @line += 1 if sexp[0] == :newline
28
28
  new_node = Node.new(sexp, line: @line)
29
- check_node(new_node) if html_tag?(sexp)
29
+ check_node(new_node) if html_tag?(sexp) || slim_output?(sexp)
30
30
  sexp.each { |child| walk(child) }
31
31
  end
32
32
 
@@ -34,6 +34,10 @@ module A11y
34
34
  sexp[0] == :html && sexp[1] == :tag
35
35
  end
36
36
 
37
+ def slim_output?(sexp)
38
+ sexp[0] == :slim && sexp[1] == :output
39
+ end
40
+
37
41
  def node?(sexp)
38
42
  sexp.is_a?(Array) && !sexp.empty? && sexp[0].is_a?(Symbol)
39
43
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module A11y
4
4
  module Lint
5
- VERSION = "0.2.0"
5
+ VERSION = "0.3.0"
6
6
  end
7
7
  end
data/lib/a11y/lint.rb CHANGED
@@ -5,6 +5,7 @@ require_relative "lint/version"
5
5
  require_relative "lint/offense"
6
6
  require_relative "lint/node"
7
7
  require_relative "lint/rule"
8
+ require_relative "lint/rules/image_tag_missing_alt"
8
9
  require_relative "lint/rules/img_missing_alt"
9
10
  require_relative "lint/runner"
10
11
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: a11y-lint
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Abdullah Hashim
@@ -45,6 +45,7 @@ files:
45
45
  - lib/a11y/lint/node.rb
46
46
  - lib/a11y/lint/offense.rb
47
47
  - lib/a11y/lint/rule.rb
48
+ - lib/a11y/lint/rules/image_tag_missing_alt.rb
48
49
  - lib/a11y/lint/rules/img_missing_alt.rb
49
50
  - lib/a11y/lint/runner.rb
50
51
  - lib/a11y/lint/version.rb