Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(43)

Side by Side Diff: third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp

Issue 2614663008: Migrate WTF::Vector::append() to ::push_back() [part 13 of N] (Closed)
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2012, Google Inc. All rights reserved. 2 * Copyright (C) 2012, Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 #if ENABLE(ASSERT) 127 #if ENABLE(ASSERT)
128 // Double-check that an AXObject is never accessed before 128 // Double-check that an AXObject is never accessed before
129 // it's been initialized. 129 // it's been initialized.
130 ASSERT(m_initialized); 130 ASSERT(m_initialized);
131 #endif 131 #endif
132 132
133 // If this element is within a parent that cannot have children, it should not 133 // If this element is within a parent that cannot have children, it should not
134 // be exposed. 134 // be exposed.
135 if (isDescendantOfLeafNode()) { 135 if (isDescendantOfLeafNode()) {
136 if (ignoredReasons) 136 if (ignoredReasons)
137 ignoredReasons->append( 137 ignoredReasons->push_back(
138 IgnoredReason(AXAncestorIsLeafNode, leafNodeAncestor())); 138 IgnoredReason(AXAncestorIsLeafNode, leafNodeAncestor()));
139 return true; 139 return true;
140 } 140 }
141 141
142 // Ignore labels that are already referenced by a control. 142 // Ignore labels that are already referenced by a control.
143 AXObject* controlObject = correspondingControlForLabelElement(); 143 AXObject* controlObject = correspondingControlForLabelElement();
144 if (controlObject && controlObject->isCheckboxOrRadio() && 144 if (controlObject && controlObject->isCheckboxOrRadio() &&
145 controlObject->nameFromLabelElement()) { 145 controlObject->nameFromLabelElement()) {
146 if (ignoredReasons) { 146 if (ignoredReasons) {
147 HTMLLabelElement* label = labelElementContainer(); 147 HTMLLabelElement* label = labelElementContainer();
148 if (label && label != getNode()) { 148 if (label && label != getNode()) {
149 AXObject* labelAXObject = axObjectCache().getOrCreate(label); 149 AXObject* labelAXObject = axObjectCache().getOrCreate(label);
150 ignoredReasons->append(IgnoredReason(AXLabelContainer, labelAXObject)); 150 ignoredReasons->push_back(
151 IgnoredReason(AXLabelContainer, labelAXObject));
151 } 152 }
152 153
153 ignoredReasons->append(IgnoredReason(AXLabelFor, controlObject)); 154 ignoredReasons->push_back(IgnoredReason(AXLabelFor, controlObject));
154 } 155 }
155 return true; 156 return true;
156 } 157 }
157 158
158 Element* element = getNode()->isElementNode() ? toElement(getNode()) 159 Element* element = getNode()->isElementNode() ? toElement(getNode())
159 : getNode()->parentElement(); 160 : getNode()->parentElement();
160 if (!getLayoutObject() && (!element || !element->isInCanvasSubtree()) && 161 if (!getLayoutObject() && (!element || !element->isInCanvasSubtree()) &&
161 !equalIgnoringCase(getAttribute(aria_hiddenAttr), "false")) { 162 !equalIgnoringCase(getAttribute(aria_hiddenAttr), "false")) {
162 if (ignoredReasons) 163 if (ignoredReasons)
163 ignoredReasons->append(IgnoredReason(AXNotRendered)); 164 ignoredReasons->push_back(IgnoredReason(AXNotRendered));
164 return true; 165 return true;
165 } 166 }
166 167
167 if (m_role == UnknownRole) { 168 if (m_role == UnknownRole) {
168 if (ignoredReasons) 169 if (ignoredReasons)
169 ignoredReasons->append(IgnoredReason(AXUninteresting)); 170 ignoredReasons->push_back(IgnoredReason(AXUninteresting));
170 return true; 171 return true;
171 } 172 }
172 return false; 173 return false;
173 } 174 }
174 175
175 static bool isListElement(Node* node) { 176 static bool isListElement(Node* node) {
176 return isHTMLUListElement(*node) || isHTMLOListElement(*node) || 177 return isHTMLUListElement(*node) || isHTMLOListElement(*node) ||
177 isHTMLDListElement(*node); 178 isHTMLDListElement(*node);
178 } 179 }
179 180
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after
567 elementsFromAttribute(elements, attr); 568 elementsFromAttribute(elements, attr);
568 569
569 AXObjectCacheImpl& cache = axObjectCache(); 570 AXObjectCacheImpl& cache = axObjectCache();
570 for (const auto& element : elements) { 571 for (const auto& element : elements) {
571 if (AXObject* child = cache.getOrCreate(element)) { 572 if (AXObject* child = cache.getOrCreate(element)) {
572 // Only aria-labelledby and aria-describedby can target hidden elements. 573 // Only aria-labelledby and aria-describedby can target hidden elements.
573 if (child->accessibilityIsIgnored() && attr != aria_labelledbyAttr && 574 if (child->accessibilityIsIgnored() && attr != aria_labelledbyAttr &&
574 attr != aria_labeledbyAttr && attr != aria_describedbyAttr) { 575 attr != aria_labeledbyAttr && attr != aria_describedbyAttr) {
575 continue; 576 continue;
576 } 577 }
577 children.append(child); 578 children.push_back(child);
578 } 579 }
579 } 580 }
580 } 581 }
581 582
582 // This only returns true if this is the element that actually has the 583 // This only returns true if this is the element that actually has the
583 // contentEditable attribute set, unlike node->hasEditableStyle() which will 584 // contentEditable attribute set, unlike node->hasEditableStyle() which will
584 // also return true if an ancestor is editable. 585 // also return true if an ancestor is editable.
585 bool AXNodeObject::hasContentEditableAttributeSet() const { 586 bool AXNodeObject::hasContentEditableAttributeSet() const {
586 const AtomicString& contentEditableValue = getAttribute(contenteditableAttr); 587 const AtomicString& contentEditableValue = getAttribute(contenteditableAttr);
587 if (contentEditableValue.isNull()) 588 if (contentEditableValue.isNull())
(...skipping 612 matching lines...) Expand 10 before | Expand all | Expand 10 after
1200 return; 1201 return;
1201 1202
1202 DocumentMarkerController& markerController = getDocument()->markers(); 1203 DocumentMarkerController& markerController = getDocument()->markers();
1203 DocumentMarkerVector markers = markerController.markersFor(getNode()); 1204 DocumentMarkerVector markers = markerController.markersFor(getNode());
1204 for (size_t i = 0; i < markers.size(); ++i) { 1205 for (size_t i = 0; i < markers.size(); ++i) {
1205 DocumentMarker* marker = markers[i]; 1206 DocumentMarker* marker = markers[i];
1206 switch (marker->type()) { 1207 switch (marker->type()) {
1207 case DocumentMarker::Spelling: 1208 case DocumentMarker::Spelling:
1208 case DocumentMarker::Grammar: 1209 case DocumentMarker::Grammar:
1209 case DocumentMarker::TextMatch: 1210 case DocumentMarker::TextMatch:
1210 markerTypes.append(marker->type()); 1211 markerTypes.push_back(marker->type());
1211 markerRanges.append( 1212 markerRanges.push_back(
1212 AXRange(marker->startOffset(), marker->endOffset())); 1213 AXRange(marker->startOffset(), marker->endOffset()));
1213 break; 1214 break;
1214 case DocumentMarker::InvisibleSpellcheck: 1215 case DocumentMarker::InvisibleSpellcheck:
1215 case DocumentMarker::Composition: 1216 case DocumentMarker::Composition:
1216 // No need for accessibility to know about these marker types. 1217 // No need for accessibility to know about these marker types.
1217 break; 1218 break;
1218 } 1219 }
1219 } 1220 }
1220 } 1221 }
1221 1222
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after
1580 // Step 2D from: http://www.w3.org/TR/accname-aam-1.1 1581 // Step 2D from: http://www.w3.org/TR/accname-aam-1.1
1581 textAlternative = nativeTextAlternative(visited, nameFrom, relatedObjects, 1582 textAlternative = nativeTextAlternative(visited, nameFrom, relatedObjects,
1582 nameSources, &foundTextAlternative); 1583 nameSources, &foundTextAlternative);
1583 if (!textAlternative.isEmpty() && !nameSources) 1584 if (!textAlternative.isEmpty() && !nameSources)
1584 return textAlternative; 1585 return textAlternative;
1585 1586
1586 // Step 2F / 2G from: http://www.w3.org/TR/accname-aam-1.1 1587 // Step 2F / 2G from: http://www.w3.org/TR/accname-aam-1.1
1587 if (recursive || nameFromContents()) { 1588 if (recursive || nameFromContents()) {
1588 nameFrom = AXNameFromContents; 1589 nameFrom = AXNameFromContents;
1589 if (nameSources) { 1590 if (nameSources) {
1590 nameSources->append(NameSource(foundTextAlternative)); 1591 nameSources->push_back(NameSource(foundTextAlternative));
1591 nameSources->back().type = nameFrom; 1592 nameSources->back().type = nameFrom;
1592 } 1593 }
1593 1594
1594 Node* node = this->getNode(); 1595 Node* node = this->getNode();
1595 if (node && node->isTextNode()) 1596 if (node && node->isTextNode())
1596 textAlternative = toText(node)->wholeText(); 1597 textAlternative = toText(node)->wholeText();
1597 else if (isHTMLBRElement(node)) 1598 else if (isHTMLBRElement(node))
1598 textAlternative = String("\n"); 1599 textAlternative = String("\n");
1599 else 1600 else
1600 textAlternative = textFromDescendants(visited, false); 1601 textAlternative = textFromDescendants(visited, false);
1601 1602
1602 if (!textAlternative.isEmpty()) { 1603 if (!textAlternative.isEmpty()) {
1603 if (nameSources) { 1604 if (nameSources) {
1604 foundTextAlternative = true; 1605 foundTextAlternative = true;
1605 nameSources->back().text = textAlternative; 1606 nameSources->back().text = textAlternative;
1606 } else { 1607 } else {
1607 return textAlternative; 1608 return textAlternative;
1608 } 1609 }
1609 } 1610 }
1610 } 1611 }
1611 1612
1612 // Step 2H from: http://www.w3.org/TR/accname-aam-1.1 1613 // Step 2H from: http://www.w3.org/TR/accname-aam-1.1
1613 nameFrom = AXNameFromTitle; 1614 nameFrom = AXNameFromTitle;
1614 if (nameSources) { 1615 if (nameSources) {
1615 nameSources->append(NameSource(foundTextAlternative, titleAttr)); 1616 nameSources->push_back(NameSource(foundTextAlternative, titleAttr));
1616 nameSources->back().type = nameFrom; 1617 nameSources->back().type = nameFrom;
1617 } 1618 }
1618 const AtomicString& title = getAttribute(titleAttr); 1619 const AtomicString& title = getAttribute(titleAttr);
1619 if (!title.isEmpty()) { 1620 if (!title.isEmpty()) {
1620 textAlternative = title; 1621 textAlternative = title;
1621 if (nameSources) { 1622 if (nameSources) {
1622 foundTextAlternative = true; 1623 foundTextAlternative = true;
1623 nameSources->back().text = textAlternative; 1624 nameSources->back().text = textAlternative;
1624 } else { 1625 } else {
1625 return textAlternative; 1626 return textAlternative;
(...skipping 24 matching lines...) Expand all
1650 1651
1651 StringBuilder accumulatedText; 1652 StringBuilder accumulatedText;
1652 AXObject* previous = nullptr; 1653 AXObject* previous = nullptr;
1653 1654
1654 AXObjectVector children; 1655 AXObjectVector children;
1655 1656
1656 HeapVector<Member<AXObject>> ownedChildren; 1657 HeapVector<Member<AXObject>> ownedChildren;
1657 computeAriaOwnsChildren(ownedChildren); 1658 computeAriaOwnsChildren(ownedChildren);
1658 for (AXObject* obj = rawFirstChild(); obj; obj = obj->rawNextSibling()) { 1659 for (AXObject* obj = rawFirstChild(); obj; obj = obj->rawNextSibling()) {
1659 if (!axObjectCache().isAriaOwned(obj)) 1660 if (!axObjectCache().isAriaOwned(obj))
1660 children.append(obj); 1661 children.push_back(obj);
1661 } 1662 }
1662 for (const auto& ownedChild : ownedChildren) 1663 for (const auto& ownedChild : ownedChildren)
1663 children.append(ownedChild); 1664 children.push_back(ownedChild);
1664 1665
1665 for (AXObject* child : children) { 1666 for (AXObject* child : children) {
1666 // Don't recurse into children that are explicitly marked as aria-hidden. 1667 // Don't recurse into children that are explicitly marked as aria-hidden.
1667 // Note that we don't call isInertOrAriaHidden because that would return 1668 // Note that we don't call isInertOrAriaHidden because that would return
1668 // true if any ancestor is hidden, but we need to be able to compute the 1669 // true if any ancestor is hidden, but we need to be able to compute the
1669 // accessible name of object inside hidden subtrees (for example, if 1670 // accessible name of object inside hidden subtrees (for example, if
1670 // aria-labelledby points to an object that's hidden). 1671 // aria-labelledby points to an object that's hidden).
1671 if (equalIgnoringCase(child->getAttribute(aria_hiddenAttr), "true")) 1672 if (equalIgnoringCase(child->getAttribute(aria_hiddenAttr), "true"))
1672 continue; 1673 continue;
1673 1674
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1765 if (getNode()->parentElement()->isInCanvasSubtree()) { 1766 if (getNode()->parentElement()->isInCanvasSubtree()) {
1766 Vector<FloatRect> rects; 1767 Vector<FloatRect> rects;
1767 for (Node& child : NodeTraversal::childrenOf(*getNode())) { 1768 for (Node& child : NodeTraversal::childrenOf(*getNode())) {
1768 if (child.isHTMLElement()) { 1769 if (child.isHTMLElement()) {
1769 if (AXObject* obj = axObjectCache().get(&child)) { 1770 if (AXObject* obj = axObjectCache().get(&child)) {
1770 AXObject* container; 1771 AXObject* container;
1771 FloatRect bounds; 1772 FloatRect bounds;
1772 obj->getRelativeBounds(&container, bounds, outContainerTransform); 1773 obj->getRelativeBounds(&container, bounds, outContainerTransform);
1773 if (container) { 1774 if (container) {
1774 *outContainer = container; 1775 *outContainer = container;
1775 rects.append(bounds); 1776 rects.push_back(bounds);
1776 } 1777 }
1777 } 1778 }
1778 } 1779 }
1779 } 1780 }
1780 1781
1781 if (*outContainer) { 1782 if (*outContainer) {
1782 outBoundsInContainer = unionRect(rects); 1783 outBoundsInContainer = unionRect(rects);
1783 return; 1784 return;
1784 } 1785 }
1785 } 1786 }
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after
2239 2240
2240 // 5.1/5.5 Text inputs, Other labelable Elements 2241 // 5.1/5.5 Text inputs, Other labelable Elements
2241 // If you change this logic, update AXNodeObject::nameFromLabelElement, too. 2242 // If you change this logic, update AXNodeObject::nameFromLabelElement, too.
2242 HTMLElement* htmlElement = nullptr; 2243 HTMLElement* htmlElement = nullptr;
2243 if (getNode()->isHTMLElement()) 2244 if (getNode()->isHTMLElement())
2244 htmlElement = toHTMLElement(getNode()); 2245 htmlElement = toHTMLElement(getNode());
2245 2246
2246 if (htmlElement && htmlElement->isLabelable()) { 2247 if (htmlElement && htmlElement->isLabelable()) {
2247 nameFrom = AXNameFromRelatedElement; 2248 nameFrom = AXNameFromRelatedElement;
2248 if (nameSources) { 2249 if (nameSources) {
2249 nameSources->append(NameSource(*foundTextAlternative)); 2250 nameSources->push_back(NameSource(*foundTextAlternative));
2250 nameSources->back().type = nameFrom; 2251 nameSources->back().type = nameFrom;
2251 nameSources->back().nativeSource = AXTextFromNativeHTMLLabel; 2252 nameSources->back().nativeSource = AXTextFromNativeHTMLLabel;
2252 } 2253 }
2253 2254
2254 LabelsNodeList* labels = toLabelableElement(htmlElement)->labels(); 2255 LabelsNodeList* labels = toLabelableElement(htmlElement)->labels();
2255 if (labels && labels->length() > 0) { 2256 if (labels && labels->length() > 0) {
2256 HeapVector<Member<Element>> labelElements; 2257 HeapVector<Member<Element>> labelElements;
2257 for (unsigned labelIndex = 0; labelIndex < labels->length(); 2258 for (unsigned labelIndex = 0; labelIndex < labels->length();
2258 ++labelIndex) { 2259 ++labelIndex) {
2259 Element* label = labels->item(labelIndex); 2260 Element* label = labels->item(labelIndex);
2260 if (nameSources) { 2261 if (nameSources) {
2261 if (label->getAttribute(forAttr) == htmlElement->getIdAttribute()) 2262 if (label->getAttribute(forAttr) == htmlElement->getIdAttribute())
2262 nameSources->back().nativeSource = AXTextFromNativeHTMLLabelFor; 2263 nameSources->back().nativeSource = AXTextFromNativeHTMLLabelFor;
2263 else 2264 else
2264 nameSources->back().nativeSource = AXTextFromNativeHTMLLabelWrapped; 2265 nameSources->back().nativeSource = AXTextFromNativeHTMLLabelWrapped;
2265 } 2266 }
2266 labelElements.append(label); 2267 labelElements.push_back(label);
2267 } 2268 }
2268 2269
2269 textAlternative = 2270 textAlternative =
2270 textFromElements(false, visited, labelElements, relatedObjects); 2271 textFromElements(false, visited, labelElements, relatedObjects);
2271 if (!textAlternative.isNull()) { 2272 if (!textAlternative.isNull()) {
2272 *foundTextAlternative = true; 2273 *foundTextAlternative = true;
2273 if (nameSources) { 2274 if (nameSources) {
2274 NameSource& source = nameSources->back(); 2275 NameSource& source = nameSources->back();
2275 source.relatedObjects = *relatedObjects; 2276 source.relatedObjects = *relatedObjects;
2276 source.text = textAlternative; 2277 source.text = textAlternative;
2277 } else { 2278 } else {
2278 return textAlternative; 2279 return textAlternative;
2279 } 2280 }
2280 } else if (nameSources) { 2281 } else if (nameSources) {
2281 nameSources->back().invalid = true; 2282 nameSources->back().invalid = true;
2282 } 2283 }
2283 } 2284 }
2284 } 2285 }
2285 2286
2286 // 5.2 input type="button", input type="submit" and input type="reset" 2287 // 5.2 input type="button", input type="submit" and input type="reset"
2287 if (inputElement && inputElement->isTextButton()) { 2288 if (inputElement && inputElement->isTextButton()) {
2288 // value attribue 2289 // value attribue
2289 nameFrom = AXNameFromValue; 2290 nameFrom = AXNameFromValue;
2290 if (nameSources) { 2291 if (nameSources) {
2291 nameSources->append(NameSource(*foundTextAlternative, valueAttr)); 2292 nameSources->push_back(NameSource(*foundTextAlternative, valueAttr));
2292 nameSources->back().type = nameFrom; 2293 nameSources->back().type = nameFrom;
2293 } 2294 }
2294 String value = inputElement->value(); 2295 String value = inputElement->value();
2295 if (!value.isNull()) { 2296 if (!value.isNull()) {
2296 textAlternative = value; 2297 textAlternative = value;
2297 if (nameSources) { 2298 if (nameSources) {
2298 NameSource& source = nameSources->back(); 2299 NameSource& source = nameSources->back();
2299 source.text = textAlternative; 2300 source.text = textAlternative;
2300 *foundTextAlternative = true; 2301 *foundTextAlternative = true;
2301 } else { 2302 } else {
2302 return textAlternative; 2303 return textAlternative;
2303 } 2304 }
2304 } 2305 }
2305 return textAlternative; 2306 return textAlternative;
2306 } 2307 }
2307 2308
2308 // 5.3 input type="image" 2309 // 5.3 input type="image"
2309 if (inputElement && 2310 if (inputElement &&
2310 inputElement->getAttribute(typeAttr) == InputTypeNames::image) { 2311 inputElement->getAttribute(typeAttr) == InputTypeNames::image) {
2311 // alt attr 2312 // alt attr
2312 nameFrom = AXNameFromAttribute; 2313 nameFrom = AXNameFromAttribute;
2313 if (nameSources) { 2314 if (nameSources) {
2314 nameSources->append(NameSource(*foundTextAlternative, altAttr)); 2315 nameSources->push_back(NameSource(*foundTextAlternative, altAttr));
2315 nameSources->back().type = nameFrom; 2316 nameSources->back().type = nameFrom;
2316 } 2317 }
2317 const AtomicString& alt = inputElement->getAttribute(altAttr); 2318 const AtomicString& alt = inputElement->getAttribute(altAttr);
2318 if (!alt.isNull()) { 2319 if (!alt.isNull()) {
2319 textAlternative = alt; 2320 textAlternative = alt;
2320 if (nameSources) { 2321 if (nameSources) {
2321 NameSource& source = nameSources->back(); 2322 NameSource& source = nameSources->back();
2322 source.attributeValue = alt; 2323 source.attributeValue = alt;
2323 source.text = textAlternative; 2324 source.text = textAlternative;
2324 *foundTextAlternative = true; 2325 *foundTextAlternative = true;
2325 } else { 2326 } else {
2326 return textAlternative; 2327 return textAlternative;
2327 } 2328 }
2328 } 2329 }
2329 2330
2330 // value attr 2331 // value attr
2331 if (nameSources) { 2332 if (nameSources) {
2332 nameSources->append(NameSource(*foundTextAlternative, valueAttr)); 2333 nameSources->push_back(NameSource(*foundTextAlternative, valueAttr));
2333 nameSources->back().type = nameFrom; 2334 nameSources->back().type = nameFrom;
2334 } 2335 }
2335 nameFrom = AXNameFromAttribute; 2336 nameFrom = AXNameFromAttribute;
2336 String value = inputElement->value(); 2337 String value = inputElement->value();
2337 if (!value.isNull()) { 2338 if (!value.isNull()) {
2338 textAlternative = value; 2339 textAlternative = value;
2339 if (nameSources) { 2340 if (nameSources) {
2340 NameSource& source = nameSources->back(); 2341 NameSource& source = nameSources->back();
2341 source.text = textAlternative; 2342 source.text = textAlternative;
2342 *foundTextAlternative = true; 2343 *foundTextAlternative = true;
2343 } else { 2344 } else {
2344 return textAlternative; 2345 return textAlternative;
2345 } 2346 }
2346 } 2347 }
2347 2348
2348 // localised default value ("Submit") 2349 // localised default value ("Submit")
2349 nameFrom = AXNameFromValue; 2350 nameFrom = AXNameFromValue;
2350 textAlternative = inputElement->locale().queryString( 2351 textAlternative = inputElement->locale().queryString(
2351 WebLocalizedString::SubmitButtonDefaultLabel); 2352 WebLocalizedString::SubmitButtonDefaultLabel);
2352 if (nameSources) { 2353 if (nameSources) {
2353 nameSources->append(NameSource(*foundTextAlternative, typeAttr)); 2354 nameSources->push_back(NameSource(*foundTextAlternative, typeAttr));
2354 NameSource& source = nameSources->back(); 2355 NameSource& source = nameSources->back();
2355 source.attributeValue = inputElement->getAttribute(typeAttr); 2356 source.attributeValue = inputElement->getAttribute(typeAttr);
2356 source.type = nameFrom; 2357 source.type = nameFrom;
2357 source.text = textAlternative; 2358 source.text = textAlternative;
2358 *foundTextAlternative = true; 2359 *foundTextAlternative = true;
2359 } else { 2360 } else {
2360 return textAlternative; 2361 return textAlternative;
2361 } 2362 }
2362 return textAlternative; 2363 return textAlternative;
2363 } 2364 }
2364 2365
2365 // 5.1 Text inputs - step 3 (placeholder attribute) 2366 // 5.1 Text inputs - step 3 (placeholder attribute)
2366 if (htmlElement && htmlElement->isTextControl()) { 2367 if (htmlElement && htmlElement->isTextControl()) {
2367 nameFrom = AXNameFromPlaceholder; 2368 nameFrom = AXNameFromPlaceholder;
2368 if (nameSources) { 2369 if (nameSources) {
2369 nameSources->append(NameSource(*foundTextAlternative, placeholderAttr)); 2370 nameSources->push_back(
2371 NameSource(*foundTextAlternative, placeholderAttr));
2370 NameSource& source = nameSources->back(); 2372 NameSource& source = nameSources->back();
2371 source.type = nameFrom; 2373 source.type = nameFrom;
2372 } 2374 }
2373 const String placeholder = placeholderFromNativeAttribute(); 2375 const String placeholder = placeholderFromNativeAttribute();
2374 if (!placeholder.isEmpty()) { 2376 if (!placeholder.isEmpty()) {
2375 textAlternative = placeholder; 2377 textAlternative = placeholder;
2376 if (nameSources) { 2378 if (nameSources) {
2377 NameSource& source = nameSources->back(); 2379 NameSource& source = nameSources->back();
2378 source.text = textAlternative; 2380 source.text = textAlternative;
2379 source.attributeValue = htmlElement->fastGetAttribute(placeholderAttr); 2381 source.attributeValue = htmlElement->fastGetAttribute(placeholderAttr);
2380 *foundTextAlternative = true; 2382 *foundTextAlternative = true;
2381 } else { 2383 } else {
2382 return textAlternative; 2384 return textAlternative;
2383 } 2385 }
2384 } 2386 }
2385 2387
2386 // Also check for aria-placeholder. 2388 // Also check for aria-placeholder.
2387 nameFrom = AXNameFromPlaceholder; 2389 nameFrom = AXNameFromPlaceholder;
2388 if (nameSources) { 2390 if (nameSources) {
2389 nameSources->append( 2391 nameSources->push_back(
2390 NameSource(*foundTextAlternative, aria_placeholderAttr)); 2392 NameSource(*foundTextAlternative, aria_placeholderAttr));
2391 NameSource& source = nameSources->back(); 2393 NameSource& source = nameSources->back();
2392 source.type = nameFrom; 2394 source.type = nameFrom;
2393 } 2395 }
2394 const AtomicString& ariaPlaceholder = 2396 const AtomicString& ariaPlaceholder =
2395 htmlElement->fastGetAttribute(aria_placeholderAttr); 2397 htmlElement->fastGetAttribute(aria_placeholderAttr);
2396 if (!ariaPlaceholder.isEmpty()) { 2398 if (!ariaPlaceholder.isEmpty()) {
2397 textAlternative = ariaPlaceholder; 2399 textAlternative = ariaPlaceholder;
2398 if (nameSources) { 2400 if (nameSources) {
2399 NameSource& source = nameSources->back(); 2401 NameSource& source = nameSources->back();
2400 source.text = textAlternative; 2402 source.text = textAlternative;
2401 source.attributeValue = ariaPlaceholder; 2403 source.attributeValue = ariaPlaceholder;
2402 *foundTextAlternative = true; 2404 *foundTextAlternative = true;
2403 } else { 2405 } else {
2404 return textAlternative; 2406 return textAlternative;
2405 } 2407 }
2406 } 2408 }
2407 2409
2408 return textAlternative; 2410 return textAlternative;
2409 } 2411 }
2410 2412
2411 // 5.7 figure and figcaption Elements 2413 // 5.7 figure and figcaption Elements
2412 if (getNode()->hasTagName(figureTag)) { 2414 if (getNode()->hasTagName(figureTag)) {
2413 // figcaption 2415 // figcaption
2414 nameFrom = AXNameFromRelatedElement; 2416 nameFrom = AXNameFromRelatedElement;
2415 if (nameSources) { 2417 if (nameSources) {
2416 nameSources->append(NameSource(*foundTextAlternative)); 2418 nameSources->push_back(NameSource(*foundTextAlternative));
2417 nameSources->back().type = nameFrom; 2419 nameSources->back().type = nameFrom;
2418 nameSources->back().nativeSource = AXTextFromNativeHTMLFigcaption; 2420 nameSources->back().nativeSource = AXTextFromNativeHTMLFigcaption;
2419 } 2421 }
2420 Element* figcaption = nullptr; 2422 Element* figcaption = nullptr;
2421 for (Element& element : ElementTraversal::descendantsOf(*(getNode()))) { 2423 for (Element& element : ElementTraversal::descendantsOf(*(getNode()))) {
2422 if (element.hasTagName(figcaptionTag)) { 2424 if (element.hasTagName(figcaptionTag)) {
2423 figcaption = &element; 2425 figcaption = &element;
2424 break; 2426 break;
2425 } 2427 }
2426 } 2428 }
2427 if (figcaption) { 2429 if (figcaption) {
2428 AXObject* figcaptionAXObject = axObjectCache().getOrCreate(figcaption); 2430 AXObject* figcaptionAXObject = axObjectCache().getOrCreate(figcaption);
2429 if (figcaptionAXObject) { 2431 if (figcaptionAXObject) {
2430 textAlternative = 2432 textAlternative =
2431 recursiveTextAlternative(*figcaptionAXObject, false, visited); 2433 recursiveTextAlternative(*figcaptionAXObject, false, visited);
2432 2434
2433 if (relatedObjects) { 2435 if (relatedObjects) {
2434 localRelatedObjects.append( 2436 localRelatedObjects.push_back(
2435 new NameSourceRelatedObject(figcaptionAXObject, textAlternative)); 2437 new NameSourceRelatedObject(figcaptionAXObject, textAlternative));
2436 *relatedObjects = localRelatedObjects; 2438 *relatedObjects = localRelatedObjects;
2437 localRelatedObjects.clear(); 2439 localRelatedObjects.clear();
2438 } 2440 }
2439 2441
2440 if (nameSources) { 2442 if (nameSources) {
2441 NameSource& source = nameSources->back(); 2443 NameSource& source = nameSources->back();
2442 source.relatedObjects = *relatedObjects; 2444 source.relatedObjects = *relatedObjects;
2443 source.text = textAlternative; 2445 source.text = textAlternative;
2444 *foundTextAlternative = true; 2446 *foundTextAlternative = true;
2445 } else { 2447 } else {
2446 return textAlternative; 2448 return textAlternative;
2447 } 2449 }
2448 } 2450 }
2449 } 2451 }
2450 return textAlternative; 2452 return textAlternative;
2451 } 2453 }
2452 2454
2453 // 5.8 img or area Element 2455 // 5.8 img or area Element
2454 if (isHTMLImageElement(getNode()) || isHTMLAreaElement(getNode()) || 2456 if (isHTMLImageElement(getNode()) || isHTMLAreaElement(getNode()) ||
2455 (getLayoutObject() && getLayoutObject()->isSVGImage())) { 2457 (getLayoutObject() && getLayoutObject()->isSVGImage())) {
2456 // alt 2458 // alt
2457 nameFrom = AXNameFromAttribute; 2459 nameFrom = AXNameFromAttribute;
2458 if (nameSources) { 2460 if (nameSources) {
2459 nameSources->append(NameSource(*foundTextAlternative, altAttr)); 2461 nameSources->push_back(NameSource(*foundTextAlternative, altAttr));
2460 nameSources->back().type = nameFrom; 2462 nameSources->back().type = nameFrom;
2461 } 2463 }
2462 const AtomicString& alt = getAttribute(altAttr); 2464 const AtomicString& alt = getAttribute(altAttr);
2463 if (!alt.isNull()) { 2465 if (!alt.isNull()) {
2464 textAlternative = alt; 2466 textAlternative = alt;
2465 if (nameSources) { 2467 if (nameSources) {
2466 NameSource& source = nameSources->back(); 2468 NameSource& source = nameSources->back();
2467 source.attributeValue = alt; 2469 source.attributeValue = alt;
2468 source.text = textAlternative; 2470 source.text = textAlternative;
2469 *foundTextAlternative = true; 2471 *foundTextAlternative = true;
2470 } else { 2472 } else {
2471 return textAlternative; 2473 return textAlternative;
2472 } 2474 }
2473 } 2475 }
2474 return textAlternative; 2476 return textAlternative;
2475 } 2477 }
2476 2478
2477 // 5.9 table Element 2479 // 5.9 table Element
2478 if (isHTMLTableElement(getNode())) { 2480 if (isHTMLTableElement(getNode())) {
2479 HTMLTableElement* tableElement = toHTMLTableElement(getNode()); 2481 HTMLTableElement* tableElement = toHTMLTableElement(getNode());
2480 2482
2481 // caption 2483 // caption
2482 nameFrom = AXNameFromCaption; 2484 nameFrom = AXNameFromCaption;
2483 if (nameSources) { 2485 if (nameSources) {
2484 nameSources->append(NameSource(*foundTextAlternative)); 2486 nameSources->push_back(NameSource(*foundTextAlternative));
2485 nameSources->back().type = nameFrom; 2487 nameSources->back().type = nameFrom;
2486 nameSources->back().nativeSource = AXTextFromNativeHTMLTableCaption; 2488 nameSources->back().nativeSource = AXTextFromNativeHTMLTableCaption;
2487 } 2489 }
2488 HTMLTableCaptionElement* caption = tableElement->caption(); 2490 HTMLTableCaptionElement* caption = tableElement->caption();
2489 if (caption) { 2491 if (caption) {
2490 AXObject* captionAXObject = axObjectCache().getOrCreate(caption); 2492 AXObject* captionAXObject = axObjectCache().getOrCreate(caption);
2491 if (captionAXObject) { 2493 if (captionAXObject) {
2492 textAlternative = 2494 textAlternative =
2493 recursiveTextAlternative(*captionAXObject, false, visited); 2495 recursiveTextAlternative(*captionAXObject, false, visited);
2494 if (relatedObjects) { 2496 if (relatedObjects) {
2495 localRelatedObjects.append( 2497 localRelatedObjects.push_back(
2496 new NameSourceRelatedObject(captionAXObject, textAlternative)); 2498 new NameSourceRelatedObject(captionAXObject, textAlternative));
2497 *relatedObjects = localRelatedObjects; 2499 *relatedObjects = localRelatedObjects;
2498 localRelatedObjects.clear(); 2500 localRelatedObjects.clear();
2499 } 2501 }
2500 2502
2501 if (nameSources) { 2503 if (nameSources) {
2502 NameSource& source = nameSources->back(); 2504 NameSource& source = nameSources->back();
2503 source.relatedObjects = *relatedObjects; 2505 source.relatedObjects = *relatedObjects;
2504 source.text = textAlternative; 2506 source.text = textAlternative;
2505 *foundTextAlternative = true; 2507 *foundTextAlternative = true;
2506 } else { 2508 } else {
2507 return textAlternative; 2509 return textAlternative;
2508 } 2510 }
2509 } 2511 }
2510 } 2512 }
2511 2513
2512 // summary 2514 // summary
2513 nameFrom = AXNameFromAttribute; 2515 nameFrom = AXNameFromAttribute;
2514 if (nameSources) { 2516 if (nameSources) {
2515 nameSources->append(NameSource(*foundTextAlternative, summaryAttr)); 2517 nameSources->push_back(NameSource(*foundTextAlternative, summaryAttr));
2516 nameSources->back().type = nameFrom; 2518 nameSources->back().type = nameFrom;
2517 } 2519 }
2518 const AtomicString& summary = getAttribute(summaryAttr); 2520 const AtomicString& summary = getAttribute(summaryAttr);
2519 if (!summary.isNull()) { 2521 if (!summary.isNull()) {
2520 textAlternative = summary; 2522 textAlternative = summary;
2521 if (nameSources) { 2523 if (nameSources) {
2522 NameSource& source = nameSources->back(); 2524 NameSource& source = nameSources->back();
2523 source.attributeValue = summary; 2525 source.attributeValue = summary;
2524 source.text = textAlternative; 2526 source.text = textAlternative;
2525 *foundTextAlternative = true; 2527 *foundTextAlternative = true;
2526 } else { 2528 } else {
2527 return textAlternative; 2529 return textAlternative;
2528 } 2530 }
2529 } 2531 }
2530 2532
2531 return textAlternative; 2533 return textAlternative;
2532 } 2534 }
2533 2535
2534 // Per SVG AAM 1.0's modifications to 2D of this algorithm. 2536 // Per SVG AAM 1.0's modifications to 2D of this algorithm.
2535 if (getNode()->isSVGElement()) { 2537 if (getNode()->isSVGElement()) {
2536 nameFrom = AXNameFromRelatedElement; 2538 nameFrom = AXNameFromRelatedElement;
2537 if (nameSources) { 2539 if (nameSources) {
2538 nameSources->append(NameSource(*foundTextAlternative)); 2540 nameSources->push_back(NameSource(*foundTextAlternative));
2539 nameSources->back().type = nameFrom; 2541 nameSources->back().type = nameFrom;
2540 nameSources->back().nativeSource = AXTextFromNativeHTMLTitleElement; 2542 nameSources->back().nativeSource = AXTextFromNativeHTMLTitleElement;
2541 } 2543 }
2542 ASSERT(getNode()->isContainerNode()); 2544 ASSERT(getNode()->isContainerNode());
2543 Element* title = ElementTraversal::firstChild( 2545 Element* title = ElementTraversal::firstChild(
2544 toContainerNode(*(getNode())), HasTagName(SVGNames::titleTag)); 2546 toContainerNode(*(getNode())), HasTagName(SVGNames::titleTag));
2545 2547
2546 if (title) { 2548 if (title) {
2547 AXObject* titleAXObject = axObjectCache().getOrCreate(title); 2549 AXObject* titleAXObject = axObjectCache().getOrCreate(title);
2548 if (titleAXObject && !visited.contains(titleAXObject)) { 2550 if (titleAXObject && !visited.contains(titleAXObject)) {
2549 textAlternative = 2551 textAlternative =
2550 recursiveTextAlternative(*titleAXObject, false, visited); 2552 recursiveTextAlternative(*titleAXObject, false, visited);
2551 if (relatedObjects) { 2553 if (relatedObjects) {
2552 localRelatedObjects.append( 2554 localRelatedObjects.push_back(
2553 new NameSourceRelatedObject(titleAXObject, textAlternative)); 2555 new NameSourceRelatedObject(titleAXObject, textAlternative));
2554 *relatedObjects = localRelatedObjects; 2556 *relatedObjects = localRelatedObjects;
2555 localRelatedObjects.clear(); 2557 localRelatedObjects.clear();
2556 } 2558 }
2557 } 2559 }
2558 if (nameSources) { 2560 if (nameSources) {
2559 NameSource& source = nameSources->back(); 2561 NameSource& source = nameSources->back();
2560 source.text = textAlternative; 2562 source.text = textAlternative;
2561 source.relatedObjects = *relatedObjects; 2563 source.relatedObjects = *relatedObjects;
2562 *foundTextAlternative = true; 2564 *foundTextAlternative = true;
2563 } else { 2565 } else {
2564 return textAlternative; 2566 return textAlternative;
2565 } 2567 }
2566 } 2568 }
2567 } 2569 }
2568 2570
2569 // Fieldset / legend. 2571 // Fieldset / legend.
2570 if (isHTMLFieldSetElement(getNode())) { 2572 if (isHTMLFieldSetElement(getNode())) {
2571 nameFrom = AXNameFromRelatedElement; 2573 nameFrom = AXNameFromRelatedElement;
2572 if (nameSources) { 2574 if (nameSources) {
2573 nameSources->append(NameSource(*foundTextAlternative)); 2575 nameSources->push_back(NameSource(*foundTextAlternative));
2574 nameSources->back().type = nameFrom; 2576 nameSources->back().type = nameFrom;
2575 nameSources->back().nativeSource = AXTextFromNativeHTMLLegend; 2577 nameSources->back().nativeSource = AXTextFromNativeHTMLLegend;
2576 } 2578 }
2577 HTMLElement* legend = toHTMLFieldSetElement(getNode())->legend(); 2579 HTMLElement* legend = toHTMLFieldSetElement(getNode())->legend();
2578 if (legend) { 2580 if (legend) {
2579 AXObject* legendAXObject = axObjectCache().getOrCreate(legend); 2581 AXObject* legendAXObject = axObjectCache().getOrCreate(legend);
2580 // Avoid an infinite loop 2582 // Avoid an infinite loop
2581 if (legendAXObject && !visited.contains(legendAXObject)) { 2583 if (legendAXObject && !visited.contains(legendAXObject)) {
2582 textAlternative = 2584 textAlternative =
2583 recursiveTextAlternative(*legendAXObject, false, visited); 2585 recursiveTextAlternative(*legendAXObject, false, visited);
2584 2586
2585 if (relatedObjects) { 2587 if (relatedObjects) {
2586 localRelatedObjects.append( 2588 localRelatedObjects.push_back(
2587 new NameSourceRelatedObject(legendAXObject, textAlternative)); 2589 new NameSourceRelatedObject(legendAXObject, textAlternative));
2588 *relatedObjects = localRelatedObjects; 2590 *relatedObjects = localRelatedObjects;
2589 localRelatedObjects.clear(); 2591 localRelatedObjects.clear();
2590 } 2592 }
2591 2593
2592 if (nameSources) { 2594 if (nameSources) {
2593 NameSource& source = nameSources->back(); 2595 NameSource& source = nameSources->back();
2594 source.relatedObjects = *relatedObjects; 2596 source.relatedObjects = *relatedObjects;
2595 source.text = textAlternative; 2597 source.text = textAlternative;
2596 *foundTextAlternative = true; 2598 *foundTextAlternative = true;
2597 } else { 2599 } else {
2598 return textAlternative; 2600 return textAlternative;
2599 } 2601 }
2600 } 2602 }
2601 } 2603 }
2602 } 2604 }
2603 2605
2604 // Document. 2606 // Document.
2605 if (isWebArea()) { 2607 if (isWebArea()) {
2606 Document* document = this->getDocument(); 2608 Document* document = this->getDocument();
2607 if (document) { 2609 if (document) {
2608 nameFrom = AXNameFromAttribute; 2610 nameFrom = AXNameFromAttribute;
2609 if (nameSources) { 2611 if (nameSources) {
2610 nameSources->append(NameSource(foundTextAlternative, aria_labelAttr)); 2612 nameSources->push_back(
2613 NameSource(foundTextAlternative, aria_labelAttr));
2611 nameSources->back().type = nameFrom; 2614 nameSources->back().type = nameFrom;
2612 } 2615 }
2613 if (Element* documentElement = document->documentElement()) { 2616 if (Element* documentElement = document->documentElement()) {
2614 const AtomicString& ariaLabel = 2617 const AtomicString& ariaLabel =
2615 documentElement->getAttribute(aria_labelAttr); 2618 documentElement->getAttribute(aria_labelAttr);
2616 if (!ariaLabel.isEmpty()) { 2619 if (!ariaLabel.isEmpty()) {
2617 textAlternative = ariaLabel; 2620 textAlternative = ariaLabel;
2618 2621
2619 if (nameSources) { 2622 if (nameSources) {
2620 NameSource& source = nameSources->back(); 2623 NameSource& source = nameSources->back();
2621 source.text = textAlternative; 2624 source.text = textAlternative;
2622 source.attributeValue = ariaLabel; 2625 source.attributeValue = ariaLabel;
2623 *foundTextAlternative = true; 2626 *foundTextAlternative = true;
2624 } else { 2627 } else {
2625 return textAlternative; 2628 return textAlternative;
2626 } 2629 }
2627 } 2630 }
2628 } 2631 }
2629 2632
2630 nameFrom = AXNameFromRelatedElement; 2633 nameFrom = AXNameFromRelatedElement;
2631 if (nameSources) { 2634 if (nameSources) {
2632 nameSources->append(NameSource(*foundTextAlternative)); 2635 nameSources->push_back(NameSource(*foundTextAlternative));
2633 nameSources->back().type = nameFrom; 2636 nameSources->back().type = nameFrom;
2634 nameSources->back().nativeSource = AXTextFromNativeHTMLTitleElement; 2637 nameSources->back().nativeSource = AXTextFromNativeHTMLTitleElement;
2635 } 2638 }
2636 2639
2637 textAlternative = document->title(); 2640 textAlternative = document->title();
2638 2641
2639 Element* titleElement = document->titleElement(); 2642 Element* titleElement = document->titleElement();
2640 AXObject* titleAXObject = axObjectCache().getOrCreate(titleElement); 2643 AXObject* titleAXObject = axObjectCache().getOrCreate(titleElement);
2641 if (titleAXObject) { 2644 if (titleAXObject) {
2642 if (relatedObjects) { 2645 if (relatedObjects) {
2643 localRelatedObjects.append( 2646 localRelatedObjects.push_back(
2644 new NameSourceRelatedObject(titleAXObject, textAlternative)); 2647 new NameSourceRelatedObject(titleAXObject, textAlternative));
2645 *relatedObjects = localRelatedObjects; 2648 *relatedObjects = localRelatedObjects;
2646 localRelatedObjects.clear(); 2649 localRelatedObjects.clear();
2647 } 2650 }
2648 2651
2649 if (nameSources) { 2652 if (nameSources) {
2650 NameSource& source = nameSources->back(); 2653 NameSource& source = nameSources->back();
2651 source.relatedObjects = *relatedObjects; 2654 source.relatedObjects = *relatedObjects;
2652 source.text = textAlternative; 2655 source.text = textAlternative;
2653 *foundTextAlternative = true; 2656 *foundTextAlternative = true;
2654 } else { 2657 } else {
2655 return textAlternative; 2658 return textAlternative;
2656 } 2659 }
2657 } 2660 }
2658 } 2661 }
2659 } 2662 }
2660 2663
2661 return textAlternative; 2664 return textAlternative;
2662 } 2665 }
2663 2666
2664 String AXNodeObject::description(AXNameFrom nameFrom, 2667 String AXNodeObject::description(AXNameFrom nameFrom,
2665 AXDescriptionFrom& descriptionFrom, 2668 AXDescriptionFrom& descriptionFrom,
2666 AXObjectVector* descriptionObjects) const { 2669 AXObjectVector* descriptionObjects) const {
2667 AXRelatedObjectVector relatedObjects; 2670 AXRelatedObjectVector relatedObjects;
2668 String result = 2671 String result =
2669 description(nameFrom, descriptionFrom, nullptr, &relatedObjects); 2672 description(nameFrom, descriptionFrom, nullptr, &relatedObjects);
2670 if (descriptionObjects) { 2673 if (descriptionObjects) {
2671 descriptionObjects->clear(); 2674 descriptionObjects->clear();
2672 for (size_t i = 0; i < relatedObjects.size(); i++) 2675 for (size_t i = 0; i < relatedObjects.size(); i++)
2673 descriptionObjects->append(relatedObjects[i]->object); 2676 descriptionObjects->push_back(relatedObjects[i]->object);
2674 } 2677 }
2675 2678
2676 return collapseWhitespace(result); 2679 return collapseWhitespace(result);
2677 } 2680 }
2678 2681
2679 // Based on 2682 // Based on
2680 // http://rawgit.com/w3c/aria/master/html-aam/html-aam.html#accessible-name-and- description-calculation 2683 // http://rawgit.com/w3c/aria/master/html-aam/html-aam.html#accessible-name-and- description-calculation
2681 String AXNodeObject::description(AXNameFrom nameFrom, 2684 String AXNodeObject::description(AXNameFrom nameFrom,
2682 AXDescriptionFrom& descriptionFrom, 2685 AXDescriptionFrom& descriptionFrom,
2683 DescriptionSources* descriptionSources, 2686 DescriptionSources* descriptionSources,
2684 AXRelatedObjectVector* relatedObjects) const { 2687 AXRelatedObjectVector* relatedObjects) const {
2685 // If descriptionSources is non-null, relatedObjects is used in filling it in, 2688 // If descriptionSources is non-null, relatedObjects is used in filling it in,
2686 // so it must be non-null as well. 2689 // so it must be non-null as well.
2687 if (descriptionSources) 2690 if (descriptionSources)
2688 ASSERT(relatedObjects); 2691 ASSERT(relatedObjects);
2689 2692
2690 if (!getNode()) 2693 if (!getNode())
2691 return String(); 2694 return String();
2692 2695
2693 String description; 2696 String description;
2694 bool foundDescription = false; 2697 bool foundDescription = false;
2695 2698
2696 descriptionFrom = AXDescriptionFromRelatedElement; 2699 descriptionFrom = AXDescriptionFromRelatedElement;
2697 if (descriptionSources) { 2700 if (descriptionSources) {
2698 descriptionSources->append( 2701 descriptionSources->push_back(
2699 DescriptionSource(foundDescription, aria_describedbyAttr)); 2702 DescriptionSource(foundDescription, aria_describedbyAttr));
2700 descriptionSources->back().type = descriptionFrom; 2703 descriptionSources->back().type = descriptionFrom;
2701 } 2704 }
2702 2705
2703 // aria-describedby overrides any other accessible description, from: 2706 // aria-describedby overrides any other accessible description, from:
2704 // http://rawgit.com/w3c/aria/master/html-aam/html-aam.html 2707 // http://rawgit.com/w3c/aria/master/html-aam/html-aam.html
2705 const AtomicString& ariaDescribedby = getAttribute(aria_describedbyAttr); 2708 const AtomicString& ariaDescribedby = getAttribute(aria_describedbyAttr);
2706 if (!ariaDescribedby.isNull()) { 2709 if (!ariaDescribedby.isNull()) {
2707 if (descriptionSources) 2710 if (descriptionSources)
2708 descriptionSources->back().attributeValue = ariaDescribedby; 2711 descriptionSources->back().attributeValue = ariaDescribedby;
(...skipping 17 matching lines...) Expand all
2726 2729
2727 const HTMLInputElement* inputElement = nullptr; 2730 const HTMLInputElement* inputElement = nullptr;
2728 if (isHTMLInputElement(getNode())) 2731 if (isHTMLInputElement(getNode()))
2729 inputElement = toHTMLInputElement(getNode()); 2732 inputElement = toHTMLInputElement(getNode());
2730 2733
2731 // value, 5.2.2 from: http://rawgit.com/w3c/aria/master/html-aam/html-aam.html 2734 // value, 5.2.2 from: http://rawgit.com/w3c/aria/master/html-aam/html-aam.html
2732 if (nameFrom != AXNameFromValue && inputElement && 2735 if (nameFrom != AXNameFromValue && inputElement &&
2733 inputElement->isTextButton()) { 2736 inputElement->isTextButton()) {
2734 descriptionFrom = AXDescriptionFromAttribute; 2737 descriptionFrom = AXDescriptionFromAttribute;
2735 if (descriptionSources) { 2738 if (descriptionSources) {
2736 descriptionSources->append( 2739 descriptionSources->push_back(
2737 DescriptionSource(foundDescription, valueAttr)); 2740 DescriptionSource(foundDescription, valueAttr));
2738 descriptionSources->back().type = descriptionFrom; 2741 descriptionSources->back().type = descriptionFrom;
2739 } 2742 }
2740 String value = inputElement->value(); 2743 String value = inputElement->value();
2741 if (!value.isNull()) { 2744 if (!value.isNull()) {
2742 description = value; 2745 description = value;
2743 if (descriptionSources) { 2746 if (descriptionSources) {
2744 DescriptionSource& source = descriptionSources->back(); 2747 DescriptionSource& source = descriptionSources->back();
2745 source.text = description; 2748 source.text = description;
2746 foundDescription = true; 2749 foundDescription = true;
2747 } else { 2750 } else {
2748 return description; 2751 return description;
2749 } 2752 }
2750 } 2753 }
2751 } 2754 }
2752 2755
2753 // table caption, 5.9.2 from: 2756 // table caption, 5.9.2 from:
2754 // http://rawgit.com/w3c/aria/master/html-aam/html-aam.html 2757 // http://rawgit.com/w3c/aria/master/html-aam/html-aam.html
2755 if (nameFrom != AXNameFromCaption && isHTMLTableElement(getNode())) { 2758 if (nameFrom != AXNameFromCaption && isHTMLTableElement(getNode())) {
2756 HTMLTableElement* tableElement = toHTMLTableElement(getNode()); 2759 HTMLTableElement* tableElement = toHTMLTableElement(getNode());
2757 2760
2758 descriptionFrom = AXDescriptionFromRelatedElement; 2761 descriptionFrom = AXDescriptionFromRelatedElement;
2759 if (descriptionSources) { 2762 if (descriptionSources) {
2760 descriptionSources->append(DescriptionSource(foundDescription)); 2763 descriptionSources->push_back(DescriptionSource(foundDescription));
2761 descriptionSources->back().type = descriptionFrom; 2764 descriptionSources->back().type = descriptionFrom;
2762 descriptionSources->back().nativeSource = 2765 descriptionSources->back().nativeSource =
2763 AXTextFromNativeHTMLTableCaption; 2766 AXTextFromNativeHTMLTableCaption;
2764 } 2767 }
2765 HTMLTableCaptionElement* caption = tableElement->caption(); 2768 HTMLTableCaptionElement* caption = tableElement->caption();
2766 if (caption) { 2769 if (caption) {
2767 AXObject* captionAXObject = axObjectCache().getOrCreate(caption); 2770 AXObject* captionAXObject = axObjectCache().getOrCreate(caption);
2768 if (captionAXObject) { 2771 if (captionAXObject) {
2769 AXObjectSet visited; 2772 AXObjectSet visited;
2770 description = 2773 description =
2771 recursiveTextAlternative(*captionAXObject, false, visited); 2774 recursiveTextAlternative(*captionAXObject, false, visited);
2772 if (relatedObjects) 2775 if (relatedObjects)
2773 relatedObjects->append( 2776 relatedObjects->push_back(
2774 new NameSourceRelatedObject(captionAXObject, description)); 2777 new NameSourceRelatedObject(captionAXObject, description));
2775 2778
2776 if (descriptionSources) { 2779 if (descriptionSources) {
2777 DescriptionSource& source = descriptionSources->back(); 2780 DescriptionSource& source = descriptionSources->back();
2778 source.relatedObjects = *relatedObjects; 2781 source.relatedObjects = *relatedObjects;
2779 source.text = description; 2782 source.text = description;
2780 foundDescription = true; 2783 foundDescription = true;
2781 } else { 2784 } else {
2782 return description; 2785 return description;
2783 } 2786 }
2784 } 2787 }
2785 } 2788 }
2786 } 2789 }
2787 2790
2788 // summary, 5.6.2 from: 2791 // summary, 5.6.2 from:
2789 // http://rawgit.com/w3c/aria/master/html-aam/html-aam.html 2792 // http://rawgit.com/w3c/aria/master/html-aam/html-aam.html
2790 if (nameFrom != AXNameFromContents && isHTMLSummaryElement(getNode())) { 2793 if (nameFrom != AXNameFromContents && isHTMLSummaryElement(getNode())) {
2791 descriptionFrom = AXDescriptionFromContents; 2794 descriptionFrom = AXDescriptionFromContents;
2792 if (descriptionSources) { 2795 if (descriptionSources) {
2793 descriptionSources->append(DescriptionSource(foundDescription)); 2796 descriptionSources->push_back(DescriptionSource(foundDescription));
2794 descriptionSources->back().type = descriptionFrom; 2797 descriptionSources->back().type = descriptionFrom;
2795 } 2798 }
2796 2799
2797 AXObjectSet visited; 2800 AXObjectSet visited;
2798 description = textFromDescendants(visited, false); 2801 description = textFromDescendants(visited, false);
2799 2802
2800 if (!description.isEmpty()) { 2803 if (!description.isEmpty()) {
2801 if (descriptionSources) { 2804 if (descriptionSources) {
2802 foundDescription = true; 2805 foundDescription = true;
2803 descriptionSources->back().text = description; 2806 descriptionSources->back().text = description;
2804 } else { 2807 } else {
2805 return description; 2808 return description;
2806 } 2809 }
2807 } 2810 }
2808 } 2811 }
2809 2812
2810 // title attribute, from: 2813 // title attribute, from:
2811 // http://rawgit.com/w3c/aria/master/html-aam/html-aam.html 2814 // http://rawgit.com/w3c/aria/master/html-aam/html-aam.html
2812 if (nameFrom != AXNameFromTitle) { 2815 if (nameFrom != AXNameFromTitle) {
2813 descriptionFrom = AXDescriptionFromAttribute; 2816 descriptionFrom = AXDescriptionFromAttribute;
2814 if (descriptionSources) { 2817 if (descriptionSources) {
2815 descriptionSources->append( 2818 descriptionSources->push_back(
2816 DescriptionSource(foundDescription, titleAttr)); 2819 DescriptionSource(foundDescription, titleAttr));
2817 descriptionSources->back().type = descriptionFrom; 2820 descriptionSources->back().type = descriptionFrom;
2818 } 2821 }
2819 const AtomicString& title = getAttribute(titleAttr); 2822 const AtomicString& title = getAttribute(titleAttr);
2820 if (!title.isEmpty()) { 2823 if (!title.isEmpty()) {
2821 description = title; 2824 description = title;
2822 if (descriptionSources) { 2825 if (descriptionSources) {
2823 foundDescription = true; 2826 foundDescription = true;
2824 descriptionSources->back().text = description; 2827 descriptionSources->back().text = description;
2825 } else { 2828 } else {
2826 return description; 2829 return description;
2827 } 2830 }
2828 } 2831 }
2829 } 2832 }
2830 2833
2831 // aria-help. 2834 // aria-help.
2832 // FIXME: this is not part of the official standard, but it's needed because 2835 // FIXME: this is not part of the official standard, but it's needed because
2833 // the built-in date/time controls use it. 2836 // the built-in date/time controls use it.
2834 descriptionFrom = AXDescriptionFromAttribute; 2837 descriptionFrom = AXDescriptionFromAttribute;
2835 if (descriptionSources) { 2838 if (descriptionSources) {
2836 descriptionSources->append( 2839 descriptionSources->push_back(
2837 DescriptionSource(foundDescription, aria_helpAttr)); 2840 DescriptionSource(foundDescription, aria_helpAttr));
2838 descriptionSources->back().type = descriptionFrom; 2841 descriptionSources->back().type = descriptionFrom;
2839 } 2842 }
2840 const AtomicString& help = getAttribute(aria_helpAttr); 2843 const AtomicString& help = getAttribute(aria_helpAttr);
2841 if (!help.isEmpty()) { 2844 if (!help.isEmpty()) {
2842 description = help; 2845 description = help;
2843 if (descriptionSources) { 2846 if (descriptionSources) {
2844 foundDescription = true; 2847 foundDescription = true;
2845 descriptionSources->back().text = description; 2848 descriptionSources->back().text = description;
2846 } else { 2849 } else {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
2892 return String(); 2895 return String();
2893 return toTextControlElement(node)->strippedPlaceholder(); 2896 return toTextControlElement(node)->strippedPlaceholder();
2894 } 2897 }
2895 2898
2896 DEFINE_TRACE(AXNodeObject) { 2899 DEFINE_TRACE(AXNodeObject) {
2897 visitor->trace(m_node); 2900 visitor->trace(m_node);
2898 AXObject::trace(visitor); 2901 AXObject::trace(visitor);
2899 } 2902 }
2900 2903
2901 } // namespace blink 2904 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698