diff --git a/change/react-native-windows-2019-10-21-16-17-09-action.json b/change/react-native-windows-2019-10-21-16-17-09-action.json new file mode 100644 index 00000000000..959f4dbef4f --- /dev/null +++ b/change/react-native-windows-2019-10-21-16-17-09-action.json @@ -0,0 +1,9 @@ +{ + "type": "none", + "comment": "Implement accessibilityAction", + "packageName": "react-native-windows", + "email": "licanhua@live.com", + "commit": "e931062bbaef57538e8e7ea06c6f1fb929f7b024", + "date": "2019-10-21T23:17:08.915Z", + "file": "F:\\repo\\react-native-windows\\change\\react-native-windows-2019-10-21-16-17-09-action.json" +} \ No newline at end of file diff --git a/packages/E2ETest/app/AccessibilityTestPage.tsx b/packages/E2ETest/app/AccessibilityTestPage.tsx index 8454243c6b5..de4059f1b32 100644 --- a/packages/E2ETest/app/AccessibilityTestPage.tsx +++ b/packages/E2ETest/app/AccessibilityTestPage.tsx @@ -1,15 +1,59 @@ -import { View, Text } from 'react-native' +/** + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. + */ + +import { View, Text, ViewProps } from 'react-native' import React, { useState } from 'react'; +// MyView is a workaround. Currently in typescript, accessibilityAction doesn't allow name to be any string. +const MyView = (props: any) => (); + export function AccessibilityTestPage() { const [pressedCountNested, setPressedCountNested] = useState(0); const [pressedCount, setPressedCount] = useState(0); + const [accessibilityAction, setAccessibilityAction] = useState(''); + return ( - - I'm bold - setPressedCountNested(pressedCountNested + 1)} accessible={true} accessibilityLiveRegion="polite">Pressed {pressedCountNested} times - - setPressedCount(pressedCount + 1)} accessible={true} accessibilityLiveRegion="polite">Pressed {pressedCount} times + + + I'm bold + setPressedCountNested(pressedCountNested + 1)} accessible={true} accessibilityLiveRegion="polite">Pressed {pressedCountNested} times + + setPressedCount(pressedCount + 1)} accessible={true} accessibilityLiveRegion="polite">Pressed {pressedCount} times + + + { + switch (event.nativeEvent.actionName) { + case 'toggle': + setAccessibilityAction('toggle action success'); + break; + case 'invoke': + setAccessibilityAction('invoke action success'); + break; + case 'expand': + setAccessibilityAction('expand action success'); + break; + case 'collapseIt': + setAccessibilityAction('collapseIt action success'); + break; + } + }} + > + accessibilityAction:{accessibilityAction} + + ) } \ No newline at end of file diff --git a/vnext/ReactUWP/ABI/idl/AccessibilityAction.idl b/vnext/ReactUWP/ABI/idl/AccessibilityAction.idl new file mode 100644 index 00000000000..85b4261016e --- /dev/null +++ b/vnext/ReactUWP/ABI/idl/AccessibilityAction.idl @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// Note: This is just a workaround should be removed in the future. +// Currently there are two folders which hold idl files: ABI/idl and Views/cppwinrt +// ABI/idl is compiled by MidlRT target, but Views/cppwinrt is built by buildcppwinrt. +// Views/cppwinrt is not merged into ReactUWP.Winmd, but ABI/idl is merged. +// so it hits without this file: Exception thrown at 0x7646EF12 (KernelBase.dll) in ReactUWPTestApp.exe: WinRT originate error - 0x80131522 : 'System.TypeLoadException: Could not find Windows Runtime type 'react.uwp.AccessibilityAction' +// This file has the same 'struct AccessibilityAction' in Views/cppwinrt/AccessibilityAction.idl. + +import "inspectable.idl"; + +namespace react.uwp +{ + [version(1)] + + struct AccessibilityAction { + String Name; + String Label; + }; +} diff --git a/vnext/ReactUWP/ReactUWP.vcxproj b/vnext/ReactUWP/ReactUWP.vcxproj index 5bfbd4d2a76..4c592c480ad 100644 --- a/vnext/ReactUWP/ReactUWP.vcxproj +++ b/vnext/ReactUWP/ReactUWP.vcxproj @@ -421,6 +421,7 @@ + diff --git a/vnext/ReactUWP/Views/DynamicAutomationPeer.cpp b/vnext/ReactUWP/Views/DynamicAutomationPeer.cpp index 4757ab0306a..a8f2b40ed38 100644 --- a/vnext/ReactUWP/Views/DynamicAutomationPeer.cpp +++ b/vnext/ReactUWP/Views/DynamicAutomationPeer.cpp @@ -152,6 +152,8 @@ winrt::hstring DynamicAutomationPeer::GetItemStatusCore() const { // IInvokeProvider void DynamicAutomationPeer::Invoke() const { + DynamicAutomationProperties::DispatchAccessibilityAction(Owner(), L"invoke"); + if (auto const &invokeHandler = GetAccessibilityInvokeEventHandler()) { invokeHandler(); } @@ -183,15 +185,15 @@ winrt::IRawElementProviderSimple DynamicAutomationPeer::SelectionContainer() con } void DynamicAutomationPeer::AddToSelection() const { - // Right now RN does not have "selection" events, so this is a no-op + DynamicAutomationProperties::DispatchAccessibilityAction(Owner(), L"addToSelection"); } void DynamicAutomationPeer::RemoveFromSelection() const { - // Right now RN does not have "selection" events, so this is a no-op + DynamicAutomationProperties::DispatchAccessibilityAction(Owner(), L"removeFromSelection"); } void DynamicAutomationPeer::Select() const { - // Right now RN does not have "selection" events, so this is a no-op + DynamicAutomationProperties::DispatchAccessibilityAction(Owner(), L"select"); } // IToggleProvider @@ -210,6 +212,8 @@ winrt::ToggleState DynamicAutomationPeer::ToggleState() const { } void DynamicAutomationPeer::Toggle() const { + DynamicAutomationProperties::DispatchAccessibilityAction(Owner(), L"toggle"); + if (auto const &invokeHandler = GetAccessibilityInvokeEventHandler()) { invokeHandler(); } @@ -233,11 +237,11 @@ winrt::ExpandCollapseState DynamicAutomationPeer::ExpandCollapseState() const { } void DynamicAutomationPeer::Expand() const { - // Right now RN does not have "expand" events, so this is a no-op + DynamicAutomationProperties::DispatchAccessibilityAction(Owner(), L"expand"); } void DynamicAutomationPeer::Collapse() const { - // Right now RN does not have "collapse" events, so this is a no-op + DynamicAutomationProperties::DispatchAccessibilityAction(Owner(), L"collapse"); } // Private Methods diff --git a/vnext/ReactUWP/Views/DynamicAutomationPeer.h b/vnext/ReactUWP/Views/DynamicAutomationPeer.h index 0293f5cddf7..d743880a029 100644 --- a/vnext/ReactUWP/Views/DynamicAutomationPeer.h +++ b/vnext/ReactUWP/Views/DynamicAutomationPeer.h @@ -70,6 +70,22 @@ struct DynamicAutomationPeer : DynamicAutomationPeerT { bool HasAccessibilityState(winrt::react::uwp::AccessibilityStates state) const; bool GetAccessibilityState(winrt::react::uwp::AccessibilityStates state) const; winrt::react::uwp::AccessibilityInvokeEventHandler GetAccessibilityInvokeEventHandler() const; + + static winrt::Windows::UI::Xaml::DependencyProperty AccessibilityActionsProperty(); + static void SetAccessibilityActions( + Windows::UI::Xaml::UIElement const &element, + Windows::Foundation::Collections::IVector const &value); + static Windows::Foundation::Collections::IVector GetAccessibilityActions( + Windows::UI::Xaml::UIElement const &element); + static void DispatchAccessibilityAction( + Windows::UI::Xaml::UIElement const &element, + std::wstring_view const &actionName); + static winrt::Windows::UI::Xaml::DependencyProperty AccessibilityActionEventHandlerProperty(); + static void SetAccessibilityActionEventHandler( + Windows::UI::Xaml::UIElement const &element, + winrt::react::uwp::AccessibilityActionEventHandler const &value); + static winrt::react::uwp::AccessibilityActionEventHandler GetAccessibilityActionEventHandler( + winrt::Windows::UI::Xaml::UIElement const &element); }; } // namespace winrt::react::uwp::implementation diff --git a/vnext/ReactUWP/Views/DynamicAutomationProperties.cpp b/vnext/ReactUWP/Views/DynamicAutomationProperties.cpp index 1677b5777cd..45f7f11f73c 100644 --- a/vnext/ReactUWP/Views/DynamicAutomationProperties.cpp +++ b/vnext/ReactUWP/Views/DynamicAutomationProperties.cpp @@ -206,4 +206,69 @@ winrt::react::uwp::AccessibilityInvokeEventHandler DynamicAutomationProperties:: element.GetValue(AccessibilityInvokeEventHandlerProperty())); } +winrt::Windows::UI::Xaml::DependencyProperty DynamicAutomationProperties::AccessibilityActionsProperty() { + static winrt::DependencyProperty s_AccessibilityActionsProperty = winrt::DependencyProperty::RegisterAttached( + L"AccessibilityActions", + winrt::xaml_typename>(), + dynamicAutomationTypeName, + winrt::PropertyMetadata(nullptr)); + + return s_AccessibilityActionsProperty; +} + +void DynamicAutomationProperties::SetAccessibilityActions( + Windows::UI::Xaml::UIElement const &element, + Windows::Foundation::Collections::IVector const &value) { + return element.SetValue(AccessibilityActionsProperty(), winrt::box_value(value)); +} + +Windows::Foundation::Collections::IVector +DynamicAutomationProperties::GetAccessibilityActions(Windows::UI::Xaml::UIElement const &element) { + return winrt::unbox_value>( + element.GetValue(AccessibilityActionsProperty())); +} + +void DynamicAutomationProperties::DispatchAccessibilityAction( + Windows::UI::Xaml::UIElement const &element, + std::wstring_view const &actionName) { + if (element) { + auto vector = GetAccessibilityActions(element); + if (vector) { + for (uint32_t i = 0; i < vector.Size(); i++) { + auto item = vector.GetAt(i); + + if (item.Name.operator std::wstring_view() == actionName) { + if (auto const &handler = GetAccessibilityActionEventHandler(element)) { + handler(item); + } + } + } + } + } +} + +winrt::Windows::UI::Xaml::DependencyProperty DynamicAutomationProperties::AccessibilityActionEventHandlerProperty() { + static winrt::DependencyProperty s_AccessibilityActionEventHandlerProperty = + winrt::DependencyProperty::RegisterAttached( + L"AccessibilityActionEventHandler", + winrt::xaml_typename(), + dynamicAutomationTypeName, + winrt::PropertyMetadata(winrt::box_value(nullptr))); + + return s_AccessibilityActionEventHandlerProperty; +} + +void DynamicAutomationProperties::SetAccessibilityActionEventHandler( + winrt::Windows::UI::Xaml::UIElement const &element, + winrt::react::uwp::AccessibilityActionEventHandler const &value) { + element.SetValue( + AccessibilityActionEventHandlerProperty(), + winrt::box_value(value)); +} + +winrt::react::uwp::AccessibilityActionEventHandler DynamicAutomationProperties::GetAccessibilityActionEventHandler( + winrt::Windows::UI::Xaml::UIElement const &element) { + return winrt::unbox_value( + element.GetValue(AccessibilityActionEventHandlerProperty())); +} } // namespace winrt::react::uwp::implementation diff --git a/vnext/ReactUWP/Views/DynamicAutomationProperties.h b/vnext/ReactUWP/Views/DynamicAutomationProperties.h index f174288fb0d..f39b9c79619 100644 --- a/vnext/ReactUWP/Views/DynamicAutomationProperties.h +++ b/vnext/ReactUWP/Views/DynamicAutomationProperties.h @@ -62,6 +62,26 @@ struct DynamicAutomationProperties : DynamicAutomationPropertiesT const &value); + + static Windows::Foundation::Collections::IVector GetAccessibilityActions( + Windows::UI::Xaml::UIElement const &element); + + static void DispatchAccessibilityAction( + Windows::UI::Xaml::UIElement const &element, + std::wstring_view const &actionName); + + static winrt::Windows::UI::Xaml::DependencyProperty AccessibilityActionEventHandlerProperty(); + static void SetAccessibilityActionEventHandler( + Windows::UI::Xaml::UIElement const &element, + winrt::react::uwp::AccessibilityActionEventHandler const &value); + static winrt::react::uwp::AccessibilityActionEventHandler GetAccessibilityActionEventHandler( + winrt::Windows::UI::Xaml::UIElement const &element); }; } // namespace winrt::react::uwp::implementation diff --git a/vnext/ReactUWP/Views/FrameworkElementViewManager.cpp b/vnext/ReactUWP/Views/FrameworkElementViewManager.cpp index 389d5fbedc4..b5d090222a3 100644 --- a/vnext/ReactUWP/Views/FrameworkElementViewManager.cpp +++ b/vnext/ReactUWP/Views/FrameworkElementViewManager.cpp @@ -21,6 +21,8 @@ #include #include +#include "Utils/PropertyHandlerUtils.h" + #include "DynamicAutomationProperties.h" namespace winrt { @@ -28,11 +30,45 @@ using namespace Windows::UI::Xaml; using namespace Windows::UI::Xaml::Controls; using namespace Windows::UI::Xaml::Automation; using namespace Windows::UI::Xaml::Automation::Peers; +using namespace Windows::Foundation::Collections; } // namespace winrt namespace react { namespace uwp { +template <> +struct json_type_traits { + static winrt::react::uwp::AccessibilityAction parseJson(const folly::dynamic &json) { + auto action = winrt::react::uwp::AccessibilityAction(); + + for (auto &item : json.items()) { + if (item.first == "name") { + action.Name = react::uwp::asHstring(item.second); + } else if (item.first == "label") { + action.Label = react::uwp::asHstring(item.second); + } + } + return action; + } +}; + +template <> +struct json_type_traits> { + static winrt::IVector parseJson(const folly::dynamic &json) { + auto vector = winrt::single_threaded_vector(); + + if (json.isArray()) { + for (const auto &action : json) { + if (!action.isObject()) + continue; + + vector.Append(json_type_traits::parseJson(action)); + } + } + return vector; + } +}; + FrameworkElementViewManager::FrameworkElementViewManager(const std::shared_ptr &reactInstance) : Super(reactInstance) {} @@ -87,6 +123,8 @@ void FrameworkElementViewManager::TransferProperties(XamlView oldView, XamlView TransferProperty(oldView, newView, DynamicAutomationProperties::AccessibilityStateExpandedProperty()); TransferProperty(oldView, newView, DynamicAutomationProperties::AccessibilityStateCollapsedProperty()); TransferProperty(oldView, newView, DynamicAutomationProperties::AccessibilityInvokeEventHandlerProperty()); + TransferProperty(oldView, newView, DynamicAutomationProperties::AccessibilityActionEventHandlerProperty()); + TransferProperty(oldView, newView, DynamicAutomationProperties::AccessibilityActionsProperty()); auto tooltip = winrt::ToolTipService::GetToolTip(oldView); oldView.ClearValue(winrt::ToolTipService::ToolTipProperty()); @@ -103,9 +141,10 @@ void FrameworkElementViewManager::TransferProperties(XamlView oldView, XamlView folly::dynamic FrameworkElementViewManager::GetNativeProps() const { folly::dynamic props = Super::GetNativeProps(); - props.update(folly::dynamic::object("accessible", "boolean")("accessibilityRole", "string")( - "accessibilityStates", "array")("accessibilityHint", "string")("accessibilityLabel", "string")( - "accessibilityPosInSet", "number")("accessibilitySetSize", "number")("testID", "string")("tooltip", "string")); + props.update( + folly::dynamic::object("accessible", "boolean")("accessibilityRole", "string")("accessibilityStates", "array")( + "accessibilityHint", "string")("accessibilityLabel", "string")("accessibilityPosInSet", "number")( + "accessibilitySetSize", "number")("testID", "string")("tooltip", "string")("accessibilityActions", "array")); return props; } @@ -421,6 +460,9 @@ void FrameworkElementViewManager::UpdateProperties(ShadowNodeBase *nodeToUpdate, } } else if (TryUpdateFlowDirection(element, propertyName, propertyValue)) { continue; + } else if (propertyName == "accessibilityActions") { + auto value = json_type_traits>::parseJson(propertyValue); + DynamicAutomationProperties::SetAccessibilityActions(element, value); } } } diff --git a/vnext/ReactUWP/Views/ViewManagerBase.cpp b/vnext/ReactUWP/Views/ViewManagerBase.cpp index 75b546525e6..6ac1212eef8 100644 --- a/vnext/ReactUWP/Views/ViewManagerBase.cpp +++ b/vnext/ReactUWP/Views/ViewManagerBase.cpp @@ -163,7 +163,8 @@ dynamic ViewManagerBase::GetExportedCustomDirectEventTypeConstants() const { folly::dynamic eventTypes = folly::dynamic::object(); eventTypes.update(folly::dynamic::object("topLayout", folly::dynamic::object("registrationName", "onLayout"))( "topMouseEnter", folly::dynamic::object("registrationName", "onMouseEnter"))( - "topMouseLeave", folly::dynamic::object("registrationName", "onMouseLeave")) + "topMouseLeave", folly::dynamic::object("registrationName", "onMouseLeave"))( + "topAccessibilityAction", folly::dynamic::object("registrationName", "onAccessibilityAction")) // ("topMouseMove", // folly::dynamic::object("registrationName", // "onMouseMove")) diff --git a/vnext/ReactUWP/Views/ViewViewManager.cpp b/vnext/ReactUWP/Views/ViewViewManager.cpp index fb57d916322..a18d381ba9b 100644 --- a/vnext/ReactUWP/Views/ViewViewManager.cpp +++ b/vnext/ReactUWP/Views/ViewViewManager.cpp @@ -45,6 +45,16 @@ class ViewShadowNode : public ShadowNodeBase { else DispatchEvent("topAccessibilityTap", std::move(folly::dynamic::object("target", m_tag))); }); + + DynamicAutomationProperties::SetAccessibilityActionEventHandler( + panel, [=](winrt::react::uwp::AccessibilityAction const &action) { + folly::dynamic eventData = folly::dynamic::object("target", m_tag); + + eventData.insert( + "actionName", action.Label.empty() ? HstringToDynamic(action.Name) : HstringToDynamic(action.Label)); + + DispatchEvent("topAccessibilityAction", std::move(eventData)); + }); } bool IsControl() { diff --git a/vnext/ReactUWP/Views/cppwinrt/AccessibilityAction.idl b/vnext/ReactUWP/Views/cppwinrt/AccessibilityAction.idl new file mode 100644 index 00000000000..3db3f0160c5 --- /dev/null +++ b/vnext/ReactUWP/Views/cppwinrt/AccessibilityAction.idl @@ -0,0 +1,11 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace react.uwp +{ + [version(1)] + struct AccessibilityAction { + String Name; + String Label; + }; +} diff --git a/vnext/ReactUWP/Views/cppwinrt/DynamicAutomationPeer.idl b/vnext/ReactUWP/Views/cppwinrt/DynamicAutomationPeer.idl index 94b265dbe06..5875fd45fe1 100644 --- a/vnext/ReactUWP/Views/cppwinrt/DynamicAutomationPeer.idl +++ b/vnext/ReactUWP/Views/cppwinrt/DynamicAutomationPeer.idl @@ -6,6 +6,10 @@ // If you modify this file, be sure to run buildcppwinrt.cmd in this folder // to generate new headers +#define VERSION 1.0 + +import "AccessibilityAction.idl"; + namespace react.uwp { enum AccessibilityRoles @@ -56,6 +60,7 @@ namespace react.uwp }; delegate void AccessibilityInvokeEventHandler(); + delegate void AccessibilityActionEventHandler(AccessibilityAction action); [default_interface] [webhosthidden] @@ -97,6 +102,14 @@ namespace react.uwp static Windows.UI.Xaml.DependencyProperty AccessibilityInvokeEventHandlerProperty { get; }; static void SetAccessibilityInvokeEventHandler(Windows.UI.Xaml.UIElement element, AccessibilityInvokeEventHandler value); static AccessibilityInvokeEventHandler GetAccessibilityInvokeEventHandler(Windows.UI.Xaml.UIElement element); + + static Windows.UI.Xaml.DependencyProperty AccessibilityActionsProperty { get; }; + static void SetAccessibilityActions(Windows.UI.Xaml.UIElement element, Windows.Foundation.Collections.IVector value); + static Windows.Foundation.Collections.IVector GetAccessibilityActions(Windows.UI.Xaml.UIElement element); + + static Windows.UI.Xaml.DependencyProperty AccessibilityActionEventHandlerProperty { get; }; + static void SetAccessibilityActionEventHandler(Windows.UI.Xaml.UIElement element, AccessibilityActionEventHandler value); + static AccessibilityActionEventHandler GetAccessibilityActionEventHandler(Windows.UI.Xaml.UIElement element); } [default_interface] diff --git a/vnext/ReactUWP/Views/cppwinrt/DynamicAutomationProperties.g.h b/vnext/ReactUWP/Views/cppwinrt/DynamicAutomationProperties.g.h index f6e1eb68d60..b696aabdad3 100644 --- a/vnext/ReactUWP/Views/cppwinrt/DynamicAutomationProperties.g.h +++ b/vnext/ReactUWP/Views/cppwinrt/DynamicAutomationProperties.g.h @@ -195,6 +195,36 @@ struct WINRT_EBO DynamicAutomationPropertiesT : implements const& value) + { + T::SetAccessibilityActions(element, value); + } + + Windows::Foundation::Collections::IVector GetAccessibilityActions(Windows::UI::Xaml::UIElement const& element) + { + return T::GetAccessibilityActions(element); + } + + Windows::UI::Xaml::DependencyProperty AccessibilityActionEventHandlerProperty() + { + return T::AccessibilityActionEventHandlerProperty(); + } + + void SetAccessibilityActionEventHandler(Windows::UI::Xaml::UIElement const& element, react::uwp::AccessibilityActionEventHandler const& value) + { + T::SetAccessibilityActionEventHandler(element, value); + } + + react::uwp::AccessibilityActionEventHandler GetAccessibilityActionEventHandler(Windows::UI::Xaml::UIElement const& element) + { + return T::GetAccessibilityActionEventHandler(element); + } }; } diff --git a/vnext/ReactUWP/Views/cppwinrt/winrt/impl/react.uwp.0.h b/vnext/ReactUWP/Views/cppwinrt/winrt/impl/react.uwp.0.h index 52573472d0b..863b8ba15a6 100644 --- a/vnext/ReactUWP/Views/cppwinrt/winrt/impl/react.uwp.0.h +++ b/vnext/ReactUWP/Views/cppwinrt/winrt/impl/react.uwp.0.h @@ -97,6 +97,8 @@ struct DynamicAutomationPeer; struct DynamicAutomationProperties; struct ViewControl; struct ViewPanel; +struct AccessibilityAction; +struct AccessibilityActionEventHandler; struct AccessibilityInvokeEventHandler; } @@ -116,6 +118,8 @@ template <> struct category{ using type = class_categor template <> struct category{ using type = class_category; }; template <> struct category{ using type = enum_category; }; template <> struct category{ using type = enum_category; }; +template <> struct category{ using type = struct_category; }; +template <> struct category{ using type = delegate_category; }; template <> struct category{ using type = delegate_category; }; template <> struct name{ static constexpr auto & value{ L"react.uwp.IDynamicAutomationPeer" }; }; template <> struct name{ static constexpr auto & value{ L"react.uwp.IDynamicAutomationPeerFactory" }; }; @@ -130,14 +134,17 @@ template <> struct name{ static constexpr auto & value{ template <> struct name{ static constexpr auto & value{ L"react.uwp.ViewPanel" }; }; template <> struct name{ static constexpr auto & value{ L"react.uwp.AccessibilityRoles" }; }; template <> struct name{ static constexpr auto & value{ L"react.uwp.AccessibilityStates" }; }; +template <> struct name{ static constexpr auto & value{ L"react.uwp.AccessibilityAction" }; }; +template <> struct name{ static constexpr auto & value{ L"react.uwp.AccessibilityActionEventHandler" }; }; template <> struct name{ static constexpr auto & value{ L"react.uwp.AccessibilityInvokeEventHandler" }; }; template <> struct guid_storage{ static constexpr guid value{ 0x96D2FA46,0xD93B,0x5EB4,{ 0x9E,0xD8,0xFC,0x60,0x2C,0xB5,0xB7,0x8F } }; }; template <> struct guid_storage{ static constexpr guid value{ 0x0F0A64B1,0xCCEF,0x54F1,{ 0xB9,0x05,0x0C,0x58,0x26,0xCB,0x6C,0xC4 } }; }; template <> struct guid_storage{ static constexpr guid value{ 0xB70AAC96,0x549C,0x52C1,{ 0xA1,0x24,0xAE,0x0C,0xA4,0x96,0xC8,0x05 } }; }; -template <> struct guid_storage{ static constexpr guid value{ 0x12D63F8E,0xB2E6,0x577F,{ 0x9A,0x87,0xE3,0xB5,0x46,0x03,0xFA,0x0F } }; }; +template <> struct guid_storage{ static constexpr guid value{ 0x8BECBDA4,0xC633,0x55B5,{ 0xA8,0x1F,0x4D,0x4B,0x03,0xFA,0x89,0xF8 } }; }; template <> struct guid_storage{ static constexpr guid value{ 0xDD899021,0xA952,0x5F5A,{ 0xA5,0xC1,0xAC,0x9E,0x85,0x08,0x09,0xBD } }; }; template <> struct guid_storage{ static constexpr guid value{ 0x46487875,0x5C11,0x5EBE,{ 0xAA,0x1A,0xC7,0xC9,0x70,0xCF,0x46,0x02 } }; }; template <> struct guid_storage{ static constexpr guid value{ 0xF820A53A,0x6DFD,0x53F9,{ 0xA1,0x96,0x40,0xA4,0xED,0x81,0x8B,0x80 } }; }; +template <> struct guid_storage{ static constexpr guid value{ 0x0989B119,0x9348,0x5B3A,{ 0xA7,0x29,0x8C,0xF2,0xE5,0x01,0x6F,0x19 } }; }; template <> struct guid_storage{ static constexpr guid value{ 0xCF396F1D,0x7B41,0x5E44,{ 0xB2,0xD5,0xBA,0xB5,0x86,0xC7,0xEE,0x33 } }; }; template <> struct default_interface{ using type = react::uwp::IDynamicAutomationPeer; }; template <> struct default_interface{ using type = react::uwp::IDynamicAutomationProperties; }; @@ -186,6 +193,12 @@ template <> struct abi{ struct virtual int32_t WINRT_CALL get_AccessibilityInvokeEventHandlerProperty(void** value) noexcept = 0; virtual int32_t WINRT_CALL SetAccessibilityInvokeEventHandler(void* element, void* value) noexcept = 0; virtual int32_t WINRT_CALL GetAccessibilityInvokeEventHandler(void* element, void** result) noexcept = 0; + virtual int32_t WINRT_CALL get_AccessibilityActionsProperty(void** value) noexcept = 0; + virtual int32_t WINRT_CALL SetAccessibilityActions(void* element, void* value) noexcept = 0; + virtual int32_t WINRT_CALL GetAccessibilityActions(void* element, void** result) noexcept = 0; + virtual int32_t WINRT_CALL get_AccessibilityActionEventHandlerProperty(void** value) noexcept = 0; + virtual int32_t WINRT_CALL SetAccessibilityActionEventHandler(void* element, void* value) noexcept = 0; + virtual int32_t WINRT_CALL GetAccessibilityActionEventHandler(void* element, void** result) noexcept = 0; };}; template <> struct abi{ struct type : IInspectable @@ -227,6 +240,11 @@ template <> struct abi{ struct type : IInspectabl virtual int32_t WINRT_CALL GetLeft(void* element, double* result) noexcept = 0; };}; +template <> struct abi{ struct type : IUnknown +{ + virtual int32_t WINRT_CALL Invoke(struct struct_react_uwp_AccessibilityAction action) noexcept = 0; +};}; + template <> struct abi{ struct type : IUnknown { virtual int32_t WINRT_CALL Invoke() noexcept = 0; @@ -281,6 +299,12 @@ struct consume_react_uwp_IDynamicAutomationPropertiesStatics Windows::UI::Xaml::DependencyProperty AccessibilityInvokeEventHandlerProperty() const; void SetAccessibilityInvokeEventHandler(Windows::UI::Xaml::UIElement const& element, react::uwp::AccessibilityInvokeEventHandler const& value) const; react::uwp::AccessibilityInvokeEventHandler GetAccessibilityInvokeEventHandler(Windows::UI::Xaml::UIElement const& element) const; + Windows::UI::Xaml::DependencyProperty AccessibilityActionsProperty() const; + void SetAccessibilityActions(Windows::UI::Xaml::UIElement const& element, param::vector const& value) const; + Windows::Foundation::Collections::IVector GetAccessibilityActions(Windows::UI::Xaml::UIElement const& element) const; + Windows::UI::Xaml::DependencyProperty AccessibilityActionEventHandlerProperty() const; + void SetAccessibilityActionEventHandler(Windows::UI::Xaml::UIElement const& element, react::uwp::AccessibilityActionEventHandler const& value) const; + react::uwp::AccessibilityActionEventHandler GetAccessibilityActionEventHandler(Windows::UI::Xaml::UIElement const& element) const; }; template <> struct consume { template using type = consume_react_uwp_IDynamicAutomationPropertiesStatics; }; @@ -329,4 +353,12 @@ struct consume_react_uwp_IViewPanelStatics }; template <> struct consume { template using type = consume_react_uwp_IViewPanelStatics; }; +struct struct_react_uwp_AccessibilityAction +{ + void* Name; + void* Label; +}; +template <> struct abi{ using type = struct_react_uwp_AccessibilityAction; }; + + } diff --git a/vnext/ReactUWP/Views/cppwinrt/winrt/impl/react.uwp.2.h b/vnext/ReactUWP/Views/cppwinrt/winrt/impl/react.uwp.2.h index 64e14d7361d..cd02ba0d77f 100644 --- a/vnext/ReactUWP/Views/cppwinrt/winrt/impl/react.uwp.2.h +++ b/vnext/ReactUWP/Views/cppwinrt/winrt/impl/react.uwp.2.h @@ -12,6 +12,17 @@ WINRT_EXPORT namespace winrt::react::uwp { +struct AccessibilityActionEventHandler : Windows::Foundation::IUnknown +{ + AccessibilityActionEventHandler(std::nullptr_t = nullptr) noexcept {} + template AccessibilityActionEventHandler(L lambda); + template AccessibilityActionEventHandler(F* function); + template AccessibilityActionEventHandler(O* object, M method); + template AccessibilityActionEventHandler(com_ptr&& object, M method); + template AccessibilityActionEventHandler(weak_ref&& object, M method); + void operator()(react::uwp::AccessibilityAction const& action) const; +}; + struct AccessibilityInvokeEventHandler : Windows::Foundation::IUnknown { AccessibilityInvokeEventHandler(std::nullptr_t = nullptr) noexcept {} @@ -23,6 +34,22 @@ struct AccessibilityInvokeEventHandler : Windows::Foundation::IUnknown void operator()() const; }; +struct AccessibilityAction +{ + hstring Name; + hstring Label; +}; + +inline bool operator==(AccessibilityAction const& left, AccessibilityAction const& right) noexcept +{ + return left.Name == right.Name && left.Label == right.Label; +} + +inline bool operator!=(AccessibilityAction const& left, AccessibilityAction const& right) noexcept +{ + return !(left == right); +} + } namespace winrt::impl { @@ -71,6 +98,12 @@ struct WINRT_EBO DynamicAutomationProperties : static Windows::UI::Xaml::DependencyProperty AccessibilityInvokeEventHandlerProperty(); static void SetAccessibilityInvokeEventHandler(Windows::UI::Xaml::UIElement const& element, react::uwp::AccessibilityInvokeEventHandler const& value); static react::uwp::AccessibilityInvokeEventHandler GetAccessibilityInvokeEventHandler(Windows::UI::Xaml::UIElement const& element); + static Windows::UI::Xaml::DependencyProperty AccessibilityActionsProperty(); + static void SetAccessibilityActions(Windows::UI::Xaml::UIElement const& element, param::vector const& value); + static Windows::Foundation::Collections::IVector GetAccessibilityActions(Windows::UI::Xaml::UIElement const& element); + static Windows::UI::Xaml::DependencyProperty AccessibilityActionEventHandlerProperty(); + static void SetAccessibilityActionEventHandler(Windows::UI::Xaml::UIElement const& element, react::uwp::AccessibilityActionEventHandler const& value); + static react::uwp::AccessibilityActionEventHandler GetAccessibilityActionEventHandler(Windows::UI::Xaml::UIElement const& element); }; struct WINRT_EBO ViewControl : diff --git a/vnext/ReactUWP/Views/cppwinrt/winrt/react.uwp.h b/vnext/ReactUWP/Views/cppwinrt/winrt/react.uwp.h index 7a60e24de5c..f69b7d02b16 100644 --- a/vnext/ReactUWP/Views/cppwinrt/winrt/react.uwp.h +++ b/vnext/ReactUWP/Views/cppwinrt/winrt/react.uwp.h @@ -197,6 +197,44 @@ template react::uwp::AccessibilityInvokeEventHandler consume_react_ return result; } +template Windows::UI::Xaml::DependencyProperty consume_react_uwp_IDynamicAutomationPropertiesStatics::AccessibilityActionsProperty() const +{ + Windows::UI::Xaml::DependencyProperty value{ nullptr }; + check_hresult(WINRT_SHIM(react::uwp::IDynamicAutomationPropertiesStatics)->get_AccessibilityActionsProperty(put_abi(value))); + return value; +} + +template void consume_react_uwp_IDynamicAutomationPropertiesStatics::SetAccessibilityActions(Windows::UI::Xaml::UIElement const& element, param::vector const& value) const +{ + check_hresult(WINRT_SHIM(react::uwp::IDynamicAutomationPropertiesStatics)->SetAccessibilityActions(get_abi(element), get_abi(value))); +} + +template Windows::Foundation::Collections::IVector consume_react_uwp_IDynamicAutomationPropertiesStatics::GetAccessibilityActions(Windows::UI::Xaml::UIElement const& element) const +{ + Windows::Foundation::Collections::IVector result{ nullptr }; + check_hresult(WINRT_SHIM(react::uwp::IDynamicAutomationPropertiesStatics)->GetAccessibilityActions(get_abi(element), put_abi(result))); + return result; +} + +template Windows::UI::Xaml::DependencyProperty consume_react_uwp_IDynamicAutomationPropertiesStatics::AccessibilityActionEventHandlerProperty() const +{ + Windows::UI::Xaml::DependencyProperty value{ nullptr }; + check_hresult(WINRT_SHIM(react::uwp::IDynamicAutomationPropertiesStatics)->get_AccessibilityActionEventHandlerProperty(put_abi(value))); + return value; +} + +template void consume_react_uwp_IDynamicAutomationPropertiesStatics::SetAccessibilityActionEventHandler(Windows::UI::Xaml::UIElement const& element, react::uwp::AccessibilityActionEventHandler const& value) const +{ + check_hresult(WINRT_SHIM(react::uwp::IDynamicAutomationPropertiesStatics)->SetAccessibilityActionEventHandler(get_abi(element), get_abi(value))); +} + +template react::uwp::AccessibilityActionEventHandler consume_react_uwp_IDynamicAutomationPropertiesStatics::GetAccessibilityActionEventHandler(Windows::UI::Xaml::UIElement const& element) const +{ + react::uwp::AccessibilityActionEventHandler result{ nullptr }; + check_hresult(WINRT_SHIM(react::uwp::IDynamicAutomationPropertiesStatics)->GetAccessibilityActionEventHandler(get_abi(element), put_abi(result))); + return result; +} + template react::uwp::ViewPanel consume_react_uwp_IViewControl::GetPanel() const { react::uwp::ViewPanel result{ nullptr }; @@ -364,6 +402,28 @@ template double consume_react_uwp_IViewPanelStatics::GetLeft(Win return result; } +template <> struct delegate +{ + template + struct type : implements_delegate + { + type(H&& handler) : implements_delegate(std::forward(handler)) {} + + int32_t WINRT_CALL Invoke(struct struct_react_uwp_AccessibilityAction action) noexcept final + { + try + { + (*this)(*reinterpret_cast(&action)); + return 0; + } + catch (...) + { + return to_hresult(); + } + } + }; +}; + template <> struct delegate { template @@ -747,6 +807,82 @@ struct produce : produce_bas } catch (...) { return to_hresult(); } } + + int32_t WINRT_CALL get_AccessibilityActionsProperty(void** value) noexcept final + { + try + { + *value = nullptr; + typename D::abi_guard guard(this->shim()); + WINRT_ASSERT_DECLARATION(AccessibilityActionsProperty, WINRT_WRAP(Windows::UI::Xaml::DependencyProperty)); + *value = detach_from(this->shim().AccessibilityActionsProperty()); + return 0; + } + catch (...) { return to_hresult(); } + } + + int32_t WINRT_CALL SetAccessibilityActions(void* element, void* value) noexcept final + { + try + { + typename D::abi_guard guard(this->shim()); + WINRT_ASSERT_DECLARATION(SetAccessibilityActions, WINRT_WRAP(void), Windows::UI::Xaml::UIElement const&, Windows::Foundation::Collections::IVector const&); + this->shim().SetAccessibilityActions(*reinterpret_cast(&element), *reinterpret_cast const*>(&value)); + return 0; + } + catch (...) { return to_hresult(); } + } + + int32_t WINRT_CALL GetAccessibilityActions(void* element, void** result) noexcept final + { + try + { + *result = nullptr; + typename D::abi_guard guard(this->shim()); + WINRT_ASSERT_DECLARATION(GetAccessibilityActions, WINRT_WRAP(Windows::Foundation::Collections::IVector), Windows::UI::Xaml::UIElement const&); + *result = detach_from>(this->shim().GetAccessibilityActions(*reinterpret_cast(&element))); + return 0; + } + catch (...) { return to_hresult(); } + } + + int32_t WINRT_CALL get_AccessibilityActionEventHandlerProperty(void** value) noexcept final + { + try + { + *value = nullptr; + typename D::abi_guard guard(this->shim()); + WINRT_ASSERT_DECLARATION(AccessibilityActionEventHandlerProperty, WINRT_WRAP(Windows::UI::Xaml::DependencyProperty)); + *value = detach_from(this->shim().AccessibilityActionEventHandlerProperty()); + return 0; + } + catch (...) { return to_hresult(); } + } + + int32_t WINRT_CALL SetAccessibilityActionEventHandler(void* element, void* value) noexcept final + { + try + { + typename D::abi_guard guard(this->shim()); + WINRT_ASSERT_DECLARATION(SetAccessibilityActionEventHandler, WINRT_WRAP(void), Windows::UI::Xaml::UIElement const&, react::uwp::AccessibilityActionEventHandler const&); + this->shim().SetAccessibilityActionEventHandler(*reinterpret_cast(&element), *reinterpret_cast(&value)); + return 0; + } + catch (...) { return to_hresult(); } + } + + int32_t WINRT_CALL GetAccessibilityActionEventHandler(void* element, void** result) noexcept final + { + try + { + *result = nullptr; + typename D::abi_guard guard(this->shim()); + WINRT_ASSERT_DECLARATION(GetAccessibilityActionEventHandler, WINRT_WRAP(react::uwp::AccessibilityActionEventHandler), Windows::UI::Xaml::UIElement const&); + *result = detach_from(this->shim().GetAccessibilityActionEventHandler(*reinterpret_cast(&element))); + return 0; + } + catch (...) { return to_hresult(); } + } }; template @@ -1239,6 +1375,36 @@ inline react::uwp::AccessibilityInvokeEventHandler DynamicAutomationProperties:: return impl::call_factory([&](auto&& f) { return f.GetAccessibilityInvokeEventHandler(element); }); } +inline Windows::UI::Xaml::DependencyProperty DynamicAutomationProperties::AccessibilityActionsProperty() +{ + return impl::call_factory([&](auto&& f) { return f.AccessibilityActionsProperty(); }); +} + +inline void DynamicAutomationProperties::SetAccessibilityActions(Windows::UI::Xaml::UIElement const& element, param::vector const& value) +{ + impl::call_factory([&](auto&& f) { return f.SetAccessibilityActions(element, value); }); +} + +inline Windows::Foundation::Collections::IVector DynamicAutomationProperties::GetAccessibilityActions(Windows::UI::Xaml::UIElement const& element) +{ + return impl::call_factory([&](auto&& f) { return f.GetAccessibilityActions(element); }); +} + +inline Windows::UI::Xaml::DependencyProperty DynamicAutomationProperties::AccessibilityActionEventHandlerProperty() +{ + return impl::call_factory([&](auto&& f) { return f.AccessibilityActionEventHandlerProperty(); }); +} + +inline void DynamicAutomationProperties::SetAccessibilityActionEventHandler(Windows::UI::Xaml::UIElement const& element, react::uwp::AccessibilityActionEventHandler const& value) +{ + impl::call_factory([&](auto&& f) { return f.SetAccessibilityActionEventHandler(element, value); }); +} + +inline react::uwp::AccessibilityActionEventHandler DynamicAutomationProperties::GetAccessibilityActionEventHandler(Windows::UI::Xaml::UIElement const& element) +{ + return impl::call_factory([&](auto&& f) { return f.GetAccessibilityActionEventHandler(element); }); +} + inline ViewControl::ViewControl() : ViewControl(impl::call_factory([](auto&& f) { return f.template ActivateInstance(); })) {} @@ -1302,6 +1468,31 @@ inline double ViewPanel::GetLeft(Windows::UI::Xaml::UIElement const& element) return impl::call_factory([&](auto&& f) { return f.GetLeft(element); }); } +template AccessibilityActionEventHandler::AccessibilityActionEventHandler(L handler) : + AccessibilityActionEventHandler(impl::make_delegate(std::forward(handler))) +{} + +template AccessibilityActionEventHandler::AccessibilityActionEventHandler(F* handler) : + AccessibilityActionEventHandler([=](auto&&... args) { return handler(args...); }) +{} + +template AccessibilityActionEventHandler::AccessibilityActionEventHandler(O* object, M method) : + AccessibilityActionEventHandler([=](auto&&... args) { return ((*object).*(method))(args...); }) +{} + +template AccessibilityActionEventHandler::AccessibilityActionEventHandler(com_ptr&& object, M method) : + AccessibilityActionEventHandler([o = std::move(object), method](auto&&... args) { return ((*o).*(method))(args...); }) +{} + +template AccessibilityActionEventHandler::AccessibilityActionEventHandler(weak_ref&& object, M method) : + AccessibilityActionEventHandler([o = std::move(object), method](auto&&... args) { if (auto s = o.get()) { ((*s).*(method))(args...); } }) +{} + +inline void AccessibilityActionEventHandler::operator()(react::uwp::AccessibilityAction const& action) const +{ + check_hresult((*(impl::abi_t**)this)->Invoke(get_abi(action))); +} + template AccessibilityInvokeEventHandler::AccessibilityInvokeEventHandler(L handler) : AccessibilityInvokeEventHandler(impl::make_delegate(std::forward(handler))) {} @@ -1333,6 +1524,40 @@ namespace winrt::impl { struct property_react_uwp_IDynamicAutomationPropertiesStatics { struct named { + struct AccessibilityActionEventHandlerProperty + { + struct name { static constexpr std::wstring_view value{ L"AccessibilityActionEventHandlerProperty"sv }; }; + using property_type = winrt::Windows::UI::Xaml::DependencyProperty; + using target_type = winrt::react::uwp::IDynamicAutomationPropertiesStatics; + + using is_readable = std::true_type; + using is_writable = std::false_type; + using is_static = std::false_type; + struct getter + { + auto operator()(target_type const& target) const + { + return target.AccessibilityActionEventHandlerProperty(); + } + }; + }; + struct AccessibilityActionsProperty + { + struct name { static constexpr std::wstring_view value{ L"AccessibilityActionsProperty"sv }; }; + using property_type = winrt::Windows::UI::Xaml::DependencyProperty; + using target_type = winrt::react::uwp::IDynamicAutomationPropertiesStatics; + + using is_readable = std::true_type; + using is_writable = std::false_type; + using is_static = std::false_type; + struct getter + { + auto operator()(target_type const& target) const + { + return target.AccessibilityActionsProperty(); + } + }; + }; struct AccessibilityInvokeEventHandlerProperty { struct name { static constexpr std::wstring_view value{ L"AccessibilityInvokeEventHandlerProperty"sv }; }; @@ -1486,7 +1711,7 @@ struct property_react_uwp_IDynamicAutomationPropertiesStatics } }; };}; - struct list { using type = impl::typelist; }; + struct list { using type = impl::typelist; }; }; struct property_react_uwp_IViewPanel @@ -1852,6 +2077,40 @@ struct property_react_uwp_DynamicAutomationPeer struct property_react_uwp_DynamicAutomationProperties { struct named { + struct AccessibilityActionEventHandlerProperty + { + struct name { static constexpr std::wstring_view value{ L"AccessibilityActionEventHandlerProperty"sv }; }; + using property_type = winrt::Windows::UI::Xaml::DependencyProperty; + using target_type = winrt::react::uwp::DynamicAutomationProperties; + + using is_readable = std::true_type; + using is_writable = std::false_type; + using is_static = std::true_type; + struct getter + { + auto operator()() const + { + return target_type::AccessibilityActionEventHandlerProperty(); + } + }; + }; + struct AccessibilityActionsProperty + { + struct name { static constexpr std::wstring_view value{ L"AccessibilityActionsProperty"sv }; }; + using property_type = winrt::Windows::UI::Xaml::DependencyProperty; + using target_type = winrt::react::uwp::DynamicAutomationProperties; + + using is_readable = std::true_type; + using is_writable = std::false_type; + using is_static = std::true_type; + struct getter + { + auto operator()() const + { + return target_type::AccessibilityActionsProperty(); + } + }; + }; struct AccessibilityInvokeEventHandlerProperty { struct name { static constexpr std::wstring_view value{ L"AccessibilityInvokeEventHandlerProperty"sv }; }; @@ -2005,7 +2264,7 @@ struct property_react_uwp_DynamicAutomationProperties } }; };}; - struct list { using type = impl::typelist; }; + struct list { using type = impl::typelist; }; }; struct property_react_uwp_ViewPanel