@javascriptcommon/react-native-webview 13.12.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +82 -0
  3. package/android/build.gradle +110 -0
  4. package/android/gradle.properties +5 -0
  5. package/android/src/main/AndroidManifest.xml +15 -0
  6. package/android/src/main/AndroidManifestNew.xml +13 -0
  7. package/android/src/main/java/com/reactnativecommunity/webview/RNCBasicAuthCredential.java +11 -0
  8. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebChromeClient.java +372 -0
  9. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebView.java +450 -0
  10. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewClient.java +328 -0
  11. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewConfig.java +11 -0
  12. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewFileProvider.java +14 -0
  13. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManagerImpl.kt +720 -0
  14. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewMessagingModule.kt +19 -0
  15. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewModuleImpl.java +554 -0
  16. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewPackage.java +56 -0
  17. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewWrapper.kt +39 -0
  18. package/android/src/main/java/com/reactnativecommunity/webview/URLUtil.java +179 -0
  19. package/android/src/main/java/com/reactnativecommunity/webview/events/TopCustomMenuSelectionEvent.kt +24 -0
  20. package/android/src/main/java/com/reactnativecommunity/webview/events/TopHttpErrorEvent.kt +25 -0
  21. package/android/src/main/java/com/reactnativecommunity/webview/events/TopLoadingErrorEvent.kt +25 -0
  22. package/android/src/main/java/com/reactnativecommunity/webview/events/TopLoadingFinishEvent.kt +24 -0
  23. package/android/src/main/java/com/reactnativecommunity/webview/events/TopLoadingProgressEvent.kt +24 -0
  24. package/android/src/main/java/com/reactnativecommunity/webview/events/TopLoadingStartEvent.kt +25 -0
  25. package/android/src/main/java/com/reactnativecommunity/webview/events/TopMessageEvent.kt +24 -0
  26. package/android/src/main/java/com/reactnativecommunity/webview/events/TopNewWindowEvent.kt +25 -0
  27. package/android/src/main/java/com/reactnativecommunity/webview/events/TopRenderProcessGoneEvent.kt +26 -0
  28. package/android/src/main/java/com/reactnativecommunity/webview/events/TopShouldStartLoadWithRequestEvent.kt +29 -0
  29. package/android/src/main/res/xml/file_provider_paths.xml +6 -0
  30. package/android/src/newarch/com/reactnativecommunity/webview/RNCWebViewManager.java +553 -0
  31. package/android/src/newarch/com/reactnativecommunity/webview/RNCWebViewModule.java +63 -0
  32. package/android/src/oldarch/com/reactnativecommunity/webview/RNCWebViewManager.java +328 -0
  33. package/android/src/oldarch/com/reactnativecommunity/webview/RNCWebViewModule.java +59 -0
  34. package/apple/RCTConvert+WKDataDetectorTypes.h +11 -0
  35. package/apple/RCTConvert+WKDataDetectorTypes.m +27 -0
  36. package/apple/RNCWKProcessPoolManager.h +15 -0
  37. package/apple/RNCWKProcessPoolManager.m +36 -0
  38. package/apple/RNCWebView.h +35 -0
  39. package/apple/RNCWebView.mm +546 -0
  40. package/apple/RNCWebViewDecisionManager.h +20 -0
  41. package/apple/RNCWebViewDecisionManager.m +47 -0
  42. package/apple/RNCWebViewImpl.h +161 -0
  43. package/apple/RNCWebViewImpl.m +1979 -0
  44. package/apple/RNCWebViewManager.h +9 -0
  45. package/apple/RNCWebViewManager.mm +215 -0
  46. package/apple/RNCWebViewModule.h +23 -0
  47. package/apple/RNCWebViewModule.mm +34 -0
  48. package/index.d.ts +65 -0
  49. package/index.js +4 -0
  50. package/ios/RNCWebView.xcodeproj/project.pbxproj +273 -0
  51. package/lib/NativeRNCWebViewModule.d.ts +10 -0
  52. package/lib/NativeRNCWebViewModule.js +1 -0
  53. package/lib/RNCWebViewNativeComponent.d.ts +242 -0
  54. package/lib/RNCWebViewNativeComponent.js +1 -0
  55. package/lib/WebView.android.d.ts +6 -0
  56. package/lib/WebView.android.js +1 -0
  57. package/lib/WebView.d.ts +6 -0
  58. package/lib/WebView.ios.d.ts +6 -0
  59. package/lib/WebView.ios.js +1 -0
  60. package/lib/WebView.js +1 -0
  61. package/lib/WebView.macos.d.ts +6 -0
  62. package/lib/WebView.macos.js +1 -0
  63. package/lib/WebView.styles.d.ts +38 -0
  64. package/lib/WebView.styles.js +1 -0
  65. package/lib/WebView.windows.d.ts +17 -0
  66. package/lib/WebView.windows.js +1 -0
  67. package/lib/WebViewNativeComponent.macos.d.ts +3 -0
  68. package/lib/WebViewNativeComponent.macos.js +1 -0
  69. package/lib/WebViewNativeComponent.windows.d.ts +3 -0
  70. package/lib/WebViewNativeComponent.windows.js +1 -0
  71. package/lib/WebViewShared.d.ts +38 -0
  72. package/lib/WebViewShared.js +1 -0
  73. package/lib/WebViewTypes.d.ts +1093 -0
  74. package/lib/WebViewTypes.js +1 -0
  75. package/lib/index.d.ts +3 -0
  76. package/lib/index.js +1 -0
  77. package/macos/RNCWebView.xcodeproj/project.pbxproj +363 -0
  78. package/package.json +101 -0
  79. package/react-native-webview.podspec +46 -0
  80. package/react-native.config.js +44 -0
  81. package/src/NativeRNCWebViewModule.ts +15 -0
  82. package/src/RNCWebViewNativeComponent.ts +342 -0
  83. package/src/WebView.android.tsx +317 -0
  84. package/src/WebView.ios.tsx +299 -0
  85. package/src/WebView.macos.tsx +245 -0
  86. package/src/WebView.styles.ts +41 -0
  87. package/src/WebView.tsx +25 -0
  88. package/src/WebView.windows.tsx +210 -0
  89. package/src/WebViewNativeComponent.macos.ts +7 -0
  90. package/src/WebViewNativeComponent.windows.ts +8 -0
  91. package/src/WebViewShared.tsx +283 -0
  92. package/src/WebViewTypes.ts +1332 -0
  93. package/src/__tests__/WebViewShared-test.js +323 -0
  94. package/src/__tests__/__snapshots__/WebViewShared-test.js.snap +8 -0
  95. package/src/index.ts +4 -0
  96. package/windows/ExperimentalFeatures.props +11 -0
  97. package/windows/ReactNativeWebView/PropertySheet.props +16 -0
  98. package/windows/ReactNativeWebView/ReactNativeWebView.def +3 -0
  99. package/windows/ReactNativeWebView/ReactNativeWebView.filters +33 -0
  100. package/windows/ReactNativeWebView/ReactNativeWebView.vcxproj +189 -0
  101. package/windows/ReactNativeWebView/ReactPackageProvider.cpp +26 -0
  102. package/windows/ReactNativeWebView/ReactPackageProvider.h +20 -0
  103. package/windows/ReactNativeWebView/ReactPackageProvider.idl +7 -0
  104. package/windows/ReactNativeWebView/ReactWebView.cpp +242 -0
  105. package/windows/ReactNativeWebView/ReactWebView.h +56 -0
  106. package/windows/ReactNativeWebView/ReactWebView.idl +31 -0
  107. package/windows/ReactNativeWebView/ReactWebView2.cpp +473 -0
  108. package/windows/ReactNativeWebView/ReactWebView2.h +91 -0
  109. package/windows/ReactNativeWebView/ReactWebView2Manager.cpp +205 -0
  110. package/windows/ReactNativeWebView/ReactWebView2Manager.h +57 -0
  111. package/windows/ReactNativeWebView/ReactWebViewHelpers.cpp +70 -0
  112. package/windows/ReactNativeWebView/ReactWebViewHelpers.h +16 -0
  113. package/windows/ReactNativeWebView/ReactWebViewManager.cpp +224 -0
  114. package/windows/ReactNativeWebView/ReactWebViewManager.h +58 -0
  115. package/windows/ReactNativeWebView/WebBridge.cpp +19 -0
  116. package/windows/ReactNativeWebView/WebBridge.h +24 -0
  117. package/windows/ReactNativeWebView/WebBridge.idl +11 -0
  118. package/windows/ReactNativeWebView/pch.cpp +1 -0
  119. package/windows/ReactNativeWebView/pch.h +37 -0
  120. package/windows/ReactNativeWebView.sln +185 -0
@@ -0,0 +1,205 @@
1
+ #include "pch.h"
2
+ #include "ReactWebView2Manager.h"
3
+
4
+ #if HAS_WEBVIEW2
5
+ #include "NativeModules.h"
6
+ #include "ReactWebView2.h"
7
+ #include "JSValueXaml.h"
8
+
9
+ namespace mux {
10
+ using namespace winrt::Microsoft::UI::Xaml::Controls;
11
+ }
12
+
13
+ namespace winrt {
14
+ using namespace Microsoft::ReactNative;
15
+ using namespace Windows::Foundation;
16
+ using namespace Windows::Foundation::Collections;
17
+ using namespace Windows::Web::Http;
18
+ using namespace Windows::Web::Http::Headers;
19
+ using namespace xaml;
20
+ using namespace xaml::Controls;
21
+ using namespace xaml::Input;
22
+ }
23
+
24
+ namespace winrt::ReactNativeWebView::implementation {
25
+
26
+ ReactWebView2Manager::ReactWebView2Manager() {}
27
+
28
+ // IViewManager
29
+ winrt::hstring ReactWebView2Manager::Name() noexcept {
30
+ return L"RCTWebView2";
31
+ }
32
+
33
+ winrt::FrameworkElement ReactWebView2Manager::CreateView() noexcept {
34
+ auto view = winrt::ReactNativeWebView::ReactWebView2(m_reactContext);
35
+ return view;
36
+ }
37
+
38
+ // IViewManagerWithReactContext
39
+ winrt::IReactContext ReactWebView2Manager::ReactContext() noexcept {
40
+ return m_reactContext;
41
+ }
42
+
43
+ void ReactWebView2Manager::ReactContext(IReactContext reactContext) noexcept {
44
+ m_reactContext = reactContext;
45
+ }
46
+
47
+ // IViewManagerWithNativeProperties
48
+ IMapView<hstring, ViewManagerPropertyType> ReactWebView2Manager::NativeProps() noexcept {
49
+ auto nativeProps = winrt::single_threaded_map<hstring, ViewManagerPropertyType>();
50
+ nativeProps.Insert(L"source", ViewManagerPropertyType::Map);
51
+ nativeProps.Insert(L"messagingEnabled", ViewManagerPropertyType::Boolean);
52
+ nativeProps.Insert(L"injectedJavaScript", ViewManagerPropertyType::String);
53
+ nativeProps.Insert(L"linkHandlingEnabled", ViewManagerPropertyType::String);
54
+ return nativeProps.GetView();
55
+ }
56
+
57
+ void ReactWebView2Manager::UpdateProperties(
58
+ FrameworkElement const& view,
59
+ IJSValueReader const& propertyMapReader) noexcept {
60
+ auto control = view.as<winrt::ContentPresenter>();
61
+ auto content = control.Content();
62
+ auto webView = content.as<mux::WebView2>();
63
+ const JSValueObject& propertyMap = JSValueObject::ReadFrom(propertyMapReader);
64
+
65
+ for (auto const& pair : propertyMap) {
66
+ auto const& propertyName = pair.first;
67
+ auto const& propertyValue = pair.second;
68
+ if (propertyValue.IsNull()) continue;
69
+
70
+ if (propertyName == "source") {
71
+ auto const& srcMap = propertyValue.AsObject();
72
+ auto reactWebView2 = view.as<winrt::ReactNativeWebView::ReactWebView2>();
73
+ std::string const fileScheme = "file://";
74
+ if (srcMap.find("uri") != srcMap.end()) {
75
+ auto uriString = srcMap.at("uri").AsString();
76
+ if (uriString.length() == 0) {
77
+ continue;
78
+ }
79
+
80
+ bool isPackagerAsset = false;
81
+ if (srcMap.find("__packager_asset") != srcMap.end()) {
82
+ isPackagerAsset = srcMap.at("__packager_asset").AsBoolean();
83
+ }
84
+ if (isPackagerAsset && uriString.find(fileScheme) == 0) {
85
+ auto bundleRootPath = winrt::to_string(ReactNativeHost().InstanceSettings().BundleRootPath());
86
+ uriString.replace(0, std::size(fileScheme), bundleRootPath.empty() ? "ms-appx-web:///Bundle/" : bundleRootPath);
87
+ }
88
+ if (uriString.find("ms-appdata://") == 0 || uriString.find("ms-appx-web://") == 0) {
89
+ reactWebView2.NavigateToHtml(to_hstring(uriString));
90
+ } else {
91
+ reactWebView2.NavigateWithWebResourceRequest(MakeJSValueTreeReader(JSValue(srcMap.Copy())));
92
+ }
93
+ }
94
+ else if (srcMap.find("html") != srcMap.end()) {
95
+ auto htmlString = srcMap.at("html").AsString();
96
+ reactWebView2.NavigateToHtml(to_hstring(htmlString));
97
+ }
98
+ }
99
+ else if (propertyName == "messagingEnabled") {
100
+ auto messagingEnabled = propertyValue.To<bool>();
101
+ auto reactWebView2 = view.as<ReactNativeWebView::ReactWebView2>();
102
+ reactWebView2.MessagingEnabled(messagingEnabled);
103
+ }
104
+ else if (propertyName == "injectedJavaScript")
105
+ {
106
+ auto injectedJavascript = propertyValue.AsString();
107
+ auto reactWebView2 = view.as<ReactNativeWebView::ReactWebView2>();
108
+ reactWebView2.InjectedJavascript(to_hstring(injectedJavascript));
109
+ }
110
+ else if (propertyName == "linkHandlingEnabled") {
111
+ auto linkHandlingEnabled = propertyValue.To<bool>();
112
+ auto reactWebView2 = view.as<ReactNativeWebView::ReactWebView2>();
113
+ reactWebView2.LinkHandlingEnabled(linkHandlingEnabled);
114
+ }
115
+ }
116
+ }
117
+
118
+ // IViewManagerWithExportedEventTypeConstants
119
+ ConstantProviderDelegate ReactWebView2Manager::ExportedCustomBubblingEventTypeConstants() noexcept {
120
+ return nullptr;
121
+ }
122
+
123
+ ConstantProviderDelegate ReactWebView2Manager::ExportedCustomDirectEventTypeConstants() noexcept {
124
+ return [](winrt::IJSValueWriter const& constantWriter) {
125
+ WriteCustomDirectEventTypeConstant(constantWriter, "DOMContentLoaded");
126
+ WriteCustomDirectEventTypeConstant(constantWriter, "LoadingStart");
127
+ WriteCustomDirectEventTypeConstant(constantWriter, "LoadingFinish");
128
+ WriteCustomDirectEventTypeConstant(constantWriter, "LoadingError");
129
+ WriteCustomDirectEventTypeConstant(constantWriter, "Message");
130
+ WriteCustomDirectEventTypeConstant(constantWriter, "FrameNavigationStart");
131
+ WriteCustomDirectEventTypeConstant(constantWriter, "FrameNavigationFinish");
132
+ WriteCustomDirectEventTypeConstant(constantWriter, "OpenWindow");
133
+ WriteCustomDirectEventTypeConstant(constantWriter, "SourceChanged");
134
+ };
135
+ }
136
+
137
+ // IViewManagerWithCommands
138
+ IVectorView<hstring> ReactWebView2Manager::Commands() noexcept {
139
+ auto commands = winrt::single_threaded_vector<hstring>();
140
+ commands.Append(L"goForward");
141
+ commands.Append(L"goBack");
142
+ commands.Append(L"reload");
143
+ commands.Append(L"stopLoading");
144
+ commands.Append(L"injectJavaScript");
145
+ commands.Append(L"requestFocus");
146
+ commands.Append(L"clearCache");
147
+ commands.Append(L"postMessage");
148
+ commands.Append(L"loadUrl");
149
+ return commands.GetView();
150
+ }
151
+
152
+ void ReactWebView2Manager::DispatchCommand(
153
+ FrameworkElement const& view,
154
+ winrt::hstring const& commandId,
155
+ winrt::IJSValueReader const& commandArgsReader) noexcept {
156
+ auto control = view.as<winrt::ContentPresenter>();
157
+ auto content = control.Content();
158
+ auto webView = content.as<mux::WebView2>();
159
+ auto commandArgs = JSValue::ReadArrayFrom(commandArgsReader);
160
+
161
+ if (commandId == L"goForward") {
162
+ if (webView.CanGoForward()) {
163
+ webView.GoForward();
164
+ }
165
+ }
166
+ else if (commandId == L"goBack") {
167
+ if (webView.CanGoBack()) {
168
+ webView.GoBack();
169
+ }
170
+ }
171
+ else if (commandId == L"reload") {
172
+ webView.Reload();
173
+ }
174
+ else if (commandId == L"stopLoading") {
175
+ if (webView.CoreWebView2() != nullptr) {
176
+ webView.CoreWebView2().Stop();
177
+ }
178
+ }
179
+ else if (commandId == L"injectJavaScript") {
180
+ webView.ExecuteScriptAsync(winrt::to_hstring(commandArgs[0].AsString()));
181
+ }
182
+ else if (commandId == L"requestFocus") {
183
+ FocusManager::TryFocusAsync(webView, FocusState::Programmatic);
184
+ }
185
+ else if (commandId == L"clearCache") {
186
+ // There is no way to clear the cache in WebView2 because it is shared with Edge.
187
+ // The best we can do is clear the cookies, because we cannot access history or local storage.
188
+ auto cookieManager = webView.CoreWebView2().CookieManager();
189
+ cookieManager.DeleteAllCookies();
190
+ }
191
+ else if (commandId == L"loadUrl") {
192
+ auto uri = winrt::Uri(to_hstring(commandArgs[0].AsString()));
193
+ webView.Source(uri);
194
+ }
195
+ else if (commandId == L"postMessage") {
196
+ if (webView.CoreWebView2() != nullptr) {
197
+ auto message = commandArgs[0].AsString();
198
+ webView.CoreWebView2().PostWebMessageAsString(to_hstring(message));
199
+ }
200
+ }
201
+ }
202
+
203
+ } // namespace winrt::ReactNativeWebView::implementation
204
+
205
+ #endif // HAS_WEBVIEW2
@@ -0,0 +1,57 @@
1
+ // Copyright (c) Microsoft Corporation. All rights reserved.
2
+ // Licensed under the MIT License.
3
+
4
+ #pragma once
5
+
6
+ #include "ReactWebView2.h"
7
+
8
+ #if HAS_WEBVIEW2
9
+ #include "winrt/Microsoft.ReactNative.h"
10
+ #include "NativeModules.h"
11
+
12
+ namespace winrt::ReactNativeWebView::implementation {
13
+
14
+ class ReactWebView2Manager : public winrt::implements<
15
+ ReactWebView2Manager,
16
+ winrt::Microsoft::ReactNative::IViewManager,
17
+ winrt::Microsoft::ReactNative::IViewManagerWithReactContext,
18
+ winrt::Microsoft::ReactNative::IViewManagerWithNativeProperties,
19
+ winrt::Microsoft::ReactNative::IViewManagerWithExportedEventTypeConstants,
20
+ winrt::Microsoft::ReactNative::IViewManagerWithCommands> {
21
+ public:
22
+ ReactWebView2Manager();
23
+ // IViewManager
24
+ winrt::hstring Name() noexcept;
25
+ xaml::FrameworkElement CreateView() noexcept;
26
+
27
+ // IViewManagerWithReactContext
28
+ winrt::Microsoft::ReactNative::IReactContext ReactContext() noexcept;
29
+ void ReactContext(winrt::Microsoft::ReactNative::IReactContext reactContext) noexcept;
30
+
31
+ // IViewManagerWithNativeProperties
32
+ winrt::Windows::Foundation::Collections::
33
+ IMapView<winrt::hstring, winrt::Microsoft::ReactNative::ViewManagerPropertyType>
34
+ NativeProps() noexcept;
35
+
36
+ void UpdateProperties(
37
+ xaml::FrameworkElement const& view,
38
+ winrt::Microsoft::ReactNative::IJSValueReader const& propertyMapReader) noexcept;
39
+
40
+ // IViewManagerWithExportedEventTypeConstants
41
+ winrt::Microsoft::ReactNative::ConstantProviderDelegate ExportedCustomBubblingEventTypeConstants() noexcept;
42
+ winrt::Microsoft::ReactNative::ConstantProviderDelegate ExportedCustomDirectEventTypeConstants() noexcept;
43
+
44
+ // IViewManagerWithCommands
45
+ winrt::Windows::Foundation::Collections::IVectorView<winrt::hstring> Commands() noexcept;
46
+
47
+ void DispatchCommand(
48
+ xaml::FrameworkElement const& view,
49
+ winrt::hstring const& commandId,
50
+ winrt::Microsoft::ReactNative::IJSValueReader const& commandArgsReader) noexcept;
51
+
52
+ private:
53
+ winrt::Microsoft::ReactNative::IReactContext m_reactContext{ nullptr };
54
+
55
+ };
56
+ } // namespace winrt::ReactNativeWebView::implementation
57
+ #endif // HAS_WEBVIEW2
@@ -0,0 +1,70 @@
1
+ // Copyright (c) Microsoft Corporation. All rights reserved.
2
+ // Licensed under the MIT License.
3
+
4
+ #pragma once
5
+
6
+ #include "pch.h"
7
+ #include "winrt/ReactNativeWebView.h"
8
+
9
+ using namespace winrt::ReactNativeWebView;
10
+
11
+ namespace winrt::ReactNativeWebView::implementation {
12
+ namespace ReactWebViewHelpers {
13
+ std::string TrimString(const std::string& str) {
14
+ std::string trimmedString = str;
15
+
16
+ // Trim from start
17
+ trimmedString.erase(0, trimmedString.find_first_not_of(" \t\n\r\f\v"));
18
+
19
+ // Trim from end
20
+ trimmedString.erase(trimmedString.find_last_not_of(" \t\n\r\f\v") + 1);
21
+
22
+ return trimmedString;
23
+ }
24
+
25
+ std::vector<std::string> SplitString(
26
+ const std::string& str,
27
+ const std::string& delim) {
28
+ std::vector<std::string> tokens;
29
+ auto startPos = 0;
30
+ auto endPos = str.find(delim);
31
+
32
+ while (endPos != std::string::npos) {
33
+ auto token = str.substr(startPos, endPos - startPos);
34
+ tokens.push_back(TrimString(token));
35
+
36
+ startPos = endPos + delim.length();
37
+ endPos = str.find(delim, startPos);
38
+ }
39
+
40
+ auto lastToken = str.substr(startPos);
41
+ tokens.push_back(TrimString(lastToken));
42
+
43
+ return tokens;
44
+ }
45
+
46
+ std::map<std::string, std::string> ParseSetCookieHeader(
47
+ const std::string& setCookieHeader) {
48
+ std::map<std::string, std::string> cookie;
49
+
50
+ // Split the header into individual cookie strings
51
+ auto cookieStrings = SplitString(setCookieHeader, ";");
52
+
53
+ // Extract the cookie name and value from the first string
54
+ auto nameValuePair = SplitString(cookieStrings[0], "=");
55
+ cookie["Name"] = TrimString(nameValuePair[0]);
56
+ cookie["Value"] = TrimString(nameValuePair[1]);
57
+
58
+ // Extract the attributes from the remaining strings
59
+ for (std::size_t i = 1; i < cookieStrings.size(); ++i) {
60
+ auto attributeValuePair = SplitString(cookieStrings[i], "=");
61
+ auto attributeName = attributeValuePair[0];
62
+ auto attributeValue =
63
+ attributeValuePair.size() > 1 ? attributeValuePair[1] : "";
64
+ cookie[attributeName] = TrimString(attributeValue);
65
+ }
66
+
67
+ return cookie;
68
+ }
69
+ }
70
+ } // namespace winrt::ReactNativeWebView::implementation
@@ -0,0 +1,16 @@
1
+ // Copyright (c) Microsoft Corporation. All rights reserved.
2
+ // Licensed under the MIT License.
3
+
4
+ #pragma once
5
+
6
+ #include "winrt/ReactNativeWebView.h"
7
+
8
+ using namespace winrt::ReactNativeWebView;
9
+
10
+ namespace winrt::ReactNativeWebView::implementation {
11
+ namespace ReactWebViewHelpers {
12
+ std::string TrimString(const std::string& str);
13
+ std::vector<std::string> SplitString(const std::string& str, const std::string& delim);
14
+ std::map<std::string, std::string> ParseSetCookieHeader(const std::string& setCookieHeader);
15
+ }
16
+ } // namespace winrt::ReactNativeWebView::implementation
@@ -0,0 +1,224 @@
1
+ // Copyright (c) Microsoft Corporation. All rights reserved.
2
+ // Licensed under the MIT License.
3
+
4
+ #include "pch.h"
5
+
6
+ #ifndef USE_WINUI3
7
+
8
+ #include "ReactWebViewManager.h"
9
+ #include "NativeModules.h"
10
+ #include "ReactWebView.h"
11
+ #include "JSValueXaml.h"
12
+
13
+
14
+ namespace winrt {
15
+ using namespace Microsoft::ReactNative;
16
+ using namespace Windows::Foundation;
17
+ using namespace Windows::Foundation::Collections;
18
+ using namespace Windows::UI;
19
+ using namespace Windows::UI::Xaml;
20
+ using namespace Windows::UI::Xaml::Controls;
21
+ using namespace Windows::Web::Http;
22
+ using namespace Windows::Web::Http::Headers;
23
+ }
24
+
25
+ namespace winrt::ReactNativeWebView::implementation {
26
+
27
+ ReactWebViewManager::ReactWebViewManager() {}
28
+
29
+ // IViewManager
30
+ winrt::hstring ReactWebViewManager::Name() noexcept {
31
+ return L"RCTWebView";
32
+ }
33
+
34
+ winrt::FrameworkElement ReactWebViewManager::CreateView() noexcept {
35
+ auto view = winrt::ReactNativeWebView::ReactWebView(m_reactContext);
36
+ return view;
37
+ }
38
+
39
+ // IViewManagerWithReactContext
40
+ winrt::IReactContext ReactWebViewManager::ReactContext() noexcept {
41
+ return m_reactContext;
42
+ }
43
+
44
+ void ReactWebViewManager::ReactContext(IReactContext reactContext) noexcept {
45
+ m_reactContext = reactContext;
46
+ }
47
+
48
+ // IViewManagerWithNativeProperties
49
+ IMapView<hstring, ViewManagerPropertyType> ReactWebViewManager::NativeProps() noexcept {
50
+ auto nativeProps = winrt::single_threaded_map<hstring, ViewManagerPropertyType>();
51
+ nativeProps.Insert(L"source", ViewManagerPropertyType::Map);
52
+ nativeProps.Insert(L"backgroundColor", ViewManagerPropertyType::Color);
53
+ nativeProps.Insert(L"messagingEnabled", ViewManagerPropertyType::Boolean);
54
+ return nativeProps.GetView();
55
+ }
56
+
57
+ void ReactWebViewManager::UpdateProperties(
58
+ FrameworkElement const& view,
59
+ IJSValueReader const& propertyMapReader) noexcept {
60
+ auto control = view.as<winrt::ContentPresenter>();
61
+ auto content = control.Content();
62
+ auto webView = content.as<winrt::WebView>();
63
+ const JSValueObject& propertyMap = JSValueObject::ReadFrom(propertyMapReader);
64
+
65
+ for (auto const& pair : propertyMap) {
66
+ auto const& propertyName = pair.first;
67
+ auto const& propertyValue = pair.second;
68
+ if (propertyValue.IsNull()) continue;
69
+
70
+ if (propertyName == "source") {
71
+ auto const& srcMap = propertyValue.AsObject();
72
+ if (srcMap.find("uri") != srcMap.end()) {
73
+ auto uriString = srcMap.at("uri").AsString();
74
+ if (uriString.length() == 0) {
75
+ continue;
76
+ }
77
+
78
+ bool isPackagerAsset = false;
79
+ if (srcMap.find("__packager_asset") != srcMap.end()) {
80
+ isPackagerAsset = srcMap.at("__packager_asset").AsBoolean();
81
+ }
82
+ if (isPackagerAsset && uriString.find("file://") == 0) {
83
+ auto bundleRootPath = winrt::to_string(ReactNativeHost().InstanceSettings().BundleRootPath());
84
+ uriString.replace(0, 7, bundleRootPath.empty() ? "ms-appx-web:///Bundle/" : bundleRootPath);
85
+ }
86
+
87
+ if (uriString.find("ms-appdata://") == 0 || uriString.find("ms-appx-web://") == 0) {
88
+ webView.Navigate(winrt::Uri(to_hstring(uriString)));
89
+ }
90
+ else {
91
+ bool hasHeaders = srcMap.find("headers") != srcMap.end();
92
+ auto httpRequest = winrt::HttpRequestMessage();
93
+ httpRequest.RequestUri(winrt::Uri(to_hstring(uriString)));
94
+ if (srcMap.find("method") != srcMap.end() && srcMap.at("method").AsString() == "POST")
95
+ {
96
+ httpRequest.Method(winrt::HttpMethod::Post());
97
+ auto formBody = srcMap.at("body").AsString();
98
+ bool isUrlEncodedForm = hasHeaders &&
99
+ srcMap.at("headers").AsObject().find("content-type") !=
100
+ srcMap.at("headers").AsObject().end() &&
101
+ srcMap.at("headers").AsObject().at("content-type") == "application/x-www-form-urlencoded";
102
+ if (isUrlEncodedForm)
103
+ {
104
+ auto formContent = winrt::single_threaded_observable_map<winrt::hstring, winrt::hstring>();
105
+ size_t counter = 0u;
106
+ auto current = formBody.find_first_of("&");
107
+ while (counter <= formBody.find_last_of("&"))
108
+ {
109
+ auto keyValueSeparator = formBody.substr(counter, counter + current).find('=');
110
+ if (keyValueSeparator <= current)
111
+ {
112
+ auto key = winrt::to_hstring(formBody.substr(counter, keyValueSeparator));
113
+ auto value = winrt::to_hstring(formBody.substr(
114
+ keyValueSeparator + counter + 1, current - keyValueSeparator - 1));
115
+ formContent.Insert(key, value);
116
+ }
117
+ counter += current + 1;
118
+ current = formBody.substr(counter, formBody.size() - counter).find_first_of("&");
119
+ }
120
+ httpRequest.Content(winrt::HttpFormUrlEncodedContent(formContent));
121
+ httpRequest.Headers().Accept().TryParseAdd(L"application/x-www-form-urlencoded");
122
+ }
123
+ else
124
+ {
125
+ httpRequest.Content(winrt::HttpStringContent(to_hstring(formBody)));
126
+ }
127
+ }
128
+ if (hasHeaders) {
129
+ for (auto const& header : srcMap.at("headers").AsObject()) {
130
+ auto const& headerKey = header.first;
131
+ auto const& headerValue = header.second;
132
+ if (headerValue.IsNull()) continue;
133
+ httpRequest.Headers().TryAppendWithoutValidation(winrt::to_hstring(headerKey), winrt::to_hstring(headerValue.AsString()));
134
+ }
135
+ }
136
+ webView.NavigateWithHttpRequestMessage(httpRequest);
137
+ }
138
+ }
139
+ else if (srcMap.find("html") != srcMap.end()) {
140
+ auto htmlString = srcMap.at("html").AsString();
141
+ webView.NavigateToString(to_hstring(htmlString));
142
+ }
143
+ }
144
+ else if (propertyName == "backgroundColor") {
145
+ auto color = propertyValue.To<winrt::Color>();
146
+ webView.DefaultBackgroundColor(color.A==0 ? winrt::Colors::Transparent() : color);
147
+ }
148
+ else if (propertyName == "messagingEnabled") {
149
+ auto messagingEnabled = propertyValue.To<bool>();
150
+ auto reactWebView = view.as<ReactNativeWebView::ReactWebView>();
151
+ reactWebView.MessagingEnabled(messagingEnabled);
152
+ }
153
+ }
154
+ }
155
+
156
+ // IViewManagerWithExportedEventTypeConstants
157
+ ConstantProviderDelegate ReactWebViewManager::ExportedCustomBubblingEventTypeConstants() noexcept {
158
+ return nullptr;
159
+ }
160
+
161
+ ConstantProviderDelegate ReactWebViewManager::ExportedCustomDirectEventTypeConstants() noexcept {
162
+ return [](winrt::IJSValueWriter const& constantWriter) {
163
+ WriteCustomDirectEventTypeConstant(constantWriter, "LoadingStart");
164
+ WriteCustomDirectEventTypeConstant(constantWriter, "LoadingFinish");
165
+ WriteCustomDirectEventTypeConstant(constantWriter, "LoadingError");
166
+ WriteCustomDirectEventTypeConstant(constantWriter, "Message");
167
+ WriteCustomDirectEventTypeConstant(constantWriter, "DOMContentLoaded");
168
+ WriteCustomDirectEventTypeConstant(constantWriter, "Message");
169
+ };
170
+ }
171
+
172
+ // IViewManagerWithCommands
173
+ IVectorView<hstring> ReactWebViewManager::Commands() noexcept {
174
+ auto commands = winrt::single_threaded_vector<hstring>();
175
+ commands.Append(L"goForward");
176
+ commands.Append(L"goBack");
177
+ commands.Append(L"reload");
178
+ commands.Append(L"stopLoading");
179
+ commands.Append(L"injectJavaScript");
180
+ commands.Append(L"postMessage");
181
+ commands.Append(L"loadUrl");
182
+ return commands.GetView();
183
+ }
184
+
185
+ void ReactWebViewManager::DispatchCommand(
186
+ FrameworkElement const& view,
187
+ winrt::hstring const& commandId,
188
+ winrt::IJSValueReader const& commandArgsReader) noexcept {
189
+ auto control = view.as<winrt::ContentPresenter>();
190
+ auto content = control.Content();
191
+ auto webView = content.as<winrt::WebView>();
192
+ auto commandArgs = JSValue::ReadArrayFrom(commandArgsReader);
193
+
194
+ if (commandId == L"goForward") {
195
+ if (webView.CanGoForward()) {
196
+ webView.GoForward();
197
+ }
198
+ }
199
+ else if (commandId == L"goBack") {
200
+ if (webView.CanGoBack()) {
201
+ webView.GoBack();
202
+ }
203
+ }
204
+ else if (commandId == L"reload") {
205
+ webView.Refresh();
206
+ }
207
+ else if (commandId == L"stopLoading") {
208
+ webView.Stop();
209
+ }
210
+ else if (commandId == L"injectJavaScript") {
211
+ webView.InvokeScriptAsync(L"eval", { winrt::to_hstring(commandArgs[0].AsString()) });
212
+ }
213
+ else if (commandId == L"postMessage") {
214
+ auto reactWebView = view.as<ReactNativeWebView::ReactWebView>();
215
+ reactWebView.PostMessage(to_hstring(commandArgs[0].AsString()));
216
+ }
217
+ else if (commandId == L"loadUrl") {
218
+ webView.Navigate(winrt::Uri(to_hstring(commandArgs[0].AsString())));
219
+ }
220
+ }
221
+
222
+ } // namespace winrt::ReactWebView::implementation
223
+
224
+ #endif // USE_WINUI3
@@ -0,0 +1,58 @@
1
+ // Copyright (c) Microsoft Corporation. All rights reserved.
2
+ // Licensed under the MIT License.
3
+
4
+ #pragma once
5
+
6
+ #ifndef USE_WINUI3
7
+
8
+ #include "winrt/Microsoft.ReactNative.h"
9
+ #include "NativeModules.h"
10
+ #include "ReactWebView.h"
11
+
12
+ namespace winrt::ReactNativeWebView::implementation {
13
+
14
+ class ReactWebViewManager : public winrt::implements<
15
+ ReactWebViewManager,
16
+ winrt::Microsoft::ReactNative::IViewManager,
17
+ winrt::Microsoft::ReactNative::IViewManagerWithReactContext,
18
+ winrt::Microsoft::ReactNative::IViewManagerWithNativeProperties,
19
+ winrt::Microsoft::ReactNative::IViewManagerWithExportedEventTypeConstants,
20
+ winrt::Microsoft::ReactNative::IViewManagerWithCommands> {
21
+ public:
22
+ ReactWebViewManager();
23
+ // IViewManager
24
+ winrt::hstring Name() noexcept;
25
+ winrt::Windows::UI::Xaml::FrameworkElement CreateView() noexcept;
26
+
27
+ // IViewManagerWithReactContext
28
+ winrt::Microsoft::ReactNative::IReactContext ReactContext() noexcept;
29
+ void ReactContext(winrt::Microsoft::ReactNative::IReactContext reactContext) noexcept;
30
+
31
+ // IViewManagerWithNativeProperties
32
+ winrt::Windows::Foundation::Collections::
33
+ IMapView<winrt::hstring, winrt::Microsoft::ReactNative::ViewManagerPropertyType>
34
+ NativeProps() noexcept;
35
+
36
+ void UpdateProperties(
37
+ winrt::Windows::UI::Xaml::FrameworkElement const& view,
38
+ winrt::Microsoft::ReactNative::IJSValueReader const& propertyMapReader) noexcept;
39
+
40
+ // IViewManagerWithExportedEventTypeConstants
41
+ winrt::Microsoft::ReactNative::ConstantProviderDelegate ExportedCustomBubblingEventTypeConstants() noexcept;
42
+ winrt::Microsoft::ReactNative::ConstantProviderDelegate ExportedCustomDirectEventTypeConstants() noexcept;
43
+
44
+ // IViewManagerWithCommands
45
+ winrt::Windows::Foundation::Collections::IVectorView<winrt::hstring> Commands() noexcept;
46
+
47
+ void DispatchCommand(
48
+ winrt::Windows::UI::Xaml::FrameworkElement const& view,
49
+ winrt::hstring const& commandId,
50
+ winrt::Microsoft::ReactNative::IJSValueReader const& commandArgsReader) noexcept;
51
+
52
+ private:
53
+ winrt::Microsoft::ReactNative::IReactContext m_reactContext{ nullptr };
54
+
55
+ };
56
+ } // namespace winrt::ReactWebView::implementation
57
+
58
+ #endif // USE_WINUI3
@@ -0,0 +1,19 @@
1
+ #include "pch.h"
2
+ #include "WebBridge.h"
3
+ #include "WebBridge.g.cpp"
4
+
5
+ namespace winrt::ReactNativeWebView::implementation
6
+ {
7
+ void WebBridge::PostMessage(hstring const& message)
8
+ {
9
+ m_messageEvent(*this, message);
10
+ }
11
+ winrt::event_token WebBridge::MessagePostEvent(Windows::Foundation::EventHandler<hstring> const& handler)
12
+ {
13
+ return m_messageEvent.add(handler);
14
+ }
15
+ void WebBridge::MessagePostEvent(winrt::event_token const& token) noexcept
16
+ {
17
+ m_messageEvent.remove(token);
18
+ }
19
+ }
@@ -0,0 +1,24 @@
1
+ #pragma once
2
+ #include "WebBridge.g.h"
3
+
4
+
5
+ namespace winrt::ReactNativeWebView::implementation
6
+ {
7
+ struct WebBridge : WebBridgeT<WebBridge>
8
+ {
9
+ WebBridge() = default;
10
+
11
+ void PostMessage(hstring const& message);
12
+ winrt::event_token MessagePostEvent(Windows::Foundation::EventHandler<hstring> const& handler);
13
+ void MessagePostEvent(winrt::event_token const& token) noexcept;
14
+
15
+ private:
16
+ winrt::event<Windows::Foundation::EventHandler<winrt::hstring>> m_messageEvent;
17
+ };
18
+ }
19
+ namespace winrt::ReactNativeWebView::factory_implementation
20
+ {
21
+ struct WebBridge : WebBridgeT<WebBridge, implementation::WebBridge>
22
+ {
23
+ };
24
+ }