@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.
- package/LICENSE +21 -0
- package/README.md +82 -0
- package/android/build.gradle +110 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +15 -0
- package/android/src/main/AndroidManifestNew.xml +13 -0
- package/android/src/main/java/com/reactnativecommunity/webview/RNCBasicAuthCredential.java +11 -0
- package/android/src/main/java/com/reactnativecommunity/webview/RNCWebChromeClient.java +372 -0
- package/android/src/main/java/com/reactnativecommunity/webview/RNCWebView.java +450 -0
- package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewClient.java +328 -0
- package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewConfig.java +11 -0
- package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewFileProvider.java +14 -0
- package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManagerImpl.kt +720 -0
- package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewMessagingModule.kt +19 -0
- package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewModuleImpl.java +554 -0
- package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewPackage.java +56 -0
- package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewWrapper.kt +39 -0
- package/android/src/main/java/com/reactnativecommunity/webview/URLUtil.java +179 -0
- package/android/src/main/java/com/reactnativecommunity/webview/events/TopCustomMenuSelectionEvent.kt +24 -0
- package/android/src/main/java/com/reactnativecommunity/webview/events/TopHttpErrorEvent.kt +25 -0
- package/android/src/main/java/com/reactnativecommunity/webview/events/TopLoadingErrorEvent.kt +25 -0
- package/android/src/main/java/com/reactnativecommunity/webview/events/TopLoadingFinishEvent.kt +24 -0
- package/android/src/main/java/com/reactnativecommunity/webview/events/TopLoadingProgressEvent.kt +24 -0
- package/android/src/main/java/com/reactnativecommunity/webview/events/TopLoadingStartEvent.kt +25 -0
- package/android/src/main/java/com/reactnativecommunity/webview/events/TopMessageEvent.kt +24 -0
- package/android/src/main/java/com/reactnativecommunity/webview/events/TopNewWindowEvent.kt +25 -0
- package/android/src/main/java/com/reactnativecommunity/webview/events/TopRenderProcessGoneEvent.kt +26 -0
- package/android/src/main/java/com/reactnativecommunity/webview/events/TopShouldStartLoadWithRequestEvent.kt +29 -0
- package/android/src/main/res/xml/file_provider_paths.xml +6 -0
- package/android/src/newarch/com/reactnativecommunity/webview/RNCWebViewManager.java +553 -0
- package/android/src/newarch/com/reactnativecommunity/webview/RNCWebViewModule.java +63 -0
- package/android/src/oldarch/com/reactnativecommunity/webview/RNCWebViewManager.java +328 -0
- package/android/src/oldarch/com/reactnativecommunity/webview/RNCWebViewModule.java +59 -0
- package/apple/RCTConvert+WKDataDetectorTypes.h +11 -0
- package/apple/RCTConvert+WKDataDetectorTypes.m +27 -0
- package/apple/RNCWKProcessPoolManager.h +15 -0
- package/apple/RNCWKProcessPoolManager.m +36 -0
- package/apple/RNCWebView.h +35 -0
- package/apple/RNCWebView.mm +546 -0
- package/apple/RNCWebViewDecisionManager.h +20 -0
- package/apple/RNCWebViewDecisionManager.m +47 -0
- package/apple/RNCWebViewImpl.h +161 -0
- package/apple/RNCWebViewImpl.m +1979 -0
- package/apple/RNCWebViewManager.h +9 -0
- package/apple/RNCWebViewManager.mm +215 -0
- package/apple/RNCWebViewModule.h +23 -0
- package/apple/RNCWebViewModule.mm +34 -0
- package/index.d.ts +65 -0
- package/index.js +4 -0
- package/ios/RNCWebView.xcodeproj/project.pbxproj +273 -0
- package/lib/NativeRNCWebViewModule.d.ts +10 -0
- package/lib/NativeRNCWebViewModule.js +1 -0
- package/lib/RNCWebViewNativeComponent.d.ts +242 -0
- package/lib/RNCWebViewNativeComponent.js +1 -0
- package/lib/WebView.android.d.ts +6 -0
- package/lib/WebView.android.js +1 -0
- package/lib/WebView.d.ts +6 -0
- package/lib/WebView.ios.d.ts +6 -0
- package/lib/WebView.ios.js +1 -0
- package/lib/WebView.js +1 -0
- package/lib/WebView.macos.d.ts +6 -0
- package/lib/WebView.macos.js +1 -0
- package/lib/WebView.styles.d.ts +38 -0
- package/lib/WebView.styles.js +1 -0
- package/lib/WebView.windows.d.ts +17 -0
- package/lib/WebView.windows.js +1 -0
- package/lib/WebViewNativeComponent.macos.d.ts +3 -0
- package/lib/WebViewNativeComponent.macos.js +1 -0
- package/lib/WebViewNativeComponent.windows.d.ts +3 -0
- package/lib/WebViewNativeComponent.windows.js +1 -0
- package/lib/WebViewShared.d.ts +38 -0
- package/lib/WebViewShared.js +1 -0
- package/lib/WebViewTypes.d.ts +1093 -0
- package/lib/WebViewTypes.js +1 -0
- package/lib/index.d.ts +3 -0
- package/lib/index.js +1 -0
- package/macos/RNCWebView.xcodeproj/project.pbxproj +363 -0
- package/package.json +101 -0
- package/react-native-webview.podspec +46 -0
- package/react-native.config.js +44 -0
- package/src/NativeRNCWebViewModule.ts +15 -0
- package/src/RNCWebViewNativeComponent.ts +342 -0
- package/src/WebView.android.tsx +317 -0
- package/src/WebView.ios.tsx +299 -0
- package/src/WebView.macos.tsx +245 -0
- package/src/WebView.styles.ts +41 -0
- package/src/WebView.tsx +25 -0
- package/src/WebView.windows.tsx +210 -0
- package/src/WebViewNativeComponent.macos.ts +7 -0
- package/src/WebViewNativeComponent.windows.ts +8 -0
- package/src/WebViewShared.tsx +283 -0
- package/src/WebViewTypes.ts +1332 -0
- package/src/__tests__/WebViewShared-test.js +323 -0
- package/src/__tests__/__snapshots__/WebViewShared-test.js.snap +8 -0
- package/src/index.ts +4 -0
- package/windows/ExperimentalFeatures.props +11 -0
- package/windows/ReactNativeWebView/PropertySheet.props +16 -0
- package/windows/ReactNativeWebView/ReactNativeWebView.def +3 -0
- package/windows/ReactNativeWebView/ReactNativeWebView.filters +33 -0
- package/windows/ReactNativeWebView/ReactNativeWebView.vcxproj +189 -0
- package/windows/ReactNativeWebView/ReactPackageProvider.cpp +26 -0
- package/windows/ReactNativeWebView/ReactPackageProvider.h +20 -0
- package/windows/ReactNativeWebView/ReactPackageProvider.idl +7 -0
- package/windows/ReactNativeWebView/ReactWebView.cpp +242 -0
- package/windows/ReactNativeWebView/ReactWebView.h +56 -0
- package/windows/ReactNativeWebView/ReactWebView.idl +31 -0
- package/windows/ReactNativeWebView/ReactWebView2.cpp +473 -0
- package/windows/ReactNativeWebView/ReactWebView2.h +91 -0
- package/windows/ReactNativeWebView/ReactWebView2Manager.cpp +205 -0
- package/windows/ReactNativeWebView/ReactWebView2Manager.h +57 -0
- package/windows/ReactNativeWebView/ReactWebViewHelpers.cpp +70 -0
- package/windows/ReactNativeWebView/ReactWebViewHelpers.h +16 -0
- package/windows/ReactNativeWebView/ReactWebViewManager.cpp +224 -0
- package/windows/ReactNativeWebView/ReactWebViewManager.h +58 -0
- package/windows/ReactNativeWebView/WebBridge.cpp +19 -0
- package/windows/ReactNativeWebView/WebBridge.h +24 -0
- package/windows/ReactNativeWebView/WebBridge.idl +11 -0
- package/windows/ReactNativeWebView/pch.cpp +1 -0
- package/windows/ReactNativeWebView/pch.h +37 -0
- 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
|
+
}
|