зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1722621: Fix detection of autocomplete popups in XULListboxAccessible after recent DOM changes. r=morgan
Previously, we used GetFlattenedTreeParent from the list box to find the autocomplete popup. After bug 1708735, this now returns a slot instead of the panel. We now use GetParentElement instead, which works as expected and is consistent with other code in this class anyway. I also added a new test so this doesn't regress yet again. We already have test_focus_autocomplete.xhtml which is supposed to test this, but that test is broken, was thus disabled and is complicated enough that I don't think we're going to fix it any time soon, if ever. The new test was triggering an assertion on Windows when trying to handle a caret event, so HyperTextAccessible::GetCaretRect had to be tweaked slightly to fix this. Differential Revision: https://phabricator.services.mozilla.com/D121163
This commit is contained in:
Родитель
2f5b54bbea
Коммит
f2a0bfe104
|
@ -1818,8 +1818,16 @@ LayoutDeviceIntRect HyperTextAccessible::GetCaretRect(nsIWidget** aWidget) {
|
|||
// the character. This is important for font size transitions, and is
|
||||
// necessary because the Gecko caret uses the previous character's size as
|
||||
// the user moves forward in the text by character.
|
||||
int32_t caretOffset = CaretOffset();
|
||||
if (NS_WARN_IF(caretOffset == -1)) {
|
||||
// The caret offset will be -1 if this Accessible isn't focused. Note that
|
||||
// the DOM node contaning the caret might be focused, but the Accessible
|
||||
// might not be; e.g. due to an autocomplete popup suggestion having a11y
|
||||
// focus.
|
||||
return LayoutDeviceIntRect();
|
||||
}
|
||||
nsIntRect charRect = CharBounds(
|
||||
CaretOffset(), nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE);
|
||||
caretOffset, nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE);
|
||||
if (!charRect.IsEmpty()) {
|
||||
caretRect.SetTopEdge(charRect.Y());
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ support-files =
|
|||
[test_flush.html]
|
||||
[test_focusable_statechange.html]
|
||||
[test_focus_aria_activedescendant.html]
|
||||
[test_focus_autocomplete.html]
|
||||
[test_focus_autocomplete.xhtml]
|
||||
# Disabled on Linux and Windows due to frequent failures - bug 695019, bug 890795
|
||||
skip-if = os == 'win' || os == 'linux'
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
<!doctype html>
|
||||
|
||||
<head>
|
||||
<title>Form Autocomplete Tests</title>
|
||||
|
||||
<link rel="stylesheet"
|
||||
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
|
||||
<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
|
||||
|
||||
<script src="../common.js"></script>
|
||||
<script src="../promisified-events.js"></script>
|
||||
<script src="../role.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
const { TestUtils } = ChromeUtils.import(
|
||||
"resource://testing-common/TestUtils.jsm");
|
||||
|
||||
async function waitForFocusOnOptionWithname(name) {
|
||||
let event = await waitForEvent(
|
||||
EVENT_FOCUS,
|
||||
evt => evt.accessible.role == ROLE_COMBOBOX_OPTION
|
||||
);
|
||||
if (!event.accessible.name) {
|
||||
// Sometimes, the name is null for a very short time after the focus
|
||||
// event.
|
||||
await waitForEvent(EVENT_NAME_CHANGE, event.accessible);
|
||||
}
|
||||
is(event.accessible.name, name, "Got focus on option with name " + name);
|
||||
}
|
||||
|
||||
async function doTests() {
|
||||
const input = getNode("input");
|
||||
info("Focusing the input");
|
||||
let focused = waitForEvent(EVENT_FOCUS, input);
|
||||
input.focus();
|
||||
await focused;
|
||||
|
||||
let shown = waitForEvent(EVENT_SHOW, event =>
|
||||
event.accessible.role == ROLE_GROUPING &&
|
||||
event.accessible.firstChild.role == ROLE_COMBOBOX_LIST);
|
||||
info("Pressing ArrowDown to open the popup");
|
||||
synthesizeKey("KEY_ArrowDown");
|
||||
await shown;
|
||||
// The popup still doesn't seem to be ready even once it's fired an a11y
|
||||
// show event!
|
||||
const controller = Cc["@mozilla.org/autocomplete/controller;1"].
|
||||
getService(Ci.nsIAutoCompleteController);
|
||||
info("Waiting for popup to be fully open and ready");
|
||||
await TestUtils.waitForCondition(() => controller.input.popupOpen);
|
||||
|
||||
focused = waitForFocusOnOptionWithname("a");
|
||||
info("Pressing ArrowDown to focus first item");
|
||||
synthesizeKey("KEY_ArrowDown");
|
||||
await focused;
|
||||
|
||||
focused = waitForFocusOnOptionWithname("b");
|
||||
info("Pressing ArrowDown to focus the second item");
|
||||
synthesizeKey("KEY_ArrowDown");
|
||||
await focused;
|
||||
|
||||
focused = waitForEvent(EVENT_FOCUS, input);
|
||||
info("Pressing enter to select the second item");
|
||||
synthesizeKey("KEY_Enter");
|
||||
await focused;
|
||||
is(input.value, "b", "input value filled with second item");
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<input id="input" list="list">
|
||||
<datalist id="list">
|
||||
<option id="a" value="a">
|
||||
<option id="b" value="b">
|
||||
</datalist>
|
||||
</body>
|
||||
</html>
|
|
@ -67,10 +67,10 @@ bool XULColumnItemAccessible::DoAction(uint8_t aIndex) const {
|
|||
XULListboxAccessible::XULListboxAccessible(nsIContent* aContent,
|
||||
DocAccessible* aDoc)
|
||||
: XULSelectControlAccessible(aContent, aDoc) {
|
||||
nsIContent* parentContent = mContent->GetFlattenedTreeParent();
|
||||
if (parentContent) {
|
||||
dom::Element* parentEl = mContent->GetParentElement();
|
||||
if (parentEl) {
|
||||
nsCOMPtr<nsIAutoCompletePopup> autoCompletePopupElm =
|
||||
parentContent->AsElement()->AsAutoCompletePopup();
|
||||
parentEl->AsAutoCompletePopup();
|
||||
if (autoCompletePopupElm) mGenericTypes |= eAutoCompletePopup;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче