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

Side by Side Diff: Source/core/accessibility/AXObject.cpp

Issue 661183002: Fix case where accessible scrollToMakeVisible didn't work. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Fix test expectation Created 6 years, 2 months 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
« no previous file with comments | « LayoutTests/accessibility/scroll-to-make-visible-nested-2-expected.txt ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 636 matching lines...) Expand 10 before | Expand all | Expand 10 after
647 IntRect objectRect = pixelSnappedIntRect(elementRect()); 647 IntRect objectRect = pixelSnappedIntRect(elementRect());
648 objectRect.setLocation(IntPoint()); 648 objectRect.setLocation(IntPoint());
649 scrollToMakeVisibleWithSubFocus(objectRect); 649 scrollToMakeVisibleWithSubFocus(objectRect);
650 } 650 }
651 651
652 // This is a 1-dimensional scroll offset helper function that's applied 652 // This is a 1-dimensional scroll offset helper function that's applied
653 // separately in the horizontal and vertical directions, because the 653 // separately in the horizontal and vertical directions, because the
654 // logic is the same. The goal is to compute the best scroll offset 654 // logic is the same. The goal is to compute the best scroll offset
655 // in order to make an object visible within a viewport. 655 // in order to make an object visible within a viewport.
656 // 656 //
657 // If the object is already fully visible, returns the same scroll
658 // offset.
659 //
657 // In case the whole object cannot fit, you can specify a 660 // In case the whole object cannot fit, you can specify a
658 // subfocus - a smaller region within the object that should 661 // subfocus - a smaller region within the object that should
659 // be prioritized. If the whole object can fit, the subfocus is 662 // be prioritized. If the whole object can fit, the subfocus is
660 // ignored. 663 // ignored.
661 // 664 //
662 // Example: the viewport is scrolled to the right just enough 665 // If possible, the object and subfocus are centered within the
663 // that the object is in view. 666 // viewport.
667 //
668 // Example 1: the object is already visible, so nothing happens.
669 // +----------Viewport---------+
670 // +---Object---+
671 // +--SubFocus--+
672 //
673 // Example 2: the object is not fully visible, so it's centered
674 // within the viewport.
664 // Before: 675 // Before:
665 // +----------Viewport---------+ 676 // +----------Viewport---------+
666 // +---Object---+ 677 // +---Object---+
667 // +--SubFocus--+ 678 // +--SubFocus--+
668 // 679 //
669 // After: 680 // After:
670 // +----------Viewport---------+ 681 // +----------Viewport---------+
671 // +---Object---+ 682 // +---Object---+
672 // +--SubFocus--+ 683 // +--SubFocus--+
673 // 684 //
685 // Example 3: the object is larger than the viewport, so the
686 // viewport moves to show as much of the object as possible,
687 // while also trying to center the subfocus.
688 // Before:
689 // +----------Viewport---------+
690 // +---------------Object--------------+
691 // +-SubFocus-+
692 //
693 // After:
694 // +----------Viewport---------+
695 // +---------------Object--------------+
696 // +-SubFocus-+
697 //
674 // When constraints cannot be fully satisfied, the min 698 // When constraints cannot be fully satisfied, the min
675 // (left/top) position takes precedence over the max (right/bottom). 699 // (left/top) position takes precedence over the max (right/bottom).
676 // 700 //
677 // Note that the return value represents the ideal new scroll offset. 701 // Note that the return value represents the ideal new scroll offset.
678 // This may be out of range - the calling function should clip this 702 // This may be out of range - the calling function should clip this
679 // to the available range. 703 // to the available range.
680 static int computeBestScrollOffset(int currentScrollOffset, int subfocusMin, int subfocusMax, int objectMin, int objectMax, int viewportMin, int viewportMax) 704 static int computeBestScrollOffset(int currentScrollOffset, int subfocusMin, int subfocusMax, int objectMin, int objectMax, int viewportMin, int viewportMax)
681 { 705 {
682 int viewportSize = viewportMax - viewportMin; 706 int viewportSize = viewportMax - viewportMin;
683 707
684 // If the focus size is larger than the viewport size, shrink it in the 708 // If the object size is larger than the viewport size, consider
685 // direction of subfocus. 709 // only a portion that's as large as the viewport, centering on
710 // the subfocus as much as possible.
686 if (objectMax - objectMin > viewportSize) { 711 if (objectMax - objectMin > viewportSize) {
687 // Subfocus must be within focus: 712 // Subfocus must be within focus:
688 subfocusMin = std::max(subfocusMin, objectMin); 713 subfocusMin = std::max(subfocusMin, objectMin);
689 subfocusMax = std::min(subfocusMax, objectMax); 714 subfocusMax = std::min(subfocusMax, objectMax);
690 715
691 // Subfocus must be no larger than the viewport size; favor top/left. 716 // Subfocus must be no larger than the viewport size; favor top/left.
692 if (subfocusMax - subfocusMin > viewportSize) 717 if (subfocusMax - subfocusMin > viewportSize)
693 subfocusMax = subfocusMin + viewportSize; 718 subfocusMax = subfocusMin + viewportSize;
694 719
695 if (subfocusMin + viewportSize > objectMax) { 720 // Compute the size of an object centered on the subfocus, the size of t he viewport.
696 objectMin = objectMax - viewportSize; 721 int centeredObjectMin = (subfocusMin + subfocusMax - viewportSize) / 2;
697 } else { 722 int centeredObjectMax = centeredObjectMin + viewportSize;
698 objectMin = subfocusMin; 723
699 objectMax = subfocusMin + viewportSize; 724 objectMin = std::max(objectMin, centeredObjectMin);
700 } 725 objectMax = std::min(objectMax, centeredObjectMax);
701 } 726 }
702 727
703 // Exit now if the focus is already within the viewport. 728 // Exit now if the focus is already within the viewport.
704 if (objectMin - currentScrollOffset >= viewportMin 729 if (objectMin - currentScrollOffset >= viewportMin
705 && objectMax - currentScrollOffset <= viewportMax) 730 && objectMax - currentScrollOffset <= viewportMax)
706 return currentScrollOffset; 731 return currentScrollOffset;
707 732
708 // Scroll left if we're too far to the right. 733 // Center the object in the viewport.
709 if (objectMax - currentScrollOffset > viewportMax) 734 return (objectMin + objectMax - viewportMin - viewportMax) / 2;
710 return objectMax - viewportMax;
711
712 // Scroll right if we're too far to the left.
713 if (objectMin - currentScrollOffset < viewportMin)
714 return objectMin - viewportMin;
715
716 ASSERT_NOT_REACHED();
717
718 // This shouldn't happen.
719 return currentScrollOffset;
720 } 735 }
721 736
722 void AXObject::scrollToMakeVisibleWithSubFocus(const IntRect& subfocus) const 737 void AXObject::scrollToMakeVisibleWithSubFocus(const IntRect& subfocus) const
723 { 738 {
724 // Search up the parent chain until we find the first one that's scrollable. 739 // Search up the parent chain until we find the first one that's scrollable.
725 AXObject* scrollParent = parentObject(); 740 AXObject* scrollParent = parentObject();
726 ScrollableArea* scrollableArea = 0; 741 ScrollableArea* scrollableArea = 0;
727 while (scrollParent) { 742 while (scrollParent) {
728 scrollableArea = scrollParent->getScrollableAreaIfScrollable(); 743 scrollableArea = scrollParent->getScrollableAreaIfScrollable();
729 if (scrollableArea) 744 if (scrollableArea)
(...skipping 13 matching lines...) Expand all
743 objectRect.x(), objectRect.maxX(), 758 objectRect.x(), objectRect.maxX(),
744 0, scrollVisibleRect.width()); 759 0, scrollVisibleRect.width());
745 int desiredY = computeBestScrollOffset( 760 int desiredY = computeBestScrollOffset(
746 scrollPosition.y(), 761 scrollPosition.y(),
747 objectRect.y() + subfocus.y(), objectRect.y() + subfocus.maxY(), 762 objectRect.y() + subfocus.y(), objectRect.y() + subfocus.maxY(),
748 objectRect.y(), objectRect.maxY(), 763 objectRect.y(), objectRect.maxY(),
749 0, scrollVisibleRect.height()); 764 0, scrollVisibleRect.height());
750 765
751 scrollParent->scrollTo(IntPoint(desiredX, desiredY)); 766 scrollParent->scrollTo(IntPoint(desiredX, desiredY));
752 767
768 // Convert the subfocus into the coordinates of the scroll parent.
769 IntRect newSubfocus = subfocus;
770 IntRect newElementRect = pixelSnappedIntRect(elementRect());
771 IntRect scrollParentRect = pixelSnappedIntRect(scrollParent->elementRect());
772 newSubfocus.move(newElementRect.x(), newElementRect.y());
773 newSubfocus.move(-scrollParentRect.x(), -scrollParentRect.y());
774
753 // Recursively make sure the scroll parent itself is visible. 775 // Recursively make sure the scroll parent itself is visible.
754 if (scrollParent->parentObject()) 776 if (scrollParent->parentObject())
755 scrollParent->scrollToMakeVisible(); 777 scrollParent->scrollToMakeVisibleWithSubFocus(newSubfocus);
756 } 778 }
757 779
758 void AXObject::scrollToGlobalPoint(const IntPoint& globalPoint) const 780 void AXObject::scrollToGlobalPoint(const IntPoint& globalPoint) const
759 { 781 {
760 // Search up the parent chain and create a vector of all scrollable parent o bjects 782 // Search up the parent chain and create a vector of all scrollable parent o bjects
761 // and ending with this object itself. 783 // and ending with this object itself.
762 Vector<const AXObject*> objects; 784 Vector<const AXObject*> objects;
763 AXObject* parentObject; 785 AXObject* parentObject;
764 for (parentObject = this->parentObject(); parentObject; parentObject = paren tObject->parentObject()) { 786 for (parentObject = this->parentObject(); parentObject; parentObject = paren tObject->parentObject()) {
765 if (parentObject->getScrollableAreaIfScrollable()) 787 if (parentObject->getScrollableAreaIfScrollable())
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
896 return ToggleButtonRole; 918 return ToggleButtonRole;
897 if (ariaHasPopup()) 919 if (ariaHasPopup())
898 return PopUpButtonRole; 920 return PopUpButtonRole;
899 // We don't contemplate RadioButtonRole, as it depends on the input 921 // We don't contemplate RadioButtonRole, as it depends on the input
900 // type. 922 // type.
901 923
902 return ButtonRole; 924 return ButtonRole;
903 } 925 }
904 926
905 } // namespace blink 927 } // namespace blink
OLDNEW
« no previous file with comments | « LayoutTests/accessibility/scroll-to-make-visible-nested-2-expected.txt ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698