Commit 169c2efa authored by Rakina Zata Amni's avatar Rakina Zata Amni Committed by Commit Bot

Make mouse-triggered focus use flat tree traversal

Previously mouse-triggered focusing on an element (e.g. clicking) uses
repeated calls of ParentOrShadowElement() instead of using flat-tree
traversal methods, causing it to go up its shadow-including ancestors
instead of flat-tree. This behavior is not specified, but other
browser vendors had implemented flat-tree traversal usage for focus
traversal.

See: https://github.com/w3c/webcomponents/issues/773

Bug: 894931
Change-Id: I5666c9e973480648e8e9a1774e5d6abe026aac5c
Reviewed-on: https://chromium-review.googlesource.com/c/1455839Reviewed-by: default avatarHayato Ito <hayato@chromium.org>
Reviewed-by: default avatarKent Tamura <tkent@chromium.org>
Commit-Queue: Rakina Zata Amni <rakina@chromium.org>
Cr-Commit-Position: refs/heads/master@{#629515}
parent 043cd45c
...@@ -490,7 +490,7 @@ WebInputEventResult MouseEventManager::HandleMouseFocus( ...@@ -490,7 +490,7 @@ WebInputEventResult MouseEventManager::HandleMouseFocus(
frame_->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets(); frame_->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
Element* element = element_under_mouse_; Element* element = element_under_mouse_;
for (; element; element = element->ParentOrShadowHostElement()) { for (; element; element = FlatTreeTraversal::ParentElement(*element)) {
if (element->IsFocusable() && element->IsFocusedElementInDocument()) if (element->IsFocusable() && element->IsFocusedElementInDocument())
return WebInputEventResult::kNotHandled; return WebInputEventResult::kNotHandled;
if (element->IsMouseFocusable()) if (element->IsMouseFocusable())
......
<!DOCTYPE html>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script>
function clickOn(el) {
return new Promise(function(resolve, reject) {
chrome.gpuBenchmarking.pointerActionSequence([{
source: 'mouse',
actions: [
{ name: 'pointerDown',
x: el.offsetLeft + 5,
y: el.offsetTop + 5
},
{ name: 'pointerUp' }
]
}], resolve);
});
}
</script>
<body>
<div id='normalDiv' tabindex='0'><span id='normalSpan'>OK</span></div>
<div id='container'><span id='slottedSpan'>OK</span></div>
</body>
<script>
let sr = container.attachShadow({ mode: 'open' });
sr.innerHTML = '<div id="shadowDiv" tabindex="0"><slot></slot></div>';
promise_test(async () => {
await clickOn(normalSpan);
assert_equals(document.activeElement, normalDiv);
await clickOn(slottedSpan);
assert_equals(sr.activeElement, sr.getElementById('shadowDiv'));
}, 'Clicking on non-focusable slot inside focusable button will make the flat-tree focusable ancestor get focused');
</script>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment