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

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

Issue 1473833002: Fix bugs in accessible name calculation code exposed by Bryan Garaventa's test files. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@dumb_mistake
Patch Set: Rebase 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) 2008, 2009, 2011 Apple Inc. All rights reserved. 2 * Copyright (C) 2008, 2009, 2011 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 658 matching lines...) Expand 10 before | Expand all | Expand 10 after
669 updateCachedAttributeValuesIfNeeded(); 669 updateCachedAttributeValuesIfNeeded();
670 return m_cachedHasInheritedPresentationalRole; 670 return m_cachedHasInheritedPresentationalRole;
671 } 671 }
672 672
673 bool AXObject::isPresentationalChild() const 673 bool AXObject::isPresentationalChild() const
674 { 674 {
675 updateCachedAttributeValuesIfNeeded(); 675 updateCachedAttributeValuesIfNeeded();
676 return m_cachedIsPresentationalChild; 676 return m_cachedIsPresentationalChild;
677 } 677 }
678 678
679 // Simplify and whitespace, but preserve a single leading and trailing whitespac e
aboxhall 2015/11/30 19:20:19 First clause seems a little weird - can't tell if
dmazzoni 2015/12/01 08:52:39 Done.
680 // character if it's present.
681 // static
682 String AXObject::collapseWhitespace(const String& str)
683 {
684 StringBuilder result;
685 if (!str.isEmpty() && isHTMLSpace<UChar>(str[0]))
686 result.append(' ');
687 result.append(str.simplifyWhiteSpace(isHTMLSpace<UChar>));
688 if (!str.isEmpty() && isHTMLSpace<UChar>(str[str.length() - 1]))
689 result.append(' ');
690 return result.toString();
691 }
692
679 String AXObject::computedName() const 693 String AXObject::computedName() const
680 { 694 {
681 AXNameFrom nameFrom; 695 AXNameFrom nameFrom;
682 AXObject::AXObjectVector nameObjects; 696 AXObject::AXObjectVector nameObjects;
683 return name(nameFrom, &nameObjects); 697 return name(nameFrom, &nameObjects);
684 } 698 }
685 699
686 String AXObject::name(AXNameFrom& nameFrom, AXObject::AXObjectVector* nameObject s) const 700 String AXObject::name(AXNameFrom& nameFrom, AXObject::AXObjectVector* nameObject s) const
687 { 701 {
688 HeapHashSet<Member<const AXObject>> visited; 702 HeapHashSet<Member<const AXObject>> visited;
689 AXRelatedObjectVector relatedObjects; 703 AXRelatedObjectVector relatedObjects;
690 String text = textAlternative(false, false, visited, nameFrom, &relatedObjec ts, nullptr); 704 String text = textAlternative(false, false, visited, nameFrom, &relatedObjec ts, nullptr);
691 705
692 if (!node() || !isHTMLBRElement(node())) 706 if (!node() || !isHTMLBRElement(node()))
693 text = text.simplifyWhiteSpace(isHTMLSpace<UChar>, WTF::DoNotStripWhiteS pace); 707 text = collapseWhitespace(text);
694 708
695 if (nameObjects) { 709 if (nameObjects) {
696 nameObjects->clear(); 710 nameObjects->clear();
697 for (size_t i = 0; i < relatedObjects.size(); i++) 711 for (size_t i = 0; i < relatedObjects.size(); i++)
698 nameObjects->append(relatedObjects[i]->object); 712 nameObjects->append(relatedObjects[i]->object);
699 } 713 }
700 return text; 714 return text;
701 } 715 }
702 716
703 String AXObject::name(NameSources* nameSources) const 717 String AXObject::name(NameSources* nameSources) const
704 { 718 {
705 AXObjectSet visited; 719 AXObjectSet visited;
706 AXNameFrom tmpNameFrom; 720 AXNameFrom tmpNameFrom;
707 AXRelatedObjectVector tmpRelatedObjects; 721 AXRelatedObjectVector tmpRelatedObjects;
708 String text = textAlternative(false, false, visited, tmpNameFrom, &tmpRelate dObjects, nameSources); 722 String text = textAlternative(false, false, visited, tmpNameFrom, &tmpRelate dObjects, nameSources);
709 text = text.simplifyWhiteSpace(isHTMLSpace<UChar>); 723 text = text.simplifyWhiteSpace(isHTMLSpace<UChar>);
710 return text; 724 return text;
711 } 725 }
712 726
713 String AXObject::recursiveTextAlternative(const AXObject& axObj, bool inAriaLabe lledByTraversal, AXObjectSet& visited) 727 String AXObject::recursiveTextAlternative(const AXObject& axObj, bool inAriaLabe lledByTraversal, AXObjectSet& visited)
714 { 728 {
715 AXNameFrom tmpNameFrom; 729 AXNameFrom tmpNameFrom;
716 return axObj.textAlternative(true, inAriaLabelledByTraversal, visited, tmpNa meFrom, nullptr, nullptr); 730 return axObj.textAlternative(true, inAriaLabelledByTraversal, visited, tmpNa meFrom, nullptr, nullptr);
717 } 731 }
718 732
733 bool AXObject::isHiddenForTextAlternativeCalculation() const
734 {
735 if (equalIgnoringCase(getAttribute(aria_hiddenAttr), "false"))
736 return false;
737
738 if (layoutObject())
739 return layoutObject()->style()->visibility() != VISIBLE;
740
741 // This is an obscure corner case: if a node has no LayoutObject, that means it's not rendered,
aboxhall 2015/11/30 19:20:19 Helpful comment, thanks!
742 // but we still may be exploring it as part of a text alternative calculatio n, for example if it
743 // was explicitly referenced by aria-labelledby. So we need to explicitly ca ll the style resolver
744 // to check whether it's invisible or display:none, rather than relying on t he style cached in the
745 // LayoutObject.
746 Document* doc = document();
747 if (doc && node() && node()->isElementNode()) {
748 RefPtr<ComputedStyle> style = doc->ensureStyleResolver().styleForElement (toElement(node()));
749 return style->display() == NONE || style->visibility() != VISIBLE;
750 }
751
752 return false;
753 }
754
719 String AXObject::ariaTextAlternative(bool recursive, bool inAriaLabelledByTraver sal, AXObjectSet& visited, AXNameFrom& nameFrom, AXRelatedObjectVector* relatedO bjects, NameSources* nameSources, bool* foundTextAlternative) const 755 String AXObject::ariaTextAlternative(bool recursive, bool inAriaLabelledByTraver sal, AXObjectSet& visited, AXNameFrom& nameFrom, AXRelatedObjectVector* relatedO bjects, NameSources* nameSources, bool* foundTextAlternative) const
720 { 756 {
721 String textAlternative; 757 String textAlternative;
722 bool alreadyVisited = visited.contains(this); 758 bool alreadyVisited = visited.contains(this);
723 visited.add(this); 759 visited.add(this);
724 760
725 // Step 2A from: http://www.w3.org/TR/accname-aam-1.1 761 // Step 2A from: http://www.w3.org/TR/accname-aam-1.1
726 // If you change this logic, update AXNodeObject::nameFromLabelElement, too. 762 // If you change this logic, update AXNodeObject::nameFromLabelElement, too.
727 if (!recursive && layoutObject() 763 if (!inAriaLabelledByTraversal && isHiddenForTextAlternativeCalculation()) {
aboxhall 2015/11/30 19:20:19 This looks much better now.
728 && layoutObject()->style()->visibility() != VISIBLE 764 *foundTextAlternative = true;
729 && !equalIgnoringCase(getAttribute(aria_hiddenAttr), "false")) {
730 return String(); 765 return String();
731 } 766 }
732 767
733 // Step 2B from: http://www.w3.org/TR/accname-aam-1.1 768 // Step 2B from: http://www.w3.org/TR/accname-aam-1.1
734 // If you change this logic, update AXNodeObject::nameFromLabelElement, too. 769 // If you change this logic, update AXNodeObject::nameFromLabelElement, too.
735 if (!inAriaLabelledByTraversal && !alreadyVisited) { 770 if (!inAriaLabelledByTraversal && !alreadyVisited) {
736 const QualifiedName& attr = hasAttribute(aria_labeledbyAttr) && !hasAttr ibute(aria_labelledbyAttr) ? aria_labeledbyAttr : aria_labelledbyAttr; 771 const QualifiedName& attr = hasAttribute(aria_labeledbyAttr) && !hasAttr ibute(aria_labelledbyAttr) ? aria_labeledbyAttr : aria_labelledbyAttr;
737 nameFrom = AXNameFromRelatedElement; 772 nameFrom = AXNameFromRelatedElement;
738 if (nameSources) { 773 if (nameSources) {
739 nameSources->append(NameSource(*foundTextAlternative, attr)); 774 nameSources->append(NameSource(*foundTextAlternative, attr));
(...skipping 941 matching lines...) Expand 10 before | Expand all | Expand 10 after
1681 1716
1682 DEFINE_TRACE(AXObject) 1717 DEFINE_TRACE(AXObject)
1683 { 1718 {
1684 visitor->trace(m_children); 1719 visitor->trace(m_children);
1685 visitor->trace(m_parent); 1720 visitor->trace(m_parent);
1686 visitor->trace(m_cachedLiveRegionRoot); 1721 visitor->trace(m_cachedLiveRegionRoot);
1687 visitor->trace(m_axObjectCache); 1722 visitor->trace(m_axObjectCache);
1688 } 1723 }
1689 1724
1690 } // namespace blink 1725 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698