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

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

Issue 1435113003: Make use of new AX name calc in Chromium. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix issue with ariaTextAlternative Created 5 years, 1 month 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) 2008 Apple Inc. All rights reserved. 2 * Copyright (C) 2008 Apple 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 574 matching lines...) Expand 10 before | Expand all | Expand 10 after
585 } 585 }
586 586
587 // TODO: we should refactor this - but right now this is necessary to make 587 // TODO: we should refactor this - but right now this is necessary to make
588 // sure scroll areas stay in the tree. 588 // sure scroll areas stay in the tree.
589 if (isAttachment()) 589 if (isAttachment())
590 return false; 590 return false;
591 591
592 // find out if this element is inside of a label element. 592 // find out if this element is inside of a label element.
593 // if so, it may be ignored because it's the label for a checkbox or radio b utton 593 // if so, it may be ignored because it's the label for a checkbox or radio b utton
594 AXObject* controlObject = correspondingControlForLabelElement(); 594 AXObject* controlObject = correspondingControlForLabelElement();
595 if (controlObject && !controlObject->deprecatedExposesTitleUIElement() && co ntrolObject->isCheckboxOrRadio()) { 595 if (controlObject && controlObject->isCheckboxOrRadio()) {
596 if (ignoredReasons) { 596 AXNameFrom controlNameFrom;
597 HTMLLabelElement* label = labelElementContainer(); 597 AXObject::AXObjectVector controlNameObjects;
598 if (label && !label->isSameNode(node())) { 598 controlObject->name(controlNameFrom, &controlNameObjects);
599 AXObject* labelAXObject = axObjectCache().getOrCreate(label); 599 if (controlNameFrom == AXNameFromRelatedElement) {
600 ignoredReasons->append(IgnoredReason(AXLabelContainer, labelAXOb ject)); 600 if (ignoredReasons) {
601 HTMLLabelElement* label = labelElementContainer();
602 if (label && !label->isSameNode(node())) {
603 AXObject* labelAXObject = axObjectCache().getOrCreate(label) ;
604 ignoredReasons->append(IgnoredReason(AXLabelContainer, label AXObject));
605 }
606
607 ignoredReasons->append(IgnoredReason(AXLabelFor, controlObject)) ;
601 } 608 }
602 609 return true;
603 ignoredReasons->append(IgnoredReason(AXLabelFor, controlObject));
604 } 610 }
605 return true;
606 } 611 }
607 612
608 if (m_layoutObject->isBR()) 613 if (m_layoutObject->isBR())
609 return false; 614 return false;
610 615
611 if (m_layoutObject->isText()) { 616 if (m_layoutObject->isText()) {
612 // static text beneath MenuItems and MenuButtons are just reported along with the menu item, so it's ignored on an individual level 617 // static text beneath MenuItems and MenuButtons are just reported along with the menu item, so it's ignored on an individual level
613 AXObject* parent = parentObjectUnignored(); 618 AXObject* parent = parentObjectUnignored();
614 if (parent && (parent->ariaRoleAttribute() == MenuItemRole || parent->ar iaRoleAttribute() == MenuButtonRole)) { 619 if (parent && (parent->ariaRoleAttribute() == MenuItemRole || parent->ar iaRoleAttribute() == MenuButtonRole)) {
615 if (ignoredReasons) 620 if (ignoredReasons)
(...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after
1081 } 1086 }
1082 } 1087 }
1083 1088
1084 String AXLayoutObject::stringValue() const 1089 String AXLayoutObject::stringValue() const
1085 { 1090 {
1086 if (!m_layoutObject) 1091 if (!m_layoutObject)
1087 return String(); 1092 return String();
1088 1093
1089 LayoutBoxModelObject* cssBox = layoutBoxModelObject(); 1094 LayoutBoxModelObject* cssBox = layoutBoxModelObject();
1090 1095
1091 if (ariaRoleAttribute() == StaticTextRole) {
1092 String staticText = text();
1093 if (!staticText.length())
1094 staticText = deprecatedTextUnderElement(TextUnderElementAll);
1095 return staticText;
1096 }
1097
1098 if (m_layoutObject->isText())
1099 return deprecatedTextUnderElement(TextUnderElementAll);
1100
1101 if (cssBox && cssBox->isMenuList()) { 1096 if (cssBox && cssBox->isMenuList()) {
1102 // LayoutMenuList will go straight to the text() of its selected item. 1097 // LayoutMenuList will go straight to the text() of its selected item.
1103 // This has to be overridden in the case where the selected item has an ARIA label. 1098 // This has to be overridden in the case where the selected item has an ARIA label.
1104 HTMLSelectElement* selectElement = toHTMLSelectElement(m_layoutObject->n ode()); 1099 HTMLSelectElement* selectElement = toHTMLSelectElement(m_layoutObject->n ode());
1105 int selectedIndex = selectElement->selectedIndex(); 1100 int selectedIndex = selectElement->selectedIndex();
1106 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& listItems = sel ectElement->listItems(); 1101 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& listItems = sel ectElement->listItems();
1107 if (selectedIndex >= 0 && static_cast<size_t>(selectedIndex) < listItems .size()) { 1102 if (selectedIndex >= 0 && static_cast<size_t>(selectedIndex) < listItems .size()) {
1108 const AtomicString& overriddenDescription = listItems[selectedIndex] ->fastGetAttribute(aria_labelAttr); 1103 const AtomicString& overriddenDescription = listItems[selectedIndex] ->fastGetAttribute(aria_labelAttr);
1109 if (!overriddenDescription.isNull()) 1104 if (!overriddenDescription.isNull())
1110 return overriddenDescription; 1105 return overriddenDescription;
1111 } 1106 }
1112 return toLayoutMenuList(m_layoutObject)->text(); 1107 return toLayoutMenuList(m_layoutObject)->text();
1113 } 1108 }
1114 1109
1115 if (m_layoutObject->isListMarker())
1116 return toLayoutListMarker(m_layoutObject)->text();
1117
1118 if (isWebArea()) { 1110 if (isWebArea()) {
1119 // FIXME: Why would a layoutObject exist when the Document isn't attache d to a frame? 1111 // FIXME: Why would a layoutObject exist when the Document isn't attache d to a frame?
1120 if (m_layoutObject->frame()) 1112 if (m_layoutObject->frame())
1121 return String(); 1113 return String();
1122 1114
1123 ASSERT_NOT_REACHED(); 1115 ASSERT_NOT_REACHED();
1124 } 1116 }
1125 1117
1126 if (isTextControl()) 1118 if (isTextControl())
1127 return text(); 1119 return text();
(...skipping 10 matching lines...) Expand all
1138 return input->value(); 1130 return input->value();
1139 } 1131 }
1140 1132
1141 // FIXME: We might need to implement a value here for more types 1133 // FIXME: We might need to implement a value here for more types
1142 // FIXME: It would be better not to advertise a value at all for the types f or which we don't implement one; 1134 // FIXME: It would be better not to advertise a value at all for the types f or which we don't implement one;
1143 // this would require subclassing or making accessibilityAttributeNames do s omething other than return a 1135 // this would require subclassing or making accessibilityAttributeNames do s omething other than return a
1144 // single static array. 1136 // single static array.
1145 return String(); 1137 return String();
1146 } 1138 }
1147 1139
1140 String AXLayoutObject::textAlternative(bool recursive, bool inAriaLabelledByTrav ersal, AXObjectSet& visited, AXNameFrom& nameFrom, AXRelatedObjectVector* relate dObjects, NameSources* nameSources) const
1141 {
1142 if (m_layoutObject) {
1143 String textAlternative;
1144 bool foundTextAlternative = false;
1145
1146 if (m_layoutObject->isBR()) {
1147 textAlternative = String("\n");
1148 foundTextAlternative = true;
1149 } else if (m_layoutObject->isText() && (!recursive || !m_layoutObject->i sCounter())) {
1150 LayoutText* layoutText = toLayoutText(m_layoutObject);
1151 String result = layoutText->plainText();
1152 if (!result.isEmpty() || layoutText->isAllCollapsibleWhitespace())
1153 textAlternative = result;
1154 else
1155 textAlternative = layoutText->text();
1156 foundTextAlternative = true;
1157 } else if (m_layoutObject->isListMarker() && !recursive) {
1158 textAlternative = toLayoutListMarker(m_layoutObject)->text();
1159 foundTextAlternative = true;
1160 }
1161
1162 if (foundTextAlternative) {
1163 nameFrom = AXNameFromContents;
1164 if (nameSources) {
1165 nameSources->append(NameSource(false));
1166 nameSources->last().type = nameFrom;
1167 nameSources->last().text = textAlternative;
1168 }
1169 return textAlternative;
1170 }
1171 }
1172
1173 return AXNodeObject::textAlternative(recursive, inAriaLabelledByTraversal, v isited, nameFrom, relatedObjects, nameSources);
1174 }
1175
1148 // 1176 //
1149 // ARIA attributes. 1177 // ARIA attributes.
1150 // 1178 //
1151 1179
1152 AXObject* AXLayoutObject::activeDescendant() const 1180 AXObject* AXLayoutObject::activeDescendant() const
1153 { 1181 {
1154 if (!m_layoutObject) 1182 if (!m_layoutObject)
1155 return 0; 1183 return 0;
1156 1184
1157 if (m_layoutObject->node() && !m_layoutObject->node()->isElementNode()) 1185 if (m_layoutObject->node() && !m_layoutObject->node()->isElementNode())
(...skipping 23 matching lines...) Expand all
1181 void AXLayoutObject::ariaFlowToElements(AXObjectVector& flowTo) const 1209 void AXLayoutObject::ariaFlowToElements(AXObjectVector& flowTo) const
1182 { 1210 {
1183 accessibilityChildrenFromAttribute(aria_flowtoAttr, flowTo); 1211 accessibilityChildrenFromAttribute(aria_flowtoAttr, flowTo);
1184 } 1212 }
1185 1213
1186 void AXLayoutObject::ariaControlsElements(AXObjectVector& controls) const 1214 void AXLayoutObject::ariaControlsElements(AXObjectVector& controls) const
1187 { 1215 {
1188 accessibilityChildrenFromAttribute(aria_controlsAttr, controls); 1216 accessibilityChildrenFromAttribute(aria_controlsAttr, controls);
1189 } 1217 }
1190 1218
1191 void AXLayoutObject::deprecatedAriaDescribedbyElements(AXObjectVector& described by) const
1192 {
1193 accessibilityChildrenFromAttribute(aria_describedbyAttr, describedby);
1194 }
1195
1196 void AXLayoutObject::deprecatedAriaLabelledbyElements(AXObjectVector& labelledby ) const
1197 {
1198 accessibilityChildrenFromAttribute(aria_labelledbyAttr, labelledby);
1199 }
1200
1201 void AXLayoutObject::ariaOwnsElements(AXObjectVector& owns) const 1219 void AXLayoutObject::ariaOwnsElements(AXObjectVector& owns) const
1202 { 1220 {
1203 accessibilityChildrenFromAttribute(aria_ownsAttr, owns); 1221 accessibilityChildrenFromAttribute(aria_ownsAttr, owns);
1204 } 1222 }
1205 1223
1224 void AXLayoutObject::ariaDescribedbyElements(AXObjectVector& describedby) const
1225 {
1226 accessibilityChildrenFromAttribute(aria_describedbyAttr, describedby);
1227 }
1228
1229 void AXLayoutObject::ariaLabelledbyElements(AXObjectVector& labelledby) const
1230 {
1231 accessibilityChildrenFromAttribute(aria_labelledbyAttr, labelledby);
1232 }
1233
1206 bool AXLayoutObject::ariaHasPopup() const 1234 bool AXLayoutObject::ariaHasPopup() const
1207 { 1235 {
1208 return elementAttributeValue(aria_haspopupAttr); 1236 return elementAttributeValue(aria_haspopupAttr);
1209 } 1237 }
1210 1238
1211 bool AXLayoutObject::ariaRoleHasPresentationalChildren() const 1239 bool AXLayoutObject::ariaRoleHasPresentationalChildren() const
1212 { 1240 {
1213 switch (m_ariaRole) { 1241 switch (m_ariaRole) {
1214 case ButtonRole: 1242 case ButtonRole:
1215 case SliderRole: 1243 case SliderRole:
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
1343 return true; 1371 return true;
1344 return elementAttributeValue(aria_atomicAttr); 1372 return elementAttributeValue(aria_atomicAttr);
1345 } 1373 }
1346 1374
1347 bool AXLayoutObject::liveRegionBusy() const 1375 bool AXLayoutObject::liveRegionBusy() const
1348 { 1376 {
1349 return elementAttributeValue(aria_busyAttr); 1377 return elementAttributeValue(aria_busyAttr);
1350 } 1378 }
1351 1379
1352 // 1380 //
1353 // Accessibility Text.
1354 //
1355
1356 String AXLayoutObject::deprecatedTextUnderElement(TextUnderElementMode mode) con st
1357 {
1358 if (!m_layoutObject)
1359 return String();
1360
1361 if (m_layoutObject->isBR())
1362 return String("\n");
1363
1364 if (m_layoutObject->isFileUploadControl())
1365 return toLayoutFileUploadControl(m_layoutObject)->buttonValue();
1366
1367 if (m_layoutObject->isText()) {
1368 LayoutText* layoutText = toLayoutText(m_layoutObject);
1369 String result = layoutText->plainText();
1370 if (!result.isEmpty() || layoutText->isAllCollapsibleWhitespace())
1371 return result;
1372 return layoutText->text();
1373 }
1374
1375 return AXNodeObject::deprecatedTextUnderElement(mode);
1376 }
1377
1378 //
1379 // Accessibility Text - (To be deprecated).
1380 //
1381
1382 String AXLayoutObject::deprecatedHelpText() const
1383 {
1384 if (!m_layoutObject)
1385 return String();
1386
1387 const AtomicString& ariaHelp = getAttribute(aria_helpAttr);
1388 if (!ariaHelp.isEmpty())
1389 return ariaHelp;
1390
1391 String describedBy = ariaDescribedByAttribute();
1392 if (!describedBy.isEmpty())
1393 return describedBy;
1394
1395 String description = deprecatedAccessibilityDescription();
1396 for (LayoutObject* curr = m_layoutObject; curr; curr = curr->parent()) {
1397 if (curr->node() && curr->node()->isHTMLElement()) {
1398 const AtomicString& summary = toElement(curr->node())->getAttribute( summaryAttr);
1399 if (!summary.isEmpty())
1400 return summary;
1401
1402 // The title attribute should be used as help text unless it is alre ady being used as descriptive text.
1403 const AtomicString& title = toElement(curr->node())->getAttribute(ti tleAttr);
1404 if (!title.isEmpty() && description != title)
1405 return title;
1406 }
1407
1408 // Only take help text from an ancestor element if its a group or an unk nown role. If help was
1409 // added to those kinds of elements, it is likely it was meant for a chi ld element.
1410 AXObject* axObj = axObjectCache().getOrCreate(curr);
1411 if (axObj) {
1412 AccessibilityRole role = axObj->roleValue();
1413 if (role != GroupRole && role != UnknownRole)
1414 break;
1415 }
1416 }
1417
1418 return String();
1419 }
1420
1421 //
1422 // Position and size. 1381 // Position and size.
1423 // 1382 //
1424 1383
1425 void AXLayoutObject::checkCachedElementRect() const 1384 void AXLayoutObject::checkCachedElementRect() const
1426 { 1385 {
1427 if (m_cachedElementRectDirty) 1386 if (m_cachedElementRectDirty)
1428 return; 1387 return;
1429 1388
1430 if (!m_layoutObject) 1389 if (!m_layoutObject)
1431 return; 1390 return;
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
1528 1487
1529 LayoutObject* obj = node->layoutObject(); 1488 LayoutObject* obj = node->layoutObject();
1530 if (!obj) 1489 if (!obj)
1531 return 0; 1490 return 0;
1532 1491
1533 AXObject* result = axObjectCache().getOrCreate(obj); 1492 AXObject* result = axObjectCache().getOrCreate(obj);
1534 result->updateChildrenIfNecessary(); 1493 result->updateChildrenIfNecessary();
1535 1494
1536 // Allow the element to perform any hit-testing it might need to do to reach non-layout children. 1495 // Allow the element to perform any hit-testing it might need to do to reach non-layout children.
1537 result = result->elementAccessibilityHitTest(point); 1496 result = result->elementAccessibilityHitTest(point);
1538
1539 if (result && result->accessibilityIsIgnored()) { 1497 if (result && result->accessibilityIsIgnored()) {
1540 // If this element is the label of a control, a hit test should return t he control. 1498 // If this element is the label of a control, a hit test should return t he control.
1541 if (result->isAXLayoutObject()) { 1499 if (result->isAXLayoutObject()) {
1542 AXObject* controlObject = toAXLayoutObject(result)->correspondingCon trolForLabelElement(); 1500 AXObject* controlObject = toAXLayoutObject(result)->correspondingCon trolForLabelElement();
1543 if (controlObject && !controlObject->deprecatedExposesTitleUIElement ()) 1501 if (controlObject) {
1544 return controlObject; 1502 AXNameFrom controlNameFrom;
1503 AXObject::AXObjectVector controlNameObjects;
1504 controlObject->name(controlNameFrom, &controlNameObjects);
1505 if (controlObject && controlNameFrom == AXNameFromRelatedElement )
1506 return controlObject;
1507 }
1545 } 1508 }
1546 1509
1547 result = result->parentObjectUnignored(); 1510 result = result->parentObjectUnignored();
1548 } 1511 }
1549 1512
1550 return result; 1513 return result;
1551 } 1514 }
1552 1515
1553 AXObject* AXLayoutObject::elementAccessibilityHitTest(const IntPoint& point) con st 1516 AXObject* AXLayoutObject::elementAccessibilityHitTest(const IntPoint& point) con st
1554 { 1517 {
(...skipping 1037 matching lines...) Expand 10 before | Expand all | Expand 10 after
2592 if (label && label->layoutObject()) { 2555 if (label && label->layoutObject()) {
2593 LayoutRect labelRect = axObjectCache().getOrCreate(label)->elementRe ct(); 2556 LayoutRect labelRect = axObjectCache().getOrCreate(label)->elementRe ct();
2594 result.unite(labelRect); 2557 result.unite(labelRect);
2595 } 2558 }
2596 } 2559 }
2597 2560
2598 return result; 2561 return result;
2599 } 2562 }
2600 2563
2601 } // namespace blink 2564 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698