AccessibilityTree.cpp [plain text]
#include "config.h"
#include "AccessibilityTree.h"
#include "AXObjectCache.h"
#include "AccessibilityTreeItem.h"
#include "Element.h"
#include "HTMLNames.h"
#include <wtf/Deque.h>
namespace WebCore {
using namespace HTMLNames;
AccessibilityTree::AccessibilityTree(RenderObject* renderer)
: AccessibilityRenderObject(renderer)
{
}
AccessibilityTree::~AccessibilityTree() = default;
Ref<AccessibilityTree> AccessibilityTree::create(RenderObject* renderer)
{
return adoptRef(*new AccessibilityTree(renderer));
}
bool AccessibilityTree::computeAccessibilityIsIgnored() const
{
return accessibilityIsIgnoredByDefault();
}
AccessibilityRole AccessibilityTree::determineAccessibilityRole()
{
if ((m_ariaRole = determineAriaRoleAttribute()) != AccessibilityRole::Tree)
return AccessibilityRenderObject::determineAccessibilityRole();
return isTreeValid() ? AccessibilityRole::Tree : AccessibilityRole::Group;
}
bool AccessibilityTree::nodeHasTreeItemChild(Node& node) const
{
for (auto* child = node.firstChild(); child; child = child->nextSibling()) {
if (nodeHasRole(child, "treeitem"))
return true;
}
return false;
}
bool AccessibilityTree::isTreeValid() const
{
Node* node = this->node();
if (!node)
return false;
Deque<Node*> queue;
for (auto* child = node->firstChild(); child; child = child->nextSibling())
queue.append(child);
while (!queue.isEmpty()) {
auto child = queue.takeFirst();
if (!is<Element>(*child))
continue;
if (nodeHasRole(child, "treeitem"))
continue;
if (nodeHasRole(child, "presentation")) {
if (!nodeHasTreeItemChild(*child))
return false;
continue;
}
if (!nodeHasRole(child, "group"))
return false;
for (auto* groupChild = child->firstChild(); groupChild; groupChild = groupChild->nextSibling())
queue.append(groupChild);
}
return true;
}
}