1 /* 2 * Copyright (C) 2009 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 14 * its contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include "config.h" 30 #include "core/accessibility/AccessibilityARIAGrid.h" 31 32 #include "core/accessibility/AXObjectCache.h" 33 #include "core/accessibility/AccessibilityTableColumn.h" 34 #include "core/accessibility/AccessibilityTableRow.h" 35 #include "core/rendering/RenderObject.h" 36 37 using namespace std; 38 39 namespace WebCore { 40 41 AccessibilityARIAGrid::AccessibilityARIAGrid(RenderObject* renderer) 42 : AccessibilityTable(renderer) 43 { 44 } 45 46 AccessibilityARIAGrid::~AccessibilityARIAGrid() 47 { 48 } 49 50 PassRefPtr<AccessibilityARIAGrid> AccessibilityARIAGrid::create(RenderObject* renderer) 51 { 52 return adoptRef(new AccessibilityARIAGrid(renderer)); 53 } 54 55 bool AccessibilityARIAGrid::addTableCellChild(AccessibilityObject* child, HashSet<AccessibilityObject*>& appendedRows, unsigned& columnCount) 56 { 57 if (!child || !child->isTableRow() || child->ariaRoleAttribute() != RowRole) 58 return false; 59 60 AccessibilityTableRow* row = static_cast<AccessibilityTableRow*>(child); 61 if (appendedRows.contains(row)) 62 return false; 63 64 // store the maximum number of columns 65 unsigned rowCellCount = row->children().size(); 66 if (rowCellCount > columnCount) 67 columnCount = rowCellCount; 68 69 row->setRowIndex((int)m_rows.size()); 70 m_rows.append(row); 71 72 // Try adding the row if it's not ignoring accessibility, 73 // otherwise add its children (the cells) as the grid's children. 74 if (!row->accessibilityIsIgnored()) 75 m_children.append(row); 76 else 77 m_children.append(row->children()); 78 79 appendedRows.add(row); 80 return true; 81 } 82 83 void AccessibilityARIAGrid::addChildren() 84 { 85 ASSERT(!m_haveChildren); 86 87 if (!isAccessibilityTable()) { 88 AccessibilityRenderObject::addChildren(); 89 return; 90 } 91 92 m_haveChildren = true; 93 if (!m_renderer) 94 return; 95 96 AXObjectCache* axCache = m_renderer->document()->axObjectCache(); 97 98 // add only rows that are labeled as aria rows 99 HashSet<AccessibilityObject*> appendedRows; 100 unsigned columnCount = 0; 101 for (RefPtr<AccessibilityObject> child = firstChild(); child; child = child->nextSibling()) { 102 103 if (!addTableCellChild(child.get(), appendedRows, columnCount)) { 104 105 // in case the render tree doesn't match the expected ARIA hierarchy, look at the children 106 if (!child->hasChildren()) 107 child->addChildren(); 108 109 // The children of this non-row will contain all non-ignored elements (recursing to find them). 110 // This allows the table to dive arbitrarily deep to find the rows. 111 AccessibilityChildrenVector children = child->children(); 112 size_t length = children.size(); 113 for (size_t i = 0; i < length; ++i) 114 addTableCellChild(children[i].get(), appendedRows, columnCount); 115 } 116 } 117 118 // make the columns based on the number of columns in the first body 119 for (unsigned i = 0; i < columnCount; ++i) { 120 AccessibilityTableColumn* column = static_cast<AccessibilityTableColumn*>(axCache->getOrCreate(ColumnRole)); 121 column->setColumnIndex((int)i); 122 column->setParent(this); 123 m_columns.append(column); 124 if (!column->accessibilityIsIgnored()) 125 m_children.append(column); 126 } 127 128 AccessibilityObject* headerContainerObject = headerContainer(); 129 if (headerContainerObject && !headerContainerObject->accessibilityIsIgnored()) 130 m_children.append(headerContainerObject); 131 } 132 133 } // namespace WebCore 134