暫無描述

ReactWebViewManager.cpp 6.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. #include "pch.h"
  2. #include "ReactWebViewManager.h"
  3. #include "NativeModules.h"
  4. #include "ReactWebView.h"
  5. #include "JSValueXaml.h"
  6. namespace winrt {
  7. using namespace Microsoft::ReactNative;
  8. using namespace Windows::Foundation;
  9. using namespace Windows::Foundation::Collections;
  10. using namespace Windows::UI;
  11. using namespace Windows::UI::Xaml;
  12. using namespace Windows::UI::Xaml::Controls;
  13. }
  14. namespace winrt::ReactNativeWebView::implementation {
  15. ReactWebViewManager::ReactWebViewManager() {}
  16. // IViewManager
  17. winrt::hstring ReactWebViewManager::Name() noexcept {
  18. return L"RCTWebView";
  19. }
  20. winrt::FrameworkElement ReactWebViewManager::CreateView() noexcept {
  21. auto view = winrt::ReactNativeWebView::ReactWebView(m_reactContext);
  22. return view;
  23. }
  24. // IViewManagerWithReactContext
  25. winrt::IReactContext ReactWebViewManager::ReactContext() noexcept {
  26. return m_reactContext;
  27. }
  28. void ReactWebViewManager::ReactContext(IReactContext reactContext) noexcept {
  29. m_reactContext = reactContext;
  30. }
  31. // IViewManagerWithNativeProperties
  32. IMapView<hstring, ViewManagerPropertyType> ReactWebViewManager::NativeProps() noexcept {
  33. auto nativeProps = winrt::single_threaded_map<hstring, ViewManagerPropertyType>();
  34. nativeProps.Insert(L"source", ViewManagerPropertyType::Map);
  35. nativeProps.Insert(L"backgroundColor", ViewManagerPropertyType::Color);
  36. nativeProps.Insert(L"messagingEnabled", ViewManagerPropertyType::Boolean);
  37. return nativeProps.GetView();
  38. }
  39. void ReactWebViewManager::UpdateProperties(
  40. FrameworkElement const& view,
  41. IJSValueReader const& propertyMapReader) noexcept {
  42. auto control = view.try_as<winrt::UserControl>();
  43. auto content = control.Content();
  44. if (auto webView = content.try_as<winrt::WebView>()) {
  45. const JSValueObject& propertyMap = JSValueObject::ReadFrom(propertyMapReader);
  46. for (auto const& pair : propertyMap) {
  47. auto const& propertyName = pair.first;
  48. auto const& propertyValue = pair.second;
  49. if (propertyValue.IsNull()) continue;
  50. if (propertyName == "source") {
  51. auto const& srcMap = propertyValue.AsObject();
  52. if (srcMap.find("uri") != srcMap.end()) {
  53. auto uriString = srcMap.at("uri").AsString();
  54. if (uriString.length() == 0) {
  55. continue;
  56. }
  57. bool isPackagerAsset = false;
  58. if (srcMap.find("__packager_asset") != srcMap.end()) {
  59. isPackagerAsset = srcMap.at("__packager_asset").AsBoolean();
  60. }
  61. if (isPackagerAsset && uriString.find("file://") == 0) {
  62. auto bundleRootPath = winrt::to_string(ReactNativeHost().InstanceSettings().BundleRootPath());
  63. uriString.replace(0, 7, bundleRootPath.empty() ? "ms-appx-web:///Bundle/" : bundleRootPath);
  64. }
  65. webView.Navigate(winrt::Uri(to_hstring(uriString)));
  66. }
  67. else if (srcMap.find("html") != srcMap.end()) {
  68. auto htmlString = srcMap.at("html").AsString();
  69. webView.NavigateToString(to_hstring(htmlString));
  70. }
  71. }
  72. else if (propertyName == "backgroundColor") {
  73. auto color = propertyValue.To<winrt::Color>();
  74. webView.DefaultBackgroundColor(color.A==0 ? winrt::Colors::Transparent() : color);
  75. }
  76. else if (propertyName == "messagingEnabled") {
  77. auto messagingEnabled = propertyValue.To<bool>();
  78. if (auto reactWebView = view.try_as<ReactNativeWebView::ReactWebView>()) {
  79. reactWebView.SetMessagingEnabled(messagingEnabled);
  80. }
  81. }
  82. }
  83. }
  84. }
  85. // IViewManagerWithExportedEventTypeConstants
  86. ConstantProviderDelegate ReactWebViewManager::ExportedCustomBubblingEventTypeConstants() noexcept {
  87. return nullptr;
  88. }
  89. ConstantProviderDelegate ReactWebViewManager::ExportedCustomDirectEventTypeConstants() noexcept {
  90. return [](winrt::IJSValueWriter const& constantWriter) {
  91. WriteCustomDirectEventTypeConstant(constantWriter, "LoadingStart");
  92. WriteCustomDirectEventTypeConstant(constantWriter, "LoadingFinish");
  93. WriteCustomDirectEventTypeConstant(constantWriter, "LoadingError");
  94. WriteCustomDirectEventTypeConstant(constantWriter, "Message");
  95. };
  96. }
  97. // IViewManagerWithCommands
  98. IVectorView<hstring> ReactWebViewManager::Commands() noexcept {
  99. auto commands = winrt::single_threaded_vector<hstring>();
  100. commands.Append(L"goForward");
  101. commands.Append(L"goBack");
  102. commands.Append(L"reload");
  103. commands.Append(L"stopLoading");
  104. commands.Append(L"injectJavaScript");
  105. commands.Append(L"postMessage");
  106. return commands.GetView();
  107. }
  108. void ReactWebViewManager::DispatchCommand(
  109. FrameworkElement const& view,
  110. winrt::hstring const& commandId,
  111. winrt::IJSValueReader const& commandArgsReader) noexcept {
  112. auto control = view.try_as<winrt::UserControl>();
  113. auto content = control.Content();
  114. auto commandArgs = JSValue::ReadArrayFrom(commandArgsReader);
  115. if (auto webView = content.try_as<winrt::WebView>()) {
  116. if (commandId == L"goForward") {
  117. if (webView.CanGoForward()) {
  118. webView.GoForward();
  119. }
  120. }
  121. else if (commandId == L"goBack") {
  122. if (webView.CanGoBack()) {
  123. webView.GoBack();
  124. }
  125. }
  126. else if (commandId == L"reload") {
  127. webView.Refresh();
  128. }
  129. else if (commandId == L"stopLoading") {
  130. webView.Stop();
  131. }
  132. else if (commandId == L"injectJavaScript") {
  133. webView.InvokeScriptAsync(L"eval", { winrt::to_hstring(commandArgs[0].AsString()) });
  134. } else if(commandId == L"postMessage") {
  135. if (auto reactWebView = view.try_as<ReactNativeWebView::ReactWebView>()) {
  136. reactWebView.PostMessage(winrt::to_hstring(commandArgs[0].AsString()));
  137. }
  138. }
  139. }
  140. }
  141. } // namespace winrt::ReactWebView::implementation