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/AXTableCell.h" 315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/accessibility/AXObjectCache.h" 3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderTableCell.h" 345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 36c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 3702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace HTMLNames; 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 40bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)AXTableCell::AXTableCell(RenderObject* renderer) 41bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) : AXRenderObject(renderer) 425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 45bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)AXTableCell::~AXTableCell() 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 49bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)PassRefPtr<AXTableCell> AXTableCell::create(RenderObject* renderer) 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 51bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) return adoptRef(new AXTableCell(renderer)); 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 54bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)bool AXTableCell::computeAccessibilityIsIgnored() const 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 56bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) AXObjectInclusion decision = defaultObjectInclusion(); 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (decision == IncludeObject) 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (decision == IgnoreObject) 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 6102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!isTableCell()) 63bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) return AXRenderObject::computeAccessibilityIsIgnored(); 6402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 68bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)AXObject* AXTableCell::parentTable() const 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_renderer || !m_renderer->isTableCell()) 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 72926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 73926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // If the document no longer exists, we might not have an axObjectCache. 74926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!axObjectCache()) 75926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return 0; 7602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 7702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch // Do not use getOrCreate. parentTable() can be called while the render tree is being modified 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // by javascript, and creating a table element may try to access the render tree while in a bad state. 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // By using only get() implies that the AXTable must be created before AXTableCells. This should 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // always be the case when AT clients access a table. 8102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch // https://bugs.webkit.org/show_bug.cgi?id=42652 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return axObjectCache()->get(toRenderTableCell(m_renderer)->table()); 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 8402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 85bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)bool AXTableCell::isTableCell() const 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 87bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) AXObject* parent = parentObjectUnignored(); 88926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!parent || !parent->isTableRow()) 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 9002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 9302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 94bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)AccessibilityRole AXTableCell::determineAccessibilityRole() 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!isTableCell()) 97bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) return AXRenderObject::determineAccessibilityRole(); 9802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return CellRole; 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 10102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 102bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)void AXTableCell::rowIndexRange(pair<unsigned, unsigned>& rowRange) 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_renderer || !m_renderer->isTableCell()) 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 10602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderTableCell* renderCell = toRenderTableCell(m_renderer); 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rowRange.first = renderCell->rowIndex(); 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rowRange.second = renderCell->rowSpan(); 11002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // since our table might have multiple sections, we have to offset our row appropriately 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderTableSection* section = renderCell->section(); 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderTable* table = renderCell->table(); 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!table || !section) 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch RenderTableSection* tableSection = table->topSection(); 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned rowOffset = 0; 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (tableSection) { 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (tableSection == section) 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rowOffset += tableSection->numRows(); 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) tableSection = table->sectionBelow(tableSection, SkipEmptySections); 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rowRange.first += rowOffset; 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 12802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 129bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)void AXTableCell::columnIndexRange(pair<unsigned, unsigned>& columnRange) 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_renderer || !m_renderer->isTableCell()) 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 13302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderTableCell* renderCell = toRenderTableCell(m_renderer); 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) columnRange.first = renderCell->col(); 13602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch columnRange.second = renderCell->colSpan(); 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 13802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 139bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)AXObject* AXTableCell::titleUIElement() const 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Try to find if the first cell in this row is a <th>. If it is, 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // then it can act as the title ui element. (This is only in the 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // case when the table is not appearing as an AXTable.) 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isTableCell() || !m_renderer || !m_renderer->isTableCell()) 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Table cells that are th cannot have title ui elements, since by definition 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // they are title ui elements 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Node* node = m_renderer->node(); 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (node && node->hasTagName(thTag)) 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 15202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderTableCell* renderCell = toRenderTableCell(m_renderer); 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If this cell is in the first column, there is no need to continue. 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int col = renderCell->col(); 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!col) 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int row = renderCell->rowIndex(); 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderTableSection* section = renderCell->section(); 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!section) 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 16502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderTableCell* headerCell = section->primaryCellAt(row, 0); 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!headerCell || headerCell == renderCell) 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Node* cellElement = headerCell->node(); 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!cellElement || !cellElement->hasTagName(thTag)) 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 17302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return axObjectCache()->getOrCreate(headerCell); 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 17602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 177c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink 178