| 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 |