Bug 1775451 - Scroll into view after changing focus state, not before. r=smaug

This matches other browsers.

The scroll event is dispatched async, so
the test would mostly pass without the patch, actually, except for the
fact that we wouldn't scroll. So without the patch the test times out.

Differential Revision: https://phabricator.services.mozilla.com/D150237
This commit is contained in:
Emilio Cobos Álvarez 2022-06-27 10:56:15 +00:00
Родитель 4e1ef97a03
Коммит 4fdd211396
2 изменённых файлов: 52 добавлений и 4 удалений

Просмотреть файл

@ -2636,15 +2636,16 @@ void nsFocusManager::Focus(
aWindow->SetFocusedElement(aElement, focusMethod, false);
// if the focused element changed, scroll it into view
if (aElement && aFocusChanged) {
ScrollIntoView(presShell, aElement, aFlags);
}
const RefPtr<nsPresContext> presContext = presShell->GetPresContext();
if (sendFocusEvent) {
NotifyFocusStateChange(aElement, nullptr, aFlags,
/* aGettingFocus = */ true, shouldShowFocusRing);
// If the focused element changed, scroll it into view
if (aFocusChanged) {
ScrollIntoView(presShell, aElement, aFlags);
}
// If this is a remote browser, focus its widget and activate remote
// content. Note that we might no longer be in the same document,
// due to the events we fired above when aIsNewDocument.

Просмотреть файл

@ -0,0 +1,47 @@
<!doctype html>
<meta charset=utf-8>
<title>:focus applies before scrolling into view</title>
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1775451">
<link href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
<link href="https://mozilla.com" title="Mozilla">
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<style>
body {
margin: 0;
}
.padding {
height: 200vh;
background-color: purple;
}
#focusable {
z-index: 0;
position: absolute;
top: 0;
left: 0;
}
#focusable:focus {
z-index: 1;
left: auto;
top: auto;
}
</style>
<div class="padding"></div>
<div id="focusable" tabindex=0>I am focusable</div>
<div class="padding"></div>
<script>
onload = function() {
async_test(function(t) {
let focusable = document.getElementById("focusable");
assert_equals(getComputedStyle(focusable).zIndex, "0", "focusable style is correct");
window.addEventListener("scroll", t.step_func_done(function(e) {
assert_equals(document.activeElement, focusable, "activeElement should be set");
assert_true(focusable.matches(":focus"), ":focus should match by the time we scroll");
assert_equals(getComputedStyle(focusable).zIndex, "1", "focusable style is correct");
}), { once: true });
focusable.focus();
});
};
</script>