зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1811129 - Implement the new dialog initial focus algorithm r=emilio
The main changes of the new algorithm are * Make the dialog focusing steps look at sequentially focusable elements instead of any focusable element. * Make the dialog element itself get focus if it has the autofocus attribute set. * Make the dialog element itself get focus as a fallback instead of focus being "reset" to the body element. Spec PR (merged): https://github.com/whatwg/html/pull/8199 Differential Revision: https://phabricator.services.mozilla.com/D181263
This commit is contained in:
Родитель
f34cf84e56
Коммит
0a3d5faf4b
|
@ -1036,9 +1036,14 @@ Element* nsIContent::GetFocusDelegate(bool aWithMouse,
|
||||||
whereToLook = root;
|
whereToLook = root;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto IsFocusable = [&](Element* aElement) {
|
auto IsFocusable = [&](Element* aElement) -> nsIFrame::Focusable {
|
||||||
nsIFrame* frame = aElement->GetPrimaryFrame();
|
nsIFrame* frame = aElement->GetPrimaryFrame();
|
||||||
return frame && frame->IsFocusable(aWithMouse);
|
|
||||||
|
if (!frame) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return frame->IsFocusable(aWithMouse);
|
||||||
};
|
};
|
||||||
|
|
||||||
Element* potentialFocus = nullptr;
|
Element* potentialFocus = nullptr;
|
||||||
|
@ -1059,11 +1064,21 @@ Element* nsIContent::GetFocusDelegate(bool aWithMouse,
|
||||||
// Found an autofocus candidate.
|
// Found an autofocus candidate.
|
||||||
return el;
|
return el;
|
||||||
}
|
}
|
||||||
} else if (!potentialFocus && IsFocusable(el)) {
|
} else if (!potentialFocus) {
|
||||||
|
if (nsIFrame::Focusable focusable = IsFocusable(el)) {
|
||||||
|
if (IsHTMLElement(nsGkAtoms::dialog)) {
|
||||||
|
if (focusable.mTabIndex >= 0) {
|
||||||
|
// If focusTarget is a dialog element and descendant is sequentially
|
||||||
|
// focusable, then set focusableArea to descendant.
|
||||||
|
potentialFocus = el;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
// This element could be the one if we can't find an
|
// This element could be the one if we can't find an
|
||||||
// autofocus candidate which has the precedence.
|
// autofocus candidate which has the precedence.
|
||||||
potentialFocus = el;
|
potentialFocus = el;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!autofocus && potentialFocus) {
|
if (!autofocus && potentialFocus) {
|
||||||
// Nothing else to do, we are not looking for more focusable elements
|
// Nothing else to do, we are not looking for more focusable elements
|
||||||
|
|
|
@ -140,7 +140,9 @@ void HTMLDialogElement::FocusDialog() {
|
||||||
doc->FlushPendingNotifications(FlushType::Frames);
|
doc->FlushPendingNotifications(FlushType::Frames);
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<Element> control = GetFocusDelegate(false /* aWithMouse */);
|
RefPtr<Element> control = HasAttr(nsGkAtoms::autofocus)
|
||||||
|
? this
|
||||||
|
: GetFocusDelegate(false /* aWithMouse */);
|
||||||
|
|
||||||
// If there isn't one of those either, then let control be subject.
|
// If there isn't one of those either, then let control be subject.
|
||||||
if (!control) {
|
if (!control) {
|
||||||
|
@ -150,6 +152,8 @@ void HTMLDialogElement::FocusDialog() {
|
||||||
FocusCandidate(*control, IsInTopLayer());
|
FocusCandidate(*control, IsInTopLayer());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t HTMLDialogElement::TabIndexDefault() { return 0; }
|
||||||
|
|
||||||
void HTMLDialogElement::QueueCancelDialog() {
|
void HTMLDialogElement::QueueCancelDialog() {
|
||||||
// queues an element task on the user interaction task source
|
// queues an element task on the user interaction task source
|
||||||
OwnerDoc()
|
OwnerDoc()
|
||||||
|
|
|
@ -47,6 +47,8 @@ class HTMLDialogElement final : public nsGenericHTMLElement {
|
||||||
|
|
||||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY void FocusDialog();
|
MOZ_CAN_RUN_SCRIPT_BOUNDARY void FocusDialog();
|
||||||
|
|
||||||
|
int32_t TabIndexDefault() override;
|
||||||
|
|
||||||
nsString mReturnValue;
|
nsString mReturnValue;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
[content-visibility-with-top-layer-006.html]
|
|
||||||
expected:
|
|
||||||
if (os == "android") and fission: [OK, TIMEOUT]
|
|
||||||
[CSS Content Visibility: offscreen c-v auto content is relevant when in top layer]
|
|
||||||
expected: FAIL
|
|
|
@ -1,12 +0,0 @@
|
||||||
[child-sequential-focus.html]
|
|
||||||
[dialog element with autofocus should get initial focus.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Only keyboard-focusable elements should get dialog initial focus.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Only keyboard-focusable elements should get dialog initial focus including in subtrees.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Only keyboard-focusable elements should get dialog initial focus including in nested buttons.]
|
|
||||||
expected: FAIL
|
|
|
@ -1,20 +0,0 @@
|
||||||
[dialog-focus-shadow.html]
|
|
||||||
expected:
|
|
||||||
if (os == "android") and fission: [OK, TIMEOUT]
|
|
||||||
[show: No autofocus, no delegatesFocus, no siblings]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[showModal: No autofocus, no delegatesFocus, no siblings]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[show: Autofocus on shadow host, no delegatesFocus, no siblings]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[showModal: Autofocus on shadow host, no delegatesFocus, no siblings]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[show: Autofocus inside shadow tree, no delegatesFocus, no siblings]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[showModal: Autofocus inside shadow tree, no delegatesFocus, no siblings]
|
|
||||||
expected: FAIL
|
|
|
@ -1,5 +0,0 @@
|
||||||
[dialog-showModal.html]
|
|
||||||
expected:
|
|
||||||
if (os == "android") and fission: [OK, TIMEOUT]
|
|
||||||
[opening dialog without focusable children]
|
|
||||||
expected: FAIL
|
|
|
@ -1,5 +0,0 @@
|
||||||
[show-modal-focusing-steps.html]
|
|
||||||
expected:
|
|
||||||
if (os == "android") and fission: [OK, TIMEOUT]
|
|
||||||
[focus when a modal dialog is opened]
|
|
||||||
expected: FAIL
|
|
|
@ -7,6 +7,9 @@ dialog::backdrop {
|
||||||
background-color: rgb(0, 128, 0);
|
background-color: rgb(0, 128, 0);
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
dialog:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
<body>
|
<body>
|
||||||
<dialog>Test passes if you see a green backdrop at half opacity.</dialog>
|
<dialog>Test passes if you see a green backdrop at half opacity.</dialog>
|
||||||
|
|
Загрузка…
Ссылка в новой задаче