Açıklama Yok

ReactWebView.cpp 6.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. // Copyright (c) Microsoft Corporation. All rights reserved.
  2. // Licensed under the MIT License.
  3. #include "pch.h"
  4. #include "JSValueXaml.h"
  5. #include "ReactWebView.h"
  6. #include "ReactWebView.g.cpp"
  7. namespace winrt {
  8. using namespace Microsoft::ReactNative;
  9. using namespace Windows::Data::Json;
  10. using namespace Windows::Foundation;
  11. using namespace Windows::UI;
  12. using namespace Windows::UI::Popups;
  13. using namespace Windows::UI::Xaml;
  14. using namespace Windows::UI::Xaml::Controls;
  15. using namespace Windows::UI::Xaml::Input;
  16. using namespace Windows::UI::Xaml::Media;
  17. } // namespace winrt
  18. namespace winrt::ReactNativeWebView::implementation {
  19. ReactWebView::ReactWebView(winrt::IReactContext const& reactContext) : m_reactContext(reactContext) {
  20. #ifdef CHAKRACORE_UWP
  21. m_webView = winrt::WebView(winrt::WebViewExecutionMode::SeparateProcess);
  22. #else
  23. m_webView = winrt::WebView();
  24. #endif
  25. this->Content(m_webView);
  26. RegisterEvents();
  27. }
  28. ReactWebView::~ReactWebView()
  29. {
  30. if (m_messagingEnabled) {
  31. //m_webBridge.MessagePostedEvent(m_message_token);
  32. }
  33. }
  34. void ReactWebView::RegisterEvents() {
  35. m_navigationStartingRevoker = m_webView.NavigationStarting(
  36. winrt::auto_revoke, [ref = get_weak()](auto const& sender, auto const& args) {
  37. if (auto self = ref.get()) {
  38. self->OnNavigationStarting(sender, args);
  39. }
  40. });
  41. m_navigationCompletedRevoker = m_webView.NavigationCompleted(
  42. winrt::auto_revoke, [ref = get_weak()](auto const& sender, auto const& args) {
  43. if (auto self = ref.get()) {
  44. self->OnNavigationCompleted(sender, args);
  45. }
  46. });
  47. m_navigationFailedRevoker = m_webView.NavigationFailed(
  48. winrt::auto_revoke, [ref = get_weak()](auto const& sender, auto const& args) {
  49. if (auto self = ref.get()) {
  50. self->OnNavigationFailed(sender, args);
  51. }
  52. });
  53. }
  54. void ReactWebView::WriteWebViewNavigationEventArg(winrt::WebView const& sender, winrt::IJSValueWriter const& eventDataWriter) {
  55. auto tag = this->GetValue(winrt::FrameworkElement::TagProperty()).as<winrt::IPropertyValue>().GetInt64();
  56. WriteProperty(eventDataWriter, L"canGoBack", sender.CanGoBack());
  57. WriteProperty(eventDataWriter, L"canGoForward", sender.CanGoForward());
  58. WriteProperty(eventDataWriter, L"loading", !sender.IsLoaded());
  59. WriteProperty(eventDataWriter, L"target", tag);
  60. WriteProperty(eventDataWriter, L"title", sender.DocumentTitle());
  61. if (auto uri = sender.Source()) {
  62. WriteProperty(eventDataWriter, L"url", uri.AbsoluteCanonicalUri());
  63. }
  64. }
  65. void ReactWebView::OnNavigationStarting(winrt::WebView const& webView, winrt::WebViewNavigationStartingEventArgs const& /*args*/) {
  66. m_reactContext.DispatchEvent(
  67. *this,
  68. L"topLoadingStart",
  69. [&](winrt::IJSValueWriter const& eventDataWriter) noexcept {
  70. eventDataWriter.WriteObjectBegin();
  71. WriteWebViewNavigationEventArg(webView, eventDataWriter);
  72. eventDataWriter.WriteObjectEnd();
  73. });
  74. if (m_messagingEnabled) {
  75. auto tag = this->GetValue(winrt::FrameworkElement::TagProperty()).as<winrt::IPropertyValue>().GetInt64();
  76. /*
  77. m_webBridge = WebViewBridge::WebBridge(tag);
  78. m_message_token = m_webBridge.MessagePostedEvent([this](hstring const& message) {
  79. this->OnMessagePosted(message);
  80. });
  81. webView.AddWebAllowedObject(L"__REACT_WEB_VIEW_BRIDGE", m_webBridge);
  82. */
  83. m_webBridge = WebBridge();
  84. webView.AddWebAllowedObject(L"__REACT_WEB_VIEW_BRIDGE", m_webBridge);
  85. }
  86. }
  87. void ReactWebView::OnMessagePosted(hstring const& message)
  88. {
  89. PostMessage(message);
  90. }
  91. void ReactWebView::OnNavigationCompleted(winrt::WebView const& webView, winrt::WebViewNavigationCompletedEventArgs const& /*args*/) {
  92. m_reactContext.DispatchEvent(
  93. *this,
  94. L"topLoadingFinish",
  95. [&](winrt::IJSValueWriter const& eventDataWriter) noexcept {
  96. eventDataWriter.WriteObjectBegin();
  97. WriteWebViewNavigationEventArg(webView, eventDataWriter);
  98. eventDataWriter.WriteObjectEnd();
  99. });
  100. if (m_messagingEnabled) {
  101. winrt::hstring windowAlert = L"window.alert = function (msg) {__REACT_WEB_VIEW_BRIDGE.postMessage(`{\"type\":\"__alert\",\"message\":\"${msg}\"}`)};";
  102. winrt::hstring postMessage = L"window.ReactNativeWebView = {postMessage: function (data) {__REACT_WEB_VIEW_BRIDGE.postMessage(String(data))}};";
  103. webView.InvokeScriptAsync(L"eval", { windowAlert + postMessage });
  104. }
  105. }
  106. void ReactWebView::OnNavigationFailed(winrt::IInspectable const& /*sender*/, winrt::WebViewNavigationFailedEventArgs const& args) {
  107. m_reactContext.DispatchEvent(
  108. *this,
  109. L"topLoadingError",
  110. [&](winrt::IJSValueWriter const& eventDataWriter) noexcept {
  111. auto httpCode = static_cast<int32_t>(args.WebErrorStatus());
  112. eventDataWriter.WriteObjectBegin();
  113. {
  114. WriteProperty(eventDataWriter, L"code", httpCode);
  115. WriteWebViewNavigationEventArg(m_webView, eventDataWriter);
  116. }
  117. eventDataWriter.WriteObjectEnd();
  118. });
  119. }
  120. void ReactWebView::PostMessage(winrt::hstring const& message) {
  121. winrt::JsonObject jsonObject;
  122. if (winrt::JsonObject::TryParse(message, jsonObject) && jsonObject.HasKey(L"type")) {
  123. auto type = jsonObject.GetNamedString(L"type");
  124. if (type == L"__alert") {
  125. auto dialog = winrt::MessageDialog(jsonObject.GetNamedString(L"message"));
  126. dialog.Commands().Append(winrt::UICommand(L"OK"));
  127. dialog.ShowAsync();
  128. return;
  129. }
  130. }
  131. m_reactContext.DispatchEvent(
  132. *this,
  133. L"topMessage",
  134. [&](winrt::Microsoft::ReactNative::IJSValueWriter const& eventDataWriter) noexcept {
  135. eventDataWriter.WriteObjectBegin();
  136. {
  137. WriteProperty(eventDataWriter, L"data", message);
  138. }
  139. eventDataWriter.WriteObjectEnd();
  140. });
  141. }
  142. void ReactWebView::SetMessagingEnabled(bool enabled) {
  143. m_messagingEnabled = enabled;
  144. }
  145. } // namespace winrt::ReactNativeWebView::implementation