OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <atlbase.h> | 5 #include <atlbase.h> |
6 #include <atlcom.h> | 6 #include <atlcom.h> |
7 #include <limits.h> | 7 #include <limits.h> |
8 #include <oleacc.h> | 8 #include <oleacc.h> |
9 #include <stdint.h> | 9 #include <stdint.h> |
10 | 10 |
11 #include "base/containers/hash_tables.h" | 11 #include "base/containers/hash_tables.h" |
12 #include "base/lazy_instance.h" | 12 #include "base/lazy_instance.h" |
13 #include "base/strings/string_number_conversions.h" | 13 #include "base/strings/string_number_conversions.h" |
14 #include "base/strings/string_util.h" | 14 #include "base/strings/string_util.h" |
15 #include "base/strings/utf_string_conversions.h" | 15 #include "base/strings/utf_string_conversions.h" |
16 #include "base/win/enum_variant.h" | 16 #include "base/win/enum_variant.h" |
17 #include "base/win/scoped_comptr.h" | 17 #include "base/win/scoped_comptr.h" |
18 #include "base/win/scoped_variant.h" | 18 #include "base/win/scoped_variant.h" |
19 #include "third_party/iaccessible2/ia2_api_all.h" | 19 #include "third_party/iaccessible2/ia2_api_all.h" |
20 #include "third_party/skia/include/core/SkColor.h" | 20 #include "third_party/skia/include/core/SkColor.h" |
21 #include "ui/accessibility/ax_action_data.h" | 21 #include "ui/accessibility/ax_action_data.h" |
22 #include "ui/accessibility/ax_node_data.h" | 22 #include "ui/accessibility/ax_node_data.h" |
| 23 #include "ui/accessibility/ax_role_properties.h" |
23 #include "ui/accessibility/ax_text_utils.h" | 24 #include "ui/accessibility/ax_text_utils.h" |
24 #include "ui/accessibility/ax_tree_data.h" | 25 #include "ui/accessibility/ax_tree_data.h" |
25 #include "ui/accessibility/platform/ax_platform_node_delegate.h" | 26 #include "ui/accessibility/platform/ax_platform_node_delegate.h" |
26 #include "ui/accessibility/platform/ax_platform_node_win.h" | 27 #include "ui/accessibility/platform/ax_platform_node_win.h" |
27 #include "ui/base/win/atl_module.h" | 28 #include "ui/base/win/atl_module.h" |
28 #include "ui/gfx/geometry/rect_conversions.h" | 29 #include "ui/gfx/geometry/rect_conversions.h" |
29 | 30 |
30 // | 31 // |
31 // Macros to use at the top of any AXPlatformNodeWin function that implements | 32 // Macros to use at the top of any AXPlatformNodeWin function that implements |
32 // a COM interface. Because COM objects are reference counted and clients | 33 // a COM interface. Because COM objects are reference counted and clients |
(...skipping 707 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
740 // | 741 // |
741 | 742 |
742 STDMETHODIMP AXPlatformNodeWin::role(LONG* role) { | 743 STDMETHODIMP AXPlatformNodeWin::role(LONG* role) { |
743 COM_OBJECT_VALIDATE_1_ARG(role); | 744 COM_OBJECT_VALIDATE_1_ARG(role); |
744 *role = MSAARole(); | 745 *role = MSAARole(); |
745 return S_OK; | 746 return S_OK; |
746 } | 747 } |
747 | 748 |
748 STDMETHODIMP AXPlatformNodeWin::get_states(AccessibleStates* states) { | 749 STDMETHODIMP AXPlatformNodeWin::get_states(AccessibleStates* states) { |
749 COM_OBJECT_VALIDATE_1_ARG(states); | 750 COM_OBJECT_VALIDATE_1_ARG(states); |
750 // There are only a couple of states we need to support | 751 *states = IA2State(); |
751 // in IAccessible2. If any more are added, we may want to | |
752 // add a helper function like MSAAState. | |
753 *states = IA2_STATE_OPAQUE; | |
754 if (GetData().state & (1 << ui::AX_STATE_EDITABLE)) | |
755 *states |= IA2_STATE_EDITABLE; | |
756 if (GetData().state & (1 << ui::AX_STATE_VERTICAL)) | |
757 *states |= IA2_STATE_VERTICAL; | |
758 | |
759 return S_OK; | 752 return S_OK; |
760 } | 753 } |
761 | 754 |
762 STDMETHODIMP AXPlatformNodeWin::get_uniqueID(LONG* unique_id) { | 755 STDMETHODIMP AXPlatformNodeWin::get_uniqueID(LONG* unique_id) { |
763 COM_OBJECT_VALIDATE_1_ARG(unique_id); | 756 COM_OBJECT_VALIDATE_1_ARG(unique_id); |
764 *unique_id = -unique_id_; | 757 *unique_id = -unique_id_; |
765 return S_OK; | 758 return S_OK; |
766 } | 759 } |
767 | 760 |
768 STDMETHODIMP AXPlatformNodeWin::get_windowHandle(HWND* window_handle) { | 761 STDMETHODIMP AXPlatformNodeWin::get_windowHandle(HWND* window_handle) { |
(...skipping 829 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1598 return false; | 1591 return false; |
1599 } | 1592 } |
1600 | 1593 |
1601 auto* parent = FromNativeViewAccessible(GetParent()); | 1594 auto* parent = FromNativeViewAccessible(GetParent()); |
1602 if (!parent) | 1595 if (!parent) |
1603 return false; | 1596 return false; |
1604 | 1597 |
1605 return parent->GetData().role == ui::AX_ROLE_IFRAME_PRESENTATIONAL; | 1598 return parent->GetData().role == ui::AX_ROLE_IFRAME_PRESENTATIONAL; |
1606 } | 1599 } |
1607 | 1600 |
| 1601 int32_t AXPlatformNodeWin::IA2State() { |
| 1602 const AXNodeData& data = GetData(); |
| 1603 |
| 1604 int32_t ia2_state = IA2_STATE_OPAQUE; |
| 1605 |
| 1606 const auto checked_state = static_cast<ui::AXCheckedState>( |
| 1607 GetIntAttribute(ui::AX_ATTR_CHECKED_STATE)); |
| 1608 if (checked_state) { |
| 1609 ia2_state |= IA2_STATE_CHECKABLE; |
| 1610 } |
| 1611 |
| 1612 if (HasIntAttribute(ui::AX_ATTR_INVALID_STATE) && |
| 1613 GetIntAttribute(ui::AX_ATTR_INVALID_STATE) != ui::AX_INVALID_STATE_FALSE) |
| 1614 ia2_state |= IA2_STATE_INVALID_ENTRY; |
| 1615 if (data.HasState(ui::AX_STATE_REQUIRED)) |
| 1616 ia2_state |= IA2_STATE_REQUIRED; |
| 1617 if (data.HasState(ui::AX_STATE_VERTICAL)) |
| 1618 ia2_state |= IA2_STATE_VERTICAL; |
| 1619 if (data.HasState(ui::AX_STATE_HORIZONTAL)) |
| 1620 ia2_state |= IA2_STATE_HORIZONTAL; |
| 1621 |
| 1622 const bool is_editable = data.HasState(ui::AX_STATE_EDITABLE); |
| 1623 if (is_editable) |
| 1624 ia2_state |= IA2_STATE_EDITABLE; |
| 1625 |
| 1626 if (IsRichTextControl() || ui::IsEditField(data.role)) { |
| 1627 // Support multi/single line states if root editable or appropriate role. |
| 1628 // We support the edit box roles even if the area is not actually editable, |
| 1629 // because it is technically feasible for JS to implement the edit box |
| 1630 // by controlling selection. |
| 1631 if (data.HasState(ui::AX_STATE_MULTILINE)) { |
| 1632 ia2_state |= IA2_STATE_MULTI_LINE; |
| 1633 } else { |
| 1634 ia2_state |= IA2_STATE_SINGLE_LINE; |
| 1635 } |
| 1636 } |
| 1637 |
| 1638 if (!GetStringAttribute(ui::AX_ATTR_AUTO_COMPLETE).empty()) |
| 1639 ia2_state |= IA2_STATE_SUPPORTS_AUTOCOMPLETION; |
| 1640 |
| 1641 if (GetBoolAttribute(ui::AX_ATTR_MODAL)) |
| 1642 ia2_state |= IA2_STATE_MODAL; |
| 1643 |
| 1644 switch (data.role) { |
| 1645 case ui::AX_ROLE_MENU_LIST_POPUP: |
| 1646 ia2_state &= ~(IA2_STATE_EDITABLE); |
| 1647 break; |
| 1648 case ui::AX_ROLE_MENU_LIST_OPTION: |
| 1649 ia2_state &= ~(IA2_STATE_EDITABLE); |
| 1650 break; |
| 1651 case ui::AX_ROLE_SCROLL_AREA: |
| 1652 ia2_state &= ~(IA2_STATE_EDITABLE); |
| 1653 break; |
| 1654 case ui::AX_ROLE_TEXT_FIELD: |
| 1655 case ui::AX_ROLE_SEARCH_BOX: |
| 1656 if (data.HasState(ui::AX_STATE_MULTILINE)) { |
| 1657 ia2_state |= IA2_STATE_MULTI_LINE; |
| 1658 } else { |
| 1659 ia2_state |= IA2_STATE_SINGLE_LINE; |
| 1660 } |
| 1661 ia2_state |= IA2_STATE_SELECTABLE_TEXT; |
| 1662 break; |
| 1663 default: |
| 1664 break; |
| 1665 } |
| 1666 return ia2_state; |
| 1667 } |
| 1668 |
1608 bool AXPlatformNodeWin::ShouldNodeHaveReadonlyState( | 1669 bool AXPlatformNodeWin::ShouldNodeHaveReadonlyState( |
1609 const AXNodeData& data) const { | 1670 const AXNodeData& data) const { |
1610 if (data.GetBoolAttribute(ui::AX_ATTR_ARIA_READONLY)) | 1671 if (data.GetBoolAttribute(ui::AX_ATTR_ARIA_READONLY)) |
1611 return true; | 1672 return true; |
1612 | 1673 |
1613 if (!data.HasState(ui::AX_STATE_READ_ONLY)) | 1674 if (!data.HasState(ui::AX_STATE_READ_ONLY)) |
1614 return false; | 1675 return false; |
1615 | 1676 |
1616 switch (data.role) { | 1677 switch (data.role) { |
1617 case ui::AX_ROLE_ARTICLE: | 1678 case ui::AX_ROLE_ARTICLE: |
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1939 if (container && container->GetData().role == ui::AX_ROLE_GROUP) | 2000 if (container && container->GetData().role == ui::AX_ROLE_GROUP) |
1940 container = FromNativeViewAccessible(container->GetParent()); | 2001 container = FromNativeViewAccessible(container->GetParent()); |
1941 | 2002 |
1942 if (!container) | 2003 if (!container) |
1943 return false; | 2004 return false; |
1944 | 2005 |
1945 return container->GetData().role == ui::AX_ROLE_TREE_GRID; | 2006 return container->GetData().role == ui::AX_ROLE_TREE_GRID; |
1946 } | 2007 } |
1947 | 2008 |
1948 } // namespace ui | 2009 } // namespace ui |
OLD | NEW |