AccessibilityList.cpp [plain text]
#include "config.h"
#include "AccessibilityList.h"
#include "AXObjectCache.h"
#include "HTMLElement.h"
#include "HTMLNames.h"
#include "HTMLParserIdioms.h"
#include "PseudoElement.h"
#include "RenderListItem.h"
#include "RenderObject.h"
namespace WebCore {
using namespace HTMLNames;
AccessibilityList::AccessibilityList(RenderObject* renderer)
: AccessibilityRenderObject(renderer)
{
}
AccessibilityList::~AccessibilityList() = default;
Ref<AccessibilityList> AccessibilityList::create(RenderObject* renderer)
{
return adoptRef(*new AccessibilityList(renderer));
}
bool AccessibilityList::computeAccessibilityIsIgnored() const
{
return accessibilityIsIgnoredByDefault();
}
bool AccessibilityList::isUnorderedList() const
{
if (!m_renderer)
return false;
Node* node = m_renderer->node();
if (ariaRoleAttribute() == AccessibilityRole::List)
return true;
return node && node->hasTagName(ulTag);
}
bool AccessibilityList::isOrderedList() const
{
if (!m_renderer)
return false;
if (ariaRoleAttribute() == AccessibilityRole::Directory)
return true;
Node* node = m_renderer->node();
return node && node->hasTagName(olTag);
}
bool AccessibilityList::isDescriptionList() const
{
if (!m_renderer)
return false;
Node* node = m_renderer->node();
return node && node->hasTagName(dlTag);
}
bool AccessibilityList::childHasPseudoVisibleListItemMarkers(RenderObject* listItem)
{
Element* listItemElement = downcast<Element>(listItem->node());
if (!listItemElement || !listItemElement->beforePseudoElement())
return false;
AccessibilityObject* axObj = axObjectCache()->getOrCreate(listItemElement->beforePseudoElement()->renderer());
if (!axObj)
return false;
if (!axObj->accessibilityIsIgnored())
return true;
for (const auto& child : axObj->children()) {
if (!child->accessibilityIsIgnored())
return true;
}
#if USE(ATK)
String text = axObj->textUnderElement();
return !text.isEmpty() && !text.isAllSpecialCharacters<isHTMLSpace>();
#else
return false;
#endif
}
AccessibilityRole AccessibilityList::determineAccessibilityRole()
{
m_ariaRole = determineAriaRoleAttribute();
if (ariaRoleAttribute() == AccessibilityRole::Directory)
return AccessibilityRole::List;
AccessibilityRole role = AccessibilityRole::List;
m_role = role;
unsigned listItemCount = 0;
bool hasVisibleMarkers = false;
const auto& children = this->children();
if (isDescriptionList() && children.size())
return AccessibilityRole::DescriptionList;
for (const auto& child : children) {
if (child->ariaRoleAttribute() == AccessibilityRole::ListItem)
listItemCount++;
else if (child->roleValue() == AccessibilityRole::ListItem) {
RenderObject* listItem = child->renderer();
if (!listItem)
continue;
if (listItem->isListItem()) {
if (!hasVisibleMarkers && (listItem->style().listStyleType() != ListStyleType::None || listItem->style().listStyleImage() || childHasPseudoVisibleListItemMarkers(listItem)))
hasVisibleMarkers = true;
listItemCount++;
} else if (listItem->node() && listItem->node()->hasTagName(liTag)) {
if (m_ariaRole == AccessibilityRole::List)
listItemCount++;
if (childHasPseudoVisibleListItemMarkers(listItem)) {
hasVisibleMarkers = true;
listItemCount++;
}
}
}
}
if (ariaRoleAttribute() != AccessibilityRole::Unknown) {
if (!listItemCount)
role = AccessibilityRole::ApplicationGroup;
} else if (!hasVisibleMarkers)
role = AccessibilityRole::Group;
return role;
}
AccessibilityRole AccessibilityList::roleValue() const
{
ASSERT(m_role != AccessibilityRole::Unknown);
return m_role;
}
}