react-native-webview.git

ReactWebViewManager.cpp 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. #include "pch.h"
  2. #include "ReactWebViewManager.h"
  3. #include "NativeModules.h"
  4. namespace winrt {
  5. using namespace Microsoft::ReactNative;
  6. using namespace Windows::Foundation;
  7. using namespace Windows::Foundation::Collections;
  8. using namespace Windows::UI::Xaml;
  9. using namespace Windows::UI::Xaml::Controls;
  10. }
  11. namespace winrt::ReactNativeWebView::implementation {
  12. ReactWebViewManager::ReactWebViewManager() {}
  13. // IViewManager
  14. winrt::hstring ReactWebViewManager::Name() noexcept {
  15. return L"RCTWebView";
  16. }
  17. winrt::FrameworkElement ReactWebViewManager::CreateView() noexcept {
  18. auto webView = winrt::WebView();
  19. m_webView = winrt::make_weak(webView);
  20. RegisterEvents();
  21. return webView;
  22. }
  23. void ReactWebViewManager::RegisterEvents() {
  24. if (auto webView = m_webView.get()) {
  25. m_navigationCompletedRevoker = webView.NavigationCompleted(
  26. winrt::auto_revoke, [=](auto const& sender, auto const& args) {
  27. OnNavigationCompleted(sender, args);
  28. });
  29. }
  30. }
  31. // IViewManagerWithReactContext
  32. winrt::IReactContext ReactWebViewManager::ReactContext() noexcept {
  33. return m_reactContext;
  34. }
  35. void ReactWebViewManager::ReactContext(IReactContext reactContext) noexcept {
  36. m_reactContext = reactContext;
  37. }
  38. // IViewManagerWithNativeProperties
  39. IMapView<hstring, ViewManagerPropertyType> ReactWebViewManager::NativeProps() noexcept {
  40. auto nativeProps = winrt::single_threaded_map<hstring, ViewManagerPropertyType>();
  41. nativeProps.Insert(L"source", ViewManagerPropertyType::Map);
  42. return nativeProps.GetView();
  43. }
  44. void ReactWebViewManager::UpdateProperties(
  45. FrameworkElement const& view,
  46. IJSValueReader const& propertyMapReader) noexcept {
  47. if (auto webView = view.try_as<winrt::WebView>()) {
  48. const JSValueObject& propertyMap = JSValue::ReadObjectFrom(propertyMapReader);
  49. for (auto const& pair : propertyMap) {
  50. auto const& propertyName = pair.first;
  51. auto const& propertyValue = pair.second;
  52. if (propertyName == "source") {
  53. if (!propertyValue.IsNull()) {
  54. auto const& srcMap = propertyValue.Object();
  55. auto uriString = srcMap.at("uri").String();
  56. // non-uri sources not yet supported
  57. if (uriString.length() == 0) {
  58. continue;
  59. }
  60. bool isPackagerAsset = false;
  61. if (srcMap.find("__packager_asset") != srcMap.end()) {
  62. isPackagerAsset = srcMap.at("__packager_asset").Boolean();
  63. }
  64. if (isPackagerAsset && uriString.find("assets") == 0) {
  65. uriString.replace(0, 6, "ms-appx://");
  66. }
  67. SetSource(winrt::Uri(to_hstring(uriString)));
  68. }
  69. }
  70. }
  71. }
  72. }
  73. void ReactWebViewManager::SetSource(winrt::Uri const& uri) {
  74. if (auto webView = m_webView.get()) {
  75. auto tag = webView.GetValue(winrt::FrameworkElement::TagProperty()).as<winrt::IPropertyValue>().GetInt64();
  76. m_reactContext.DispatchEvent(
  77. webView,
  78. L"topLoadingStart",
  79. [tag](winrt::IJSValueWriter const& eventDataWriter) noexcept {
  80. eventDataWriter.WriteObjectBegin();
  81. {
  82. WriteProperty(eventDataWriter, L"target", tag);
  83. }
  84. eventDataWriter.WriteObjectEnd();
  85. });
  86. webView.Navigate(uri);
  87. }
  88. }
  89. // IViewManagerWithExportedEventTypeConstants
  90. ConstantProvider ReactWebViewManager::ExportedCustomBubblingEventTypeConstants() noexcept {
  91. return nullptr;
  92. }
  93. ConstantProvider ReactWebViewManager::ExportedCustomDirectEventTypeConstants() noexcept {
  94. return [](winrt::Microsoft::ReactNative::IJSValueWriter const& constantWriter) {
  95. WriteCustomDirectEventTypeConstant(constantWriter, "onLoadingStart");
  96. WriteCustomDirectEventTypeConstant(constantWriter, "onLoad");
  97. WriteCustomDirectEventTypeConstant(constantWriter, "onLoadingFinish");
  98. };
  99. }
  100. // IViewManagerWithCommands
  101. IMapView<hstring, int64_t> ReactWebViewManager::Commands() noexcept {
  102. auto commands = winrt::single_threaded_map<hstring, int64_t>();
  103. commands.Insert(L"goForward", 0);
  104. commands.Insert(L"goBack", 1);
  105. commands.Insert(L"reload", 2);
  106. return commands.GetView();
  107. }
  108. void ReactWebViewManager::DispatchCommand(
  109. FrameworkElement const& view,
  110. int64_t commandId,
  111. winrt::Microsoft::ReactNative::IJSValueReader const& commandArgsReader) noexcept {
  112. if (auto webView = view.try_as<winrt::WebView>()) {
  113. switch (commandId) {
  114. case 0: // goForward
  115. webView.GoForward();
  116. break;
  117. case 1: // goBack
  118. webView.GoBack();
  119. break;
  120. case 2: // reload
  121. webView.Refresh();
  122. break;
  123. }
  124. }
  125. }
  126. void ReactWebViewManager::OnNavigationCompleted(winrt::WebView const& webView, winrt::WebViewNavigationCompletedEventArgs const& args) {
  127. m_reactContext.DispatchEvent(
  128. webView,
  129. L"topLoadingFinish",
  130. [webView, args](winrt::IJSValueWriter const& eventDataWriter) noexcept {
  131. eventDataWriter.WriteObjectBegin();
  132. {
  133. auto tag = webView.GetValue(winrt::FrameworkElement::TagProperty()).as<winrt::IPropertyValue>().GetInt64();
  134. WriteProperty(eventDataWriter, L"canGoBack", webView.CanGoBack());
  135. WriteProperty(eventDataWriter, L"canGoForward", webView.CanGoForward());
  136. WriteProperty(eventDataWriter, L"loading", false);
  137. WriteProperty(eventDataWriter, L"target", tag);
  138. WriteProperty(eventDataWriter, L"title", webView.DocumentTitle());
  139. WriteProperty(eventDataWriter, L"url", args.Uri().ToString());
  140. }
  141. eventDataWriter.WriteObjectEnd();
  142. });
  143. }
  144. } // namespace winrt::ReactWebView::implementation