Skip to content

Commit

Permalink
AX: AccessibilityRenderObject::computeAccessibilityIsIgnored performs…
Browse files Browse the repository at this point in the history
… an unnecessary ancestry traversal for RenderTexts

https://bugs.webkit.org/show_bug.cgi?id=264861
rdar://problem/118437052

Reviewed by Chris Fleizach and Andres Gonzalez.

AccessibilityRenderObject::computeAccessibilityIsIgnored for RenderTexts traverses the ancestry twice.
We can combine this into one traversal. Also modernizes some nearby code to use dynamicDowncast instead
of is + downcast.

* Source/WebCore/accessibility/AccessibilityRenderObject.cpp:
(WebCore::AccessibilityRenderObject::computeAccessibilityIsIgnored const):

Canonical link: https://commits.webkit.org/270805@main
  • Loading branch information
twilco committed Nov 16, 2023
1 parent ed83f1e commit 02e30d0
Showing 1 changed file with 23 additions and 28 deletions.
51 changes: 23 additions & 28 deletions Source/WebCore/accessibility/AccessibilityRenderObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1101,45 +1101,40 @@ bool AccessibilityRenderObject::computeAccessibilityIsIgnored() const
if (m_renderer->isBR())
return true;

if (is<RenderText>(*m_renderer)) {
// static text beneath MenuItems and MenuButtons are just reported along with the menu item, so it's ignored on an individual level
AXCoreObject* parent = parentObjectUnignored();

// Walking up the parent chain might reset the m_renderer.
if (!m_renderer)
return true;

if (parent && (parent->isMenuItem() || parent->isMenuButton()))
if (WeakPtr renderText = dynamicDowncast<RenderText>(m_renderer.get())) {
// Text elements with no rendered text, or only whitespace should not be part of the AX tree.
if (!renderText->hasRenderedText() || renderText->text().containsOnly<isASCIIWhitespace>())
return true;

auto& renderText = downcast<RenderText>(*m_renderer);
if (!renderText.hasRenderedText())
if (renderText->parent()->isFirstLetter())
return true;

if (renderText.parent()->isFirstLetter())
return true;

// static text beneath TextControls is reported along with the text control text so it's ignored.
for (AccessibilityObject* parent = parentObject(); parent; parent = parent->parentObject()) {
if (parent->roleValue() == AccessibilityRole::TextField)
return true;
}

// Walking up the parent chain might reset the m_renderer.
if (!m_renderer)
return true;

// The alt attribute may be set on a text fragment through CSS, which should be honored.
if (is<RenderTextFragment>(renderText)) {
AccessibilityObjectInclusion altTextInclusion = objectInclusionFromAltText(downcast<RenderTextFragment>(renderText).altText());
if (auto* renderTextFragment = dynamicDowncast<RenderTextFragment>(renderText.get())) {
auto altTextInclusion = objectInclusionFromAltText(renderTextFragment->altText());
if (altTextInclusion == AccessibilityObjectInclusion::IgnoreObject)
return true;
if (altTextInclusion == AccessibilityObjectInclusion::IncludeObject)
return false;
}

// text elements that are just empty whitespace should not be returned
return renderText.text().containsOnly<isASCIIWhitespace>();
bool checkForIgnored = true;
for (RefPtr ancestor = parentObject(); ancestor; ancestor = ancestor->parentObject()) {
// Static text beneath TextControls is reported along with the text control text so it's ignored.
// FIXME: Why does this not check for the other text-control roles (e.g. textarea)?
if (ancestor->roleValue() == AccessibilityRole::TextField)
return true;

if (checkForIgnored && !ancestor->accessibilityIsIgnored()) {
checkForIgnored = false;
// Static text beneath MenuItems and MenuButtons are just reported along with the menu item, so it's ignored on an individual level.
if (ancestor->isMenuItem() || ancestor->isMenuButton())
return true;
}
}

// If iterating the ancestry has caused m_renderer to be destroyed, ignore `this`.
return !renderText;
}

if (isHeading())
Expand Down

0 comments on commit 02e30d0

Please sign in to comment.