Bug 1530931: Correctly handle retrieving a container accessible for a shadow root. r=eeejay

This can happen, for example, when GetAccessibleOrContainer is called within SelectionManager::ProcessSelectionChanged due to focusing a direct child of a shadow root.
In this case, the common ancestor is the shadow root itself.
Previously, we returned null in this case because GetFlattenedTreeParent doesn't work on the shadow root itself.
Now, we check if the given node is the shadow root, and if so, we use the shadow host instead.

This prevents the "We must reach document accessible implementing text interface!" assertion in SelectionManager::ProcessSelectionChanged when a direct child of a shadow root gets focus.

Differential Revision: https://phabricator.services.mozilla.com/D21349

--HG--
extra : moz-landing-system : lando
This commit is contained in:
James Teh 2019-03-20 15:19:44 +00:00
Родитель bdf43f53c2
Коммит d4b9670c0d
1 изменённых файлов: 21 добавлений и 3 удалений

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

@ -1130,10 +1130,28 @@ Accessible* DocAccessible::GetAccessibleByUniqueIDInSubtree(void* aUniqueID) {
Accessible* DocAccessible::GetAccessibleOrContainer(nsINode* aNode,
int aARIAHiddenFlag) const {
if (!aNode || !aNode->GetComposedDoc()) return nullptr;
if (!aNode || !aNode->GetComposedDoc()) {
return nullptr;
}
for (nsINode* currNode = aNode; currNode;
currNode = currNode->GetFlattenedTreeParentNode()) {
nsINode* currNode = nullptr;
if (aNode->IsShadowRoot()) {
// This can happen, for example, when called within
// SelectionManager::ProcessSelectionChanged due to focusing a direct
// child of a shadow root.
// GetFlattenedTreeParent works on children of a shadow root, but not the
// shadow root itself.
const dom::ShadowRoot* shadowRoot = dom::ShadowRoot::FromNode(aNode);
currNode = shadowRoot->GetHost();
if (!currNode) {
return nullptr;
}
} else {
currNode = aNode;
}
MOZ_ASSERT(currNode);
for (; currNode; currNode = currNode->GetFlattenedTreeParentNode()) {
// No container if is inside of aria-hidden subtree.
if (aARIAHiddenFlag == eNoContainerIfARIAHidden && currNode->IsElement() &&
aria::HasDefinedARIAHidden(currNode->AsElement())) {