Bug 1800755: Don't send selection changes for defunct Accessibles. r=morgan

When a selection event is dropped due to coalescence, we still include the impacted Accessible in the SelectedAccessiblesChanged notification we send to the parent process.
Although we skip events with defunct targets, we weren't skipping defunct items referenced by selection events.
This meant that if an Accessible was selected/unselected but was shut down before we sent SelectedAccessiblesChanged, the notification would include a dead Accessible.
This was causing an assertion in the parent process.
To fix this, we now ignore defunct items in selection events.

Differential Revision: https://phabricator.services.mozilla.com/D162551
This commit is contained in:
James Teh 2022-11-22 02:24:28 +00:00
Родитель f6e656ccfe
Коммит da36b6436a
2 изменённых файлов: 40 добавлений и 8 удалений

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

@ -357,14 +357,16 @@ void EventQueue::ProcessEventQueue() {
// and manually push their new state to the parent process.
AccSelChangeEvent* selChangeEvent = downcast_accEvent(event);
LocalAccessible* item = selChangeEvent->mItem;
uint64_t itemID =
item->IsDoc() ? 0 : reinterpret_cast<uint64_t>(item->UniqueID());
bool selected =
selChangeEvent->mSelChangeType == AccSelChangeEvent::eSelectionAdd;
if (selected) {
selectedIDs.AppendElement(itemID);
} else {
unselectedIDs.AppendElement(itemID);
if (!item->IsDefunct()) {
uint64_t itemID =
item->IsDoc() ? 0 : reinterpret_cast<uint64_t>(item->UniqueID());
bool selected = selChangeEvent->mSelChangeType ==
AccSelChangeEvent::eSelectionAdd;
if (selected) {
selectedIDs.AppendElement(itemID);
} else {
unselectedIDs.AppendElement(itemID);
}
}
}
}

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

@ -297,3 +297,33 @@ addAccessibleTask(
remoteIframe: false,
}
);
/**
* Ensure that we don't assert when dealing with defunct items in selection
* events dropped due to coalescence (bug 1800755).
*/
addAccessibleTask(
`
<form id="form">
<select id="select">
<option>
<optgroup id="optgroup">
<option>
</optgroup>
</select>
</form>
`,
async function(browser, docAcc) {
let selected = waitForEvent(EVENT_SELECTION_WITHIN, "select");
await invokeContentTask(browser, [], () => {
const form = content.document.getElementById("form");
const select = content.document.getElementById("select");
const optgroup = content.document.getElementById("optgroup");
form.reset();
select.selectedIndex = 1;
select.add(optgroup);
select.item(0).remove();
});
await selected;
}
);