Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't delegate focus when the shadow host is an ancestor of the currently focused area #5039

Merged
merged 4 commits into from
Oct 28, 2019
Merged

Don't delegate focus when the shadow host is an ancestor of the currently focused area #5039

merged 4 commits into from
Oct 28, 2019

Conversation

rakina
Copy link
Member

@rakina rakina commented Oct 24, 2019

As discussed in WICG/webcomponents#840

(See WHATWG Working Mode: Changes for more details.)

cc @domenic @rniwa @smaug----


/interaction.html ( diff )

Copy link
Member

@domenic domenic left a comment

Choose a reason for hiding this comment

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

LGTM with editorial nit I will push a fix for

<ol>
<li>If <var>new focus target</var> is a <span>shadow-including inclusive ancestor</span> of
the <span>currently focused area of a top-level browsing context</span>'s <span>DOM
anchor</span>, then set <var>new focus target</var> to null and stop these steps.</li>
Copy link
Member

Choose a reason for hiding this comment

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

It's a bit ambiguous how to interpret "stop these steps" here. I think the easiest thing to do will be to just nest the other three steps under an "Otherwise:" step 2.

I'll make that change since it's easy enough.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thank you!

@domenic domenic added topic: focus topic: shadow Relates to shadow trees (as defined in DOM) labels Oct 24, 2019
@domenic
Copy link
Member

domenic commented Oct 25, 2019

I'll merge this, as well as the accompany tests, Monday or Tuesday if there haven't been any comments. Feel free to file bugs pointing to the spec and tests PR; there's no need to wait on landing before doing so.

@domenic domenic merged commit 3bbb870 into whatwg:master Oct 28, 2019
area">focusable areas</span> whose <span>DOM anchor</span> is a descendant of <var>new focus
target</var> in the <span>flat tree</span>.</p>
<ol>
<li>If <var>new focus target</var> is a <span>shadow-including inclusive ancestor</span> of
Copy link

Choose a reason for hiding this comment

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

I don't think this is quite right. You can have two elements that are descendants of each other without shadow trees, in those cases, focus() should be able to move the focus to the outer / ancestor node which is a simple ancestor of the currently focused element.

e.g.

const div = document.body.appendChild(document.createElement('div'));
div.tabIndex = 0;
const span = div.appendChild(document.createElement('span'));
span.textContent = 'hello'
div.tabIndex = 0;
span.tabIndex = 0;
span.focus();
div.focus(); // This should move the focus to div.

Copy link
Member Author

Choose a reason for hiding this comment

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

I think it does move the focus to the div, because div is not a shadow host that delegates focus. These steps are within the "If new focus target is a shadow host whose shadow root 's delegates focus is true" clause.

Copy link

Choose a reason for hiding this comment

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

Oh, you're right.

@rniwa
Copy link

rniwa commented Oct 28, 2019

Also see #5052

josepharhar added a commit to josepharhar/html that referenced this pull request Oct 29, 2022
I was implementing the new dialog shadowdom initial focus goodness when
I noticed this in chromium:
https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/dom/element.cc;l=4714-4718;drc=82b10d45463bbc3d019f5ef981dc8afeb8900a6d

When getting the focusable area of a target, in the case that the
target is a shadow-incuding inclusive ancestor of the currently focused
element, the spec says to return null, but chromium's implementation
returns the currently focused element instead and cites this issue:
WICG/webcomponents#840

I'm not certain exactly what the consensus was, but I do see that this
spec PR and test was made in response:
whatwg#5039
web-platform-tests/wpt#19867
The added test doesn't fail if I return null like the spec says to do,
but dialog-focus-shadow-double-nested.html does fail if I return null
with this error message:
```
FAIL showModal() assert_equals: document.activeElement expected Element node <div></div> but got Element node <button tabindex="-1">Focusable</button>
```

Based on this test failure and reading the WICG issue, I believe that we
should be returning the currently focused element, which this patch
does.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: focus topic: shadow Relates to shadow trees (as defined in DOM)
Development

Successfully merging this pull request may close these issues.

3 participants