OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2014, Google Inc. All rights reserved. | 2 * Copyright (C) 2014, Google 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 629 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
640 textChanged(getOrCreate(layoutObject)); | 640 textChanged(getOrCreate(layoutObject)); |
641 } | 641 } |
642 | 642 |
643 void AXObjectCacheImpl::textChanged(AXObject* obj) | 643 void AXObjectCacheImpl::textChanged(AXObject* obj) |
644 { | 644 { |
645 if (!obj) | 645 if (!obj) |
646 return; | 646 return; |
647 | 647 |
648 bool parentAlreadyExists = obj->parentObjectIfExists(); | 648 bool parentAlreadyExists = obj->parentObjectIfExists(); |
649 obj->textChanged(); | 649 obj->textChanged(); |
650 postNotification(obj, AXObjectCacheImpl::AXTextChanged, true); | 650 postNotification(obj, AXObjectCacheImpl::AXTextChanged); |
651 if (parentAlreadyExists) | 651 if (parentAlreadyExists) |
652 obj->notifyIfIgnoredValueChanged(); | 652 obj->notifyIfIgnoredValueChanged(); |
653 } | 653 } |
654 | 654 |
655 void AXObjectCacheImpl::updateCacheAfterNodeIsAttached(Node* node) | 655 void AXObjectCacheImpl::updateCacheAfterNodeIsAttached(Node* node) |
656 { | 656 { |
657 // Calling get() will update the AX object if we had an AXNodeObject but now
we need | 657 // Calling get() will update the AX object if we had an AXNodeObject but now
we need |
658 // an AXLayoutObject, because it was reparented to a location outside of a c
anvas. | 658 // an AXLayoutObject, because it was reparented to a location outside of a c
anvas. |
659 get(node); | 659 get(node); |
660 } | 660 } |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
706 AXNotification notification = m_notificationsToPost[i].second; | 706 AXNotification notification = m_notificationsToPost[i].second; |
707 postPlatformNotification(obj, notification); | 707 postPlatformNotification(obj, notification); |
708 | 708 |
709 if (notification == AXChildrenChanged && obj->parentObjectIfExists() &&
obj->lastKnownIsIgnoredValue() != obj->accessibilityIsIgnored()) | 709 if (notification == AXChildrenChanged && obj->parentObjectIfExists() &&
obj->lastKnownIsIgnoredValue() != obj->accessibilityIsIgnored()) |
710 childrenChanged(obj->parentObject()); | 710 childrenChanged(obj->parentObject()); |
711 } | 711 } |
712 | 712 |
713 m_notificationsToPost.clear(); | 713 m_notificationsToPost.clear(); |
714 } | 714 } |
715 | 715 |
716 void AXObjectCacheImpl::postNotification(LayoutObject* layoutObject, AXNotificat
ion notification, bool postToElement) | 716 void AXObjectCacheImpl::postNotification(LayoutObject* layoutObject, AXNotificat
ion notification) |
717 { | 717 { |
718 if (!layoutObject) | 718 if (!layoutObject) |
719 return; | 719 return; |
720 | 720 |
721 m_modificationCount++; | 721 m_modificationCount++; |
722 postNotification(get(layoutObject), notification, postToElement); | 722 postNotification(get(layoutObject), notification); |
723 } | 723 } |
724 | 724 |
725 void AXObjectCacheImpl::postNotification(Node* node, AXNotification notification
, bool postToElement) | 725 void AXObjectCacheImpl::postNotification(Node* node, AXNotification notification
) |
726 { | 726 { |
727 if (!node) | 727 if (!node) |
728 return; | 728 return; |
729 | 729 |
730 m_modificationCount++; | 730 m_modificationCount++; |
731 postNotification(get(node), notification, postToElement); | 731 postNotification(get(node), notification); |
732 } | 732 } |
733 | 733 |
734 void AXObjectCacheImpl::postNotification(AXObject* object, AXNotification notifi
cation, bool postToElement) | 734 void AXObjectCacheImpl::postNotification(AXObject* object, AXNotification notifi
cation) |
735 { | 735 { |
736 m_modificationCount++; | 736 m_modificationCount++; |
737 | |
738 if (object && !postToElement) | |
739 object = object->observableObject(); | |
740 | |
741 if (!object) | 737 if (!object) |
742 return; | 738 return; |
743 | 739 |
744 m_notificationsToPost.append(std::make_pair(object, notification)); | 740 m_notificationsToPost.append(std::make_pair(object, notification)); |
745 if (!m_notificationPostTimer.isActive()) | 741 if (!m_notificationPostTimer.isActive()) |
746 m_notificationPostTimer.startOneShot(0, FROM_HERE); | 742 m_notificationPostTimer.startOneShot(0, FROM_HERE); |
747 } | 743 } |
748 | 744 |
749 void AXObjectCacheImpl::checkedStateChanged(Node* node) | 745 void AXObjectCacheImpl::checkedStateChanged(Node* node) |
750 { | 746 { |
751 postNotification(node, AXObjectCacheImpl::AXCheckedStateChanged, true); | 747 postNotification(node, AXObjectCacheImpl::AXCheckedStateChanged); |
752 } | 748 } |
753 | 749 |
754 void AXObjectCacheImpl::selectedChildrenChanged(Node* node) | 750 void AXObjectCacheImpl::selectedChildrenChanged(Node* node) |
755 { | 751 { |
756 // postToElement is false so that you can pass in any child of an element an
d it will go up the parent tree | 752 selectedChildrenChanged(get(node)); |
757 // to find the container which should send out the notification. | |
758 postNotification(node, AXSelectedChildrenChanged, false); | |
759 } | 753 } |
760 | 754 |
761 void AXObjectCacheImpl::selectedChildrenChanged(LayoutObject* layoutObject) | 755 void AXObjectCacheImpl::selectedChildrenChanged(LayoutObject* layoutObject) |
762 { | 756 { |
763 // postToElement is false so that you can pass in any child of an element an
d it will go up the parent tree | 757 selectedChildrenChanged(get(layoutObject)); |
764 // to find the container which should send out the notification. | 758 } |
765 postNotification(layoutObject, AXSelectedChildrenChanged, false); | 759 |
| 760 void AXObjectCacheImpl::selectedChildrenChanged(AXObject* obj) |
| 761 { |
| 762 while (obj && obj->roleValue() != ListBoxRole) |
| 763 obj = obj->parentObject(); |
| 764 postNotification(obj, AXSelectedChildrenChanged); |
766 } | 765 } |
767 | 766 |
768 void AXObjectCacheImpl::handleScrollbarUpdate(FrameView* view) | 767 void AXObjectCacheImpl::handleScrollbarUpdate(FrameView* view) |
769 { | 768 { |
770 if (!view) | 769 if (!view) |
771 return; | 770 return; |
772 | 771 |
773 // We don't want to create a scroll view from this method, only update an ex
isting one. | 772 // We don't want to create a scroll view from this method, only update an ex
isting one. |
774 if (AXObject* scrollViewObject = get(view)) { | 773 if (AXObject* scrollViewObject = get(view)) { |
775 m_modificationCount++; | 774 m_modificationCount++; |
776 scrollViewObject->updateChildrenIfNecessary(); | 775 scrollViewObject->updateChildrenIfNecessary(); |
777 } | 776 } |
778 } | 777 } |
779 | 778 |
780 void AXObjectCacheImpl::handleLayoutComplete(LayoutObject* layoutObject) | 779 void AXObjectCacheImpl::handleLayoutComplete(LayoutObject* layoutObject) |
781 { | 780 { |
782 if (!layoutObject) | 781 if (!layoutObject) |
783 return; | 782 return; |
784 | 783 |
785 m_modificationCount++; | 784 m_modificationCount++; |
786 | 785 |
787 // Create the AXObject if it didn't yet exist - that's always safe at the en
d of a layout, and it | 786 // Create the AXObject if it didn't yet exist - that's always safe at the en
d of a layout, and it |
788 // allows an AX notification to be sent when a page has its first layout, ra
ther than when the | 787 // allows an AX notification to be sent when a page has its first layout, ra
ther than when the |
789 // document first loads. | 788 // document first loads. |
790 if (AXObject* obj = getOrCreate(layoutObject)) | 789 if (AXObject* obj = getOrCreate(layoutObject)) |
791 postNotification(obj, AXLayoutComplete, true); | 790 postNotification(obj, AXLayoutComplete); |
792 } | 791 } |
793 | 792 |
794 void AXObjectCacheImpl::handleAriaExpandedChange(Node* node) | 793 void AXObjectCacheImpl::handleAriaExpandedChange(Node* node) |
795 { | 794 { |
796 if (AXObject* obj = getOrCreate(node)) | 795 if (AXObject* obj = getOrCreate(node)) |
797 obj->handleAriaExpandedChanged(); | 796 obj->handleAriaExpandedChanged(); |
798 } | 797 } |
799 | 798 |
800 void AXObjectCacheImpl::handleActiveDescendantChanged(Node* node) | 799 void AXObjectCacheImpl::handleActiveDescendantChanged(Node* node) |
801 { | 800 { |
(...skipping 18 matching lines...) Expand all Loading... |
820 textChanged(element); | 819 textChanged(element); |
821 else if (attrName == forAttr && isHTMLLabelElement(*element)) | 820 else if (attrName == forAttr && isHTMLLabelElement(*element)) |
822 labelChanged(element); | 821 labelChanged(element); |
823 | 822 |
824 if (!attrName.localName().startsWith("aria-")) | 823 if (!attrName.localName().startsWith("aria-")) |
825 return; | 824 return; |
826 | 825 |
827 if (attrName == aria_activedescendantAttr) | 826 if (attrName == aria_activedescendantAttr) |
828 handleActiveDescendantChanged(element); | 827 handleActiveDescendantChanged(element); |
829 else if (attrName == aria_valuenowAttr || attrName == aria_valuetextAttr) | 828 else if (attrName == aria_valuenowAttr || attrName == aria_valuetextAttr) |
830 postNotification(element, AXObjectCacheImpl::AXValueChanged, true); | 829 postNotification(element, AXObjectCacheImpl::AXValueChanged); |
831 else if (attrName == aria_labelAttr || attrName == aria_labeledbyAttr || att
rName == aria_labelledbyAttr) | 830 else if (attrName == aria_labelAttr || attrName == aria_labeledbyAttr || att
rName == aria_labelledbyAttr) |
832 textChanged(element); | 831 textChanged(element); |
833 else if (attrName == aria_checkedAttr) | 832 else if (attrName == aria_checkedAttr) |
834 checkedStateChanged(element); | 833 checkedStateChanged(element); |
835 else if (attrName == aria_selectedAttr) | 834 else if (attrName == aria_selectedAttr) |
836 selectedChildrenChanged(element); | 835 selectedChildrenChanged(element); |
837 else if (attrName == aria_expandedAttr) | 836 else if (attrName == aria_expandedAttr) |
838 handleAriaExpandedChange(element); | 837 handleAriaExpandedChange(element); |
839 else if (attrName == aria_hiddenAttr) | 838 else if (attrName == aria_hiddenAttr) |
840 childrenChanged(element->parentNode()); | 839 childrenChanged(element->parentNode()); |
841 else if (attrName == aria_invalidAttr) | 840 else if (attrName == aria_invalidAttr) |
842 postNotification(element, AXObjectCacheImpl::AXInvalidStatusChanged, tru
e); | 841 postNotification(element, AXObjectCacheImpl::AXInvalidStatusChanged); |
843 else | 842 else |
844 postNotification(element, AXObjectCacheImpl::AXAriaAttributeChanged, tru
e); | 843 postNotification(element, AXObjectCacheImpl::AXAriaAttributeChanged); |
845 } | 844 } |
846 | 845 |
847 void AXObjectCacheImpl::labelChanged(Element* element) | 846 void AXObjectCacheImpl::labelChanged(Element* element) |
848 { | 847 { |
849 textChanged(toHTMLLabelElement(element)->control()); | 848 textChanged(toHTMLLabelElement(element)->control()); |
850 } | 849 } |
851 | 850 |
852 void AXObjectCacheImpl::recomputeIsIgnored(LayoutObject* layoutObject) | 851 void AXObjectCacheImpl::recomputeIsIgnored(LayoutObject* layoutObject) |
853 { | 852 { |
854 if (AXObject* obj = get(layoutObject)) | 853 if (AXObject* obj = get(layoutObject)) |
855 obj->notifyIfIgnoredValueChanged(); | 854 obj->notifyIfIgnoredValueChanged(); |
856 } | 855 } |
857 | 856 |
858 void AXObjectCacheImpl::inlineTextBoxesUpdated(LayoutObject* layoutObject) | 857 void AXObjectCacheImpl::inlineTextBoxesUpdated(LayoutObject* layoutObject) |
859 { | 858 { |
860 if (!inlineTextBoxAccessibilityEnabled()) | 859 if (!inlineTextBoxAccessibilityEnabled()) |
861 return; | 860 return; |
862 | 861 |
863 // Only update if the accessibility object already exists and it's | 862 // Only update if the accessibility object already exists and it's |
864 // not already marked as dirty. | 863 // not already marked as dirty. |
865 if (AXObject* obj = get(layoutObject)) { | 864 if (AXObject* obj = get(layoutObject)) { |
866 if (!obj->needsToUpdateChildren()) { | 865 if (!obj->needsToUpdateChildren()) { |
867 obj->setNeedsToUpdateChildren(); | 866 obj->setNeedsToUpdateChildren(); |
868 postNotification(layoutObject, AXChildrenChanged, true); | 867 postNotification(layoutObject, AXChildrenChanged); |
869 } | 868 } |
870 } | 869 } |
871 } | 870 } |
872 | 871 |
873 Settings* AXObjectCacheImpl::settings() | 872 Settings* AXObjectCacheImpl::settings() |
874 { | 873 { |
875 return m_document.settings(); | 874 return m_document.settings(); |
876 } | 875 } |
877 | 876 |
878 bool AXObjectCacheImpl::accessibilityEnabled() | 877 bool AXObjectCacheImpl::accessibilityEnabled() |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
985 | 984 |
986 AXObject* focusedObject = focusedUIElementForPage(page); | 985 AXObject* focusedObject = focusedUIElementForPage(page); |
987 if (!focusedObject) | 986 if (!focusedObject) |
988 return; | 987 return; |
989 | 988 |
990 postPlatformNotification(focusedObject, AXFocusedUIElementChanged); | 989 postPlatformNotification(focusedObject, AXFocusedUIElementChanged); |
991 } | 990 } |
992 | 991 |
993 void AXObjectCacheImpl::handleInitialFocus() | 992 void AXObjectCacheImpl::handleInitialFocus() |
994 { | 993 { |
995 postNotification(&m_document, AXObjectCache::AXFocusedUIElementChanged, true
); | 994 postNotification(&m_document, AXObjectCache::AXFocusedUIElementChanged); |
996 } | 995 } |
997 | 996 |
998 void AXObjectCacheImpl::handleEditableTextContentChanged(Node* node) | 997 void AXObjectCacheImpl::handleEditableTextContentChanged(Node* node) |
999 { | 998 { |
1000 postNotification(node, AXObjectCache::AXValueChanged, false); | 999 AXObject* obj = get(node); |
| 1000 while (obj && !obj->isNativeTextControl() && !obj->isNonNativeTextControl()) |
| 1001 obj = obj->parentObject(); |
| 1002 postNotification(obj, AXObjectCache::AXValueChanged); |
1001 } | 1003 } |
1002 | 1004 |
1003 void AXObjectCacheImpl::handleTextFormControlChanged(Node* node) | 1005 void AXObjectCacheImpl::handleTextFormControlChanged(Node* node) |
1004 { | 1006 { |
1005 postNotification(node, AXObjectCache::AXValueChanged, false); | 1007 handleEditableTextContentChanged(node); |
1006 } | 1008 } |
1007 | 1009 |
1008 void AXObjectCacheImpl::handleValueChanged(Node* node) | 1010 void AXObjectCacheImpl::handleValueChanged(Node* node) |
1009 { | 1011 { |
1010 postNotification(node, AXObjectCache::AXValueChanged, true); | 1012 postNotification(node, AXObjectCache::AXValueChanged); |
1011 } | 1013 } |
1012 | 1014 |
1013 void AXObjectCacheImpl::handleUpdateActiveMenuOption(LayoutMenuList* menuList, i
nt optionIndex) | 1015 void AXObjectCacheImpl::handleUpdateActiveMenuOption(LayoutMenuList* menuList, i
nt optionIndex) |
1014 { | 1016 { |
1015 if (AXMenuList* axMenuList = static_cast<AXMenuList*>(get(menuList))) | 1017 if (AXMenuList* axMenuList = static_cast<AXMenuList*>(get(menuList))) |
1016 axMenuList->didUpdateActiveOption(optionIndex); | 1018 axMenuList->didUpdateActiveOption(optionIndex); |
1017 } | 1019 } |
1018 | 1020 |
1019 void AXObjectCacheImpl::handleLoadComplete(Document* document) | 1021 void AXObjectCacheImpl::handleLoadComplete(Document* document) |
1020 { | 1022 { |
1021 postNotification(getOrCreate(document), AXObjectCache::AXLoadComplete, true)
; | 1023 postNotification(getOrCreate(document), AXObjectCache::AXLoadComplete); |
1022 } | 1024 } |
1023 | 1025 |
1024 void AXObjectCacheImpl::handleLayoutComplete(Document* document) | 1026 void AXObjectCacheImpl::handleLayoutComplete(Document* document) |
1025 { | 1027 { |
1026 postNotification(getOrCreate(document), AXObjectCache::AXLayoutComplete, tru
e); | 1028 postNotification(getOrCreate(document), AXObjectCache::AXLayoutComplete); |
1027 } | 1029 } |
1028 | 1030 |
1029 void AXObjectCacheImpl::handleScrolledToAnchor(const Node* anchorNode) | 1031 void AXObjectCacheImpl::handleScrolledToAnchor(const Node* anchorNode) |
1030 { | 1032 { |
1031 // The anchor node may not be accessible. Post the notification for the | 1033 // The anchor node may not be accessible. Post the notification for the |
1032 // first accessible object. | 1034 // first accessible object. |
1033 postPlatformNotification(firstAccessibleObjectFromNode(anchorNode), AXScroll
edToAnchor); | 1035 postPlatformNotification(firstAccessibleObjectFromNode(anchorNode), AXScroll
edToAnchor); |
1034 } | 1036 } |
1035 | 1037 |
1036 void AXObjectCacheImpl::handleScrollPositionChanged(FrameView* frameView) | 1038 void AXObjectCacheImpl::handleScrollPositionChanged(FrameView* frameView) |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1094 void AXObjectCacheImpl::setCanvasObjectBounds(Element* element, const LayoutRect
& rect) | 1096 void AXObjectCacheImpl::setCanvasObjectBounds(Element* element, const LayoutRect
& rect) |
1095 { | 1097 { |
1096 AXObject* obj = getOrCreate(element); | 1098 AXObject* obj = getOrCreate(element); |
1097 if (!obj) | 1099 if (!obj) |
1098 return; | 1100 return; |
1099 | 1101 |
1100 obj->setElementRect(rect); | 1102 obj->setElementRect(rect); |
1101 } | 1103 } |
1102 | 1104 |
1103 } // namespace blink | 1105 } // namespace blink |
OLD | NEW |