Bug 1691813 - Use TreeWalker to find accessible descendants. r=Jamie

This speeds up reflows on pages like view source that have a single
giant container. But this maybe slows down other cases? I'm not 100%
sure.

Differential Revision: https://phabricator.services.mozilla.com/D117948
This commit is contained in:
Eitan Isaacson 2021-06-16 16:42:47 +00:00
Родитель a6cc0d3961
Коммит ac98d85fc6
4 изменённых файлов: 47 добавлений и 14 удалений

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

@ -1377,20 +1377,10 @@ LocalAccessible* DocAccessible::GetAccessibleOrDescendant(
return const_cast<DocAccessible*>(this);
}
acc = GetContainerAccessible(aNode);
if (acc) {
// We access the `mChildren` array directly so that we don't access
// lazily created children in places like `XULTreeAccessible` and
// `XULTreeGridAccessible`.
uint32_t childCnt = acc->mChildren.Length();
for (uint32_t idx = 0; idx < childCnt; idx++) {
LocalAccessible* child = acc->mChildren.ElementAt(idx);
for (nsIContent* elm = child->GetContent();
elm && elm != acc->GetContent();
elm = elm->GetFlattenedTreeParent()) {
if (elm == aNode) return child;
}
}
if (acc = GetContainerAccessible(aNode)) {
TreeWalker walker(acc, aNode->AsContent(),
TreeWalker::eWalkCache | TreeWalker::eScoped);
return walker.Next();
}
return nullptr;

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

@ -33,6 +33,8 @@ interface nsIAccessibilityService : nsISupports
*/
nsIAccessible getAccessibleFor(in Node aNode);
nsIAccessible getAccessibleDescendantFor(in Node aNode);
/**
* Returns accessible role as a string.
*

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

@ -16,6 +16,10 @@
src="../attributes.js"></script>
<script type="application/javascript">
function getAccessibleDescendantFor(selector) {
return gAccService.getAccessibleDescendantFor(document.querySelector(selector));
}
function doTest() {
// All below test cases are wrapped in a div which always gets rendered.
// c1 through c10 are the containers, the actual test cases are inside.
@ -270,6 +274,16 @@ function doTest() {
};
testAccessibleTree("c15", tree);
// Test getting descendants of unrendered nodes.
ok(!getAccessibleDescendantFor("#c16 > span"),
"Span has no accessible children");
ok(!getAccessibleDescendantFor("#c17 > span"),
"Span with relocated child should return null");
is(getAccessibleDescendantFor("#c12 > div").role, ROLE_PARAGRAPH,
"Descendant has correct role")
SimpleTest.finish();
}
@ -329,5 +343,9 @@ addA11yLoadEvent(doTest);
<!-- Inner div should be rendered because previous sibling is text. -->
<div id="c15">l1<div></div>l2</div>
<div id="c16">hello <span></span> world</div>
<div id="c17"><div aria-owns="c"></div>hello <span><button id="c">b</button></span> world</div>
</body>
</html>

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

@ -127,6 +127,29 @@ xpcAccessibilityService::GetAccessibleFor(nsINode* aNode,
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibilityService::GetAccessibleDescendantFor(
nsINode* aNode, nsIAccessible** aAccessible) {
NS_ENSURE_ARG_POINTER(aAccessible);
*aAccessible = nullptr;
if (!aNode) {
return NS_OK;
}
nsAccessibilityService* accService = GetAccService();
if (!accService) {
return NS_ERROR_SERVICE_NOT_AVAILABLE;
}
DocAccessible* document = accService->GetDocAccessible(aNode->OwnerDoc());
if (document) {
NS_IF_ADDREF(*aAccessible =
ToXPC(document->GetAccessibleOrDescendant(aNode)));
}
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibilityService::GetStringRole(uint32_t aRole, nsAString& aString) {
nsAccessibilityService* accService = GetAccService();