Commit 7c100313 authored by bdakin@apple.com's avatar bdakin@apple.com

2008-05-13 Beth Dakin <bdakin@apple.com>

        Reviewed by Brady.

        This patch adds support for the ARIA progressbar role and the 
        following ARIA states (ie HTML attributes): aria-checked, aria-
        level, aria-pressed, aria-valuenow, aria-valuemin, and aria-
        valuemax.

        * html/HTMLAttributeNames.in:
        * page/AccessibilityObject.h:
        (WebCore::AccessibilityObject::isProgressIndicator):
        (WebCore::AccessibilityObject::valueForRange):
        (WebCore::AccessibilityObject::maxValueForRange):
        (WebCore::AccessibilityObject::minValueForRange):
        * page/AccessibilityRenderObject.cpp:
        (WebCore::AccessibilityRenderObject::isProgressIndicator):
        (WebCore::AccessibilityRenderObject::isPressed): Check the aria-
        pressed attribute if this is an ARIA button.
        (WebCore::AccessibilityRenderObject::headingLevel): Check the aria-
        level attribute if this is an ARIA heading.
        (WebCore::AccessibilityRenderObject::intValue): Check the aria-
        checked attribute if this is an ARIA radio button or checkbox.
        (WebCore::AccessibilityRenderObject::valueForRange):
        (WebCore::AccessibilityRenderObject::maxValueForRange):
        (WebCore::AccessibilityRenderObject::minValueForRange):
        (WebCore::RoleEntry::):
        (WebCore::AccessibilityRenderObject::canSetValueAttribute):
        * page/AccessibilityRenderObject.h:
        * page/mac/AccessibilityObjectWrapper.mm:
        (-[AccessibilityObjectWrapper accessibilityAttributeNames]):
        (-[AccessibilityObjectWrapper accessibilityAttributeValue:]):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@33465 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 6101f799
2008-05-13 Beth Dakin <bdakin@apple.com>
Reviewed by Brady.
This patch adds support for the ARIA progressbar role and the
following ARIA states (ie HTML attributes): aria-checked, aria-
level, aria-pressed, aria-valuenow, aria-valuemin, and aria-
valuemax.
* html/HTMLAttributeNames.in:
* page/AccessibilityObject.h:
(WebCore::AccessibilityObject::isProgressIndicator):
(WebCore::AccessibilityObject::valueForRange):
(WebCore::AccessibilityObject::maxValueForRange):
(WebCore::AccessibilityObject::minValueForRange):
* page/AccessibilityRenderObject.cpp:
(WebCore::AccessibilityRenderObject::isProgressIndicator):
(WebCore::AccessibilityRenderObject::isPressed): Check the aria-
pressed attribute if this is an ARIA button.
(WebCore::AccessibilityRenderObject::headingLevel): Check the aria-
level attribute if this is an ARIA heading.
(WebCore::AccessibilityRenderObject::intValue): Check the aria-
checked attribute if this is an ARIA radio button or checkbox.
(WebCore::AccessibilityRenderObject::valueForRange):
(WebCore::AccessibilityRenderObject::maxValueForRange):
(WebCore::AccessibilityRenderObject::minValueForRange):
(WebCore::RoleEntry::):
(WebCore::AccessibilityRenderObject::canSetValueAttribute):
* page/AccessibilityRenderObject.h:
* page/mac/AccessibilityObjectWrapper.mm:
(-[AccessibilityObjectWrapper accessibilityAttributeNames]):
(-[AccessibilityObjectWrapper accessibilityAttributeValue:]):
=======
2008-05-14 Kevin McCullough <kmccullough@apple.com>
Reviewed by John.
......@@ -7,9 +7,15 @@ align
alink
alt
archive
aria-checked
aria-describedby
aria-labeledby
aria-labelledby
aria-describedby
aria-level
aria-pressed
aria-valuemax
aria-valuemin
aria-valuenow
autocomplete
autoplay
autosave
......
......@@ -199,6 +199,7 @@ public:
virtual bool isCheckboxOrRadio() const { return false; };
virtual bool isListBox() const { return false; };
virtual bool isFileUploadButton() const { return false; };
virtual bool isProgressIndicator() const { return false; };
virtual bool isChecked() const { return false; };
virtual bool isEnabled() const { return false; };
......@@ -223,6 +224,9 @@ public:
virtual bool accessibilityIsIgnored() const { return true; };
virtual int intValue() const;
virtual float valueForRange() const { return 0.0f; }
virtual float maxValueForRange() const { return 0.0f; }
virtual float minValueForRange() const {return 0.0f; }
virtual int layoutCount() const;
static bool isARIAControl(AccessibilityRole);
static bool isARIAInput(AccessibilityRole);
......
......@@ -237,12 +237,29 @@ bool AccessibilityRenderObject::isFileUploadButton() const
return false;
}
bool AccessibilityRenderObject::isProgressIndicator() const
{
return roleValue() == ProgressIndicatorRole;
}
bool AccessibilityRenderObject::isPressed() const
{
ASSERT(m_renderer);
if (roleValue() != ButtonRole)
return false;
return m_renderer->node() && m_renderer->node()->active();
Node* node = m_renderer->node();
if (!node)
return false;
// If this is an ARIA button, check the aria-pressed attribute rather than node()->active()
if (ariaRoleAttribute() == ButtonRole) {
if (equalIgnoringCase(getAttribute(aria_pressedAttr).string(), "true"))
return true;
return false;
}
return node->active();
}
bool AccessibilityRenderObject::isIndeterminate() const
......@@ -290,10 +307,20 @@ bool AccessibilityRenderObject::isOffScreen() const
int AccessibilityRenderObject::headingLevel(Node* node)
{
// headings can be in block flow and non-block flow
if (!node)
return 0;
if (RenderObject* renderer = node->renderer()) {
AccessibilityObject* axObjectForNode = node->document()->axObjectCache()->get(renderer);
if (axObjectForNode->ariaRoleAttribute() == HeadingRole) {
if (!node->isElementNode())
return 0;
Element* element = static_cast<Element*>(node);
return element->getAttribute(aria_levelAttr).toInt();
}
}
if (node->hasTagName(h1Tag))
return 1;
......@@ -312,15 +339,6 @@ int AccessibilityRenderObject::headingLevel(Node* node)
if (node->hasTagName(h6Tag))
return 6;
// FIXME: When we implement ARIA's level property, this needs to return that instead of 1.
RenderObject* renderer = node->renderer();
if (!renderer)
return 0;
AccessibilityObject* axObjectForNode = node->document()->axObjectCache()->get(renderer);
if (axObjectForNode->ariaRoleAttribute() == HeadingRole)
return 1;
return 0;
}
......@@ -334,6 +352,19 @@ bool AccessibilityRenderObject::isLink() const
return roleValue() == WebCoreLinkRole;
}
const AtomicString& AccessibilityRenderObject::getAttribute(const QualifiedName& attribute) const
{
Node* node = m_renderer->element();
if (!node)
return nullAtom;
if (!node->isElementNode())
return nullAtom;
Element* element = static_cast<Element*>(node);
return element->getAttribute(attribute);
}
HTMLAnchorElement* AccessibilityRenderObject::anchorElement() const
{
// FIXME: In XHTML 2.0, any HTML element can have an href attribute. We will need to implement this to fully
......@@ -479,10 +510,42 @@ int AccessibilityRenderObject::intValue() const
return headingLevel(m_renderer->element());
Node* node = m_renderer->element();
if (node && isCheckboxOrRadio() && ariaRoleAttribute() == UnknownRole)
if (!node || !isCheckboxOrRadio())
return 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).string(), "true"))
return true;
return false;
}
return static_cast<HTMLInputElement*>(node)->checked();
}
return 0;
float AccessibilityRenderObject::valueForRange() const
{
if (!isProgressIndicator())
return 0.0f;
return getAttribute(aria_valuenowAttr).toFloat();
}
float AccessibilityRenderObject::maxValueForRange() const
{
if (!isProgressIndicator())
return 0.0f;
return getAttribute(aria_valuemaxAttr).toFloat();
}
float AccessibilityRenderObject::minValueForRange() const
{
if (!isProgressIndicator())
return 0.0f;
return getAttribute(aria_valueminAttr).toFloat();
}
String AccessibilityRenderObject::stringValue() const
......@@ -578,15 +641,17 @@ String AccessibilityRenderObject::ariaAccessiblityName(const String& s) const
String AccessibilityRenderObject::ariaLabeledByAttribute() const
{
Node* node = m_renderer->node();
if (!node || !node->isElementNode())
if (!node)
return String();
if (!node->isElementNode())
return String();
// The ARIA spec uses the British spelling: "labelled." It seems prudent to support the American
// spelling ("labeled") as well.
Element* element = static_cast<Element*>(node);
String idList = element->getAttribute(aria_labeledbyAttr).string();
String idList = getAttribute(aria_labeledbyAttr).string();
if (idList.isEmpty()) {
idList = element->getAttribute(aria_labelledbyAttr).string();
idList = getAttribute(aria_labelledbyAttr).string();
if (idList.isEmpty())
return String();
}
......@@ -639,8 +704,7 @@ String AccessibilityRenderObject::title() const
return textUnderElement();
if (isLink()) {
Element* element = static_cast<Element*>(node);
const AtomicString& title = element->getAttribute(titleAttr);
const AtomicString& title = getAttribute(titleAttr);
if (!title.isEmpty())
return title;
......@@ -655,12 +719,7 @@ String AccessibilityRenderObject::title() const
String AccessibilityRenderObject::ariaDescribedByAttribute() const
{
Node* node = m_renderer->node();
if (!node || !node->isElementNode())
return String();
Element* element = static_cast<Element*>(node);
String idList = element->getAttribute(aria_describedbyAttr).string();
String idList = getAttribute(aria_describedbyAttr).string();
if (idList.isEmpty())
return String();
......@@ -952,7 +1011,9 @@ String AccessibilityRenderObject::selectedText() const
const AtomicString& AccessibilityRenderObject::accessKey() const
{
Node* node = m_renderer->element();
if (!node || !node->isElementNode())
if (!node)
return nullAtom;
if (!node->isElementNode())
return nullAtom;
return static_cast<Element*>(node)->getAttribute(accesskeyAttr);
}
......@@ -1539,6 +1600,7 @@ static const ARIARoleMap& createARIARoleMap()
{ String("heading"), HeadingRole },
{ String("img"), ImageRole },
{ String("link"), WebCoreLinkRole },
{ String("progressbar"), ProgressIndicatorRole },
{ String("radio"), RadioButtonRole },
{ String("textbox"), TextAreaRole }
};
......@@ -1559,12 +1621,7 @@ static AccessibilityRole ariaRoleToWebCoreRole(String value)
AccessibilityRole AccessibilityRenderObject::ariaRoleAttribute() const
{
Node* node = m_renderer->node();
if (!node || !node->isElementNode())
return UnknownRole;
Element* element = static_cast<Element*>(node);
String ariaRole = element->getAttribute(roleAttr).string();
String ariaRole = getAttribute(roleAttr).string();
if (ariaRole.isNull() || ariaRole.isEmpty())
return UnknownRole;
......@@ -1712,7 +1769,7 @@ bool AccessibilityRenderObject::canSetFocusAttribute() const
bool AccessibilityRenderObject::canSetValueAttribute() const
{
return isTextControl();
return isTextControl() || isProgressIndicator();
}
bool AccessibilityRenderObject::canSetTextRangeAttributes() const
......
......@@ -74,6 +74,7 @@ public:
virtual bool isWebArea() const;
virtual bool isCheckboxOrRadio() const;
virtual bool isFileUploadButton() const;
virtual bool isProgressIndicator() const;
virtual bool isEnabled() const;
virtual bool isSelected() const;
......@@ -88,6 +89,7 @@ public:
virtual bool isReadOnly() const;
virtual bool isVisited() const;
const AtomicString& getAttribute(const QualifiedName&) const;
virtual bool canSetFocusAttribute() const;
virtual bool canSetTextRangeAttributes() const;
virtual bool canSetValueAttribute() const;
......@@ -99,6 +101,9 @@ public:
static int headingLevel(Node*);
virtual int intValue() const;
virtual float valueForRange() const;
virtual float maxValueForRange() const;
virtual float minValueForRange() const;
virtual int layoutCount() const;
virtual AccessibilityObject* doAccessibilityHitTest(const IntPoint&) const;
......
......@@ -515,6 +515,7 @@ static WebCoreTextMarkerRange* textMarkerRangeFromVisiblePositions(VisiblePositi
static NSArray* webAreaAttrs = nil;
static NSArray* textAttrs = nil;
static NSArray* listBoxAttrs = nil;
static NSArray* progressIndicatorAttrs = nil;
NSMutableArray* tempArray;
if (attributes == nil) {
attributes = [[NSArray alloc] initWithObjects: NSAccessibilityRoleAttribute,
......@@ -573,6 +574,15 @@ static WebCoreTextMarkerRange* textMarkerRangeFromVisiblePositions(VisiblePositi
listBoxAttrs = [[NSArray alloc] initWithArray:tempArray];
[tempArray release];
}
if (progressIndicatorAttrs == nil) {
tempArray = [[NSMutableArray alloc] initWithArray:attributes];
[tempArray addObject:NSAccessibilityTopLevelUIElementAttribute];
[tempArray addObject:NSAccessibilityValueAttribute];
[tempArray addObject:NSAccessibilityMinValueAttribute];
[tempArray addObject:NSAccessibilityMaxValueAttribute];
progressIndicatorAttrs = [[NSArray alloc] initWithArray:tempArray];
[tempArray release];
}
if (m_object->isPasswordField())
return attributes;
......@@ -589,6 +599,9 @@ static WebCoreTextMarkerRange* textMarkerRangeFromVisiblePositions(VisiblePositi
if (m_object->isListBox())
return listBoxAttrs;
if (m_object->isProgressIndicator())
return progressIndicatorAttrs;
return attributes;
}
......@@ -920,11 +933,19 @@ static NSString* roleValueToNSString(AccessibilityRole value)
if ([[[self attachmentView] accessibilityAttributeNames] containsObject:NSAccessibilityValueAttribute])
return [[self attachmentView] accessibilityAttributeValue:NSAccessibilityValueAttribute];
}
if (m_object->isProgressIndicator())
return [NSNumber numberWithFloat:m_object->valueForRange()];
if (m_object->hasIntValue())
return [NSNumber numberWithInt:m_object->intValue()];
return m_object->stringValue();
}
if ([attributeName isEqualToString: NSAccessibilityMinValueAttribute])
return [NSNumber numberWithFloat:m_object->minValueForRange()];
if ([attributeName isEqualToString: NSAccessibilityMaxValueAttribute])
return [NSNumber numberWithFloat:m_object->maxValueForRange()];
if ([attributeName isEqualToString: NSAccessibilityHelpAttribute])
return m_object->helpText();
......@@ -942,7 +963,8 @@ static NSString* roleValueToNSString(AccessibilityRole value)
if ([attributeName isEqualToString: NSAccessibilityPositionAttribute])
return [self position];
if ([attributeName isEqualToString: NSAccessibilityWindowAttribute]) {
if ([attributeName isEqualToString: NSAccessibilityWindowAttribute] ||
[attributeName isEqualToString: NSAccessibilityTopLevelUIElementAttribute]) {
FrameView* fv = m_object->documentFrameView();
if (fv)
return [fv->getView() window];
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment