fix(lint): improve noSvgWithoutTitle so that it reports more invalid cases#8556
fix(lint): improve noSvgWithoutTitle so that it reports more invalid cases#8556dyc3 merged 5 commits intobiomejs:nextfrom
Conversation
🦋 Changeset detectedLatest commit: 83469d1 The changes in this PR will be included in the next version bump. This PR includes changesets to release 14 packages
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 |
07bdc50 to
b6ba130
Compare
CodSpeed Performance ReportMerging this PR will not alter performanceComparing Summary
Footnotes
|
WalkthroughThis PR updates the noSvgWithoutTitle accessibility lints for HTML and JS/JSX analyzers to: restrict checks to SVGs with image-like ARIA roles ( Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (3)
⏰ 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). (10)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs (1)
90-98: Incorrect valid example at line 97.The example
<svg role="graphics-symbol img"><rect /></svg>lacks both a title element and aria-label/aria-labelledby attributes. Since both "graphics-symbol" and "img" are inNAME_REQUIRED_ROLES, the rule logic (lines 176-189) would flag this as invalid.Either move this to the Invalid section or add an accessible name attribute.
🔎 Verification of rule logic
The rule would process this example as:
- Line 150:
has_valid_title_elementreturnsSome(false)(first child is<rect>)- Lines 176-178:
has_name_required_roleistrue(contains "graphics-symbol" and "img")- Lines 181-185: No
aria-labeloraria-labelledbyfound- Line 189: Returns
Some(())→ diagnostic emitted
🧹 Nitpick comments (1)
crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs (1)
156-159: Update outdated comment.The comment refers only to
role='img', but the code now handles multiple name-required roles.🔎 Suggested rewording
- // Checks if a `svg` element has role='img' and title/aria-label/aria-labelledby attribute + // Checks if a `svg` element has a name-required role and appropriate accessibility attributes
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (4)
crates/biome_html_analyze/tests/specs/a11y/noSvgWithoutTitle/invalid.html.snapis excluded by!**/*.snapand included by**crates/biome_html_analyze/tests/specs/a11y/noSvgWithoutTitle/valid.html.snapis excluded by!**/*.snapand included by**crates/biome_js_analyze/tests/specs/a11y/noSvgWithoutTitle/invalid.jsx.snapis excluded by!**/*.snapand included by**crates/biome_js_analyze/tests/specs/a11y/noSvgWithoutTitle/valid.jsx.snapis excluded by!**/*.snapand included by**
📒 Files selected for processing (7)
.changeset/hungry-jokes-crash.mdcrates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rscrates/biome_html_analyze/tests/specs/a11y/noSvgWithoutTitle/invalid.htmlcrates/biome_html_analyze/tests/specs/a11y/noSvgWithoutTitle/valid.htmlcrates/biome_js_analyze/src/lint/a11y/no_svg_without_title.rscrates/biome_js_analyze/tests/specs/a11y/noSvgWithoutTitle/invalid.jsxcrates/biome_js_analyze/tests/specs/a11y/noSvgWithoutTitle/valid.jsx
🧰 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 thedbg!()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_js_analyze/src/lint/a11y/no_svg_without_title.rscrates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
🧠 Learnings (10)
📚 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_js_analyze/src/lint/a11y/no_svg_without_title.rscrates/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/**/biome_rule_options/lib/**/*.rs : Rule options must be placed inside the `biome_rule_options` crate
Applied to files:
crates/biome_js_analyze/src/lint/a11y/no_svg_without_title.rscrates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-12-22T09:26:56.943Z
Learnt from: ematipico
Repo: biomejs/biome PR: 8537
File: crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs:167-210
Timestamp: 2025-12-22T09:26:56.943Z
Learning: When defining lint rules (declare_lint_rule!), only specify fix_kind if the rule implements an action(...) function. Rules that only emit diagnostics without a code fix should omit fix_kind. This applies to all Rust lint rule definitions under crates/.../src/lint (e.g., crates/biome_js_analyze/src/lint/...).
Applied to files:
crates/biome_js_analyze/src/lint/a11y/no_svg_without_title.rscrates/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 rule severity to `error` for rules in correctness, security, and a11y groups
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 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 : 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 : 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 : Use generic rule names if the rule could potentially be implemented for multiple languages
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/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/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/no_svg_without_title.rs
🧬 Code graph analysis (1)
crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs (2)
crates/biome_js_analyze/src/lint/a11y/use_semantic_elements.rs (1)
role(111-116)crates/biome_js_analyze/src/lint/a11y/no_svg_without_title.rs (2)
is_valid_attribute_value(206-224)has_valid_title_element(227-239)
⏰ 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). (11)
- GitHub Check: Documentation
- GitHub Check: Test (depot-ubuntu-24.04-arm-16)
- GitHub Check: Test (depot-windows-2022-16)
- GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
- GitHub Check: Lint project (depot-windows-2022)
- GitHub Check: Check Dependencies
- GitHub Check: End-to-end tests
- GitHub Check: autofix
- GitHub Check: Bench (biome_js_parser)
- GitHub Check: Bench (biome_js_formatter)
- GitHub Check: Bench (biome_js_analyze)
🔇 Additional comments (14)
.changeset/hungry-jokes-crash.md (1)
1-9: LGTM!Changeset accurately captures the three behaviour changes. Minor bump is appropriate for these fixes.
crates/biome_js_analyze/src/lint/a11y/no_svg_without_title.rs (2)
9-9: LGTM! Well-structured constant for role checking.Centralising the roles that require accessible names makes the logic cleaner and easier to maintain.
163-186: Role handling logic looks solid.The split on whitespace correctly supports multiple role specifications, and the short-circuit for empty roles is sensible. The flow ensures that SVGs with non-name-required roles (like
presentation) don't trigger false positives.crates/biome_html_analyze/tests/specs/a11y/noSvgWithoutTitle/valid.html (1)
18-25: LGTM!Good coverage for the new
graphics-symbolrole support, including the multiple role (graphics-symbol img) scenario.crates/biome_html_analyze/tests/specs/a11y/noSvgWithoutTitle/invalid.html (2)
7-15: Good test case for non-recursive title search.This correctly validates that a
<title>nested within a<g>element should trigger the diagnostic, as only direct child titles are valid.
25-30: Solid coverage for role-based validation.Both the standalone
graphics-symboland the combinedpresentation imgcases correctly exercise the new role handling logic.crates/biome_js_analyze/tests/specs/a11y/noSvgWithoutTitle/invalid.jsx (2)
7-15: LGTM!Mirrors the HTML test case — validates that nested titles within
<g>elements should trigger diagnostics.
25-30: Good role-based test coverage.The
graphics-symbolandpresentation imgcases ensure the JSX implementation handles these scenarios consistently with the HTML linter.crates/biome_js_analyze/tests/specs/a11y/noSvgWithoutTitle/valid.jsx (2)
20-27: LGTM! Test coverage for new role support.The added test cases correctly validate SVGs with
graphics-symbolrole (single and multiple) that include proper title elements, aligning with the PR's objective to support additional name-required roles.
37-42: LGTM! Formatting adjustment.The indentation fix improves readability.
crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs (4)
9-9: LGTM! Centralised role definition.The
NAME_REQUIRED_ROLESconstant provides a single source of truth for roles requiring accessible names, improving maintainability.
46-60: LGTM! Documentation examples align with non-recursive validation.The invalid examples correctly demonstrate cases the updated rule should flag, including nested titles (lines 46-56) and graphics-symbol without title (lines 58-60).
170-192: LGTM! Multi-role support correctly implemented.The refactored logic properly:
- Handles whitespace-separated role tokens (line 177)
- Validates if any role requires an accessible name (lines 176-178)
- Enforces title or aria requirements only for name-required roles (lines 180-189)
- Returns
None(no diagnostic) for roles like "presentation" or "none"The empty/whitespace role handling (lines 171-173) correctly treats missing semantic roles as requiring a title.
211-224: LGTM! Non-recursive title validation.The simplified implementation correctly checks only the first child element for a non-empty
<title>, aligning with the PR objective to prevent recursive traversal per SVG 1.1 backwards compatibility.
.changeset/hungry-jokes-crash.md
Outdated
| @@ -0,0 +1,9 @@ | |||
| --- | |||
| "@biomejs/biome": minor | |||
There was a problem hiding this comment.
nit: Even though its going against the next branch, this should be a patch because its a fix for the rule's original behavior.
| "@biomejs/biome": minor | |
| "@biomejs/biome": patch |
There was a problem hiding this comment.
I think there should be two changesets:
- one for the fix
- one for the new supported stuff
| use biome_rule_options::no_svg_without_title::NoSvgWithoutTitleOptions; | ||
| use biome_string_case::StrLikeExtension; | ||
|
|
||
| const NAME_REQUIRED_ROLES: &[&str] = &["img", "graphics-document", "graphics-symbol"]; |
There was a problem hiding this comment.
This const could go in the aria crate so its not duplicated across the crates. Ideally we would be able to deduplicate more of it.
There was a problem hiding this comment.
There is not struct Aria for now in the biome_html_analyzer crate to use biome_aria crate, so I left the TODO comment and only refactored biome_js_analyzer.
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (4)
crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs (1)
9-9: Duplication with aria crate.This constant duplicates the role list in
has_name_required_image_role. Consider moving it to the aria crate to maintain a single source of truth..changeset/hungry-jokes-crash.md (1)
1-5: Changeset may need splitting.Per prior feedback, consider two changesets:
- A patch for the fix (stopping recursive traversal)
- A minor for the new feature (graphics-document/graphics-symbol role support)
The current changeset only documents the recursive traversal fix but omits the new role support.
crates/biome_js_analyze/src/lint/a11y/no_svg_without_title.rs (2)
203-215: Thenth(1)assumption is fragile.The comment says "first element" but the code uses
nth(1), assuming whitespace always occupies index 0. If the JSX has no leading whitespace, the actual first child would be skipped.Consider filtering to the first actual element rather than relying on positional indexing:
🔎 Proposed fix
fn has_valid_title_element(jsx_child_list: &JsxChildList) -> Option<bool> { - let first_child = jsx_child_list.iter().nth(1)?; + let first_child = jsx_child_list + .iter() + .find(|child| child.as_jsx_element().is_some())?; let jsx_element = first_child.as_jsx_element()?; let opening_element = jsx_element.opening_element().ok()?;
154-154: Emptyaria-labelpasses validation.
aria_label.is_some()accepts empty strings likearia-label="". While the valid example at lines 89-93 shows this as intentional, an empty label provides no accessible text. Consider whether this aligns with accessibility best practices.
🧹 Nitpick comments (3)
.changeset/solid-maps-relax.md (1)
5-8: Description could be slightly more complete.The changeset captures the new role support and multiple role token handling, but omits the fix for recursive title traversal (which should now only check immediate children). Worth noting if this is user-facing, but the description is acceptable as-is if the fix is considered an implementation detail.
🔎 Proposed enhancement (optional)
Added two new behaviors to the `noSvgWithoutTitle` rule. - Support for `graphics-document` and `graphics-symbol` roles. - Support for multiple role specifications. +- Improved title detection to only check immediate child elements (not recursive).crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs (2)
156-156: TODO left in code.The TODO suggests using
aria_roles.has_name_required_image_rolefrom the aria crate. The JS analyzer already uses this method. Would you like help implementing this to maintain consistency between the HTML and JS analyzers?
212-224: Refactored title check looks correct; minor efficiency nit.The logic correctly checks only the first child element for a valid
<title>. However, line 223 uses.count() > 0which iterates all children just to check non-emptiness.🔎 Proposed fix
- let has_child = html_element.children().into_iter().count() > 0; + let has_child = html_element.children().into_iter().next().is_some();
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
crates/biome_js_analyze/tests/specs/a11y/noSvgWithoutTitle/invalid.jsx.snapis excluded by!**/*.snapand included by**
📒 Files selected for processing (7)
.changeset/hungry-jokes-crash.md.changeset/solid-maps-relax.mdcrates/biome_aria/src/roles.rscrates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rscrates/biome_html_analyze/tests/specs/a11y/noSvgWithoutTitle/invalid.htmlcrates/biome_js_analyze/src/lint/a11y/no_svg_without_title.rscrates/biome_js_analyze/tests/specs/a11y/noSvgWithoutTitle/invalid.jsx
🚧 Files skipped from review as they are similar to previous changes (1)
- crates/biome_html_analyze/tests/specs/a11y/noSvgWithoutTitle/invalid.html
🧰 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 thedbg!()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/no_svg_without_title.rscrates/biome_js_analyze/src/lint/a11y/no_svg_without_title.rscrates/biome_aria/src/roles.rs
🧠 Learnings (29)
📚 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.rscrates/biome_js_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-12-22T09:26:56.943Z
Learnt from: ematipico
Repo: biomejs/biome PR: 8537
File: crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs:167-210
Timestamp: 2025-12-22T09:26:56.943Z
Learning: When defining lint rules (declare_lint_rule!), only specify fix_kind if the rule implements an action(...) function. Rules that only emit diagnostics without a code fix should omit fix_kind. This applies to all Rust lint rule definitions under crates/.../src/lint (e.g., crates/biome_js_analyze/src/lint/...).
Applied to files:
crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rscrates/biome_js_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 : Set rule severity to `error` for rules in correctness, security, and a11y groups
Applied to files:
crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rscrates/biome_js_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 : 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.rscrates/biome_js_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 : Add `issue_number` field to `declare_lint_rule!` macro for work-in-progress rules
Applied to files:
crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rscrates/biome_js_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 generic rule names if the rule could potentially be implemented for multiple languages
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/nursery/**/*.rs : Set `recommended` field to `false` for new rules in the nursery group
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 : Set `version` field to `next` in `declare_lint_rule!` macro
Applied to files:
crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-11-24T18:04:47.058Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_aria_metadata/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:04:47.058Z
Learning: Applies to crates/biome_aria_metadata/**/build.rs : The `build.rs` script uses `aria-data.json` to generate ARIA metadata
Applied to files:
crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-11-24T18:05:42.356Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:42.356Z
Learning: Applies to crates/biome_js_type_info/**/*.rs : Store type data in linear vectors instead of using recursive data structures with `Arc` for improved data locality and performance
Applied to files:
crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-11-24T18:05:42.356Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:42.356Z
Learning: Applies to crates/biome_js_type_info/**/*.rs : Use `TypeReference` instead of `Arc` for types that reference other types to avoid stale cache issues when modules are replaced
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/**/biome_rule_options/lib/**/*.rs : Rule options must be placed inside the `biome_rule_options` crate
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_js_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_js_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_js_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_js_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_js_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_js_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 `domains` field in `declare_lint_rule!` to tag rules that belong to specific concepts like testing or frameworks
Applied to files:
crates/biome_js_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_js_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_js_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: Commit rule work with message format `feat(biome_<language>_analyze): <ruleName>`
Applied to files:
.changeset/solid-maps-relax.md
📚 Learning: 2025-12-21T21:15:03.782Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-12-21T21:15:03.782Z
Learning: For promoting rules from nursery or implementing new features affecting end users, send PRs to the `next` branch
Applied to files:
.changeset/hungry-jokes-crash.md
📚 Learning: 2025-12-21T21:15:03.782Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-12-21T21:15:03.782Z
Learning: Changesets should describe user-facing changes only; internal refactoring without behavior changes does not require a changeset
Applied to files:
.changeset/hungry-jokes-crash.md
📚 Learning: 2025-12-21T21:15:03.782Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-12-21T21:15:03.782Z
Learning: Changesets should be concise (1-3 sentences) and provide quick overview of changes without overwhelming details
Applied to files:
.changeset/hungry-jokes-crash.md
📚 Learning: 2025-12-21T21:15:03.782Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-12-21T21:15:03.782Z
Learning: For rule changes in changesets, clearly demonstrate what is now invalid that wasn't before, or vice versa
Applied to files:
.changeset/hungry-jokes-crash.md
📚 Learning: 2025-12-21T21:15:03.782Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-12-21T21:15:03.782Z
Learning: In changesets, start with a link to the issue when fixing a bug (e.g., 'Fixed [#4444](link): ...')
Applied to files:
.changeset/hungry-jokes-crash.md
🧬 Code graph analysis (1)
crates/biome_js_analyze/src/lint/a11y/no_svg_without_title.rs (1)
crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs (3)
run(131-194)is_valid_attribute_value(228-244)has_valid_title_element(213-225)
⏰ 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). (11)
- GitHub Check: Test (depot-windows-2022-16)
- GitHub Check: Lint project (depot-windows-2022)
- GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
- GitHub Check: Check Dependencies
- GitHub Check: Documentation
- GitHub Check: End-to-end tests
- GitHub Check: Test (depot-ubuntu-24.04-arm-16)
- GitHub Check: Bench (biome_js_analyze)
- GitHub Check: Bench (biome_js_parser)
- GitHub Check: Bench (biome_js_formatter)
- GitHub Check: autofix
🔇 Additional comments (4)
crates/biome_js_analyze/tests/specs/a11y/noSvgWithoutTitle/invalid.jsx (1)
7-30: Good test coverage for new scenarios.The new test cases properly cover:
- Nested
<title>inside<g>(should fail as it's not a direct child)graphics-symbolrole without accessible name- Multiple roles including a name-required role (
img presentation)crates/biome_js_analyze/src/lint/a11y/no_svg_without_title.rs (2)
116-117: Nice refactor to use the Aria service.Switching to
Aria<AnyJsxElement>and leveragingctx.aria_roles()is cleaner than manually parsing role attributes. Good alignment with the aria crate's new method.
148-163: Logic is sound but implicit role handling differs from HTML version.The JS version uses
aria_roles.has_name_required_image_role(node)which considers the implicit role (GraphicsDocument for<svg>). This means an<svg>without an explicit role will require a title.The HTML version at line 158 returns
Some(())when no role attribute is present, which has the same effect. Just confirming this is the intended behaviour—SVGs without roles are now flagged.crates/biome_aria/src/roles.rs (1)
287-304: Implementation is correct; no issues found.The method cleanly handles image-related roles per ARIA specification. The first valid role token determines the element's semantic role, so checking only the single returned role is correct.
b4541c7 to
8de39db
Compare
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
crates/biome_js_analyze/src/lint/a11y/no_svg_without_title.rs (1)
32-34: Duplicate example in documentation.This example (
<svg>foo</svg>) is identical to lines 22-23. Consider removing the duplicate or replacing with a distinct invalid case.
♻️ Duplicate comments (2)
crates/biome_js_analyze/src/lint/a11y/no_svg_without_title.rs (2)
89-93: Emptyaria-labeltreated as valid.As previously noted,
aria-label=""doesn't provide accessible text, yet this is shown as a valid example. The check at line 154 only verifies presence (aria_label.is_some()), not content.
203-215: Comment vs code mismatch: "first element" but usingnth(1).The doc comment says "first element" but the code uses
nth(1), which skips index 0. This assumes whitespace always occupies position 0. Either update the comment to clarify the whitespace-skipping behaviour or refactor to explicitly filter non-element nodes.
🧹 Nitpick comments (1)
crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs (1)
223-223: Minor efficiency improvement.
.count() > 0iterates all children. Consider.next().is_some()for a short-circuit check.🔎 Proposed fix
- let has_child = html_element.children().into_iter().count() > 0; + let has_child = html_element.children().into_iter().next().is_some();
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
crates/biome_html_analyze/tests/specs/a11y/noSvgWithoutTitle/invalid.html.snapis excluded by!**/*.snapand included by**crates/biome_js_analyze/tests/specs/a11y/noSvgWithoutTitle/invalid.jsx.snapis excluded by!**/*.snapand included by**
📒 Files selected for processing (7)
.changeset/hungry-jokes-crash.md.changeset/solid-maps-relax.mdcrates/biome_aria/src/roles.rscrates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rscrates/biome_html_analyze/tests/specs/a11y/noSvgWithoutTitle/invalid.htmlcrates/biome_js_analyze/src/lint/a11y/no_svg_without_title.rscrates/biome_js_analyze/tests/specs/a11y/noSvgWithoutTitle/invalid.jsx
🚧 Files skipped from review as they are similar to previous changes (3)
- .changeset/solid-maps-relax.md
- .changeset/hungry-jokes-crash.md
- crates/biome_html_analyze/tests/specs/a11y/noSvgWithoutTitle/invalid.html
🧰 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 thedbg!()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_aria/src/roles.rscrates/biome_js_analyze/src/lint/a11y/no_svg_without_title.rscrates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
🧠 Learnings (28)
📚 Learning: 2025-11-24T18:04:47.058Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_aria_metadata/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:04:47.058Z
Learning: Applies to crates/biome_aria_metadata/**/build.rs : The `build.rs` script uses `aria-data.json` to generate ARIA metadata
Applied to files:
crates/biome_aria/src/roles.rscrates/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_js_analyze/src/lint/a11y/no_svg_without_title.rscrates/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 rule severity to `error` for rules in correctness, security, and a11y groups
Applied to files:
crates/biome_js_analyze/src/lint/a11y/no_svg_without_title.rscrates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-12-22T09:26:56.943Z
Learnt from: ematipico
Repo: biomejs/biome PR: 8537
File: crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs:167-210
Timestamp: 2025-12-22T09:26:56.943Z
Learning: When defining lint rules (declare_lint_rule!), only specify fix_kind if the rule implements an action(...) function. Rules that only emit diagnostics without a code fix should omit fix_kind. This applies to all Rust lint rule definitions under crates/.../src/lint (e.g., crates/biome_js_analyze/src/lint/...).
Applied to files:
crates/biome_js_analyze/src/lint/a11y/no_svg_without_title.rscrates/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_js_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_js_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_js_analyze/src/lint/a11y/no_svg_without_title.rscrates/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_js_analyze/src/lint/a11y/no_svg_without_title.rscrates/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_js_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_js_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 rule option must have its own h3 header with description, default value, options block, and code example
Applied to files:
crates/biome_js_analyze/src/lint/a11y/no_svg_without_title.rscrates/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 : Add `issue_number` field to `declare_lint_rule!` macro for work-in-progress rules
Applied to files:
crates/biome_js_analyze/src/lint/a11y/no_svg_without_title.rscrates/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 `domains` field in `declare_lint_rule!` to tag rules that belong to specific concepts like testing or frameworks
Applied to files:
crates/biome_js_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_js_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_js_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 : 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 : 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 : Use generic rule names if the rule could potentially be implemented for multiple languages
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/nursery/**/*.rs : Set `recommended` field to `false` for new rules in the nursery group
Applied to files:
crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-11-24T18:05:42.356Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:42.356Z
Learning: Applies to crates/biome_js_type_info/**/*.rs : Store type data in linear vectors instead of using recursive data structures with `Arc` for improved data locality and performance
Applied to files:
crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-11-24T18:05:42.356Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:42.356Z
Learning: Applies to crates/biome_js_type_info/**/*.rs : Use `TypeReference` instead of `Arc` for types that reference other types to avoid stale cache issues when modules are replaced
Applied to files:
crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-11-24T18:04:47.058Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_aria_metadata/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:04:47.058Z
Learning: Applies to crates/biome_aria_metadata/**/aria-data.json : `aria-data.json` must be a symlink to `packages/aria-data/aria-data-<version>.json`
Applied to files:
crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-11-24T18:05:27.810Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:27.810Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Do not attempt to 'fix' the code; if a token/node is known to be mandatory but is missing, return `None` instead
Applied to files:
crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs
📚 Learning: 2025-11-24T18:04:47.058Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_aria_metadata/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:04:47.058Z
Learning: Refer to the documentation of `packages/aria-data` to generate the ARIA metadata file
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 : Lines prefixed with `#` in rule documentation code examples will be hidden from output
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 `full_options` code block property for complete biome.json configuration snippets in documentation
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/**/biome_rule_options/lib/**/*.rs : Rule options must be placed inside the `biome_rule_options` crate
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 (2)
crates/biome_js_analyze/src/lint/a11y/use_semantic_elements.rs (1)
role(111-116)crates/biome_js_analyze/src/lint/a11y/no_svg_without_title.rs (3)
node(140-140)is_valid_attribute_value(183-201)has_valid_title_element(204-216)
⏰ 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). (11)
- GitHub Check: Documentation
- GitHub Check: Test (depot-windows-2022-16)
- GitHub Check: Lint project (depot-windows-2022)
- GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
- GitHub Check: Test (depot-ubuntu-24.04-arm-16)
- GitHub Check: End-to-end tests
- GitHub Check: Check Dependencies
- GitHub Check: Bench (biome_js_formatter)
- GitHub Check: Bench (biome_js_parser)
- GitHub Check: Bench (biome_js_analyze)
- GitHub Check: autofix
🔇 Additional comments (6)
crates/biome_aria/src/roles.rs (1)
287-304: LGTM!Clean implementation that correctly identifies image-related roles requiring accessible names. The use of
get_role_by_element_nameensures both explicit and implicit roles are handled consistently.crates/biome_js_analyze/tests/specs/a11y/noSvgWithoutTitle/invalid.jsx (1)
7-30: Good test coverage for the new behaviours.These test cases nicely cover:
- Nested
<title>inside<g>(lines 7-15) — correctly flagged per SVG 1.1 specgraphics-symbolrole without accessible name (lines 25-27)- Multiple role tokens where the first requires a name (lines 28-30)
crates/biome_html_analyze/src/lint/a11y/no_svg_without_title.rs (2)
171-193: Solid role-based validation logic.The
split_whitespaceapproach correctly handles multiple role tokens (e.g.,"graphics-symbol img"), and the conditional check foraria-label/aria-labelledbyonly when a name-required role is present aligns with the PR objectives.
212-222: First-child title check aligns with SVG 1.1 spec.Good refactor — only checking the immediate first child prevents false negatives from deeply nested
<title>elements.crates/biome_js_analyze/src/lint/a11y/no_svg_without_title.rs (2)
116-124: Nice integration with the ARIA service.Switching to
Aria<AnyJsxElement>and usingctx.aria_roles()keeps the logic consistent with the newhas_name_required_image_rolehelper. Clean approach.
148-163: Role-based gating looks correct.Using
aria_roles.has_name_required_image_role(node)centralises the role check, avoiding duplication of the role list. The subsequent validation ofaria-label/aria-labelledbyonly triggers when needed.
8de39db to
83469d1
Compare
Summary
close #8422
As I wrote in the issue, I improved noSvgWithoutTitle so that it reports more invalid cases.
titleelements.graphics-documentandgraphics-symbolroles.Test Plan
Docs