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 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
240 // We want to notify that the combo box has changed its active descendant, | 240 // We want to notify that the combo box has changed its active descendant, |
241 // but we do not want to change the focus, because focus should remain with
the combo box. | 241 // but we do not want to change the focus, because focus should remain with
the combo box. |
242 if (isComboBox()) | 242 if (isComboBox()) |
243 return true; | 243 return true; |
244 | 244 |
245 return shouldFocusActiveDescendant(); | 245 return shouldFocusActiveDescendant(); |
246 } | 246 } |
247 | 247 |
248 ScrollableArea* AXLayoutObject::getScrollableAreaIfScrollable() const | 248 ScrollableArea* AXLayoutObject::getScrollableAreaIfScrollable() const |
249 { | 249 { |
250 // FIXME(dmazzoni): the plan is to get rid of AXScrollView, but until | 250 if (isWebArea()) |
251 // this is done, a WebArea delegates its scrolling to its parent scroll view
. | 251 return documentFrameView(); |
252 // http://crbug.com/484878 | |
253 if (parentObject() && parentObject()->isAXScrollView()) | |
254 return parentObject()->getScrollableAreaIfScrollable(); | |
255 | 252 |
256 if (!m_layoutObject || !m_layoutObject->isBox()) | 253 if (!m_layoutObject || !m_layoutObject->isBox()) |
257 return 0; | 254 return 0; |
258 | 255 |
259 LayoutBox* box = toLayoutBox(m_layoutObject); | 256 LayoutBox* box = toLayoutBox(m_layoutObject); |
260 if (!box->canBeScrolledAndHasScrollableArea()) | 257 if (!box->canBeScrolledAndHasScrollableArea()) |
261 return 0; | 258 return 0; |
262 | 259 |
263 return box->scrollableArea(); | 260 return box->scrollableArea(); |
264 } | 261 } |
(...skipping 1306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1571 if (ariaRoleAttribute() == MenuRole) { | 1568 if (ariaRoleAttribute() == MenuRole) { |
1572 AXObject* parent = menuButtonForMenu(); | 1569 AXObject* parent = menuButtonForMenu(); |
1573 if (parent) | 1570 if (parent) |
1574 return parent; | 1571 return parent; |
1575 } | 1572 } |
1576 | 1573 |
1577 LayoutObject* parentObj = layoutParentObject(); | 1574 LayoutObject* parentObj = layoutParentObject(); |
1578 if (parentObj) | 1575 if (parentObj) |
1579 return axObjectCache().getOrCreate(parentObj); | 1576 return axObjectCache().getOrCreate(parentObj); |
1580 | 1577 |
1581 // WebArea's parent should be the scroll view containing it. | |
1582 if (isWebArea()) | |
1583 return axObjectCache().getOrCreate(m_layoutObject->frame()->view()); | |
1584 | |
1585 return 0; | 1578 return 0; |
1586 } | 1579 } |
1587 | 1580 |
1588 AXObject* AXLayoutObject::computeParentIfExists() const | 1581 AXObject* AXLayoutObject::computeParentIfExists() const |
1589 { | 1582 { |
1590 if (!m_layoutObject) | 1583 if (!m_layoutObject) |
1591 return 0; | 1584 return 0; |
1592 | 1585 |
1593 if (ariaRoleAttribute() == MenuBarRole) | 1586 if (ariaRoleAttribute() == MenuBarRole) |
1594 return axObjectCache().get(m_layoutObject->parent()); | 1587 return axObjectCache().get(m_layoutObject->parent()); |
1595 | 1588 |
1596 // menuButton and its corresponding menu are DOM siblings, but Accessibility
needs them to be parent/child | 1589 // menuButton and its corresponding menu are DOM siblings, but Accessibility
needs them to be parent/child |
1597 if (ariaRoleAttribute() == MenuRole) { | 1590 if (ariaRoleAttribute() == MenuRole) { |
1598 AXObject* parent = menuButtonForMenu(); | 1591 AXObject* parent = menuButtonForMenu(); |
1599 if (parent) | 1592 if (parent) |
1600 return parent; | 1593 return parent; |
1601 } | 1594 } |
1602 | 1595 |
1603 LayoutObject* parentObj = layoutParentObject(); | 1596 LayoutObject* parentObj = layoutParentObject(); |
1604 if (parentObj) | 1597 if (parentObj) |
1605 return axObjectCache().get(parentObj); | 1598 return axObjectCache().get(parentObj); |
1606 | 1599 |
1607 // WebArea's parent should be the scroll view containing it. | |
1608 if (isWebArea()) | |
1609 return axObjectCache().get(m_layoutObject->frame()->view()); | |
1610 | |
1611 return 0; | 1600 return 0; |
1612 } | 1601 } |
1613 | 1602 |
1614 // | 1603 // |
1615 // Low-level accessibility tree exploration, only for use within the accessibili
ty module. | 1604 // Low-level accessibility tree exploration, only for use within the accessibili
ty module. |
1616 // | 1605 // |
1617 | 1606 |
1618 AXObject* AXLayoutObject::firstChild() const | 1607 AXObject* AXLayoutObject::firstChild() const |
1619 { | 1608 { |
1620 if (!m_layoutObject) | 1609 if (!m_layoutObject) |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1685 | 1674 |
1686 HeapVector<Member<AXObject>> ownedChildren; | 1675 HeapVector<Member<AXObject>> ownedChildren; |
1687 computeAriaOwnsChildren(ownedChildren); | 1676 computeAriaOwnsChildren(ownedChildren); |
1688 | 1677 |
1689 for (AXObject* obj = firstChild(); obj; obj = obj->nextSibling()) { | 1678 for (AXObject* obj = firstChild(); obj; obj = obj->nextSibling()) { |
1690 if (!axObjectCache().isAriaOwned(obj)) | 1679 if (!axObjectCache().isAriaOwned(obj)) |
1691 addChild(obj); | 1680 addChild(obj); |
1692 } | 1681 } |
1693 | 1682 |
1694 addHiddenChildren(); | 1683 addHiddenChildren(); |
1695 addAttachmentChildren(); | |
1696 addPopupChildren(); | 1684 addPopupChildren(); |
1697 addImageMapChildren(); | 1685 addImageMapChildren(); |
1698 addTextFieldChildren(); | 1686 addTextFieldChildren(); |
1699 addCanvasChildren(); | 1687 addCanvasChildren(); |
1700 addRemoteSVGChildren(); | 1688 addRemoteSVGChildren(); |
1701 addInlineTextBoxChildren(false); | 1689 addInlineTextBoxChildren(false); |
1702 | 1690 |
1703 for (const auto& child : m_children) { | 1691 for (const auto& child : m_children) { |
1704 if (!child->cachedParentObject()) | 1692 if (!child->cachedParentObject()) |
1705 child->setParent(this); | 1693 child->setParent(this); |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1798 // NOTE: this assumes that any non-image with an anchor is an HTMLAnchorElem
ent | 1786 // NOTE: this assumes that any non-image with an anchor is an HTMLAnchorElem
ent |
1799 Node* node = currLayoutObject->node(); | 1787 Node* node = currLayoutObject->node(); |
1800 for ( ; node; node = node->parentNode()) { | 1788 for ( ; node; node = node->parentNode()) { |
1801 if (isHTMLAnchorElement(*node) || (node->layoutObject() && cache.getOrCr
eate(node->layoutObject())->isAnchor())) | 1789 if (isHTMLAnchorElement(*node) || (node->layoutObject() && cache.getOrCr
eate(node->layoutObject())->isAnchor())) |
1802 return toElement(node); | 1790 return toElement(node); |
1803 } | 1791 } |
1804 | 1792 |
1805 return 0; | 1793 return 0; |
1806 } | 1794 } |
1807 | 1795 |
1808 Widget* AXLayoutObject::widgetForAttachmentView() const | |
1809 { | |
1810 if (!isAttachment()) | |
1811 return 0; | |
1812 return toLayoutPart(m_layoutObject)->widget(); | |
1813 } | |
1814 | |
1815 // | 1796 // |
1816 // Functions that retrieve the current selection. | 1797 // Functions that retrieve the current selection. |
1817 // | 1798 // |
1818 | 1799 |
1819 AXObject::AXRange AXLayoutObject::selection() const | 1800 AXObject::AXRange AXLayoutObject::selection() const |
1820 { | 1801 { |
1821 AXRange textSelection = textControlSelection(); | 1802 AXRange textSelection = textControlSelection(); |
1822 if (textSelection.isValid()) | 1803 if (textSelection.isValid()) |
1823 return textSelection; | 1804 return textSelection; |
1824 | 1805 |
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2277 if (!isTabItem() || !m_layoutObject) | 2258 if (!isTabItem() || !m_layoutObject) |
2278 return false; | 2259 return false; |
2279 | 2260 |
2280 Node* node = m_layoutObject->node(); | 2261 Node* node = m_layoutObject->node(); |
2281 if (!node || !node->isElementNode()) | 2262 if (!node || !node->isElementNode()) |
2282 return false; | 2263 return false; |
2283 | 2264 |
2284 // The ARIA spec says a tab item can also be selected if it is aria-labeled
by a tabpanel | 2265 // The ARIA spec says a tab item can also be selected if it is aria-labeled
by a tabpanel |
2285 // that has keyboard focus inside of it, or if a tabpanel in its aria-contro
ls list has KB | 2266 // that has keyboard focus inside of it, or if a tabpanel in its aria-contro
ls list has KB |
2286 // focus inside of it. | 2267 // focus inside of it. |
2287 AXObject* focusedElement = focusedUIElement(); | 2268 Document* doc = document(); |
| 2269 if (!doc) |
| 2270 return false; |
| 2271 |
| 2272 Element* focusedElement = doc->activeElement(); |
2288 if (!focusedElement) | 2273 if (!focusedElement) |
2289 return false; | 2274 return false; |
2290 | 2275 |
2291 WillBeHeapVector<RawPtrWillBeMember<Element>> elements; | 2276 WillBeHeapVector<RawPtrWillBeMember<Element>> elements; |
2292 elementsFromAttribute(elements, aria_controlsAttr); | 2277 elementsFromAttribute(elements, aria_controlsAttr); |
2293 | 2278 |
2294 for (const auto& element : elements) { | 2279 for (const auto& element : elements) { |
2295 AXObject* tabPanel = axObjectCache().getOrCreate(element); | 2280 AXObject* tabPanel = axObjectCache().getOrCreate(element); |
2296 | 2281 |
2297 // A tab item should only control tab panels. | 2282 // A tab item should only control tab panels. |
2298 if (!tabPanel || tabPanel->roleValue() != TabPanelRole) | 2283 if (!tabPanel || tabPanel->roleValue() != TabPanelRole) |
2299 continue; | 2284 continue; |
2300 | 2285 |
2301 AXObject* checkFocusElement = focusedElement; | 2286 Element* checkFocusElement = focusedElement; |
2302 // Check if the focused element is a descendant of the element controlle
d by the tab item. | 2287 // Check if the focused element is a descendant of the element controlle
d by the tab item. |
2303 while (checkFocusElement) { | 2288 while (checkFocusElement) { |
2304 if (tabPanel == checkFocusElement) | 2289 if (tabPanel->node() == checkFocusElement) |
2305 return true; | 2290 return true; |
2306 checkFocusElement = checkFocusElement->parentObject(); | 2291 checkFocusElement = checkFocusElement->parentElement(); |
2307 } | 2292 } |
2308 } | 2293 } |
2309 | 2294 |
2310 return false; | 2295 return false; |
2311 } | 2296 } |
2312 | 2297 |
2313 AXObject* AXLayoutObject::accessibilityImageMapHitTest(HTMLAreaElement* area, co
nst IntPoint& point) const | 2298 AXObject* AXLayoutObject::accessibilityImageMapHitTest(HTMLAreaElement* area, co
nst IntPoint& point) const |
2314 { | 2299 { |
2315 if (!area) | 2300 if (!area) |
2316 return 0; | 2301 return 0; |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2508 if (!isHTMLCanvasElement(node())) | 2493 if (!isHTMLCanvasElement(node())) |
2509 return; | 2494 return; |
2510 | 2495 |
2511 // If it's a canvas, it won't have laid out children, but it might have acce
ssible fallback content. | 2496 // If it's a canvas, it won't have laid out children, but it might have acce
ssible fallback content. |
2512 // Clear m_haveChildren because AXNodeObject::addChildren will expect it to
be false. | 2497 // Clear m_haveChildren because AXNodeObject::addChildren will expect it to
be false. |
2513 ASSERT(!m_children.size()); | 2498 ASSERT(!m_children.size()); |
2514 m_haveChildren = false; | 2499 m_haveChildren = false; |
2515 AXNodeObject::addChildren(); | 2500 AXNodeObject::addChildren(); |
2516 } | 2501 } |
2517 | 2502 |
2518 void AXLayoutObject::addAttachmentChildren() | |
2519 { | |
2520 if (!isAttachment()) | |
2521 return; | |
2522 | |
2523 // FrameView's need to be inserted into the AX hierarchy when encountered. | |
2524 Widget* widget = widgetForAttachmentView(); | |
2525 if (!widget || !widget->isFrameView()) | |
2526 return; | |
2527 | |
2528 AXObject* axWidget = axObjectCache().getOrCreate(widget); | |
2529 if (!axWidget->accessibilityIsIgnored()) | |
2530 m_children.append(axWidget); | |
2531 } | |
2532 | |
2533 void AXLayoutObject::addPopupChildren() | 2503 void AXLayoutObject::addPopupChildren() |
2534 { | 2504 { |
2535 if (!isHTMLInputElement(node())) | 2505 if (!isHTMLInputElement(node())) |
2536 return; | 2506 return; |
2537 if (AXObject* axPopup = toHTMLInputElement(node())->popupRootAXObject()) | 2507 if (AXObject* axPopup = toHTMLInputElement(node())->popupRootAXObject()) |
2538 m_children.append(axPopup); | 2508 m_children.append(axPopup); |
2539 } | 2509 } |
2540 | 2510 |
2541 void AXLayoutObject::addRemoteSVGChildren() | 2511 void AXLayoutObject::addRemoteSVGChildren() |
2542 { | 2512 { |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2635 if (label && label->layoutObject()) { | 2605 if (label && label->layoutObject()) { |
2636 LayoutRect labelRect = axObjectCache().getOrCreate(label)->elementRe
ct(); | 2606 LayoutRect labelRect = axObjectCache().getOrCreate(label)->elementRe
ct(); |
2637 result.unite(labelRect); | 2607 result.unite(labelRect); |
2638 } | 2608 } |
2639 } | 2609 } |
2640 | 2610 |
2641 return result; | 2611 return result; |
2642 } | 2612 } |
2643 | 2613 |
2644 } // namespace blink | 2614 } // namespace blink |
OLD | NEW |