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 + -
显示快捷键?