OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |