Skip to content

script: Align focusable area logic to be closer to the specification#43058

Merged
mrobinson merged 1 commit into
servo:mainfrom
mrobinson:focus-area-cleanup
Mar 6, 2026
Merged

script: Align focusable area logic to be closer to the specification#43058
mrobinson merged 1 commit into
servo:mainfrom
mrobinson:focus-area-cleanup

Conversation

@mrobinson

@mrobinson mrobinson commented Mar 6, 2026

Copy link
Copy Markdown
Member

This abstracts out a common helper to determine focusable area kind
which is used by Element::is_click_focusable,
Element::is_sequentially_focusable, and Element::is_focusable_area.
This avoid having the latter depend on the former two, which was the
reverse of what the specification said. The helper is necessary because
the specification defines click and sequential focusability as subsets
of focusable elements, but going from "This is a focusable element" to
determining what kind of focusable element something is requires
duplicating a lot of the logic that was used to determine that something
is a focusable area.

It's likely that the specification needs more work here to improve the
definition (and indeed to unify all of the places that talk about what
elements are focusable areas). For now, this just tries to make our code
more similar to the text.

See: whatwg/html#4607
Testing: This shouldn't change behavior, so should be tested by existing tests.

@mrobinson mrobinson requested a review from gterzian as a code owner March 6, 2026 10:47
@servo-highfive servo-highfive added the S-awaiting-review There is new code that needs to be reviewed. label Mar 6, 2026
@mrobinson

Copy link
Copy Markdown
Member Author

cc @TimvdLippe PTAL

@TimvdLippe TimvdLippe left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Only a couple of nits. Nice solution to use bitflags for this.

Comment thread components/script/dom/element.rs Outdated
Comment on lines +1782 to +1783
/// > An element is being rendered if it has any associated CSS layout boxes, SVG layout boxes,
/// > or some equivalent in other styling languages.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: generally we only have the link to the spec in the rustdoc and then the explanation of the spec inside the method body.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Sure. I'm happy to move this.

Comment thread components/script/dom/element.rs Outdated
// > navigation scope owners, except the elements whose tabindex value is a negative integer.
// > - It contains all of the focusable areas whose DOM anchor is an element in owner's focus
// > navigation scope, except the focusable areas whose tabindex value is a negative integer.
Some(-1) => return FocusableAreaKind::Click,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: should cover all negative integers

Suggested change
Some(-1) => return FocusableAreaKind::Click,
Some(index) if index < 0 => return FocusableAreaKind::Click,

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

👍

Comment thread components/script/dom/element.rs Outdated
// > Modulo platform conventions, it is suggested that the following elements should be
// > considered as focusable areas and be sequentially focusable:
match node.type_id() {
let is_focusable_are_due_to_type = match node.type_id() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It took me a while to figure out what the typo was here 😛

Suggested change
let is_focusable_are_due_to_type = match node.type_id() {
let is_focusable_area_due_to_type = match node.type_id() {

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

😆

@servo-highfive servo-highfive removed the S-awaiting-review There is new code that needs to be reviewed. label Mar 6, 2026

@mrobinson mrobinson left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Thanks for the review.

Comment thread components/script/dom/element.rs Outdated
// > Modulo platform conventions, it is suggested that the following elements should be
// > considered as focusable areas and be sequentially focusable:
match node.type_id() {
let is_focusable_are_due_to_type = match node.type_id() {

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

😆

Comment thread components/script/dom/element.rs Outdated
// > navigation scope owners, except the elements whose tabindex value is a negative integer.
// > - It contains all of the focusable areas whose DOM anchor is an element in owner's focus
// > navigation scope, except the focusable areas whose tabindex value is a negative integer.
Some(-1) => return FocusableAreaKind::Click,

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

👍

Comment thread components/script/dom/element.rs Outdated
Comment on lines +1782 to +1783
/// > An element is being rendered if it has any associated CSS layout boxes, SVG layout boxes,
/// > or some equivalent in other styling languages.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Sure. I'm happy to move this.

This abstracts out a common helper to determine focusable area kind
which is used by `Element::is_click_focusable`,
`Element::is_sequentially_focusable`, and `Element::is_focusable_area`.
This avoid having the latter depend on the former two, which was the
reverse of what the specification said. The helper is necessary because
the specification defines click and sequential focusability as subsets
of focusable elements, but going from "This is a focusable element" to
determining what kind of focusable element something is requires
duplicating a lot of the logic that was used to determine that something
is a focusable area.

It's likely that the specification needs more work here to improve the
definition (and indeed to unify all of the places that talk about what
elements are focusable areas). For now, this just tries to make our code
more similar to the text.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
@mrobinson mrobinson force-pushed the focus-area-cleanup branch from b520208 to 0f5fb0e Compare March 6, 2026 14:45
@servo-highfive servo-highfive added the S-awaiting-review There is new code that needs to be reviewed. label Mar 6, 2026
@mrobinson mrobinson enabled auto-merge March 6, 2026 14:45
@mrobinson mrobinson added this pull request to the merge queue Mar 6, 2026
@servo-highfive servo-highfive added the S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. label Mar 6, 2026
Merged via the queue into servo:main with commit e2f6852 Mar 6, 2026
33 checks passed
@mrobinson mrobinson deleted the focus-area-cleanup branch March 6, 2026 15:40
@servo-highfive servo-highfive removed the S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. label Mar 6, 2026
offline-ant pushed a commit to offline-ant/havi that referenced this pull request Jun 4, 2026
…ervo#43058)

This abstracts out a common helper to determine focusable area kind
which is used by `Element::is_click_focusable`,
`Element::is_sequentially_focusable`, and `Element::is_focusable_area`.
This avoid having the latter depend on the former two, which was the
reverse of what the specification said. The helper is necessary because
the specification defines click and sequential focusability as subsets
of focusable elements, but going from "This is a focusable element" to
determining what kind of focusable element something is requires
duplicating a lot of the logic that was used to determine that something
is a focusable area.

It's likely that the specification needs more work here to improve the
definition (and indeed to unify all of the places that talk about what
elements are focusable areas). For now, this just tries to make our code
more similar to the text.

See: whatwg/html#4607
Testing: This shouldn't change behavior, so should be tested by existing
tests.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
(cherry picked from commit e2f6852)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-awaiting-review There is new code that needs to be reviewed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants