| OLD | NEW |
| 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 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 211 toAXLayoutObject(obj)->checkCachedElementRect(); | 211 toAXLayoutObject(obj)->checkCachedElementRect(); |
| 212 } | 212 } |
| 213 for (const AXObject* obj = this; obj; obj = obj->parentObject()) { | 213 for (const AXObject* obj = this; obj; obj = obj->parentObject()) { |
| 214 if (obj->isAXLayoutObject()) | 214 if (obj->isAXLayoutObject()) |
| 215 toAXLayoutObject(obj)->updateCachedElementRect(); | 215 toAXLayoutObject(obj)->updateCachedElementRect(); |
| 216 } | 216 } |
| 217 | 217 |
| 218 return m_cachedElementRect; | 218 return m_cachedElementRect; |
| 219 } | 219 } |
| 220 | 220 |
| 221 LayoutBoxModelObject* AXLayoutObject::layoutBoxModelObject() const | 221 LayoutBoxModelObject* AXLayoutObject::getLayoutBoxModelObject() const |
| 222 { | 222 { |
| 223 if (!m_layoutObject || !m_layoutObject->isBoxModelObject()) | 223 if (!m_layoutObject || !m_layoutObject->isBoxModelObject()) |
| 224 return 0; | 224 return 0; |
| 225 return toLayoutBoxModelObject(m_layoutObject); | 225 return toLayoutBoxModelObject(m_layoutObject); |
| 226 } | 226 } |
| 227 | 227 |
| 228 bool AXLayoutObject::shouldNotifyActiveDescendant() const | 228 bool AXLayoutObject::shouldNotifyActiveDescendant() const |
| 229 { | 229 { |
| 230 // We want to notify that the combo box has changed its active descendant, | 230 // We want to notify that the combo box has changed its active descendant, |
| 231 // but we do not want to change the focus, because focus should remain with
the combo box. | 231 // but we do not want to change the focus, because focus should remain with
the combo box. |
| (...skipping 25 matching lines...) Expand all Loading... |
| 257 if (isHTMLImageElement(node)) | 257 if (isHTMLImageElement(node)) |
| 258 return true; | 258 return true; |
| 259 if (isHTMLInputElement(node) && toHTMLInputElement(node)->hasFallbackContent
()) | 259 if (isHTMLInputElement(node) && toHTMLInputElement(node)->hasFallbackContent
()) |
| 260 return true; | 260 return true; |
| 261 return false; | 261 return false; |
| 262 } | 262 } |
| 263 | 263 |
| 264 AccessibilityRole AXLayoutObject::nativeAccessibilityRoleIgnoringAria() const | 264 AccessibilityRole AXLayoutObject::nativeAccessibilityRoleIgnoringAria() const |
| 265 { | 265 { |
| 266 Node* node = m_layoutObject->node(); | 266 Node* node = m_layoutObject->node(); |
| 267 LayoutBoxModelObject* cssBox = layoutBoxModelObject(); | 267 LayoutBoxModelObject* cssBox = getLayoutBoxModelObject(); |
| 268 | 268 |
| 269 if ((cssBox && cssBox->isListItem()) || isHTMLLIElement(node)) | 269 if ((cssBox && cssBox->isListItem()) || isHTMLLIElement(node)) |
| 270 return ListItemRole; | 270 return ListItemRole; |
| 271 if (m_layoutObject->isListMarker()) | 271 if (m_layoutObject->isListMarker()) |
| 272 return ListMarkerRole; | 272 return ListMarkerRole; |
| 273 if (m_layoutObject->isBR()) | 273 if (m_layoutObject->isBR()) |
| 274 return LineBreakRole; | 274 return LineBreakRole; |
| 275 if (m_layoutObject->isText()) | 275 if (m_layoutObject->isText()) |
| 276 return StaticTextRole; | 276 return StaticTextRole; |
| 277 if (cssBox && isImageOrAltText(cssBox, node)) { | 277 if (cssBox && isImageOrAltText(cssBox, node)) { |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 344 #endif | 344 #endif |
| 345 m_layoutObject = 0; | 345 m_layoutObject = 0; |
| 346 } | 346 } |
| 347 | 347 |
| 348 // | 348 // |
| 349 // Check object role or purpose. | 349 // Check object role or purpose. |
| 350 // | 350 // |
| 351 | 351 |
| 352 static bool isLinkable(const AXObject& object) | 352 static bool isLinkable(const AXObject& object) |
| 353 { | 353 { |
| 354 if (!object.layoutObject()) | 354 if (!object.getLayoutObject()) |
| 355 return false; | 355 return false; |
| 356 | 356 |
| 357 // See https://wiki.mozilla.org/Accessibility/AT-Windows-API for the element
s | 357 // See https://wiki.mozilla.org/Accessibility/AT-Windows-API for the element
s |
| 358 // Mozilla considers linkable. | 358 // Mozilla considers linkable. |
| 359 return object.isLink() || object.isImage() || object.layoutObject()->isText(
); | 359 return object.isLink() || object.isImage() || object.getLayoutObject()->isTe
xt(); |
| 360 } | 360 } |
| 361 | 361 |
| 362 // Requires layoutObject to be present because it relies on style | 362 // Requires layoutObject to be present because it relies on style |
| 363 // user-modify. Don't move this logic to AXNodeObject. | 363 // user-modify. Don't move this logic to AXNodeObject. |
| 364 bool AXLayoutObject::isEditable() const | 364 bool AXLayoutObject::isEditable() const |
| 365 { | 365 { |
| 366 if (layoutObject() && layoutObject()->isTextControl()) | 366 if (getLayoutObject() && getLayoutObject()->isTextControl()) |
| 367 return true; | 367 return true; |
| 368 | 368 |
| 369 if (node() && node()->isContentEditable()) | 369 if (getNode() && getNode()->isContentEditable()) |
| 370 return true; | 370 return true; |
| 371 | 371 |
| 372 if (isWebArea()) { | 372 if (isWebArea()) { |
| 373 Document& document = layoutObject()->document(); | 373 Document& document = getLayoutObject()->document(); |
| 374 HTMLElement* body = document.body(); | 374 HTMLElement* body = document.body(); |
| 375 if (body && body->isContentEditable()) | 375 if (body && body->isContentEditable()) |
| 376 return true; | 376 return true; |
| 377 | 377 |
| 378 return document.isContentEditable(); | 378 return document.isContentEditable(); |
| 379 } | 379 } |
| 380 | 380 |
| 381 return AXNodeObject::isEditable(); | 381 return AXNodeObject::isEditable(); |
| 382 } | 382 } |
| 383 | 383 |
| 384 // Requires layoutObject to be present because it relies on style | 384 // Requires layoutObject to be present because it relies on style |
| 385 // user-modify. Don't move this logic to AXNodeObject. | 385 // user-modify. Don't move this logic to AXNodeObject. |
| 386 bool AXLayoutObject::isRichlyEditable() const | 386 bool AXLayoutObject::isRichlyEditable() const |
| 387 { | 387 { |
| 388 if (isARIATextControl()) | 388 if (isARIATextControl()) |
| 389 return false; | 389 return false; |
| 390 | 390 |
| 391 if (node() && node()->isContentRichlyEditable()) | 391 if (getNode() && getNode()->isContentRichlyEditable()) |
| 392 return true; | 392 return true; |
| 393 | 393 |
| 394 if (isWebArea()) { | 394 if (isWebArea()) { |
| 395 Document& document = m_layoutObject->document(); | 395 Document& document = m_layoutObject->document(); |
| 396 HTMLElement* body = document.body(); | 396 HTMLElement* body = document.body(); |
| 397 if (body && body->isContentRichlyEditable()) | 397 if (body && body->isContentRichlyEditable()) |
| 398 return true; | 398 return true; |
| 399 | 399 |
| 400 return document.isContentRichlyEditable(); | 400 return document.isContentRichlyEditable(); |
| 401 } | 401 } |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 574 // that. We don't want to ignore those. | 574 // that. We don't want to ignore those. |
| 575 if (m_layoutObject->isLayoutPart()) | 575 if (m_layoutObject->isLayoutPart()) |
| 576 return false; | 576 return false; |
| 577 | 577 |
| 578 // find out if this element is inside of a label element. | 578 // find out if this element is inside of a label element. |
| 579 // if so, it may be ignored because it's the label for a checkbox or radio b
utton | 579 // if so, it may be ignored because it's the label for a checkbox or radio b
utton |
| 580 AXObject* controlObject = correspondingControlForLabelElement(); | 580 AXObject* controlObject = correspondingControlForLabelElement(); |
| 581 if (controlObject && controlObject->isCheckboxOrRadio() && controlObject->na
meFromLabelElement()) { | 581 if (controlObject && controlObject->isCheckboxOrRadio() && controlObject->na
meFromLabelElement()) { |
| 582 if (ignoredReasons) { | 582 if (ignoredReasons) { |
| 583 HTMLLabelElement* label = labelElementContainer(); | 583 HTMLLabelElement* label = labelElementContainer(); |
| 584 if (label && label != node()) { | 584 if (label && label != getNode()) { |
| 585 AXObject* labelAXObject = axObjectCache().getOrCreate(label); | 585 AXObject* labelAXObject = axObjectCache().getOrCreate(label); |
| 586 ignoredReasons->append(IgnoredReason(AXLabelContainer, labelAXOb
ject)); | 586 ignoredReasons->append(IgnoredReason(AXLabelContainer, labelAXOb
ject)); |
| 587 } | 587 } |
| 588 | 588 |
| 589 ignoredReasons->append(IgnoredReason(AXLabelFor, controlObject)); | 589 ignoredReasons->append(IgnoredReason(AXLabelFor, controlObject)); |
| 590 } | 590 } |
| 591 return true; | 591 return true; |
| 592 } | 592 } |
| 593 | 593 |
| 594 if (m_layoutObject->isBR()) | 594 if (m_layoutObject->isBR()) |
| (...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 980 | 980 |
| 981 return KURL(); | 981 return KURL(); |
| 982 } | 982 } |
| 983 | 983 |
| 984 // | 984 // |
| 985 // Inline text boxes. | 985 // Inline text boxes. |
| 986 // | 986 // |
| 987 | 987 |
| 988 void AXLayoutObject::loadInlineTextBoxes() | 988 void AXLayoutObject::loadInlineTextBoxes() |
| 989 { | 989 { |
| 990 if (!layoutObject() || !layoutObject()->isText()) | 990 if (!getLayoutObject() || !getLayoutObject()->isText()) |
| 991 return; | 991 return; |
| 992 | 992 |
| 993 clearChildren(); | 993 clearChildren(); |
| 994 addInlineTextBoxChildren(true); | 994 addInlineTextBoxChildren(true); |
| 995 } | 995 } |
| 996 | 996 |
| 997 AXObject* AXLayoutObject::nextOnLine() const | 997 AXObject* AXLayoutObject::nextOnLine() const |
| 998 { | 998 { |
| 999 if (!m_layoutObject) | 999 if (!m_layoutObject) |
| 1000 return 0; | 1000 return 0; |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1079 default: | 1079 default: |
| 1080 return emptyString(); | 1080 return emptyString(); |
| 1081 } | 1081 } |
| 1082 } | 1082 } |
| 1083 | 1083 |
| 1084 String AXLayoutObject::stringValue() const | 1084 String AXLayoutObject::stringValue() const |
| 1085 { | 1085 { |
| 1086 if (!m_layoutObject) | 1086 if (!m_layoutObject) |
| 1087 return String(); | 1087 return String(); |
| 1088 | 1088 |
| 1089 LayoutBoxModelObject* cssBox = layoutBoxModelObject(); | 1089 LayoutBoxModelObject* cssBox = getLayoutBoxModelObject(); |
| 1090 | 1090 |
| 1091 if (cssBox && cssBox->isMenuList()) { | 1091 if (cssBox && cssBox->isMenuList()) { |
| 1092 // LayoutMenuList will go straight to the text() of its selected item. | 1092 // LayoutMenuList will go straight to the text() of its selected item. |
| 1093 // This has to be overridden in the case where the selected item has an
ARIA label. | 1093 // This has to be overridden in the case where the selected item has an
ARIA label. |
| 1094 HTMLSelectElement* selectElement = toHTMLSelectElement(m_layoutObject->n
ode()); | 1094 HTMLSelectElement* selectElement = toHTMLSelectElement(m_layoutObject->n
ode()); |
| 1095 int selectedIndex = selectElement->selectedIndex(); | 1095 int selectedIndex = selectElement->selectedIndex(); |
| 1096 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& listItems = sel
ectElement->listItems(); | 1096 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& listItems = sel
ectElement->listItems(); |
| 1097 if (selectedIndex >= 0 && static_cast<size_t>(selectedIndex) < listItems
.size()) { | 1097 if (selectedIndex >= 0 && static_cast<size_t>(selectedIndex) < listItems
.size()) { |
| 1098 const AtomicString& overriddenDescription = listItems[selectedIndex]
->fastGetAttribute(aria_labelAttr); | 1098 const AtomicString& overriddenDescription = listItems[selectedIndex]
->fastGetAttribute(aria_labelAttr); |
| 1099 if (!overriddenDescription.isNull()) | 1099 if (!overriddenDescription.isNull()) |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1112 | 1112 |
| 1113 if (isTextControl()) | 1113 if (isTextControl()) |
| 1114 return text(); | 1114 return text(); |
| 1115 | 1115 |
| 1116 if (m_layoutObject->isFileUploadControl()) | 1116 if (m_layoutObject->isFileUploadControl()) |
| 1117 return toLayoutFileUploadControl(m_layoutObject)->fileTextValue(); | 1117 return toLayoutFileUploadControl(m_layoutObject)->fileTextValue(); |
| 1118 | 1118 |
| 1119 // Handle other HTML input elements that aren't text controls, like date and
time | 1119 // Handle other HTML input elements that aren't text controls, like date and
time |
| 1120 // controls, by returning the string value, with the exception of checkboxes | 1120 // controls, by returning the string value, with the exception of checkboxes |
| 1121 // and radio buttons (which would return "on"). | 1121 // and radio buttons (which would return "on"). |
| 1122 if (node() && isHTMLInputElement(node())) { | 1122 if (getNode() && isHTMLInputElement(getNode())) { |
| 1123 HTMLInputElement* input = toHTMLInputElement(node()); | 1123 HTMLInputElement* input = toHTMLInputElement(getNode()); |
| 1124 if (input->type() != InputTypeNames::checkbox && input->type() != InputT
ypeNames::radio) | 1124 if (input->type() != InputTypeNames::checkbox && input->type() != InputT
ypeNames::radio) |
| 1125 return input->value(); | 1125 return input->value(); |
| 1126 } | 1126 } |
| 1127 | 1127 |
| 1128 // FIXME: We might need to implement a value here for more types | 1128 // FIXME: We might need to implement a value here for more types |
| 1129 // FIXME: It would be better not to advertise a value at all for the types f
or which we don't implement one; | 1129 // FIXME: It would be better not to advertise a value at all for the types f
or which we don't implement one; |
| 1130 // this would require subclassing or making accessibilityAttributeNames do s
omething other than return a | 1130 // this would require subclassing or making accessibilityAttributeNames do s
omething other than return a |
| 1131 // single static array. | 1131 // single static array. |
| 1132 return String(); | 1132 return String(); |
| 1133 } | 1133 } |
| (...skipping 585 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1719 | 1719 |
| 1720 if (LocalFrame* frame = m_layoutObject->document().frame()) | 1720 if (LocalFrame* frame = m_layoutObject->document().frame()) |
| 1721 return frame->loader().progress().estimatedProgress(); | 1721 return frame->loader().progress().estimatedProgress(); |
| 1722 return 0; | 1722 return 0; |
| 1723 } | 1723 } |
| 1724 | 1724 |
| 1725 // | 1725 // |
| 1726 // DOM and layout tree access. | 1726 // DOM and layout tree access. |
| 1727 // | 1727 // |
| 1728 | 1728 |
| 1729 Node* AXLayoutObject::node() const | 1729 Node* AXLayoutObject::getNode() const |
| 1730 { | 1730 { |
| 1731 return m_layoutObject ? m_layoutObject->node() : 0; | 1731 return m_layoutObject ? m_layoutObject->node() : 0; |
| 1732 } | 1732 } |
| 1733 | 1733 |
| 1734 Document* AXLayoutObject::document() const | 1734 Document* AXLayoutObject::getDocument() const |
| 1735 { | 1735 { |
| 1736 if (!m_layoutObject) | 1736 if (!m_layoutObject) |
| 1737 return 0; | 1737 return 0; |
| 1738 return &m_layoutObject->document(); | 1738 return &m_layoutObject->document(); |
| 1739 } | 1739 } |
| 1740 | 1740 |
| 1741 FrameView* AXLayoutObject::documentFrameView() const | 1741 FrameView* AXLayoutObject::documentFrameView() const |
| 1742 { | 1742 { |
| 1743 if (!m_layoutObject) | 1743 if (!m_layoutObject) |
| 1744 return 0; | 1744 return 0; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1782 // | 1782 // |
| 1783 // Functions that retrieve the current selection. | 1783 // Functions that retrieve the current selection. |
| 1784 // | 1784 // |
| 1785 | 1785 |
| 1786 AXObject::AXRange AXLayoutObject::selection() const | 1786 AXObject::AXRange AXLayoutObject::selection() const |
| 1787 { | 1787 { |
| 1788 AXRange textSelection = textControlSelection(); | 1788 AXRange textSelection = textControlSelection(); |
| 1789 if (textSelection.isValid()) | 1789 if (textSelection.isValid()) |
| 1790 return textSelection; | 1790 return textSelection; |
| 1791 | 1791 |
| 1792 if (!layoutObject() || !layoutObject()->frame()) | 1792 if (!getLayoutObject() || !getLayoutObject()->frame()) |
| 1793 return AXRange(); | 1793 return AXRange(); |
| 1794 | 1794 |
| 1795 VisibleSelection selection = layoutObject()->frame()->selection().selection(
); | 1795 VisibleSelection selection = getLayoutObject()->frame()->selection().selecti
on(); |
| 1796 if (selection.isNone()) | 1796 if (selection.isNone()) |
| 1797 return AXRange(); | 1797 return AXRange(); |
| 1798 | 1798 |
| 1799 Position visibleStart = selection.visibleStart().toParentAnchoredPosition(); | 1799 Position visibleStart = selection.visibleStart().toParentAnchoredPosition(); |
| 1800 Position visibleEnd = selection.visibleEnd().toParentAnchoredPosition(); | 1800 Position visibleEnd = selection.visibleEnd().toParentAnchoredPosition(); |
| 1801 | 1801 |
| 1802 Node* anchorNode = visibleStart.anchorNode(); | 1802 Node* anchorNode = visibleStart.anchorNode(); |
| 1803 ASSERT(anchorNode); | 1803 ASSERT(anchorNode); |
| 1804 | 1804 |
| 1805 AXLayoutObject* anchorObject = nullptr; | 1805 AXLayoutObject* anchorObject = nullptr; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1848 | 1848 |
| 1849 // Gets only the start and end offsets of the selection computed using the | 1849 // Gets only the start and end offsets of the selection computed using the |
| 1850 // current object as the starting point. Returns a null selection if there is | 1850 // current object as the starting point. Returns a null selection if there is |
| 1851 // no selection in the subtree rooted at this object. | 1851 // no selection in the subtree rooted at this object. |
| 1852 AXObject::AXRange AXLayoutObject::selectionUnderObject() const | 1852 AXObject::AXRange AXLayoutObject::selectionUnderObject() const |
| 1853 { | 1853 { |
| 1854 AXRange textSelection = textControlSelection(); | 1854 AXRange textSelection = textControlSelection(); |
| 1855 if (textSelection.isValid()) | 1855 if (textSelection.isValid()) |
| 1856 return textSelection; | 1856 return textSelection; |
| 1857 | 1857 |
| 1858 if (!node() || !layoutObject()->frame()) | 1858 if (!getNode() || !getLayoutObject()->frame()) |
| 1859 return AXRange(); | 1859 return AXRange(); |
| 1860 | 1860 |
| 1861 VisibleSelection selection = layoutObject()->frame()->selection().selection(
); | 1861 VisibleSelection selection = getLayoutObject()->frame()->selection().selecti
on(); |
| 1862 RefPtrWillBeRawPtr<Range> selectionRange = firstRangeOf(selection); | 1862 RefPtrWillBeRawPtr<Range> selectionRange = firstRangeOf(selection); |
| 1863 ContainerNode* parentNode = node()->parentNode(); | 1863 ContainerNode* parentNode = getNode()->parentNode(); |
| 1864 int nodeIndex = node()->nodeIndex(); | 1864 int nodeIndex = getNode()->nodeIndex(); |
| 1865 if (!selectionRange | 1865 if (!selectionRange |
| 1866 // Selection is contained in node. | 1866 // Selection is contained in node. |
| 1867 || !(parentNode | 1867 || !(parentNode |
| 1868 && selectionRange->comparePoint(parentNode, nodeIndex, IGNORE_EXCEPTION)
< 0 | 1868 && selectionRange->comparePoint(parentNode, nodeIndex, IGNORE_EXCEPTION)
< 0 |
| 1869 && selectionRange->comparePoint(parentNode, nodeIndex + 1, IGNORE_EXCEPT
ION) > 0)) { | 1869 && selectionRange->comparePoint(parentNode, nodeIndex + 1, IGNORE_EXCEPT
ION) > 0)) { |
| 1870 return AXRange(); | 1870 return AXRange(); |
| 1871 } | 1871 } |
| 1872 | 1872 |
| 1873 int start = indexForVisiblePosition(selection.visibleStart()); | 1873 int start = indexForVisiblePosition(selection.visibleStart()); |
| 1874 ASSERT(start >= 0); | 1874 ASSERT(start >= 0); |
| 1875 int end = indexForVisiblePosition(selection.visibleEnd()); | 1875 int end = indexForVisiblePosition(selection.visibleEnd()); |
| 1876 ASSERT(end >= 0); | 1876 ASSERT(end >= 0); |
| 1877 | 1877 |
| 1878 return AXRange(start, end); | 1878 return AXRange(start, end); |
| 1879 } | 1879 } |
| 1880 | 1880 |
| 1881 AXObject::AXRange AXLayoutObject::textControlSelection() const | 1881 AXObject::AXRange AXLayoutObject::textControlSelection() const |
| 1882 { | 1882 { |
| 1883 if (!layoutObject()) | 1883 if (!getLayoutObject()) |
| 1884 return AXRange(); | 1884 return AXRange(); |
| 1885 | 1885 |
| 1886 LayoutObject* layout = nullptr; | 1886 LayoutObject* layout = nullptr; |
| 1887 if (layoutObject()->isTextControl()) { | 1887 if (getLayoutObject()->isTextControl()) { |
| 1888 layout = layoutObject(); | 1888 layout = getLayoutObject(); |
| 1889 } else { | 1889 } else { |
| 1890 Element* focusedElement = document()->focusedElement(); | 1890 Element* focusedElement = getDocument()->focusedElement(); |
| 1891 if (focusedElement && focusedElement->layoutObject() | 1891 if (focusedElement && focusedElement->layoutObject() |
| 1892 && focusedElement->layoutObject()->isTextControl()) | 1892 && focusedElement->layoutObject()->isTextControl()) |
| 1893 layout = focusedElement->layoutObject(); | 1893 layout = focusedElement->layoutObject(); |
| 1894 } | 1894 } |
| 1895 | 1895 |
| 1896 if (!layout) | 1896 if (!layout) |
| 1897 return AXRange(); | 1897 return AXRange(); |
| 1898 | 1898 |
| 1899 AXObject* axObject = axObjectCache().getOrCreate(layout); | 1899 AXObject* axObject = axObjectCache().getOrCreate(layout); |
| 1900 if (!axObject || !axObject->isAXLayoutObject()) | 1900 if (!axObject || !axObject->isAXLayoutObject()) |
| 1901 return AXRange(); | 1901 return AXRange(); |
| 1902 | 1902 |
| 1903 HTMLTextFormControlElement* textControl = toLayoutTextControl( | 1903 HTMLTextFormControlElement* textControl = toLayoutTextControl( |
| 1904 layout)->textFormControlElement(); | 1904 layout)->textFormControlElement(); |
| 1905 ASSERT(textControl); | 1905 ASSERT(textControl); |
| 1906 int start = textControl->selectionStart(); | 1906 int start = textControl->selectionStart(); |
| 1907 int end = textControl->selectionEnd(); | 1907 int end = textControl->selectionEnd(); |
| 1908 return AXRange(axObject, start, axObject, end); | 1908 return AXRange(axObject, start, axObject, end); |
| 1909 } | 1909 } |
| 1910 | 1910 |
| 1911 int AXLayoutObject::indexForVisiblePosition(const VisiblePosition& position) con
st | 1911 int AXLayoutObject::indexForVisiblePosition(const VisiblePosition& position) con
st |
| 1912 { | 1912 { |
| 1913 if (layoutObject() && layoutObject()->isTextControl()) { | 1913 if (getLayoutObject() && getLayoutObject()->isTextControl()) { |
| 1914 HTMLTextFormControlElement* textControl = toLayoutTextControl( | 1914 HTMLTextFormControlElement* textControl = toLayoutTextControl( |
| 1915 layoutObject())->textFormControlElement(); | 1915 getLayoutObject())->textFormControlElement(); |
| 1916 return textControl->indexForVisiblePosition(position); | 1916 return textControl->indexForVisiblePosition(position); |
| 1917 } | 1917 } |
| 1918 | 1918 |
| 1919 if (!node()) | 1919 if (!getNode()) |
| 1920 return 0; | 1920 return 0; |
| 1921 | 1921 |
| 1922 Position indexPosition = position.deepEquivalent(); | 1922 Position indexPosition = position.deepEquivalent(); |
| 1923 if (indexPosition.isNull()) | 1923 if (indexPosition.isNull()) |
| 1924 return 0; | 1924 return 0; |
| 1925 | 1925 |
| 1926 RefPtrWillBeRawPtr<Range> range = Range::create(*document()); | 1926 RefPtrWillBeRawPtr<Range> range = Range::create(*getDocument()); |
| 1927 range->setStart(node(), 0, IGNORE_EXCEPTION); | 1927 range->setStart(getNode(), 0, IGNORE_EXCEPTION); |
| 1928 range->setEnd(indexPosition, IGNORE_EXCEPTION); | 1928 range->setEnd(indexPosition, IGNORE_EXCEPTION); |
| 1929 | 1929 |
| 1930 return TextIterator::rangeLength(range->startPosition(), range->endPosition(
)); | 1930 return TextIterator::rangeLength(range->startPosition(), range->endPosition(
)); |
| 1931 } | 1931 } |
| 1932 | 1932 |
| 1933 AXLayoutObject* AXLayoutObject::getUnignoredObjectFromNode(Node& node) const | 1933 AXLayoutObject* AXLayoutObject::getUnignoredObjectFromNode(Node& node) const |
| 1934 { | 1934 { |
| 1935 if (isDetached()) | 1935 if (isDetached()) |
| 1936 return nullptr; | 1936 return nullptr; |
| 1937 | 1937 |
| 1938 AXObject* axObject = axObjectCache().getOrCreate(&node); | 1938 AXObject* axObject = axObjectCache().getOrCreate(&node); |
| 1939 if (!axObject) | 1939 if (!axObject) |
| 1940 return nullptr; | 1940 return nullptr; |
| 1941 | 1941 |
| 1942 if (axObject->isAXLayoutObject() && !axObject->accessibilityIsIgnored()) | 1942 if (axObject->isAXLayoutObject() && !axObject->accessibilityIsIgnored()) |
| 1943 return toAXLayoutObject(axObject); | 1943 return toAXLayoutObject(axObject); |
| 1944 | 1944 |
| 1945 return nullptr; | 1945 return nullptr; |
| 1946 } | 1946 } |
| 1947 | 1947 |
| 1948 | 1948 |
| 1949 // | 1949 // |
| 1950 // Modify or take an action on an object. | 1950 // Modify or take an action on an object. |
| 1951 // | 1951 // |
| 1952 | 1952 |
| 1953 void AXLayoutObject::setSelection(const AXRange& selection) | 1953 void AXLayoutObject::setSelection(const AXRange& selection) |
| 1954 { | 1954 { |
| 1955 if (!layoutObject() || !selection.isValid()) | 1955 if (!getLayoutObject() || !selection.isValid()) |
| 1956 return; | 1956 return; |
| 1957 | 1957 |
| 1958 AXObject* anchorObject = selection.anchorObject ? | 1958 AXObject* anchorObject = selection.anchorObject ? |
| 1959 selection.anchorObject.get() : this; | 1959 selection.anchorObject.get() : this; |
| 1960 AXObject* focusObject = selection.focusObject ? | 1960 AXObject* focusObject = selection.focusObject ? |
| 1961 selection.focusObject.get() : this; | 1961 selection.focusObject.get() : this; |
| 1962 | 1962 |
| 1963 if (!isValidSelectionBound(anchorObject) | 1963 if (!isValidSelectionBound(anchorObject) |
| 1964 || !isValidSelectionBound(focusObject)) { | 1964 || !isValidSelectionBound(focusObject)) { |
| 1965 return; | 1965 return; |
| 1966 } | 1966 } |
| 1967 | 1967 |
| 1968 if (anchorObject == focusObject | 1968 if (anchorObject == focusObject |
| 1969 && anchorObject->layoutObject()->isTextControl()) { | 1969 && anchorObject->getLayoutObject()->isTextControl()) { |
| 1970 HTMLTextFormControlElement* textControl = toLayoutTextControl( | 1970 HTMLTextFormControlElement* textControl = toLayoutTextControl( |
| 1971 anchorObject->layoutObject())->textFormControlElement(); | 1971 anchorObject->getLayoutObject())->textFormControlElement(); |
| 1972 if (selection.anchorOffset <= selection.focusOffset) { | 1972 if (selection.anchorOffset <= selection.focusOffset) { |
| 1973 textControl->setSelectionRange( | 1973 textControl->setSelectionRange( |
| 1974 selection.anchorOffset, selection.focusOffset, | 1974 selection.anchorOffset, selection.focusOffset, |
| 1975 SelectionHasForwardDirection, NotDispatchSelectEvent); | 1975 SelectionHasForwardDirection, NotDispatchSelectEvent); |
| 1976 } else { | 1976 } else { |
| 1977 textControl->setSelectionRange( | 1977 textControl->setSelectionRange( |
| 1978 selection.focusOffset, selection.anchorOffset, | 1978 selection.focusOffset, selection.anchorOffset, |
| 1979 SelectionHasBackwardDirection, NotDispatchSelectEvent); | 1979 SelectionHasBackwardDirection, NotDispatchSelectEvent); |
| 1980 } | 1980 } |
| 1981 return; | 1981 return; |
| 1982 } | 1982 } |
| 1983 | 1983 |
| 1984 Node* anchorNode = nullptr; | 1984 Node* anchorNode = nullptr; |
| 1985 while (anchorObject && !anchorNode) { | 1985 while (anchorObject && !anchorNode) { |
| 1986 anchorNode = anchorObject->node(); | 1986 anchorNode = anchorObject->getNode(); |
| 1987 anchorObject = anchorObject->parentObject(); | 1987 anchorObject = anchorObject->parentObject(); |
| 1988 } | 1988 } |
| 1989 | 1989 |
| 1990 Node* focusNode = nullptr; | 1990 Node* focusNode = nullptr; |
| 1991 while (focusObject && !focusNode) { | 1991 while (focusObject && !focusNode) { |
| 1992 focusNode = focusObject->node(); | 1992 focusNode = focusObject->getNode(); |
| 1993 focusObject = focusObject->parentObject(); | 1993 focusObject = focusObject->parentObject(); |
| 1994 } | 1994 } |
| 1995 | 1995 |
| 1996 if (!anchorNode || !focusNode) | 1996 if (!anchorNode || !focusNode) |
| 1997 return; | 1997 return; |
| 1998 | 1998 |
| 1999 LocalFrame* frame = layoutObject()->frame(); | 1999 LocalFrame* frame = getLayoutObject()->frame(); |
| 2000 if (!frame) | 2000 if (!frame) |
| 2001 return; | 2001 return; |
| 2002 | 2002 |
| 2003 frame->selection().setSelection(VisibleSelection( | 2003 frame->selection().setSelection(VisibleSelection( |
| 2004 Position(anchorNode, selection.anchorOffset), | 2004 Position(anchorNode, selection.anchorOffset), |
| 2005 Position(focusNode, selection.focusOffset))); | 2005 Position(focusNode, selection.focusOffset))); |
| 2006 } | 2006 } |
| 2007 | 2007 |
| 2008 bool AXLayoutObject::isValidSelectionBound(const AXObject* boundObject) const | 2008 bool AXLayoutObject::isValidSelectionBound(const AXObject* boundObject) const |
| 2009 { | 2009 { |
| 2010 return layoutObject() && boundObject && !boundObject->isDetached() | 2010 return getLayoutObject() && boundObject && !boundObject->isDetached() |
| 2011 && boundObject->isAXLayoutObject() && boundObject->layoutObject() | 2011 && boundObject->isAXLayoutObject() && boundObject->getLayoutObject() |
| 2012 && boundObject->layoutObject()->frame() == layoutObject()->frame() | 2012 && boundObject->getLayoutObject()->frame() == getLayoutObject()->frame() |
| 2013 && &boundObject->axObjectCache() == &axObjectCache(); | 2013 && &boundObject->axObjectCache() == &axObjectCache(); |
| 2014 } | 2014 } |
| 2015 | 2015 |
| 2016 void AXLayoutObject::setValue(const String& string) | 2016 void AXLayoutObject::setValue(const String& string) |
| 2017 { | 2017 { |
| 2018 if (!node() || !node()->isElementNode()) | 2018 if (!getNode() || !getNode()->isElementNode()) |
| 2019 return; | 2019 return; |
| 2020 if (!m_layoutObject || !m_layoutObject->isBoxModelObject()) | 2020 if (!m_layoutObject || !m_layoutObject->isBoxModelObject()) |
| 2021 return; | 2021 return; |
| 2022 | 2022 |
| 2023 LayoutBoxModelObject* layoutObject = toLayoutBoxModelObject(m_layoutObject); | 2023 LayoutBoxModelObject* layoutObject = toLayoutBoxModelObject(m_layoutObject); |
| 2024 if (layoutObject->isTextField() && isHTMLInputElement(*node())) | 2024 if (layoutObject->isTextField() && isHTMLInputElement(*getNode())) |
| 2025 toHTMLInputElement(*node()).setValue(string, DispatchInputAndChangeEvent
); | 2025 toHTMLInputElement(*getNode()).setValue(string, DispatchInputAndChangeEv
ent); |
| 2026 else if (layoutObject->isTextArea() && isHTMLTextAreaElement(*node())) | 2026 else if (layoutObject->isTextArea() && isHTMLTextAreaElement(*getNode())) |
| 2027 toHTMLTextAreaElement(*node()).setValue(string, DispatchInputAndChangeEv
ent); | 2027 toHTMLTextAreaElement(*getNode()).setValue(string, DispatchInputAndChang
eEvent); |
| 2028 } | 2028 } |
| 2029 | 2029 |
| 2030 // | 2030 // |
| 2031 // Notifications that this object may have changed. | 2031 // Notifications that this object may have changed. |
| 2032 // | 2032 // |
| 2033 | 2033 |
| 2034 void AXLayoutObject::handleActiveDescendantChanged() | 2034 void AXLayoutObject::handleActiveDescendantChanged() |
| 2035 { | 2035 { |
| 2036 Element* element = toElement(layoutObject()->node()); | 2036 Element* element = toElement(getLayoutObject()->node()); |
| 2037 if (!element) | 2037 if (!element) |
| 2038 return; | 2038 return; |
| 2039 Document& doc = layoutObject()->document(); | 2039 Document& doc = getLayoutObject()->document(); |
| 2040 if (!doc.frame()->selection().isFocusedAndActive() || doc.focusedElement() !
= element) | 2040 if (!doc.frame()->selection().isFocusedAndActive() || doc.focusedElement() !
= element) |
| 2041 return; | 2041 return; |
| 2042 AXLayoutObject* activedescendant = toAXLayoutObject(activeDescendant()); | 2042 AXLayoutObject* activedescendant = toAXLayoutObject(activeDescendant()); |
| 2043 | 2043 |
| 2044 if (activedescendant && shouldNotifyActiveDescendant()) | 2044 if (activedescendant && shouldNotifyActiveDescendant()) |
| 2045 toAXObjectCacheImpl(doc.axObjectCache())->postNotification(m_layoutObjec
t, AXObjectCacheImpl::AXActiveDescendantChanged); | 2045 toAXObjectCacheImpl(doc.axObjectCache())->postNotification(m_layoutObjec
t, AXObjectCacheImpl::AXActiveDescendantChanged); |
| 2046 } | 2046 } |
| 2047 | 2047 |
| 2048 void AXLayoutObject::handleAriaExpandedChanged() | 2048 void AXLayoutObject::handleAriaExpandedChanged() |
| 2049 { | 2049 { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2085 | 2085 |
| 2086 axObjectCache().postNotification(this, notification); | 2086 axObjectCache().postNotification(this, notification); |
| 2087 } | 2087 } |
| 2088 } | 2088 } |
| 2089 | 2089 |
| 2090 void AXLayoutObject::textChanged() | 2090 void AXLayoutObject::textChanged() |
| 2091 { | 2091 { |
| 2092 if (!m_layoutObject) | 2092 if (!m_layoutObject) |
| 2093 return; | 2093 return; |
| 2094 | 2094 |
| 2095 Settings* settings = document()->settings(); | 2095 Settings* settings = getDocument()->settings(); |
| 2096 if (settings && settings->inlineTextBoxAccessibilityEnabled() && roleValue()
== StaticTextRole) | 2096 if (settings && settings->inlineTextBoxAccessibilityEnabled() && roleValue()
== StaticTextRole) |
| 2097 childrenChanged(); | 2097 childrenChanged(); |
| 2098 | 2098 |
| 2099 // Do this last - AXNodeObject::textChanged posts live region announcements, | 2099 // Do this last - AXNodeObject::textChanged posts live region announcements, |
| 2100 // and we should update the inline text boxes first. | 2100 // and we should update the inline text boxes first. |
| 2101 AXNodeObject::textChanged(); | 2101 AXNodeObject::textChanged(); |
| 2102 } | 2102 } |
| 2103 | 2103 |
| 2104 // | 2104 // |
| 2105 // Text metrics. Most of these should be deprecated, needs major cleanup. | 2105 // Text metrics. Most of these should be deprecated, needs major cleanup. |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2137 if (!selected) | 2137 if (!selected) |
| 2138 return VisiblePosition(); | 2138 return VisiblePosition(); |
| 2139 | 2139 |
| 2140 CharacterIterator it(start, end); | 2140 CharacterIterator it(start, end); |
| 2141 it.advance(index - 1); | 2141 it.advance(index - 1); |
| 2142 return createVisiblePosition(Position(it.currentContainer(), it.endOffset())
, TextAffinity::Upstream); | 2142 return createVisiblePosition(Position(it.currentContainer(), it.endOffset())
, TextAffinity::Upstream); |
| 2143 } | 2143 } |
| 2144 | 2144 |
| 2145 void AXLayoutObject::addInlineTextBoxChildren(bool force) | 2145 void AXLayoutObject::addInlineTextBoxChildren(bool force) |
| 2146 { | 2146 { |
| 2147 Settings* settings = document()->settings(); | 2147 Settings* settings = getDocument()->settings(); |
| 2148 if (!force && (!settings || !settings->inlineTextBoxAccessibilityEnabled())) | 2148 if (!force && (!settings || !settings->inlineTextBoxAccessibilityEnabled())) |
| 2149 return; | 2149 return; |
| 2150 | 2150 |
| 2151 if (!layoutObject() || !layoutObject()->isText()) | 2151 if (!getLayoutObject() || !getLayoutObject()->isText()) |
| 2152 return; | 2152 return; |
| 2153 | 2153 |
| 2154 if (layoutObject()->needsLayout()) { | 2154 if (getLayoutObject()->needsLayout()) { |
| 2155 // If a LayoutText needs layout, its inline text boxes are either | 2155 // If a LayoutText needs layout, its inline text boxes are either |
| 2156 // nonexistent or invalid, so defer until the layout happens and | 2156 // nonexistent or invalid, so defer until the layout happens and |
| 2157 // the layoutObject calls AXObjectCacheImpl::inlineTextBoxesUpdated. | 2157 // the layoutObject calls AXObjectCacheImpl::inlineTextBoxesUpdated. |
| 2158 return; | 2158 return; |
| 2159 } | 2159 } |
| 2160 | 2160 |
| 2161 LayoutText* layoutText = toLayoutText(layoutObject()); | 2161 LayoutText* layoutText = toLayoutText(getLayoutObject()); |
| 2162 for (RefPtr<AbstractInlineTextBox> box = layoutText->firstAbstractInlineText
Box(); box.get(); box = box->nextInlineTextBox()) { | 2162 for (RefPtr<AbstractInlineTextBox> box = layoutText->firstAbstractInlineText
Box(); box.get(); box = box->nextInlineTextBox()) { |
| 2163 AXObject* axObject = axObjectCache().getOrCreate(box.get()); | 2163 AXObject* axObject = axObjectCache().getOrCreate(box.get()); |
| 2164 if (!axObject->accessibilityIsIgnored()) | 2164 if (!axObject->accessibilityIsIgnored()) |
| 2165 m_children.append(axObject); | 2165 m_children.append(axObject); |
| 2166 } | 2166 } |
| 2167 } | 2167 } |
| 2168 | 2168 |
| 2169 void AXLayoutObject::lineBreaks(Vector<int>& lineBreaks) const | 2169 void AXLayoutObject::lineBreaks(Vector<int>& lineBreaks) const |
| 2170 { | 2170 { |
| 2171 if (!isTextControl()) | 2171 if (!isTextControl()) |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2348 rect.moveBy(parent->parentObject()->elementRect().location()); | 2348 rect.moveBy(parent->parentObject()->elementRect().location()); |
| 2349 break; | 2349 break; |
| 2350 } | 2350 } |
| 2351 } | 2351 } |
| 2352 } | 2352 } |
| 2353 | 2353 |
| 2354 // Hidden children are those that are not laid out or visible, but are specifica
lly marked as aria-hidden=false, | 2354 // Hidden children are those that are not laid out or visible, but are specifica
lly marked as aria-hidden=false, |
| 2355 // meaning that they should be exposed to the AX hierarchy. | 2355 // meaning that they should be exposed to the AX hierarchy. |
| 2356 void AXLayoutObject::addHiddenChildren() | 2356 void AXLayoutObject::addHiddenChildren() |
| 2357 { | 2357 { |
| 2358 Node* node = this->node(); | 2358 Node* node = this->getNode(); |
| 2359 if (!node) | 2359 if (!node) |
| 2360 return; | 2360 return; |
| 2361 | 2361 |
| 2362 // First do a quick run through to determine if we have any hidden nodes (mo
st often we will not). | 2362 // First do a quick run through to determine if we have any hidden nodes (mo
st often we will not). |
| 2363 // If we do have hidden nodes, we need to determine where to insert them so
they match DOM order as close as possible. | 2363 // If we do have hidden nodes, we need to determine where to insert them so
they match DOM order as close as possible. |
| 2364 bool shouldInsertHiddenNodes = false; | 2364 bool shouldInsertHiddenNodes = false; |
| 2365 for (Node& child : NodeTraversal::childrenOf(*node)) { | 2365 for (Node& child : NodeTraversal::childrenOf(*node)) { |
| 2366 if (!child.layoutObject() && isNodeAriaVisible(&child)) { | 2366 if (!child.layoutObject() && isNodeAriaVisible(&child)) { |
| 2367 shouldInsertHiddenNodes = true; | 2367 shouldInsertHiddenNodes = true; |
| 2368 break; | 2368 break; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 2396 if (insertionIndex > previousSize) | 2396 if (insertionIndex > previousSize) |
| 2397 insertionIndex = previousSize; | 2397 insertionIndex = previousSize; |
| 2398 | 2398 |
| 2399 insertChild(axObjectCache().getOrCreate(&child), insertionIndex); | 2399 insertChild(axObjectCache().getOrCreate(&child), insertionIndex); |
| 2400 insertionIndex += (m_children.size() - previousSize); | 2400 insertionIndex += (m_children.size() - previousSize); |
| 2401 } | 2401 } |
| 2402 } | 2402 } |
| 2403 | 2403 |
| 2404 void AXLayoutObject::addTextFieldChildren() | 2404 void AXLayoutObject::addTextFieldChildren() |
| 2405 { | 2405 { |
| 2406 Node* node = this->node(); | 2406 Node* node = this->getNode(); |
| 2407 if (!isHTMLInputElement(node)) | 2407 if (!isHTMLInputElement(node)) |
| 2408 return; | 2408 return; |
| 2409 | 2409 |
| 2410 HTMLInputElement& input = toHTMLInputElement(*node); | 2410 HTMLInputElement& input = toHTMLInputElement(*node); |
| 2411 Element* spinButtonElement = input.userAgentShadowRoot()->getElementById(Sha
dowElementNames::spinButton()); | 2411 Element* spinButtonElement = input.userAgentShadowRoot()->getElementById(Sha
dowElementNames::spinButton()); |
| 2412 if (!spinButtonElement || !spinButtonElement->isSpinButtonElement()) | 2412 if (!spinButtonElement || !spinButtonElement->isSpinButtonElement()) |
| 2413 return; | 2413 return; |
| 2414 | 2414 |
| 2415 AXSpinButton* axSpinButton = toAXSpinButton(axObjectCache().getOrCreate(Spin
ButtonRole)); | 2415 AXSpinButton* axSpinButton = toAXSpinButton(axObjectCache().getOrCreate(Spin
ButtonRole)); |
| 2416 axSpinButton->setSpinButtonElement(toSpinButtonElement(spinButtonElement)); | 2416 axSpinButton->setSpinButtonElement(toSpinButtonElement(spinButtonElement)); |
| 2417 axSpinButton->setParent(this); | 2417 axSpinButton->setParent(this); |
| 2418 m_children.append(axSpinButton); | 2418 m_children.append(axSpinButton); |
| 2419 } | 2419 } |
| 2420 | 2420 |
| 2421 void AXLayoutObject::addImageMapChildren() | 2421 void AXLayoutObject::addImageMapChildren() |
| 2422 { | 2422 { |
| 2423 LayoutBoxModelObject* cssBox = layoutBoxModelObject(); | 2423 LayoutBoxModelObject* cssBox = getLayoutBoxModelObject(); |
| 2424 if (!cssBox || !cssBox->isLayoutImage()) | 2424 if (!cssBox || !cssBox->isLayoutImage()) |
| 2425 return; | 2425 return; |
| 2426 | 2426 |
| 2427 HTMLMapElement* map = toLayoutImage(cssBox)->imageMap(); | 2427 HTMLMapElement* map = toLayoutImage(cssBox)->imageMap(); |
| 2428 if (!map) | 2428 if (!map) |
| 2429 return; | 2429 return; |
| 2430 | 2430 |
| 2431 for (HTMLAreaElement& area : Traversal<HTMLAreaElement>::descendantsOf(*map)
) { | 2431 for (HTMLAreaElement& area : Traversal<HTMLAreaElement>::descendantsOf(*map)
) { |
| 2432 // add an <area> element for this child if it has a link | 2432 // add an <area> element for this child if it has a link |
| 2433 AXObject* obj = axObjectCache().getOrCreate(&area); | 2433 AXObject* obj = axObjectCache().getOrCreate(&area); |
| 2434 if (obj) { | 2434 if (obj) { |
| 2435 AXImageMapLink* areaObject = toAXImageMapLink(obj); | 2435 AXImageMapLink* areaObject = toAXImageMapLink(obj); |
| 2436 areaObject->setParent(this); | 2436 areaObject->setParent(this); |
| 2437 ASSERT(areaObject->axObjectID() != 0); | 2437 ASSERT(areaObject->axObjectID() != 0); |
| 2438 if (!areaObject->accessibilityIsIgnored()) | 2438 if (!areaObject->accessibilityIsIgnored()) |
| 2439 m_children.append(areaObject); | 2439 m_children.append(areaObject); |
| 2440 else | 2440 else |
| 2441 axObjectCache().remove(areaObject->axObjectID()); | 2441 axObjectCache().remove(areaObject->axObjectID()); |
| 2442 } | 2442 } |
| 2443 } | 2443 } |
| 2444 } | 2444 } |
| 2445 | 2445 |
| 2446 void AXLayoutObject::addCanvasChildren() | 2446 void AXLayoutObject::addCanvasChildren() |
| 2447 { | 2447 { |
| 2448 if (!isHTMLCanvasElement(node())) | 2448 if (!isHTMLCanvasElement(getNode())) |
| 2449 return; | 2449 return; |
| 2450 | 2450 |
| 2451 // If it's a canvas, it won't have laid out children, but it might have acce
ssible fallback content. | 2451 // If it's a canvas, it won't have laid out children, but it might have acce
ssible fallback content. |
| 2452 // Clear m_haveChildren because AXNodeObject::addChildren will expect it to
be false. | 2452 // Clear m_haveChildren because AXNodeObject::addChildren will expect it to
be false. |
| 2453 ASSERT(!m_children.size()); | 2453 ASSERT(!m_children.size()); |
| 2454 m_haveChildren = false; | 2454 m_haveChildren = false; |
| 2455 AXNodeObject::addChildren(); | 2455 AXNodeObject::addChildren(); |
| 2456 } | 2456 } |
| 2457 | 2457 |
| 2458 void AXLayoutObject::addFrameChildren() | 2458 void AXLayoutObject::addFrameChildren() |
| 2459 { | 2459 { |
| 2460 if (!m_layoutObject || !m_layoutObject->isLayoutPart()) | 2460 if (!m_layoutObject || !m_layoutObject->isLayoutPart()) |
| 2461 return; | 2461 return; |
| 2462 | 2462 |
| 2463 Widget* widget = toLayoutPart(m_layoutObject)->widget(); | 2463 Widget* widget = toLayoutPart(m_layoutObject)->widget(); |
| 2464 if (!widget || !widget->isFrameView()) | 2464 if (!widget || !widget->isFrameView()) |
| 2465 return; | 2465 return; |
| 2466 | 2466 |
| 2467 Document* doc = toFrameView(widget)->frame().document(); | 2467 Document* doc = toFrameView(widget)->frame().document(); |
| 2468 if (!doc || !doc->layoutView()) | 2468 if (!doc || !doc->layoutView()) |
| 2469 return; | 2469 return; |
| 2470 | 2470 |
| 2471 AXObject* axChildFrame = axObjectCache().getOrCreate(doc); | 2471 AXObject* axChildFrame = axObjectCache().getOrCreate(doc); |
| 2472 if (!axChildFrame->accessibilityIsIgnored()) | 2472 if (!axChildFrame->accessibilityIsIgnored()) |
| 2473 m_children.append(axChildFrame); | 2473 m_children.append(axChildFrame); |
| 2474 } | 2474 } |
| 2475 | 2475 |
| 2476 void AXLayoutObject::addPopupChildren() | 2476 void AXLayoutObject::addPopupChildren() |
| 2477 { | 2477 { |
| 2478 if (!isHTMLInputElement(node())) | 2478 if (!isHTMLInputElement(getNode())) |
| 2479 return; | 2479 return; |
| 2480 if (AXObject* axPopup = toHTMLInputElement(node())->popupRootAXObject()) | 2480 if (AXObject* axPopup = toHTMLInputElement(getNode())->popupRootAXObject()) |
| 2481 m_children.append(axPopup); | 2481 m_children.append(axPopup); |
| 2482 } | 2482 } |
| 2483 | 2483 |
| 2484 void AXLayoutObject::addRemoteSVGChildren() | 2484 void AXLayoutObject::addRemoteSVGChildren() |
| 2485 { | 2485 { |
| 2486 AXSVGRoot* root = remoteSVGRootElement(); | 2486 AXSVGRoot* root = remoteSVGRootElement(); |
| 2487 if (!root) | 2487 if (!root) |
| 2488 return; | 2488 return; |
| 2489 | 2489 |
| 2490 root->setParent(this); | 2490 root->setParent(this); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2523 if (obj->isText()) { | 2523 if (obj->isText()) { |
| 2524 Vector<FloatQuad> quads; | 2524 Vector<FloatQuad> quads; |
| 2525 toLayoutText(obj)->absoluteQuads(quads, 0, LayoutText::ClipToEllipsis); | 2525 toLayoutText(obj)->absoluteQuads(quads, 0, LayoutText::ClipToEllipsis); |
| 2526 result = LayoutRect(boundingBoxForQuads(obj, quads)); | 2526 result = LayoutRect(boundingBoxForQuads(obj, quads)); |
| 2527 } else if (isWebArea() || obj->isSVGRoot()) { | 2527 } else if (isWebArea() || obj->isSVGRoot()) { |
| 2528 result = LayoutRect(obj->absoluteBoundingBoxRect()); | 2528 result = LayoutRect(obj->absoluteBoundingBoxRect()); |
| 2529 } else { | 2529 } else { |
| 2530 result = LayoutRect(obj->absoluteElementBoundingBoxRect()); | 2530 result = LayoutRect(obj->absoluteElementBoundingBoxRect()); |
| 2531 } | 2531 } |
| 2532 | 2532 |
| 2533 Document* document = this->document(); | 2533 Document* document = this->getDocument(); |
| 2534 if (document && document->isSVGDocument()) | 2534 if (document && document->isSVGDocument()) |
| 2535 offsetBoundingBoxForRemoteSVGElement(result); | 2535 offsetBoundingBoxForRemoteSVGElement(result); |
| 2536 if (document && document->frame() && document->frame()->pagePopupOwner()) { | 2536 if (document && document->frame() && document->frame()->pagePopupOwner()) { |
| 2537 IntPoint popupOrigin = document->view()->contentsToScreen(IntRect()).loc
ation(); | 2537 IntPoint popupOrigin = document->view()->contentsToScreen(IntRect()).loc
ation(); |
| 2538 IntPoint mainOrigin = axObjectCache().rootObject()->documentFrameView()-
>contentsToScreen(IntRect()).location(); | 2538 IntPoint mainOrigin = axObjectCache().rootObject()->documentFrameView()-
>contentsToScreen(IntRect()).location(); |
| 2539 result.moveBy(IntPoint(popupOrigin - mainOrigin)); | 2539 result.moveBy(IntPoint(popupOrigin - mainOrigin)); |
| 2540 } | 2540 } |
| 2541 | 2541 |
| 2542 // The size of the web area should be the content size, not the clipped size
. | 2542 // The size of the web area should be the content size, not the clipped size
. |
| 2543 if (isWebArea() && obj->frame()->view()) | 2543 if (isWebArea() && obj->frame()->view()) |
| 2544 result.setSize(LayoutSize(obj->frame()->view()->contentsSize())); | 2544 result.setSize(LayoutSize(obj->frame()->view()->contentsSize())); |
| 2545 | 2545 |
| 2546 // Checkboxes and radio buttons include their label as part of their rect. | 2546 // Checkboxes and radio buttons include their label as part of their rect. |
| 2547 if (isCheckboxOrRadio()) { | 2547 if (isCheckboxOrRadio()) { |
| 2548 HTMLLabelElement* label = labelForElement(toElement(m_layoutObject->node
())); | 2548 HTMLLabelElement* label = labelForElement(toElement(m_layoutObject->node
())); |
| 2549 if (label && label->layoutObject()) { | 2549 if (label && label->layoutObject()) { |
| 2550 LayoutRect labelRect = axObjectCache().getOrCreate(label)->elementRe
ct(); | 2550 LayoutRect labelRect = axObjectCache().getOrCreate(label)->elementRe
ct(); |
| 2551 result.unite(labelRect); | 2551 result.unite(labelRect); |
| 2552 } | 2552 } |
| 2553 } | 2553 } |
| 2554 | 2554 |
| 2555 return result; | 2555 return result; |
| 2556 } | 2556 } |
| 2557 | 2557 |
| 2558 } // namespace blink | 2558 } // namespace blink |
| OLD | NEW |