Diff
Modified: trunk/LayoutTests/ChangeLog (131904 => 131905)
--- trunk/LayoutTests/ChangeLog 2012-10-19 15:38:13 UTC (rev 131904)
+++ trunk/LayoutTests/ChangeLog 2012-10-19 16:24:43 UTC (rev 131905)
@@ -1,3 +1,14 @@
+2012-10-19 Chris Fleizach <[email protected]>
+
+ AX: Refactor accessibility name computation so it's more platform independent
+ https://bugs.webkit.org/show_bug.cgi?id=99502
+
+ Reviewed by Beth Dakin.
+
+ Update a test to reflect change in what shoud be recognized as a title.
+
+ * platform/mac/accessibility/aria-radiobutton-text.html:
+
2012-10-19 Zan Dobersek <[email protected]>
[WK2][GTK] Fullscreen tests timing out in bots
Modified: trunk/LayoutTests/platform/chromium/TestExpectations (131904 => 131905)
--- trunk/LayoutTests/platform/chromium/TestExpectations 2012-10-19 15:38:13 UTC (rev 131904)
+++ trunk/LayoutTests/platform/chromium/TestExpectations 2012-10-19 16:24:43 UTC (rev 131905)
@@ -1420,6 +1420,7 @@
webkit.org/b/97359 accessibility/svg-bounds.html [ Skip ]
webkit.org/b/73912 accessibility/aria-checkbox-text.html [ Skip ]
+webkit.org/b/99665 accessibility/loading-iframe-sends-notification.html [ Skip ]
webkit.org/b/73912 accessibility/aria-checkbox-sends-notification.html [ Failure Pass ]
Modified: trunk/LayoutTests/platform/mac/accessibility/aria-radiobutton-text.html (131904 => 131905)
--- trunk/LayoutTests/platform/mac/accessibility/aria-radiobutton-text.html 2012-10-19 15:38:13 UTC (rev 131904)
+++ trunk/LayoutTests/platform/mac/accessibility/aria-radiobutton-text.html 2012-10-19 16:24:43 UTC (rev 131905)
@@ -30,7 +30,9 @@
var succeeded = obj.childAtIndex(1).title == "AXTitle: Two";
shouldBe("succeeded", "true");
- var succeeded = obj.childAtIndex(2).title == "AXTitle: Three";
+ // Because the third button uses aria-labelledby, the accessible name
+ // will be inside the description field.
+ var succeeded = obj.childAtIndex(2).description == "AXDescription: Three";
shouldBe("succeeded", "true");
}
Modified: trunk/Source/WebCore/ChangeLog (131904 => 131905)
--- trunk/Source/WebCore/ChangeLog 2012-10-19 15:38:13 UTC (rev 131904)
+++ trunk/Source/WebCore/ChangeLog 2012-10-19 16:24:43 UTC (rev 131905)
@@ -1,3 +1,72 @@
+2012-10-17 Chris Fleizach <[email protected]>
+
+ AX: Refactor accessibility name computation so it's more platform independent
+ https://bugs.webkit.org/show_bug.cgi?id=99502
+
+ Reviewed by Beth Dakin.
+
+ The current model of determining the accessible text for an object has a lot of Mac biases built in
+ due to legacy implementation.
+
+ This change categorizes and orders accessibility text based on WAI-ARIA text computation rules and then
+ allows the platform (only Mac right now) to decide how best to apply that text to its own AX API.
+ http://www.w3.org/TR/wai-aria/roles#textalternativecomputation
+
+ This change tried very hard not to change any test behavior, even though it exposed a number of weird
+ edge cases where we were treating attributes differently based on element type.
+
+ Future patches will resolve those discrepancies.
+
+ * accessibility/AccessibilityImageMapLink.cpp:
+ (WebCore::AccessibilityImageMapLink::accessibilityText):
+ * accessibility/AccessibilityImageMapLink.h:
+ (AccessibilityImageMapLink):
+ * accessibility/AccessibilityMediaControls.cpp:
+ (WebCore::AccessibilityMediaControl::accessibilityText):
+ * accessibility/AccessibilityMediaControls.h:
+ (AccessibilityMediaControl):
+ (WebCore::AccessibilityMediaTimeDisplay::isMediaControlLabel):
+ * accessibility/AccessibilityNodeObject.cpp:
+ (WebCore::AccessibilityNodeObject::titleElementText):
+ (WebCore::AccessibilityNodeObject::accessibilityText):
+ (WebCore::AccessibilityNodeObject::ariaLabeledByText):
+ (WebCore::AccessibilityNodeObject::alternativeText):
+ (WebCore::AccessibilityNodeObject::alternativeTextForWebArea):
+ (WebCore::AccessibilityNodeObject::visibleText):
+ (WebCore::AccessibilityNodeObject::helpText):
+ (WebCore::AccessibilityNodeObject::ariaDescribedByAttribute):
+ * accessibility/AccessibilityNodeObject.h:
+ (AccessibilityNodeObject):
+ * accessibility/AccessibilityObject.h:
+ (AccessibilityText):
+ (WebCore::AccessibilityText::AccessibilityText):
+ (WebCore::AccessibilityObject::isMediaControlLabel):
+ (AccessibilityObject):
+ (WebCore::AccessibilityObject::accessibilityText):
+ (WebCore::AccessibilityObject::setAccessibleName):
+ (WebCore::AccessibilityObject::accessibilityDescription):
+ (WebCore::AccessibilityObject::title):
+ (WebCore::AccessibilityObject::helpText):
+ (WebCore::AccessibilityObject::stringValue):
+ (WebCore::AccessibilityObject::textUnderElement):
+ (WebCore::AccessibilityObject::text):
+ (WebCore::AccessibilityObject::textLength):
+ (WebCore::AccessibilityObject::setRoleValue):
+ (WebCore::AccessibilityObject::roleValue):
+ (WebCore::AccessibilityObject::selection):
+ (WebCore::AccessibilityObject::hierarchicalLevel):
+ * accessibility/AccessibilityRenderObject.cpp:
+ * accessibility/AccessibilityRenderObject.h:
+ (AccessibilityRenderObject):
+ * accessibility/mac/WebAccessibilityObjectWrapper.mm:
+ (-[WebAccessibilityObjectWrapper titleTagShouldBeUsedInDescriptionField]):
+ (-[WebAccessibilityObjectWrapper accessibilityTitle]):
+ (-[WebAccessibilityObjectWrapper accessibilityDescription]):
+ (-[WebAccessibilityObjectWrapper accessibilityHelpText]):
+ (-[WebAccessibilityObjectWrapper accessibilityAttributeValue:]):
+ * platform/LocalizedStrings.cpp:
+ (WebCore::localizedMediaControlElementHelpText):
+
2012-10-19 Kent Tamura <[email protected]>
Use Localizer::monthFormat to construct input[type=month] UI
Modified: trunk/Source/WebCore/accessibility/AccessibilityImageMapLink.cpp (131904 => 131905)
--- trunk/Source/WebCore/accessibility/AccessibilityImageMapLink.cpp 2012-10-19 15:38:13 UTC (rev 131904)
+++ trunk/Source/WebCore/accessibility/AccessibilityImageMapLink.cpp 2012-10-19 16:24:43 UTC (rev 131905)
@@ -94,6 +94,21 @@
return m_areaElement->href();
}
+
+void AccessibilityImageMapLink::accessibilityText(Vector<AccessibilityText>& textOrder)
+{
+ String description = accessibilityDescription();
+ if (!description.isEmpty())
+ textOrder.append(AccessibilityText(description, AlternativeText));
+
+ const AtomicString& titleText = getAttribute(titleAttr);
+ if (!titleText.isEmpty())
+ textOrder.append(AccessibilityText(titleText, TitleTagText));
+
+ const AtomicString& summary = getAttribute(summaryAttr);
+ if (!summary.isEmpty())
+ textOrder.append(AccessibilityText(summary, SummaryText));
+}
String AccessibilityImageMapLink::accessibilityDescription() const
{
Modified: trunk/Source/WebCore/accessibility/AccessibilityImageMapLink.h (131904 => 131905)
--- trunk/Source/WebCore/accessibility/AccessibilityImageMapLink.h 2012-10-19 15:38:13 UTC (rev 131904)
+++ trunk/Source/WebCore/accessibility/AccessibilityImageMapLink.h 2012-10-19 16:24:43 UTC (rev 131905)
@@ -73,6 +73,7 @@
RefPtr<HTMLAreaElement> m_areaElement;
RefPtr<HTMLMapElement> m_mapElement;
+ virtual void accessibilityText(Vector<AccessibilityText>&);
virtual bool isImageMapLink() const { return true; }
};
Modified: trunk/Source/WebCore/accessibility/AccessibilityMediaControls.cpp (131904 => 131905)
--- trunk/Source/WebCore/accessibility/AccessibilityMediaControls.cpp 2012-10-19 15:38:13 UTC (rev 131904)
+++ trunk/Source/WebCore/accessibility/AccessibilityMediaControls.cpp 2012-10-19 16:24:43 UTC (rev 131905)
@@ -140,6 +140,22 @@
return String();
}
+void AccessibilityMediaControl::accessibilityText(Vector<AccessibilityText>& textOrder)
+{
+ String description = accessibilityDescription();
+ if (!description.isEmpty())
+ textOrder.append(AccessibilityText(description, AlternativeText));
+
+ String title = this->title();
+ if (!title.isEmpty())
+ textOrder.append(AccessibilityText(title, AlternativeText));
+
+ String helptext = helpText();
+ if (!helptext.isEmpty())
+ textOrder.append(AccessibilityText(helptext, HelpText));
+}
+
+
String AccessibilityMediaControl::title() const
{
DEFINE_STATIC_LOCAL(const String, controlsPanel, (ASCIILiteral("ControlsPanel")));
Modified: trunk/Source/WebCore/accessibility/AccessibilityMediaControls.h (131904 => 131905)
--- trunk/Source/WebCore/accessibility/AccessibilityMediaControls.h 2012-10-19 15:38:13 UTC (rev 131904)
+++ trunk/Source/WebCore/accessibility/AccessibilityMediaControls.h 2012-10-19 16:24:43 UTC (rev 131905)
@@ -54,6 +54,7 @@
explicit AccessibilityMediaControl(RenderObject*);
MediaControlElementType controlType() const;
String controlTypeName() const;
+ virtual void accessibilityText(Vector<AccessibilityText>&);
};
@@ -107,6 +108,7 @@
private:
explicit AccessibilityMediaTimeDisplay(RenderObject*);
+ virtual bool isMediaControlLabel() const { return true; }
};
Modified: trunk/Source/WebCore/accessibility/AccessibilityNodeObject.cpp (131904 => 131905)
--- trunk/Source/WebCore/accessibility/AccessibilityNodeObject.cpp 2012-10-19 15:38:13 UTC (rev 131904)
+++ trunk/Source/WebCore/accessibility/AccessibilityNodeObject.cpp 2012-10-19 16:24:43 UTC (rev 131905)
@@ -1079,6 +1079,215 @@
return 0;
}
+void AccessibilityNodeObject::titleElementText(Vector<AccessibilityText>& textOrder)
+{
+ Node* node = this->node();
+ if (!node)
+ return;
+
+ bool isInputTag = node->hasTagName(inputTag);
+ if (isInputTag || AccessibilityObject::isARIAInput(ariaRoleAttribute()) || isControl()) {
+ HTMLLabelElement* label = labelForElement(toElement(node));
+ if (label) {
+ AccessibilityObject* labelObject = axObjectCache()->getOrCreate(label);
+ textOrder.append(AccessibilityText(label->innerText(), LabelByElementText, labelObject));
+ return;
+ }
+ }
+
+ AccessibilityObject* titleUIElement = this->titleUIElement();
+ if (titleUIElement)
+ textOrder.append(AccessibilityText(String(), LabelByElementText, titleUIElement));
+}
+
+void AccessibilityNodeObject::alternativeText(Vector<AccessibilityText>& textOrder) const
+{
+ if (isWebArea()) {
+ String webAreaText = alternativeTextForWebArea();
+ if (!webAreaText.isEmpty())
+ textOrder.append(AccessibilityText(webAreaText, AlternativeText));
+ return;
+ }
+
+ ariaLabeledByText(textOrder);
+
+ const AtomicString& ariaLabel = getAttribute(aria_labelAttr);
+ if (!ariaLabel.isEmpty())
+ textOrder.append(AccessibilityText(ariaLabel, AlternativeText));
+
+ if (isImage() || isInputImage() || isNativeImage() || isCanvas()) {
+ // Images should use alt as long as the attribute is present, even if empty.
+ // Otherwise, it should fallback to other methods, like the title attribute.
+ const AtomicString& alt = getAttribute(altAttr);
+ if (!alt.isNull())
+ textOrder.append(AccessibilityText(alt, AlternativeText));
+ }
+
+#if ENABLE(MATHML)
+ Node* node = this->node();
+ if (node && node->isElementNode() && toElement(node)->isMathMLElement())
+ textOrder.append(AccessibilityText(getAttribute(MathMLNames::alttextAttr), AlternativeText));
+#endif
+}
+
+void AccessibilityNodeObject::visibleText(Vector<AccessibilityText>& textOrder) const
+{
+ Node* node = this->node();
+ if (!node)
+ return;
+
+ bool isInputTag = node->hasTagName(inputTag);
+ if (isInputTag) {
+ HTMLInputElement* input = static_cast<HTMLInputElement*>(node);
+ if (input->isTextButton()) {
+ textOrder.append(AccessibilityText(input->valueWithDefault(), VisibleText));
+ return;
+ }
+ }
+
+ // If this node isn't rendered, there's no inner text we can extract from a select element.
+ if (!isAccessibilityRenderObject() && node->hasTagName(selectTag))
+ return;
+
+ bool useTextUnderElement = false;
+
+ switch (roleValue()) {
+ case PopUpButtonRole:
+ case ButtonRole:
+ case ToggleButtonRole:
+ case CheckBoxRole:
+ case ListBoxOptionRole:
+ case MenuButtonRole:
+ case MenuItemRole:
+ case RadioButtonRole:
+ case TabRole:
+ useTextUnderElement = true;
+ break;
+ default:
+ break;
+ }
+
+ // If it's focusable but it's not content editable or a known control type, then it will appear to
+ // the user as a single atomic object, so we should use its text as the default title.
+ if (isHeading() || isLink() || isGenericFocusableElement())
+ useTextUnderElement = true;
+
+ if (useTextUnderElement) {
+ String text = textUnderElement();
+ if (!text.isEmpty())
+ textOrder.append(AccessibilityText(text, ChildrenText));
+ }
+}
+
+void AccessibilityNodeObject::helpText(Vector<AccessibilityText>& textOrder) const
+{
+ const AtomicString& ariaHelp = getAttribute(aria_helpAttr);
+ if (!ariaHelp.isEmpty())
+ textOrder.append(AccessibilityText(ariaHelp, HelpText));
+
+ String describedBy = ariaDescribedByAttribute();
+ if (!describedBy.isEmpty())
+ textOrder.append(AccessibilityText(describedBy, SummaryText));
+
+ // Add help type text that is derived from ancestors.
+ for (Node* curr = node(); curr; curr = curr->parentNode()) {
+ const AtomicString& summary = getAttribute(summaryAttr);
+ if (!summary.isEmpty())
+ textOrder.append(AccessibilityText(summary, SummaryText));
+
+ // The title attribute should be used as help text unless it is already being used as descriptive text.
+ const AtomicString& title = getAttribute(titleAttr);
+ if (!title.isEmpty())
+ textOrder.append(AccessibilityText(title, TitleTagText));
+
+ // 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)
+ return;
+
+ AccessibilityRole role = axObj->roleValue();
+ if (role != GroupRole && role != UnknownRole)
+ break;
+ }
+}
+
+void AccessibilityNodeObject::accessibilityText(Vector<AccessibilityText>& textOrder)
+{
+ titleElementText(textOrder);
+ alternativeText(textOrder);
+ visibleText(textOrder);
+ helpText(textOrder);
+
+ String placeholder = placeholderValue();
+ if (!placeholder.isEmpty())
+ textOrder.append(AccessibilityText(placeholder, PlaceholderText));
+}
+
+void AccessibilityNodeObject::ariaLabeledByText(Vector<AccessibilityText>& textOrder) const
+{
+ String ariaLabeledBy = ariaLabeledByAttribute();
+ if (!ariaLabeledBy.isEmpty()) {
+ Vector<Element*> elements;
+ ariaLabeledByElements(elements);
+
+ Vector<RefPtr<AccessibilityObject> > axElements;
+ unsigned length = elements.size();
+ for (unsigned k = 0; k < length; k++) {
+ RefPtr<AccessibilityObject> axElement = axObjectCache()->getOrCreate(elements[k]);
+ axElements.append(axElement);
+ }
+
+ textOrder.append(AccessibilityText(ariaLabeledBy, AlternativeText, axElements));
+ }
+}
+
+String AccessibilityNodeObject::alternativeTextForWebArea() const
+{
+ // The WebArea description should follow this order:
+ // aria-label on the <html>
+ // title on the <html>
+ // <title> inside the <head> (of it was set through JS)
+ // name on the <html>
+ // For iframes:
+ // aria-label on the <iframe>
+ // title on the <iframe>
+ // name on the <iframe>
+
+ Document* document = this->document();
+ if (!document)
+ return String();
+
+ // Check if the HTML element has an aria-label for the webpage.
+ if (Element* documentElement = document->documentElement()) {
+ const AtomicString& ariaLabel = documentElement->getAttribute(aria_labelAttr);
+ if (!ariaLabel.isEmpty())
+ return ariaLabel;
+ }
+
+ Node* owner = document->ownerElement();
+ if (owner) {
+ if (owner->hasTagName(frameTag) || owner->hasTagName(iframeTag)) {
+ const AtomicString& title = static_cast<HTMLFrameElementBase*>(owner)->getAttribute(titleAttr);
+ if (!title.isEmpty())
+ return title;
+ return static_cast<HTMLFrameElementBase*>(owner)->getNameAttribute();
+ }
+ if (owner->isHTMLElement())
+ return toHTMLElement(owner)->getNameAttribute();
+ }
+
+ String documentTitle = document->title();
+ if (!documentTitle.isEmpty())
+ return documentTitle;
+
+ owner = document->body();
+ if (owner && owner->isHTMLElement())
+ return toHTMLElement(owner)->getNameAttribute();
+
+ return String();
+}
+
String AccessibilityNodeObject::accessibilityDescription() const
{
// Static text should not have a description, it should only have a stringValue.
@@ -1346,6 +1555,14 @@
return builder.toString();
}
+String AccessibilityNodeObject::ariaDescribedByAttribute() const
+{
+ Vector<Element*> elements;
+ elementsFromAttribute(elements, aria_describedbyAttr);
+
+ return accessibilityDescriptionForElements(elements);
+}
+
void AccessibilityNodeObject::elementsFromAttribute(Vector<Element*>& elements, const QualifiedName& attribute) const
{
Node* node = this->node();
Modified: trunk/Source/WebCore/accessibility/AccessibilityNodeObject.h (131904 => 131905)
--- trunk/Source/WebCore/accessibility/AccessibilityNodeObject.h 2012-10-19 15:38:13 UTC (rev 131904)
+++ trunk/Source/WebCore/accessibility/AccessibilityNodeObject.h 2012-10-19 16:24:43 UTC (rev 131905)
@@ -174,13 +174,22 @@
void ariaLabeledByElements(Vector<Element*>& elements) const;
String accessibilityDescriptionForElements(Vector<Element*> &elements) const;
void elementsFromAttribute(Vector<Element*>& elements, const QualifiedName&) const;
-
+ String ariaDescribedByAttribute() const;
+
Element* menuElementForMenuButton() const;
Element* menuItemElementForMenu() const;
AccessibilityObject* menuButtonForMenu() const;
private:
Node* m_node;
+
+ virtual void accessibilityText(Vector<AccessibilityText>&);
+ void titleElementText(Vector<AccessibilityText>&);
+ void alternativeText(Vector<AccessibilityText>&) const;
+ void visibleText(Vector<AccessibilityText>&) const;
+ void helpText(Vector<AccessibilityText>&) const;
+ String alternativeTextForWebArea() const;
+ void ariaLabeledByText(Vector<AccessibilityText>&) const;
};
inline AccessibilityNodeObject* toAccessibilityNodeObject(AccessibilityObject* object)
Modified: trunk/Source/WebCore/accessibility/AccessibilityObject.h (131904 => 131905)
--- trunk/Source/WebCore/accessibility/AccessibilityObject.h 2012-10-19 15:38:13 UTC (rev 131904)
+++ trunk/Source/WebCore/accessibility/AccessibilityObject.h 2012-10-19 16:24:43 UTC (rev 131905)
@@ -201,6 +201,41 @@
WindowRole,
};
+enum AccessibilityTextSource {
+ AlternativeText,
+ ChildrenText,
+ SummaryText,
+ HelpText,
+ VisibleText,
+ TitleTagText,
+ PlaceholderText,
+ LabelByElementText,
+};
+
+struct AccessibilityText {
+ String text;
+ AccessibilityTextSource textSource;
+ Vector<RefPtr<AccessibilityObject> > textElements;
+
+ AccessibilityText(const String& t, const AccessibilityTextSource& s)
+ : text(t)
+ , textSource(s)
+ { }
+
+ AccessibilityText(const String& t, const AccessibilityTextSource& s, const Vector<RefPtr<AccessibilityObject> > elements)
+ : text(t)
+ , textSource(s)
+ , textElements(elements)
+ { }
+
+ AccessibilityText(const String& t, const AccessibilityTextSource& s, const RefPtr<AccessibilityObject> element)
+ : text(t)
+ , textSource(s)
+ {
+ textElements.append(element);
+ }
+};
+
enum AccessibilityOrientation {
AccessibilityOrientationVertical,
AccessibilityOrientationHorizontal,
@@ -371,6 +406,7 @@
virtual bool isSpinButton() const { return roleValue() == SpinButtonRole; }
virtual bool isSpinButtonPart() const { return false; }
virtual bool isMockObject() const { return false; }
+ virtual bool isMediaControlLabel() const { return false; }
bool isTextControl() const { return roleValue() == TextAreaRole || roleValue() == TextFieldRole; }
bool isARIATextControl() const;
bool isTabList() const { return roleValue() == TabListRole; }
@@ -430,9 +466,6 @@
virtual bool canSetSelectedChildrenAttribute() const { return false; }
virtual bool canSetExpandedAttribute() const { return false; }
- // A programmatic way to set a name on an AccessibleObject.
- virtual void setAccessibleName(const AtomicString&) { }
-
virtual Node* node() const { return 0; }
virtual RenderObject* renderer() const { return 0; }
virtual bool accessibilityIsIgnored() const { return true; }
@@ -501,12 +534,29 @@
virtual bool isPresentationalChildOfAriaRole() const { return false; }
virtual bool ariaRoleHasPresentationalChildren() const { return false; }
- void setRoleValue(AccessibilityRole role) { m_role = role; }
- virtual AccessibilityRole roleValue() const { return m_role; }
+ // Accessibility Text
+ virtual void accessibilityText(Vector<AccessibilityText>&) { };
+
+ // A programmatic way to set a name on an AccessibleObject.
+ virtual void setAccessibleName(const AtomicString&) { }
+
+ // Accessibility Text - (To be deprecated).
+ virtual String accessibilityDescription() const { return String(); }
+ virtual String title() const { return String(); }
+ virtual String helpText() const { return String(); }
+
+ // Methods for determining accessibility text.
+ virtual String stringValue() const { return String(); }
+ virtual String textUnderElement() const { return String(); }
+ virtual String text() const { return String(); }
+ virtual int textLength() const { return 0; }
virtual String ariaLabeledByAttribute() const { return String(); }
virtual String ariaDescribedByAttribute() const { return String(); }
- virtual String accessibilityDescription() const { return String(); }
+ const AtomicString& placeholderValue() const;
+ void setRoleValue(AccessibilityRole role) { m_role = role; }
+ virtual AccessibilityRole roleValue() const { return m_role; }
+
virtual AXObjectCache* axObjectCache() const;
AXID axObjectID() const { return m_id; }
void setAXObjectID(AXID axObjectID) { m_id = axObjectID; }
@@ -529,12 +579,6 @@
virtual KURL url() const { return KURL(); }
virtual VisibleSelection selection() const { return VisibleSelection(); }
- virtual String stringValue() const { return String(); }
- virtual String title() const { return String(); }
- virtual String helpText() const { return String(); }
- virtual String textUnderElement() const { return String(); }
- virtual String text() const { return String(); }
- virtual int textLength() const { return 0; }
virtual String selectedText() const { return String(); }
virtual const AtomicString& accessKey() const { return nullAtom; }
const String& actionVerb() const;
@@ -546,7 +590,6 @@
virtual FrameView* documentFrameView() const;
String language() const;
virtual unsigned hierarchicalLevel() const { return 0; }
- const AtomicString& placeholderValue() const;
virtual void setFocused(bool) { }
virtual void setSelectedText(const String&) { }
Modified: trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp (131904 => 131905)
--- trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp 2012-10-19 15:38:13 UTC (rev 131904)
+++ trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp 2012-10-19 16:24:43 UTC (rev 131905)
@@ -725,72 +725,6 @@
return 0;
}
-String AccessibilityRenderObject::ariaDescribedByAttribute() const
-{
- Vector<Element*> elements;
- elementsFromAttribute(elements, aria_describedbyAttr);
-
- return accessibilityDescriptionForElements(elements);
-}
-
-String AccessibilityRenderObject::webAreaAccessibilityDescription() const
-{
- // The WebArea description should follow this order:
- // aria-label on the <html>
- // title on the <html>
- // <title> inside the <head> (of it was set through JS)
- // name on the <html>
- // For iframes:
- // aria-label on the <iframe>
- // title on the <iframe>
- // name on the <iframe>
-
- if (!m_renderer)
- return String();
-
- Document* document = m_renderer->document();
-
- // Check if the HTML element has an aria-label for the webpage.
- if (Element* documentElement = document->documentElement()) {
- const AtomicString& ariaLabel = documentElement->getAttribute(aria_labelAttr);
- if (!ariaLabel.isEmpty())
- return ariaLabel;
- }
-
- Node* owner = document->ownerElement();
- if (owner) {
- if (owner->hasTagName(frameTag) || owner->hasTagName(iframeTag)) {
- const AtomicString& title = static_cast<HTMLFrameElementBase*>(owner)->getAttribute(titleAttr);
- if (!title.isEmpty())
- return title;
- return static_cast<HTMLFrameElementBase*>(owner)->getNameAttribute();
- }
- if (owner->isHTMLElement())
- return toHTMLElement(owner)->getNameAttribute();
- }
-
- String documentTitle = document->title();
- if (!documentTitle.isEmpty())
- return documentTitle;
-
- owner = document->body();
- if (owner && owner->isHTMLElement())
- return toHTMLElement(owner)->getNameAttribute();
-
- return String();
-}
-
-String AccessibilityRenderObject::accessibilityDescription() const
-{
- if (!m_renderer)
- return String();
-
- if (isWebArea())
- return webAreaAccessibilityDescription();
-
- return AccessibilityNodeObject::accessibilityDescription();
-}
-
LayoutRect AccessibilityRenderObject::boundingBoxRect() const
{
RenderObject* obj = m_renderer;
Modified: trunk/Source/WebCore/accessibility/AccessibilityRenderObject.h (131904 => 131905)
--- trunk/Source/WebCore/accessibility/AccessibilityRenderObject.h 2012-10-19 15:38:13 UTC (rev 131904)
+++ trunk/Source/WebCore/accessibility/AccessibilityRenderObject.h 2012-10-19 16:24:43 UTC (rev 131905)
@@ -143,8 +143,6 @@
virtual PlainTextRange selectedTextRange() const;
virtual VisibleSelection selection() const;
virtual String stringValue() const;
- virtual String ariaDescribedByAttribute() const;
- virtual String accessibilityDescription() const;
virtual String helpText() const;
virtual String textUnderElement() const;
virtual String text() const;
@@ -261,8 +259,6 @@
bool elementAttributeValue(const QualifiedName&) const;
void setElementAttributeValue(const QualifiedName&, bool);
- String webAreaAccessibilityDescription() const;
-
virtual ESpeak speakProperty() const;
virtual const AtomicString& ariaLiveRegionStatus() const;
Modified: trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapper.mm (131904 => 131905)
--- trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapper.mm 2012-10-19 15:38:13 UTC (rev 131904)
+++ trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapper.mm 2012-10-19 16:24:43 UTC (rev 131905)
@@ -1826,6 +1826,103 @@
return [self remoteAccessibilityParentObject];
}
+// FIXME: Different kinds of elements are putting the title tag to use in different
+// AX fields. This should be rectified, but in the initial patch I want to achieve
+// parity with existing behavior.
+- (BOOL)titleTagShouldBeUsedInDescriptionField
+{
+ return (m_object->isLink() && !m_object->isImageMapLink()) || m_object->isImage();
+}
+
+// This should be the "visible" text that's actually on the screen if possible.
+// If there's alternative text, that can override the title.
+- (NSString *)accessibilityTitle
+{
+ // Static text objects should not have a title. Its content is communicated in its AXValue.
+ if (m_object->roleValue() == StaticTextRole)
+ return [NSString string];
+
+ Vector<AccessibilityText> textOrder;
+ m_object->accessibilityText(textOrder);
+
+ unsigned length = textOrder.size();
+ for (unsigned k = 0; k < length; k++) {
+ const AccessibilityText& text = textOrder[k];
+
+ // Once we encounter visible text, or the text from our children that should be used foremost.
+ if (text.textSource == VisibleText || text.textSource == ChildrenText)
+ return text.text;
+
+ // If there's an element that labels this object and it's not exposed, then we should use
+ // that text as our title.
+ if (text.textSource == LabelByElementText && !m_object->exposesTitleUIElement())
+ return text.text;
+
+ // FIXME: The title tag is used in certain cases for the title. This usage should
+ // probably be in the description field since it's not "visible".
+ if (text.textSource == TitleTagText && ![self titleTagShouldBeUsedInDescriptionField])
+ return text.text;
+ }
+
+ return [NSString string];
+}
+
+- (NSString *)accessibilityDescription
+{
+ // Static text objects should not have a description. Its content is communicated in its AXValue.
+ // One exception is the media control labels that have a value and a description. Those are set programatically.
+ if (m_object->roleValue() == StaticTextRole && !m_object->isMediaControlLabel())
+ return [NSString string];
+
+ Vector<AccessibilityText> textOrder;
+ m_object->accessibilityText(textOrder);
+
+ unsigned length = textOrder.size();
+ for (unsigned k = 0; k < length; k++) {
+ const AccessibilityText& text = textOrder[k];
+
+ if (text.textSource == AlternativeText)
+ return text.text;
+
+ if (text.textSource == TitleTagText && [self titleTagShouldBeUsedInDescriptionField])
+ return text.text;
+ }
+
+ return [NSString string];
+}
+
+- (NSString *)accessibilityHelpText
+{
+ Vector<AccessibilityText> textOrder;
+ m_object->accessibilityText(textOrder);
+
+ unsigned length = textOrder.size();
+ bool descriptiveTextAvailable = false;
+ for (unsigned k = 0; k < length; k++) {
+ const AccessibilityText& text = textOrder[k];
+
+ if (text.textSource == HelpText || text.textSource == SummaryText)
+ return text.text;
+
+ // If an element does NOT have other descriptive text the title tag should be used as its descriptive text.
+ // But, if those ARE available, then the title tag should be used for help text instead.
+ switch (text.textSource) {
+ case AlternativeText:
+ case VisibleText:
+ case ChildrenText:
+ case LabelByElementText:
+ descriptiveTextAvailable = true;
+ default:
+ break;
+ }
+
+ if (text.textSource == TitleTagText && descriptiveTextAvailable)
+ return text.text;
+ }
+
+ return [NSString string];
+}
+
// FIXME: split up this function in a better way.
// suggestions: Use a hash table that maps attribute names to function calls,
// or maybe pointers to member functions
@@ -1992,7 +2089,8 @@
if ([[[self attachmentView] accessibilityAttributeNames] containsObject:NSAccessibilityTitleAttribute])
return [[self attachmentView] accessibilityAttributeValue:NSAccessibilityTitleAttribute];
}
- return m_object->title();
+
+ return [self accessibilityTitle];
}
if ([attributeName isEqualToString: NSAccessibilityDescriptionAttribute]) {
@@ -2000,7 +2098,7 @@
if ([[[self attachmentView] accessibilityAttributeNames] containsObject:NSAccessibilityDescriptionAttribute])
return [[self attachmentView] accessibilityAttributeValue:NSAccessibilityDescriptionAttribute];
}
- return m_object->accessibilityDescription();
+ return [self accessibilityDescription];
}
if ([attributeName isEqualToString: NSAccessibilityValueAttribute]) {
@@ -2054,7 +2152,7 @@
return [NSNumber numberWithFloat:m_object->maxValueForRange()];
if ([attributeName isEqualToString: NSAccessibilityHelpAttribute])
- return m_object->helpText();
+ return [self accessibilityHelpText];
if ([attributeName isEqualToString: NSAccessibilityFocusedAttribute])
return [NSNumber numberWithBool: m_object->isFocused()];
Modified: trunk/Source/WebCore/platform/LocalizedStrings.cpp (131904 => 131905)
--- trunk/Source/WebCore/platform/LocalizedStrings.cpp 2012-10-19 15:38:13 UTC (rev 131904)
+++ trunk/Source/WebCore/platform/LocalizedStrings.cpp 2012-10-19 16:24:43 UTC (rev 131905)
@@ -882,6 +882,10 @@
if (name == "HideClosedCaptionsButton")
return WEB_UI_STRING("stop displaying closed captions", "accessibility help text for hide closed captions button");
+ // The description of this button is descriptive enough that it doesn't require help text.
+ if (name == "EnterFullscreenButton")
+ return String();
+
ASSERT_NOT_REACHED();
return String();
}