Index: third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp |
diff --git a/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp b/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp |
index e27b54f495c82e0c75f2e48d521be16364cd9e35..2bec3fa21901b8037fc79c3605f8e27280d4bead 100644 |
--- a/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp |
+++ b/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp |
@@ -50,6 +50,7 @@ |
#include "core/html/HTMLTableRowElement.h" |
#include "core/html/HTMLTableSectionElement.h" |
#include "core/html/HTMLTextAreaElement.h" |
+#include "core/html/LabelsNodeList.h" |
#include "core/html/parser/HTMLParserIdioms.h" |
#include "core/html/shadow/MediaControlElements.h" |
#include "core/layout/LayoutBlockFlow.h" |
@@ -643,24 +644,6 @@ bool AXNodeObject::isGenericFocusableElement() const |
return true; |
} |
-HTMLLabelElement* AXNodeObject::labelForElement(const Element* element) const |
-{ |
- if (!element->isHTMLElement() || !toHTMLElement(element)->isLabelable()) |
- return 0; |
- |
- const AtomicString& id = element->getIdAttribute(); |
- if (!id.isEmpty()) { |
- if (HTMLLabelElement* labelFor = element->treeScope().labelElementForId(id)) |
- return labelFor; |
- } |
- |
- HTMLLabelElement* labelWrappedElement = Traversal<HTMLLabelElement>::firstAncestor(*element); |
- if (labelWrappedElement && labelWrappedElement->control() == toLabelableElement(element)) |
- return labelWrappedElement; |
- |
- return 0; |
-} |
- |
AXObject* AXNodeObject::menuButtonForMenu() const |
{ |
Element* menuItem = menuItemElementForMenu(); |
@@ -1614,7 +1597,7 @@ String AXNodeObject::textAlternative(bool recursive, bool inAriaLabelledByTraver |
nameFrom = AXNameFromUninitialized; |
- if (foundTextAlternative) { |
+ if (nameSources && foundTextAlternative) { |
for (size_t i = 0; i < nameSources->size(); ++i) { |
if (!(*nameSources)[i].text.isNull() && !(*nameSources)[i].superseded) { |
NameSource& nameSource = (*nameSources)[i]; |
@@ -1708,9 +1691,8 @@ bool AXNodeObject::nameFromLabelElement() const |
HTMLElement* htmlElement = nullptr; |
if (getNode()->isHTMLElement()) |
htmlElement = toHTMLElement(getNode()); |
- if (htmlElement && htmlElement->isLabelable()) { |
- HTMLLabelElement* label = labelForElement(htmlElement); |
- if (label) |
+ if (htmlElement && isLabelableElement(htmlElement)) { |
+ if (toLabelableElement(htmlElement)->labels() && toLabelableElement(htmlElement)->labels()->length() > 0) |
return true; |
} |
@@ -2177,40 +2159,52 @@ String AXNodeObject::nativeTextAlternative(AXObjectSet& visited, AXNameFrom& nam |
HTMLElement* htmlElement = nullptr; |
if (getNode()->isHTMLElement()) |
htmlElement = toHTMLElement(getNode()); |
+ |
if (htmlElement && htmlElement->isLabelable()) { |
- // label |
- nameFrom = AXNameFromRelatedElement; |
- if (nameSources) { |
- nameSources->append(NameSource(*foundTextAlternative)); |
- nameSources->last().type = nameFrom; |
- nameSources->last().nativeSource = AXTextFromNativeHTMLLabel; |
- } |
- HTMLLabelElement* label = labelForElement(htmlElement); |
- if (label) { |
- AXObject* labelAXObject = axObjectCache().getOrCreate(label); |
- // Avoid an infinite loop for label wrapped |
- if (labelAXObject && !visited.contains(labelAXObject)) { |
- textAlternative = recursiveTextAlternative(*labelAXObject, false, visited); |
+ LabelsNodeList* labels = toLabelableElement(htmlElement)->labels(); |
+ if (labels && labels->length() > 0) { |
+ nameFrom = AXNameFromRelatedElement; |
aboxhall
2016/05/13 20:19:16
This needs to be set outside this if block, as bef
dmazzoni
2016/05/13 22:22:42
OK, done. I was thinking it was okay to skip it if
|
+ StringBuilder accumulatedText; |
+ for (unsigned labelIndex = 0; labelIndex < labels->length(); ++labelIndex) { |
+ Element* label = labels->item(labelIndex); |
+ AXObject* labelAXObject = axObjectCache().getOrCreate(label); |
+ // Avoid an infinite loop for label wrapped |
+ if (labelAXObject && !visited.contains(labelAXObject)) { |
+ String result = recursiveTextAlternative(*labelAXObject, false, visited); |
+ if (!result.isEmpty()) { |
+ if (!accumulatedText.isEmpty()) |
+ accumulatedText.append(" "); |
+ accumulatedText.append(result); |
+ } |
- if (relatedObjects) { |
- localRelatedObjects.append(new NameSourceRelatedObject(labelAXObject, textAlternative)); |
- *relatedObjects = localRelatedObjects; |
- localRelatedObjects.clear(); |
- } |
+ if (relatedObjects) { |
+ localRelatedObjects.append(new NameSourceRelatedObject(labelAXObject, result)); |
+ *relatedObjects = localRelatedObjects; |
+ } |
- if (nameSources) { |
- NameSource& source = nameSources->last(); |
- source.relatedObjects = *relatedObjects; |
- source.text = textAlternative; |
- if (label->getAttribute(forAttr) == htmlElement->getIdAttribute()) |
- source.nativeSource = AXTextFromNativeHTMLLabelFor; |
- else |
- source.nativeSource = AXTextFromNativeHTMLLabelWrapped; |
- *foundTextAlternative = true; |
- } else { |
- return textAlternative; |
+ if (nameSources) { |
+ nameSources->append(NameSource(*foundTextAlternative)); |
+ NameSource& source = nameSources->last(); |
+ source.type = nameFrom; |
+ source.nativeSource = AXTextFromNativeHTMLLabel; |
+ source.relatedObjects = *relatedObjects; |
+ source.text = textAlternative; |
+ if (label->getAttribute(forAttr) == htmlElement->getIdAttribute()) |
+ source.nativeSource = AXTextFromNativeHTMLLabelFor; |
+ else |
+ source.nativeSource = AXTextFromNativeHTMLLabelWrapped; |
+ } |
} |
} |
+ |
+ if (relatedObjects) |
+ localRelatedObjects.clear(); |
+ |
+ textAlternative = accumulatedText.toString(); |
+ *foundTextAlternative = true; |
+ |
+ if (!nameSources) |
+ return textAlternative; |
} |
} |