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 4ee9228e6fad4586fd15b2573edf91227fc9e4ff..f65f6070890e62a03c70356fe5823a0d01b0f8f0 100644 |
--- a/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp |
+++ b/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp |
@@ -52,6 +52,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" |
@@ -645,24 +646,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(); |
@@ -1669,7 +1652,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]; |
@@ -1763,9 +1746,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; |
} |
@@ -2232,39 +2214,41 @@ 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); |
- if (relatedObjects) { |
- localRelatedObjects.append(new NameSourceRelatedObject(labelAXObject, textAlternative)); |
- *relatedObjects = localRelatedObjects; |
- localRelatedObjects.clear(); |
+ LabelsNodeList* labels = toLabelableElement(htmlElement)->labels(); |
+ if (labels && labels->length() > 0) { |
+ HeapVector<Member<Element>> labelElements; |
+ for (unsigned labelIndex = 0; labelIndex < labels->length(); ++labelIndex) { |
+ Element* label = labels->item(labelIndex); |
+ if (nameSources) { |
+ if (label->getAttribute(forAttr) == htmlElement->getIdAttribute()) |
+ nameSources->last().nativeSource = AXTextFromNativeHTMLLabelFor; |
+ else |
+ nameSources->last().nativeSource = AXTextFromNativeHTMLLabelWrapped; |
} |
+ labelElements.append(label); |
+ } |
+ textAlternative = textFromElements(false, visited, labelElements, relatedObjects); |
+ if (!textAlternative.isNull()) { |
+ *foundTextAlternative = true; |
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; |
} |
+ } else if (nameSources) { |
+ nameSources->last().invalid = true; |
} |
} |
} |