Skip to content
Closed
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
2 changes: 1 addition & 1 deletion docs/docs/blog/whats-new-in-herb-v0-8.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ This release brings a total of 14 new linter rules to help you write better HTML
- [`html-head-only-elements`](/linter/rules/html-head-only-elements.md) <br/>
Require head-scoped elements inside `<head>`.

- [`html-input-require-autocomplete`](/linter/rules/html-input-require-autocomplete.md) <br/>
- [`html-input-require-autocomplete`](/linter/rules/a11y-input-require-autocomplete.md) <br/>
Require `autocomplete` attributes on `<input>` tags.

- [`html-no-duplicate-meta-names`](/linter/rules/html-no-duplicate-meta-names.md) <br/>
Expand Down
4 changes: 2 additions & 2 deletions docs/docs/blog/whats-new-in-herb-v0-9.md
Original file line number Diff line number Diff line change
Expand Up @@ -441,8 +441,8 @@ This release also introduces two new rule categories: **`erb-safety-*`** rules e

- [`html-allowed-script-type`](/linter/rules/html-allowed-script-type.md)<br/>Restrict allowed `type` attributes on `<script>` tags
- [`html-details-has-summary`](/linter/rules/html-details-has-summary.md)<br/>Require `<summary>` inside `<details>` elements
- [`html-no-abstract-roles`](/linter/rules/html-no-abstract-roles.md)<br/>Disallow abstract ARIA roles
- [`html-no-aria-hidden-on-body`](/linter/rules/html-no-aria-hidden-on-body.md)<br/>Disallow `aria-hidden` on `<body>`
- [`html-no-abstract-roles`](/linter/rules/a11y-no-abstract-roles.md)<br/>Disallow abstract ARIA roles
- [`html-no-aria-hidden-on-body`](/linter/rules/a11y-no-aria-hidden-on-body.md)<br/>Disallow `aria-hidden` on `<body>`
- [`html-require-closing-tags`](/linter/rules/html-require-closing-tags.md)<br/>Require explicit closing tags

##### Turbo Rules
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ linter:
severity: warning # Options: error, warning, info, hint

# Rule with file pattern restrictions
html-img-require-alt:
a11y-img-require-alt:
# Only apply this rule to files matching these patterns
only:
- 'app/views/**/*'
Expand Down
2 changes: 1 addition & 1 deletion javascript/packages/config/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -633,7 +633,7 @@ export class Config {
* await Config.mutateConfigFile('/path/to/.herb.yml', {
* linter: {
* rules: {
* 'html-img-require-alt': { enabled: false }
* 'a11y-img-require-alt': { enabled: false }
* }
* }
* })
Expand Down
4 changes: 2 additions & 2 deletions javascript/packages/config/test/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ describe("@herb-tools/config", () => {
version: 0.9.2
linter:
rules:
html-img-require-alt:
a11y-img-require-alt:
enabled: false
`

Expand All @@ -231,7 +231,7 @@ describe("@herb-tools/config", () => {

const updatedYaml = Config.applyMutationToYamlString(existingYaml, mutation)

expect(updatedYaml).toContain("html-img-require-alt:")
expect(updatedYaml).toContain("a11y-img-require-alt:")
expect(updatedYaml).toContain("html-tag-name-lowercase:")
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ describe("herb:disable comment formatting", () => {

test("keeps herb:disable comment on same line as tag name in multiline opening tag", () => {
expectFormattedToMatch(dedent`
<a <%# herb:disable html-anchor-require-href %>
<a <%# herb:disable a11y-anchor-require-href %>
class="btn btn-secondary no-donate-btn"
aria-label="Close"
data-dismiss="modal"
Expand Down
10 changes: 5 additions & 5 deletions javascript/packages/linter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -267,9 +267,9 @@ npx @herb-tools/linter --format=simple --github

**Example: `--github` (GitHub annotations + detailed format)**
```
::error file=template.html.erb,line=3,col=3,title=html-img-require-alt • @herb-tools/linter@0.9.2::Missing required `alt` attribute on `<img>` tag [html-img-require-alt]%0A%0A%0Atemplate.html.erb:3:3%0A%0A 1 │ <div>%0A 2 │ <span>Test content</span>%0A → 3 │ <img src="test.jpg">%0A │ ~~~%0A 4 │ </div>%0A
::error file=template.html.erb,line=3,col=3,title=a11y-img-require-alt • @herb-tools/linter@0.9.2::Missing required `alt` attribute on `<img>` tag [a11y-img-require-alt]%0A%0A%0Atemplate.html.erb:3:3%0A%0A 1 │ <div>%0A 2 │ <span>Test content</span>%0A → 3 │ <img src="test.jpg">%0A │ ~~~%0A 4 │ </div>%0A

[error] Missing required `alt` attribute on `<img>` tag [html-img-require-alt]
[error] Missing required `alt` attribute on `<img>` tag [a11y-img-require-alt]

template.html.erb:3:3

Expand All @@ -282,10 +282,10 @@ template.html.erb:3:3

**Example: `--format=simple --github` (GitHub annotations + simple format)**
```
::error file=template.html.erb,line=3,col=3,title=html-img-require-alt • @herb-tools/linter@0.9.2::Missing required `alt` attribute on `<img>` tag [html-img-require-alt]%0A%0A%0Atemplate.html.erb:3:3%0A%0A 1 │ <div>%0A 2 │ <span>Test content</span>%0A → 3 │ <img src="test.jpg">%0A │ ~~~%0A 4 │ </div>%0A
::error file=template.html.erb,line=3,col=3,title=a11y-img-require-alt • @herb-tools/linter@0.9.2::Missing required `alt` attribute on `<img>` tag [a11y-img-require-alt]%0A%0A%0Atemplate.html.erb:3:3%0A%0A 1 │ <div>%0A 2 │ <span>Test content</span>%0A → 3 │ <img src="test.jpg">%0A │ ~~~%0A 4 │ </div>%0A

template.html.erb:
3:3 ✗ Missing required `alt` attribute on `<img>` tag [html-img-require-alt]
3:3 ✗ Missing required `alt` attribute on `<img>` tag [a11y-img-require-alt]
```

The GitHub Actions annotations include:
Expand Down Expand Up @@ -472,7 +472,7 @@ Apply rules to specific files using `include`, `only`, and `exclude` patterns:
linter:
rules:
# Apply rule only to component files
html-img-require-alt:
a11y-img-require-alt:
include:
- 'app/components/**/*'
exclude:
Expand Down
36 changes: 19 additions & 17 deletions javascript/packages/linter/docs/rules/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,24 @@ This page contains documentation for all Herb Linter rules.

## Available Rules

- [`a11y-anchor-require-href`](./a11y-anchor-require-href.md) - Requires an href attribute on anchor tags
- [`a11y-aria-attribute-must-be-valid`](./a11y-aria-attribute-must-be-valid.md) - Disallow invalid or unknown `aria-*` attributes.
- [`a11y-aria-label-is-well-formatted`](./a11y-aria-label-is-well-formatted.md) - `aria-label` must be well-formatted
- [`a11y-aria-level-must-be-valid`](./a11y-aria-level-must-be-valid.md) - `aria-level` must be between 1 and 6
- [`a11y-aria-role-heading-requires-level`](./a11y-aria-role-heading-requires-level.md) - Requires `aria-level` when supplying a `role`
- [`a11y-aria-role-must-be-valid`](./a11y-aria-role-must-be-valid.md) - The `role` attribute must have a valid WAI-ARIA Role.
- [`a11y-avoid-both-disabled-and-aria-disabled`](./a11y-avoid-both-disabled-and-aria-disabled.md) - Avoid using both `disabled` and `aria-disabled` attributes
- [`a11y-iframe-has-title`](./a11y-iframe-has-title.md) - `iframe` elements must have a `title` attribute
- [`a11y-img-require-alt`](./a11y-img-require-alt.md) - Requires `alt` attributes on `<img>` tags
- [`a11y-input-require-autocomplete`](./a11y-input-require-autocomplete.md) - Require `autocomplete` attributes on `<input>` tags.
- [`a11y-navigation-has-label`](./a11y-navigation-has-label.md) - Navigation landmarks must have accessible labels
- [`a11y-no-abstract-roles`](./a11y-no-abstract-roles.md) - No abstract ARIA roles
- [`a11y-no-aria-hidden-on-body`](./a11y-no-aria-hidden-on-body.md) - No `aria-hidden` on `<body>`
- [`a11y-no-aria-hidden-on-focusable`](./a11y-no-aria-hidden-on-focusable.md) - Focusable elements should not have `aria-hidden="true"`
- [`a11y-no-empty-headings`](./a11y-no-empty-headings.md) - Headings must not be empty
- [`a11y-no-nested-links`](./a11y-no-nested-links.md) - Prevents nested anchor tags
- [`a11y-no-positive-tab-index`](./a11y-no-positive-tab-index.md) - Avoid positive `tabindex` values
- [`a11y-no-title-attribute`](./a11y-no-title-attribute.md) - Avoid using the `title` attribute
- [`actionview-no-silent-helper`](./actionview-no-silent-helper.md) - Disallow silent ERB tags for Action View helpers
- [`actionview-no-silent-render`](./actionview-no-silent-render.md) - Disallow calling `render` without outputting the result
- [`actionview-no-void-element-content`](./actionview-no-void-element-content.md) - Disallow content arguments for void Action View elements
Expand Down Expand Up @@ -43,38 +61,22 @@ This page contains documentation for all Herb Linter rules.
- [`herb-disable-comment-unnecessary`](./herb-disable-comment-unnecessary.md) - Detect unnecessary `herb:disable` comments.
- [`herb-disable-comment-valid-rule-name`](./herb-disable-comment-valid-rule-name.md) - Validate rule names in `herb:disable` comments.
- [`html-allowed-script-type`](./html-allowed-script-type.md) - Restrict allowed `type` attributes for `<script>` tags
- [`html-anchor-require-href`](./html-anchor-require-href.md) - Requires an href attribute on anchor tags
- [`html-aria-attribute-must-be-valid`](./html-aria-attribute-must-be-valid.md) - Disallow invalid or unknown `aria-*` attributes.
- [`html-aria-label-is-well-formatted`](./html-aria-label-is-well-formatted.md) - `aria-label` must be well-formatted
- [`html-aria-level-must-be-valid`](./html-aria-level-must-be-valid.md) - `aria-level` must be between 1 and 6
- [`html-aria-role-heading-requires-level`](./html-aria-role-heading-requires-level.md) - Requires `aria-level` when supplying a `role`
- [`html-aria-role-must-be-valid`](./html-aria-role-must-be-valid.md) - The `role` attribute must have a valid WAI-ARIA Role.
- [`html-attribute-double-quotes`](./html-attribute-double-quotes.md) - Enforces double quotes for attribute values
- [`html-attribute-equals-spacing`](./html-attribute-equals-spacing.md) - No whitespace around `=` in HTML attributes
- [`html-attribute-values-require-quotes`](./html-attribute-values-require-quotes.md) - Requires quotes around attribute values
- [`html-avoid-both-disabled-and-aria-disabled`](./html-avoid-both-disabled-and-aria-disabled.md) - Avoid using both `disabled` and `aria-disabled` attributes
- [`html-body-only-elements`](./html-body-only-elements.md) - Require content elements inside `<body>`.
- [`html-boolean-attributes-no-value`](./html-boolean-attributes-no-value.md) - Prevents values on boolean attributes
- [`html-details-has-summary`](./html-details-has-summary.md) - Require `<summary>` in `<details>` elements
- [`html-head-only-elements`](./html-head-only-elements.md) - Require head-scoped elements inside `<head>`.
- [`html-iframe-has-title`](./html-iframe-has-title.md) - `iframe` elements must have a `title` attribute
- [`html-img-require-alt`](./html-img-require-alt.md) - Requires `alt` attributes on `<img>` tags
- [`html-input-require-autocomplete`](./html-input-require-autocomplete.md) - Require `autocomplete` attributes on `<input>` tags.
- [`html-navigation-has-label`](./html-navigation-has-label.md) - Navigation landmarks must have accessible labels
- [`html-no-abstract-roles`](./html-no-abstract-roles.md) - No abstract ARIA roles
- [`html-no-aria-hidden-on-body`](./html-no-aria-hidden-on-body.md) - No `aria-hidden` on `<body>`
- [`html-no-aria-hidden-on-focusable`](./html-no-aria-hidden-on-focusable.md) - Focusable elements should not have `aria-hidden="true"`
- [`html-no-block-inside-inline`](./html-no-block-inside-inline.md) - Prevents block-level elements inside inline elements
- [`html-no-duplicate-attributes`](./html-no-duplicate-attributes.md) - Prevents duplicate attributes on HTML elements
- [`html-no-duplicate-ids`](./html-no-duplicate-ids.md) - Prevents duplicate IDs within a document
- [`html-no-duplicate-meta-names`](./html-no-duplicate-meta-names.md) - Duplicate `<meta>` name attributes are not allowed.
- [`html-no-empty-attributes`](./html-no-empty-attributes.md) - Attributes must not have empty values
- [`html-no-nested-links`](./html-no-nested-links.md) - Prevents nested anchor tags
- [`html-no-positive-tab-index`](./html-no-positive-tab-index.md) - Avoid positive `tabindex` values
- [`html-no-self-closing`](./html-no-self-closing.md) - Disallow self closing tags
- [`html-no-space-in-tag`](./html-no-space-in-tag.md) - Disallow spaces in HTML tags
- [`html-no-title-attribute`](./html-no-title-attribute.md) - Avoid using the `title` attribute
- [`html-no-underscores-in-attribute-names`](./html-no-underscores-in-attribute-names.md) - Disallow underscores in HTML attribute names
- [`html-require-closing-tags`](./html-require-closing-tags.md) - Require closing tags for non-void elements
- [`html-require-script-nonce`](./html-require-script-nonce.md) - Require `nonce` attribute on script tags and helpers
- [`html-tag-name-lowercase`](./html-tag-name-lowercase.md) - Enforces lowercase tag names in HTML
- [`parser-no-errors`](./parser-no-errors.md) - Disallow parser errors in HTML+ERB documents
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Linter Rule: Require `href` attribute on `<a>` tags

**Rule:** `html-anchor-require-href`
**Rule:** `a11y-anchor-require-href`

## Description

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Linter Rule: Disallow invalid or unknown `aria-*` attributes.

**Rule:** `html-aria-attribute-must-be-valid`
**Rule:** `a11y-aria-attribute-must-be-valid`

## Description

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Linter Rule: `aria-label` must be well-formatted

**Rule:** `html-aria-label-is-well-formatted`
**Rule:** `a11y-aria-label-is-well-formatted`

## Description

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Linter Rule: `aria-level` must be between 1 and 6

**Rule:** `html-aria-level-must-be-valid`
**Rule:** `a11y-aria-level-must-be-valid`

## Description

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Linter Rule: ARIA role with heading requires level

**Rule:** `html-aria-role-heading-requires-level`
**Rule:** `a11y-aria-role-heading-requires-level`

## Description

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Linter Rule: Disallow invalid values for the `role` attribute

**Rule:** `html-aria-role-must-be-valid`
**Rule:** `a11y-aria-role-must-be-valid`

## Description

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Linter Rule: Avoid using both `disabled` and `aria-disabled` attributes

**Rule:** `html-avoid-both-disabled-and-aria-disabled`
**Rule:** `a11y-avoid-both-disabled-and-aria-disabled`

## Description

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Linter Rule: `iframe` elements must have a `title` attribute

**Rule:** `html-iframe-has-title`
**Rule:** `a11y-iframe-has-title`

## Description

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Linter Rule: Require `alt` attribute on `<img>` tags

**Rule:** `html-img-require-alt`
**Rule:** `a11y-img-require-alt`

## Description

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Linter Rule: Require `autocomplete` attributes on `<input>` tags

**Rule:** `html-input-require-autocomplete`
**Rule:** `a11y-input-require-autocomplete`

## Description

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Linter Rule: Navigation landmarks must have accessible labels

**Rule:** `html-navigation-has-label`
**Rule:** `a11y-navigation-has-label`

## Description

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Linter Rule: No abstract ARIA roles

**Rule:** `html-no-abstract-roles`
**Rule:** `a11y-no-abstract-roles`

## Description

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Linter Rule: No `aria-hidden` on `<body>`

**Rule:** `html-no-aria-hidden-on-body`
**Rule:** `a11y-no-aria-hidden-on-body`

## Description

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Linter Rule: Focusable elements should not have `aria-hidden="true"`

**Rule:** `html-no-aria-hidden-on-focusable`
**Rule:** `a11y-no-aria-hidden-on-focusable`

## Description

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Linter Rule: Disallow empty headings

**Rule:** `html-no-empty-headings`
**Rule:** `a11y-no-empty-headings`

## Description

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Linter Rule: Disallow nested links

**Rule:** `html-no-nested-links`
**Rule:** `a11y-no-nested-links`

## Description

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Linter Rule: Avoid positive `tabindex` values

**Rule:** `html-no-positive-tab-index`
**Rule:** `a11y-no-positive-tab-index`

## Description

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Linter Rule: Avoid using the `title` attribute

**Rule:** `html-no-title-attribute`
**Rule:** `a11y-no-title-attribute`

## Description

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Removing unnecessary disable comments keeps the codebase clean and ensures that

<div id="test-1">content</div> <%# herb:disable all %>

<DIV id='test-2'>content</DIV> <%# herb:disable html-tag-name-lowercase, html-attribute-double-quotes, html-no-empty-headings %>
<DIV id='test-2'>content</DIV> <%# herb:disable html-tag-name-lowercase, html-attribute-double-quotes, a11y-no-empty-headings %>

<div>test</div> <%# herb:disableall %>
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export default class extends Generator {
{
type: "input",
name: "ruleName",
message: "What is the rule name? (e.g., html-img-require-alt)",
message: "What is the rule name? (e.g., a11y-img-require-alt)",
validate: input => /^[a-z-]+$/.test(input) || "Rule name should be lowercase with hyphens"
},
{
Expand Down
Loading
Loading