| 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 |