accessibilitytable.cpp
来自「linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自Web」· C++ 代码 · 共 490 行 · 第 1/2 页
CPP
490 行
/* * Copyright (C) 2008 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#include "config.h"#include "AccessibilityTable.h"#include "AccessibilityTableCell.h"#include "AccessibilityTableColumn.h"#include "AccessibilityTableHeaderContainer.h"#include "AccessibilityTableRow.h"#include "AXObjectCache.h"#include "HTMLNames.h"#include "HTMLTableElement.h"#include "HTMLTableCaptionElement.h"#include "HTMLTableCellElement.h"#include "RenderObject.h"#include "RenderTable.h"#include "RenderTableCell.h"#include "RenderTableSection.h"using namespace std;namespace WebCore {using namespace HTMLNames;AccessibilityTable::AccessibilityTable(RenderObject* renderer) : AccessibilityRenderObject(renderer), m_headerContainer(0){#if defined(BUILDING_ON_TIGER) || defined(BUILDING_ON_LEOPARD) m_isAccessibilityTable = false;#else m_isAccessibilityTable = isTableExposableThroughAccessibility();#endif}AccessibilityTable::~AccessibilityTable(){}PassRefPtr<AccessibilityTable> AccessibilityTable::create(RenderObject* renderer){ return adoptRef(new AccessibilityTable(renderer));}bool AccessibilityTable::isTableExposableThroughAccessibility(){ // the following is a heuristic used to determine if a // <table> should be exposed as an AXTable. The goal // is to only show "data" tables if (!m_renderer || !m_renderer->isTable()) return false; // if the developer assigned an aria role to this, then we shouldn't // expose it as a table, unless, of course, the aria role is a table AccessibilityRole ariaRole = ariaRoleAttribute(); if (ariaRole == TableRole) return true; if (ariaRole != UnknownRole) return false; RenderTable* table = static_cast<RenderTable*>(m_renderer); // this employs a heuristic to determine if this table should appear. // Only "data" tables should be exposed as tables. // Unfortunately, there is no good way to determine the difference // between a "layout" table and a "data" table Node* tableNode = table->node(); if (!tableNode || !tableNode->hasTagName(tableTag)) return false; // if there is a caption element, summary, THEAD, or TFOOT section, it's most certainly a data table HTMLTableElement* tableElement = static_cast<HTMLTableElement*>(tableNode); if (!tableElement->summary().isEmpty() || tableElement->tHead() || tableElement->tFoot() || tableElement->caption()) return true; // if someone used "rules" attribute than the table should appear if (!tableElement->rules().isEmpty()) return true; // go through the cell's and check for tell-tale signs of "data" table status // cells have borders, or use attributes like headers, abbr, scope or axis RenderTableSection* firstBody = table->firstBody(); if (!firstBody) return false; int numCols = firstBody->numColumns(); int numRows = firstBody->numRows(); // if there's only one cell, it's not a good AXTable candidate if (numRows == 1 && numCols == 1) return false; // store the background color of the table to check against cell's background colors RenderStyle* tableStyle = table->style(); if (!tableStyle) return false; Color tableBGColor = tableStyle->backgroundColor(); // check enough of the cells to find if the table matches our criteria // Criteria: // 1) must have at least one valid cell (and) // 2) at least half of cells have borders (or) // 3) at least half of cells have different bg colors than the table, and there is cell spacing unsigned validCellCount = 0; unsigned borderedCellCount = 0; unsigned backgroundDifferenceCellCount = 0; for (int row = 0; row < numRows; ++row) { for (int col = 0; col < numCols; ++col) { RenderTableCell* cell = firstBody->cellAt(row, col).cell; if (!cell) continue; Node* cellNode = cell->node(); if (!cellNode) continue; if (cell->width() < 1 || cell->height() < 1) continue; validCellCount++; HTMLTableCellElement* cellElement = static_cast<HTMLTableCellElement*>(cellNode); // in this case, the developer explicitly assigned a "data" table attribute if (!cellElement->headers().isEmpty() || !cellElement->abbr().isEmpty() || !cellElement->axis().isEmpty() || !cellElement->scope().isEmpty()) return true; RenderStyle* renderStyle = cell->style(); if (!renderStyle) continue; // a cell needs to have matching bordered sides, before it can be considered a bordered cell. if ((cell->borderTop() > 0 && cell->borderBottom() > 0) || (cell->borderLeft() > 0 && cell->borderRight() > 0)) borderedCellCount++; // if the cell has a different color from the table and there is cell spacing, // then it is probably a data table cell (spacing and colors take the place of borders) Color cellColor = renderStyle->backgroundColor(); if (table->hBorderSpacing() > 0 && table->vBorderSpacing() > 0 && tableBGColor != cellColor && cellColor.alpha() != 1) backgroundDifferenceCellCount++; // if we've found 10 "good" cells, we don't need to keep searching if (borderedCellCount >= 10 || backgroundDifferenceCellCount >= 10) return true; } } // if there is less than two valid cells, it's not a data table if (validCellCount <= 1) return false; // half of the cells had borders, it's a data table unsigned neededCellCount = validCellCount / 2; if (borderedCellCount >= neededCellCount) return true; // half had different background colors, it's a data table if (backgroundDifferenceCellCount >= neededCellCount) return true; return false;} void AccessibilityTable::clearChildren(){ m_children.clear(); m_rows.clear(); m_columns.clear(); m_haveChildren = false;}void AccessibilityTable::addChildren(){ if (!isDataTable()) { AccessibilityRenderObject::addChildren(); return; } ASSERT(!m_haveChildren); m_haveChildren = true; if (!m_renderer) return; RenderTable* table = static_cast<RenderTable*>(m_renderer); AXObjectCache* axCache = m_renderer->document()->axObjectCache(); // go through all the available sections to pull out the rows // and add them as children RenderTableSection* tableSection = table->header(); if (!tableSection) tableSection = table->firstBody(); if (!tableSection) return; RenderTableSection* initialTableSection = tableSection; while (tableSection) { HashSet<AccessibilityObject*> appendedRows; unsigned numRows = tableSection->numRows(); unsigned numCols = tableSection->numColumns(); for (unsigned rowIndex = 0; rowIndex < numRows; ++rowIndex) { for (unsigned colIndex = 0; colIndex < numCols; ++colIndex) { RenderTableCell* cell = tableSection->cellAt(rowIndex, colIndex).cell; if (!cell) continue; AccessibilityObject* rowObject = axCache->getOrCreate(cell->parent()); if (!rowObject->isTableRow())
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?