script: Distinguish between sequential (keyboard) and click focusability#43019
Conversation
| // This implements <https://html.spec.whatwg.org/#html-element-removing-steps> for HTML | ||
| // elements. |
There was a problem hiding this comment.
Nit: refer to the full algorithm that implements the removing steps for DOM. The way I constructed this URL is as follows:
- Clicked on https://html.spec.whatwg.org/multipage/infrastructure.html#html-element-removing-steps
- Clicked on it to see its usages
- Clicked on "DOM trees (2)"
- Observe that the URL has
infrastructure.html#dom-trees: - Then append the relevant algorithm name from the DOM spec (
concept-node-remove-ext)
| // This implements <https://html.spec.whatwg.org/#html-element-removing-steps> for HTML | |
| // elements. | |
| /// <https://html.spec.whatwg.org/multipage#dom-trees:concept-node-remove-ext> |
There was a problem hiding this comment.
Okay. I've replaced this spec link and converted it to rustdoc. Thanks for the tip.
There was a problem hiding this comment.
Note thought that this seems to scroll to step 3 of the steps that this function refers to. I feel the link should navigate to the part of the document that starts with "The removing steps for the HTML Standard, given removedNode, isSubtreeRoot, and oldAncestor, are defined as the following:" The link you provided links to the the text "defines HTML element removing steps" in step 3.
There was a problem hiding this comment.
I am confused. When I open https://html.spec.whatwg.org/multipage#dom-trees:concept-node-remove-ext in my browser, it opens right at the top of the algorithm. Not at step 3. Can you try in a new tab?
There was a problem hiding this comment.
Ah, yes. I was using the link produced when clicking on "Dom Trees (2)" which is:
The one you produced was:
| /// This is the parts of | ||
| /// <https://html.spec.whatwg.org/multipage/interaction.html#focusable-area> that apply for | ||
| /// keyboard focusability. See also [`Self::is_click_focusable`]. | ||
| pub(crate) fn is_keyboard_focusable(&self) -> bool { |
There was a problem hiding this comment.
I don't see the spec talking about keyboard focusability, but instead it is named sequentially_focusable. Before it was called is_sequentially_focusable and I think that would be more aligned with what the spec says? Basically, if I search for "keyboard focus", nothing shows in the spec, but "click focus" and "sequentially focus" do
There was a problem hiding this comment.
I've renamed this reflect the specification terminology, "sequentially focusable."
768fcba to
0db8ed1
Compare
0db8ed1 to
50d1792
Compare
|
🔨 Triggering try run (#22686011943) for Linux (WPT) |
50d1792 to
27938ae
Compare
|
Test results for linux-wpt from try job (#22686011943): Flaky unexpected result (24)
Stable unexpected results that are known to be intermittent (24)
Stable unexpected results (2)
|
|
|
27938ae to
3492a73
Compare
TimvdLippe
left a comment
There was a problem hiding this comment.
Overall LGTM. I am a bit surprised how this code differs from the spec, especially how the two types of focus areas are mutually exclusive as I understand it. Still, this is a step in the right direction, so I am fine with it for now.
| )) | ||
| ) { | ||
| return true; | ||
| /// This is an implementation of <https://html.spec.whatwg.org/multipage/#click-focusable>i |
There was a problem hiding this comment.
| /// This is an implementation of <https://html.spec.whatwg.org/multipage/#click-focusable>i | |
| /// This is an implementation of <https://html.spec.whatwg.org/multipage/#click-focusable> |
| } | ||
| let node = self.upcast::<Node>(); | ||
| if node.get_flag(NodeFlags::SEQUENTIALLY_FOCUSABLE) { | ||
| if self.is_click_focusable() { |
There was a problem hiding this comment.
I am surprised by this logic here. The spec doesn't imply that click focusable means sequentially focusable. Shouldn't we check for https://html.spec.whatwg.org/multipage/interaction.html#sequential-focus-navigation-order instead here?
There was a problem hiding this comment.
The specification is quite hand-wavy here and leaves a lot of decisions up to the embedder. I guess you've noticed how some of the definitions appear to be practically circular? In any case, we did not seem to find much specification text which describes which kinds of focusable areas should be focusable sequentially versus which should be focusable via click. In the end, it makes sense that the keyboard can focus a superset of things that a mouse can, for accessibility reasons.
That said, if you can find better specification text, I think we'd be happy to implement it.
There was a problem hiding this comment.
For instance, consider a <div> with overflow: scroll ("The scrollable regions of elements that are being rendered and are not inert." from the specification text). By observation you can see that these are focusable with a keyboard in browsers, but not with a click. You can see this by putting a :focus selector with an outline on the <div>.
On the other hand, the specification also says that "Any other element or part of an element determined by the user agent to be a focusable area, especially to aid with accessibility or to better match platform conventions" can be a focusable area.
| document.request_focus(None, FocusInitiator::Local, can_gc); | ||
| document.request_focus(target_el.as_deref(), FocusInitiator::Local, can_gc); | ||
| document.request_focus(None, FocusInitiator::Click, can_gc); | ||
| document.request_focus(target_el.as_deref(), FocusInitiator::Click, can_gc); |
There was a problem hiding this comment.
Is this the code related to https://html.spec.whatwg.org/multipage/interaction.html#data-model:click-focusable-5 ? E.g.
When a user activates a click focusable focusable area, the user agent must run the focusing steps on the focusable area with focus trigger set to "click".
If it is, please add that as a spec reference
There was a problem hiding this comment.
I believe the focusing steps are implemented when the transaction is committed. We have a TODO item to make all of that code match the specification more closely.
EDIT: To clarify we'll try to "focus" on this next as well as trying to make the code around click versus sequential focusability more closely align with the specification language.
There was a problem hiding this comment.
I'm only reviewing this part. Nice.
3492a73 to
f5d4f91
Compare
This changes makes it so that keyboard and click focusability are two separate concepts in `script`. Some elements may be focusable only by the keyboard and some only by the click events. In addition, the SEQUENTIALLY_FOCUSABLE flag is removed in favor of a more specification aligned approach of checking lazily if an element is a focusable area. This allows moving the focus fixup steps to their correct place, asynchronously during "update the rendering" and synchronously during `unbind_from_tree`. Signed-off-by: Martin Robinson <[email protected]> Co-authored-by: Oriol Brufau <[email protected]>
f5d4f91 to
83cc781
Compare
|
🔨 Triggering try run (#22706624527) for Linux (WPT) |
|
Test results for linux-wpt from try job (#22706624527): Flaky unexpected result (34)
Stable unexpected results that are known to be intermittent (16)
|
|
✨ Try run (#22706624527) succeeded. |
|
Failure is #43030 (more intermittency in largest contentful paint tests), sending back to merge queue. |
…ity (servo#43019) This changes makes it so that keyboard and click focusability are two separate concepts in `script`. Some elements may be focusable only by the keyboard and some only by the click events. In addition, the `SEQUENTIALLY_FOCUSABLE` `Node` flag is removed in favor of a more specification-aligned approach of checking lazily if an element is a focusable area. This allows moving the focus fixup steps to their correct place, asynchronously during "update the rendering" and synchronously during `unbind_from_tree`. Testing: This causes some WPT tests to start passing and some to start failing: - Two subtests tests in `tests/wpt/meta/css/css-conditional/container-queries/` because we do not implement support for container queries. These are legitimate failures and they are compensated by a good subtest pass in the same file. - A few subtests in `/html/interaction/focus/tabindex-focus-flag.html` because now we do not allow focusing non-rendering elements. The failures are HTML elements with `<svg>` which we do not rendering and `<summary>` elements of `<details>` which need special handling we do not implement yet. - `html/semantics/forms/the-fieldset-element/disabled-003.html`: Some of these tests start to fail, but they are not spec compliant and browser properly implementing the asynchronous focus fixup rule also fail them. Fixes: servo#31870. Signed-off-by: Martin Robinson <[email protected]> Co-authored-by: Oriol Brufau <[email protected]>
This changes makes it so that keyboard and click focusability are two
separate concepts in
script. Some elements may be focusable only bythe keyboard and some only by the click events.
In addition, the
SEQUENTIALLY_FOCUSABLENodeflag is removed in favor of amore specification-aligned approach of checking lazily if an element is
a focusable area. This allows moving the focus fixup steps to their
correct place, asynchronously during "update the rendering" and
synchronously during
unbind_from_tree.Testing: This causes some WPT tests to start passing and some to start failing:
tests/wpt/meta/css/css-conditional/container-queries/becausewe do not implement support for container queries. These are legitimate failures
and they are compensated by a good subtest pass in the same file.
/html/interaction/focus/tabindex-focus-flag.htmlbecause nowwe do not allow focusing non-rendering elements. The failures are HTML elements with
<svg>which we do not rendering and<summary>elements of<details>whichneed special handling we do not implement yet.
html/semantics/forms/the-fieldset-element/disabled-003.html: Some of these testsstart to fail, but they are not spec compliant and browser properly implementing
the asynchronous focus fixup rule also fail them.
Fixes: #31870.