Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ require "erblint-github/linters"
linters:
GitHub::Accessibility::AvoidBothDisabledAndAriaDisabled:
enabled: true
GitHub::Accessibility::IframeHasTitle:
enabled: true
GitHub::Accessibility::ImageHasAlt:
enabled: true
GitHub::Accessibility::NoAriaLabelMisuse:
Expand All @@ -36,6 +38,7 @@ linters:
## Rules

- [GitHub::Accessibility::AvoidBothDisabledAndAriaDisabled](./docs/rules/accessibility/avoid-both-disabled-and-aria-disabled.md)
- [GitHub::Accessibility::IframeHasTitle](./docs/rules/accessibility/iframe-has-title.md)
- [GitHub::Accessibility::ImageHasAlt](./docs/rules/accessibility/image-has-alt.md)
- [GitHub::Accessibility::NoAriaLabelMisuse](./docs/rules/accessibility/no-aria-label-misuse.md)
- [GitHub::Accessibility::NoRedundantImageAlt](./docs/rules/accessibility/no-redundant-image-alt.md)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ HTML elements with `disabled` are ignored when a screen reader uses tab navigati

This linter will raise when both `aria-disabled` and `disabled` are set on HTML elements that natively support `disabled` including `button`, `fieldset`, `input`, `optgroup`, `option`, `select`, and `textarea`.

👎 Examples of **incorrect** code for this rule:
### 👎 Examples of **incorrect** code for this rule:

```erb
<button aria-disabled="true" disabled="true">
<input aria-disabled="true" disabled="true">
```

👍 Examples of **correct** code for this rule:
### 👍 Examples of **correct** code for this rule:

```erb
<button disabled="true">
Expand Down
25 changes: 25 additions & 0 deletions docs/rules/accessibility/iframe-has-title.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Iframe has title

## Rule Details

`<iframe>` should have a unique title attribute that identifies the content. The title will help screen reader users determine whether to explore the frame in detail. If an `<iframe>` contains no meaningful content, hide it by setting `aria-hidden="true"`.

### 👎 Examples of **incorrect** code for this rule:

```erb
<iframe src="../welcome-video"></iframe>
```

### 👍 Examples of **correct** code for this rule:

```erb
<!-- good -->
<iframe src="../welcome-video" title="Welcome to GitHub Video" ></iframe>
```

```erb
<!-- also good -->
<iframe aria-hidden="true">
<!-- Meaningless JavaScript code -->
</iframe>
```
4 changes: 2 additions & 2 deletions docs/rules/accessibility/image-has-alt.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@

Learn more at [W3C WAI Images Tutorial](https://www.w3.org/WAI/tutorials/images/).

👎 Examples of **incorrect** code for this rule:
### 👎 Examples of **incorrect** code for this rule:

```erb
<img src="logo.png">
```

👍 Examples of **correct** code for this rule:
### 👍 Examples of **correct** code for this rule:

```erb
<!-- good -->
Expand Down
4 changes: 2 additions & 2 deletions docs/rules/accessibility/no-aria-label-misuse.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Also check out the following resources:
- [w3c/aria Consider prohibiting author naming certain roles #833](https://github.com/w3c/aria/issues/833)
- [Not so short note on aria-label usage - Big Table Edition](https://html5accessibility.com/stuff/2020/11/07/not-so-short-note-on-aria-label-usage-big-table-edition/)

👎 Examples of **incorrect** code for this rule:
### 👎 Examples of **incorrect** code for this rule:

```erb
<span aria-label="This does something">Hello</span>
Expand All @@ -26,7 +26,7 @@ Also check out the following resources:
<h1 aria-label="This will override the content">Page title</h1>
```

👍 Examples of **correct** code for this rule:
### 👍 Examples of **correct** code for this rule:

```erb
<span>Hello</span>
Expand Down
4 changes: 2 additions & 2 deletions docs/rules/accessibility/no-redundant-image-alt.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@

Learn more at [W3C WAI Images Tutorial](https://www.w3.org/WAI/tutorials/images/).

👎 Examples of **incorrect** code for this rule:
### 👎 Examples of **incorrect** code for this rule:

```erb
<img alt="picture of Mona Lisa" src="monalisa.png">
```

👍 Examples of **correct** code for this rule:
### 👍 Examples of **correct** code for this rule:

```erb
<!-- good -->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# frozen_string_literal: true

require_relative "../../custom_helpers"

module ERBLint
module Linters
module GitHub
module Accessibility
class IframeHasTitle < Linter
include ERBLint::Linters::CustomHelpers
include LinterRegistry

MESSAGE = "<iframe> with meaningful content should have a title attribute that identifies the content."\
" If <iframe> has no meaningful content, hide it from assistive technology with `aria-hidden='true'`."\

def run(processed_source)
tags(processed_source).each do |tag|
next if tag.name != "iframe"
next if tag.closing?

title = possible_attribute_values(tag, "title")

generate_offense(self.class, processed_source, tag) if title.empty? && !aria_hidden?(tag)
end

rule_disabled?(processed_source)
end

private

def aria_hidden?(tag)
tag.attributes["aria-hidden"]&.value&.present?
end
end
end
end
end
end
30 changes: 30 additions & 0 deletions test/linters/accessibility/iframe_has_title_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# frozen_string_literal: true

require "test_helper"

class IframeHasTitle < LinterTestCase
def linter_class
ERBLint::Linters::GitHub::Accessibility::IframeHasTitle
end

def test_warns_if_iframe_has_no_title
@file = "<iframe alt='image of an octopus'></iframe>"
@linter.run(processed_source)

refute_empty @linter.offenses
end

def test_does_not_warn_if_iframe_has_aria_hidden_to_true
@file = "<iframe aria-hidden='true'></iframe>"
@linter.run(processed_source)

assert_empty @linter.offenses
end

def test_does_not_warn_if_iframe_has_title_set_to_string
@file = "<iframe title='Video tutorial of GitHub Actions'></iframe>"
@linter.run(processed_source)

assert_empty @linter.offenses
end
end