AccessibilityTableColumn.cpp [plain text]
#include "config.h"
#include "AccessibilityTableColumn.h"
#include "AXObjectCache.h"
#include "AccessibilityTableCell.h"
#include "HTMLElement.h"
#include "HTMLNames.h"
#include "RenderTable.h"
#include "RenderTableCell.h"
#include "RenderTableSection.h"
namespace WebCore {
using namespace HTMLNames;
AccessibilityTableColumn::AccessibilityTableColumn()
{
}
AccessibilityTableColumn::~AccessibilityTableColumn()
{
}
Ref<AccessibilityTableColumn> AccessibilityTableColumn::create()
{
return adoptRef(*new AccessibilityTableColumn());
}
void AccessibilityTableColumn::setParent(AccessibilityObject* parent)
{
AccessibilityMockObject::setParent(parent);
clearChildren();
}
LayoutRect AccessibilityTableColumn::elementRect() const
{
return m_columnRect;
}
AccessibilityObject* AccessibilityTableColumn::headerObject()
{
if (!m_parent)
return nullptr;
RenderObject* renderer = m_parent->renderer();
if (!renderer)
return nullptr;
if (!is<AccessibilityTable>(*m_parent))
return nullptr;
auto& parentTable = downcast<AccessibilityTable>(*m_parent);
if (!parentTable.isExposableThroughAccessibility())
return nullptr;
if (parentTable.isAriaTable()) {
for (const auto& cell : children()) {
if (cell->ariaRoleAttribute() == ColumnHeaderRole)
return cell.get();
}
return nullptr;
}
if (!is<RenderTable>(*renderer))
return nullptr;
RenderTable& table = downcast<RenderTable>(*renderer);
if (auto* headerObject = headerObjectForSection(table.header(), false))
return headerObject;
RenderTableSection* bodySection = table.firstBody();
while (bodySection && bodySection->isAnonymous())
bodySection = table.sectionBelow(bodySection, SkipEmptySections);
return headerObjectForSection(bodySection, true);
}
AccessibilityObject* AccessibilityTableColumn::headerObjectForSection(RenderTableSection* section, bool thTagRequired)
{
if (!section)
return nullptr;
unsigned numCols = section->numColumns();
if (m_columnIndex >= numCols)
return nullptr;
if (!section->numRows())
return nullptr;
RenderTableCell* cell = nullptr;
for (int testCol = m_columnIndex; testCol >= 0; --testCol) {
unsigned rowCount = section->numRows();
for (unsigned testRow = 0; testRow < rowCount; testRow++) {
RenderTableCell* testCell = section->primaryCellAt(testRow, testCol);
if (!testCell)
continue;
if ((testCell->col() + (testCell->colSpan()-1)) < m_columnIndex)
break;
if (!testCell->element())
continue;
if (thTagRequired && !testCell->element()->hasTagName(thTag))
break;
cell = testCell;
break;
}
}
if (!cell)
return nullptr;
return axObjectCache()->getOrCreate(cell);
}
bool AccessibilityTableColumn::computeAccessibilityIsIgnored() const
{
if (!m_parent)
return true;
#if PLATFORM(IOS) || PLATFORM(GTK) || PLATFORM(EFL)
return true;
#endif
return m_parent->accessibilityIsIgnored();
}
void AccessibilityTableColumn::addChildren()
{
ASSERT(!m_haveChildren);
m_haveChildren = true;
if (!is<AccessibilityTable>(m_parent))
return;
auto& parentTable = downcast<AccessibilityTable>(*m_parent);
if (!parentTable.isExposableThroughAccessibility())
return;
int numRows = parentTable.rowCount();
for (int i = 0; i < numRows; ++i) {
AccessibilityTableCell* cell = parentTable.cellForColumnAndRow(m_columnIndex, i);
if (!cell)
continue;
if (m_children.size() > 0 && m_children.last() == cell)
continue;
m_children.append(cell);
m_columnRect.unite(cell->elementRect());
}
}
}