Home | History | Annotate | Download | only in accessibility
      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