diff options
author | Ben Murdoch <benm@google.com> | 2010-07-22 15:37:06 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2010-07-27 10:20:25 +0100 |
commit | 967717af5423377c967781471ee106e2bb4e11c8 (patch) | |
tree | 1e701dc0a12f7f07cce1df4a7681717de77a211b /WebCore/accessibility | |
parent | dcc30a9fca45f634b1d3a12b276d3a0ccce99fc3 (diff) | |
download | external_webkit-967717af5423377c967781471ee106e2bb4e11c8.zip external_webkit-967717af5423377c967781471ee106e2bb4e11c8.tar.gz external_webkit-967717af5423377c967781471ee106e2bb4e11c8.tar.bz2 |
Merge WebKit at r63859 : Initial merge by git.
Change-Id: Ie8096c63ec7c991c9a9cba8bdd9c3b74a3b8ed62
Diffstat (limited to 'WebCore/accessibility')
-rw-r--r-- | WebCore/accessibility/AccessibilityImageMapLink.cpp | 16 | ||||
-rw-r--r-- | WebCore/accessibility/AccessibilityImageMapLink.h | 1 | ||||
-rw-r--r-- | WebCore/accessibility/AccessibilityListBoxOption.cpp | 9 | ||||
-rw-r--r-- | WebCore/accessibility/AccessibilityListBoxOption.h | 3 | ||||
-rw-r--r-- | WebCore/accessibility/AccessibilityObject.cpp | 52 | ||||
-rw-r--r-- | WebCore/accessibility/AccessibilityObject.h | 17 | ||||
-rw-r--r-- | WebCore/accessibility/AccessibilityRenderObject.cpp | 101 | ||||
-rw-r--r-- | WebCore/accessibility/AccessibilityRenderObject.h | 10 | ||||
-rw-r--r-- | WebCore/accessibility/AccessibilityTable.cpp | 30 | ||||
-rw-r--r-- | WebCore/accessibility/AccessibilityTableCell.cpp | 7 | ||||
-rw-r--r-- | WebCore/accessibility/AccessibilityTableColumn.cpp | 3 |
11 files changed, 125 insertions, 124 deletions
diff --git a/WebCore/accessibility/AccessibilityImageMapLink.cpp b/WebCore/accessibility/AccessibilityImageMapLink.cpp index 2eac8d3..924ba21 100644 --- a/WebCore/accessibility/AccessibilityImageMapLink.cpp +++ b/WebCore/accessibility/AccessibilityImageMapLink.cpp @@ -73,7 +73,7 @@ AccessibilityRole AccessibilityImageMapLink::roleValue() const if (!m_areaElement) return WebCoreLinkRole; - const AtomicString& ariaRole = m_areaElement->getAttribute(roleAttr); + const AtomicString& ariaRole = getAttribute(roleAttr); if (!ariaRole.isEmpty()) return AccessibilityObject::ariaRoleToWebCoreRole(ariaRole); @@ -100,13 +100,10 @@ KURL AccessibilityImageMapLink::url() const String AccessibilityImageMapLink::accessibilityDescription() const { - if (!m_areaElement) - return String(); - - const AtomicString& ariaLabel = m_areaElement->getAttribute(aria_labelAttr); + const AtomicString& ariaLabel = getAttribute(aria_labelAttr); if (!ariaLabel.isEmpty()) return ariaLabel; - const AtomicString& alt = m_areaElement->getAttribute(altAttr); + const AtomicString& alt = getAttribute(altAttr); if (!alt.isEmpty()) return alt; @@ -115,13 +112,10 @@ String AccessibilityImageMapLink::accessibilityDescription() const String AccessibilityImageMapLink::title() const { - if (!m_areaElement) - return String(); - - const AtomicString& title = m_areaElement->getAttribute(titleAttr); + const AtomicString& title = getAttribute(titleAttr); if (!title.isEmpty()) return title; - const AtomicString& summary = m_areaElement->getAttribute(summaryAttr); + const AtomicString& summary = getAttribute(summaryAttr); if (!summary.isEmpty()) return summary; diff --git a/WebCore/accessibility/AccessibilityImageMapLink.h b/WebCore/accessibility/AccessibilityImageMapLink.h index ca4c62c..e2e1544 100644 --- a/WebCore/accessibility/AccessibilityImageMapLink.h +++ b/WebCore/accessibility/AccessibilityImageMapLink.h @@ -49,6 +49,7 @@ public: void setHTMLMapElement(HTMLMapElement* element) { m_mapElement = element; } HTMLMapElement* mapElement() const { return m_mapElement; } + virtual Node* node() const { return m_areaElement; } void setParent(AccessibilityObject* parent) { m_parent = parent; } virtual AccessibilityRole roleValue() const; diff --git a/WebCore/accessibility/AccessibilityListBoxOption.cpp b/WebCore/accessibility/AccessibilityListBoxOption.cpp index 57519e3..3e4dad9 100644 --- a/WebCore/accessibility/AccessibilityListBoxOption.cpp +++ b/WebCore/accessibility/AccessibilityListBoxOption.cpp @@ -110,17 +110,12 @@ bool AccessibilityListBoxOption::accessibilityIsIgnored() const if (!m_optionElement) return true; - if (equalIgnoringCase(getAttribute(m_optionElement, aria_hiddenAttr), "true")) + if (equalIgnoringCase(getAttribute(aria_hiddenAttr), "true")) return true; return parentObject()->accessibilityIsIgnored(); } -String AccessibilityListBoxOption::language() const -{ - return AccessibilityObject::language(m_optionElement); -} - bool AccessibilityListBoxOption::canSetSelectedAttribute() const { if (!m_optionElement) @@ -144,7 +139,7 @@ String AccessibilityListBoxOption::stringValue() const if (!m_optionElement) return String(); - const AtomicString& ariaLabel = getAttribute(m_optionElement, aria_labelAttr); + const AtomicString& ariaLabel = getAttribute(aria_labelAttr); if (!ariaLabel.isNull()) return ariaLabel; diff --git a/WebCore/accessibility/AccessibilityListBoxOption.h b/WebCore/accessibility/AccessibilityListBoxOption.h index 1da77e7..c4c9315 100644 --- a/WebCore/accessibility/AccessibilityListBoxOption.h +++ b/WebCore/accessibility/AccessibilityListBoxOption.h @@ -56,7 +56,7 @@ public: virtual bool isEnabled() const; virtual String stringValue() const; virtual Element* actionElement() const; - + virtual Node* node() const { return m_optionElement; } virtual void setSelected(bool); virtual bool canSetSelectedAttribute() const; @@ -68,7 +68,6 @@ public: private: HTMLElement* m_optionElement; - virtual String language() const; virtual bool canHaveChildren() const { return false; } HTMLSelectElement* listBoxOptionParentNode() const; int listBoxOptionIndex() const; diff --git a/WebCore/accessibility/AccessibilityObject.cpp b/WebCore/accessibility/AccessibilityObject.cpp index 555ba6f..bc4e2f5 100644 --- a/WebCore/accessibility/AccessibilityObject.cpp +++ b/WebCore/accessibility/AccessibilityObject.cpp @@ -148,17 +148,12 @@ bool AccessibilityObject::press() const return true; } -String AccessibilityObject::language(Node* node) const -{ - const AtomicString& lang = getAttribute(node, langAttr); - if (lang.isEmpty()) - return AccessibilityObject::language(); - - return lang; -} - String AccessibilityObject::language() const { + const AtomicString& lang = getAttribute(langAttr); + if (!lang.isEmpty()) + return lang; + AccessibilityObject* parent = parentObject(); // as a last resort, fall back to the content language specified in the meta tag @@ -166,7 +161,7 @@ String AccessibilityObject::language() const Document* doc = document(); if (doc) return doc->contentLanguage(); - return String(); + return nullAtom; } return parent->language(); @@ -403,7 +398,7 @@ static bool replacedNodeNeedsCharacter(Node* replacedNode) } // Finds a RenderListItem parent give a node. -RenderListItem* AccessibilityObject::renderListItemContainerForNode(Node* node) const +static RenderListItem* renderListItemContainerForNode(Node* node) { for (Node* stringNode = node; stringNode; stringNode = stringNode->parent()) { RenderObject* renderObject = stringNode->renderer(); @@ -844,15 +839,16 @@ const String& AccessibilityObject::actionVerb() const } } -const AtomicString& AccessibilityObject::getAttribute(Node* node, const QualifiedName& attribute) +const AtomicString& AccessibilityObject::getAttribute(const QualifiedName& attribute) const { - if (!node) + Node* elementNode = node(); + if (!elementNode) return nullAtom; - if (!node->isElementNode()) + if (!elementNode->isElementNode()) return nullAtom; - Element* element = static_cast<Element*>(node); + Element* element = static_cast<Element*>(elementNode); return element->getAttribute(attribute); } @@ -980,6 +976,32 @@ bool AccessibilityObject::supportsARIALiveRegion() const const AtomicString& liveRegion = ariaLiveRegionStatus(); return equalIgnoringCase(liveRegion, "polite") || equalIgnoringCase(liveRegion, "assertive"); } + +int AccessibilityObject::intValue() const +{ + if (isPasswordField()) + return 0; + + if (isHeading()) + return headingLevel(); + + // If this is a real checkbox or radio button, AccessibilityRenderObject will handle. + // If it's an ARIA checkbox or radio, the aria-checked attribute should be used. + if (isCheckboxOrRadio()) + return equalIgnoringCase(getAttribute(aria_checkedAttr), "true"); + + return 0; +} +bool AccessibilityObject::hasIntValue() const +{ + if (isHeading()) + return true; + + if (isCheckboxOrRadio()) + return true; + + return false; +} } // namespace WebCore diff --git a/WebCore/accessibility/AccessibilityObject.h b/WebCore/accessibility/AccessibilityObject.h index 3c8d392..400a200 100644 --- a/WebCore/accessibility/AccessibilityObject.h +++ b/WebCore/accessibility/AccessibilityObject.h @@ -264,7 +264,8 @@ public: virtual bool isTextControl() const { return false; } virtual bool isNativeTextControl() const { return false; } virtual bool isWebArea() const { return false; } - virtual bool isCheckboxOrRadio() const { return false; } + virtual bool isCheckbox() const { return roleValue() == CheckBoxRole; } + virtual bool isRadioButton() const { return roleValue() == RadioButtonRole; } virtual bool isListBox() const { return roleValue() == ListBoxRole; } virtual bool isMediaTimeline() const { return false; } virtual bool isMenuRelated() const { return false; } @@ -298,6 +299,7 @@ public: bool isScrollbar() const { return roleValue() == ScrollBarRole; } bool isButton() const { return roleValue() == ButtonRole; } bool isListItem() const { return roleValue() == ListItemRole; } + bool isCheckboxOrRadio() const { return isCheckbox() || isRadioButton(); } virtual bool isChecked() const { return false; } virtual bool isEnabled() const { return false; } @@ -325,16 +327,17 @@ public: virtual bool canSetSelectedChildrenAttribute() const { return false; } virtual bool canSetExpandedAttribute() const { return false; } - virtual bool hasIntValue() const { return false; } - + bool hasIntValue() const; + virtual int intValue() const; + // A programmatic way to set a name on an AccessibleObject. virtual void setAccessibleName(String&) { } + virtual Node* node() const { return 0; } bool accessibilityShouldUseUniqueId() const { return true; } virtual bool accessibilityIsIgnored() const { return true; } virtual int headingLevel() const { return 0; } - virtual int intValue() const { return 0; } virtual String valueDescription() const { return String(); } virtual float valueForRange() const { return 0.0f; } virtual float maxValueForRange() const { return 0.0f; } @@ -419,8 +422,7 @@ public: virtual Document* document() const { return 0; } virtual FrameView* topDocumentFrameView() const { return 0; } virtual FrameView* documentFrameView() const; - virtual String language() const; - String language(Node*) const; + String language() const; virtual unsigned hierarchicalLevel() const { return 0; } virtual void setFocused(bool) { } @@ -454,7 +456,7 @@ public: virtual void handleAriaExpandedChanged() { } static AccessibilityRole ariaRoleToWebCoreRole(const String&); - static const AtomicString& getAttribute(Node*, const QualifiedName&); + const AtomicString& getAttribute(const QualifiedName&) const; virtual VisiblePositionRange visiblePositionRange() const { return VisiblePositionRange(); } virtual VisiblePositionRange visiblePositionRangeForLine(unsigned) const { return VisiblePositionRange(); } @@ -564,7 +566,6 @@ protected: virtual void clearChildren(); virtual bool isDetached() const { return true; } - RenderListItem* renderListItemContainerForNode(Node* node) const; #if PLATFORM(MAC) RetainPtr<AccessibilityObjectWrapper> m_wrapper; diff --git a/WebCore/accessibility/AccessibilityRenderObject.cpp b/WebCore/accessibility/AccessibilityRenderObject.cpp index 2e53703..1b3c461 100644 --- a/WebCore/accessibility/AccessibilityRenderObject.cpp +++ b/WebCore/accessibility/AccessibilityRenderObject.cpp @@ -476,12 +476,6 @@ bool AccessibilityRenderObject::isPasswordField() const return inputElement->isPasswordField(); } - -bool AccessibilityRenderObject::isCheckboxOrRadio() const -{ - AccessibilityRole role = roleValue(); - return role == RadioButtonRole || role == CheckBoxRole; -} bool AccessibilityRenderObject::isFileUploadButton() const { @@ -660,36 +654,29 @@ bool AccessibilityRenderObject::isOffScreen() const int AccessibilityRenderObject::headingLevel() const { // headings can be in block flow and non-block flow - if (!m_renderer) - return 0; - - Node* node = m_renderer->node(); - if (!node) + Node* element = node(); + if (!element) return 0; - if (ariaRoleAttribute() == HeadingRole) { - if (!node->isElementNode()) - return 0; - Element* element = static_cast<Element*>(node); - return element->getAttribute(aria_levelAttr).toInt(); - } + if (ariaRoleAttribute() == HeadingRole) + return getAttribute(aria_levelAttr).toInt(); - if (node->hasTagName(h1Tag)) + if (element->hasTagName(h1Tag)) return 1; - if (node->hasTagName(h2Tag)) + if (element->hasTagName(h2Tag)) return 2; - if (node->hasTagName(h3Tag)) + if (element->hasTagName(h3Tag)) return 3; - if (node->hasTagName(h4Tag)) + if (element->hasTagName(h4Tag)) return 4; - if (node->hasTagName(h5Tag)) + if (element->hasTagName(h5Tag)) return 5; - if (node->hasTagName(h6Tag)) + if (element->hasTagName(h6Tag)) return 6; return 0; @@ -760,11 +747,6 @@ AccessibilityObject* AccessibilityRenderObject::selectedTabItem() } return 0; } - -const AtomicString& AccessibilityRenderObject::getAttribute(const QualifiedName& attribute) const -{ - return AccessibilityObject::getAttribute(m_renderer->node(), attribute); -} Element* AccessibilityRenderObject::anchorElement() const { @@ -990,14 +972,6 @@ unsigned AccessibilityRenderObject::hierarchicalLevel() const return level; } - -String AccessibilityRenderObject::language() const -{ - if (!m_renderer) - return String(); - - return AccessibilityObject::language(m_renderer->node()); -} String AccessibilityRenderObject::textUnderElement() const { @@ -1030,38 +1004,17 @@ String AccessibilityRenderObject::textUnderElement() const return String(); } -bool AccessibilityRenderObject::hasIntValue() const -{ - if (isHeading()) - return true; - - if (m_renderer->node() && isCheckboxOrRadio()) - return true; +Node* AccessibilityRenderObject::node() const +{ + return m_renderer ? m_renderer->node() : 0; +} - return false; -} - int AccessibilityRenderObject::intValue() const { - if (!m_renderer || isPasswordField()) - return 0; - - if (isHeading()) - return headingLevel(); - - Node* node = m_renderer->node(); - if (!node || !isCheckboxOrRadio()) - return 0; + if (isCheckboxOrRadio()) + return isChecked() ? 1 : 0; - // If this is an ARIA checkbox or radio, check the aria-checked attribute rather than node()->checked() - AccessibilityRole ariaRole = ariaRoleAttribute(); - if (ariaRole == RadioButtonRole || ariaRole == CheckBoxRole) { - if (equalIgnoringCase(getAttribute(aria_checkedAttr), "true")) - return true; - return false; - } - - return static_cast<HTMLInputElement*>(node)->checked(); + return AccessibilityObject::intValue(); } String AccessibilityRenderObject::valueDescription() const @@ -1122,9 +1075,11 @@ String AccessibilityRenderObject::stringValue() const Element* selectedOption = 0; if (selectedIndex >= 0 && selectedIndex < (int)listItems.size()) selectedOption = listItems[selectedIndex]; - String overridenDescription = AccessibilityObject::getAttribute(selectedOption, aria_labelAttr); - if (!overridenDescription.isNull()) - return overridenDescription; + if (selectedOption) { + String overridenDescription = selectedOption->getAttribute(aria_labelAttr); + if (!overridenDescription.isNull()) + return overridenDescription; + } return toRenderMenuList(m_renderer)->text(); } @@ -1364,9 +1319,11 @@ String AccessibilityRenderObject::accessibilityDescription() const // Check if the HTML element has an aria-label for the webpage. Element* documentElement = document->documentElement(); - const AtomicString& ariaLabel = AccessibilityObject::getAttribute(documentElement, aria_labelAttr); - if (!ariaLabel.isEmpty()) - return ariaLabel; + if (documentElement) { + const AtomicString& ariaLabel = documentElement->getAttribute(aria_labelAttr); + if (!ariaLabel.isEmpty()) + return ariaLabel; + } Node* owner = document->ownerElement(); if (owner) { @@ -1397,8 +1354,10 @@ IntRect AccessibilityRenderObject::boundingBoxRect() const if (obj->node()) // If we are a continuation, we want to make sure to use the primary renderer. obj = obj->node()->renderer(); + // absoluteFocusRingQuads will query the hierarchy below this element, which for large webpages can be very slow. + // For a web area, which will have the most elements of any element, absoluteQuads should be used. Vector<FloatQuad> quads; - if (obj->isText()) + if (obj->isText() || isWebArea()) obj->absoluteQuads(quads); else obj->absoluteFocusRingQuads(quads); diff --git a/WebCore/accessibility/AccessibilityRenderObject.h b/WebCore/accessibility/AccessibilityRenderObject.h index d4f798a..526324f 100644 --- a/WebCore/accessibility/AccessibilityRenderObject.h +++ b/WebCore/accessibility/AccessibilityRenderObject.h @@ -75,7 +75,6 @@ public: virtual bool isTextControl() const; virtual bool isNativeTextControl() const; virtual bool isWebArea() const; - virtual bool isCheckboxOrRadio() const; virtual bool isFileUploadButton() const; virtual bool isInputImage() const; virtual bool isProgressIndicator() const; @@ -106,14 +105,11 @@ public: virtual bool isExpanded() const; virtual void setIsExpanded(bool); - const AtomicString& getAttribute(const QualifiedName&) const; virtual bool canSetFocusAttribute() const; virtual bool canSetTextRangeAttributes() const; virtual bool canSetValueAttribute() const; virtual bool canSetExpandedAttribute() const; - virtual bool hasIntValue() const; - virtual void setAccessibleName(String&); // Provides common logic used by all elements when determining isIgnored. @@ -169,10 +165,7 @@ public: void setRenderer(RenderObject* renderer) { m_renderer = renderer; } RenderObject* renderer() const { return m_renderer; } - Node* node() const - { - return m_renderer ? m_renderer->node() : 0; - }; + virtual Node* node() const; RenderView* topRenderer() const; RenderTextControl* textControl() const; @@ -283,7 +276,6 @@ private: bool isAllowedChildOfTree() const; bool hasTextAlternative() const; String positionalDescriptionForMSAA() const; - virtual String language() const; Element* menuElementForMenuButton() const; Element* menuItemElementForMenu() const; diff --git a/WebCore/accessibility/AccessibilityTable.cpp b/WebCore/accessibility/AccessibilityTable.cpp index 437ac38..a0bb655 100644 --- a/WebCore/accessibility/AccessibilityTable.cpp +++ b/WebCore/accessibility/AccessibilityTable.cpp @@ -137,6 +137,9 @@ bool AccessibilityTable::isTableExposableThroughAccessibility() unsigned borderedCellCount = 0; unsigned backgroundDifferenceCellCount = 0; + Color alternatingRowColors[5]; + int alternatingRowColorCount = 0; + int headersInFirstColumnCount = 0; for (int row = 0; row < numRows; ++row) { @@ -189,6 +192,19 @@ bool AccessibilityTable::isTableExposableThroughAccessibility() // if we've found 10 "good" cells, we don't need to keep searching if (borderedCellCount >= 10 || backgroundDifferenceCellCount >= 10) return true; + + // For the first 5 rows, cache the background color so we can check if this table has zebra-striped rows. + if (row < 5 && row == alternatingRowColorCount) { + RenderObject* renderRow = cell->parent(); + if (!renderRow || !renderRow->isTableRow()) + continue; + RenderStyle* rowRenderStyle = renderRow->style(); + if (!rowRenderStyle) + continue; + Color rowColor = rowRenderStyle->visitedDependentColor(CSSPropertyBackgroundColor); + alternatingRowColors[alternatingRowColorCount] = rowColor; + alternatingRowColorCount++; + } } if (!row && headersInFirstRowCount == numCols && numCols > 1) @@ -211,6 +227,20 @@ bool AccessibilityTable::isTableExposableThroughAccessibility() if (backgroundDifferenceCellCount >= neededCellCount) return true; + // Check if there is an alternating row background color indicating a zebra striped style pattern. + if (alternatingRowColorCount > 2) { + Color firstColor = alternatingRowColors[0]; + for (int k = 1; k < alternatingRowColorCount; k++) { + // If an odd row was the same color as the first row, its not alternating. + if (k % 2 == 1 && alternatingRowColors[k] == firstColor) + return false; + // If an even row is not the same as the first row, its not alternating. + if (!(k % 2) && alternatingRowColors[k] != firstColor) + return false; + } + return true; + } + return false; } diff --git a/WebCore/accessibility/AccessibilityTableCell.cpp b/WebCore/accessibility/AccessibilityTableCell.cpp index 7fadb88..28e66ad 100644 --- a/WebCore/accessibility/AccessibilityTableCell.cpp +++ b/WebCore/accessibility/AccessibilityTableCell.cpp @@ -73,7 +73,12 @@ AccessibilityObject* AccessibilityTableCell::parentTable() const if (!m_renderer || !m_renderer->isTableCell()) return 0; - return axObjectCache()->getOrCreate(toRenderTableCell(m_renderer)->table()); + // Do not use getOrCreate. parentTable() can be called while the render tree is being modified + // by javascript, and creating a table element may try to access the render tree while in a bad state. + // By using only get() implies that the AXTable must be created before AXTableCells. This should + // always be the case when AT clients access a table. + // https://bugs.webkit.org/show_bug.cgi?id=42652 + return axObjectCache()->get(toRenderTableCell(m_renderer)->table()); } bool AccessibilityTableCell::isTableCell() const diff --git a/WebCore/accessibility/AccessibilityTableColumn.cpp b/WebCore/accessibility/AccessibilityTableColumn.cpp index 5872706..45137ff 100644 --- a/WebCore/accessibility/AccessibilityTableColumn.cpp +++ b/WebCore/accessibility/AccessibilityTableColumn.cpp @@ -130,6 +130,9 @@ AccessibilityObject* AccessibilityTableColumn::headerObjectForSection(RenderTabl if (m_columnIndex >= numCols) return 0; + if (!section->numRows()) + return 0; + RenderTableCell* cell = 0; // also account for cells that have a span for (int testCol = m_columnIndex; testCol >= 0; --testCol) { |