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

Side by Side Diff: Source/modules/accessibility/AXLayoutObject.cpp

Issue 1175533004: Refactor: Clear m_axObjectCache when AXObject detaches (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Added ASSERT Created 5 years, 6 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 | « Source/modules/accessibility/AXLayoutObject.h ('k') | Source/modules/accessibility/AXList.h » ('j') | 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 Apple Inc. All rights reserved. 2 * Copyright (C) 2008 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 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 static LayoutBoxModelObject* nextContinuation(LayoutObject* layoutObject) 164 static LayoutBoxModelObject* nextContinuation(LayoutObject* layoutObject)
165 { 165 {
166 ASSERT(layoutObject); 166 ASSERT(layoutObject);
167 if (layoutObject->isLayoutInline() && !layoutObject->isReplaced()) 167 if (layoutObject->isLayoutInline() && !layoutObject->isReplaced())
168 return toLayoutInline(layoutObject)->continuation(); 168 return toLayoutInline(layoutObject)->continuation();
169 if (layoutObject->isLayoutBlock()) 169 if (layoutObject->isLayoutBlock())
170 return toLayoutBlock(layoutObject)->inlineElementContinuation(); 170 return toLayoutBlock(layoutObject)->inlineElementContinuation();
171 return 0; 171 return 0;
172 } 172 }
173 173
174 AXLayoutObject::AXLayoutObject(LayoutObject* layoutObject, AXObjectCacheImpl* ax ObjectCache) 174 AXLayoutObject::AXLayoutObject(LayoutObject* layoutObject, AXObjectCacheImpl& ax ObjectCache)
175 : AXNodeObject(layoutObject->node(), axObjectCache) 175 : AXNodeObject(layoutObject->node(), axObjectCache)
176 , m_layoutObject(layoutObject) 176 , m_layoutObject(layoutObject)
177 , m_cachedElementRectDirty(true) 177 , m_cachedElementRectDirty(true)
178 { 178 {
179 #if ENABLE(ASSERT) 179 #if ENABLE(ASSERT)
180 m_layoutObject->setHasAXObject(true); 180 m_layoutObject->setHasAXObject(true);
181 #endif 181 #endif
182 } 182 }
183 183
184 PassRefPtr<AXLayoutObject> AXLayoutObject::create(LayoutObject* layoutObject, AX ObjectCacheImpl* axObjectCache) 184 PassRefPtr<AXLayoutObject> AXLayoutObject::create(LayoutObject* layoutObject, AX ObjectCacheImpl& axObjectCache)
185 { 185 {
186 return adoptRef(new AXLayoutObject(layoutObject, axObjectCache)); 186 return adoptRef(new AXLayoutObject(layoutObject, axObjectCache));
187 } 187 }
188 188
189 AXLayoutObject::~AXLayoutObject() 189 AXLayoutObject::~AXLayoutObject()
190 { 190 {
191 ASSERT(isDetached()); 191 ASSERT(isDetached());
192 } 192 }
193 193
194 LayoutRect AXLayoutObject::elementRect() const 194 LayoutRect AXLayoutObject::elementRect() const
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after
564 if (isAttachment()) 564 if (isAttachment())
565 return false; 565 return false;
566 566
567 // find out if this element is inside of a label element. 567 // find out if this element is inside of a label element.
568 // if so, it may be ignored because it's the label for a checkbox or radio b utton 568 // if so, it may be ignored because it's the label for a checkbox or radio b utton
569 AXObject* controlObject = correspondingControlForLabelElement(); 569 AXObject* controlObject = correspondingControlForLabelElement();
570 if (controlObject && !controlObject->deprecatedExposesTitleUIElement() && co ntrolObject->isCheckboxOrRadio()) { 570 if (controlObject && !controlObject->deprecatedExposesTitleUIElement() && co ntrolObject->isCheckboxOrRadio()) {
571 if (ignoredReasons) { 571 if (ignoredReasons) {
572 HTMLLabelElement* label = labelElementContainer(); 572 HTMLLabelElement* label = labelElementContainer();
573 if (label && !label->isSameNode(node())) { 573 if (label && !label->isSameNode(node())) {
574 AXObject* labelAXObject = axObjectCache()->getOrCreate(label); 574 AXObject* labelAXObject = axObjectCache().getOrCreate(label);
575 ignoredReasons->append(IgnoredReason(AXLabelContainer, labelAXOb ject)); 575 ignoredReasons->append(IgnoredReason(AXLabelContainer, labelAXOb ject));
576 } 576 }
577 577
578 ignoredReasons->append(IgnoredReason(AXLabelFor, controlObject)); 578 ignoredReasons->append(IgnoredReason(AXLabelFor, controlObject));
579 } 579 }
580 return true; 580 return true;
581 } 581 }
582 582
583 if (m_layoutObject->isBR()) 583 if (m_layoutObject->isBR())
584 return false; 584 return false;
(...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after
1021 if (m_layoutObject->isLayoutInline()) 1021 if (m_layoutObject->isLayoutInline())
1022 inlineBox = toLayoutInline(m_layoutObject)->lastLineBox(); 1022 inlineBox = toLayoutInline(m_layoutObject)->lastLineBox();
1023 else if (m_layoutObject->isText()) 1023 else if (m_layoutObject->isText())
1024 inlineBox = toLayoutText(m_layoutObject)->lastTextBox(); 1024 inlineBox = toLayoutText(m_layoutObject)->lastTextBox();
1025 else 1025 else
1026 return 0; 1026 return 0;
1027 1027
1028 AXObject* result = 0; 1028 AXObject* result = 0;
1029 for (InlineBox* next = inlineBox->nextOnLine(); next; next = next->nextOnLin e()) { 1029 for (InlineBox* next = inlineBox->nextOnLine(); next; next = next->nextOnLin e()) {
1030 LayoutObject* layoutObject = &next->layoutObject(); 1030 LayoutObject* layoutObject = &next->layoutObject();
1031 result = axObjectCache()->getOrCreate(layoutObject); 1031 result = axObjectCache().getOrCreate(layoutObject);
1032 if (result) 1032 if (result)
1033 break; 1033 break;
1034 } 1034 }
1035 1035
1036 // A static text node might span multiple lines. Try to return the first inl ine 1036 // A static text node might span multiple lines. Try to return the first inl ine
1037 // text box within that static text if possible. 1037 // text box within that static text if possible.
1038 if (result && result->roleValue() == StaticTextRole && result->children().si ze()) 1038 if (result && result->roleValue() == StaticTextRole && result->children().si ze())
1039 result = result->children()[0].get(); 1039 result = result->children()[0].get();
1040 1040
1041 return result; 1041 return result;
1042 } 1042 }
1043 1043
1044 AXObject* AXLayoutObject::previousOnLine() const 1044 AXObject* AXLayoutObject::previousOnLine() const
1045 { 1045 {
1046 if (!m_layoutObject) 1046 if (!m_layoutObject)
1047 return 0; 1047 return 0;
1048 1048
1049 InlineBox* inlineBox; 1049 InlineBox* inlineBox;
1050 if (m_layoutObject->isLayoutInline()) 1050 if (m_layoutObject->isLayoutInline())
1051 inlineBox = toLayoutInline(m_layoutObject)->firstLineBox(); 1051 inlineBox = toLayoutInline(m_layoutObject)->firstLineBox();
1052 else if (m_layoutObject->isText()) 1052 else if (m_layoutObject->isText())
1053 inlineBox = toLayoutText(m_layoutObject)->firstTextBox(); 1053 inlineBox = toLayoutText(m_layoutObject)->firstTextBox();
1054 else 1054 else
1055 return 0; 1055 return 0;
1056 1056
1057 AXObject* result = 0; 1057 AXObject* result = 0;
1058 for (InlineBox* prev = inlineBox->prevOnLine(); prev; prev = prev->prevOnLin e()) { 1058 for (InlineBox* prev = inlineBox->prevOnLine(); prev; prev = prev->prevOnLin e()) {
1059 LayoutObject* layoutObject = &prev->layoutObject(); 1059 LayoutObject* layoutObject = &prev->layoutObject();
1060 result = axObjectCache()->getOrCreate(layoutObject); 1060 result = axObjectCache().getOrCreate(layoutObject);
1061 if (result) 1061 if (result)
1062 break; 1062 break;
1063 } 1063 }
1064 1064
1065 // A static text node might span multiple lines. Try to return the last inli ne 1065 // A static text node might span multiple lines. Try to return the last inli ne
1066 // text box within that static text if possible. 1066 // text box within that static text if possible.
1067 if (result && result->roleValue() == StaticTextRole && result->children().si ze()) 1067 if (result && result->roleValue() == StaticTextRole && result->children().si ze())
1068 result = result->children()[result->children().size() - 1].get(); 1068 result = result->children()[result->children().size() - 1].get();
1069 1069
1070 return result; 1070 return result;
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
1180 return 0; 1180 return 0;
1181 1181
1182 const AtomicString& activeDescendantAttrStr = element->getAttribute(aria_act ivedescendantAttr); 1182 const AtomicString& activeDescendantAttrStr = element->getAttribute(aria_act ivedescendantAttr);
1183 if (activeDescendantAttrStr.isNull() || activeDescendantAttrStr.isEmpty()) 1183 if (activeDescendantAttrStr.isNull() || activeDescendantAttrStr.isEmpty())
1184 return 0; 1184 return 0;
1185 1185
1186 Element* target = element->treeScope().getElementById(activeDescendantAttrSt r); 1186 Element* target = element->treeScope().getElementById(activeDescendantAttrSt r);
1187 if (!target) 1187 if (!target)
1188 return 0; 1188 return 0;
1189 1189
1190 AXObject* obj = axObjectCache()->getOrCreate(target); 1190 AXObject* obj = axObjectCache().getOrCreate(target);
1191 1191
1192 // An activedescendant is only useful if it has a layoutObject, because that 's what's needed to post the notification. 1192 // An activedescendant is only useful if it has a layoutObject, because that 's what's needed to post the notification.
1193 if (obj && obj->isAXLayoutObject()) 1193 if (obj && obj->isAXLayoutObject())
1194 return obj; 1194 return obj;
1195 1195
1196 return 0; 1196 return 0;
1197 } 1197 }
1198 1198
1199 void AXLayoutObject::ariaFlowToElements(AccessibilityChildrenVector& flowTo) con st 1199 void AXLayoutObject::ariaFlowToElements(AccessibilityChildrenVector& flowTo) con st
1200 { 1200 {
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
1418 return summary; 1418 return summary;
1419 1419
1420 // The title attribute should be used as help text unless it is alre ady being used as descriptive text. 1420 // The title attribute should be used as help text unless it is alre ady being used as descriptive text.
1421 const AtomicString& title = toElement(curr->node())->getAttribute(ti tleAttr); 1421 const AtomicString& title = toElement(curr->node())->getAttribute(ti tleAttr);
1422 if (!title.isEmpty() && description != title) 1422 if (!title.isEmpty() && description != title)
1423 return title; 1423 return title;
1424 } 1424 }
1425 1425
1426 // Only take help text from an ancestor element if its a group or an unk nown role. If help was 1426 // Only take help text from an ancestor element if its a group or an unk nown role. If help was
1427 // added to those kinds of elements, it is likely it was meant for a chi ld element. 1427 // added to those kinds of elements, it is likely it was meant for a chi ld element.
1428 AXObject* axObj = axObjectCache()->getOrCreate(curr); 1428 AXObject* axObj = axObjectCache().getOrCreate(curr);
1429 if (axObj) { 1429 if (axObj) {
1430 AccessibilityRole role = axObj->roleValue(); 1430 AccessibilityRole role = axObj->roleValue();
1431 if (role != GroupRole && role != UnknownRole) 1431 if (role != GroupRole && role != UnknownRole)
1432 break; 1432 break;
1433 } 1433 }
1434 } 1434 }
1435 1435
1436 return String(); 1436 return String();
1437 } 1437 }
1438 1438
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1541 if (isHTMLAreaElement(node)) 1541 if (isHTMLAreaElement(node))
1542 return accessibilityImageMapHitTest(toHTMLAreaElement(node), point); 1542 return accessibilityImageMapHitTest(toHTMLAreaElement(node), point);
1543 1543
1544 if (isHTMLOptionElement(node)) 1544 if (isHTMLOptionElement(node))
1545 node = toHTMLOptionElement(*node).ownerSelectElement(); 1545 node = toHTMLOptionElement(*node).ownerSelectElement();
1546 1546
1547 LayoutObject* obj = node->layoutObject(); 1547 LayoutObject* obj = node->layoutObject();
1548 if (!obj) 1548 if (!obj)
1549 return 0; 1549 return 0;
1550 1550
1551 AXObject* result = axObjectCache()->getOrCreate(obj); 1551 AXObject* result = axObjectCache().getOrCreate(obj);
1552 result->updateChildrenIfNecessary(); 1552 result->updateChildrenIfNecessary();
1553 1553
1554 // Allow the element to perform any hit-testing it might need to do to reach non-layout children. 1554 // Allow the element to perform any hit-testing it might need to do to reach non-layout children.
1555 result = result->elementAccessibilityHitTest(point); 1555 result = result->elementAccessibilityHitTest(point);
1556 1556
1557 if (result && result->accessibilityIsIgnored()) { 1557 if (result && result->accessibilityIsIgnored()) {
1558 // If this element is the label of a control, a hit test should return t he control. 1558 // If this element is the label of a control, a hit test should return t he control.
1559 if (result->isAXLayoutObject()) { 1559 if (result->isAXLayoutObject()) {
1560 AXObject* controlObject = toAXLayoutObject(result)->correspondingCon trolForLabelElement(); 1560 AXObject* controlObject = toAXLayoutObject(result)->correspondingCon trolForLabelElement();
1561 if (controlObject && !controlObject->deprecatedExposesTitleUIElement ()) 1561 if (controlObject && !controlObject->deprecatedExposesTitleUIElement ())
(...skipping 17 matching lines...) Expand all
1579 // 1579 //
1580 // High-level accessibility tree access. 1580 // High-level accessibility tree access.
1581 // 1581 //
1582 1582
1583 AXObject* AXLayoutObject::computeParent() const 1583 AXObject* AXLayoutObject::computeParent() const
1584 { 1584 {
1585 if (!m_layoutObject) 1585 if (!m_layoutObject)
1586 return 0; 1586 return 0;
1587 1587
1588 if (ariaRoleAttribute() == MenuBarRole) 1588 if (ariaRoleAttribute() == MenuBarRole)
1589 return axObjectCache()->getOrCreate(m_layoutObject->parent()); 1589 return axObjectCache().getOrCreate(m_layoutObject->parent());
1590 1590
1591 // menuButton and its corresponding menu are DOM siblings, but Accessibility needs them to be parent/child 1591 // menuButton and its corresponding menu are DOM siblings, but Accessibility needs them to be parent/child
1592 if (ariaRoleAttribute() == MenuRole) { 1592 if (ariaRoleAttribute() == MenuRole) {
1593 AXObject* parent = menuButtonForMenu(); 1593 AXObject* parent = menuButtonForMenu();
1594 if (parent) 1594 if (parent)
1595 return parent; 1595 return parent;
1596 } 1596 }
1597 1597
1598 LayoutObject* parentObj = layoutParentObject(); 1598 LayoutObject* parentObj = layoutParentObject();
1599 if (parentObj) 1599 if (parentObj)
1600 return axObjectCache()->getOrCreate(parentObj); 1600 return axObjectCache().getOrCreate(parentObj);
1601 1601
1602 // WebArea's parent should be the scroll view containing it. 1602 // WebArea's parent should be the scroll view containing it.
1603 if (isWebArea()) 1603 if (isWebArea())
1604 return axObjectCache()->getOrCreate(m_layoutObject->frame()->view()); 1604 return axObjectCache().getOrCreate(m_layoutObject->frame()->view());
1605 1605
1606 return 0; 1606 return 0;
1607 } 1607 }
1608 1608
1609 AXObject* AXLayoutObject::computeParentIfExists() const 1609 AXObject* AXLayoutObject::computeParentIfExists() const
1610 { 1610 {
1611 if (!m_layoutObject) 1611 if (!m_layoutObject)
1612 return 0; 1612 return 0;
1613 1613
1614 if (ariaRoleAttribute() == MenuBarRole) 1614 if (ariaRoleAttribute() == MenuBarRole)
1615 return axObjectCache()->get(m_layoutObject->parent()); 1615 return axObjectCache().get(m_layoutObject->parent());
1616 1616
1617 // menuButton and its corresponding menu are DOM siblings, but Accessibility needs them to be parent/child 1617 // menuButton and its corresponding menu are DOM siblings, but Accessibility needs them to be parent/child
1618 if (ariaRoleAttribute() == MenuRole) { 1618 if (ariaRoleAttribute() == MenuRole) {
1619 AXObject* parent = menuButtonForMenu(); 1619 AXObject* parent = menuButtonForMenu();
1620 if (parent) 1620 if (parent)
1621 return parent; 1621 return parent;
1622 } 1622 }
1623 1623
1624 LayoutObject* parentObj = layoutParentObject(); 1624 LayoutObject* parentObj = layoutParentObject();
1625 if (parentObj) 1625 if (parentObj)
1626 return axObjectCache()->get(parentObj); 1626 return axObjectCache().get(parentObj);
1627 1627
1628 // WebArea's parent should be the scroll view containing it. 1628 // WebArea's parent should be the scroll view containing it.
1629 if (isWebArea()) 1629 if (isWebArea())
1630 return axObjectCache()->get(m_layoutObject->frame()->view()); 1630 return axObjectCache().get(m_layoutObject->frame()->view());
1631 1631
1632 return 0; 1632 return 0;
1633 } 1633 }
1634 1634
1635 // 1635 //
1636 // Low-level accessibility tree exploration, only for use within the accessibili ty module. 1636 // Low-level accessibility tree exploration, only for use within the accessibili ty module.
1637 // 1637 //
1638 1638
1639 AXObject* AXLayoutObject::firstChild() const 1639 AXObject* AXLayoutObject::firstChild() const
1640 { 1640 {
1641 if (!m_layoutObject) 1641 if (!m_layoutObject)
1642 return 0; 1642 return 0;
1643 1643
1644 LayoutObject* firstChild = firstChildConsideringContinuation(m_layoutObject) ; 1644 LayoutObject* firstChild = firstChildConsideringContinuation(m_layoutObject) ;
1645 1645
1646 if (!firstChild) 1646 if (!firstChild)
1647 return 0; 1647 return 0;
1648 1648
1649 return axObjectCache()->getOrCreate(firstChild); 1649 return axObjectCache().getOrCreate(firstChild);
1650 } 1650 }
1651 1651
1652 AXObject* AXLayoutObject::nextSibling() const 1652 AXObject* AXLayoutObject::nextSibling() const
1653 { 1653 {
1654 if (!m_layoutObject) 1654 if (!m_layoutObject)
1655 return 0; 1655 return 0;
1656 1656
1657 LayoutObject* nextSibling = 0; 1657 LayoutObject* nextSibling = 0;
1658 1658
1659 LayoutInline* inlineContinuation = m_layoutObject->isLayoutBlock() ? toLayou tBlock(m_layoutObject)->inlineElementContinuation() : 0; 1659 LayoutInline* inlineContinuation = m_layoutObject->isLayoutBlock() ? toLayou tBlock(m_layoutObject)->inlineElementContinuation() : 0;
(...skipping 23 matching lines...) Expand all
1683 nextSibling = continuation; 1683 nextSibling = continuation;
1684 } else { 1684 } else {
1685 // Case 5b: continuation is an inline - in this case the inline's fi rst child is the next sibling. 1685 // Case 5b: continuation is an inline - in this case the inline's fi rst child is the next sibling.
1686 nextSibling = firstChildConsideringContinuation(continuation); 1686 nextSibling = firstChildConsideringContinuation(continuation);
1687 } 1687 }
1688 } 1688 }
1689 1689
1690 if (!nextSibling) 1690 if (!nextSibling)
1691 return 0; 1691 return 0;
1692 1692
1693 return axObjectCache()->getOrCreate(nextSibling); 1693 return axObjectCache().getOrCreate(nextSibling);
1694 } 1694 }
1695 1695
1696 void AXLayoutObject::addChildren() 1696 void AXLayoutObject::addChildren()
1697 { 1697 {
1698 // If the need to add more children in addition to existing children arises, 1698 // If the need to add more children in addition to existing children arises,
1699 // childrenChanged should have been called, leaving the object with no child ren. 1699 // childrenChanged should have been called, leaving the object with no child ren.
1700 ASSERT(!m_haveChildren); 1700 ASSERT(!m_haveChildren);
1701 1701
1702 m_haveChildren = true; 1702 m_haveChildren = true;
1703 1703
1704 if (!canHaveChildren()) 1704 if (!canHaveChildren())
1705 return; 1705 return;
1706 1706
1707 Vector<AXObject*> ownedChildren; 1707 Vector<AXObject*> ownedChildren;
1708 computeAriaOwnsChildren(ownedChildren); 1708 computeAriaOwnsChildren(ownedChildren);
1709 1709
1710 for (RefPtr<AXObject> obj = firstChild(); obj; obj = obj->nextSibling()) { 1710 for (RefPtr<AXObject> obj = firstChild(); obj; obj = obj->nextSibling()) {
1711 if (!axObjectCache()->isAriaOwned(obj.get())) 1711 if (!axObjectCache().isAriaOwned(obj.get()))
1712 addChild(obj.get()); 1712 addChild(obj.get());
1713 } 1713 }
1714 1714
1715 addHiddenChildren(); 1715 addHiddenChildren();
1716 addAttachmentChildren(); 1716 addAttachmentChildren();
1717 addPopupChildren(); 1717 addPopupChildren();
1718 addImageMapChildren(); 1718 addImageMapChildren();
1719 addTextFieldChildren(); 1719 addTextFieldChildren();
1720 addCanvasChildren(); 1720 addCanvasChildren();
1721 addRemoteSVGChildren(); 1721 addRemoteSVGChildren();
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1792 1792
1793 // this is the LayoutObject's Document's LocalFrame's FrameView 1793 // this is the LayoutObject's Document's LocalFrame's FrameView
1794 return m_layoutObject->document().view(); 1794 return m_layoutObject->document().view();
1795 } 1795 }
1796 1796
1797 Element* AXLayoutObject::anchorElement() const 1797 Element* AXLayoutObject::anchorElement() const
1798 { 1798 {
1799 if (!m_layoutObject) 1799 if (!m_layoutObject)
1800 return 0; 1800 return 0;
1801 1801
1802 AXObjectCacheImpl* cache = axObjectCache(); 1802 AXObjectCacheImpl& cache = axObjectCache();
1803 LayoutObject* currLayoutObject; 1803 LayoutObject* currLayoutObject;
1804 1804
1805 // Search up the layout tree for a LayoutObject with a DOM node. Defer to an earlier continuation, though. 1805 // Search up the layout tree for a LayoutObject with a DOM node. Defer to an earlier continuation, though.
1806 for (currLayoutObject = m_layoutObject; currLayoutObject && !currLayoutObjec t->node(); currLayoutObject = currLayoutObject->parent()) { 1806 for (currLayoutObject = m_layoutObject; currLayoutObject && !currLayoutObjec t->node(); currLayoutObject = currLayoutObject->parent()) {
1807 if (currLayoutObject->isAnonymousBlock()) { 1807 if (currLayoutObject->isAnonymousBlock()) {
1808 LayoutObject* continuation = toLayoutBlock(currLayoutObject)->contin uation(); 1808 LayoutObject* continuation = toLayoutBlock(currLayoutObject)->contin uation();
1809 if (continuation) 1809 if (continuation)
1810 return cache->getOrCreate(continuation)->anchorElement(); 1810 return cache.getOrCreate(continuation)->anchorElement();
1811 } 1811 }
1812 } 1812 }
1813 1813
1814 // bail if none found 1814 // bail if none found
1815 if (!currLayoutObject) 1815 if (!currLayoutObject)
1816 return 0; 1816 return 0;
1817 1817
1818 // search up the DOM tree for an anchor element 1818 // search up the DOM tree for an anchor element
1819 // NOTE: this assumes that any non-image with an anchor is an HTMLAnchorElem ent 1819 // NOTE: this assumes that any non-image with an anchor is an HTMLAnchorElem ent
1820 Node* node = currLayoutObject->node(); 1820 Node* node = currLayoutObject->node();
1821 for ( ; node; node = node->parentNode()) { 1821 for ( ; node; node = node->parentNode()) {
1822 if (isHTMLAnchorElement(*node) || (node->layoutObject() && cache->getOrC reate(node->layoutObject())->isAnchor())) 1822 if (isHTMLAnchorElement(*node) || (node->layoutObject() && cache.getOrCr eate(node->layoutObject())->isAnchor()))
1823 return toElement(node); 1823 return toElement(node);
1824 } 1824 }
1825 1825
1826 return 0; 1826 return 0;
1827 } 1827 }
1828 1828
1829 Widget* AXLayoutObject::widgetForAttachmentView() const 1829 Widget* AXLayoutObject::widgetForAttachmentView() const
1830 { 1830 {
1831 if (!isAttachment()) 1831 if (!isAttachment())
1832 return 0; 1832 return 0;
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
1927 } 1927 }
1928 1928
1929 if (foundParent) 1929 if (foundParent)
1930 break; 1930 break;
1931 1931
1932 containerParent = containerParent->parentObject(); 1932 containerParent = containerParent->parentObject();
1933 } 1933 }
1934 1934
1935 // Post that the row count changed. 1935 // Post that the row count changed.
1936 if (containerParent) 1936 if (containerParent)
1937 axObjectCache()->postNotification(containerParent, AXObjectCacheImpl::AX RowCountChanged); 1937 axObjectCache().postNotification(containerParent, AXObjectCacheImpl::AXR owCountChanged);
1938 1938
1939 // Post that the specific row either collapsed or expanded. 1939 // Post that the specific row either collapsed or expanded.
1940 AccessibilityExpanded expanded = isExpanded(); 1940 AccessibilityExpanded expanded = isExpanded();
1941 if (!expanded) 1941 if (!expanded)
1942 return; 1942 return;
1943 1943
1944 if (roleValue() == RowRole || roleValue() == TreeItemRole) { 1944 if (roleValue() == RowRole || roleValue() == TreeItemRole) {
1945 AXObjectCacheImpl::AXNotification notification = AXObjectCacheImpl::AXRo wExpanded; 1945 AXObjectCacheImpl::AXNotification notification = AXObjectCacheImpl::AXRo wExpanded;
1946 if (expanded == ExpandedCollapsed) 1946 if (expanded == ExpandedCollapsed)
1947 notification = AXObjectCacheImpl::AXRowCollapsed; 1947 notification = AXObjectCacheImpl::AXRowCollapsed;
1948 1948
1949 axObjectCache()->postNotification(this, notification); 1949 axObjectCache().postNotification(this, notification);
1950 } 1950 }
1951 } 1951 }
1952 1952
1953 void AXLayoutObject::textChanged() 1953 void AXLayoutObject::textChanged()
1954 { 1954 {
1955 if (!m_layoutObject) 1955 if (!m_layoutObject)
1956 return; 1956 return;
1957 1957
1958 Settings* settings = document()->settings(); 1958 Settings* settings = document()->settings();
1959 if (settings && settings->inlineTextBoxAccessibilityEnabled() && roleValue() == StaticTextRole) 1959 if (settings && settings->inlineTextBoxAccessibilityEnabled() && roleValue() == StaticTextRole)
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
2046 2046
2047 if (layoutObject()->needsLayout()) { 2047 if (layoutObject()->needsLayout()) {
2048 // If a LayoutText needs layout, its inline text boxes are either 2048 // If a LayoutText needs layout, its inline text boxes are either
2049 // nonexistent or invalid, so defer until the layout happens and 2049 // nonexistent or invalid, so defer until the layout happens and
2050 // the layoutObject calls AXObjectCacheImpl::inlineTextBoxesUpdated. 2050 // the layoutObject calls AXObjectCacheImpl::inlineTextBoxesUpdated.
2051 return; 2051 return;
2052 } 2052 }
2053 2053
2054 LayoutText* layoutText = toLayoutText(layoutObject()); 2054 LayoutText* layoutText = toLayoutText(layoutObject());
2055 for (RefPtr<AbstractInlineTextBox> box = layoutText->firstAbstractInlineText Box(); box.get(); box = box->nextInlineTextBox()) { 2055 for (RefPtr<AbstractInlineTextBox> box = layoutText->firstAbstractInlineText Box(); box.get(); box = box->nextInlineTextBox()) {
2056 AXObject* axObject = axObjectCache()->getOrCreate(box.get()); 2056 AXObject* axObject = axObjectCache().getOrCreate(box.get());
2057 if (!axObject->accessibilityIsIgnored()) 2057 if (!axObject->accessibilityIsIgnored())
2058 m_children.append(axObject); 2058 m_children.append(axObject);
2059 } 2059 }
2060 } 2060 }
2061 2061
2062 void AXLayoutObject::lineBreaks(Vector<int>& lineBreaks) const 2062 void AXLayoutObject::lineBreaks(Vector<int>& lineBreaks) const
2063 { 2063 {
2064 if (!isTextControl()) 2064 if (!isTextControl())
2065 return; 2065 return;
2066 2066
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
2131 int end = indexForVisiblePosition(visibleSelection.visibleEnd()); 2131 int end = indexForVisiblePosition(visibleSelection.visibleEnd());
2132 2132
2133 return PlainTextRange(start, end - start); 2133 return PlainTextRange(start, end - start);
2134 } 2134 }
2135 2135
2136 bool AXLayoutObject::nodeIsTextControl(const Node* node) const 2136 bool AXLayoutObject::nodeIsTextControl(const Node* node) const
2137 { 2137 {
2138 if (!node) 2138 if (!node)
2139 return false; 2139 return false;
2140 2140
2141 const AXObject* axObjectForNode = axObjectCache()->getOrCreate(const_cast<No de*>(node)); 2141 const AXObject* axObjectForNode = axObjectCache().getOrCreate(const_cast<Nod e*>(node));
2142 if (!axObjectForNode) 2142 if (!axObjectForNode)
2143 return false; 2143 return false;
2144 2144
2145 return axObjectForNode->isTextControl(); 2145 return axObjectForNode->isTextControl();
2146 } 2146 }
2147 2147
2148 bool AXLayoutObject::isTabItemSelected() const 2148 bool AXLayoutObject::isTabItemSelected() const
2149 { 2149 {
2150 if (!isTabItem() || !m_layoutObject) 2150 if (!isTabItem() || !m_layoutObject)
2151 return false; 2151 return false;
2152 2152
2153 Node* node = m_layoutObject->node(); 2153 Node* node = m_layoutObject->node();
2154 if (!node || !node->isElementNode()) 2154 if (!node || !node->isElementNode())
2155 return false; 2155 return false;
2156 2156
2157 // The ARIA spec says a tab item can also be selected if it is aria-labeled by a tabpanel 2157 // The ARIA spec says a tab item can also be selected if it is aria-labeled by a tabpanel
2158 // that has keyboard focus inside of it, or if a tabpanel in its aria-contro ls list has KB 2158 // that has keyboard focus inside of it, or if a tabpanel in its aria-contro ls list has KB
2159 // focus inside of it. 2159 // focus inside of it.
2160 AXObject* focusedElement = focusedUIElement(); 2160 AXObject* focusedElement = focusedUIElement();
2161 if (!focusedElement) 2161 if (!focusedElement)
2162 return false; 2162 return false;
2163 2163
2164 WillBeHeapVector<RawPtrWillBeMember<Element>> elements; 2164 WillBeHeapVector<RawPtrWillBeMember<Element>> elements;
2165 elementsFromAttribute(elements, aria_controlsAttr); 2165 elementsFromAttribute(elements, aria_controlsAttr);
2166 2166
2167 for (const auto& element : elements) { 2167 for (const auto& element : elements) {
2168 AXObject* tabPanel = axObjectCache()->getOrCreate(element); 2168 AXObject* tabPanel = axObjectCache().getOrCreate(element);
2169 2169
2170 // A tab item should only control tab panels. 2170 // A tab item should only control tab panels.
2171 if (!tabPanel || tabPanel->roleValue() != TabPanelRole) 2171 if (!tabPanel || tabPanel->roleValue() != TabPanelRole)
2172 continue; 2172 continue;
2173 2173
2174 AXObject* checkFocusElement = focusedElement; 2174 AXObject* checkFocusElement = focusedElement;
2175 // Check if the focused element is a descendant of the element controlle d by the tab item. 2175 // Check if the focused element is a descendant of the element controlle d by the tab item.
2176 while (checkFocusElement) { 2176 while (checkFocusElement) {
2177 if (tabPanel == checkFocusElement) 2177 if (tabPanel == checkFocusElement)
2178 return true; 2178 return true;
2179 checkFocusElement = checkFocusElement->parentObject(); 2179 checkFocusElement = checkFocusElement->parentObject();
2180 } 2180 }
2181 } 2181 }
2182 2182
2183 return false; 2183 return false;
2184 } 2184 }
2185 2185
2186 AXObject* AXLayoutObject::accessibilityImageMapHitTest(HTMLAreaElement* area, co nst IntPoint& point) const 2186 AXObject* AXLayoutObject::accessibilityImageMapHitTest(HTMLAreaElement* area, co nst IntPoint& point) const
2187 { 2187 {
2188 if (!area) 2188 if (!area)
2189 return 0; 2189 return 0;
2190 2190
2191 AXObject* parent = axObjectCache()->getOrCreate(area->imageElement()); 2191 AXObject* parent = axObjectCache().getOrCreate(area->imageElement());
2192 if (!parent) 2192 if (!parent)
2193 return 0; 2193 return 0;
2194 2194
2195 for (const auto& child : parent->children()) { 2195 for (const auto& child : parent->children()) {
2196 if (child->elementRect().contains(point)) 2196 if (child->elementRect().contains(point))
2197 return child.get(); 2197 return child.get();
2198 } 2198 }
2199 2199
2200 return 0; 2200 return 0;
2201 } 2201 }
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
2303 2303
2304 if (!shouldInsertHiddenNodes) 2304 if (!shouldInsertHiddenNodes)
2305 return; 2305 return;
2306 2306
2307 // Iterate through all of the children, including those that may have alread y been added, and 2307 // Iterate through all of the children, including those that may have alread y been added, and
2308 // try to insert hidden nodes in the correct place in the DOM order. 2308 // try to insert hidden nodes in the correct place in the DOM order.
2309 unsigned insertionIndex = 0; 2309 unsigned insertionIndex = 0;
2310 for (Node& child : NodeTraversal::childrenOf(*node)) { 2310 for (Node& child : NodeTraversal::childrenOf(*node)) {
2311 if (child.layoutObject()) { 2311 if (child.layoutObject()) {
2312 // Find out where the last layout sibling is located within m_childr en. 2312 // Find out where the last layout sibling is located within m_childr en.
2313 if (AXObject* childObject = axObjectCache()->get(child.layoutObject( ))) { 2313 if (AXObject* childObject = axObjectCache().get(child.layoutObject() )) {
2314 if (childObject->accessibilityIsIgnored()) { 2314 if (childObject->accessibilityIsIgnored()) {
2315 const auto& children = childObject->children(); 2315 const auto& children = childObject->children();
2316 childObject = children.size() ? children.last().get() : 0; 2316 childObject = children.size() ? children.last().get() : 0;
2317 } 2317 }
2318 if (childObject) 2318 if (childObject)
2319 insertionIndex = m_children.find(childObject) + 1; 2319 insertionIndex = m_children.find(childObject) + 1;
2320 continue; 2320 continue;
2321 } 2321 }
2322 } 2322 }
2323 2323
2324 if (!isNodeAriaVisible(&child)) 2324 if (!isNodeAriaVisible(&child))
2325 continue; 2325 continue;
2326 2326
2327 unsigned previousSize = m_children.size(); 2327 unsigned previousSize = m_children.size();
2328 if (insertionIndex > previousSize) 2328 if (insertionIndex > previousSize)
2329 insertionIndex = previousSize; 2329 insertionIndex = previousSize;
2330 2330
2331 insertChild(axObjectCache()->getOrCreate(&child), insertionIndex); 2331 insertChild(axObjectCache().getOrCreate(&child), insertionIndex);
2332 insertionIndex += (m_children.size() - previousSize); 2332 insertionIndex += (m_children.size() - previousSize);
2333 } 2333 }
2334 } 2334 }
2335 2335
2336 void AXLayoutObject::addTextFieldChildren() 2336 void AXLayoutObject::addTextFieldChildren()
2337 { 2337 {
2338 Node* node = this->node(); 2338 Node* node = this->node();
2339 if (!isHTMLInputElement(node)) 2339 if (!isHTMLInputElement(node))
2340 return; 2340 return;
2341 2341
2342 HTMLInputElement& input = toHTMLInputElement(*node); 2342 HTMLInputElement& input = toHTMLInputElement(*node);
2343 Element* spinButtonElement = input.userAgentShadowRoot()->getElementById(Sha dowElementNames::spinButton()); 2343 Element* spinButtonElement = input.userAgentShadowRoot()->getElementById(Sha dowElementNames::spinButton());
2344 if (!spinButtonElement || !spinButtonElement->isSpinButtonElement()) 2344 if (!spinButtonElement || !spinButtonElement->isSpinButtonElement())
2345 return; 2345 return;
2346 2346
2347 AXSpinButton* axSpinButton = toAXSpinButton(axObjectCache()->getOrCreate(Spi nButtonRole)); 2347 AXSpinButton* axSpinButton = toAXSpinButton(axObjectCache().getOrCreate(Spin ButtonRole));
2348 axSpinButton->setSpinButtonElement(toSpinButtonElement(spinButtonElement)); 2348 axSpinButton->setSpinButtonElement(toSpinButtonElement(spinButtonElement));
2349 axSpinButton->setParent(this); 2349 axSpinButton->setParent(this);
2350 m_children.append(axSpinButton); 2350 m_children.append(axSpinButton);
2351 } 2351 }
2352 2352
2353 void AXLayoutObject::addImageMapChildren() 2353 void AXLayoutObject::addImageMapChildren()
2354 { 2354 {
2355 LayoutBoxModelObject* cssBox = layoutBoxModelObject(); 2355 LayoutBoxModelObject* cssBox = layoutBoxModelObject();
2356 if (!cssBox || !cssBox->isLayoutImage()) 2356 if (!cssBox || !cssBox->isLayoutImage())
2357 return; 2357 return;
2358 2358
2359 HTMLMapElement* map = toLayoutImage(cssBox)->imageMap(); 2359 HTMLMapElement* map = toLayoutImage(cssBox)->imageMap();
2360 if (!map) 2360 if (!map)
2361 return; 2361 return;
2362 2362
2363 for (HTMLAreaElement& area : Traversal<HTMLAreaElement>::descendantsOf(*map) ) { 2363 for (HTMLAreaElement& area : Traversal<HTMLAreaElement>::descendantsOf(*map) ) {
2364 // add an <area> element for this child if it has a link 2364 // add an <area> element for this child if it has a link
2365 if (area.isLink()) { 2365 if (area.isLink()) {
2366 AXImageMapLink* areaObject = toAXImageMapLink(axObjectCache()->getOr Create(ImageMapLinkRole)); 2366 AXImageMapLink* areaObject = toAXImageMapLink(axObjectCache().getOrC reate(ImageMapLinkRole));
2367 areaObject->setHTMLAreaElement(&area); 2367 areaObject->setHTMLAreaElement(&area);
2368 areaObject->setHTMLMapElement(map); 2368 areaObject->setHTMLMapElement(map);
2369 areaObject->setParent(this); 2369 areaObject->setParent(this);
2370 if (!areaObject->accessibilityIsIgnored()) 2370 if (!areaObject->accessibilityIsIgnored())
2371 m_children.append(areaObject); 2371 m_children.append(areaObject);
2372 else 2372 else
2373 axObjectCache()->remove(areaObject->axObjectID()); 2373 axObjectCache().remove(areaObject->axObjectID());
2374 } 2374 }
2375 } 2375 }
2376 } 2376 }
2377 2377
2378 void AXLayoutObject::addCanvasChildren() 2378 void AXLayoutObject::addCanvasChildren()
2379 { 2379 {
2380 if (!isHTMLCanvasElement(node())) 2380 if (!isHTMLCanvasElement(node()))
2381 return; 2381 return;
2382 2382
2383 // If it's a canvas, it won't have laid out children, but it might have acce ssible fallback content. 2383 // If it's a canvas, it won't have laid out children, but it might have acce ssible fallback content.
2384 // Clear m_haveChildren because AXNodeObject::addChildren will expect it to be false. 2384 // Clear m_haveChildren because AXNodeObject::addChildren will expect it to be false.
2385 ASSERT(!m_children.size()); 2385 ASSERT(!m_children.size());
2386 m_haveChildren = false; 2386 m_haveChildren = false;
2387 AXNodeObject::addChildren(); 2387 AXNodeObject::addChildren();
2388 } 2388 }
2389 2389
2390 void AXLayoutObject::addAttachmentChildren() 2390 void AXLayoutObject::addAttachmentChildren()
2391 { 2391 {
2392 if (!isAttachment()) 2392 if (!isAttachment())
2393 return; 2393 return;
2394 2394
2395 // FrameView's need to be inserted into the AX hierarchy when encountered. 2395 // FrameView's need to be inserted into the AX hierarchy when encountered.
2396 Widget* widget = widgetForAttachmentView(); 2396 Widget* widget = widgetForAttachmentView();
2397 if (!widget || !widget->isFrameView()) 2397 if (!widget || !widget->isFrameView())
2398 return; 2398 return;
2399 2399
2400 AXObject* axWidget = axObjectCache()->getOrCreate(widget); 2400 AXObject* axWidget = axObjectCache().getOrCreate(widget);
2401 if (!axWidget->accessibilityIsIgnored()) 2401 if (!axWidget->accessibilityIsIgnored())
2402 m_children.append(axWidget); 2402 m_children.append(axWidget);
2403 } 2403 }
2404 2404
2405 void AXLayoutObject::addPopupChildren() 2405 void AXLayoutObject::addPopupChildren()
2406 { 2406 {
2407 if (!isHTMLInputElement(node())) 2407 if (!isHTMLInputElement(node()))
2408 return; 2408 return;
2409 if (AXObject* axPopup = toHTMLInputElement(node())->popupRootAXObject()) 2409 if (AXObject* axPopup = toHTMLInputElement(node())->popupRootAXObject())
2410 m_children.append(axPopup); 2410 m_children.append(axPopup);
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
2486 result = LayoutRect(obj->absoluteBoundingBoxRect()); 2486 result = LayoutRect(obj->absoluteBoundingBoxRect());
2487 } else { 2487 } else {
2488 result = LayoutRect(obj->absoluteFocusRingBoundingBoxRect()); 2488 result = LayoutRect(obj->absoluteFocusRingBoundingBoxRect());
2489 } 2489 }
2490 2490
2491 Document* document = this->document(); 2491 Document* document = this->document();
2492 if (document && document->isSVGDocument()) 2492 if (document && document->isSVGDocument())
2493 offsetBoundingBoxForRemoteSVGElement(result); 2493 offsetBoundingBoxForRemoteSVGElement(result);
2494 if (document && document->frame() && document->frame()->pagePopupOwner()) { 2494 if (document && document->frame() && document->frame()->pagePopupOwner()) {
2495 IntPoint popupOrigin = document->view()->contentsToScreen(IntRect()).loc ation(); 2495 IntPoint popupOrigin = document->view()->contentsToScreen(IntRect()).loc ation();
2496 IntPoint mainOrigin = axObjectCache()->rootObject()->documentFrameView() ->contentsToScreen(IntRect()).location(); 2496 IntPoint mainOrigin = axObjectCache().rootObject()->documentFrameView()- >contentsToScreen(IntRect()).location();
2497 result.moveBy(IntPoint(popupOrigin - mainOrigin)); 2497 result.moveBy(IntPoint(popupOrigin - mainOrigin));
2498 } 2498 }
2499 2499
2500 // The size of the web area should be the content size, not the clipped size . 2500 // The size of the web area should be the content size, not the clipped size .
2501 if (isWebArea() && obj->frame()->view()) 2501 if (isWebArea() && obj->frame()->view())
2502 result.setSize(LayoutSize(obj->frame()->view()->contentsSize())); 2502 result.setSize(LayoutSize(obj->frame()->view()->contentsSize()));
2503 2503
2504 // Checkboxes and radio buttons include their label as part of their rect. 2504 // Checkboxes and radio buttons include their label as part of their rect.
2505 if (isCheckboxOrRadio()) { 2505 if (isCheckboxOrRadio()) {
2506 HTMLLabelElement* label = labelForElement(toElement(m_layoutObject->node ())); 2506 HTMLLabelElement* label = labelForElement(toElement(m_layoutObject->node ()));
2507 if (label && label->layoutObject()) { 2507 if (label && label->layoutObject()) {
2508 LayoutRect labelRect = axObjectCache()->getOrCreate(label)->elementR ect(); 2508 LayoutRect labelRect = axObjectCache().getOrCreate(label)->elementRe ct();
2509 result.unite(labelRect); 2509 result.unite(labelRect);
2510 } 2510 }
2511 } 2511 }
2512 2512
2513 return result; 2513 return result;
2514 } 2514 }
2515 2515
2516 } // namespace blink 2516 } // namespace blink
OLDNEW
« no previous file with comments | « Source/modules/accessibility/AXLayoutObject.h ('k') | Source/modules/accessibility/AXList.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698