| 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 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 113 | 113 |
| 114 if (!firstChild && isInlineWithContinuation(layoutObject)) | 114 if (!firstChild && isInlineWithContinuation(layoutObject)) |
| 115 firstChild = firstChildInContinuation(toLayoutInline(*layoutObject)); | 115 firstChild = firstChildInContinuation(toLayoutInline(*layoutObject)); |
| 116 | 116 |
| 117 return firstChild; | 117 return firstChild; |
| 118 } | 118 } |
| 119 | 119 |
| 120 static inline LayoutInline* startOfContinuations(LayoutObject* r) | 120 static inline LayoutInline* startOfContinuations(LayoutObject* r) |
| 121 { | 121 { |
| 122 if (r->isInlineElementContinuation()) { | 122 if (r->isInlineElementContinuation()) { |
| 123 return toLayoutInline(r->node()->renderer()); | 123 return toLayoutInline(r->node()->layoutObject()); |
| 124 } | 124 } |
| 125 | 125 |
| 126 // Blocks with a previous continuation always have a next continuation | 126 // Blocks with a previous continuation always have a next continuation |
| 127 if (r->isLayoutBlock() && toLayoutBlock(r)->inlineElementContinuation()) | 127 if (r->isLayoutBlock() && toLayoutBlock(r)->inlineElementContinuation()) |
| 128 return toLayoutInline(toLayoutBlock(r)->inlineElementContinuation()->nod
e()->renderer()); | 128 return toLayoutInline(toLayoutBlock(r)->inlineElementContinuation()->nod
e()->layoutObject()); |
| 129 | 129 |
| 130 return 0; | 130 return 0; |
| 131 } | 131 } |
| 132 | 132 |
| 133 static inline LayoutObject* endOfContinuations(LayoutObject* layoutObject) | 133 static inline LayoutObject* endOfContinuations(LayoutObject* layoutObject) |
| 134 { | 134 { |
| 135 LayoutObject* prev = layoutObject; | 135 LayoutObject* prev = layoutObject; |
| 136 LayoutObject* cur = layoutObject; | 136 LayoutObject* cur = layoutObject; |
| 137 | 137 |
| 138 if (!cur->isLayoutInline() && !cur->isLayoutBlock()) | 138 if (!cur->isLayoutInline() && !cur->isLayoutBlock()) |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 413 if (!layoutObject) | 413 if (!layoutObject) |
| 414 return false; | 414 return false; |
| 415 // Widgets are the replaced elements that we represent to AX as attachments | 415 // Widgets are the replaced elements that we represent to AX as attachments |
| 416 bool isLayoutPart = layoutObject->isLayoutPart(); | 416 bool isLayoutPart = layoutObject->isLayoutPart(); |
| 417 ASSERT(!isLayoutPart || (layoutObject->isReplaced() && !isImage())); | 417 ASSERT(!isLayoutPart || (layoutObject->isReplaced() && !isImage())); |
| 418 return isLayoutPart; | 418 return isLayoutPart; |
| 419 } | 419 } |
| 420 | 420 |
| 421 static bool isLinkable(const AXObject& object) | 421 static bool isLinkable(const AXObject& object) |
| 422 { | 422 { |
| 423 if (!object.renderer()) | 423 if (!object.layoutObject()) |
| 424 return false; | 424 return false; |
| 425 | 425 |
| 426 // See https://wiki.mozilla.org/Accessibility/AT-Windows-API for the element
s | 426 // See https://wiki.mozilla.org/Accessibility/AT-Windows-API for the element
s |
| 427 // Mozilla considers linkable. | 427 // Mozilla considers linkable. |
| 428 return object.isLink() || object.isImage() || object.renderer()->isText(); | 428 return object.isLink() || object.isImage() || object.layoutObject()->isText(
); |
| 429 } | 429 } |
| 430 | 430 |
| 431 bool AXLayoutObject::isLinked() const | 431 bool AXLayoutObject::isLinked() const |
| 432 { | 432 { |
| 433 if (!isLinkable(*this)) | 433 if (!isLinkable(*this)) |
| 434 return false; | 434 return false; |
| 435 | 435 |
| 436 Element* anchor = anchorElement(); | 436 Element* anchor = anchorElement(); |
| 437 if (!isHTMLAnchorElement(anchor)) | 437 if (!isHTMLAnchorElement(anchor)) |
| 438 return false; | 438 return false; |
| (...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 874 | 874 |
| 875 return KURL(); | 875 return KURL(); |
| 876 } | 876 } |
| 877 | 877 |
| 878 // | 878 // |
| 879 // Load inline text boxes. | 879 // Load inline text boxes. |
| 880 // | 880 // |
| 881 | 881 |
| 882 void AXLayoutObject::loadInlineTextBoxes() | 882 void AXLayoutObject::loadInlineTextBoxes() |
| 883 { | 883 { |
| 884 if (!renderer() || !renderer()->isText()) | 884 if (!layoutObject() || !layoutObject()->isText()) |
| 885 return; | 885 return; |
| 886 | 886 |
| 887 clearChildren(); | 887 clearChildren(); |
| 888 addInlineTextBoxChildren(true); | 888 addInlineTextBoxChildren(true); |
| 889 } | 889 } |
| 890 | 890 |
| 891 // | 891 // |
| 892 // Properties of interactive elements. | 892 // Properties of interactive elements. |
| 893 // | 893 // |
| 894 | 894 |
| (...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1352 // Allow the hit test to return media control buttons. | 1352 // Allow the hit test to return media control buttons. |
| 1353 if (node->isInShadowTree() && (!isHTMLInputElement(*node) || !node->isMediaC
ontrolElement())) | 1353 if (node->isInShadowTree() && (!isHTMLInputElement(*node) || !node->isMediaC
ontrolElement())) |
| 1354 node = node->shadowHost(); | 1354 node = node->shadowHost(); |
| 1355 | 1355 |
| 1356 if (isHTMLAreaElement(node)) | 1356 if (isHTMLAreaElement(node)) |
| 1357 return accessibilityImageMapHitTest(toHTMLAreaElement(node), point); | 1357 return accessibilityImageMapHitTest(toHTMLAreaElement(node), point); |
| 1358 | 1358 |
| 1359 if (isHTMLOptionElement(node)) | 1359 if (isHTMLOptionElement(node)) |
| 1360 node = toHTMLOptionElement(*node).ownerSelectElement(); | 1360 node = toHTMLOptionElement(*node).ownerSelectElement(); |
| 1361 | 1361 |
| 1362 LayoutObject* obj = node->renderer(); | 1362 LayoutObject* obj = node->layoutObject(); |
| 1363 if (!obj) | 1363 if (!obj) |
| 1364 return 0; | 1364 return 0; |
| 1365 | 1365 |
| 1366 AXObject* result = axObjectCache()->getOrCreate(obj); | 1366 AXObject* result = axObjectCache()->getOrCreate(obj); |
| 1367 result->updateChildrenIfNecessary(); | 1367 result->updateChildrenIfNecessary(); |
| 1368 | 1368 |
| 1369 // Allow the element to perform any hit-testing it might need to do to reach
non-layout children. | 1369 // Allow the element to perform any hit-testing it might need to do to reach
non-layout children. |
| 1370 result = result->elementAccessibilityHitTest(point); | 1370 result = result->elementAccessibilityHitTest(point); |
| 1371 | 1371 |
| 1372 if (result && result->accessibilityIsIgnored()) { | 1372 if (result && result->accessibilityIsIgnored()) { |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1630 } | 1630 } |
| 1631 | 1631 |
| 1632 // bail if none found | 1632 // bail if none found |
| 1633 if (!currLayoutObject) | 1633 if (!currLayoutObject) |
| 1634 return 0; | 1634 return 0; |
| 1635 | 1635 |
| 1636 // search up the DOM tree for an anchor element | 1636 // search up the DOM tree for an anchor element |
| 1637 // NOTE: this assumes that any non-image with an anchor is an HTMLAnchorElem
ent | 1637 // NOTE: this assumes that any non-image with an anchor is an HTMLAnchorElem
ent |
| 1638 Node* node = currLayoutObject->node(); | 1638 Node* node = currLayoutObject->node(); |
| 1639 for ( ; node; node = node->parentNode()) { | 1639 for ( ; node; node = node->parentNode()) { |
| 1640 if (isHTMLAnchorElement(*node) || (node->renderer() && cache->getOrCreat
e(node->renderer())->isAnchor())) | 1640 if (isHTMLAnchorElement(*node) || (node->layoutObject() && cache->getOrC
reate(node->layoutObject())->isAnchor())) |
| 1641 return toElement(node); | 1641 return toElement(node); |
| 1642 } | 1642 } |
| 1643 | 1643 |
| 1644 return 0; | 1644 return 0; |
| 1645 } | 1645 } |
| 1646 | 1646 |
| 1647 Widget* AXLayoutObject::widgetForAttachmentView() const | 1647 Widget* AXLayoutObject::widgetForAttachmentView() const |
| 1648 { | 1648 { |
| 1649 if (!isAttachment()) | 1649 if (!isAttachment()) |
| 1650 return 0; | 1650 return 0; |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1727 | 1727 |
| 1728 box->scrollToOffset(IntSize(point.x(), point.y())); | 1728 box->scrollToOffset(IntSize(point.x(), point.y())); |
| 1729 } | 1729 } |
| 1730 | 1730 |
| 1731 // | 1731 // |
| 1732 // Notifications that this object may have changed. | 1732 // Notifications that this object may have changed. |
| 1733 // | 1733 // |
| 1734 | 1734 |
| 1735 void AXLayoutObject::handleActiveDescendantChanged() | 1735 void AXLayoutObject::handleActiveDescendantChanged() |
| 1736 { | 1736 { |
| 1737 Element* element = toElement(renderer()->node()); | 1737 Element* element = toElement(layoutObject()->node()); |
| 1738 if (!element) | 1738 if (!element) |
| 1739 return; | 1739 return; |
| 1740 Document& doc = renderer()->document(); | 1740 Document& doc = layoutObject()->document(); |
| 1741 if (!doc.frame()->selection().isFocusedAndActive() || doc.focusedElement() !
= element) | 1741 if (!doc.frame()->selection().isFocusedAndActive() || doc.focusedElement() !
= element) |
| 1742 return; | 1742 return; |
| 1743 AXLayoutObject* activedescendant = toAXLayoutObject(activeDescendant()); | 1743 AXLayoutObject* activedescendant = toAXLayoutObject(activeDescendant()); |
| 1744 | 1744 |
| 1745 if (activedescendant && shouldNotifyActiveDescendant()) | 1745 if (activedescendant && shouldNotifyActiveDescendant()) |
| 1746 toAXObjectCacheImpl(doc.axObjectCache())->postNotification(m_layoutObjec
t, AXObjectCacheImpl::AXActiveDescendantChanged, true); | 1746 toAXObjectCacheImpl(doc.axObjectCache())->postNotification(m_layoutObjec
t, AXObjectCacheImpl::AXActiveDescendantChanged, true); |
| 1747 } | 1747 } |
| 1748 | 1748 |
| 1749 void AXLayoutObject::handleAriaExpandedChanged() | 1749 void AXLayoutObject::handleAriaExpandedChanged() |
| 1750 { | 1750 { |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1870 | 1870 |
| 1871 return TextIterator::rangeLength(range.get()); | 1871 return TextIterator::rangeLength(range.get()); |
| 1872 } | 1872 } |
| 1873 | 1873 |
| 1874 void AXLayoutObject::addInlineTextBoxChildren(bool force) | 1874 void AXLayoutObject::addInlineTextBoxChildren(bool force) |
| 1875 { | 1875 { |
| 1876 Settings* settings = document()->settings(); | 1876 Settings* settings = document()->settings(); |
| 1877 if (!force && (!settings || !settings->inlineTextBoxAccessibilityEnabled())) | 1877 if (!force && (!settings || !settings->inlineTextBoxAccessibilityEnabled())) |
| 1878 return; | 1878 return; |
| 1879 | 1879 |
| 1880 if (!renderer() || !renderer()->isText()) | 1880 if (!layoutObject() || !layoutObject()->isText()) |
| 1881 return; | 1881 return; |
| 1882 | 1882 |
| 1883 if (renderer()->needsLayout()) { | 1883 if (layoutObject()->needsLayout()) { |
| 1884 // If a LayoutText needs layout, its inline text boxes are either | 1884 // If a LayoutText needs layout, its inline text boxes are either |
| 1885 // nonexistent or invalid, so defer until the layout happens and | 1885 // nonexistent or invalid, so defer until the layout happens and |
| 1886 // the layoutObject calls AXObjectCacheImpl::inlineTextBoxesUpdated. | 1886 // the layoutObject calls AXObjectCacheImpl::inlineTextBoxesUpdated. |
| 1887 return; | 1887 return; |
| 1888 } | 1888 } |
| 1889 | 1889 |
| 1890 LayoutText* layoutText = toLayoutText(renderer()); | 1890 LayoutText* layoutText = toLayoutText(layoutObject()); |
| 1891 for (RefPtr<AbstractInlineTextBox> box = layoutText->firstAbstractInlineText
Box(); box.get(); box = box->nextInlineTextBox()) { | 1891 for (RefPtr<AbstractInlineTextBox> box = layoutText->firstAbstractInlineText
Box(); box.get(); box = box->nextInlineTextBox()) { |
| 1892 AXObject* axObject = axObjectCache()->getOrCreate(box.get()); | 1892 AXObject* axObject = axObjectCache()->getOrCreate(box.get()); |
| 1893 if (!axObject->accessibilityIsIgnored()) | 1893 if (!axObject->accessibilityIsIgnored()) |
| 1894 m_children.append(axObject); | 1894 m_children.append(axObject); |
| 1895 } | 1895 } |
| 1896 } | 1896 } |
| 1897 | 1897 |
| 1898 void AXLayoutObject::lineBreaks(Vector<int>& lineBreaks) const | 1898 void AXLayoutObject::lineBreaks(Vector<int>& lineBreaks) const |
| 1899 { | 1899 { |
| 1900 if (!isTextControl()) | 1900 if (!isTextControl()) |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2076 if (startOfConts) { | 2076 if (startOfConts) { |
| 2077 // Case 2: node's parent is an inline which is some node's continuation;
parent is | 2077 // Case 2: node's parent is an inline which is some node's continuation;
parent is |
| 2078 // the earliest node in the continuation chain. | 2078 // the earliest node in the continuation chain. |
| 2079 return startOfConts; | 2079 return startOfConts; |
| 2080 } | 2080 } |
| 2081 | 2081 |
| 2082 LayoutObject* firstChild = parent ? parent->slowFirstChild() : 0; | 2082 LayoutObject* firstChild = parent ? parent->slowFirstChild() : 0; |
| 2083 if (firstChild && firstChild->node()) { | 2083 if (firstChild && firstChild->node()) { |
| 2084 // Case 3: The first sibling is the beginning of a continuation chain. F
ind the origin of that continuation. | 2084 // Case 3: The first sibling is the beginning of a continuation chain. F
ind the origin of that continuation. |
| 2085 // Get the node's layoutObject and follow that continuation chain until
the first child is found. | 2085 // Get the node's layoutObject and follow that continuation chain until
the first child is found. |
| 2086 for (LayoutObject* nodeLayoutFirstChild = firstChild->node()->renderer()
; nodeLayoutFirstChild != firstChild; nodeLayoutFirstChild = firstChild->node()-
>renderer()) { | 2086 for (LayoutObject* nodeLayoutFirstChild = firstChild->node()->layoutObje
ct(); nodeLayoutFirstChild != firstChild; nodeLayoutFirstChild = firstChild->nod
e()->layoutObject()) { |
| 2087 for (LayoutObject* contsTest = nodeLayoutFirstChild; contsTest; cont
sTest = nextContinuation(contsTest)) { | 2087 for (LayoutObject* contsTest = nodeLayoutFirstChild; contsTest; cont
sTest = nextContinuation(contsTest)) { |
| 2088 if (contsTest == firstChild) { | 2088 if (contsTest == firstChild) { |
| 2089 parent = nodeLayoutFirstChild->parent(); | 2089 parent = nodeLayoutFirstChild->parent(); |
| 2090 break; | 2090 break; |
| 2091 } | 2091 } |
| 2092 } | 2092 } |
| 2093 LayoutObject* newFirstChild = parent->slowFirstChild(); | 2093 LayoutObject* newFirstChild = parent->slowFirstChild(); |
| 2094 if (firstChild == newFirstChild) | 2094 if (firstChild == newFirstChild) |
| 2095 break; | 2095 break; |
| 2096 firstChild = newFirstChild; | 2096 firstChild = newFirstChild; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2156 void AXLayoutObject::addHiddenChildren() | 2156 void AXLayoutObject::addHiddenChildren() |
| 2157 { | 2157 { |
| 2158 Node* node = this->node(); | 2158 Node* node = this->node(); |
| 2159 if (!node) | 2159 if (!node) |
| 2160 return; | 2160 return; |
| 2161 | 2161 |
| 2162 // First do a quick run through to determine if we have any hidden nodes (mo
st often we will not). | 2162 // First do a quick run through to determine if we have any hidden nodes (mo
st often we will not). |
| 2163 // If we do have hidden nodes, we need to determine where to insert them so
they match DOM order as close as possible. | 2163 // If we do have hidden nodes, we need to determine where to insert them so
they match DOM order as close as possible. |
| 2164 bool shouldInsertHiddenNodes = false; | 2164 bool shouldInsertHiddenNodes = false; |
| 2165 for (Node* child = node->firstChild(); child; child = child->nextSibling())
{ | 2165 for (Node* child = node->firstChild(); child; child = child->nextSibling())
{ |
| 2166 if (!child->renderer() && isNodeAriaVisible(child)) { | 2166 if (!child->layoutObject() && isNodeAriaVisible(child)) { |
| 2167 shouldInsertHiddenNodes = true; | 2167 shouldInsertHiddenNodes = true; |
| 2168 break; | 2168 break; |
| 2169 } | 2169 } |
| 2170 } | 2170 } |
| 2171 | 2171 |
| 2172 if (!shouldInsertHiddenNodes) | 2172 if (!shouldInsertHiddenNodes) |
| 2173 return; | 2173 return; |
| 2174 | 2174 |
| 2175 // Iterate through all of the children, including those that may have alread
y been added, and | 2175 // Iterate through all of the children, including those that may have alread
y been added, and |
| 2176 // try to insert hidden nodes in the correct place in the DOM order. | 2176 // try to insert hidden nodes in the correct place in the DOM order. |
| 2177 unsigned insertionIndex = 0; | 2177 unsigned insertionIndex = 0; |
| 2178 for (Node* child = node->firstChild(); child; child = child->nextSibling())
{ | 2178 for (Node* child = node->firstChild(); child; child = child->nextSibling())
{ |
| 2179 if (child->renderer()) { | 2179 if (child->layoutObject()) { |
| 2180 // Find out where the last layout sibling is located within m_childr
en. | 2180 // Find out where the last layout sibling is located within m_childr
en. |
| 2181 AXObject* childObject = axObjectCache()->get(child->renderer()); | 2181 AXObject* childObject = axObjectCache()->get(child->layoutObject()); |
| 2182 if (childObject && childObject->accessibilityIsIgnored()) { | 2182 if (childObject && childObject->accessibilityIsIgnored()) { |
| 2183 AccessibilityChildrenVector children = childObject->children(); | 2183 AccessibilityChildrenVector children = childObject->children(); |
| 2184 if (children.size()) | 2184 if (children.size()) |
| 2185 childObject = children.last().get(); | 2185 childObject = children.last().get(); |
| 2186 else | 2186 else |
| 2187 childObject = 0; | 2187 childObject = 0; |
| 2188 } | 2188 } |
| 2189 | 2189 |
| 2190 if (childObject) | 2190 if (childObject) |
| 2191 insertionIndex = m_children.find(childObject) + 1; | 2191 insertionIndex = m_children.find(childObject) + 1; |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2368 } | 2368 } |
| 2369 | 2369 |
| 2370 LayoutRect AXLayoutObject::computeElementRect() const | 2370 LayoutRect AXLayoutObject::computeElementRect() const |
| 2371 { | 2371 { |
| 2372 LayoutObject* obj = m_layoutObject; | 2372 LayoutObject* obj = m_layoutObject; |
| 2373 | 2373 |
| 2374 if (!obj) | 2374 if (!obj) |
| 2375 return LayoutRect(); | 2375 return LayoutRect(); |
| 2376 | 2376 |
| 2377 if (obj->node()) // If we are a continuation, we want to make sure to use th
e primary layoutObject. | 2377 if (obj->node()) // If we are a continuation, we want to make sure to use th
e primary layoutObject. |
| 2378 obj = obj->node()->renderer(); | 2378 obj = obj->node()->layoutObject(); |
| 2379 | 2379 |
| 2380 // absoluteFocusRingBoundingBox will query the hierarchy below this element,
which for large webpages can be very slow. | 2380 // absoluteFocusRingBoundingBox will query the hierarchy below this element,
which for large webpages can be very slow. |
| 2381 // For a web area, which will have the most elements of any element, absolut
eQuads should be used. | 2381 // For a web area, which will have the most elements of any element, absolut
eQuads should be used. |
| 2382 // We should also use absoluteQuads for SVG elements, otherwise transforms w
on't be applied. | 2382 // We should also use absoluteQuads for SVG elements, otherwise transforms w
on't be applied. |
| 2383 | 2383 |
| 2384 LayoutRect result; | 2384 LayoutRect result; |
| 2385 if (obj->isText()) { | 2385 if (obj->isText()) { |
| 2386 Vector<FloatQuad> quads; | 2386 Vector<FloatQuad> quads; |
| 2387 toLayoutText(obj)->absoluteQuads(quads, 0, LayoutText::ClipToEllipsis); | 2387 toLayoutText(obj)->absoluteQuads(quads, 0, LayoutText::ClipToEllipsis); |
| 2388 result = LayoutRect(boundingBoxForQuads(obj, quads)); | 2388 result = LayoutRect(boundingBoxForQuads(obj, quads)); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2401 result.moveBy(IntPoint(popupOrigin - mainOrigin)); | 2401 result.moveBy(IntPoint(popupOrigin - mainOrigin)); |
| 2402 } | 2402 } |
| 2403 | 2403 |
| 2404 // The size of the web area should be the content size, not the clipped size
. | 2404 // The size of the web area should be the content size, not the clipped size
. |
| 2405 if (isWebArea() && obj->frame()->view()) | 2405 if (isWebArea() && obj->frame()->view()) |
| 2406 result.setSize(LayoutSize(obj->frame()->view()->contentsSize())); | 2406 result.setSize(LayoutSize(obj->frame()->view()->contentsSize())); |
| 2407 | 2407 |
| 2408 // Checkboxes and radio buttons include their label as part of their rect. | 2408 // Checkboxes and radio buttons include their label as part of their rect. |
| 2409 if (isCheckboxOrRadio()) { | 2409 if (isCheckboxOrRadio()) { |
| 2410 HTMLLabelElement* label = labelForElement(toElement(m_layoutObject->node
())); | 2410 HTMLLabelElement* label = labelForElement(toElement(m_layoutObject->node
())); |
| 2411 if (label && label->renderer()) { | 2411 if (label && label->layoutObject()) { |
| 2412 LayoutRect labelRect = axObjectCache()->getOrCreate(label)->elementR
ect(); | 2412 LayoutRect labelRect = axObjectCache()->getOrCreate(label)->elementR
ect(); |
| 2413 result.unite(labelRect); | 2413 result.unite(labelRect); |
| 2414 } | 2414 } |
| 2415 } | 2415 } |
| 2416 | 2416 |
| 2417 return result; | 2417 return result; |
| 2418 } | 2418 } |
| 2419 | 2419 |
| 2420 } // namespace blink | 2420 } // namespace blink |
| OLD | NEW |