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 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 m_hasBeenDisposed = true; | 119 m_hasBeenDisposed = true; |
120 #endif | 120 #endif |
121 } | 121 } |
122 | 122 |
123 AXObject* AXObjectCacheImpl::root() { | 123 AXObject* AXObjectCacheImpl::root() { |
124 return getOrCreate(m_document); | 124 return getOrCreate(m_document); |
125 } | 125 } |
126 | 126 |
127 AXObject* AXObjectCacheImpl::focusedImageMapUIElement( | 127 AXObject* AXObjectCacheImpl::focusedImageMapUIElement( |
128 HTMLAreaElement* areaElement) { | 128 HTMLAreaElement* areaElement) { |
129 // Find the corresponding accessibility object for the HTMLAreaElement. This s
hould be | 129 // Find the corresponding accessibility object for the HTMLAreaElement. This |
130 // in the list of children for its corresponding image. | 130 // should be in the list of children for its corresponding image. |
131 if (!areaElement) | 131 if (!areaElement) |
132 return 0; | 132 return 0; |
133 | 133 |
134 HTMLImageElement* imageElement = areaElement->imageElement(); | 134 HTMLImageElement* imageElement = areaElement->imageElement(); |
135 if (!imageElement) | 135 if (!imageElement) |
136 return 0; | 136 return 0; |
137 | 137 |
138 AXObject* axLayoutImage = getOrCreate(imageElement); | 138 AXObject* axLayoutImage = getOrCreate(imageElement); |
139 if (!axLayoutImage) | 139 if (!axLayoutImage) |
140 return 0; | 140 return 0; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
173 if (Element* focusedElementInPopup = | 173 if (Element* focusedElementInPopup = |
174 axPopup->getDocument()->focusedElement()) | 174 axPopup->getDocument()->focusedElement()) |
175 focusedNode = focusedElementInPopup; | 175 focusedNode = focusedElementInPopup; |
176 } | 176 } |
177 } | 177 } |
178 | 178 |
179 AXObject* obj = getOrCreate(focusedNode); | 179 AXObject* obj = getOrCreate(focusedNode); |
180 if (!obj) | 180 if (!obj) |
181 return nullptr; | 181 return nullptr; |
182 | 182 |
183 // the HTML element, for example, is focusable but has an AX object that is ig
nored | 183 // the HTML element, for example, is focusable but has an AX object that is |
| 184 // ignored |
184 if (obj->accessibilityIsIgnored()) | 185 if (obj->accessibilityIsIgnored()) |
185 obj = obj->parentObjectUnignored(); | 186 obj = obj->parentObjectUnignored(); |
186 | 187 |
187 return obj; | 188 return obj; |
188 } | 189 } |
189 | 190 |
190 AXObject* AXObjectCacheImpl::get(LayoutObject* layoutObject) { | 191 AXObject* AXObjectCacheImpl::get(LayoutObject* layoutObject) { |
191 if (!layoutObject) | 192 if (!layoutObject) |
192 return 0; | 193 return 0; |
193 | 194 |
(...skipping 14 matching lines...) Expand all Loading... |
208 if (!select) | 209 if (!select) |
209 return false; | 210 return false; |
210 LayoutObject* layoutObject = select->layoutObject(); | 211 LayoutObject* layoutObject = select->layoutObject(); |
211 return layoutObject && layoutObject->isMenuList(); | 212 return layoutObject && layoutObject->isMenuList(); |
212 } | 213 } |
213 | 214 |
214 AXObject* AXObjectCacheImpl::get(Node* node) { | 215 AXObject* AXObjectCacheImpl::get(Node* node) { |
215 if (!node) | 216 if (!node) |
216 return 0; | 217 return 0; |
217 | 218 |
218 // Menu list option and HTML area elements are indexed by DOM node, never by l
ayout object. | 219 // Menu list option and HTML area elements are indexed by DOM node, never by |
| 220 // layout object. |
219 LayoutObject* layoutObject = node->layoutObject(); | 221 LayoutObject* layoutObject = node->layoutObject(); |
220 if (isMenuListOption(node) || isHTMLAreaElement(node)) | 222 if (isMenuListOption(node) || isHTMLAreaElement(node)) |
221 layoutObject = nullptr; | 223 layoutObject = nullptr; |
222 | 224 |
223 AXID layoutID = layoutObject ? m_layoutObjectMapping.get(layoutObject) : 0; | 225 AXID layoutID = layoutObject ? m_layoutObjectMapping.get(layoutObject) : 0; |
224 ASSERT(!HashTraits<AXID>::isDeletedValue(layoutID)); | 226 ASSERT(!HashTraits<AXID>::isDeletedValue(layoutID)); |
225 | 227 |
226 AXID nodeID = m_nodeObjectMapping.get(node); | 228 AXID nodeID = m_nodeObjectMapping.get(node); |
227 ASSERT(!HashTraits<AXID>::isDeletedValue(nodeID)); | 229 ASSERT(!HashTraits<AXID>::isDeletedValue(nodeID)); |
228 | 230 |
229 if (layoutObject && nodeID && !layoutID) { | 231 if (layoutObject && nodeID && !layoutID) { |
230 // This can happen if an AXNodeObject is created for a node that's not | 232 // This can happen if an AXNodeObject is created for a node that's not |
231 // laid out, but later something changes and it gets a layoutObject (like if
it's | 233 // laid out, but later something changes and it gets a layoutObject (like if |
232 // reparented). | 234 // it's reparented). |
233 remove(nodeID); | 235 remove(nodeID); |
234 return 0; | 236 return 0; |
235 } | 237 } |
236 | 238 |
237 if (layoutID) | 239 if (layoutID) |
238 return m_objects.get(layoutID); | 240 return m_objects.get(layoutID); |
239 | 241 |
240 if (!nodeID) | 242 if (!nodeID) |
241 return 0; | 243 return 0; |
242 | 244 |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
341 return AXInlineTextBox::create(inlineTextBox, *this); | 343 return AXInlineTextBox::create(inlineTextBox, *this); |
342 } | 344 } |
343 | 345 |
344 AXObject* AXObjectCacheImpl::getOrCreate(Node* node) { | 346 AXObject* AXObjectCacheImpl::getOrCreate(Node* node) { |
345 if (!node) | 347 if (!node) |
346 return 0; | 348 return 0; |
347 | 349 |
348 if (AXObject* obj = get(node)) | 350 if (AXObject* obj = get(node)) |
349 return obj; | 351 return obj; |
350 | 352 |
351 // If the node has a layout object, prefer using that as the primary key for t
he AXObject, | 353 // If the node has a layout object, prefer using that as the primary key for |
352 // with the exception of an HTMLAreaElement, which is created based on its nod
e. | 354 // the AXObject, with the exception of an HTMLAreaElement, which is created |
| 355 // based on its node. |
353 if (node->layoutObject() && !isHTMLAreaElement(node)) | 356 if (node->layoutObject() && !isHTMLAreaElement(node)) |
354 return getOrCreate(node->layoutObject()); | 357 return getOrCreate(node->layoutObject()); |
355 | 358 |
356 if (!node->parentElement()) | 359 if (!node->parentElement()) |
357 return 0; | 360 return 0; |
358 | 361 |
359 if (isHTMLHeadElement(node)) | 362 if (isHTMLHeadElement(node)) |
360 return 0; | 363 return 0; |
361 | 364 |
362 AXObject* newObj = createFromNode(node); | 365 AXObject* newObj = createFromNode(node); |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
565 for (size_t i = 0; i < childAXIDs.size(); ++i) | 568 for (size_t i = 0; i < childAXIDs.size(); ++i) |
566 m_ariaOwnedChildToOwnerMapping.remove(childAXIDs[i]); | 569 m_ariaOwnedChildToOwnerMapping.remove(childAXIDs[i]); |
567 m_ariaOwnerToChildrenMapping.remove(objID); | 570 m_ariaOwnerToChildrenMapping.remove(objID); |
568 } | 571 } |
569 m_ariaOwnedChildToOwnerMapping.remove(objID); | 572 m_ariaOwnedChildToOwnerMapping.remove(objID); |
570 m_ariaOwnedChildToRealParentMapping.remove(objID); | 573 m_ariaOwnedChildToRealParentMapping.remove(objID); |
571 m_ariaOwnerToIdsMapping.remove(objID); | 574 m_ariaOwnerToIdsMapping.remove(objID); |
572 } | 575 } |
573 | 576 |
574 void AXObjectCacheImpl::selectionChanged(Node* node) { | 577 void AXObjectCacheImpl::selectionChanged(Node* node) { |
575 // Find the nearest ancestor that already has an accessibility object, since w
e | 578 // Find the nearest ancestor that already has an accessibility object, since |
576 // might be in the middle of a layout. | 579 // we might be in the middle of a layout. |
577 while (node) { | 580 while (node) { |
578 if (AXObject* obj = get(node)) { | 581 if (AXObject* obj = get(node)) { |
579 obj->selectionChanged(); | 582 obj->selectionChanged(); |
580 return; | 583 return; |
581 } | 584 } |
582 node = node->parentNode(); | 585 node = node->parentNode(); |
583 } | 586 } |
584 } | 587 } |
585 | 588 |
586 void AXObjectCacheImpl::textChanged(Node* node) { | 589 void AXObjectCacheImpl::textChanged(Node* node) { |
587 textChanged(getOrCreate(node)); | 590 textChanged(getOrCreate(node)); |
588 } | 591 } |
589 | 592 |
590 void AXObjectCacheImpl::textChanged(LayoutObject* layoutObject) { | 593 void AXObjectCacheImpl::textChanged(LayoutObject* layoutObject) { |
591 textChanged(getOrCreate(layoutObject)); | 594 textChanged(getOrCreate(layoutObject)); |
592 } | 595 } |
593 | 596 |
594 void AXObjectCacheImpl::textChanged(AXObject* obj) { | 597 void AXObjectCacheImpl::textChanged(AXObject* obj) { |
595 if (!obj) | 598 if (!obj) |
596 return; | 599 return; |
597 | 600 |
598 bool parentAlreadyExists = obj->parentObjectIfExists(); | 601 bool parentAlreadyExists = obj->parentObjectIfExists(); |
599 obj->textChanged(); | 602 obj->textChanged(); |
600 postNotification(obj, AXObjectCacheImpl::AXTextChanged); | 603 postNotification(obj, AXObjectCacheImpl::AXTextChanged); |
601 if (parentAlreadyExists) | 604 if (parentAlreadyExists) |
602 obj->notifyIfIgnoredValueChanged(); | 605 obj->notifyIfIgnoredValueChanged(); |
603 } | 606 } |
604 | 607 |
605 void AXObjectCacheImpl::updateCacheAfterNodeIsAttached(Node* node) { | 608 void AXObjectCacheImpl::updateCacheAfterNodeIsAttached(Node* node) { |
606 // Calling get() will update the AX object if we had an AXNodeObject but now w
e need | 609 // Calling get() will update the AX object if we had an AXNodeObject but now |
607 // an AXLayoutObject, because it was reparented to a location outside of a can
vas. | 610 // we need an AXLayoutObject, because it was reparented to a location outside |
| 611 // of a canvas. |
608 get(node); | 612 get(node); |
609 if (node->isElementNode()) | 613 if (node->isElementNode()) |
610 updateTreeIfElementIdIsAriaOwned(toElement(node)); | 614 updateTreeIfElementIdIsAriaOwned(toElement(node)); |
611 } | 615 } |
612 | 616 |
613 void AXObjectCacheImpl::childrenChanged(Node* node) { | 617 void AXObjectCacheImpl::childrenChanged(Node* node) { |
614 childrenChanged(get(node)); | 618 childrenChanged(get(node)); |
615 } | 619 } |
616 | 620 |
617 void AXObjectCacheImpl::childrenChanged(LayoutObject* layoutObject) { | 621 void AXObjectCacheImpl::childrenChanged(LayoutObject* layoutObject) { |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
696 AXObject* AXObjectCacheImpl::getAriaOwnedParent(const AXObject* child) const { | 700 AXObject* AXObjectCacheImpl::getAriaOwnedParent(const AXObject* child) const { |
697 return objectFromAXID( | 701 return objectFromAXID( |
698 m_ariaOwnedChildToOwnerMapping.get(child->axObjectID())); | 702 m_ariaOwnedChildToOwnerMapping.get(child->axObjectID())); |
699 } | 703 } |
700 | 704 |
701 void AXObjectCacheImpl::updateAriaOwns( | 705 void AXObjectCacheImpl::updateAriaOwns( |
702 const AXObject* owner, | 706 const AXObject* owner, |
703 const Vector<String>& idVector, | 707 const Vector<String>& idVector, |
704 HeapVector<Member<AXObject>>& ownedChildren) { | 708 HeapVector<Member<AXObject>>& ownedChildren) { |
705 // | 709 // |
706 // Update the map from the AXID of this element to the ids of the owned childr
en, | 710 // Update the map from the AXID of this element to the ids of the owned |
707 // and the reverse map from ids to possible AXID owners. | 711 // children, and the reverse map from ids to possible AXID owners. |
708 // | 712 // |
709 | 713 |
710 HashSet<String> currentIds = m_ariaOwnerToIdsMapping.get(owner->axObjectID()); | 714 HashSet<String> currentIds = m_ariaOwnerToIdsMapping.get(owner->axObjectID()); |
711 HashSet<String> newIds; | 715 HashSet<String> newIds; |
712 bool idsChanged = false; | 716 bool idsChanged = false; |
713 for (const String& id : idVector) { | 717 for (const String& id : idVector) { |
714 newIds.add(id); | 718 newIds.add(id); |
715 if (!currentIds.contains(id)) { | 719 if (!currentIds.contains(id)) { |
716 idsChanged = true; | 720 idsChanged = true; |
717 HashSet<AXID>* owners = m_idToAriaOwnersMapping.get(id); | 721 HashSet<AXID>* owners = m_idToAriaOwnersMapping.get(id); |
(...skipping 30 matching lines...) Expand all Loading... |
748 for (const String& idName : idVector) { | 752 for (const String& idName : idVector) { |
749 Element* element = scope.getElementById(AtomicString(idName)); | 753 Element* element = scope.getElementById(AtomicString(idName)); |
750 if (!element) | 754 if (!element) |
751 continue; | 755 continue; |
752 | 756 |
753 AXObject* child = getOrCreate(element); | 757 AXObject* child = getOrCreate(element); |
754 if (!child) | 758 if (!child) |
755 continue; | 759 continue; |
756 | 760 |
757 // If this child is already aria-owned by a different owner, continue. | 761 // If this child is already aria-owned by a different owner, continue. |
758 // It's an author error if this happens and we don't worry about which of th
e | 762 // It's an author error if this happens and we don't worry about which of |
759 // two owners wins ownership of the child, as long as only one of them does. | 763 // the two owners wins ownership of the child, as long as only one of them |
| 764 // does. |
760 if (isAriaOwned(child) && getAriaOwnedParent(child) != owner) | 765 if (isAriaOwned(child) && getAriaOwnedParent(child) != owner) |
761 continue; | 766 continue; |
762 | 767 |
763 // You can't own yourself! | 768 // You can't own yourself! |
764 if (child == owner) | 769 if (child == owner) |
765 continue; | 770 continue; |
766 | 771 |
767 // Walk up the parents of the owner object, make sure that this child doesn'
t appear | 772 // Walk up the parents of the owner object, make sure that this child |
768 // there, as that would create a cycle. | 773 // doesn't appear there, as that would create a cycle. |
769 bool foundCycle = false; | 774 bool foundCycle = false; |
770 for (AXObject* parent = owner->parentObject(); parent && !foundCycle; | 775 for (AXObject* parent = owner->parentObject(); parent && !foundCycle; |
771 parent = parent->parentObject()) { | 776 parent = parent->parentObject()) { |
772 if (parent == child) | 777 if (parent == child) |
773 foundCycle = true; | 778 foundCycle = true; |
774 } | 779 } |
775 if (foundCycle) | 780 if (foundCycle) |
776 continue; | 781 continue; |
777 | 782 |
778 newChildAXIDs.append(child->axObjectID()); | 783 newChildAXIDs.append(child->axObjectID()); |
779 ownedChildren.append(child); | 784 ownedChildren.append(child); |
780 } | 785 } |
781 | 786 |
782 // Compare this to the current list of owned children, and exit early if there
are no changes. | 787 // Compare this to the current list of owned children, and exit early if there |
| 788 // are no changes. |
783 Vector<AXID> currentChildAXIDs = | 789 Vector<AXID> currentChildAXIDs = |
784 m_ariaOwnerToChildrenMapping.get(owner->axObjectID()); | 790 m_ariaOwnerToChildrenMapping.get(owner->axObjectID()); |
785 bool same = true; | 791 bool same = true; |
786 if (currentChildAXIDs.size() != newChildAXIDs.size()) { | 792 if (currentChildAXIDs.size() != newChildAXIDs.size()) { |
787 same = false; | 793 same = false; |
788 } else { | 794 } else { |
789 for (size_t i = 0; i < currentChildAXIDs.size() && same; ++i) { | 795 for (size_t i = 0; i < currentChildAXIDs.size() && same; ++i) { |
790 if (currentChildAXIDs[i] != newChildAXIDs[i]) | 796 if (currentChildAXIDs[i] != newChildAXIDs[i]) |
791 same = false; | 797 same = false; |
792 } | 798 } |
793 } | 799 } |
794 if (same) | 800 if (same) |
795 return; | 801 return; |
796 | 802 |
797 // The list of owned children has changed. Even if they were just reordered, t
o be safe | 803 // The list of owned children has changed. Even if they were just reordered, |
798 // and handle all cases we remove all of the current owned children and add th
e new list | 804 // to be safe and handle all cases we remove all of the current owned children |
799 // of owned children. | 805 // and add the new list of owned children. |
800 for (size_t i = 0; i < currentChildAXIDs.size(); ++i) { | 806 for (size_t i = 0; i < currentChildAXIDs.size(); ++i) { |
801 // Find the AXObject for the child that this owner no longer owns. | 807 // Find the AXObject for the child that this owner no longer owns. |
802 AXID removedChildID = currentChildAXIDs[i]; | 808 AXID removedChildID = currentChildAXIDs[i]; |
803 AXObject* removedChild = objectFromAXID(removedChildID); | 809 AXObject* removedChild = objectFromAXID(removedChildID); |
804 | 810 |
805 // It's possible that this child has already been owned by some other owner, | 811 // It's possible that this child has already been owned by some other owner, |
806 // in which case we don't need to do anything. | 812 // in which case we don't need to do anything. |
807 if (removedChild && getAriaOwnedParent(removedChild) != owner) | 813 if (removedChild && getAriaOwnedParent(removedChild) != owner) |
808 continue; | 814 continue; |
809 | 815 |
810 // Remove it from the child -> owner mapping so it's not owned by this owner
anymore. | 816 // Remove it from the child -> owner mapping so it's not owned by this owner |
| 817 // anymore. |
811 m_ariaOwnedChildToOwnerMapping.remove(removedChildID); | 818 m_ariaOwnedChildToOwnerMapping.remove(removedChildID); |
812 | 819 |
813 if (removedChild) { | 820 if (removedChild) { |
814 // If the child still exists, find its "real" parent, and reparent it back
to | 821 // If the child still exists, find its "real" parent, and reparent it back |
815 // its real parent in the tree by detaching it from its current parent and | 822 // to its real parent in the tree by detaching it from its current parent |
816 // calling childrenChanged on its real parent. | 823 // and calling childrenChanged on its real parent. |
817 removedChild->detachFromParent(); | 824 removedChild->detachFromParent(); |
818 AXID realParentID = | 825 AXID realParentID = |
819 m_ariaOwnedChildToRealParentMapping.get(removedChildID); | 826 m_ariaOwnedChildToRealParentMapping.get(removedChildID); |
820 AXObject* realParent = objectFromAXID(realParentID); | 827 AXObject* realParent = objectFromAXID(realParentID); |
821 childrenChanged(realParent); | 828 childrenChanged(realParent); |
822 } | 829 } |
823 | 830 |
824 // Remove the child -> original parent mapping too since this object has now
been | 831 // Remove the child -> original parent mapping too since this object has now |
825 // reparented back to its original parent. | 832 // been reparented back to its original parent. |
826 m_ariaOwnedChildToRealParentMapping.remove(removedChildID); | 833 m_ariaOwnedChildToRealParentMapping.remove(removedChildID); |
827 } | 834 } |
828 | 835 |
829 for (size_t i = 0; i < newChildAXIDs.size(); ++i) { | 836 for (size_t i = 0; i < newChildAXIDs.size(); ++i) { |
830 // Find the AXObject for the child that will now be a child of this owner. | 837 // Find the AXObject for the child that will now be a child of this owner. |
831 AXID addedChildID = newChildAXIDs[i]; | 838 AXID addedChildID = newChildAXIDs[i]; |
832 AXObject* addedChild = objectFromAXID(addedChildID); | 839 AXObject* addedChild = objectFromAXID(addedChildID); |
833 | 840 |
834 // Add this child to the mapping from child to owner. | 841 // Add this child to the mapping from child to owner. |
835 m_ariaOwnedChildToOwnerMapping.set(addedChildID, owner->axObjectID()); | 842 m_ariaOwnedChildToOwnerMapping.set(addedChildID, owner->axObjectID()); |
836 | 843 |
837 // Add its parent object to a mapping from child to real parent. If later th
is owner | 844 // Add its parent object to a mapping from child to real parent. If later |
838 // doesn't own this child anymore, we need to return it to its original pare
nt. | 845 // this owner doesn't own this child anymore, we need to return it to its |
| 846 // original parent. |
839 AXObject* originalParent = addedChild->parentObject(); | 847 AXObject* originalParent = addedChild->parentObject(); |
840 m_ariaOwnedChildToRealParentMapping.set(addedChildID, | 848 m_ariaOwnedChildToRealParentMapping.set(addedChildID, |
841 originalParent->axObjectID()); | 849 originalParent->axObjectID()); |
842 | 850 |
843 // Now detach the object from its original parent and call childrenChanged o
n the | 851 // Now detach the object from its original parent and call childrenChanged |
844 // original parent so that it can recompute its list of children. | 852 // on the original parent so that it can recompute its list of children. |
845 addedChild->detachFromParent(); | 853 addedChild->detachFromParent(); |
846 childrenChanged(originalParent); | 854 childrenChanged(originalParent); |
847 } | 855 } |
848 | 856 |
849 // Finally, update the mapping from the owner to the list of child IDs. | 857 // Finally, update the mapping from the owner to the list of child IDs. |
850 m_ariaOwnerToChildrenMapping.set(owner->axObjectID(), newChildAXIDs); | 858 m_ariaOwnerToChildrenMapping.set(owner->axObjectID(), newChildAXIDs); |
851 } | 859 } |
852 | 860 |
853 void AXObjectCacheImpl::updateTreeIfElementIdIsAriaOwned(Element* element) { | 861 void AXObjectCacheImpl::updateTreeIfElementIdIsAriaOwned(Element* element) { |
854 if (!element->hasID()) | 862 if (!element->hasID()) |
(...skipping 10 matching lines...) Expand all Loading... |
865 | 873 |
866 // If it's already owned, call childrenChanged on the owner to make sure it's | 874 // If it's already owned, call childrenChanged on the owner to make sure it's |
867 // still an owner. | 875 // still an owner. |
868 if (isAriaOwned(axElement)) { | 876 if (isAriaOwned(axElement)) { |
869 AXObject* ownedParent = getAriaOwnedParent(axElement); | 877 AXObject* ownedParent = getAriaOwnedParent(axElement); |
870 ASSERT(ownedParent); | 878 ASSERT(ownedParent); |
871 childrenChanged(ownedParent); | 879 childrenChanged(ownedParent); |
872 return; | 880 return; |
873 } | 881 } |
874 | 882 |
875 // If it's not already owned, check the possible owners based on our mapping f
rom | 883 // If it's not already owned, check the possible owners based on our mapping |
876 // ids to elements that have that id listed in their aria-owns attribute. | 884 // from ids to elements that have that id listed in their aria-owns attribute. |
877 for (const auto& axID : *owners) { | 885 for (const auto& axID : *owners) { |
878 AXObject* owner = objectFromAXID(axID); | 886 AXObject* owner = objectFromAXID(axID); |
879 if (owner) | 887 if (owner) |
880 childrenChanged(owner); | 888 childrenChanged(owner); |
881 } | 889 } |
882 } | 890 } |
883 | 891 |
884 void AXObjectCacheImpl::checkedStateChanged(Node* node) { | 892 void AXObjectCacheImpl::checkedStateChanged(Node* node) { |
885 postNotification(node, AXObjectCacheImpl::AXCheckedStateChanged); | 893 postNotification(node, AXObjectCacheImpl::AXCheckedStateChanged); |
886 } | 894 } |
(...skipping 14 matching lines...) Expand all Loading... |
901 | 909 |
902 toAXListBox(obj)->activeIndexChanged(); | 910 toAXListBox(obj)->activeIndexChanged(); |
903 } | 911 } |
904 | 912 |
905 void AXObjectCacheImpl::radiobuttonRemovedFromGroup( | 913 void AXObjectCacheImpl::radiobuttonRemovedFromGroup( |
906 HTMLInputElement* groupMember) { | 914 HTMLInputElement* groupMember) { |
907 AXObject* obj = get(groupMember); | 915 AXObject* obj = get(groupMember); |
908 if (!obj || !obj->isAXRadioInput()) | 916 if (!obj || !obj->isAXRadioInput()) |
909 return; | 917 return; |
910 | 918 |
911 // The 'posInSet' and 'setSize' attributes should be updated from the first no
de, | 919 // The 'posInSet' and 'setSize' attributes should be updated from the first |
912 // as the removed node is already detached from tree. | 920 // node, as the removed node is already detached from tree. |
913 HTMLInputElement* firstRadio = | 921 HTMLInputElement* firstRadio = |
914 toAXRadioInput(obj)->findFirstRadioButtonInGroup(groupMember); | 922 toAXRadioInput(obj)->findFirstRadioButtonInGroup(groupMember); |
915 AXObject* firstObj = get(firstRadio); | 923 AXObject* firstObj = get(firstRadio); |
916 if (!firstObj || !firstObj->isAXRadioInput()) | 924 if (!firstObj || !firstObj->isAXRadioInput()) |
917 return; | 925 return; |
918 | 926 |
919 toAXRadioInput(firstObj)->updatePosAndSetSize(1); | 927 toAXRadioInput(firstObj)->updatePosAndSetSize(1); |
920 postNotification(firstObj, AXAriaAttributeChanged); | 928 postNotification(firstObj, AXAriaAttributeChanged); |
921 toAXRadioInput(firstObj)->requestUpdateToNextNode(true); | 929 toAXRadioInput(firstObj)->requestUpdateToNextNode(true); |
922 } | 930 } |
923 | 931 |
924 void AXObjectCacheImpl::handleLayoutComplete(LayoutObject* layoutObject) { | 932 void AXObjectCacheImpl::handleLayoutComplete(LayoutObject* layoutObject) { |
925 if (!layoutObject) | 933 if (!layoutObject) |
926 return; | 934 return; |
927 | 935 |
928 m_modificationCount++; | 936 m_modificationCount++; |
929 | 937 |
930 // Create the AXObject if it didn't yet exist - that's always safe at the end
of a layout, and it | 938 // Create the AXObject if it didn't yet exist - that's always safe at the end |
931 // allows an AX notification to be sent when a page has its first layout, rath
er than when the | 939 // of a layout, and it allows an AX notification to be sent when a page has |
932 // document first loads. | 940 // its first layout, rather than when the document first loads. |
933 if (AXObject* obj = getOrCreate(layoutObject)) | 941 if (AXObject* obj = getOrCreate(layoutObject)) |
934 postNotification(obj, AXLayoutComplete); | 942 postNotification(obj, AXLayoutComplete); |
935 } | 943 } |
936 | 944 |
937 void AXObjectCacheImpl::handleClicked(Node* node) { | 945 void AXObjectCacheImpl::handleClicked(Node* node) { |
938 if (AXObject* obj = getOrCreate(node)) | 946 if (AXObject* obj = getOrCreate(node)) |
939 postNotification(obj, AXClicked); | 947 postNotification(obj, AXClicked); |
940 } | 948 } |
941 | 949 |
942 void AXObjectCacheImpl::handleAriaExpandedChange(Node* node) { | 950 void AXObjectCacheImpl::handleAriaExpandedChange(Node* node) { |
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1247 visitor->trace(m_document); | 1255 visitor->trace(m_document); |
1248 visitor->trace(m_nodeObjectMapping); | 1256 visitor->trace(m_nodeObjectMapping); |
1249 | 1257 |
1250 visitor->trace(m_objects); | 1258 visitor->trace(m_objects); |
1251 visitor->trace(m_notificationsToPost); | 1259 visitor->trace(m_notificationsToPost); |
1252 | 1260 |
1253 AXObjectCache::trace(visitor); | 1261 AXObjectCache::trace(visitor); |
1254 } | 1262 } |
1255 | 1263 |
1256 } // namespace blink | 1264 } // namespace blink |
OLD | NEW |