diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/accessibility/AccessibilityTableColumn.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebCore/accessibility/AccessibilityTableColumn.cpp')
-rw-r--r-- | Source/WebCore/accessibility/AccessibilityTableColumn.cpp | 137 |
1 files changed, 84 insertions, 53 deletions
diff --git a/Source/WebCore/accessibility/AccessibilityTableColumn.cpp b/Source/WebCore/accessibility/AccessibilityTableColumn.cpp index 6791c3320..1669a6fc0 100644 --- a/Source/WebCore/accessibility/AccessibilityTableColumn.cpp +++ b/Source/WebCore/accessibility/AccessibilityTableColumn.cpp @@ -10,7 +10,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * 3. Neither the name of Apple Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -31,6 +31,8 @@ #include "AXObjectCache.h" #include "AccessibilityTableCell.h" +#include "HTMLCollection.h" +#include "HTMLElement.h" #include "HTMLNames.h" #include "RenderTable.h" #include "RenderTableCell.h" @@ -48,9 +50,9 @@ AccessibilityTableColumn::~AccessibilityTableColumn() { } -PassRefPtr<AccessibilityTableColumn> AccessibilityTableColumn::create() +Ref<AccessibilityTableColumn> AccessibilityTableColumn::create() { - return adoptRef(new AccessibilityTableColumn()); + return adoptRef(*new AccessibilityTableColumn()); } void AccessibilityTableColumn::setParent(AccessibilityObject* parent) @@ -62,88 +64,115 @@ void AccessibilityTableColumn::setParent(AccessibilityObject* parent) LayoutRect AccessibilityTableColumn::elementRect() const { - // this will be filled in when addChildren is called - return m_columnRect; + // This used to be cached during the call to addChildren(), but calling elementRect() + // can invalidate elements, so its better to ask for this on demand. + LayoutRect columnRect; + AccessibilityChildrenVector childrenCopy = m_children; + for (const auto& cell : childrenCopy) + columnRect.unite(cell->elementRect()); + + return columnRect; } AccessibilityObject* AccessibilityTableColumn::headerObject() { if (!m_parent) - return 0; + return nullptr; RenderObject* renderer = m_parent->renderer(); if (!renderer) - return 0; - - if (!m_parent->isAccessibilityTable()) - return 0; + return nullptr; + if (!is<AccessibilityTable>(*m_parent)) + return nullptr; + + auto& parentTable = downcast<AccessibilityTable>(*m_parent); + if (!parentTable.isExposableThroughAccessibility()) + return nullptr; - AccessibilityTable* parentTable = toAccessibilityTable(m_parent); - if (parentTable->isAriaTable()) { + if (parentTable.isAriaTable()) { for (const auto& cell : children()) { if (cell->ariaRoleAttribute() == ColumnHeaderRole) return cell.get(); } - return 0; + return nullptr; } - if (!renderer->isTable()) - return 0; + if (!is<RenderTable>(*renderer)) + return nullptr; - RenderTable* table = toRenderTable(renderer); - - AccessibilityObject* headerObject = 0; - - // try the <thead> section first. this doesn't require th tags - headerObject = headerObjectForSection(table->header(), false); + RenderTable& table = downcast<RenderTable>(*renderer); - if (headerObject) + // try the <thead> section first. this doesn't require th tags + if (auto* headerObject = headerObjectForSection(table.header(), false)) return headerObject; - // now try for <th> tags in the first body - headerObject = headerObjectForSection(table->firstBody(), true); - - return headerObject; + RenderTableSection* bodySection = table.firstBody(); + while (bodySection && bodySection->isAnonymous()) + bodySection = table.sectionBelow(bodySection, SkipEmptySections); + + // now try for <th> tags in the first body. If the first body is + return headerObjectForSection(bodySection, true); } AccessibilityObject* AccessibilityTableColumn::headerObjectForSection(RenderTableSection* section, bool thTagRequired) { if (!section) - return 0; + return nullptr; unsigned numCols = section->numColumns(); if (m_columnIndex >= numCols) - return 0; + return nullptr; if (!section->numRows()) - return 0; + return nullptr; - RenderTableCell* cell = 0; + RenderTableCell* cell = nullptr; // also account for cells that have a span for (int testCol = m_columnIndex; testCol >= 0; --testCol) { - RenderTableCell* testCell = section->primaryCellAt(0, testCol); - if (!testCell) - continue; - // we've reached a cell that doesn't even overlap our column - // it can't be our header - if ((testCell->col() + (testCell->colSpan()-1)) < m_columnIndex) + // Run down the rows in case initial rows are invalid (like when a <caption> is used). + unsigned rowCount = section->numRows(); + for (unsigned testRow = 0; testRow < rowCount; testRow++) { + RenderTableCell* testCell = section->primaryCellAt(testRow, testCol); + // No cell at this index, keep checking more rows and columns. + if (!testCell) + continue; + + // If we've reached a cell that doesn't even overlap our column it can't be the header. + if ((testCell->col() + (testCell->colSpan()-1)) < m_columnIndex) + break; + + Node* testCellNode = testCell->element(); + // If the RenderTableCell doesn't have an element because its anonymous, + // try to see if we can find the original cell element to check if it has a <th> tag. + if (!testCellNode && testCell->isAnonymous()) { + if (Element* parentElement = testCell->parent() ? testCell->parent()->element() : nullptr) { + if (parentElement->hasTagName(trTag) && testCol < static_cast<int>(parentElement->countChildNodes())) + testCellNode = parentElement->traverseToChildAt(testCol); + } + } + + if (!testCellNode) + continue; + + // If th is required, but we found an element that doesn't have a th tag, we can stop looking. + if (thTagRequired && !testCellNode->hasTagName(thTag)) + break; + + cell = testCell; break; - - if (!testCell->element()) - continue; - - if (thTagRequired && !testCell->element()->hasTagName(thTag)) - continue; - - cell = testCell; + } } if (!cell) - return 0; + return nullptr; - return axObjectCache()->getOrCreate(cell); + auto* cellObject = axObjectCache()->getOrCreate(cell); + if (!cellObject || cellObject->accessibilityIsIgnored()) + return nullptr; + + return cellObject; } bool AccessibilityTableColumn::computeAccessibilityIsIgnored() const @@ -151,7 +180,7 @@ bool AccessibilityTableColumn::computeAccessibilityIsIgnored() const if (!m_parent) return true; -#if PLATFORM(IOS) || PLATFORM(GTK) || PLATFORM(EFL) +#if PLATFORM(IOS) || PLATFORM(GTK) return true; #endif @@ -163,14 +192,17 @@ void AccessibilityTableColumn::addChildren() ASSERT(!m_haveChildren); m_haveChildren = true; - if (!m_parent || !m_parent->isAccessibilityTable()) + if (!is<AccessibilityTable>(m_parent)) + return; + + auto& parentTable = downcast<AccessibilityTable>(*m_parent); + if (!parentTable.isExposableThroughAccessibility()) return; - AccessibilityTable* parentTable = toAccessibilityTable(m_parent); - int numRows = parentTable->rowCount(); + int numRows = parentTable.rowCount(); - for (int i = 0; i < numRows; i++) { - AccessibilityTableCell* cell = parentTable->cellForColumnAndRow(m_columnIndex, i); + for (int i = 0; i < numRows; ++i) { + AccessibilityTableCell* cell = parentTable.cellForColumnAndRow(m_columnIndex, i); if (!cell) continue; @@ -179,7 +211,6 @@ void AccessibilityTableColumn::addChildren() continue; m_children.append(cell); - m_columnRect.unite(cell->elementRect()); } } |