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 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
496 IgnoredReasons* ignoredReasons) const { | 496 IgnoredReasons* ignoredReasons) const { |
497 if (isInertOrAriaHidden()) { | 497 if (isInertOrAriaHidden()) { |
498 if (ignoredReasons) | 498 if (ignoredReasons) |
499 computeIsInertOrAriaHidden(ignoredReasons); | 499 computeIsInertOrAriaHidden(ignoredReasons); |
500 return IgnoreObject; | 500 return IgnoreObject; |
501 } | 501 } |
502 | 502 |
503 if (isPresentationalChild()) { | 503 if (isPresentationalChild()) { |
504 if (ignoredReasons) { | 504 if (ignoredReasons) { |
505 AXObject* ancestor = ancestorForWhichThisIsAPresentationalChild(); | 505 AXObject* ancestor = ancestorForWhichThisIsAPresentationalChild(); |
506 ignoredReasons->append(IgnoredReason(AXAncestorDisallowsChild, ancestor)); | 506 ignoredReasons->push_back( |
| 507 IgnoredReason(AXAncestorDisallowsChild, ancestor)); |
507 } | 508 } |
508 return IgnoreObject; | 509 return IgnoreObject; |
509 } | 510 } |
510 | 511 |
511 return accessibilityPlatformIncludesObject(); | 512 return accessibilityPlatformIncludesObject(); |
512 } | 513 } |
513 | 514 |
514 bool AXObject::isInertOrAriaHidden() const { | 515 bool AXObject::isInertOrAriaHidden() const { |
515 updateCachedAttributeValuesIfNeeded(); | 516 updateCachedAttributeValuesIfNeeded(); |
516 return m_cachedIsInertOrAriaHidden; | 517 return m_cachedIsInertOrAriaHidden; |
517 } | 518 } |
518 | 519 |
519 bool AXObject::computeIsInertOrAriaHidden( | 520 bool AXObject::computeIsInertOrAriaHidden( |
520 IgnoredReasons* ignoredReasons) const { | 521 IgnoredReasons* ignoredReasons) const { |
521 if (getNode()) { | 522 if (getNode()) { |
522 if (getNode()->isInert()) { | 523 if (getNode()->isInert()) { |
523 if (ignoredReasons) { | 524 if (ignoredReasons) { |
524 HTMLDialogElement* dialog = getActiveDialogElement(getNode()); | 525 HTMLDialogElement* dialog = getActiveDialogElement(getNode()); |
525 if (dialog) { | 526 if (dialog) { |
526 AXObject* dialogObject = axObjectCache().getOrCreate(dialog); | 527 AXObject* dialogObject = axObjectCache().getOrCreate(dialog); |
527 if (dialogObject) | 528 if (dialogObject) |
528 ignoredReasons->append( | 529 ignoredReasons->push_back( |
529 IgnoredReason(AXActiveModalDialog, dialogObject)); | 530 IgnoredReason(AXActiveModalDialog, dialogObject)); |
530 else | 531 else |
531 ignoredReasons->append(IgnoredReason(AXInert)); | 532 ignoredReasons->push_back(IgnoredReason(AXInert)); |
532 } else { | 533 } else { |
533 // TODO(aboxhall): handle inert attribute if it eventuates | 534 // TODO(aboxhall): handle inert attribute if it eventuates |
534 ignoredReasons->append(IgnoredReason(AXInert)); | 535 ignoredReasons->push_back(IgnoredReason(AXInert)); |
535 } | 536 } |
536 } | 537 } |
537 return true; | 538 return true; |
538 } | 539 } |
539 } else { | 540 } else { |
540 AXObject* parent = parentObject(); | 541 AXObject* parent = parentObject(); |
541 if (parent && parent->isInertOrAriaHidden()) { | 542 if (parent && parent->isInertOrAriaHidden()) { |
542 if (ignoredReasons) | 543 if (ignoredReasons) |
543 parent->computeIsInertOrAriaHidden(ignoredReasons); | 544 parent->computeIsInertOrAriaHidden(ignoredReasons); |
544 return true; | 545 return true; |
545 } | 546 } |
546 } | 547 } |
547 | 548 |
548 const AXObject* hiddenRoot = ariaHiddenRoot(); | 549 const AXObject* hiddenRoot = ariaHiddenRoot(); |
549 if (hiddenRoot) { | 550 if (hiddenRoot) { |
550 if (ignoredReasons) { | 551 if (ignoredReasons) { |
551 if (hiddenRoot == this) | 552 if (hiddenRoot == this) |
552 ignoredReasons->append(IgnoredReason(AXAriaHidden)); | 553 ignoredReasons->push_back(IgnoredReason(AXAriaHidden)); |
553 else | 554 else |
554 ignoredReasons->append(IgnoredReason(AXAriaHiddenRoot, hiddenRoot)); | 555 ignoredReasons->push_back(IgnoredReason(AXAriaHiddenRoot, hiddenRoot)); |
555 } | 556 } |
556 return true; | 557 return true; |
557 } | 558 } |
558 | 559 |
559 return false; | 560 return false; |
560 } | 561 } |
561 | 562 |
562 bool AXObject::isDescendantOfLeafNode() const { | 563 bool AXObject::isDescendantOfLeafNode() const { |
563 updateCachedAttributeValuesIfNeeded(); | 564 updateCachedAttributeValuesIfNeeded(); |
564 return m_cachedIsDescendantOfLeafNode; | 565 return m_cachedIsDescendantOfLeafNode; |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
669 &relatedObjects, nullptr); | 670 &relatedObjects, nullptr); |
670 | 671 |
671 AccessibilityRole role = roleValue(); | 672 AccessibilityRole role = roleValue(); |
672 if (!getNode() || (!isHTMLBRElement(getNode()) && role != StaticTextRole && | 673 if (!getNode() || (!isHTMLBRElement(getNode()) && role != StaticTextRole && |
673 role != InlineTextBoxRole)) | 674 role != InlineTextBoxRole)) |
674 text = collapseWhitespace(text); | 675 text = collapseWhitespace(text); |
675 | 676 |
676 if (nameObjects) { | 677 if (nameObjects) { |
677 nameObjects->clear(); | 678 nameObjects->clear(); |
678 for (size_t i = 0; i < relatedObjects.size(); i++) | 679 for (size_t i = 0; i < relatedObjects.size(); i++) |
679 nameObjects->append(relatedObjects[i]->object); | 680 nameObjects->push_back(relatedObjects[i]->object); |
680 } | 681 } |
681 | 682 |
682 return text; | 683 return text; |
683 } | 684 } |
684 | 685 |
685 String AXObject::name(NameSources* nameSources) const { | 686 String AXObject::name(NameSources* nameSources) const { |
686 AXObjectSet visited; | 687 AXObjectSet visited; |
687 AXNameFrom tmpNameFrom; | 688 AXNameFrom tmpNameFrom; |
688 AXRelatedObjectVector tmpRelatedObjects; | 689 AXRelatedObjectVector tmpRelatedObjects; |
689 String text = textAlternative(false, false, visited, tmpNameFrom, | 690 String text = textAlternative(false, false, visited, tmpNameFrom, |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
747 | 748 |
748 // Step 2B from: http://www.w3.org/TR/accname-aam-1.1 | 749 // Step 2B from: http://www.w3.org/TR/accname-aam-1.1 |
749 // If you change this logic, update AXNodeObject::nameFromLabelElement, too. | 750 // If you change this logic, update AXNodeObject::nameFromLabelElement, too. |
750 if (!inAriaLabelledByTraversal && !alreadyVisited) { | 751 if (!inAriaLabelledByTraversal && !alreadyVisited) { |
751 const QualifiedName& attr = | 752 const QualifiedName& attr = |
752 hasAttribute(aria_labeledbyAttr) && !hasAttribute(aria_labelledbyAttr) | 753 hasAttribute(aria_labeledbyAttr) && !hasAttribute(aria_labelledbyAttr) |
753 ? aria_labeledbyAttr | 754 ? aria_labeledbyAttr |
754 : aria_labelledbyAttr; | 755 : aria_labelledbyAttr; |
755 nameFrom = AXNameFromRelatedElement; | 756 nameFrom = AXNameFromRelatedElement; |
756 if (nameSources) { | 757 if (nameSources) { |
757 nameSources->append(NameSource(*foundTextAlternative, attr)); | 758 nameSources->push_back(NameSource(*foundTextAlternative, attr)); |
758 nameSources->back().type = nameFrom; | 759 nameSources->back().type = nameFrom; |
759 } | 760 } |
760 | 761 |
761 const AtomicString& ariaLabelledby = getAttribute(attr); | 762 const AtomicString& ariaLabelledby = getAttribute(attr); |
762 if (!ariaLabelledby.isNull()) { | 763 if (!ariaLabelledby.isNull()) { |
763 if (nameSources) | 764 if (nameSources) |
764 nameSources->back().attributeValue = ariaLabelledby; | 765 nameSources->back().attributeValue = ariaLabelledby; |
765 | 766 |
766 // Operate on a copy of |visited| so that if |nameSources| is not null, | 767 // Operate on a copy of |visited| so that if |nameSources| is not null, |
767 // the set of visited objects is preserved unmodified for future | 768 // the set of visited objects is preserved unmodified for future |
(...skipping 14 matching lines...) Expand all Loading... |
782 } else if (nameSources) { | 783 } else if (nameSources) { |
783 nameSources->back().invalid = true; | 784 nameSources->back().invalid = true; |
784 } | 785 } |
785 } | 786 } |
786 } | 787 } |
787 | 788 |
788 // Step 2C from: http://www.w3.org/TR/accname-aam-1.1 | 789 // Step 2C from: http://www.w3.org/TR/accname-aam-1.1 |
789 // If you change this logic, update AXNodeObject::nameFromLabelElement, too. | 790 // If you change this logic, update AXNodeObject::nameFromLabelElement, too. |
790 nameFrom = AXNameFromAttribute; | 791 nameFrom = AXNameFromAttribute; |
791 if (nameSources) { | 792 if (nameSources) { |
792 nameSources->append(NameSource(*foundTextAlternative, aria_labelAttr)); | 793 nameSources->push_back(NameSource(*foundTextAlternative, aria_labelAttr)); |
793 nameSources->back().type = nameFrom; | 794 nameSources->back().type = nameFrom; |
794 } | 795 } |
795 const AtomicString& ariaLabel = getAttribute(aria_labelAttr); | 796 const AtomicString& ariaLabel = getAttribute(aria_labelAttr); |
796 if (!ariaLabel.isEmpty()) { | 797 if (!ariaLabel.isEmpty()) { |
797 textAlternative = ariaLabel; | 798 textAlternative = ariaLabel; |
798 | 799 |
799 if (nameSources) { | 800 if (nameSources) { |
800 NameSource& source = nameSources->back(); | 801 NameSource& source = nameSources->back(); |
801 source.text = textAlternative; | 802 source.text = textAlternative; |
802 source.attributeValue = ariaLabel; | 803 source.attributeValue = ariaLabel; |
(...skipping 15 matching lines...) Expand all Loading... |
818 bool foundValidElement = false; | 819 bool foundValidElement = false; |
819 AXRelatedObjectVector localRelatedObjects; | 820 AXRelatedObjectVector localRelatedObjects; |
820 | 821 |
821 for (const auto& element : elements) { | 822 for (const auto& element : elements) { |
822 AXObject* axElement = axObjectCache().getOrCreate(element); | 823 AXObject* axElement = axObjectCache().getOrCreate(element); |
823 if (axElement) { | 824 if (axElement) { |
824 foundValidElement = true; | 825 foundValidElement = true; |
825 | 826 |
826 String result = recursiveTextAlternative( | 827 String result = recursiveTextAlternative( |
827 *axElement, inAriaLabelledbyTraversal, visited); | 828 *axElement, inAriaLabelledbyTraversal, visited); |
828 localRelatedObjects.append( | 829 localRelatedObjects.push_back( |
829 new NameSourceRelatedObject(axElement, result)); | 830 new NameSourceRelatedObject(axElement, result)); |
830 if (!result.isEmpty()) { | 831 if (!result.isEmpty()) { |
831 if (!accumulatedText.isEmpty()) | 832 if (!accumulatedText.isEmpty()) |
832 accumulatedText.append(' '); | 833 accumulatedText.append(' '); |
833 accumulatedText.append(result); | 834 accumulatedText.append(result); |
834 } | 835 } |
835 } | 836 } |
836 } | 837 } |
837 if (!foundValidElement) | 838 if (!foundValidElement) |
838 return String(); | 839 return String(); |
(...skipping 19 matching lines...) Expand all Loading... |
858 void AXObject::elementsFromAttribute(HeapVector<Member<Element>>& elements, | 859 void AXObject::elementsFromAttribute(HeapVector<Member<Element>>& elements, |
859 const QualifiedName& attribute) const { | 860 const QualifiedName& attribute) const { |
860 Vector<String> ids; | 861 Vector<String> ids; |
861 tokenVectorFromAttribute(ids, attribute); | 862 tokenVectorFromAttribute(ids, attribute); |
862 if (ids.isEmpty()) | 863 if (ids.isEmpty()) |
863 return; | 864 return; |
864 | 865 |
865 TreeScope& scope = getNode()->treeScope(); | 866 TreeScope& scope = getNode()->treeScope(); |
866 for (const auto& id : ids) { | 867 for (const auto& id : ids) { |
867 if (Element* idElement = scope.getElementById(AtomicString(id))) | 868 if (Element* idElement = scope.getElementById(AtomicString(id))) |
868 elements.append(idElement); | 869 elements.push_back(idElement); |
869 } | 870 } |
870 } | 871 } |
871 | 872 |
872 void AXObject::ariaLabelledbyElementVector( | 873 void AXObject::ariaLabelledbyElementVector( |
873 HeapVector<Member<Element>>& elements) const { | 874 HeapVector<Member<Element>>& elements) const { |
874 // Try both spellings, but prefer aria-labelledby, which is the official spec. | 875 // Try both spellings, but prefer aria-labelledby, which is the official spec. |
875 elementsFromAttribute(elements, aria_labelledbyAttr); | 876 elementsFromAttribute(elements, aria_labelledbyAttr); |
876 if (!elements.size()) | 877 if (!elements.size()) |
877 elementsFromAttribute(elements, aria_labeledbyAttr); | 878 elementsFromAttribute(elements, aria_labeledbyAttr); |
878 } | 879 } |
(...skipping 626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1505 void AXObject::scrollToGlobalPoint(const IntPoint& globalPoint) const { | 1506 void AXObject::scrollToGlobalPoint(const IntPoint& globalPoint) const { |
1506 // Search up the parent chain and create a vector of all scrollable parent | 1507 // Search up the parent chain and create a vector of all scrollable parent |
1507 // objects and ending with this object itself. | 1508 // objects and ending with this object itself. |
1508 HeapVector<Member<const AXObject>> objects; | 1509 HeapVector<Member<const AXObject>> objects; |
1509 AXObject* parentObject; | 1510 AXObject* parentObject; |
1510 for (parentObject = this->parentObject(); parentObject; | 1511 for (parentObject = this->parentObject(); parentObject; |
1511 parentObject = parentObject->parentObject()) { | 1512 parentObject = parentObject->parentObject()) { |
1512 if (parentObject->getScrollableAreaIfScrollable()) | 1513 if (parentObject->getScrollableAreaIfScrollable()) |
1513 objects.prepend(parentObject); | 1514 objects.prepend(parentObject); |
1514 } | 1515 } |
1515 objects.append(this); | 1516 objects.push_back(this); |
1516 | 1517 |
1517 // Start with the outermost scrollable (the main window) and try to scroll the | 1518 // Start with the outermost scrollable (the main window) and try to scroll the |
1518 // next innermost object to the given point. | 1519 // next innermost object to the given point. |
1519 int offsetX = 0, offsetY = 0; | 1520 int offsetX = 0, offsetY = 0; |
1520 IntPoint point = globalPoint; | 1521 IntPoint point = globalPoint; |
1521 size_t levels = objects.size() - 1; | 1522 size_t levels = objects.size() - 1; |
1522 for (size_t i = 0; i < levels; i++) { | 1523 for (size_t i = 0; i < levels; i++) { |
1523 const AXObject* outer = objects[i]; | 1524 const AXObject* outer = objects[i]; |
1524 const AXObject* inner = objects[i + 1]; | 1525 const AXObject* inner = objects[i + 1]; |
1525 ScrollableArea* scrollableArea = outer->getScrollableAreaIfScrollable(); | 1526 ScrollableArea* scrollableArea = outer->getScrollableAreaIfScrollable(); |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1738 } | 1739 } |
1739 | 1740 |
1740 DEFINE_TRACE(AXObject) { | 1741 DEFINE_TRACE(AXObject) { |
1741 visitor->trace(m_children); | 1742 visitor->trace(m_children); |
1742 visitor->trace(m_parent); | 1743 visitor->trace(m_parent); |
1743 visitor->trace(m_cachedLiveRegionRoot); | 1744 visitor->trace(m_cachedLiveRegionRoot); |
1744 visitor->trace(m_axObjectCache); | 1745 visitor->trace(m_axObjectCache); |
1745 } | 1746 } |
1746 | 1747 |
1747 } // namespace blink | 1748 } // namespace blink |
OLD | NEW |