react-native-webview-bootpay 13.8.42 → 13.13.4
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.
- package/README.md +53 -69
- package/android/build.gradle +1 -11
- package/android/gradle.properties +0 -42
- package/android/src/main/AndroidManifest.xml +3 -1
- package/android/src/main/AndroidManifestNew.xml +13 -0
- package/android/src/main/java/kr/co/bootpay/webview/BPCWebChromeClient.java +54 -10
- package/android/src/main/java/kr/co/bootpay/webview/BPCWebView.java +101 -68
- package/android/src/main/java/kr/co/bootpay/webview/BPCWebViewClient.java +68 -60
- package/android/src/main/java/kr/co/bootpay/webview/BPCWebViewManagerImpl.kt +119 -65
- package/android/src/main/java/kr/co/bootpay/webview/BPCWebViewMessagingModule.kt +9 -0
- package/android/src/main/java/kr/co/bootpay/webview/BPCWebViewModuleImpl.java +1 -1
- package/android/src/main/java/kr/co/bootpay/webview/BootpayUrlHelper.java +4 -12
- package/android/src/newarch/{com/reactnativecommunity → kr/co/bootpay}/webview/BPCWebViewManager.java +118 -109
- package/android/src/newarch/{com/reactnativecommunity → kr/co/bootpay}/webview/BPCWebViewModule.java +1 -1
- package/android/src/{main/java → oldarch}/kr/co/bootpay/webview/BPCWebViewManager.java +63 -58
- package/android/src/{main/java → oldarch}/kr/co/bootpay/webview/BPCWebViewModule.java +1 -1
- package/apple/BPCWebView.mm +21 -12
- package/apple/BPCWebViewImpl.h +11 -1
- package/apple/BPCWebViewImpl.m +278 -216
- package/apple/BPCWebViewManager.mm +5 -24
- package/apple/BPCWebViewModule.h +23 -0
- package/apple/BPCWebViewModule.mm +34 -0
- package/apple/RCTConvert+WKDataDetectorTypes.h +11 -0
- package/apple/RCTConvert+WKDataDetectorTypes.m +27 -0
- package/ios/RNCWebView.xcodeproj/project.pbxproj +24 -24
- package/ios/RNCWebView.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
- package/ios/RNCWebView.xcodeproj/project.xcworkspace/xcuserdata/taesupyoon.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/ios/RNCWebView.xcodeproj/xcuserdata/taesupyoon.xcuserdatad/xcschemes/xcschememanagement.plist +14 -0
- package/lib/BPCWebViewNativeComponent.d.ts +24 -25
- package/lib/BPCWebViewNativeComponent.js +1 -1
- package/lib/{NativeBPCWebView.d.ts → NativeBPCWebViewModule.d.ts} +2 -5
- package/lib/{NativeBPCWebView.js → NativeBPCWebViewModule.js} +1 -1
- package/lib/WebView.android.d.ts +0 -1
- package/lib/WebView.android.js +1 -1
- package/lib/WebView.d.ts +0 -1
- package/lib/WebView.ios.d.ts +0 -1
- package/lib/WebView.ios.js +1 -1
- package/lib/WebView.js +1 -1
- package/lib/WebView.macos.d.ts +0 -1
- package/lib/WebView.macos.js +1 -1
- package/lib/WebView.styles.d.ts +37 -11
- package/lib/WebView.styles.js +1 -1
- package/lib/WebView.windows.d.ts +0 -1
- package/lib/WebView.windows.js +1 -1
- package/lib/WebViewNativeComponent.macos.d.ts +1 -2
- package/lib/WebViewNativeComponent.windows.d.ts +1 -2
- package/lib/WebViewShared.d.ts +0 -1
- package/lib/WebViewShared.js +1 -1
- package/lib/WebViewTypes.d.ts +51 -3
- package/lib/WebViewTypes.js +1 -1
- package/lib/index.d.ts +0 -1
- package/macos/RNCWebView.xcodeproj/project.pbxproj +36 -36
- package/package.json +13 -12
- package/react-native.config.js +1 -5
- package/src/BPCWebViewNativeComponent.ts +143 -79
- package/src/NativeBPCWebViewModule.ts +13 -0
- package/src/WebView.android.tsx +295 -190
- package/src/WebView.ios.tsx +253 -186
- package/src/WebView.macos.tsx +220 -152
- package/src/WebView.styles.ts +9 -12
- package/src/WebView.tsx +14 -7
- package/src/WebView.windows.tsx +180 -126
- package/src/WebViewNativeComponent.macos.ts +4 -5
- package/src/WebViewNativeComponent.windows.ts +6 -8
- package/src/WebViewShared.tsx +139 -91
- package/src/WebViewTypes.ts +80 -35
- package/src/__tests__/WebViewShared-test.js +170 -55
- package/windows/ReactNativeWebView/ReactNativeWebView.vcxproj +8 -17
- package/windows/ReactNativeWebView/ReactPackageProvider.cpp +5 -1
- package/windows/ReactNativeWebView/ReactWebView.cpp +73 -6
- package/windows/ReactNativeWebView/ReactWebView.h +11 -1
- package/windows/ReactNativeWebView/ReactWebView.idl +12 -3
- package/windows/ReactNativeWebView/ReactWebView2.cpp +294 -129
- package/windows/ReactNativeWebView/ReactWebView2.h +42 -5
- package/windows/ReactNativeWebView/ReactWebView2Manager.cpp +60 -34
- package/windows/ReactNativeWebView/ReactWebView2Manager.h +4 -4
- package/windows/ReactNativeWebView/ReactWebViewHelpers.cpp +70 -0
- package/windows/ReactNativeWebView/ReactWebViewHelpers.h +16 -0
- package/windows/ReactNativeWebView/ReactWebViewManager.cpp +22 -3
- package/windows/ReactNativeWebView/ReactWebViewManager.h +6 -1
- package/windows/ReactNativeWebView/pch.h +11 -7
- package/windows/ReactNativeWebView.sln +14 -14
- package/ios/main.jsbundle +0 -457
- package/lib/BPCWebViewNativeComponent.d.ts.map +0 -1
- package/lib/NativeBPCWebView.d.ts.map +0 -1
- package/lib/WebView.android.d.ts.map +0 -1
- package/lib/WebView.d.ts.map +0 -1
- package/lib/WebView.ios.d.ts.map +0 -1
- package/lib/WebView.macos.d.ts.map +0 -1
- package/lib/WebView.styles.d.ts.map +0 -1
- package/lib/WebView.windows.d.ts.map +0 -1
- package/lib/WebViewNativeComponent.macos.d.ts.map +0 -1
- package/lib/WebViewNativeComponent.windows.d.ts.map +0 -1
- package/lib/WebViewShared.d.ts.map +0 -1
- package/lib/WebViewTypes.d.ts.map +0 -1
- package/lib/index.d.ts.map +0 -1
- package/react-native-webview-bootpay.podspec +0 -46
- package/src/NativeBPCWebView.ts +0 -14
- package/windows/ReactNativeWebView/packages.config +0 -5
- /package/android/src/main/java/kr/co/bootpay/webview/{BPCWebviewWrapper.kt → BPCWebViewWrapper.kt} +0 -0
|
@@ -3,95 +3,38 @@
|
|
|
3
3
|
|
|
4
4
|
#include "pch.h"
|
|
5
5
|
#include "ReactWebView2.h"
|
|
6
|
+
#include "ReactWebViewHelpers.h"
|
|
6
7
|
|
|
7
8
|
#if HAS_WEBVIEW2
|
|
8
9
|
#include "JSValueXaml.h"
|
|
9
10
|
#include "ReactWebView2.g.cpp"
|
|
10
11
|
#include <winrt/Windows.Foundation.Metadata.h>
|
|
12
|
+
#include <winrt/Windows.System.h>
|
|
11
13
|
#include <optional>
|
|
12
|
-
#include <iostream>
|
|
13
|
-
#include <vector>
|
|
14
|
-
#include <algorithm>
|
|
15
|
-
#include <cctype>
|
|
16
14
|
|
|
15
|
+
namespace mux {
|
|
16
|
+
using namespace winrt::Microsoft::UI::Xaml::Controls;
|
|
17
|
+
}
|
|
17
18
|
|
|
18
19
|
namespace winrt {
|
|
19
20
|
using namespace Microsoft::ReactNative;
|
|
20
21
|
using namespace Windows::Foundation;
|
|
21
|
-
using namespace Windows::UI;
|
|
22
|
-
using namespace Windows::UI::Xaml;
|
|
23
|
-
using namespace Windows::UI::Xaml::Controls;
|
|
24
|
-
using namespace Microsoft::UI::Xaml::Controls;
|
|
25
22
|
using namespace Microsoft::Web::WebView2::Core;
|
|
26
23
|
using namespace Windows::Data::Json;
|
|
27
24
|
using namespace Windows::UI::Popups;
|
|
28
|
-
using namespace Windows::
|
|
29
|
-
using namespace Windows::UI::Xaml::Media;
|
|
25
|
+
using namespace Windows::Web::Http;
|
|
30
26
|
using namespace Windows::Storage::Streams;
|
|
27
|
+
using namespace Windows::Security::Cryptography;
|
|
28
|
+
using namespace xaml;
|
|
29
|
+
using namespace xaml::Controls;
|
|
30
|
+
using namespace xaml::Input;
|
|
31
|
+
using namespace xaml::Media;
|
|
31
32
|
} // namespace winrt
|
|
32
33
|
|
|
33
34
|
namespace winrt::ReactNativeWebView::implementation {
|
|
34
|
-
namespace helpers {
|
|
35
|
-
std::string trimString(const std::string& str) {
|
|
36
|
-
std::string trimmedString = str;
|
|
37
|
-
|
|
38
|
-
// Trim from start
|
|
39
|
-
trimmedString.erase(0, trimmedString.find_first_not_of(" \t\n\r\f\v"));
|
|
40
|
-
|
|
41
|
-
// Trim from end
|
|
42
|
-
trimmedString.erase(trimmedString.find_last_not_of(" \t\n\r\f\v") + 1);
|
|
43
|
-
|
|
44
|
-
return trimmedString;
|
|
45
|
-
}
|
|
46
|
-
std::vector<std::string> splitString(
|
|
47
|
-
const std::string& str,
|
|
48
|
-
const std::string& delim) {
|
|
49
|
-
std::vector<std::string> tokens;
|
|
50
|
-
auto startPos = 0;
|
|
51
|
-
auto endPos = str.find(delim);
|
|
52
|
-
|
|
53
|
-
while (endPos != std::string::npos) {
|
|
54
|
-
auto token = str.substr(startPos, endPos - startPos);
|
|
55
|
-
tokens.push_back(trimString(token));
|
|
56
|
-
|
|
57
|
-
startPos = endPos + delim.length();
|
|
58
|
-
endPos = str.find(delim, startPos);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
auto lastToken = str.substr(startPos);
|
|
62
|
-
tokens.push_back(trimString(lastToken));
|
|
63
|
-
|
|
64
|
-
return tokens;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
std::map<std::string, std::string> parseSetCookieHeader(
|
|
68
|
-
const std::string& setCookieHeader) {
|
|
69
|
-
std::map<std::string, std::string> cookie;
|
|
70
|
-
|
|
71
|
-
// Split the header into individual cookie strings
|
|
72
|
-
auto cookieStrings = splitString(setCookieHeader, ";");
|
|
73
|
-
|
|
74
|
-
// Extract the cookie name and value from the first string
|
|
75
|
-
auto nameValuePair = splitString(cookieStrings[0], "=");
|
|
76
|
-
cookie["Name"] = trimString(nameValuePair[0]);
|
|
77
|
-
cookie["Value"] = trimString(nameValuePair[1]);
|
|
78
|
-
|
|
79
|
-
// Extract the attributes from the remaining strings
|
|
80
|
-
for (std::size_t i = 1; i < cookieStrings.size(); ++i) {
|
|
81
|
-
auto attributeValuePair = splitString(cookieStrings[i], "=");
|
|
82
|
-
auto attributeName = attributeValuePair[0];
|
|
83
|
-
auto attributeValue =
|
|
84
|
-
attributeValuePair.size() > 1 ? attributeValuePair[1] : "";
|
|
85
|
-
cookie[attributeName] = trimString(attributeValue);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
return cookie;
|
|
89
|
-
}
|
|
90
|
-
} // namespace HP
|
|
91
|
-
|
|
92
35
|
|
|
93
36
|
ReactWebView2::ReactWebView2(winrt::IReactContext const& reactContext) : m_reactContext(reactContext) {
|
|
94
|
-
m_webView =
|
|
37
|
+
m_webView = mux::WebView2();
|
|
95
38
|
this->Content(m_webView);
|
|
96
39
|
RegisterEvents();
|
|
97
40
|
}
|
|
@@ -101,18 +44,18 @@ namespace winrt::ReactNativeWebView::implementation {
|
|
|
101
44
|
void ReactWebView2::RegisterEvents() {
|
|
102
45
|
m_navigationStartingRevoker = m_webView.NavigationStarting(
|
|
103
46
|
winrt::auto_revoke, [ref = get_weak()](auto const& sender, auto const& args) {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
47
|
+
if (auto self = ref.get()) {
|
|
48
|
+
self->OnNavigationStarting(sender, args);
|
|
49
|
+
}
|
|
107
50
|
|
|
108
|
-
|
|
51
|
+
});
|
|
109
52
|
|
|
110
53
|
m_navigationCompletedRevoker = m_webView.NavigationCompleted(
|
|
111
54
|
winrt::auto_revoke, [ref = get_weak()](auto const& sender, auto const& args) {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
55
|
+
if (auto self = ref.get()) {
|
|
56
|
+
self->OnNavigationCompleted(sender, args);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
116
59
|
|
|
117
60
|
m_CoreWebView2InitializedRevoker = m_webView.CoreWebView2Initialized(
|
|
118
61
|
winrt::auto_revoke, [ref = get_weak()](auto const& sender, auto const& args){
|
|
@@ -122,6 +65,71 @@ namespace winrt::ReactNativeWebView::implementation {
|
|
|
122
65
|
});
|
|
123
66
|
}
|
|
124
67
|
|
|
68
|
+
void ReactWebView2::RegisterCoreWebView2Events()
|
|
69
|
+
{
|
|
70
|
+
// We need to wait for the CoreWebView component to be initialized before registering its event listeners
|
|
71
|
+
assert(m_webView.CoreWebView2());
|
|
72
|
+
m_webResourceRequestedRevoker = m_webView.CoreWebView2().WebResourceRequested(
|
|
73
|
+
winrt::auto_revoke,
|
|
74
|
+
[ref = get_weak()](auto const& sender, auto const& args)
|
|
75
|
+
{
|
|
76
|
+
if (auto self = ref.get())
|
|
77
|
+
{
|
|
78
|
+
self->OnCoreWebView2ResourceRequseted(sender, args);
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
m_CoreWebView2DOMContentLoadedRevoker = m_webView.CoreWebView2().DOMContentLoaded(
|
|
83
|
+
winrt::auto_revoke,
|
|
84
|
+
[ref = get_weak()](auto const& sender, auto const& args)
|
|
85
|
+
{
|
|
86
|
+
if (auto self = ref.get())
|
|
87
|
+
{
|
|
88
|
+
self->OnCoreWebView2DOMContentLoaded(sender, args);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
m_frameNavigationStartingRevoker = m_webView.CoreWebView2().FrameNavigationStarting(
|
|
93
|
+
winrt::auto_revoke,
|
|
94
|
+
[ref = get_weak()](auto const& sender, auto const& args)
|
|
95
|
+
{
|
|
96
|
+
if (auto self = ref.get())
|
|
97
|
+
{
|
|
98
|
+
self->OnCoreWebView2FrameNavigationStarted(sender, args);
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
m_frameNavigationCompletedRevoker = m_webView.CoreWebView2().FrameNavigationCompleted(
|
|
103
|
+
winrt::auto_revoke,
|
|
104
|
+
[ref = get_weak()](auto const& sender, auto const& args)
|
|
105
|
+
{
|
|
106
|
+
if (auto self = ref.get())
|
|
107
|
+
{
|
|
108
|
+
self->OnCoreWebView2FrameNavigationCompleted(sender, args);
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
m_sourceChangedRevoker = m_webView.CoreWebView2().SourceChanged(
|
|
113
|
+
winrt::auto_revoke,
|
|
114
|
+
[ref = get_weak()](auto const& sender, auto const& args)
|
|
115
|
+
{
|
|
116
|
+
if (auto self = ref.get())
|
|
117
|
+
{
|
|
118
|
+
self->OnCoreWebView2SourceChanged(sender, args);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
m_newWindowRequestedRevoker = m_webView.CoreWebView2().NewWindowRequested(
|
|
123
|
+
winrt::auto_revoke,
|
|
124
|
+
[ref = get_weak()](auto const& sender, auto const& args)
|
|
125
|
+
{
|
|
126
|
+
if (auto self = ref.get())
|
|
127
|
+
{
|
|
128
|
+
self->OnCoreWebView2NewWindowRequested(sender, args);
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
|
|
125
133
|
bool ReactWebView2::Is17763OrHigher() {
|
|
126
134
|
static std::optional<bool> hasUniversalAPIContract_v7;
|
|
127
135
|
|
|
@@ -131,7 +139,7 @@ namespace winrt::ReactNativeWebView::implementation {
|
|
|
131
139
|
return hasUniversalAPIContract_v7.value();
|
|
132
140
|
}
|
|
133
141
|
|
|
134
|
-
void ReactWebView2::WriteWebViewNavigationEventArg(
|
|
142
|
+
void ReactWebView2::WriteWebViewNavigationEventArg(mux::WebView2 const& sender, winrt::IJSValueWriter const& eventDataWriter) {
|
|
135
143
|
auto tag = this->GetValue(winrt::FrameworkElement::TagProperty()).as<winrt::IPropertyValue>().GetInt64();
|
|
136
144
|
WriteProperty(eventDataWriter, L"canGoBack", sender.CanGoBack());
|
|
137
145
|
WriteProperty(eventDataWriter, L"canGoForward", sender.CanGoForward());
|
|
@@ -144,7 +152,7 @@ namespace winrt::ReactNativeWebView::implementation {
|
|
|
144
152
|
}
|
|
145
153
|
}
|
|
146
154
|
|
|
147
|
-
void ReactWebView2::OnNavigationStarting(
|
|
155
|
+
void ReactWebView2::OnNavigationStarting(mux::WebView2 const& webView, winrt::CoreWebView2NavigationStartingEventArgs const& /* args */) {
|
|
148
156
|
m_reactContext.DispatchEvent(
|
|
149
157
|
*this,
|
|
150
158
|
L"topLoadingStart",
|
|
@@ -156,7 +164,12 @@ namespace winrt::ReactNativeWebView::implementation {
|
|
|
156
164
|
|
|
157
165
|
|
|
158
166
|
if (m_messagingEnabled) {
|
|
159
|
-
|
|
167
|
+
if (m_messageToken)
|
|
168
|
+
{
|
|
169
|
+
// In case the webview has a new navigation, we need to clean up the old WebMessageReceived handler
|
|
170
|
+
webView.WebMessageReceived(m_messageToken);
|
|
171
|
+
}
|
|
172
|
+
m_messageToken = webView.WebMessageReceived([this](auto const& /* sender */ , winrt::CoreWebView2WebMessageReceivedEventArgs const& messageArgs)
|
|
160
173
|
{
|
|
161
174
|
try {
|
|
162
175
|
auto message = messageArgs.TryGetWebMessageAsString();
|
|
@@ -174,7 +187,7 @@ namespace winrt::ReactNativeWebView::implementation {
|
|
|
174
187
|
HandleMessageFromJS(message);
|
|
175
188
|
}
|
|
176
189
|
|
|
177
|
-
void ReactWebView2::OnNavigationCompleted(
|
|
190
|
+
void ReactWebView2::OnNavigationCompleted(mux::WebView2 const& webView, winrt::CoreWebView2NavigationCompletedEventArgs const& /* args */) {
|
|
178
191
|
m_reactContext.DispatchEvent(
|
|
179
192
|
*this,
|
|
180
193
|
L"topLoadingFinish",
|
|
@@ -186,52 +199,140 @@ namespace winrt::ReactNativeWebView::implementation {
|
|
|
186
199
|
|
|
187
200
|
if (m_messagingEnabled) {
|
|
188
201
|
winrt::hstring message = LR"(window.alert = function (msg) {window.chrome.webview.postMessage(`{"type":"__alert","message":"${msg}"}`)};
|
|
189
|
-
window.ReactNativeWebView = {postMessage: function (data) {window.chrome.webview.postMessage(String(data))}};
|
|
202
|
+
window.ReactNativeWebView = {postMessage: function (data) {window.chrome.webview.postMessage(String(data))}};
|
|
203
|
+
const originalPostMessage = globalThis.postMessage;
|
|
204
|
+
globalThis.postMessage = function (data) { originalPostMessage(data); globalThis.ReactNativeWebView.postMessage(typeof data == 'string' ? data : JSON.stringify(data));};)";
|
|
190
205
|
webView.ExecuteScriptAsync(message);
|
|
191
206
|
}
|
|
192
207
|
}
|
|
193
208
|
|
|
194
|
-
void ReactWebView2::OnCoreWebView2Initialized(
|
|
209
|
+
void ReactWebView2::OnCoreWebView2Initialized(mux::WebView2 const& sender, mux::CoreWebView2InitializedEventArgs const& /* args */) {
|
|
195
210
|
assert(sender.CoreWebView2());
|
|
196
211
|
|
|
212
|
+
RegisterCoreWebView2Events();
|
|
213
|
+
|
|
197
214
|
if (m_navigateToHtml != L"") {
|
|
198
215
|
m_webView.NavigateToString(m_navigateToHtml);
|
|
199
216
|
m_navigateToHtml = L"";
|
|
200
217
|
}
|
|
201
|
-
|
|
202
|
-
|
|
218
|
+
if (!m_request.empty())
|
|
219
|
+
{
|
|
220
|
+
auto uriString = winrt::to_hstring(m_request.at("uri").AsString());
|
|
221
|
+
sender.CoreWebView2().AddWebResourceRequestedFilter(
|
|
222
|
+
uriString, winrt::CoreWebView2WebResourceContext::All);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
203
225
|
|
|
204
|
-
|
|
226
|
+
void ReactWebView2::OnCoreWebView2ResourceRequseted(
|
|
227
|
+
winrt::Microsoft::Web::WebView2::Core::CoreWebView2 const& sender,
|
|
228
|
+
winrt::CoreWebView2WebResourceRequestedEventArgs const& args)
|
|
229
|
+
{
|
|
230
|
+
assert(sender);
|
|
231
|
+
if (!m_request.empty()) {
|
|
232
|
+
auto uriString = winrt::to_hstring(m_request.at("uri").AsString());
|
|
233
|
+
if (args.Request().Uri() == uriString) {
|
|
234
|
+
SetupRequest(m_request, args.Request());
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
205
238
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
239
|
+
void ReactWebView2::OnCoreWebView2DOMContentLoaded(
|
|
240
|
+
winrt::Microsoft::Web::WebView2::Core::CoreWebView2 const& sender,
|
|
241
|
+
winrt::Microsoft::Web::WebView2::Core::CoreWebView2DOMContentLoadedEventArgs const& /* args */)
|
|
242
|
+
{
|
|
243
|
+
m_reactContext.DispatchEvent(
|
|
244
|
+
*this,
|
|
245
|
+
L"topDOMContentLoaded",
|
|
246
|
+
[&](winrt::IJSValueWriter const& eventDataWriter) noexcept
|
|
247
|
+
{
|
|
248
|
+
eventDataWriter.WriteObjectBegin();
|
|
249
|
+
WriteWebViewNavigationEventArg(m_webView, eventDataWriter);
|
|
250
|
+
eventDataWriter.WriteObjectEnd();
|
|
251
|
+
});
|
|
252
|
+
if (!m_injectedJavascript.empty())
|
|
253
|
+
{
|
|
254
|
+
sender.ExecuteScriptAsync(m_injectedJavascript);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
216
257
|
|
|
217
|
-
|
|
258
|
+
void ReactWebView2::OnCoreWebView2FrameNavigationStarted(
|
|
259
|
+
winrt::Microsoft::Web::WebView2::Core::CoreWebView2 const& /* sender */,
|
|
260
|
+
winrt::Microsoft::Web::WebView2::Core::CoreWebView2NavigationStartingEventArgs const& /* args */)
|
|
261
|
+
{
|
|
262
|
+
m_reactContext.DispatchEvent(
|
|
263
|
+
*this,
|
|
264
|
+
L"topFrameNavigationStart",
|
|
265
|
+
[&](winrt::IJSValueWriter const& eventDataWriter) noexcept
|
|
266
|
+
{
|
|
267
|
+
eventDataWriter.WriteObjectBegin();
|
|
268
|
+
WriteWebViewNavigationEventArg(m_webView, eventDataWriter);
|
|
269
|
+
eventDataWriter.WriteObjectEnd();
|
|
270
|
+
});
|
|
271
|
+
}
|
|
218
272
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
273
|
+
void ReactWebView2::OnCoreWebView2FrameNavigationCompleted(
|
|
274
|
+
winrt::Microsoft::Web::WebView2::Core::CoreWebView2 const& /* sender */,
|
|
275
|
+
winrt::Microsoft::Web::WebView2::Core::CoreWebView2NavigationCompletedEventArgs const& /* args */)
|
|
276
|
+
{
|
|
277
|
+
m_reactContext.DispatchEvent(
|
|
278
|
+
*this,
|
|
279
|
+
L"topFrameNavigationFinish",
|
|
280
|
+
[&](winrt::IJSValueWriter const& eventDataWriter) noexcept
|
|
281
|
+
{
|
|
282
|
+
eventDataWriter.WriteObjectBegin();
|
|
283
|
+
WriteWebViewNavigationEventArg(m_webView, eventDataWriter);
|
|
284
|
+
eventDataWriter.WriteObjectEnd();
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
void ReactWebView2::OnCoreWebView2SourceChanged(
|
|
289
|
+
winrt::Microsoft::Web::WebView2::Core::CoreWebView2 const& /* sender */,
|
|
290
|
+
winrt::Microsoft::Web::WebView2::Core::CoreWebView2SourceChangedEventArgs const& /* args */)
|
|
291
|
+
{
|
|
292
|
+
m_reactContext.DispatchEvent(
|
|
293
|
+
*this,
|
|
294
|
+
L"topSourceChanged",
|
|
295
|
+
[&](winrt::IJSValueWriter const& eventDataWriter) noexcept
|
|
296
|
+
{
|
|
297
|
+
eventDataWriter.WriteObjectBegin();
|
|
298
|
+
WriteWebViewNavigationEventArg(m_webView, eventDataWriter);
|
|
299
|
+
eventDataWriter.WriteObjectEnd();
|
|
300
|
+
});
|
|
301
|
+
}
|
|
226
302
|
|
|
227
|
-
|
|
228
|
-
|
|
303
|
+
void ReactWebView2::OnCoreWebView2NewWindowRequested(
|
|
304
|
+
winrt::Microsoft::Web::WebView2::Core::CoreWebView2 const& sender,
|
|
305
|
+
winrt::Microsoft::Web::WebView2::Core::CoreWebView2NewWindowRequestedEventArgs const& args)
|
|
306
|
+
{
|
|
307
|
+
if (m_linkHandlingEnabled) {
|
|
308
|
+
m_reactContext.DispatchEvent(
|
|
309
|
+
*this,
|
|
310
|
+
L"topOpenWindow",
|
|
311
|
+
[&](winrt::IJSValueWriter const& eventDataWriter) noexcept
|
|
312
|
+
{
|
|
313
|
+
eventDataWriter.WriteObjectBegin();
|
|
314
|
+
WriteProperty(eventDataWriter, L"targetUrl", args.Uri());
|
|
315
|
+
eventDataWriter.WriteObjectEnd();
|
|
316
|
+
});
|
|
317
|
+
args.Handled(true);
|
|
318
|
+
} else {
|
|
319
|
+
try
|
|
320
|
+
{
|
|
321
|
+
winrt::Windows::Foundation::Uri uri(args.Uri());
|
|
322
|
+
winrt::Windows::System::Launcher::LaunchUriAsync(uri);
|
|
323
|
+
args.Handled(true);
|
|
324
|
+
}
|
|
325
|
+
catch (winrt::hresult_error& e)
|
|
326
|
+
{
|
|
327
|
+
// Do Nothing
|
|
328
|
+
}
|
|
229
329
|
}
|
|
230
330
|
}
|
|
231
331
|
|
|
232
332
|
void ReactWebView2::HandleMessageFromJS(winrt::hstring const& message) {
|
|
233
333
|
winrt::JsonObject jsonObject;
|
|
234
|
-
if (winrt::JsonObject::TryParse(message, jsonObject))
|
|
334
|
+
if (winrt::JsonObject::TryParse(message, jsonObject) && jsonObject.HasKey(L"type"))
|
|
335
|
+
{
|
|
235
336
|
if (auto v = jsonObject.Lookup(L"type"); v && v.ValueType() == JsonValueType::String) {
|
|
236
337
|
auto type = v.GetString();
|
|
237
338
|
if (type == L"__alert") {
|
|
@@ -248,23 +349,47 @@ namespace winrt::ReactNativeWebView::implementation {
|
|
|
248
349
|
L"topMessage",
|
|
249
350
|
[&](winrt::Microsoft::ReactNative::IJSValueWriter const& eventDataWriter) noexcept {
|
|
250
351
|
eventDataWriter.WriteObjectBegin();
|
|
251
|
-
|
|
252
|
-
WriteProperty(eventDataWriter, L"data", message);
|
|
253
|
-
}
|
|
352
|
+
WriteProperty(eventDataWriter, L"data", message);
|
|
254
353
|
eventDataWriter.WriteObjectEnd();
|
|
255
354
|
});
|
|
256
355
|
}
|
|
257
356
|
|
|
258
|
-
void ReactWebView2::MessagingEnabled(bool enabled) noexcept
|
|
357
|
+
void ReactWebView2::MessagingEnabled(bool enabled) noexcept{
|
|
259
358
|
m_messagingEnabled = enabled;
|
|
260
359
|
}
|
|
261
360
|
|
|
262
|
-
bool ReactWebView2::MessagingEnabled() const noexcept
|
|
361
|
+
bool ReactWebView2::MessagingEnabled() const noexcept{
|
|
263
362
|
return m_messagingEnabled;
|
|
264
363
|
}
|
|
265
364
|
|
|
365
|
+
void ReactWebView2::LinkHandlingEnabled(bool enabled) noexcept {
|
|
366
|
+
m_linkHandlingEnabled = enabled;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
bool ReactWebView2::LinkHandlingEnabled() const noexcept {
|
|
370
|
+
return m_linkHandlingEnabled;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
void ReactWebView2::WebResourceRequestSource(Microsoft::ReactNative::JSValueObject const& source) noexcept
|
|
374
|
+
{
|
|
375
|
+
m_request = std::move(source.Copy());
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
JSValueObject ReactWebView2::WebResourceRequestSource() const noexcept
|
|
379
|
+
{
|
|
380
|
+
return m_request.Copy();
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
void ReactWebView2::InjectedJavascript(winrt::hstring const& injectedJavascript) noexcept {
|
|
384
|
+
m_injectedJavascript = injectedJavascript;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
winrt::hstring ReactWebView2::InjectedJavascript() const noexcept
|
|
388
|
+
{
|
|
389
|
+
return m_injectedJavascript;
|
|
390
|
+
}
|
|
266
391
|
|
|
267
|
-
void ReactWebView2::NavigateToHtml(winrt::hstring html) {
|
|
392
|
+
void ReactWebView2::NavigateToHtml(winrt::hstring const& html) {
|
|
268
393
|
if (m_webView.CoreWebView2()) {
|
|
269
394
|
m_webView.NavigateToString(html);
|
|
270
395
|
}
|
|
@@ -274,33 +399,73 @@ namespace winrt::ReactNativeWebView::implementation {
|
|
|
274
399
|
}
|
|
275
400
|
}
|
|
276
401
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
402
|
+
winrt::fire_and_forget ReactWebView2::NavigateWithWebResourceRequest(Microsoft::ReactNative::IJSValueReader const& source)
|
|
403
|
+
{
|
|
404
|
+
m_request = JSValueObject::ReadFrom(source);
|
|
405
|
+
co_await m_webView.EnsureCoreWebView2Async();
|
|
406
|
+
assert(m_webView.CoreWebView2());
|
|
407
|
+
if (m_webView.CoreWebView2())
|
|
408
|
+
{
|
|
409
|
+
auto uri = winrt::Uri(winrt::to_hstring(m_request.at("uri").AsString()));
|
|
410
|
+
auto method = (m_request.find("method") != m_request.end()) ? m_request.at("method").AsString() : "GET";
|
|
411
|
+
auto webResourceRequest = m_webView.CoreWebView2().Environment().CreateWebResourceRequest(
|
|
412
|
+
uri.ToString(), winrt::to_hstring(method), nullptr, L"");
|
|
413
|
+
|
|
414
|
+
SetupRequest(m_request.Copy(), webResourceRequest);
|
|
415
|
+
|
|
416
|
+
m_webView.CoreWebView2().NavigateWithWebResourceRequest(webResourceRequest);
|
|
417
|
+
}
|
|
280
418
|
}
|
|
281
419
|
|
|
282
|
-
void ReactWebView2::WriteCookiesToWebView2(
|
|
420
|
+
void ReactWebView2::WriteCookiesToWebView2(std::string const& cookies) {
|
|
283
421
|
// Persisting cookies passed from JS
|
|
284
422
|
// Cookies are separated by ;, and adheres to the Set-Cookie HTTP header format of RFC-6265.
|
|
285
423
|
|
|
286
|
-
auto
|
|
287
|
-
auto
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
auto cookieData = helpers::parseSetCookieHeader(helpers::trimString(cookie_str));
|
|
424
|
+
auto cookieManager = m_webView.CoreWebView2().CookieManager();
|
|
425
|
+
auto cookiesList = ReactWebViewHelpers::SplitString(cookies, ";,");
|
|
426
|
+
for (const auto& cookie_str : cookiesList) {
|
|
427
|
+
auto cookieData = ReactWebViewHelpers::ParseSetCookieHeader(ReactWebViewHelpers::TrimString(cookie_str));
|
|
291
428
|
|
|
292
429
|
if (!cookieData.count("Name") || !cookieData.count("Value")) {
|
|
293
430
|
continue;
|
|
294
431
|
}
|
|
295
|
-
|
|
432
|
+
|
|
433
|
+
auto cookie = cookieManager.CreateCookie(
|
|
296
434
|
winrt::to_hstring(cookieData["Name"]),
|
|
297
435
|
winrt::to_hstring(cookieData["Value"]),
|
|
298
|
-
cookieData.count("Domain")
|
|
299
|
-
? winrt::to_hstring(cookieData["
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
436
|
+
cookieData.count("Domain") ? winrt::to_hstring(cookieData["Domain"]) : L"",
|
|
437
|
+
cookieData.count("Path") ? winrt::to_hstring(cookieData["Path"]) : L"");
|
|
438
|
+
cookieManager.AddOrUpdateCookie(cookie);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
void ReactWebView2::SetupRequest(Microsoft::ReactNative::JSValueObject const& srcMap, winrt::Microsoft::Web::WebView2::Core::CoreWebView2WebResourceRequest const& request) {
|
|
443
|
+
bool hasHeaders = srcMap.find("headers") != srcMap.end();
|
|
444
|
+
auto method = srcMap.find("method") != srcMap.end() ? srcMap.at("method").AsString() : "GET";
|
|
445
|
+
request.Method(winrt::to_hstring(method));
|
|
446
|
+
if (method == "POST")
|
|
447
|
+
{
|
|
448
|
+
auto formBody = srcMap.at("body").AsString();
|
|
449
|
+
winrt::InMemoryRandomAccessStream formContent;
|
|
450
|
+
winrt::IBuffer buffer{winrt::CryptographicBuffer::ConvertStringToBinary(
|
|
451
|
+
winrt::to_hstring(formBody), winrt::BinaryStringEncoding::Utf8)};
|
|
452
|
+
formContent.ReadAsync(buffer, buffer.Length(), InputStreamOptions::None);
|
|
453
|
+
request.Content(formContent);
|
|
454
|
+
}
|
|
455
|
+
if (hasHeaders)
|
|
456
|
+
{
|
|
457
|
+
for (auto const& header : srcMap.at("headers").AsObject())
|
|
458
|
+
{
|
|
459
|
+
auto const& headerKey = header.first;
|
|
460
|
+
auto const& headerValue = header.second;
|
|
461
|
+
if (headerValue.IsNull())
|
|
462
|
+
continue;
|
|
463
|
+
if (headerKey == "Cookie") {
|
|
464
|
+
WriteCookiesToWebView2(headerValue.AsString());
|
|
465
|
+
} else {
|
|
466
|
+
request.Headers().SetHeader(winrt::to_hstring(headerKey), winrt::to_hstring(headerValue.AsString()));
|
|
467
|
+
}
|
|
468
|
+
}
|
|
304
469
|
}
|
|
305
470
|
}
|
|
306
471
|
} // namespace winrt::ReactNativeWebView::implementation
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
#pragma once
|
|
5
5
|
|
|
6
6
|
#if HAS_WEBVIEW2
|
|
7
|
-
|
|
8
7
|
#include "winrt/Microsoft.ReactNative.h"
|
|
9
8
|
#include "NativeModules.h"
|
|
10
9
|
#include "ReactWebView2.g.h"
|
|
@@ -20,14 +19,23 @@ namespace winrt::ReactNativeWebView::implementation {
|
|
|
20
19
|
ReactWebView2(Microsoft::ReactNative::IReactContext const& reactContext);
|
|
21
20
|
void MessagingEnabled(bool enabled) noexcept;
|
|
22
21
|
bool MessagingEnabled() const noexcept;
|
|
23
|
-
void
|
|
24
|
-
|
|
22
|
+
void LinkHandlingEnabled(bool enabled) noexcept;
|
|
23
|
+
bool LinkHandlingEnabled() const noexcept;
|
|
24
|
+
void WebResourceRequestSource(Microsoft::ReactNative::JSValueObject const& source) noexcept;
|
|
25
|
+
Microsoft::ReactNative::JSValueObject WebResourceRequestSource() const noexcept;
|
|
26
|
+
void InjectedJavascript(winrt::hstring const& injectedJavascript) noexcept;
|
|
27
|
+
winrt::hstring InjectedJavascript() const noexcept;
|
|
28
|
+
void NavigateToHtml(winrt::hstring const& html);
|
|
29
|
+
winrt::fire_and_forget NavigateWithWebResourceRequest(Microsoft::ReactNative::IJSValueReader const& source);
|
|
25
30
|
~ReactWebView2();
|
|
26
31
|
|
|
27
32
|
private:
|
|
28
33
|
winrt::hstring m_navigateToHtml = L"";
|
|
29
|
-
|
|
34
|
+
winrt::Microsoft::ReactNative::JSValueObject m_request{};
|
|
30
35
|
bool m_messagingEnabled{ true };
|
|
36
|
+
bool m_linkHandlingEnabled{ true };
|
|
37
|
+
winrt::hstring m_injectedJavascript = L"";
|
|
38
|
+
|
|
31
39
|
|
|
32
40
|
winrt::Microsoft::UI::Xaml::Controls::WebView2 m_webView{ nullptr };
|
|
33
41
|
Microsoft::ReactNative::IReactContext m_reactContext{ nullptr };
|
|
@@ -35,15 +43,44 @@ namespace winrt::ReactNativeWebView::implementation {
|
|
|
35
43
|
winrt::Microsoft::UI::Xaml::Controls::WebView2::NavigationStarting_revoker m_navigationStartingRevoker{};
|
|
36
44
|
winrt::Microsoft::UI::Xaml::Controls::WebView2::NavigationCompleted_revoker m_navigationCompletedRevoker{};
|
|
37
45
|
winrt::Microsoft::UI::Xaml::Controls::WebView2::CoreWebView2Initialized_revoker m_CoreWebView2InitializedRevoker{};
|
|
46
|
+
winrt::Microsoft::Web::WebView2::Core::CoreWebView2::WebResourceRequested_revoker
|
|
47
|
+
m_webResourceRequestedRevoker{};
|
|
48
|
+
winrt::Microsoft::Web::WebView2::Core::CoreWebView2::DOMContentLoaded_revoker
|
|
49
|
+
m_CoreWebView2DOMContentLoadedRevoker{};
|
|
50
|
+
winrt::Microsoft::Web::WebView2::Core::CoreWebView2::FrameNavigationStarting_revoker m_frameNavigationStartingRevoker{};
|
|
51
|
+
winrt::Microsoft::Web::WebView2::Core::CoreWebView2::FrameNavigationCompleted_revoker m_frameNavigationCompletedRevoker{};
|
|
52
|
+
winrt::Microsoft::Web::WebView2::Core::CoreWebView2::SourceChanged_revoker m_sourceChangedRevoker{};
|
|
53
|
+
winrt::Microsoft::Web::WebView2::Core::CoreWebView2::NewWindowRequested_revoker m_newWindowRequestedRevoker{};
|
|
38
54
|
void HandleMessageFromJS(winrt::hstring const& message);
|
|
39
55
|
void RegisterEvents();
|
|
40
|
-
void
|
|
56
|
+
void RegisterCoreWebView2Events();
|
|
41
57
|
void WriteWebViewNavigationEventArg(winrt::Microsoft::UI::Xaml::Controls::WebView2 const& sender, winrt::Microsoft::ReactNative::IJSValueWriter const& eventDataWriter);
|
|
42
58
|
void OnNavigationStarting(winrt::Microsoft::UI::Xaml::Controls::WebView2 const& sender, winrt::Microsoft::Web::WebView2::Core::CoreWebView2NavigationStartingEventArgs const& args);
|
|
43
59
|
void OnNavigationCompleted(winrt::Microsoft::UI::Xaml::Controls::WebView2 const& sender, winrt::Microsoft::Web::WebView2::Core::CoreWebView2NavigationCompletedEventArgs const& args);
|
|
44
60
|
void OnCoreWebView2Initialized(winrt::Microsoft::UI::Xaml::Controls::WebView2 const& sender, winrt::Microsoft::UI::Xaml::Controls::CoreWebView2InitializedEventArgs const& args);
|
|
61
|
+
void OnCoreWebView2ResourceRequseted(
|
|
62
|
+
winrt::Microsoft::Web::WebView2::Core::CoreWebView2 const& sender,
|
|
63
|
+
winrt::Microsoft::Web::WebView2::Core::CoreWebView2WebResourceRequestedEventArgs const& args);
|
|
64
|
+
void OnCoreWebView2DOMContentLoaded(
|
|
65
|
+
winrt::Microsoft::Web::WebView2::Core::CoreWebView2 const& sender,
|
|
66
|
+
winrt::Microsoft::Web::WebView2::Core::CoreWebView2DOMContentLoadedEventArgs const& args);
|
|
67
|
+
void OnCoreWebView2FrameNavigationStarted(
|
|
68
|
+
winrt::Microsoft::Web::WebView2::Core::CoreWebView2 const& sender,
|
|
69
|
+
winrt::Microsoft::Web::WebView2::Core::CoreWebView2NavigationStartingEventArgs const& args);
|
|
70
|
+
void OnCoreWebView2FrameNavigationCompleted(
|
|
71
|
+
winrt::Microsoft::Web::WebView2::Core::CoreWebView2 const& sender,
|
|
72
|
+
winrt::Microsoft::Web::WebView2::Core::CoreWebView2NavigationCompletedEventArgs const& args);
|
|
73
|
+
void OnCoreWebView2SourceChanged(
|
|
74
|
+
winrt::Microsoft::Web::WebView2::Core::CoreWebView2 const& sender,
|
|
75
|
+
winrt::Microsoft::Web::WebView2::Core::CoreWebView2SourceChangedEventArgs const& args);
|
|
76
|
+
void OnCoreWebView2NewWindowRequested(
|
|
77
|
+
winrt::Microsoft::Web::WebView2::Core::CoreWebView2 const& sender,
|
|
78
|
+
winrt::Microsoft::Web::WebView2::Core::CoreWebView2NewWindowRequestedEventArgs const& args);
|
|
79
|
+
|
|
45
80
|
void OnMessagePosted(hstring const& message);
|
|
46
81
|
bool Is17763OrHigher();
|
|
82
|
+
void WriteCookiesToWebView2(std::string const& cookies);
|
|
83
|
+
void SetupRequest(Microsoft::ReactNative::JSValueObject const& srcMap, winrt::Microsoft::Web::WebView2::Core::CoreWebView2WebResourceRequest const& request);
|
|
47
84
|
};
|
|
48
85
|
} // namespace winrt::ReactNativeWebView2::implementation
|
|
49
86
|
|