Skip to content

feat(lint/html): implement noSvgWithoutTitle for html#8412

Merged
ematipico merged 2 commits intobiomejs:nextfrom
mehm8128:no-svg-without-title-for-html
Dec 22, 2025
Merged

feat(lint/html): implement noSvgWithoutTitle for html#8412
ematipico merged 2 commits intobiomejs:nextfrom
mehm8128:no-svg-without-title-for-html

Conversation

@mehm8128
Copy link
Contributor

@mehm8128 mehm8128 commented Dec 9, 2025

Summary

related to #8155

implemented useValidAriaRole for html.

For this PR I just ported the existing logic of the rule, but I notice about this rule may have two incomplete points.

  1. <title> element should not be in the descendant of other svg elements such as <g> for the spec of SVG 1.1, so the first Valid case should report diagnostic. For the spec of SVG2, this is not applicable but MDN mentions this from the point of backward compatibility.

Note: For backward compatibility with SVG 1.1, <title> elements should be the first child element of their parent.

  1. <svg role="graphics-symbol"><rect /></svg> and <svg role="graphics-symbol img"><rect /></svg> should report diagnostics because they don't have accessible name. WAI-ARIA Graphics Module says graphics-symbol role requires accessible name, and of course img role does.
    Their cases are handled in the code _ => None,, so we should handle them with match arms.

Could I create issue for them and fix them?

Test Plan

Docs

@changeset-bot
Copy link

changeset-bot bot commented Dec 9, 2025

🦋 Changeset detected

Latest commit: e29479f

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 14 packages
Name Type
@biomejs/biome Minor
@biomejs/cli-win32-x64 Minor
@biomejs/cli-win32-arm64 Minor
@biomejs/cli-darwin-x64 Minor
@biomejs/cli-darwin-arm64 Minor
@biomejs/cli-linux-x64 Minor
@biomejs/cli-linux-arm64 Minor
@biomejs/cli-linux-x64-musl Minor
@biomejs/cli-linux-arm64-musl Minor
@biomejs/wasm-web Minor
@biomejs/wasm-bundler Minor
@biomejs/wasm-nodejs Minor
@biomejs/backend-jsonrpc Patch
@biomejs/js-api Major

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions github-actions bot added A-Linter Area: linter L-HTML Language: HTML and super languages labels Dec 9, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 9, 2025

Walkthrough

Adds a new HTML accessibility lint rule noSvgWithoutTitle that enforces accessible labelling for <svg> elements (requires a <title> descendant or appropriate aria-* attributes when role="img", and skips elements with aria-hidden="true"). The rule is publicly declared and registered in the A11y lint group. New unit-test fixtures (valid and invalid) exercise title, aria-label, and aria-labelledby behaviours.

Possibly related PRs

Suggested labels

A-Diagnostic

Suggested reviewers

  • dyc3

Pre-merge checks and finishing touches

✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: implementing the noSvgWithoutTitle HTML lint rule.
Description check ✅ Passed The description thoroughly explains the changes, rationale, and even highlights two incomplete aspects the author identified for future work.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (2)
.changeset/witty-coats-serve.md (1)

5-5: Consider adding an invalid code example.

The description is concise and clear. Per coding guidelines, changesets for new lint rules should show an example of an invalid case.

As per coding guidelines, consider adding an invalid example:

-Added the `noSvgWithoutTitle` lint rule for HTML. The rule enforces the usage of the `title` element for the `svg` element.
+Added the `noSvgWithoutTitle` lint rule for HTML. The rule enforces the usage of the `title` element for the `svg` element. For example, `<svg>foo</svg>` now triggers a diagnostic.
crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs (1)

191-204: Verify that title text content is non-empty.

Line 201 checks count() > 0 to determine if a <title> has content. This only confirms child nodes exist, not that text content is non-empty. A <title></title> with an empty text node would pass this check.

Consider validating the actual text content:

-    let has_title_name = html_element.children().into_iter().count() > 0;
-    Some(has_title_element && has_title_name)
+    let has_title_content = html_element
+        .children()
+        .into_iter()
+        .any(|child| {
+            child.as_html_content()
+                .and_then(|c| c.value().ok())
+                .map_or(false, |text| !text.text().trim().is_empty())
+        });
+    Some(has_title_element && has_title_content)

Run the test suite to confirm <title></title> correctly triggers a diagnostic:

#!/bin/bash
# Test that empty title elements are properly detected as invalid
cargo test -p biome_html_analyze noSvgWithoutTitle
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1a9334c and 9e91bc2.

⛔ Files ignored due to path filters (2)
  • crates/biome_html_analyze/tests/specs/a11y/noSvgWithoutTitle/invalid.html.snap is excluded by !**/*.snap and included by **
  • crates/biome_html_analyze/tests/specs/a11y/noSvgWithoutTitle/valid.html.snap is excluded by !**/*.snap and included by **
📒 Files selected for processing (5)
  • .changeset/witty-coats-serve.md (1 hunks)
  • crates/biome_html_analyze/src/lint/a11y.rs (1 hunks)
  • crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs (1 hunks)
  • crates/biome_html_analyze/tests/specs/a11y/noSvgWithoutTitle/invalid.html (1 hunks)
  • crates/biome_html_analyze/tests/specs/a11y/noSvgWithoutTitle/valid.html (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

**/*.rs: Use the dbg!() macro for debugging output during testing, and pass the --show-output flag to cargo to view debug output
Use cargo t or cargo test to run tests; for a single test, pass the test name after the test command
Use snapshot testing with the insta crate; run cargo insta accept, cargo insta reject, or cargo insta review to manage snapshot changes
Write doctests as doc comments with code blocks; the code inside code blocks will be run during the testing phase
Use just f (alias for just format) to format Rust and TOML files before committing

Files:

  • crates/biome_html_analyze/src/lint/a11y.rs
  • crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
.changeset/**/*.md

📄 CodeRabbit inference engine (CONTRIBUTING.md)

.changeset/**/*.md: Create changesets for user-facing changes using just new-changeset; use headers with #### or ##### only; keep descriptions concise (1-3 sentences) and focus on user-facing changes
Use past tense when describing what was done ('Added new feature'), present tense when describing Biome behavior ('Biome now supports'); end sentences with a full stop
For new lint rules, show an example of an invalid case in an inline code snippet or code block; for rule changes, demonstrate what is now invalid or valid; for formatter changes, use a diff code block

Files:

  • .changeset/witty-coats-serve.md
🧠 Learnings (21)
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noUnknown` prefix for rules that report mistyped entities in CSS (e.g., `noUnknownUnit`)

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y.rs
  • crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : The `declare_lint_rule!` macro must include metadata fields: `version` (set to 'next'), `name` (rule identifier), `language` (applicable language), `recommended` (boolean), and optional fields like `severity`, `fix_kind`, `sources`, `domains`, and `deprecated`

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y.rs
  • crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noUndeclared` prefix for rules that report undefined entities (e.g., `noUndeclaredVariables`)

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noUnsafe` prefix for rules that report code leading to runtime failures (e.g., `noUnsafeOptionalChaining`)

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y.rs
  • crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Framework-specific rules should be named using the `use` or `no` prefix followed by the framework name (e.g., `noVueReservedProps`)

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y.rs
  • crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/nursery/**/*.rs : New rules must be placed inside the `nursery` group as an incubation space exempt from semantic versioning, with promotion to appropriate groups done during minor/major releases

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noUnused` prefix for rules that report unused entities (e.g., `noUnusedVariables`)

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noEmpty` prefix for rules that report empty code (e.g., `noEmptyBlockStatements`)

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y.rs
  • crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noRestricted` prefix for rules that report user-banned entities (e.g., `noRestrictedGlobals`)

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noMisleading` prefix for rules that report valid but potentially misleading code (e.g., `noMisleadingCharacterClass`)

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y.rs
  • crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Rules should use the `use` prefix naming convention when the sole intention is to mandate a single concept (e.g., `useValidLang` to enforce valid HTML lang attribute values)

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y.rs
  • crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noRedundant` prefix for rules that report redundant code (e.g., `noRedundantUseStrict`)

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Rules should use the `no` prefix naming convention when the sole intention is to forbid a single concept (e.g., `noDebugger` to disallow debugger statements)

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y.rs
📚 Learning: 2025-11-28T09:08:10.091Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-11-28T09:08:10.091Z
Learning: Applies to .changeset/**/*.md : Create changesets for user-facing changes using `just new-changeset`; use headers with `####` or `#####` only; keep descriptions concise (1-3 sentences) and focus on user-facing changes

Applied to files:

  • .changeset/witty-coats-serve.md
📚 Learning: 2025-11-28T09:08:10.091Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-11-28T09:08:10.091Z
Learning: Applies to .changeset/**/*.md : Use past tense when describing what was done ('Added new feature'), present tense when describing Biome behavior ('Biome now supports'); end sentences with a full stop

Applied to files:

  • .changeset/witty-coats-serve.md
📚 Learning: 2025-11-28T09:08:10.091Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-11-28T09:08:10.091Z
Learning: Applies to .changeset/**/*.md : For new lint rules, show an example of an invalid case in an inline code snippet or code block; for rule changes, demonstrate what is now invalid or valid; for formatter changes, use a `diff` code block

Applied to files:

  • .changeset/witty-coats-serve.md
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Rule diagnostics must explain to the user what the error is, why it is triggered, and what should be done to fix it following the three pillars: (1) what the error is, (2) why the error is triggered, (3) what the user should do

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : The `diagnostic` function must return a `RuleDiagnostic` that defines the message reported to the user using the `markup!` macro

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Set rule severity to `error` for correctness/security/a11y rules, `warn` for suspicious/performance rules, `info` for style/complexity rules, and `info` for actions

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : In rule documentation code blocks, mark invalid examples with the `expect_diagnostic` property and valid examples without it; each invalid example must emit exactly one diagnostic

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Lint rules must be implemented using the `Rule` trait with type parameters: `Query` (node type to analyze), `State` (information for signals), `Signals` (return type from run function), and `Options` (rule configuration)

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
🧬 Code graph analysis (1)
crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs (3)
crates/biome_service/src/workspace.rs (1)
  • markup (1203-1205)
packages/@biomejs/plugin-api/index.d.ts (1)
  • Severity (1-1)
crates/biome_analyze/src/rule.rs (1)
  • recommended (602-605)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: autofix
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Check Dependencies
🔇 Additional comments (3)
crates/biome_html_analyze/src/lint/a11y.rs (1)

9-9: LGTM!

The new no_svg_without_title module is correctly integrated into the A11y lint group.

Also applies to: 15-15

crates/biome_html_analyze/tests/specs/a11y/noSvgWithoutTitle/valid.html (1)

6-18: Known limitation: nested title should trigger diagnostic per SVG 1.1.

Per the PR description, SVG 1.1 specifies that <title> should not be a descendant of other SVG elements like <g>. This test case currently passes but should report a diagnostic according to the spec. MDN recommends placing <title> as the first child for backward compatibility.

The PR author mentioned creating issues to track these limitations. Please confirm whether an issue will be opened to handle nested title validation.

crates/biome_html_analyze/tests/specs/a11y/noSvgWithoutTitle/invalid.html (1)

1-15: Test cases look appropriate.

The invalid cases correctly exercise the diagnostic paths. Note that lines 3-6 (<title></title>) depend on the has_valid_title_element function properly detecting empty title content—verify this aligns with the implementation review comments.

@dyc3 dyc3 mentioned this pull request Dec 9, 2025
32 tasks
@mehm8128 mehm8128 force-pushed the no-svg-without-title-for-html branch from 9e91bc2 to 2eb5b30 Compare December 10, 2025 04:15
@ematipico
Copy link
Member

Could I create issue for them and fix them?

Sure please do! 😊

@mehm8128
Copy link
Contributor Author

I've created issue, so please continue to review other points.
💅 noSvgWithoutTitle should report diagnostics some cases · Issue #8422 · biomejs/biome

@mehm8128 mehm8128 requested a review from ematipico December 19, 2025 12:40
@ematipico ematipico force-pushed the no-svg-without-title-for-html branch from 2eb5b30 to d893849 Compare December 22, 2025 09:19
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs (1)

184-197: Revise diagnostic message to cover all triggering scenarios.

The message "Alternative text 'title' element cannot be empty" is misleading when no title exists or when role="img" lacks valid aria attributes.

🔎 Suggested revision
-                "Alternative text "<Emphasis>"title"</Emphasis>" element cannot be empty"
+                "Provide an accessible name for this "<Emphasis>"svg"</Emphasis>" element"
🧹 Nitpick comments (1)
crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs (1)

200-213: Consider renaming variable for clarity.

Line 210: The variable has_title_name actually checks whether the title has content (children count > 0), not whether it has a name. Consider has_title_content or is_title_non_empty for clarity.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2eb5b30 and e29479f.

⛔ Files ignored due to path filters (2)
  • crates/biome_html_analyze/tests/specs/a11y/noSvgWithoutTitle/invalid.html.snap is excluded by !**/*.snap and included by **
  • crates/biome_html_analyze/tests/specs/a11y/noSvgWithoutTitle/valid.html.snap is excluded by !**/*.snap and included by **
📒 Files selected for processing (5)
  • .changeset/witty-coats-serve.md
  • crates/biome_html_analyze/src/lint/a11y.rs
  • crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
  • crates/biome_html_analyze/tests/specs/a11y/noSvgWithoutTitle/invalid.html
  • crates/biome_html_analyze/tests/specs/a11y/noSvgWithoutTitle/valid.html
🚧 Files skipped from review as they are similar to previous changes (3)
  • crates/biome_html_analyze/tests/specs/a11y/noSvgWithoutTitle/valid.html
  • crates/biome_html_analyze/tests/specs/a11y/noSvgWithoutTitle/invalid.html
  • .changeset/witty-coats-serve.md
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

**/*.rs: Use inline rustdoc documentation for rules, assists, and their options
Use the dbg!() macro for debugging output in Rust tests and code
Use doc tests (doctest) format with code blocks in rustdoc comments; ensure assertions pass in tests

Files:

  • crates/biome_html_analyze/src/lint/a11y.rs
  • crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
🧠 Learnings (27)
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/nursery/**/*.rs : Add `issue_number` field to `declare_lint_rule!` macro for work-in-progress rules

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y.rs
  • crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/nursery/**/*.rs : Place new rules inside the `nursery` group during development

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Set rule severity to `error` for rules in correctness, security, and a11y groups

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y.rs
  • crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Add `deprecated` field to `declare_lint_rule!` macro when deprecating a rule

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y.rs
  • crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Set `version` field to `next` in `declare_lint_rule!` macro

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Set `language` field in `declare_lint_rule!` macro to the language the rule primarily applies to

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `domains` field in `declare_lint_rule!` to tag rules that belong to specific concepts like testing or frameworks

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y.rs
  • crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `declare_lint_rule!` macro to declare analyzer rule types and implement the RuleMeta trait

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y.rs
  • crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Lint rules should perform static analysis of source code to detect invalid or error-prone patterns and emit diagnostics with proposed fixes

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y.rs
  • crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/nursery/**/*.rs : Set `recommended` field to `false` for new rules in the nursery group

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Each rule option must have its own h3 header with description, default value, options block, and code example

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Rule documentation must include `## Options` section if the rule has options

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : The first paragraph of rule documentation must be a single line describing what the rule does

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Add `sources` field with `RuleSource` to cite ESLint or other rules that inspired the implementation

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use language-specific rule names if the rule is meant for a specific language only

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Invalid code examples in rule documentation must be marked with `expect_diagnostic` code block property

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Each invalid code example in rule documentation must emit exactly one diagnostic

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Rule documentation must include `## Examples` section with `### Invalid` and `### Valid` subsections

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Valid code examples in rule documentation should not trigger any diagnostics

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Prefix line with `#` in documentation code examples sparingly; prefer concise complete snippets

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `ignore` code block property to exclude documentation code examples from automatic validation

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Rule documentation code blocks should be ordered as language, expect_diagnostic, options/full_options/use_options, ignore, file

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-11-24T18:04:57.309Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_diagnostics/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:04:57.309Z
Learning: Diagnostic should provide a way for the user to fix the issue through log advice, diff advice, or command advice. Add the FIXABLE tag to highlight actionable hints

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Assist rules should detect refactoring opportunities and emit code action signals

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Rules with `recommended: true` and no domains are enabled by default

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Lint rules should check syntax according to language specification and emit error diagnostics

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `RuleSource::Eslint(...).inspired()` when implementing a rule inspired by but with different behavior than an ESLint rule

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
🧬 Code graph analysis (1)
crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs (1)
crates/biome_js_analyze/src/lint/a11y/no_svg_without_title.rs (1)
  • Rule (110-188)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: autofix
🔇 Additional comments (4)
crates/biome_html_analyze/src/lint/a11y.rs (1)

10-10: LGTM!

The module declaration and lint group registration are correct.

Also applies to: 16-16

crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs (3)

88-93: Verify the known issue is tracked for follow-up.

Per the PR description, these examples with role="graphics-symbol" should report diagnostics but currently fall through to return None. Confirm that issue #8422 properly tracks this limitation.


127-182: LGTM!

The role-based validation logic correctly handles aria-hidden, title elements, and role="img" with aria attributes. The acceptance of empty aria-label="" for decorative SVGs is intentional.


215-232: LGTM!

The function correctly validates that aria-labelledby references an existing id in the SVG's children.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Linter Area: linter L-HTML Language: HTML and super languages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants