#include "pch.h" #include "ReactWebViewManager.h" #include "NativeModules.h" #include "ReactWebView.h" #include "JSValueXaml.h" namespace winrt { using namespace Microsoft::ReactNative; using namespace Windows::Foundation; using namespace Windows::Foundation::Collections; using namespace Windows::UI; using namespace Windows::UI::Xaml; using namespace Windows::UI::Xaml::Controls; } namespace winrt::ReactNativeWebView::implementation { ReactWebViewManager::ReactWebViewManager() {} // IViewManager winrt::hstring ReactWebViewManager::Name() noexcept { return L"RCTWebView"; } winrt::FrameworkElement ReactWebViewManager::CreateView() noexcept { m_reactWebView = *winrt::make_self(m_reactContext); return m_reactWebView.GetView(); } // IViewManagerWithReactContext winrt::IReactContext ReactWebViewManager::ReactContext() noexcept { return m_reactContext; } void ReactWebViewManager::ReactContext(IReactContext reactContext) noexcept { m_reactContext = reactContext; } // IViewManagerWithNativeProperties IMapView ReactWebViewManager::NativeProps() noexcept { auto nativeProps = winrt::single_threaded_map(); nativeProps.Insert(L"source", ViewManagerPropertyType::Map); return nativeProps.GetView(); } void ReactWebViewManager::UpdateProperties( FrameworkElement const& view, IJSValueReader const& propertyMapReader) noexcept { if (auto webView = view.try_as()) { const JSValueObject& propertyMap = JSValueObject::ReadFrom(propertyMapReader); for (auto const& pair : propertyMap) { auto const& propertyName = pair.first; auto const& propertyValue = pair.second; if (propertyValue.IsNull()) continue; if (propertyName == "source") { auto const& srcMap = propertyValue.AsObject(); if (srcMap.find("uri") != srcMap.end()) { auto uriString = srcMap.at("uri").AsString(); // non-uri sources not yet supported if (uriString.length() == 0) { continue; } bool isPackagerAsset = false; if (srcMap.find("__packager_asset") != srcMap.end()) { isPackagerAsset = srcMap.at("__packager_asset").AsBoolean(); } if (isPackagerAsset && uriString.find("assets") == 0) { uriString.replace(0, 6, "ms-appx://"); } webView.Navigate(winrt::Uri(to_hstring(uriString))); } else if (srcMap.find("html") != srcMap.end()) { auto htmlString = srcMap.at("html").AsString(); webView.NavigateToString(to_hstring(htmlString)); } } else if (propertyName == "backgroundColor") { auto color = propertyValue.To(); webView.DefaultBackgroundColor(color.A==0 ? winrt::Colors::Transparent() : color); } } } } // IViewManagerWithExportedEventTypeConstants ConstantProviderDelegate ReactWebViewManager::ExportedCustomBubblingEventTypeConstants() noexcept { return nullptr; } ConstantProviderDelegate ReactWebViewManager::ExportedCustomDirectEventTypeConstants() noexcept { return [](winrt::IJSValueWriter const& constantWriter) { WriteCustomDirectEventTypeConstant(constantWriter, "onLoadingStart"); WriteCustomDirectEventTypeConstant(constantWriter, "onLoadingFinish"); WriteCustomDirectEventTypeConstant(constantWriter, "onLoadingError"); WriteCustomDirectEventTypeConstant(constantWriter, "onMessage"); }; } // IViewManagerWithCommands IMapView ReactWebViewManager::Commands() noexcept { auto commands = winrt::single_threaded_map(); commands.Insert(L"goForward", static_cast(WebViewCommands::GoForward)); commands.Insert(L"goBack", static_cast(WebViewCommands::GoBack)); commands.Insert(L"reload", static_cast(WebViewCommands::Reload)); commands.Insert(L"stopLoading", static_cast(WebViewCommands::StopLoading)); commands.Insert(L"injectJavaScript", static_cast(WebViewCommands::InjectJavaScript)); return commands.GetView(); } void ReactWebViewManager::DispatchCommand( FrameworkElement const& view, int64_t commandId, winrt::IJSValueReader const& commandArgsReader) noexcept { auto commandArgs = JSValue::ReadArrayFrom(commandArgsReader); if (auto webView = view.try_as()) { switch (commandId) { case static_cast(WebViewCommands::GoForward) : if (webView.CanGoForward()) { webView.GoForward(); } break; case static_cast(WebViewCommands::GoBack) : if (webView.CanGoBack()) { webView.GoBack(); } break; case static_cast(WebViewCommands::Reload) : webView.Refresh(); break; case static_cast(WebViewCommands::StopLoading) : webView.Stop(); break; case static_cast(WebViewCommands::InjectJavaScript) : webView.InvokeScriptAsync(L"eval", { winrt::to_hstring(commandArgs[0].AsString()) }); break; } } } } // namespace winrt::ReactWebView::implementation