Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"type": "prerelease",
"comment": "Add XamlUIService with ElementFromReactTag",
"packageName": "react-native-windows",
"email": "acoates@microsoft.com",
"dependentChangeType": "patch",
"date": "2020-05-28T15:10:23.674Z"
}
15 changes: 8 additions & 7 deletions vnext/Microsoft.ReactNative/IReactContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "pch.h"
#include "IReactContext.h"
#include "DynamicWriter.h"
#include "XamlUIService.h"

namespace winrt::Microsoft::ReactNative::implementation {

Expand All @@ -17,18 +18,18 @@ IReactDispatcher ReactContext::UIDispatcher() noexcept {
return Properties().Get(ReactDispatcherHelper::UIDispatcherProperty()).try_as<IReactDispatcher>();
}

// Deprecated: Use XamlUIService directly.
void ReactContext::DispatchEvent(
winrt::Windows::UI::Xaml::FrameworkElement const &view,
hstring const &eventName,
JSValueArgWriter const &eventDataArgWriter) noexcept {
folly::dynamic eventData; // default to NULLT
if (eventDataArgWriter != nullptr) {
auto eventDataWriter = winrt::make_self<DynamicWriter>();
eventDataArgWriter(*eventDataWriter);
eventData = eventDataWriter->TakeValue();
}
auto xamlUIService = Properties()
.Get(XamlUIService::XamlUIServiceProperty().Handle())
.try_as<winrt::Microsoft::ReactNative::XamlUIService>();

m_context->DispatchEvent(unbox_value<int64_t>(view.Tag()), to_string(eventName), std::move(eventData));
if (xamlUIService) {
xamlUIService.DispatchEvent(view, eventName, eventDataArgWriter);
}
}

void ReactContext::CallJSFunction(
Expand Down
5 changes: 4 additions & 1 deletion vnext/Microsoft.ReactNative/IReactContext.idl
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@ namespace Microsoft.ReactNative {
[webhosthidden]
interface IReactContext {
IReactPropertyBag Properties { get; };
void DispatchEvent(Windows.UI.Xaml.FrameworkElement view, String eventName, JSValueArgWriter eventDataArgWriter);
// Get ReactDispatcherHelper::UIDispatcherProperty from the Properties property bag.
IReactDispatcher UIDispatcher { get; };

// Deprecated: Use DispatchEvent on XamlUIService instead
void DispatchEvent(Windows.UI.Xaml.FrameworkElement view, String eventName, JSValueArgWriter eventDataArgWriter);

// Call JavaScript function methodName of moduleName.
void CallJSFunction(String moduleName, String methodName, JSValueArgWriter paramsArgWriter);
void EmitJSEvent(String eventEmitterName, String eventName, JSValueArgWriter paramsArgWriter);
}
Expand Down
11 changes: 11 additions & 0 deletions vnext/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,10 @@
<DependentUpon>ReactNativeHost.idl</DependentUpon>
<SubType>Code</SubType>
</ClInclude>
<ClInclude Include="XamlUIService.h">
<DependentUpon>XamlUIService.idl</DependentUpon>
<SubType>Code</SubType>
</ClInclude>
<ClInclude Include="ReactPackageBuilder.h">
<DependentUpon>IReactPackageBuilder.idl</DependentUpon>
</ClInclude>
Expand Down Expand Up @@ -493,6 +497,10 @@
<DependentUpon>ReactNativeHost.idl</DependentUpon>
<SubType>Code</SubType>
</ClCompile>
<ClCompile Include="XamlUIService.cpp">
<DependentUpon>XamlUIService.idl</DependentUpon>
<SubType>Code</SubType>
</ClCompile>
<ClCompile Include="ReactPackageBuilder.cpp">
<DependentUpon>IReactPackageBuilder.idl</DependentUpon>
</ClCompile>
Expand Down Expand Up @@ -552,6 +560,9 @@
<Midl Include="ReactNativeHost.idl">
<SubType>Designer</SubType>
</Midl>
<Midl Include="XamlUIService.idl">
<SubType>Designer</SubType>
</Midl>
<Midl Include="ReactRootView.idl">
<SubType>Designer</SubType>
</Midl>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -706,6 +706,7 @@
<Midl Include="ReactNativeHost.idl" />
<Midl Include="ReactRootView.idl" />
<Midl Include="XamlHelper.idl" />
<Midl Include="XamlUIService.idl" />
</ItemGroup>
<ItemGroup>
<None Include="microsoft.reactnative.def" />
Expand Down
5 changes: 5 additions & 0 deletions vnext/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <ReactUWP/CreateUwpModules.h>
#include <ReactUWP/Modules/I18nModule.h>
#include <Threading/MessageDispatchQueue.h>
#include <XamlUIService.h>
#include "ReactErrorProvider.h"

#include "Microsoft.ReactNative/Threading/MessageQueueThreadFactory.h"
Expand Down Expand Up @@ -481,6 +482,10 @@ void ReactInstanceWin::InitUIManager() noexcept {
react::uwp::AddPolyesterViewManagers(viewManagers, m_legacyReactInstance);

auto uiManager = react::uwp::CreateUIManager2(std::move(viewManagers));
auto wkUIManger = std::weak_ptr<facebook::react::IUIManager>(uiManager);
m_reactContext->Properties().Set(
winrt::Microsoft::ReactNative::implementation::XamlUIService::XamlUIServiceProperty().Handle(),
winrt::make<winrt::Microsoft::ReactNative::implementation::XamlUIService>(std::move(wkUIManger), m_reactContext));
m_uiManager.Exchange(std::move(uiManager));
}

Expand Down
53 changes: 53 additions & 0 deletions vnext/Microsoft.ReactNative/XamlUIService.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

#include "pch.h"
#include "XamlUIService.h"
#include "XamlUIService.g.cpp"
#include "DynamicWriter.h"
#include "Views/ShadowNodeBase.h"

namespace winrt::Microsoft::ReactNative::implementation {

XamlUIService::XamlUIService(
std::weak_ptr<facebook::react::IUIManager> &&uimanager,
Mso::CntPtr<Mso::React::IReactContext> &&context) noexcept
: m_wkUIManager(uimanager), m_context(context) {}

winrt::Windows::UI::Xaml::DependencyObject XamlUIService::ElementFromReactTag(int64_t reactTag) noexcept {
if (auto strongUIManager = m_wkUIManager.lock()) {
auto shadowNode = strongUIManager->FindShadowNodeForTag(reactTag);
if (!shadowNode)
return nullptr;

return static_cast<react::uwp::ShadowNodeBase *>(shadowNode)->GetView();
}
return nullptr;
}

/*static*/ winrt::Microsoft::ReactNative::XamlUIService XamlUIService::FromContext(IReactContext context) {
return context.Properties()
.Get(XamlUIService::XamlUIServiceProperty().Handle())
.try_as<winrt::Microsoft::ReactNative::XamlUIService>();
}

void XamlUIService::DispatchEvent(
winrt::Windows::UI::Xaml::FrameworkElement const &view,
hstring const &eventName,
JSValueArgWriter const &eventDataArgWriter) noexcept {
folly::dynamic eventData; // default to NULLT
if (eventDataArgWriter != nullptr) {
auto eventDataWriter = winrt::make_self<DynamicWriter>();
eventDataArgWriter(*eventDataWriter);
eventData = eventDataWriter->TakeValue();
}

m_context->DispatchEvent(unbox_value<int64_t>(view.Tag()), to_string(eventName), std::move(eventData));
}

/*static*/ ReactPropertyId<XamlUIService> XamlUIService::XamlUIServiceProperty() noexcept {
static ReactPropertyId<XamlUIService> uiManagerProperty{L"ReactNative.UIManager", L"XamlUIManager"};
return uiManagerProperty;
}

} // namespace winrt::Microsoft::ReactNative::implementation
38 changes: 38 additions & 0 deletions vnext/Microsoft.ReactNative/XamlUIService.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

#pragma once

#include "XamlUIService.g.h"
#include "IUIManager.h"

#include "ReactHost/React.h"
#include "ReactPropertyBag.h"
#include "winrt/Microsoft.ReactNative.h"

namespace winrt::Microsoft::ReactNative::implementation {

struct XamlUIService : XamlUIServiceT<XamlUIService> {
public:
XamlUIService(
std::weak_ptr<facebook::react::IUIManager> &&uimanager,
Mso::CntPtr<Mso::React::IReactContext> &&context) noexcept;
static ReactPropertyId<XamlUIService> XamlUIServiceProperty() noexcept;

winrt::Windows::UI::Xaml::DependencyObject ElementFromReactTag(int64_t reactTag) noexcept;
static winrt::Microsoft::ReactNative::XamlUIService FromContext(IReactContext context);
void DispatchEvent(
winrt::Windows::UI::Xaml::FrameworkElement const &view,
hstring const &eventName,
JSValueArgWriter const &eventDataArgWriter) noexcept;

private:
std::weak_ptr<facebook::react::IUIManager> m_wkUIManager;
Mso::CntPtr<Mso::React::IReactContext> m_context;
};

} // namespace winrt::Microsoft::ReactNative::implementation

namespace winrt::Microsoft::ReactNative::factory_implementation {
struct XamlUIService : XamlUIServiceT<XamlUIService, implementation::XamlUIService> {};
} // namespace winrt::Microsoft::ReactNative::factory_implementation
19 changes: 19 additions & 0 deletions vnext/Microsoft.ReactNative/XamlUIService.idl
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

import "IReactContext.idl";

namespace Microsoft.ReactNative {

[default_interface]
[webhosthidden]
runtimeclass XamlUIService {
static XamlUIService FromContext(IReactContext context);

Windows.UI.Xaml.DependencyObject ElementFromReactTag(Int64 reactTag);

// Dispatch UI event. This method is to be moved to IReactViewContext.
void DispatchEvent(Windows.UI.Xaml.FrameworkElement view, String eventName, JSValueArgWriter eventDataArgWriter);
}

} // namespace Microsoft.ReactNative