15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2008 Apple Inc. All rights reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met:
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1.  Redistributions of source code must retain the above copyright
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     notice, this list of conditions and the following disclaimer.
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2.  Redistributions in binary form must reproduce the above copyright
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     notice, this list of conditions and the following disclaimer in the
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     documentation and/or other materials provided with the distribution.
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     its contributors may be used to endorse or promote products derived
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     from this software without specific prior written permission.
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
30bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "core/accessibility/AXTableColumn.h"
315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/accessibility/AXObjectCache.h"
33bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "core/accessibility/AXTableCell.h"
3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderTableCell.h"
355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore {
3802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace HTMLNames;
405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
41bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)AXTableColumn::AXTableColumn()
425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
45bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)AXTableColumn::~AXTableColumn()
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch}
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
49bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)PassRefPtr<AXTableColumn> AXTableColumn::create()
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
51bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    return adoptRef(new AXTableColumn());
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
54bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)void AXTableColumn::setParent(AXObject* parent)
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
56bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    AXMockObject::setParent(parent);
5702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    clearChildren();
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
61bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)LayoutRect AXTableColumn::elementRect() const
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // this will be filled in when addChildren is called
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return m_columnRect;
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
67bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)AXObject* AXTableColumn::headerObject()
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_parent)
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
7102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderObject* renderer = m_parent->renderer();
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!renderer)
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
7502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
76bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    if (!m_parent->isAXTable())
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
7802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
79bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    AXTable* parentTable = toAXTable(m_parent);
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (parentTable->isAriaTable()) {
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        AccessibilityChildrenVector rowChildren = children();
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        unsigned childrenCount = rowChildren.size();
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (unsigned i = 0; i < childrenCount; ++i) {
84bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)            AXObject* cell = rowChildren[i].get();
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (cell->ariaRoleAttribute() == ColumnHeaderRole)
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return cell;
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
8802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!renderer->isTable())
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
9402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderTable* table = toRenderTable(renderer);
9602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
97bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    AXObject* headerObject = 0;
9802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // try the <thead> section first. this doesn't require th tags
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    headerObject = headerObjectForSection(table->header(), false);
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (headerObject)
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return headerObject;
10402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // now try for <th> tags in the first body
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    headerObject = headerObjectForSection(table->firstBody(), true);
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return headerObject;
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
111bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)AXObject* AXTableColumn::headerObjectForSection(RenderTableSection* section, bool thTagRequired)
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!section)
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
11502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned numCols = section->numColumns();
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_columnIndex >= numCols)
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
11902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!section->numRows())
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
12202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderTableCell* cell = 0;
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // also account for cells that have a span
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (int testCol = m_columnIndex; testCol >= 0; --testCol) {
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RenderTableCell* testCell = section->primaryCellAt(0, testCol);
1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!testCell)
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
12902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
13002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch        // we've reached a cell that doesn't even overlap our column
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // it can't be our header
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if ((testCell->col() + (testCell->colSpan()-1)) < m_columnIndex)
1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
13402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Node* node = testCell->node();
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!node)
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
13802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (thTagRequired && !node->hasTagName(thTag))
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
14102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        cell = testCell;
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
14402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!cell)
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return axObjectCache()->getOrCreate(cell);
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
15002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
151bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)bool AXTableColumn::computeAccessibilityIsIgnored() const
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_parent)
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return true;
15553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return m_parent->accessibilityIsIgnored();
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
15802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
159bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)void AXTableColumn::addChildren()
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
16102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    ASSERT(!m_haveChildren);
16202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_haveChildren = true;
164bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    if (!m_parent || !m_parent->isAXTable())
1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
16602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
167bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    AXTable* parentTable = toAXTable(m_parent);
1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int numRows = parentTable->rowCount();
16902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (int i = 0; i < numRows; i++) {
171bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        AXTableCell* cell = parentTable->cellForColumnAndRow(m_columnIndex, i);
1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!cell)
1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
17402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // make sure the last one isn't the same as this one (rowspan cells)
1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (m_children.size() > 0 && m_children.last() == cell)
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
17802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_children.append(cell);
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_columnRect.unite(cell->elementRect());
1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
18302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace WebCore
185