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

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

Issue 1477043003: Handle aria-owns and presentational children in AX name calc. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@garaventa_visibility_hidden
Patch Set: Better solution to handle both aria-owns and role=presentation in name calc Created 5 years 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 1456 matching lines...) Expand 10 before | Expand all | Expand 10 after
1467 return false; 1467 return false;
1468 if (!r1->isInline() || !r2->isInline()) 1468 if (!r1->isInline() || !r2->isInline())
1469 return false; 1469 return false;
1470 LayoutBlockFlow* b1 = nonInlineBlockFlow(r1); 1470 LayoutBlockFlow* b1 = nonInlineBlockFlow(r1);
1471 LayoutBlockFlow* b2 = nonInlineBlockFlow(r2); 1471 LayoutBlockFlow* b2 = nonInlineBlockFlow(r2);
1472 return b1 && b2 && b1 == b2; 1472 return b1 && b2 && b1 == b2;
1473 } 1473 }
1474 1474
1475 AXObject* AXNodeObject::findChildWithTagName(const HTMLQualifiedName& tagName) c onst 1475 AXObject* AXNodeObject::findChildWithTagName(const HTMLQualifiedName& tagName) c onst
1476 { 1476 {
1477 for (AXObject* child = rawFirstChild(); child; child = child->rawFirstSiblin g()) { 1477 for (AXObject* child = rawFirstChild(); child; child = child->rawNextSibling ()) {
1478 Node* childNode = child->node(); 1478 Node* childNode = child->node();
1479 if (childNode && childNode->hasTagName(tagName)) 1479 if (childNode && childNode->hasTagName(tagName))
1480 return child; 1480 return child;
1481 } 1481 }
1482 return 0; 1482 return 0;
1483 } 1483 }
1484 1484
1485 bool AXNodeObject::isNativeCheckboxInMixedState() const 1485 bool AXNodeObject::isNativeCheckboxInMixedState() const
1486 { 1486 {
1487 if (!isHTMLInputElement(m_node)) 1487 if (!isHTMLInputElement(m_node))
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1536 nameSources->append(NameSource(foundTextAlternative)); 1536 nameSources->append(NameSource(foundTextAlternative));
1537 nameSources->last().type = nameFrom; 1537 nameSources->last().type = nameFrom;
1538 } 1538 }
1539 1539
1540 Node* node = this->node(); 1540 Node* node = this->node();
1541 if (node && node->isTextNode()) 1541 if (node && node->isTextNode())
1542 textAlternative = toText(node)->wholeText(); 1542 textAlternative = toText(node)->wholeText();
1543 else if (isHTMLBRElement(node)) 1543 else if (isHTMLBRElement(node))
1544 textAlternative = String("\n"); 1544 textAlternative = String("\n");
1545 else 1545 else
1546 textAlternative = textFromDescendants(visited); 1546 textAlternative = textFromDescendants(visited, false);
1547 1547
1548 if (!textAlternative.isEmpty()) { 1548 if (!textAlternative.isEmpty()) {
1549 if (nameSources) { 1549 if (nameSources) {
1550 foundTextAlternative = true; 1550 foundTextAlternative = true;
1551 nameSources->last().text = textAlternative; 1551 nameSources->last().text = textAlternative;
1552 } else { 1552 } else {
1553 return textAlternative; 1553 return textAlternative;
1554 } 1554 }
1555 } 1555 }
1556 } 1556 }
(...skipping 25 matching lines...) Expand all
1582 if (!nameSource.relatedObjects.isEmpty()) 1582 if (!nameSource.relatedObjects.isEmpty())
1583 *relatedObjects = nameSource.relatedObjects; 1583 *relatedObjects = nameSource.relatedObjects;
1584 return nameSource.text; 1584 return nameSource.text;
1585 } 1585 }
1586 } 1586 }
1587 } 1587 }
1588 1588
1589 return String(); 1589 return String();
1590 } 1590 }
1591 1591
1592 String AXNodeObject::textFromDescendants(AXObjectSet& visited) const 1592 String AXNodeObject::textFromDescendants(AXObjectSet& visited, bool recursive) c onst
aboxhall 2015/12/14 22:40:37 Could 'recursive' be renamed to something like 'in
dmazzoni 2015/12/14 22:51:06 This is the same as textAlternative so based on ou
1593 { 1593 {
1594 if (!canHaveChildren() && recursive)
1595 return String();
1596
1594 StringBuilder accumulatedText; 1597 StringBuilder accumulatedText;
1595 AXObject* previous = nullptr; 1598 AXObject* previous = nullptr;
1596 for (AXObject* child = rawFirstChild(); child; child = child->rawFirstSiblin g()) { 1599
1600 AXObjectVector children;
1601
1602 HeapVector<Member<AXObject>> ownedChildren;
1603 computeAriaOwnsChildren(ownedChildren);
1604 for (AXObject* obj = rawFirstChild(); obj; obj = obj->rawNextSibling()) {
aboxhall 2015/12/14 22:40:37 Where else do we conflate "native" and aria-owned
dmazzoni 2015/12/14 22:51:06 Great question, I just searched the code and there
1605 if (!axObjectCache().isAriaOwned(obj))
1606 children.append(obj);
1607 }
1608 for (const auto& ownedChild : ownedChildren)
1609 children.append(ownedChild);
1610
1611 for (AXObject* child : children) {
1597 // Skip hidden children 1612 // Skip hidden children
1598 if (child->isInertOrAriaHidden()) 1613 if (child->isInertOrAriaHidden())
1599 continue; 1614 continue;
1600 1615
1601 // If we're going between two layoutObjects that are in separate LayoutB oxes, add 1616 // If we're going between two layoutObjects that are in separate LayoutB oxes, add
1602 // whitespace if it wasn't there already. Intuitively if you have 1617 // whitespace if it wasn't there already. Intuitively if you have
1603 // <span>Hello</span><span>World</span>, those are part of the same Layo utBox 1618 // <span>Hello</span><span>World</span>, those are part of the same Layo utBox
1604 // so we should return "HelloWorld", but given <div>Hello</div><div>Worl d</div> the 1619 // so we should return "HelloWorld", but given <div>Hello</div><div>Worl d</div> the
1605 // strings are in separate boxes so we should return "Hello World". 1620 // strings are in separate boxes so we should return "Hello World".
1606 if (previous && accumulatedText.length() && !isHTMLSpace(accumulatedText [accumulatedText.length() - 1])) { 1621 if (previous && accumulatedText.length() && !isHTMLSpace(accumulatedText [accumulatedText.length() - 1])) {
1607 if (!isInSameNonInlineBlockFlow(child->layoutObject(), previous->lay outObject())) 1622 if (!isInSameNonInlineBlockFlow(child->layoutObject(), previous->lay outObject()))
1608 accumulatedText.append(' '); 1623 accumulatedText.append(' ');
1609 } 1624 }
1610 1625
1611 String result = recursiveTextAlternative(*child, false, visited); 1626 String result;
1627 if (child->isPresentational())
1628 result = child->textFromDescendants(visited, true);
1629 else
1630 result = recursiveTextAlternative(*child, false, visited);
1612 accumulatedText.append(result); 1631 accumulatedText.append(result);
1613 previous = child; 1632 previous = child;
1614 } 1633 }
1615 1634
1616 return accumulatedText.toString(); 1635 return accumulatedText.toString();
1617 } 1636 }
1618 1637
1619 bool AXNodeObject::nameFromLabelElement() const 1638 bool AXNodeObject::nameFromLabelElement() const
1620 { 1639 {
1621 // This unfortunately duplicates a bit of logic from textAlternative and nat iveTextAlternative, 1640 // This unfortunately duplicates a bit of logic from textAlternative and nat iveTextAlternative,
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
1738 return 0; 1757 return 0;
1739 1758
1740 Node* firstChild = node()->firstChild(); 1759 Node* firstChild = node()->firstChild();
1741 1760
1742 if (!firstChild) 1761 if (!firstChild)
1743 return 0; 1762 return 0;
1744 1763
1745 return axObjectCache().getOrCreate(firstChild); 1764 return axObjectCache().getOrCreate(firstChild);
1746 } 1765 }
1747 1766
1748 AXObject* AXNodeObject::rawFirstSibling() const 1767 AXObject* AXNodeObject::rawNextSibling() const
1749 { 1768 {
1750 if (!node()) 1769 if (!node())
1751 return 0; 1770 return 0;
1752 1771
1753 Node* nextSibling = node()->nextSibling(); 1772 Node* nextSibling = node()->nextSibling();
1754 if (!nextSibling) 1773 if (!nextSibling)
1755 return 0; 1774 return 0;
1756 1775
1757 return axObjectCache().getOrCreate(nextSibling); 1776 return axObjectCache().getOrCreate(nextSibling);
1758 } 1777 }
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
2074 void AXNodeObject::updateAccessibilityRole() 2093 void AXNodeObject::updateAccessibilityRole()
2075 { 2094 {
2076 bool ignoredStatus = accessibilityIsIgnored(); 2095 bool ignoredStatus = accessibilityIsIgnored();
2077 m_role = determineAccessibilityRole(); 2096 m_role = determineAccessibilityRole();
2078 2097
2079 // The AX hierarchy only needs to be updated if the ignored status of an ele ment has changed. 2098 // The AX hierarchy only needs to be updated if the ignored status of an ele ment has changed.
2080 if (ignoredStatus != accessibilityIsIgnored()) 2099 if (ignoredStatus != accessibilityIsIgnored())
2081 childrenChanged(); 2100 childrenChanged();
2082 } 2101 }
2083 2102
2084 void AXNodeObject::computeAriaOwnsChildren(HeapVector<Member<AXObject>>& ownedCh ildren) 2103 void AXNodeObject::computeAriaOwnsChildren(HeapVector<Member<AXObject>>& ownedCh ildren) const
2085 { 2104 {
2086 if (!hasAttribute(aria_ownsAttr)) 2105 if (!hasAttribute(aria_ownsAttr))
2087 return; 2106 return;
2088 2107
2089 Vector<String> idVector; 2108 Vector<String> idVector;
2090 tokenVectorFromAttribute(idVector, aria_ownsAttr); 2109 tokenVectorFromAttribute(idVector, aria_ownsAttr);
2091 2110
2092 axObjectCache().updateAriaOwns(this, idVector, ownedChildren); 2111 axObjectCache().updateAriaOwns(this, idVector, ownedChildren);
2093 } 2112 }
2094 2113
(...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after
2599 2618
2600 // summary, 5.6.2 from: http://rawgit.com/w3c/aria/master/html-aam/html-aam. html 2619 // summary, 5.6.2 from: http://rawgit.com/w3c/aria/master/html-aam/html-aam. html
2601 if (nameFrom != AXNameFromContents && isHTMLSummaryElement(node())) { 2620 if (nameFrom != AXNameFromContents && isHTMLSummaryElement(node())) {
2602 descriptionFrom = AXDescriptionFromContents; 2621 descriptionFrom = AXDescriptionFromContents;
2603 if (descriptionSources) { 2622 if (descriptionSources) {
2604 descriptionSources->append(DescriptionSource(foundDescription)); 2623 descriptionSources->append(DescriptionSource(foundDescription));
2605 descriptionSources->last().type = descriptionFrom; 2624 descriptionSources->last().type = descriptionFrom;
2606 } 2625 }
2607 2626
2608 AXObjectSet visited; 2627 AXObjectSet visited;
2609 description = textFromDescendants(visited); 2628 description = textFromDescendants(visited, false);
2610 2629
2611 if (!description.isEmpty()) { 2630 if (!description.isEmpty()) {
2612 if (descriptionSources) { 2631 if (descriptionSources) {
2613 foundDescription = true; 2632 foundDescription = true;
2614 descriptionSources->last().text = description; 2633 descriptionSources->last().text = description;
2615 } else { 2634 } else {
2616 return description; 2635 return description;
2617 } 2636 }
2618 } 2637 }
2619 } 2638 }
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
2694 return placeholder; 2713 return placeholder;
2695 } 2714 }
2696 2715
2697 DEFINE_TRACE(AXNodeObject) 2716 DEFINE_TRACE(AXNodeObject)
2698 { 2717 {
2699 visitor->trace(m_node); 2718 visitor->trace(m_node);
2700 AXObject::trace(visitor); 2719 AXObject::trace(visitor);
2701 } 2720 }
2702 2721
2703 } // namespace blin 2722 } // namespace blin
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698