summaryrefslogtreecommitdiffstats
path: root/WebCore/accessibility
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/accessibility')
-rw-r--r--WebCore/accessibility/AXObjectCache.cpp26
-rw-r--r--WebCore/accessibility/AXObjectCache.h3
-rw-r--r--WebCore/accessibility/AccessibilityARIAGrid.cpp3
-rw-r--r--WebCore/accessibility/AccessibilityImageMapLink.cpp3
-rw-r--r--WebCore/accessibility/AccessibilityList.cpp6
-rw-r--r--WebCore/accessibility/AccessibilityListBox.cpp26
-rw-r--r--WebCore/accessibility/AccessibilityListBox.h5
-rw-r--r--WebCore/accessibility/AccessibilityListBoxOption.cpp20
-rw-r--r--WebCore/accessibility/AccessibilityListBoxOption.h3
-rw-r--r--WebCore/accessibility/AccessibilityMediaControls.cpp2
-rw-r--r--WebCore/accessibility/AccessibilityObject.cpp28
-rw-r--r--WebCore/accessibility/AccessibilityObject.h29
-rw-r--r--WebCore/accessibility/AccessibilityProgressIndicator.cpp78
-rw-r--r--WebCore/accessibility/AccessibilityProgressIndicator.h57
-rw-r--r--WebCore/accessibility/AccessibilityRenderObject.cpp251
-rw-r--r--WebCore/accessibility/AccessibilityRenderObject.h18
-rw-r--r--WebCore/accessibility/AccessibilitySlider.cpp11
-rw-r--r--WebCore/accessibility/AccessibilitySlider.h4
-rw-r--r--WebCore/accessibility/AccessibilityTable.cpp54
-rw-r--r--WebCore/accessibility/AccessibilityTableCell.cpp6
-rw-r--r--WebCore/accessibility/AccessibilityTableColumn.cpp12
-rw-r--r--WebCore/accessibility/AccessibilityTableColumn.h2
-rw-r--r--WebCore/accessibility/AccessibilityTableHeaderContainer.cpp12
-rw-r--r--WebCore/accessibility/AccessibilityTableHeaderContainer.h3
-rw-r--r--WebCore/accessibility/AccessibilityTableRow.cpp6
-rw-r--r--WebCore/accessibility/chromium/AccessibilityObjectChromium.cpp2
-rw-r--r--WebCore/accessibility/efl/AccessibilityObjectEfl.cpp36
-rw-r--r--WebCore/accessibility/gtk/AccessibilityObjectAtk.cpp29
-rw-r--r--WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp17
-rw-r--r--WebCore/accessibility/mac/AccessibilityObjectMac.mm2
-rw-r--r--WebCore/accessibility/mac/AccessibilityObjectWrapper.h2
-rw-r--r--WebCore/accessibility/mac/AccessibilityObjectWrapper.mm31
-rw-r--r--WebCore/accessibility/qt/AccessibilityObjectQt.cpp2
-rw-r--r--WebCore/accessibility/win/AccessibilityObjectWin.cpp2
-rw-r--r--WebCore/accessibility/wx/AccessibilityObjectWx.cpp2
35 files changed, 613 insertions, 180 deletions
diff --git a/WebCore/accessibility/AXObjectCache.cpp b/WebCore/accessibility/AXObjectCache.cpp
index c347a81..b7622b8 100644
--- a/WebCore/accessibility/AXObjectCache.cpp
+++ b/WebCore/accessibility/AXObjectCache.cpp
@@ -38,8 +38,9 @@
#include "AccessibilityListBoxOption.h"
#include "AccessibilityMediaControls.h"
#include "AccessibilityMenuList.h"
-#include "AccessibilityMenuListPopup.h"
#include "AccessibilityMenuListOption.h"
+#include "AccessibilityMenuListPopup.h"
+#include "AccessibilityProgressIndicator.h"
#include "AccessibilityRenderObject.h"
#include "AccessibilityScrollbar.h"
#include "AccessibilitySlider.h"
@@ -59,6 +60,7 @@
#include "InputElement.h"
#include "Page.h"
#include "RenderObject.h"
+#include "RenderProgress.h"
#include "RenderView.h"
#include <wtf/PassRefPtr.h>
@@ -159,7 +161,7 @@ AccessibilityObject* AXObjectCache::get(RenderObject* renderer)
return obj;
}
-bool AXObjectCache::nodeIsAriaType(Node* node, String role)
+bool AXObjectCache::nodeHasRole(Node* node, const AtomicString& role)
{
if (!node || !node->isElementNode())
return false;
@@ -183,16 +185,16 @@ AccessibilityObject* AXObjectCache::getOrCreate(RenderObject* renderer)
newObj = AccessibilityMenuList::create(renderer);
// If the node is aria role="list" or the aria role is empty and its a ul/ol/dl type (it shouldn't be a list if aria says otherwise).
- else if (node && ((nodeIsAriaType(node, "list") || nodeIsAriaType(node, "directory"))
- || (nodeIsAriaType(node, nullAtom) && (node->hasTagName(ulTag) || node->hasTagName(olTag) || node->hasTagName(dlTag)))))
+ else if (node && ((nodeHasRole(node, "list") || nodeHasRole(node, "directory"))
+ || (nodeHasRole(node, nullAtom) && (node->hasTagName(ulTag) || node->hasTagName(olTag) || node->hasTagName(dlTag)))))
newObj = AccessibilityList::create(renderer);
// aria tables
- else if (nodeIsAriaType(node, "grid") || nodeIsAriaType(node, "treegrid"))
+ else if (nodeHasRole(node, "grid") || nodeHasRole(node, "treegrid"))
newObj = AccessibilityARIAGrid::create(renderer);
- else if (nodeIsAriaType(node, "row"))
+ else if (nodeHasRole(node, "row"))
newObj = AccessibilityARIAGridRow::create(renderer);
- else if (nodeIsAriaType(node, "gridcell") || nodeIsAriaType(node, "columnheader") || nodeIsAriaType(node, "rowheader"))
+ else if (nodeHasRole(node, "gridcell") || nodeHasRole(node, "columnheader") || nodeHasRole(node, "rowheader"))
newObj = AccessibilityARIAGridCell::create(renderer);
// standard tables
@@ -209,6 +211,12 @@ AccessibilityObject* AXObjectCache::getOrCreate(RenderObject* renderer)
newObj = AccessibilityMediaControl::create(renderer);
#endif
+#if ENABLE(PROGRESS_TAG)
+ // progress bar
+ else if (renderer->isProgress())
+ newObj = AccessibilityProgressIndicator::create(toRenderProgress(renderer));
+#endif
+
// input type=range
else if (renderer->isSlider())
newObj = AccessibilitySlider::create(renderer);
@@ -441,7 +449,9 @@ void AXObjectCache::postNotification(AccessibilityObject* object, Document* docu
void AXObjectCache::selectedChildrenChanged(RenderObject* renderer)
{
- postNotification(renderer, AXSelectedChildrenChanged, true);
+ // postToElement is false so that you can pass in any child of an element and it will go up the parent tree
+ // to find the container which should send out the notification.
+ postNotification(renderer, AXSelectedChildrenChanged, false);
}
#endif
diff --git a/WebCore/accessibility/AXObjectCache.h b/WebCore/accessibility/AXObjectCache.h
index dad73f2..25f5347 100644
--- a/WebCore/accessibility/AXObjectCache.h
+++ b/WebCore/accessibility/AXObjectCache.h
@@ -121,6 +121,8 @@ public:
void postNotification(RenderObject*, AXNotification, bool postToElement, PostType = PostAsynchronously);
void postNotification(AccessibilityObject*, Document*, AXNotification, bool postToElement, PostType = PostAsynchronously);
+ bool nodeHasRole(Node*, const AtomicString& role);
+
protected:
void postPlatformNotification(AccessibilityObject*, AXNotification);
@@ -139,7 +141,6 @@ private:
static AccessibilityObject* focusedImageMapUIElement(HTMLAreaElement*);
AXID getAXID(AccessibilityObject*);
- bool nodeIsAriaType(Node*, String role);
};
#if !HAVE(ACCESSIBILITY)
diff --git a/WebCore/accessibility/AccessibilityARIAGrid.cpp b/WebCore/accessibility/AccessibilityARIAGrid.cpp
index a0cf77a..58b3fa1 100644
--- a/WebCore/accessibility/AccessibilityARIAGrid.cpp
+++ b/WebCore/accessibility/AccessibilityARIAGrid.cpp
@@ -131,8 +131,7 @@ AccessibilityTableCell* AccessibilityARIAGrid::cellForColumnAndRow(unsigned colu
if (!m_renderer)
return 0;
- if (!hasChildren())
- addChildren();
+ updateChildrenIfNecessary();
if (column >= columnCount() || row >= rowCount())
return 0;
diff --git a/WebCore/accessibility/AccessibilityImageMapLink.cpp b/WebCore/accessibility/AccessibilityImageMapLink.cpp
index 06150b9..2eac8d3 100644
--- a/WebCore/accessibility/AccessibilityImageMapLink.cpp
+++ b/WebCore/accessibility/AccessibilityImageMapLink.cpp
@@ -103,6 +103,9 @@ String AccessibilityImageMapLink::accessibilityDescription() const
if (!m_areaElement)
return String();
+ const AtomicString& ariaLabel = m_areaElement->getAttribute(aria_labelAttr);
+ if (!ariaLabel.isEmpty())
+ return ariaLabel;
const AtomicString& alt = m_areaElement->getAttribute(altAttr);
if (!alt.isEmpty())
return alt;
diff --git a/WebCore/accessibility/AccessibilityList.cpp b/WebCore/accessibility/AccessibilityList.cpp
index feceee5..073b0fc 100644
--- a/WebCore/accessibility/AccessibilityList.cpp
+++ b/WebCore/accessibility/AccessibilityList.cpp
@@ -55,8 +55,10 @@ PassRefPtr<AccessibilityList> AccessibilityList::create(RenderObject* renderer)
bool AccessibilityList::accessibilityIsIgnored() const
{
- // Is the platform interested in the object?
- if (accessibilityPlatformIncludesObject() == IgnoreObject)
+ AccessibilityObjectInclusion decision = accessibilityIsIgnoredBase();
+ if (decision == IncludeObject)
+ return false;
+ if (decision == IgnoreObject)
return true;
// lists don't appear on tiger/leopard on the mac
diff --git a/WebCore/accessibility/AccessibilityListBox.cpp b/WebCore/accessibility/AccessibilityListBox.cpp
index 2c267c1..8a9e062 100644
--- a/WebCore/accessibility/AccessibilityListBox.cpp
+++ b/WebCore/accessibility/AccessibilityListBox.cpp
@@ -80,7 +80,7 @@ void AccessibilityListBox::addChildren()
// The cast to HTMLElement below is safe because the only other possible listItem type
// would be a WMLElement, but WML builds don't use accessibility features at all.
AccessibilityObject* listOption = listBoxOptionAccessibilityObject(static_cast<HTMLElement*>(listItems[i]));
- if (listOption)
+ if (listOption && !listOption->accessibilityIsIgnored())
m_children.append(listOption);
}
}
@@ -151,6 +151,17 @@ AccessibilityObject* AccessibilityListBox::listBoxOptionAccessibilityObject(HTML
return listBoxObject;
}
+
+bool AccessibilityListBox::accessibilityIsIgnored() const
+{
+ AccessibilityObjectInclusion decision = accessibilityIsIgnoredBase();
+ if (decision == IncludeObject)
+ return false;
+ if (decision == IgnoreObject)
+ return true;
+
+ return false;
+}
AccessibilityObject* AccessibilityListBox::doAccessibilityHitTest(const IntPoint& point) const
{
@@ -165,16 +176,21 @@ AccessibilityObject* AccessibilityListBox::doAccessibilityHitTest(const IntPoint
IntRect parentRect = boundingBoxRect();
- const Vector<Element*>& listItems = static_cast<HTMLSelectElement*>(node)->listItems();
- unsigned length = listItems.size();
+ AccessibilityObject* listBoxOption = 0;
+ unsigned length = m_children.size();
for (unsigned i = 0; i < length; i++) {
IntRect rect = toRenderListBox(m_renderer)->itemBoundingBoxRect(parentRect.x(), parentRect.y(), i);
// The cast to HTMLElement below is safe because the only other possible listItem type
// would be a WMLElement, but WML builds don't use accessibility features at all.
- if (rect.contains(point))
- return listBoxOptionAccessibilityObject(static_cast<HTMLElement*>(listItems[i]));
+ if (rect.contains(point)) {
+ listBoxOption = m_children[i].get();
+ break;
+ }
}
+ if (listBoxOption && !listBoxOption->accessibilityIsIgnored())
+ return listBoxOption;
+
return axObjectCache()->getOrCreate(m_renderer);
}
diff --git a/WebCore/accessibility/AccessibilityListBox.h b/WebCore/accessibility/AccessibilityListBox.h
index ce1abe0..72ce82f 100644
--- a/WebCore/accessibility/AccessibilityListBox.h
+++ b/WebCore/accessibility/AccessibilityListBox.h
@@ -49,9 +49,7 @@ public:
virtual bool canSetSelectedChildrenAttribute() const;
void setSelectedChildren(AccessibilityChildrenVector&);
virtual AccessibilityRole roleValue() const { return ListBoxRole; }
-
- virtual bool accessibilityIsIgnored() const { return false; }
-
+
virtual void selectedChildren(AccessibilityChildrenVector&);
virtual void visibleChildren(AccessibilityChildrenVector&);
@@ -59,6 +57,7 @@ public:
private:
AccessibilityObject* listBoxOptionAccessibilityObject(HTMLElement*) const;
+ virtual bool accessibilityIsIgnored() const;
};
} // namespace WebCore
diff --git a/WebCore/accessibility/AccessibilityListBoxOption.cpp b/WebCore/accessibility/AccessibilityListBoxOption.cpp
index 6a77dac..57519e3 100644
--- a/WebCore/accessibility/AccessibilityListBoxOption.cpp
+++ b/WebCore/accessibility/AccessibilityListBoxOption.cpp
@@ -105,6 +105,22 @@ IntRect AccessibilityListBoxOption::elementRect() const
return rect;
}
+bool AccessibilityListBoxOption::accessibilityIsIgnored() const
+{
+ if (!m_optionElement)
+ return true;
+
+ if (equalIgnoringCase(getAttribute(m_optionElement, aria_hiddenAttr), "true"))
+ return true;
+
+ return parentObject()->accessibilityIsIgnored();
+}
+
+String AccessibilityListBoxOption::language() const
+{
+ return AccessibilityObject::language(m_optionElement);
+}
+
bool AccessibilityListBoxOption::canSetSelectedAttribute() const
{
if (!m_optionElement)
@@ -128,6 +144,10 @@ String AccessibilityListBoxOption::stringValue() const
if (!m_optionElement)
return String();
+ const AtomicString& ariaLabel = getAttribute(m_optionElement, aria_labelAttr);
+ if (!ariaLabel.isNull())
+ return ariaLabel;
+
if (m_optionElement->hasTagName(optionTag))
return static_cast<HTMLOptionElement*>(m_optionElement)->text();
diff --git a/WebCore/accessibility/AccessibilityListBoxOption.h b/WebCore/accessibility/AccessibilityListBoxOption.h
index f8fd5f0..1da77e7 100644
--- a/WebCore/accessibility/AccessibilityListBoxOption.h
+++ b/WebCore/accessibility/AccessibilityListBoxOption.h
@@ -51,7 +51,7 @@ public:
void setHTMLElement(HTMLElement* element) { m_optionElement = element; }
virtual AccessibilityRole roleValue() const { return ListBoxOptionRole; }
- virtual bool accessibilityIsIgnored() const { return false; }
+ virtual bool accessibilityIsIgnored() const;
virtual bool isSelected() const;
virtual bool isEnabled() const;
virtual String stringValue() const;
@@ -68,6 +68,7 @@ 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/AccessibilityMediaControls.cpp b/WebCore/accessibility/AccessibilityMediaControls.cpp
index 6151840..2f98acd 100644
--- a/WebCore/accessibility/AccessibilityMediaControls.cpp
+++ b/WebCore/accessibility/AccessibilityMediaControls.cpp
@@ -89,7 +89,7 @@ PassRefPtr<AccessibilityObject> AccessibilityMediaControl::create(RenderObject*
MediaControlElementType AccessibilityMediaControl::controlType() const
{
if (!renderer() || !renderer()->node())
- return MediaTimelineContainer; // Timeline container is not accessible.
+ return MediaTimelineContainer; // Timeline container is not accessible.
Node* node = renderer()->node();
diff --git a/WebCore/accessibility/AccessibilityObject.cpp b/WebCore/accessibility/AccessibilityObject.cpp
index 7c616ea..8dedc36 100644
--- a/WebCore/accessibility/AccessibilityObject.cpp
+++ b/WebCore/accessibility/AccessibilityObject.cpp
@@ -148,6 +148,15 @@ 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
{
AccessibilityObject* parent = parentObject();
@@ -731,8 +740,8 @@ FrameView* AccessibilityObject::documentFrameView() const
void AccessibilityObject::clearChildren()
{
- m_haveChildren = false;
m_children.clear();
+ m_haveChildren = false;
}
AccessibilityObject* AccessibilityObject::anchorElementForNode(Node* node)
@@ -835,6 +844,18 @@ const String& AccessibilityObject::actionVerb() const
}
}
+const AtomicString& AccessibilityObject::getAttribute(Node* node, const QualifiedName& attribute)
+{
+ if (!node)
+ return nullAtom;
+
+ if (!node->isElementNode())
+ return nullAtom;
+
+ Element* element = static_cast<Element*>(node);
+ return element->getAttribute(attribute);
+}
+
// Lacking concrete evidence of orientation, horizontal means width > height. vertical is height > width;
AccessibilityOrientation AccessibilityObject::orientation() const
{
@@ -949,6 +970,11 @@ bool AccessibilityObject::isInsideARIALiveRegion() const
return false;
}
+bool AccessibilityObject::supportsARIAAttributes() const
+{
+ return supportsARIALiveRegion() || supportsARIADragging() || supportsARIADropping() || supportsARIAFlowTo() || supportsARIAOwns();
+}
+
bool AccessibilityObject::supportsARIALiveRegion() const
{
const AtomicString& liveRegion = ariaLiveRegionStatus();
diff --git a/WebCore/accessibility/AccessibilityObject.h b/WebCore/accessibility/AccessibilityObject.h
index e4b1d99..8b4923a 100644
--- a/WebCore/accessibility/AccessibilityObject.h
+++ b/WebCore/accessibility/AccessibilityObject.h
@@ -34,7 +34,6 @@
#include "Range.h"
#include "VisiblePosition.h"
#include "VisibleSelection.h"
-#include <wtf/Platform.h>
#include <wtf/RefPtr.h>
#include <wtf/Vector.h>
@@ -204,7 +203,7 @@ enum AccessibilityOrientation {
AccessibilityOrientationHorizontal,
};
-enum AccessibilityObjectPlatformInclusion {
+enum AccessibilityObjectInclusion {
IncludeObject,
IgnoreObject,
DefaultBehavior,
@@ -326,6 +325,9 @@ public:
virtual bool hasIntValue() const { return false; }
+ // A programmatic way to set a name on an AccessibleObject.
+ virtual void setAccessibleName(String&) { }
+
bool accessibilityShouldUseUniqueId() const { return true; }
virtual bool accessibilityIsIgnored() const { return true; }
@@ -345,10 +347,11 @@ public:
virtual void ariaOwnsElements(AccessibilityChildrenVector&) const { }
virtual bool supportsARIAFlowTo() const { return false; }
virtual void ariaFlowToElements(AccessibilityChildrenVector&) const { }
+ virtual bool ariaHasPopup() const { return false; }
// ARIA drag and drop
- virtual bool supportsARIADropping() { return false; }
- virtual bool supportsARIADragging() { return false; }
+ virtual bool supportsARIADropping() const { return false; }
+ virtual bool supportsARIADragging() const { return false; }
virtual bool isARIAGrabbed() { return false; }
virtual void setARIAGrabbed(bool) { }
virtual void determineARIADropEffects(Vector<String>&) { }
@@ -415,6 +418,7 @@ public:
virtual FrameView* topDocumentFrameView() const { return 0; }
virtual FrameView* documentFrameView() const;
virtual String language() const;
+ String language(Node*) const;
virtual unsigned hierarchicalLevel() const { return 0; }
virtual void setFocused(bool) { }
@@ -446,7 +450,8 @@ public:
virtual void handleActiveDescendantChanged() { }
static AccessibilityRole ariaRoleToWebCoreRole(const String&);
-
+ static const AtomicString& getAttribute(Node*, const QualifiedName&);
+
virtual VisiblePositionRange visiblePositionRange() const { return VisiblePositionRange(); }
virtual VisiblePositionRange visiblePositionRangeForLine(unsigned) const { return VisiblePositionRange(); }
@@ -518,6 +523,8 @@ public:
virtual bool ariaLiveRegionAtomic() const { return false; }
virtual bool ariaLiveRegionBusy() const { return false; }
+ bool supportsARIAAttributes() const;
+
#if HAVE(ACCESSIBILITY)
#if PLATFORM(GTK)
AccessibilityObjectWrapper* wrapper() const;
@@ -531,18 +538,14 @@ public:
#endif
#endif
- // a platform-specific method for determining if an attachment is ignored
#if HAVE(ACCESSIBILITY)
+ // a platform-specific method for determining if an attachment is ignored
bool accessibilityIgnoreAttachment() const;
-#else
- bool accessibilityIgnoreAttachment() const { return true; }
-#endif
-
// gives platforms the opportunity to indicate if and how an object should be included
-#if HAVE(ACCESSIBILITY)
- AccessibilityObjectPlatformInclusion accessibilityPlatformIncludesObject() const;
+ AccessibilityObjectInclusion accessibilityPlatformIncludesObject() const;
#else
- AccessibilityObjectPlatformInclusion accessibilityPlatformIncludesObject() const { return DefaultBehavior; }
+ bool accessibilityIgnoreAttachment() const { return true; }
+ AccessibilityObjectInclusion accessibilityPlatformIncludesObject() const { return DefaultBehavior; }
#endif
// allows for an AccessibilityObject to update its render tree or perform
diff --git a/WebCore/accessibility/AccessibilityProgressIndicator.cpp b/WebCore/accessibility/AccessibilityProgressIndicator.cpp
new file mode 100644
index 0000000..c7202f0
--- /dev/null
+++ b/WebCore/accessibility/AccessibilityProgressIndicator.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(PROGRESS_TAG)
+
+#include "AccessibilityProgressIndicator.h"
+
+#include "FloatConversion.h"
+#include "HTMLNames.h"
+#include "HTMLProgressElement.h"
+#include "RenderObject.h"
+#include "RenderProgress.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+AccessibilityProgressIndicator::AccessibilityProgressIndicator(RenderProgress* renderer)
+ : AccessibilityRenderObject(renderer)
+{
+}
+
+PassRefPtr<AccessibilityProgressIndicator> AccessibilityProgressIndicator::create(RenderProgress* renderer)
+{
+ return adoptRef(new AccessibilityProgressIndicator(renderer));
+}
+
+bool AccessibilityProgressIndicator::accessibilityIsIgnored() const
+{
+ return accessibilityIsIgnoredBase() == IgnoreObject;
+}
+
+float AccessibilityProgressIndicator::valueForRange() const
+{
+ if (element()->position() >= 0)
+ return narrowPrecisionToFloat(element()->value());
+ // Indeterminate progress bar should return 0.
+ return 0.0f;
+}
+
+float AccessibilityProgressIndicator::maxValueForRange() const
+{
+ return narrowPrecisionToFloat(element()->max());
+}
+
+float AccessibilityProgressIndicator::minValueForRange() const
+{
+ return 0.0f;
+}
+
+HTMLProgressElement* AccessibilityProgressIndicator::element() const
+{
+ return toRenderProgress(m_renderer)->progressElement();
+}
+
+
+} // namespace WebCore
+
+#endif // ENABLE(PROGRESS_TAG)
diff --git a/WebCore/accessibility/AccessibilityProgressIndicator.h b/WebCore/accessibility/AccessibilityProgressIndicator.h
new file mode 100644
index 0000000..b52a619
--- /dev/null
+++ b/WebCore/accessibility/AccessibilityProgressIndicator.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef AccessibilityProgressIndicator_h
+#define AccessibilityProgressIndicator_h
+
+#if ENABLE(PROGRESS_TAG)
+
+#include "AccessibilityRenderObject.h"
+
+namespace WebCore {
+
+class HTMLProgressElement;
+class RenderProgress;
+
+class AccessibilityProgressIndicator : public AccessibilityRenderObject {
+public:
+ static PassRefPtr<AccessibilityProgressIndicator> create(RenderProgress*);
+
+private:
+ virtual AccessibilityRole roleValue() const { return ProgressIndicatorRole; }
+
+ virtual bool isProgressIndicator() const { return true; }
+
+ virtual float valueForRange() const;
+ virtual float maxValueForRange() const;
+ virtual float minValueForRange() const;
+
+ AccessibilityProgressIndicator(RenderProgress*);
+
+ HTMLProgressElement* element() const;
+ virtual bool accessibilityIsIgnored() const;
+};
+
+
+} // namespace WebCore
+
+#endif // ENABLE(PROGRESS_TAG)
+
+#endif // AccessibilityProgressIndicator_h
diff --git a/WebCore/accessibility/AccessibilityRenderObject.cpp b/WebCore/accessibility/AccessibilityRenderObject.cpp
index d738ca8..3463546 100644
--- a/WebCore/accessibility/AccessibilityRenderObject.cpp
+++ b/WebCore/accessibility/AccessibilityRenderObject.cpp
@@ -69,6 +69,7 @@
#include "RenderTheme.h"
#include "RenderView.h"
#include "RenderWidget.h"
+#include "SelectElement.h"
#include "SelectionController.h"
#include "Text.h"
#include "TextIterator.h"
@@ -547,15 +548,7 @@ AccessibilityObject* AccessibilityRenderObject::selectedTabItem()
const AtomicString& AccessibilityRenderObject::getAttribute(const QualifiedName& attribute) const
{
- Node* node = m_renderer->node();
- if (!node)
- return nullAtom;
-
- if (!node->isElementNode())
- return nullAtom;
-
- Element* element = static_cast<Element*>(node);
- return element->getAttribute(attribute);
+ return AccessibilityObject::getAttribute(m_renderer->node(), attribute);
}
Element* AccessibilityRenderObject::anchorElement() const
@@ -731,6 +724,15 @@ String AccessibilityRenderObject::helpText() const
if (!title.isEmpty())
return title;
}
+
+ // Only take help text from an ancestor element if its a group or an unknown role. If help was
+ // added to those kinds of elements, it is likely it was meant for a child element.
+ AccessibilityObject* axObj = axObjectCache()->getOrCreate(curr);
+ if (axObj) {
+ AccessibilityRole role = axObj->roleValue();
+ if (role != GroupRole && role != UnknownRole)
+ break;
+ }
}
return String();
@@ -775,18 +777,7 @@ String AccessibilityRenderObject::language() const
if (!m_renderer)
return String();
- // Defer to parent if this element doesn't have a language set
- Node* node = m_renderer->node();
- if (!node)
- return AccessibilityObject::language();
-
- if (!node->isElementNode())
- return AccessibilityObject::language();
-
- String language = static_cast<Element*>(node)->getAttribute(langAttr);
- if (language.isEmpty())
- return AccessibilityObject::language();
- return language;
+ return AccessibilityObject::language(m_renderer->node());
}
String AccessibilityRenderObject::textUnderElement() const
@@ -898,8 +889,22 @@ String AccessibilityRenderObject::stringValue() const
if (m_renderer->isText())
return textUnderElement();
- if (m_renderer->isMenuList())
+ if (m_renderer->isMenuList()) {
+ // RenderMenuList will go straight to the text() of its selected item.
+ // This has to be overriden in the case where the selected item has an aria label
+ SelectElement* selectNode = toSelectElement(static_cast<Element*>(m_renderer->node()));
+ int selectedIndex = selectNode->selectedIndex();
+ const Vector<Element*> listItems = selectNode->listItems();
+
+ 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;
+
return toRenderMenuList(m_renderer)->text();
+ }
if (m_renderer->isListMarker())
return toRenderListMarker(m_renderer)->text();
@@ -1133,6 +1138,13 @@ String AccessibilityRenderObject::accessibilityDescription() const
if (isWebArea()) {
Document* document = m_renderer->document();
+
+ // 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;
+
Node* owner = document->ownerElement();
if (owner) {
if (owner->hasTagName(frameTag) || owner->hasTagName(iframeTag)) {
@@ -1318,6 +1330,11 @@ bool AccessibilityRenderObject::hasTextAlternative() const
return false;
}
+bool AccessibilityRenderObject::ariaHasPopup() const
+{
+ return elementAttributeValue(aria_haspopupAttr);
+}
+
bool AccessibilityRenderObject::supportsARIAFlowTo() const
{
return !getAttribute(aria_flowtoAttr).string().isEmpty();
@@ -1339,13 +1356,13 @@ void AccessibilityRenderObject::ariaFlowToElements(AccessibilityChildrenVector&
}
-bool AccessibilityRenderObject::supportsARIADropping()
+bool AccessibilityRenderObject::supportsARIADropping() const
{
const AtomicString& dropEffect = getAttribute(aria_dropeffectAttr).string();
return !dropEffect.isEmpty();
}
-bool AccessibilityRenderObject::supportsARIADragging()
+bool AccessibilityRenderObject::supportsARIADragging() const
{
const AtomicString& grabbed = getAttribute(aria_grabbedAttr).string();
return equalIgnoringCase(grabbed, "true") || equalIgnoringCase(grabbed, "false");
@@ -1410,13 +1427,13 @@ AccessibilityObject* AccessibilityRenderObject::titleUIElement() const
bool AccessibilityRenderObject::ariaIsHidden() const
{
- if (equalIgnoringCase(getAttribute(aria_hiddenAttr).string(), "true"))
+ if (equalIgnoringCase(getAttribute(aria_hiddenAttr), "true"))
return true;
// aria-hidden hides this object and any children
AccessibilityObject* object = parentObject();
while (object) {
- if (object->isAccessibilityRenderObject() && equalIgnoringCase(static_cast<AccessibilityRenderObject*>(object)->getAttribute(aria_hiddenAttr).string(), "true"))
+ if (object->isAccessibilityRenderObject() && equalIgnoringCase(static_cast<AccessibilityRenderObject*>(object)->getAttribute(aria_hiddenAttr), "true"))
return true;
object = object->parentObject();
}
@@ -1456,26 +1473,43 @@ bool AccessibilityRenderObject::isAllowedChildOfTree() const
return true;
}
-bool AccessibilityRenderObject::accessibilityIsIgnored() const
+AccessibilityObjectInclusion AccessibilityRenderObject::accessibilityIsIgnoredBase() const
{
- // Is the platform interested in this object?
- AccessibilityObjectPlatformInclusion decision = accessibilityPlatformIncludesObject();
- if (decision == IncludeObject)
- return false;
- if (decision == IgnoreObject)
- return true;
- // the decision must, therefore, be DefaultBehavior.
-
- // ignore invisible element
+ // The following cases can apply to any element that's a subclass of AccessibilityRenderObject.
+
+ // Ignore invisible elements.
if (!m_renderer || m_renderer->style()->visibility() != VISIBLE)
- return true;
+ return IgnoreObject;
+ // Anything marked as aria-hidden or a child of something aria-hidden must be hidden.
if (ariaIsHidden())
- return true;
+ return IgnoreObject;
+ // Anything that is a presentational role must be hidden.
if (isPresentationalChildOfAriaRole())
- return true;
+ return IgnoreObject;
+
+ // Allow the platform to make a decision.
+ AccessibilityObjectInclusion decision = accessibilityPlatformIncludesObject();
+ if (decision == IncludeObject)
+ return IncludeObject;
+ if (decision == IgnoreObject)
+ return IgnoreObject;
+ return DefaultBehavior;
+}
+
+bool AccessibilityRenderObject::accessibilityIsIgnored() const
+{
+ // Check first if any of the common reasons cause this element to be ignored.
+ // Then process other use cases that need to be applied to all the various roles
+ // that AccessibilityRenderObjects take on.
+ AccessibilityObjectInclusion decision = accessibilityIsIgnoredBase();
+ if (decision == IncludeObject)
+ return false;
+ if (decision == IgnoreObject)
+ return true;
+
// If this element is within a parent that cannot have children, it should not be exposed.
if (isDescendantOfBarrenParent())
return true;
@@ -1531,6 +1565,9 @@ bool AccessibilityRenderObject::accessibilityIsIgnored() const
if (ariaRole != UnknownRole)
return false;
+
+ if (!helpText().isEmpty())
+ return false;
// don't ignore labels, because they serve as TitleUIElements
Node* node = m_renderer->node();
@@ -1547,6 +1584,10 @@ bool AccessibilityRenderObject::accessibilityIsIgnored() const
return false;
}
+ // if this element has aria attributes on it, it should not be ignored.
+ if (supportsARIAAttributes())
+ return false;
+
if (m_renderer->isBlockFlow() && m_renderer->childrenInline())
return !toRenderBlock(m_renderer)->firstLineBox() && !mouseButtonListener();
@@ -1779,7 +1820,8 @@ KURL AccessibilityRenderObject::url() const
bool AccessibilityRenderObject::isVisited() const
{
- return m_renderer->style()->pseudoState() == PseudoVisited;
+ // FIXME: Is it a privacy violation to expose visited information to accessibility APIs?
+ return m_renderer->style()->isLink() && m_renderer->style()->insideLink() == InsideVisitedLink;
}
bool AccessibilityRenderObject::isExpanded() const
@@ -2479,14 +2521,21 @@ AccessibilityObject* AccessibilityRenderObject::doAccessibilityHitTest(const Int
if (node->hasTagName(areaTag))
return accessibilityImageMapHitTest(static_cast<HTMLAreaElement*>(node), point);
+ if (node->hasTagName(optionTag))
+ node = static_cast<HTMLOptionElement*>(node)->ownerSelectElement();
+
RenderObject* obj = node->renderer();
if (!obj)
return 0;
AccessibilityObject* result = obj->document()->axObjectCache()->getOrCreate(obj);
- if (obj->isListBox())
- return static_cast<AccessibilityListBox*>(result)->doAccessibilityHitTest(point);
+ if (obj->isListBox()) {
+ // Make sure the children are initialized so that hit testing finds the right element.
+ AccessibilityListBox* listBox = static_cast<AccessibilityListBox*>(result);
+ listBox->updateChildrenIfNecessary();
+ return listBox->doAccessibilityHitTest(point);
+ }
if (result->accessibilityIsIgnored()) {
// If this element is the label of a control, a hit test should return the control.
@@ -2605,11 +2654,25 @@ AccessibilityObject* AccessibilityRenderObject::correspondingLabelForControlElem
return 0;
}
+bool AccessibilityRenderObject::renderObjectIsObservable(RenderObject* renderer) const
+{
+ // AX clients will listen for AXValueChange on a text control.
+ if (renderer->isTextControl())
+ return true;
+
+ // AX clients will listen for AXSelectedChildrenChanged on listboxes.
+ if (renderer->isListBox() || axObjectCache()->nodeHasRole(renderer->node(), "listbox"))
+ return true;
+
+ return false;
+}
+
AccessibilityObject* AccessibilityRenderObject::observableObject() const
{
+ // Find the object going up the parent chain that is used in accessibility to monitor certain notifications.
for (RenderObject* renderer = m_renderer; renderer && renderer->node(); renderer = renderer->parent()) {
- if (renderer->isTextControl())
- return renderer->document()->axObjectCache()->getOrCreate(renderer);
+ if (renderObjectIsObservable(renderer))
+ return axObjectCache()->getOrCreate(renderer);
}
return 0;
@@ -2623,7 +2686,7 @@ AccessibilityRole AccessibilityRenderObject::determineAriaRoleAttribute() const
AccessibilityRole role = ariaRoleToWebCoreRole(ariaRole);
- if (role == ButtonRole && elementAttributeValue(aria_haspopupAttr))
+ if (role == ButtonRole && ariaHasPopup())
role = PopUpButtonRole;
if (role)
@@ -2726,7 +2789,19 @@ AccessibilityRole AccessibilityRenderObject::determineAccessibilityRole()
if (node && (node->hasTagName(rpTag) || node->hasTagName(rtTag)))
return AnnotationRole;
-
+
+#if PLATFORM(GTK)
+ // Gtk ATs expect all tables, data and layout, to be exposed as tables.
+ if (node && (node->hasTagName(tdTag) || node->hasTagName(thTag)))
+ return CellRole;
+
+ if (node && node->hasTagName(trTag))
+ return RowRole;
+
+ if (node && node->hasTagName(tableTag))
+ return TableRole;
+#endif
+
if (m_renderer->isBlockFlow() || (node && node->hasTagName(labelTag)))
return GroupRole;
@@ -2761,7 +2836,7 @@ bool AccessibilityRenderObject::ariaRoleHasPresentationalChildren() const
case SliderRole:
case ImageRole:
case ProgressIndicatorRole:
- //case SeparatorRole:
+ // case SeparatorRole:
return true;
default:
return false;
@@ -2794,7 +2869,7 @@ bool AccessibilityRenderObject::canSetFocusAttribute() const
case SliderRole:
return true;
default:
- return false;
+ return node->supportsFocus();
}
}
@@ -2823,8 +2898,9 @@ bool AccessibilityRenderObject::canSetTextRangeAttributes() const
void AccessibilityRenderObject::contentChanged()
{
// If this element supports ARIA live regions, then notify the AT of changes.
- for (RenderObject* renderParent = m_renderer->parent(); renderParent; renderParent = renderParent->parent()) {
- AccessibilityObject* parent = m_renderer->document()->axObjectCache()->get(renderParent);
+ AXObjectCache* cache = m_renderer->document()->axObjectCache();
+ for (RenderObject* renderParent = m_renderer; renderParent; renderParent = renderParent->parent()) {
+ AccessibilityObject* parent = cache->get(renderParent);
if (!parent)
continue;
@@ -2889,15 +2965,25 @@ bool AccessibilityRenderObject::canHaveChildren() const
}
}
-const AccessibilityObject::AccessibilityChildrenVector& AccessibilityRenderObject::children()
+void AccessibilityRenderObject::clearChildren()
{
- if (m_childrenDirty) {
+ AccessibilityObject::clearChildren();
+ m_childrenDirty = false;
+}
+
+void AccessibilityRenderObject::updateChildrenIfNecessary()
+{
+ if (needsToUpdateChildren())
clearChildren();
- m_childrenDirty = false;
- }
- if (!m_haveChildren)
- addChildren();
+ if (!hasChildren())
+ addChildren();
+}
+
+const AccessibilityObject::AccessibilityChildrenVector& AccessibilityRenderObject::children()
+{
+ updateChildrenIfNecessary();
+
return m_children;
}
@@ -3026,32 +3112,18 @@ void AccessibilityRenderObject::ariaSelectedRows(AccessibilityChildrenVector& re
void AccessibilityRenderObject::ariaListboxSelectedChildren(AccessibilityChildrenVector& result)
{
- AccessibilityObject* child = firstChild();
-
- Element* element = static_cast<Element*>(renderer()->node());
- if (!element || !element->isElementNode()) // do this check to ensure safety of static_cast above
- return;
-
bool isMulti = isMultiSelectable();
-
- while (child) {
- // every child should have aria-role option, and if so, check for selected attribute/state
- AccessibilityRole ariaRole = child->ariaRoleAttribute();
- RenderObject* childRenderer = 0;
- if (child->isAccessibilityRenderObject())
- childRenderer = static_cast<AccessibilityRenderObject*>(child)->renderer();
- if (childRenderer && ariaRole == ListBoxOptionRole) {
- Element* childElement = static_cast<Element*>(childRenderer->node());
- if (childElement && childElement->isElementNode()) { // do this check to ensure safety of static_cast above
- String selectedAttrString = childElement->getAttribute(aria_selectedAttr).string();
- if (equalIgnoringCase(selectedAttrString, "true")) {
- result.append(child);
- if (isMulti)
- return;
- }
- }
+
+ AccessibilityChildrenVector childObjects = children();
+ unsigned childrenSize = childObjects.size();
+ for (unsigned k = 0; k < childrenSize; ++k) {
+ // Every child should have aria-role option, and if so, check for selected attribute/state.
+ AccessibilityObject* child = childObjects[k].get();
+ if (child->isSelected() && child->ariaRoleAttribute() == ListBoxOptionRole) {
+ result.append(child);
+ if (!isMulti)
+ return;
}
- child = child->nextSibling();
}
}
@@ -3130,7 +3202,24 @@ const String& AccessibilityRenderObject::actionVerb() const
return noAction;
}
}
-
+
+void AccessibilityRenderObject::setAccessibleName(String& name)
+{
+ // Setting the accessible name can store the value in the DOM
+ if (!m_renderer)
+ return;
+
+ Node* domNode = 0;
+ // For web areas, set the aria-label on the HTML element.
+ if (isWebArea())
+ domNode = m_renderer->document()->documentElement();
+ else
+ domNode = m_renderer->node();
+
+ if (domNode && domNode->isElementNode())
+ static_cast<Element*>(domNode)->setAttribute(aria_labelAttr, name);
+}
+
void AccessibilityRenderObject::updateBackingStore()
{
if (!m_renderer)
diff --git a/WebCore/accessibility/AccessibilityRenderObject.h b/WebCore/accessibility/AccessibilityRenderObject.h
index 6735076..494e6bb 100644
--- a/WebCore/accessibility/AccessibilityRenderObject.h
+++ b/WebCore/accessibility/AccessibilityRenderObject.h
@@ -114,6 +114,10 @@ public:
virtual bool hasIntValue() const;
+ virtual void setAccessibleName(String&);
+
+ // Provides common logic used by all elements when determining isIgnored.
+ AccessibilityObjectInclusion accessibilityIsIgnoredBase() const;
virtual bool accessibilityIsIgnored() const;
virtual int headingLevel() const;
@@ -191,10 +195,11 @@ public:
virtual Widget* widgetForAttachmentView() const;
virtual void getDocumentLinks(AccessibilityChildrenVector&);
virtual FrameView* documentFrameView() const;
- virtual String language() const;
virtual unsigned hierarchicalLevel() const;
virtual const AccessibilityChildrenVector& children();
+ virtual void clearChildren();
+ void updateChildrenIfNecessary();
virtual void setFocused(bool);
virtual void setSelectedTextRange(const PlainTextRange&);
@@ -224,9 +229,10 @@ public:
virtual void setSelectedVisiblePositionRange(const VisiblePositionRange&) const;
virtual bool supportsARIAFlowTo() const;
virtual void ariaFlowToElements(AccessibilityChildrenVector&) const;
+ virtual bool ariaHasPopup() const;
- virtual bool supportsARIADropping();
- virtual bool supportsARIADragging();
+ virtual bool supportsARIADropping() const;
+ virtual bool supportsARIADragging() const;
virtual bool isARIAGrabbed();
virtual void setARIAGrabbed(bool);
virtual void determineARIADropEffects(Vector<String>&);
@@ -259,6 +265,7 @@ protected:
void setRenderObject(RenderObject* renderer) { m_renderer = renderer; }
void ariaLabeledByElements(Vector<Element*>& elements) const;
+ bool needsToUpdateChildren() const { return m_childrenDirty; }
virtual bool isDetached() const { return !m_renderer; }
@@ -270,6 +277,7 @@ private:
bool isAllowedChildOfTree() const;
bool hasTextAlternative() const;
String positionalDescriptionForMSAA() const;
+ virtual String language() const;
Element* menuElementForMenuButton() const;
Element* menuItemElementForMenu() const;
@@ -282,7 +290,8 @@ private:
AccessibilityObject* internalLinkElement() const;
AccessibilityObject* accessibilityImageMapHitTest(HTMLAreaElement*, const IntPoint&) const;
AccessibilityObject* accessibilityParentForImageMap(HTMLMapElement* map) const;
-
+ bool renderObjectIsObservable(RenderObject*) const;
+
void ariaSelectedRows(AccessibilityChildrenVector&);
bool elementAttributeValue(const QualifiedName&) const;
@@ -297,7 +306,6 @@ private:
virtual bool ariaLiveRegionBusy() const;
void setNeedsToUpdateChildren() const { m_childrenDirty = true; }
- bool needsToUpdateChildren() const { return m_childrenDirty; }
mutable AccessibilityRole m_roleForMSAA;
};
diff --git a/WebCore/accessibility/AccessibilitySlider.cpp b/WebCore/accessibility/AccessibilitySlider.cpp
index 77f4dcc..e8d1f41 100644
--- a/WebCore/accessibility/AccessibilitySlider.cpp
+++ b/WebCore/accessibility/AccessibilitySlider.cpp
@@ -99,6 +99,17 @@ const AtomicString& AccessibilitySlider::getAttribute(const QualifiedName& attri
return element()->getAttribute(attribute);
}
+bool AccessibilitySlider::accessibilityIsIgnored() const
+{
+ AccessibilityObjectInclusion decision = accessibilityIsIgnoredBase();
+ if (decision == IncludeObject)
+ return false;
+ if (decision == IgnoreObject)
+ return true;
+
+ return false;
+}
+
float AccessibilitySlider::valueForRange() const
{
return element()->value().toFloat();
diff --git a/WebCore/accessibility/AccessibilitySlider.h b/WebCore/accessibility/AccessibilitySlider.h
index e1e3812..461f62b 100644
--- a/WebCore/accessibility/AccessibilitySlider.h
+++ b/WebCore/accessibility/AccessibilitySlider.h
@@ -42,7 +42,6 @@ public:
virtual ~AccessibilitySlider() { }
virtual AccessibilityRole roleValue() const { return SliderRole; }
- virtual bool accessibilityIsIgnored() const { return false; }
virtual bool isSlider() const { return true; }
@@ -63,6 +62,7 @@ protected:
private:
HTMLInputElement* element() const;
+ virtual bool accessibilityIsIgnored() const;
};
class AccessibilitySliderThumb : public AccessibilityObject {
@@ -72,7 +72,6 @@ public:
virtual ~AccessibilitySliderThumb() { }
virtual AccessibilityRole roleValue() const { return SliderThumbRole; }
- virtual bool accessibilityIsIgnored() const { return false; }
void setParentObject(AccessibilitySlider* slider) { m_parentSlider = slider; }
virtual AccessibilityObject* parentObject() const { return m_parentSlider; }
@@ -82,6 +81,7 @@ public:
private:
AccessibilitySliderThumb();
+ virtual bool accessibilityIsIgnored() const { return false; }
AccessibilitySlider* m_parentSlider;
};
diff --git a/WebCore/accessibility/AccessibilityTable.cpp b/WebCore/accessibility/AccessibilityTable.cpp
index 9ac1046..aed8867 100644
--- a/WebCore/accessibility/AccessibilityTable.cpp
+++ b/WebCore/accessibility/AccessibilityTable.cpp
@@ -94,6 +94,11 @@ bool AccessibilityTable::isTableExposableThroughAccessibility()
Node* tableNode = table->node();
if (!tableNode || !tableNode->hasTagName(tableTag))
return false;
+
+ // Gtk+ ATs expect all tables to be exposed as tables.
+#if PLATFORM(GTK)
+ return true;
+#endif
// if there is a caption element, summary, THEAD, or TFOOT section, it's most certainly a data table
HTMLTableElement* tableElement = static_cast<HTMLTableElement*>(tableNode);
@@ -193,10 +198,9 @@ bool AccessibilityTable::isTableExposableThroughAccessibility()
void AccessibilityTable::clearChildren()
{
- m_children.clear();
+ AccessibilityRenderObject::clearChildren();
m_rows.clear();
m_columns.clear();
- m_haveChildren = false;
}
void AccessibilityTable::addChildren()
@@ -251,7 +255,12 @@ void AccessibilityTable::addChildren()
row->setRowIndex((int)m_rows.size());
m_rows.append(row);
- m_children.append(row);
+ if (!row->accessibilityIsIgnored())
+ m_children.append(row);
+#if PLATFORM(GTK)
+ else
+ m_children.append(row->children());
+#endif
appendedRows.add(row);
}
}
@@ -266,11 +275,12 @@ void AccessibilityTable::addChildren()
column->setColumnIndex((int)i);
column->setParentTable(this);
m_columns.append(column);
- m_children.append(column);
+ if (!column->accessibilityIsIgnored())
+ m_children.append(column);
}
AccessibilityObject* headerContainerObject = headerContainer();
- if (headerContainerObject)
+ if (headerContainerObject && !headerContainerObject->accessibilityIsIgnored())
m_children.append(headerContainerObject);
}
@@ -287,17 +297,15 @@ AccessibilityObject* AccessibilityTable::headerContainer()
AccessibilityObject::AccessibilityChildrenVector& AccessibilityTable::columns()
{
- if (!hasChildren())
- addChildren();
+ updateChildrenIfNecessary();
return m_columns;
}
AccessibilityObject::AccessibilityChildrenVector& AccessibilityTable::rows()
{
- if (!hasChildren())
- addChildren();
-
+ updateChildrenIfNecessary();
+
return m_rows;
}
@@ -306,8 +314,7 @@ void AccessibilityTable::rowHeaders(AccessibilityChildrenVector& headers)
if (!m_renderer)
return;
- if (!hasChildren())
- addChildren();
+ updateChildrenIfNecessary();
unsigned rowCount = m_rows.size();
for (unsigned k = 0; k < rowCount; ++k) {
@@ -323,8 +330,7 @@ void AccessibilityTable::columnHeaders(AccessibilityChildrenVector& headers)
if (!m_renderer)
return;
- if (!hasChildren())
- addChildren();
+ updateChildrenIfNecessary();
unsigned colCount = m_columns.size();
for (unsigned k = 0; k < colCount; ++k) {
@@ -340,8 +346,7 @@ void AccessibilityTable::cells(AccessibilityObject::AccessibilityChildrenVector&
if (!m_renderer)
return;
- if (!hasChildren())
- addChildren();
+ updateChildrenIfNecessary();
int numRows = m_rows.size();
for (int row = 0; row < numRows; ++row) {
@@ -352,16 +357,14 @@ void AccessibilityTable::cells(AccessibilityObject::AccessibilityChildrenVector&
unsigned AccessibilityTable::columnCount()
{
- if (!hasChildren())
- addChildren();
+ updateChildrenIfNecessary();
return m_columns.size();
}
unsigned AccessibilityTable::rowCount()
{
- if (!hasChildren())
- addChildren();
+ updateChildrenIfNecessary();
return m_rows.size();
}
@@ -371,8 +374,7 @@ AccessibilityTableCell* AccessibilityTable::cellForColumnAndRow(unsigned column,
if (!m_renderer || !m_renderer->isTable())
return 0;
- if (!hasChildren())
- addChildren();
+ updateChildrenIfNecessary();
RenderTable* table = toRenderTable(m_renderer);
RenderTableSection* tableSection = table->header();
@@ -448,9 +450,15 @@ AccessibilityRole AccessibilityTable::roleValue() const
bool AccessibilityTable::accessibilityIsIgnored() const
{
+ AccessibilityObjectInclusion decision = accessibilityIsIgnoredBase();
+ if (decision == IncludeObject)
+ return false;
+ if (decision == IgnoreObject)
+ return true;
+
if (!isDataTable())
return AccessibilityRenderObject::accessibilityIsIgnored();
-
+
return false;
}
diff --git a/WebCore/accessibility/AccessibilityTableCell.cpp b/WebCore/accessibility/AccessibilityTableCell.cpp
index 7674cb8..318c619 100644
--- a/WebCore/accessibility/AccessibilityTableCell.cpp
+++ b/WebCore/accessibility/AccessibilityTableCell.cpp
@@ -56,6 +56,12 @@ PassRefPtr<AccessibilityTableCell> AccessibilityTableCell::create(RenderObject*
bool AccessibilityTableCell::accessibilityIsIgnored() const
{
+ AccessibilityObjectInclusion decision = accessibilityIsIgnoredBase();
+ if (decision == IncludeObject)
+ return false;
+ if (decision == IgnoreObject)
+ return true;
+
if (!isTableCell())
return AccessibilityRenderObject::accessibilityIsIgnored();
diff --git a/WebCore/accessibility/AccessibilityTableColumn.cpp b/WebCore/accessibility/AccessibilityTableColumn.cpp
index ee8531e..5872706 100644
--- a/WebCore/accessibility/AccessibilityTableColumn.cpp
+++ b/WebCore/accessibility/AccessibilityTableColumn.cpp
@@ -158,6 +158,18 @@ AccessibilityObject* AccessibilityTableColumn::headerObjectForSection(RenderTabl
return m_parentTable->axObjectCache()->getOrCreate(cell);
}
+bool AccessibilityTableColumn::accessibilityIsIgnored() const
+{
+ if (!m_parentTable)
+ return true;
+
+#if PLATFORM(GTK)
+ return true;
+#endif
+
+ return m_parentTable->accessibilityIsIgnored();
+}
+
void AccessibilityTableColumn::addChildren()
{
ASSERT(!m_haveChildren);
diff --git a/WebCore/accessibility/AccessibilityTableColumn.h b/WebCore/accessibility/AccessibilityTableColumn.h
index 6270398..15d300c 100644
--- a/WebCore/accessibility/AccessibilityTableColumn.h
+++ b/WebCore/accessibility/AccessibilityTableColumn.h
@@ -49,8 +49,8 @@ public:
virtual AccessibilityObject* parentObject() const { return m_parentTable; }
AccessibilityObject* headerObject();
+ virtual bool accessibilityIsIgnored() const;
virtual AccessibilityRole roleValue() const { return ColumnRole; }
- virtual bool accessibilityIsIgnored() const { return false; }
virtual bool isTableColumn() const { return true; }
void setColumnIndex(int columnIndex) { m_columnIndex = columnIndex; }
diff --git a/WebCore/accessibility/AccessibilityTableHeaderContainer.cpp b/WebCore/accessibility/AccessibilityTableHeaderContainer.cpp
index 3a2a241..e2da83c 100644
--- a/WebCore/accessibility/AccessibilityTableHeaderContainer.cpp
+++ b/WebCore/accessibility/AccessibilityTableHeaderContainer.cpp
@@ -68,6 +68,18 @@ IntSize AccessibilityTableHeaderContainer::size() const
return elementRect().size();
}
+bool AccessibilityTableHeaderContainer::accessibilityIsIgnored() const
+{
+ if (!m_parentTable)
+ return true;
+
+#if PLATFORM(GTK)
+ return true;
+#endif
+
+ return m_parentTable->accessibilityIsIgnored();
+}
+
void AccessibilityTableHeaderContainer::addChildren()
{
ASSERT(!m_haveChildren);
diff --git a/WebCore/accessibility/AccessibilityTableHeaderContainer.h b/WebCore/accessibility/AccessibilityTableHeaderContainer.h
index 8a9448a..79521c0 100644
--- a/WebCore/accessibility/AccessibilityTableHeaderContainer.h
+++ b/WebCore/accessibility/AccessibilityTableHeaderContainer.h
@@ -48,8 +48,6 @@ public:
void setParentTable(AccessibilityTable* table) { m_parentTable = table; }
virtual AccessibilityObject* parentObject() const { return m_parentTable; }
- virtual bool accessibilityIsIgnored() const { return false; }
-
virtual const AccessibilityChildrenVector& children();
virtual void addChildren();
@@ -60,6 +58,7 @@ private:
AccessibilityTable* m_parentTable;
IntRect m_headerRect;
+ virtual bool accessibilityIsIgnored() const;
};
} // namespace WebCore
diff --git a/WebCore/accessibility/AccessibilityTableRow.cpp b/WebCore/accessibility/AccessibilityTableRow.cpp
index 71f8b2b..e2a1157 100644
--- a/WebCore/accessibility/AccessibilityTableRow.cpp
+++ b/WebCore/accessibility/AccessibilityTableRow.cpp
@@ -76,6 +76,12 @@ bool AccessibilityTableRow::isTableRow() const
bool AccessibilityTableRow::accessibilityIsIgnored() const
{
+ AccessibilityObjectInclusion decision = accessibilityIsIgnoredBase();
+ if (decision == IncludeObject)
+ return false;
+ if (decision == IgnoreObject)
+ return true;
+
if (!isTableRow())
return AccessibilityRenderObject::accessibilityIsIgnored();
diff --git a/WebCore/accessibility/chromium/AccessibilityObjectChromium.cpp b/WebCore/accessibility/chromium/AccessibilityObjectChromium.cpp
index 6749f77..5b4cfd5 100644
--- a/WebCore/accessibility/chromium/AccessibilityObjectChromium.cpp
+++ b/WebCore/accessibility/chromium/AccessibilityObjectChromium.cpp
@@ -34,7 +34,7 @@ bool AccessibilityObject::accessibilityIgnoreAttachment() const
return false;
}
-AccessibilityObjectPlatformInclusion AccessibilityObject::accessibilityPlatformIncludesObject() const
+AccessibilityObjectInclusion AccessibilityObject::accessibilityPlatformIncludesObject() const
{
if (isMenuListPopup() || isMenuListOption())
return IgnoreObject;
diff --git a/WebCore/accessibility/efl/AccessibilityObjectEfl.cpp b/WebCore/accessibility/efl/AccessibilityObjectEfl.cpp
new file mode 100644
index 0000000..d57c3fa
--- /dev/null
+++ b/WebCore/accessibility/efl/AccessibilityObjectEfl.cpp
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2008 Apple Ltd.
+ * Copyright (C) 2009-2010 ProFUSION embedded systems
+ * Copyright (C) 2009-2010 Samsung Electronics
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "AccessibilityObject.h"
+
+#if HAVE(ACCESSIBILITY)
+
+namespace WebCore {
+
+bool AccessibilityObject::accessibilityIgnoreAttachment() const
+{
+ return false;
+}
+
+} // namespace WebCore
+
+#endif // HAVE(ACCESSIBILITY)
diff --git a/WebCore/accessibility/gtk/AccessibilityObjectAtk.cpp b/WebCore/accessibility/gtk/AccessibilityObjectAtk.cpp
index f48770f..ca3e8cc 100644
--- a/WebCore/accessibility/gtk/AccessibilityObjectAtk.cpp
+++ b/WebCore/accessibility/gtk/AccessibilityObjectAtk.cpp
@@ -32,7 +32,7 @@ bool AccessibilityObject::accessibilityIgnoreAttachment() const
return false;
}
-AccessibilityObjectPlatformInclusion AccessibilityObject::accessibilityPlatformIncludesObject() const
+AccessibilityObjectInclusion AccessibilityObject::accessibilityPlatformIncludesObject() const
{
AccessibilityObject* parent = parentObject();
if (!parent)
@@ -41,17 +41,34 @@ AccessibilityObjectPlatformInclusion AccessibilityObject::accessibilityPlatformI
if (isMenuListPopup() || isMenuListOption())
return IgnoreObject;
- // When a list item is made up entirely of children (e.g. paragraphs)
- // the list item gets ignored. We need it.
- if (isGroup() && parent->isList())
- return IncludeObject;
+ if (isGroup()) {
+ // When a list item is made up entirely of children (e.g. paragraphs)
+ // the list item gets ignored. We need it.
+ if (parent->isList())
+ return IncludeObject;
+
+ // We expect the parent of a table cell to be a table.
+ AccessibilityObject* child = firstChild();
+ if (child && child->roleValue() == CellRole)
+ return IgnoreObject;
+ }
// Entries and password fields have extraneous children which we want to ignore.
if (parent->isPasswordField() || parent->isTextControl())
return IgnoreObject;
+ AccessibilityRole role = roleValue();
+
+ // Include all tables, even layout tables. The AT can decide what to do with each.
+ if (role == CellRole || role == TableRole)
+ return IncludeObject;
+
+ // We at some point might have a need to expose a table row; but it's not standard Gtk+.
+ if (role == RowRole)
+ return IgnoreObject;
+
// The object containing the text should implement AtkText itself.
- if (roleValue() == StaticTextRole)
+ if (role == StaticTextRole)
return IgnoreObject;
return DefaultBehavior;
diff --git a/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp b/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp
index 487fa5b..ffef2a8 100644
--- a/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp
+++ b/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp
@@ -42,7 +42,6 @@
#include "AccessibilityTableColumn.h"
#include "AccessibilityTableRow.h"
#include "AtomicString.h"
-#include "CString.h"
#include "Document.h"
#include "DocumentType.h"
#include "Editor.h"
@@ -57,6 +56,7 @@
#include "NotImplemented.h"
#include "RenderText.h"
#include "TextEncoding.h"
+#include <wtf/text/CString.h>
#include <atk/atk.h>
#include <glib.h>
@@ -448,6 +448,8 @@ static AtkRole webkit_accessible_get_role(AtkObject* object)
return ATK_ROLE_LABEL;
if (node->hasTagName(HTMLNames::divTag))
return ATK_ROLE_SECTION;
+ if (node->hasTagName(HTMLNames::formTag))
+ return ATK_ROLE_FORM;
}
}
@@ -996,8 +998,13 @@ static gint webkit_accessible_text_get_caret_offset(AtkText* text)
// coreObject is the unignored object whose offset the caller is requesting.
// focusedObject is the object with the caret. It is likely ignored -- unless it's a link.
AccessibilityObject* coreObject = core(text);
- RenderObject* focusedNode = coreObject->selection().end().node()->renderer();
- AccessibilityObject* focusedObject = coreObject->document()->axObjectCache()->getOrCreate(focusedNode);
+ Node* focusedNode = coreObject->selection().end().node();
+
+ if (!focusedNode)
+ return 0;
+
+ RenderObject* focusedRenderer = focusedNode->renderer();
+ AccessibilityObject* focusedObject = coreObject->document()->axObjectCache()->getOrCreate(focusedRenderer);
int offset;
// Don't ignore links if the offset is being requested for a link.
@@ -1563,7 +1570,7 @@ static const gchar* webkit_accessible_document_get_locale(AtkDocument* document)
{
// TODO: Should we fall back on lang xml:lang when the following comes up empty?
- String language = static_cast<AccessibilityRenderObject*>(core(document))->language();
+ String language = core(document)->language();
if (!language.isEmpty())
return returnString(language);
@@ -1656,7 +1663,7 @@ static guint16 getInterfaceMaskFromObject(AccessibilityObject* coreObject)
interfaceMask |= 1 << WAI_TEXT;
if (!coreObject->isReadOnly())
interfaceMask |= 1 << WAI_EDITABLE_TEXT;
- } else if (static_cast<AccessibilityRenderObject*>(coreObject)->renderer()->childrenInline())
+ } else if (role != TableRole && static_cast<AccessibilityRenderObject*>(coreObject)->renderer()->childrenInline())
interfaceMask |= 1 << WAI_TEXT;
// Image
diff --git a/WebCore/accessibility/mac/AccessibilityObjectMac.mm b/WebCore/accessibility/mac/AccessibilityObjectMac.mm
index 1807a9b..37fa65a 100644
--- a/WebCore/accessibility/mac/AccessibilityObjectMac.mm
+++ b/WebCore/accessibility/mac/AccessibilityObjectMac.mm
@@ -41,7 +41,7 @@ bool AccessibilityObject::accessibilityIgnoreAttachment() const
return [attachment accessibilityIsIgnored];
}
-AccessibilityObjectPlatformInclusion AccessibilityObject::accessibilityPlatformIncludesObject() const
+AccessibilityObjectInclusion AccessibilityObject::accessibilityPlatformIncludesObject() const
{
if (isMenuListPopup() || isMenuListOption())
return IgnoreObject;
diff --git a/WebCore/accessibility/mac/AccessibilityObjectWrapper.h b/WebCore/accessibility/mac/AccessibilityObjectWrapper.h
index 1f0a9e3..e6cc706 100644
--- a/WebCore/accessibility/mac/AccessibilityObjectWrapper.h
+++ b/WebCore/accessibility/mac/AccessibilityObjectWrapper.h
@@ -53,7 +53,7 @@ class VisiblePosition;
- (WebCore::AccessibilityObject*)accessibilityObject;
// Used to inform an element when a notification is posted for it. Used by DRT.
-- (void)accessibilityPostedNotification:(NSString *)notification;
+- (void)accessibilityPostedNotification:(NSString *)notificationName;
- (NSView*)attachmentView;
diff --git a/WebCore/accessibility/mac/AccessibilityObjectWrapper.mm b/WebCore/accessibility/mac/AccessibilityObjectWrapper.mm
index b53b167..f13968d 100644
--- a/WebCore/accessibility/mac/AccessibilityObjectWrapper.mm
+++ b/WebCore/accessibility/mac/AccessibilityObjectWrapper.mm
@@ -152,6 +152,10 @@ using namespace std;
#define NSAccessibilityLoadingProgressAttribute @"AXLoadingProgress"
#endif
+#ifndef NSAccessibilityHasPopupAttribute
+#define NSAccessibilityHasPopupAttribute @"AXHasPopup"
+#endif
+
#ifdef BUILDING_ON_TIGER
typedef unsigned NSUInteger;
#define NSAccessibilityValueDescriptionAttribute @"AXValueDescription"
@@ -634,6 +638,9 @@ static WebCoreTextMarkerRange* textMarkerRangeFromVisiblePositions(VisiblePositi
[additional addObject:NSAccessibilityARIABusyAttribute];
}
+ if (m_object->ariaHasPopup())
+ [additional addObject:NSAccessibilityHasPopupAttribute];
+
return additional;
}
@@ -1850,6 +1857,9 @@ static NSString* roleValueToNSString(AccessibilityRole value)
return dropEffectsArray;
}
+ if ([attributeName isEqualToString:NSAccessibilityHasPopupAttribute])
+ return [NSNumber numberWithBool:m_object->ariaHasPopup()];
+
// ARIA Live region attributes.
if ([attributeName isEqualToString:NSAccessibilityARIALiveAttribute])
return m_object->ariaLiveRegionStatus();
@@ -2657,22 +2667,19 @@ static RenderObject* rendererForView(NSView* view)
return [super accessibilityArrayAttributeValues:attribute index:index maxCount:maxCount];
}
-// These are used by DRT so that it can know when notifications are sent.
-// Since they are static, only one callback can be installed at a time (that's all DRT should need).
-typedef void (*AXPostedNotificationCallback)(id element, NSString* notification, void* context);
-static AXPostedNotificationCallback AXNotificationCallback = 0;
-static void* AXPostedNotificationContext = 0;
-
-- (void)accessibilitySetPostedNotificationCallback:(AXPostedNotificationCallback)function withContext:(void*)context
+// This is set by DRT when it wants to listen for notifications.
+static BOOL accessibilityShouldRepostNotifications;
+- (void)accessibilitySetShouldRepostNotifications:(BOOL)repost
{
- AXNotificationCallback = function;
- AXPostedNotificationContext = context;
+ accessibilityShouldRepostNotifications = repost;
}
-- (void)accessibilityPostedNotification:(NSString *)notification
+- (void)accessibilityPostedNotification:(NSString *)notificationName
{
- if (AXNotificationCallback)
- AXNotificationCallback(self, notification, AXPostedNotificationContext);
+ if (accessibilityShouldRepostNotifications) {
+ NSDictionary* userInfo = [NSDictionary dictionaryWithObjectsAndKeys:notificationName, @"notificationName", nil];
+ [[NSNotificationCenter defaultCenter] postNotificationName:@"AXDRTNotification" object:nil userInfo:userInfo];
+ }
}
@end
diff --git a/WebCore/accessibility/qt/AccessibilityObjectQt.cpp b/WebCore/accessibility/qt/AccessibilityObjectQt.cpp
index 5d85f1e..7232642 100644
--- a/WebCore/accessibility/qt/AccessibilityObjectQt.cpp
+++ b/WebCore/accessibility/qt/AccessibilityObjectQt.cpp
@@ -29,7 +29,7 @@ bool AccessibilityObject::accessibilityIgnoreAttachment() const
return false;
}
-AccessibilityObjectPlatformInclusion AccessibilityObject::accessibilityPlatformIncludesObject() const
+AccessibilityObjectInclusion AccessibilityObject::accessibilityPlatformIncludesObject() const
{
if (isMenuListPopup() || isMenuListOption())
return IgnoreObject;
diff --git a/WebCore/accessibility/win/AccessibilityObjectWin.cpp b/WebCore/accessibility/win/AccessibilityObjectWin.cpp
index a86988f..44122ef 100644
--- a/WebCore/accessibility/win/AccessibilityObjectWin.cpp
+++ b/WebCore/accessibility/win/AccessibilityObjectWin.cpp
@@ -35,7 +35,7 @@ bool AccessibilityObject::accessibilityIgnoreAttachment() const
return false;
}
-AccessibilityObjectPlatformInclusion AccessibilityObject::accessibilityPlatformIncludesObject() const
+AccessibilityObjectInclusion AccessibilityObject::accessibilityPlatformIncludesObject() const
{
if (isMenuListPopup() || isMenuListOption())
return IncludeObject;
diff --git a/WebCore/accessibility/wx/AccessibilityObjectWx.cpp b/WebCore/accessibility/wx/AccessibilityObjectWx.cpp
index 5d85f1e..7232642 100644
--- a/WebCore/accessibility/wx/AccessibilityObjectWx.cpp
+++ b/WebCore/accessibility/wx/AccessibilityObjectWx.cpp
@@ -29,7 +29,7 @@ bool AccessibilityObject::accessibilityIgnoreAttachment() const
return false;
}
-AccessibilityObjectPlatformInclusion AccessibilityObject::accessibilityPlatformIncludesObject() const
+AccessibilityObjectInclusion AccessibilityObject::accessibilityPlatformIncludesObject() const
{
if (isMenuListPopup() || isMenuListOption())
return IgnoreObject;