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