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> 2008-05-14 Kevin McCullough <kmccullough@apple.com>
Reviewed by John. Reviewed by John.
...@@ -7,9 +7,15 @@ align ...@@ -7,9 +7,15 @@ align
alink alink
alt alt
archive archive
aria-checked
aria-describedby
aria-labeledby aria-labeledby
aria-labelledby aria-labelledby
aria-describedby aria-level
aria-pressed
aria-valuemax
aria-valuemin
aria-valuenow
autocomplete autocomplete
autoplay autoplay
autosave autosave
......
...@@ -199,6 +199,7 @@ public: ...@@ -199,6 +199,7 @@ public:
virtual bool isCheckboxOrRadio() const { return false; }; virtual bool isCheckboxOrRadio() const { return false; };
virtual bool isListBox() const { return false; }; virtual bool isListBox() const { return false; };
virtual bool isFileUploadButton() const { return false; }; virtual bool isFileUploadButton() const { return false; };
virtual bool isProgressIndicator() const { return false; };
virtual bool isChecked() const { return false; }; virtual bool isChecked() const { return false; };
virtual bool isEnabled() const { return false; }; virtual bool isEnabled() const { return false; };
...@@ -223,6 +224,9 @@ public: ...@@ -223,6 +224,9 @@ public:
virtual bool accessibilityIsIgnored() const { return true; }; virtual bool accessibilityIsIgnored() const { return true; };
virtual int intValue() const; 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; virtual int layoutCount() const;
static bool isARIAControl(AccessibilityRole); static bool isARIAControl(AccessibilityRole);
static bool isARIAInput(AccessibilityRole); static bool isARIAInput(AccessibilityRole);
......
...@@ -236,13 +236,30 @@ bool AccessibilityRenderObject::isFileUploadButton() const ...@@ -236,13 +236,30 @@ bool AccessibilityRenderObject::isFileUploadButton() const
return false; return false;
} }
bool AccessibilityRenderObject::isProgressIndicator() const
{
return roleValue() == ProgressIndicatorRole;
}
bool AccessibilityRenderObject::isPressed() const bool AccessibilityRenderObject::isPressed() const
{ {
ASSERT(m_renderer); ASSERT(m_renderer);
if (roleValue() != ButtonRole) if (roleValue() != ButtonRole)
return false; 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 bool AccessibilityRenderObject::isIndeterminate() const
...@@ -290,9 +307,19 @@ bool AccessibilityRenderObject::isOffScreen() const ...@@ -290,9 +307,19 @@ bool AccessibilityRenderObject::isOffScreen() const
int AccessibilityRenderObject::headingLevel(Node* node) int AccessibilityRenderObject::headingLevel(Node* node)
{ {
// headings can be in block flow and non-block flow // headings can be in block flow and non-block flow
if (!node) if (!node)
return 0; 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)) if (node->hasTagName(h1Tag))
return 1; return 1;
...@@ -312,15 +339,6 @@ int AccessibilityRenderObject::headingLevel(Node* node) ...@@ -312,15 +339,6 @@ int AccessibilityRenderObject::headingLevel(Node* node)
if (node->hasTagName(h6Tag)) if (node->hasTagName(h6Tag))
return 6; 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; return 0;
} }
...@@ -334,6 +352,19 @@ bool AccessibilityRenderObject::isLink() const ...@@ -334,6 +352,19 @@ bool AccessibilityRenderObject::isLink() const
return roleValue() == WebCoreLinkRole; 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 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 // 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 ...@@ -479,10 +510,42 @@ int AccessibilityRenderObject::intValue() const
return headingLevel(m_renderer->element()); return headingLevel(m_renderer->element());
Node* node = m_renderer->element(); Node* node = m_renderer->element();
if (node && isCheckboxOrRadio() && ariaRoleAttribute() == UnknownRole) if (!node || !isCheckboxOrRadio())
return static_cast<HTMLInputElement*>(node)->checked(); 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 0; return static_cast<HTMLInputElement*>(node)->checked();
}
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 String AccessibilityRenderObject::stringValue() const
...@@ -578,15 +641,17 @@ String AccessibilityRenderObject::ariaAccessiblityName(const String& s) const ...@@ -578,15 +641,17 @@ String AccessibilityRenderObject::ariaAccessiblityName(const String& s) const
String AccessibilityRenderObject::ariaLabeledByAttribute() const String AccessibilityRenderObject::ariaLabeledByAttribute() const
{ {
Node* node = m_renderer->node(); Node* node = m_renderer->node();
if (!node || !node->isElementNode()) if (!node)
return String();
if (!node->isElementNode())
return String(); return String();
// The ARIA spec uses the British spelling: "labelled." It seems prudent to support the American // The ARIA spec uses the British spelling: "labelled." It seems prudent to support the American
// spelling ("labeled") as well. // spelling ("labeled") as well.
Element* element = static_cast<Element*>(node); String idList = getAttribute(aria_labeledbyAttr).string();
String idList = element->getAttribute(aria_labeledbyAttr).string();
if (idList.isEmpty()) { if (idList.isEmpty()) {
idList = element->getAttribute(aria_labelledbyAttr).string(); idList = getAttribute(aria_labelledbyAttr).string();
if (idList.isEmpty()) if (idList.isEmpty())
return String(); return String();
} }
...@@ -639,8 +704,7 @@ String AccessibilityRenderObject::title() const ...@@ -639,8 +704,7 @@ String AccessibilityRenderObject::title() const
return textUnderElement(); return textUnderElement();
if (isLink()) { if (isLink()) {
Element* element = static_cast<Element*>(node); const AtomicString& title = getAttribute(titleAttr);
const AtomicString& title = element->getAttribute(titleAttr);
if (!title.isEmpty()) if (!title.isEmpty())
return title; return title;
...@@ -655,12 +719,7 @@ String AccessibilityRenderObject::title() const ...@@ -655,12 +719,7 @@ String AccessibilityRenderObject::title() const
String AccessibilityRenderObject::ariaDescribedByAttribute() const String AccessibilityRenderObject::ariaDescribedByAttribute() const
{ {
Node* node = m_renderer->node(); String idList = getAttribute(aria_describedbyAttr).string();
if (!node || !node->isElementNode())
return String();
Element* element = static_cast<Element*>(node);
String idList = element->getAttribute(aria_describedbyAttr).string();
if (idList.isEmpty()) if (idList.isEmpty())
return String(); return String();
...@@ -952,7 +1011,9 @@ String AccessibilityRenderObject::selectedText() const ...@@ -952,7 +1011,9 @@ String AccessibilityRenderObject::selectedText() const
const AtomicString& AccessibilityRenderObject::accessKey() const const AtomicString& AccessibilityRenderObject::accessKey() const
{ {
Node* node = m_renderer->element(); Node* node = m_renderer->element();
if (!node || !node->isElementNode()) if (!node)
return nullAtom;
if (!node->isElementNode())
return nullAtom; return nullAtom;
return static_cast<Element*>(node)->getAttribute(accesskeyAttr); return static_cast<Element*>(node)->getAttribute(accesskeyAttr);
} }
...@@ -1539,6 +1600,7 @@ static const ARIARoleMap& createARIARoleMap() ...@@ -1539,6 +1600,7 @@ static const ARIARoleMap& createARIARoleMap()
{ String("heading"), HeadingRole }, { String("heading"), HeadingRole },
{ String("img"), ImageRole }, { String("img"), ImageRole },
{ String("link"), WebCoreLinkRole }, { String("link"), WebCoreLinkRole },
{ String("progressbar"), ProgressIndicatorRole },
{ String("radio"), RadioButtonRole }, { String("radio"), RadioButtonRole },
{ String("textbox"), TextAreaRole } { String("textbox"), TextAreaRole }
}; };
...@@ -1559,12 +1621,7 @@ static AccessibilityRole ariaRoleToWebCoreRole(String value) ...@@ -1559,12 +1621,7 @@ static AccessibilityRole ariaRoleToWebCoreRole(String value)
AccessibilityRole AccessibilityRenderObject::ariaRoleAttribute() const AccessibilityRole AccessibilityRenderObject::ariaRoleAttribute() const
{ {
Node* node = m_renderer->node(); String ariaRole = getAttribute(roleAttr).string();
if (!node || !node->isElementNode())
return UnknownRole;
Element* element = static_cast<Element*>(node);
String ariaRole = element->getAttribute(roleAttr).string();
if (ariaRole.isNull() || ariaRole.isEmpty()) if (ariaRole.isNull() || ariaRole.isEmpty())
return UnknownRole; return UnknownRole;
...@@ -1712,7 +1769,7 @@ bool AccessibilityRenderObject::canSetFocusAttribute() const ...@@ -1712,7 +1769,7 @@ bool AccessibilityRenderObject::canSetFocusAttribute() const
bool AccessibilityRenderObject::canSetValueAttribute() const bool AccessibilityRenderObject::canSetValueAttribute() const
{ {
return isTextControl(); return isTextControl() || isProgressIndicator();
} }
bool AccessibilityRenderObject::canSetTextRangeAttributes() const bool AccessibilityRenderObject::canSetTextRangeAttributes() const
......
...@@ -74,6 +74,7 @@ public: ...@@ -74,6 +74,7 @@ public:
virtual bool isWebArea() const; virtual bool isWebArea() const;
virtual bool isCheckboxOrRadio() const; virtual bool isCheckboxOrRadio() const;
virtual bool isFileUploadButton() const; virtual bool isFileUploadButton() const;
virtual bool isProgressIndicator() const;
virtual bool isEnabled() const; virtual bool isEnabled() const;
virtual bool isSelected() const; virtual bool isSelected() const;
...@@ -87,7 +88,8 @@ public: ...@@ -87,7 +88,8 @@ public:
virtual bool isPressed() const; virtual bool isPressed() const;
virtual bool isReadOnly() const; virtual bool isReadOnly() const;
virtual bool isVisited() const; virtual bool isVisited() const;
const AtomicString& getAttribute(const QualifiedName&) const;
virtual bool canSetFocusAttribute() const; virtual bool canSetFocusAttribute() const;
virtual bool canSetTextRangeAttributes() const; virtual bool canSetTextRangeAttributes() const;
virtual bool canSetValueAttribute() const; virtual bool canSetValueAttribute() const;
...@@ -99,6 +101,9 @@ public: ...@@ -99,6 +101,9 @@ public:
static int headingLevel(Node*); static int headingLevel(Node*);
virtual int intValue() const; virtual int intValue() const;
virtual float valueForRange() const;
virtual float maxValueForRange() const;
virtual float minValueForRange() const;
virtual int layoutCount() const; virtual int layoutCount() const;
virtual AccessibilityObject* doAccessibilityHitTest(const IntPoint&) const; virtual AccessibilityObject* doAccessibilityHitTest(const IntPoint&) const;
......
...@@ -515,6 +515,7 @@ static WebCoreTextMarkerRange* textMarkerRangeFromVisiblePositions(VisiblePositi ...@@ -515,6 +515,7 @@ static WebCoreTextMarkerRange* textMarkerRangeFromVisiblePositions(VisiblePositi
static NSArray* webAreaAttrs = nil; static NSArray* webAreaAttrs = nil;
static NSArray* textAttrs = nil; static NSArray* textAttrs = nil;
static NSArray* listBoxAttrs = nil; static NSArray* listBoxAttrs = nil;
static NSArray* progressIndicatorAttrs = nil;
NSMutableArray* tempArray; NSMutableArray* tempArray;
if (attributes == nil) { if (attributes == nil) {
attributes = [[NSArray alloc] initWithObjects: NSAccessibilityRoleAttribute, attributes = [[NSArray alloc] initWithObjects: NSAccessibilityRoleAttribute,
...@@ -573,6 +574,15 @@ static WebCoreTextMarkerRange* textMarkerRangeFromVisiblePositions(VisiblePositi ...@@ -573,6 +574,15 @@ static WebCoreTextMarkerRange* textMarkerRangeFromVisiblePositions(VisiblePositi
listBoxAttrs = [[NSArray alloc] initWithArray:tempArray]; listBoxAttrs = [[NSArray alloc] initWithArray:tempArray];
[tempArray release]; [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()) if (m_object->isPasswordField())
return attributes; return attributes;
...@@ -589,6 +599,9 @@ static WebCoreTextMarkerRange* textMarkerRangeFromVisiblePositions(VisiblePositi ...@@ -589,6 +599,9 @@ static WebCoreTextMarkerRange* textMarkerRangeFromVisiblePositions(VisiblePositi
if (m_object->isListBox()) if (m_object->isListBox())
return listBoxAttrs; return listBoxAttrs;
if (m_object->isProgressIndicator())
return progressIndicatorAttrs;
return attributes; return attributes;
} }
...@@ -919,12 +932,20 @@ static NSString* roleValueToNSString(AccessibilityRole value) ...@@ -919,12 +932,20 @@ static NSString* roleValueToNSString(AccessibilityRole value)
if (m_object->isAttachment()) { if (m_object->isAttachment()) {
if ([[[self attachmentView] accessibilityAttributeNames] containsObject:NSAccessibilityValueAttribute]) if ([[[self attachmentView] accessibilityAttributeNames] containsObject:NSAccessibilityValueAttribute])
return [[self attachmentView] accessibilityAttributeValue:NSAccessibilityValueAttribute]; return [[self attachmentView] accessibilityAttributeValue:NSAccessibilityValueAttribute];
} }
if (m_object->isProgressIndicator())
return [NSNumber numberWithFloat:m_object->valueForRange()];
if (m_object->hasIntValue()) if (m_object->hasIntValue())
return [NSNumber numberWithInt:m_object->intValue()]; return [NSNumber numberWithInt:m_object->intValue()];
return m_object->stringValue(); 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]) if ([attributeName isEqualToString: NSAccessibilityHelpAttribute])
return m_object->helpText(); return m_object->helpText();
...@@ -942,7 +963,8 @@ static NSString* roleValueToNSString(AccessibilityRole value) ...@@ -942,7 +963,8 @@ static NSString* roleValueToNSString(AccessibilityRole value)
if ([attributeName isEqualToString: NSAccessibilityPositionAttribute]) if ([attributeName isEqualToString: NSAccessibilityPositionAttribute])
return [self position]; return [self position];
if ([attributeName isEqualToString: NSAccessibilityWindowAttribute]) { if ([attributeName isEqualToString: NSAccessibilityWindowAttribute] ||
[attributeName isEqualToString: NSAccessibilityTopLevelUIElementAttribute]) {
FrameView* fv = m_object->documentFrameView(); FrameView* fv = m_object->documentFrameView();
if (fv) if (fv)
return [fv->getView() window]; 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