|
@@ -1,168 +1,173 @@
|
1
|
|
-#include "pch.h"
|
2
|
|
-#include "ReactWebViewManager.h"
|
3
|
|
-#include "NativeModules.h"
|
4
|
|
-
|
5
|
|
-namespace winrt {
|
6
|
|
- using namespace Microsoft::ReactNative;
|
7
|
|
- using namespace Windows::Foundation;
|
8
|
|
- using namespace Windows::Foundation::Collections;
|
9
|
|
- using namespace Windows::UI::Xaml;
|
10
|
|
- using namespace Windows::UI::Xaml::Controls;
|
11
|
|
-}
|
12
|
|
-
|
13
|
|
-namespace winrt::ReactNativeWebView::implementation {
|
14
|
|
-
|
15
|
|
- ReactWebViewManager::ReactWebViewManager() {}
|
16
|
|
-
|
17
|
|
- // IViewManager
|
18
|
|
- winrt::hstring ReactWebViewManager::Name() noexcept {
|
19
|
|
- return L"RCTWebView";
|
20
|
|
- }
|
21
|
|
-
|
22
|
|
- winrt::FrameworkElement ReactWebViewManager::CreateView() noexcept {
|
23
|
|
- auto webView = winrt::WebView();
|
24
|
|
- m_webView = winrt::make_weak(webView);
|
25
|
|
- RegisterEvents();
|
26
|
|
- return webView;
|
27
|
|
- }
|
28
|
|
-
|
29
|
|
- void ReactWebViewManager::RegisterEvents() {
|
30
|
|
- if (auto webView = m_webView.get()) {
|
31
|
|
- m_navigationCompletedRevoker = webView.NavigationCompleted(
|
32
|
|
- winrt::auto_revoke, [=](auto const& sender, auto const& args) {
|
33
|
|
- OnNavigationCompleted(sender, args);
|
34
|
|
- });
|
35
|
|
- }
|
36
|
|
- }
|
37
|
|
-
|
38
|
|
- // IViewManagerWithReactContext
|
39
|
|
- winrt::IReactContext ReactWebViewManager::ReactContext() noexcept {
|
40
|
|
- return m_reactContext;
|
41
|
|
- }
|
42
|
|
-
|
43
|
|
- void ReactWebViewManager::ReactContext(IReactContext reactContext) noexcept {
|
44
|
|
- m_reactContext = reactContext;
|
45
|
|
- }
|
46
|
|
-
|
47
|
|
- // IViewManagerWithNativeProperties
|
48
|
|
- IMapView<hstring, ViewManagerPropertyType> ReactWebViewManager::NativeProps() noexcept {
|
49
|
|
- auto nativeProps = winrt::single_threaded_map<hstring, ViewManagerPropertyType>();
|
50
|
|
- nativeProps.Insert(L"source", ViewManagerPropertyType::Map);
|
51
|
|
- return nativeProps.GetView();
|
52
|
|
- }
|
53
|
|
-
|
54
|
|
- void ReactWebViewManager::UpdateProperties(
|
55
|
|
- FrameworkElement const& view,
|
56
|
|
- IJSValueReader const& propertyMapReader) noexcept {
|
57
|
|
- if (auto webView = view.try_as<winrt::WebView>()) {
|
58
|
|
- const JSValueObject& propertyMap = JSValue::ReadObjectFrom(propertyMapReader);
|
59
|
|
-
|
60
|
|
- for (auto const& pair : propertyMap) {
|
61
|
|
- auto const& propertyName = pair.first;
|
62
|
|
- auto const& propertyValue = pair.second;
|
63
|
|
-
|
64
|
|
- if (propertyName == "source") {
|
65
|
|
- if (!propertyValue.IsNull()) {
|
66
|
|
- auto const& srcMap = propertyValue.Object();
|
67
|
|
-
|
68
|
|
- auto uriString = srcMap.at("uri").String();
|
69
|
|
- // non-uri sources not yet supported
|
70
|
|
- if (uriString.length() == 0) {
|
71
|
|
- continue;
|
72
|
|
- }
|
73
|
|
-
|
74
|
|
- bool isPackagerAsset = false;
|
75
|
|
- if (srcMap.find("__packager_asset") != srcMap.end()) {
|
76
|
|
- isPackagerAsset = srcMap.at("__packager_asset").Boolean();
|
77
|
|
- }
|
78
|
|
-
|
79
|
|
- if (isPackagerAsset && uriString.find("assets") == 0) {
|
80
|
|
- uriString.replace(0, 6, "ms-appx://");
|
81
|
|
- }
|
82
|
|
-
|
83
|
|
- SetSource(winrt::Uri(to_hstring(uriString)));
|
84
|
|
- }
|
85
|
|
- }
|
86
|
|
- }
|
87
|
|
- }
|
88
|
|
- }
|
89
|
|
-
|
90
|
|
- void ReactWebViewManager::SetSource(winrt::Uri const& uri) {
|
91
|
|
- if (auto webView = m_webView.get()) {
|
92
|
|
- auto tag = webView.GetValue(winrt::FrameworkElement::TagProperty()).as<winrt::IPropertyValue>().GetInt64();
|
93
|
|
- m_reactContext.DispatchEvent(
|
94
|
|
- webView,
|
95
|
|
- L"topLoadingStart",
|
96
|
|
- [tag](winrt::IJSValueWriter const& eventDataWriter) noexcept {
|
97
|
|
- eventDataWriter.WriteObjectBegin();
|
98
|
|
- {
|
99
|
|
- WriteProperty(eventDataWriter, L"target", tag);
|
100
|
|
- }
|
101
|
|
- eventDataWriter.WriteObjectEnd();
|
102
|
|
- });
|
103
|
|
-
|
104
|
|
- webView.Navigate(uri);
|
105
|
|
- }
|
106
|
|
- }
|
107
|
|
-
|
108
|
|
- // IViewManagerWithExportedEventTypeConstants
|
109
|
|
- ConstantProvider ReactWebViewManager::ExportedCustomBubblingEventTypeConstants() noexcept {
|
110
|
|
- return nullptr;
|
111
|
|
- }
|
112
|
|
-
|
113
|
|
- ConstantProvider ReactWebViewManager::ExportedCustomDirectEventTypeConstants() noexcept {
|
114
|
|
- return [](winrt::Microsoft::ReactNative::IJSValueWriter const& constantWriter) {
|
115
|
|
- WriteCustomDirectEventTypeConstant(constantWriter, "onLoadingStart");
|
116
|
|
- WriteCustomDirectEventTypeConstant(constantWriter, "onLoad");
|
117
|
|
- WriteCustomDirectEventTypeConstant(constantWriter, "onLoadingFinish");
|
118
|
|
- };
|
119
|
|
- }
|
120
|
|
-
|
121
|
|
- // IViewManagerWithCommands
|
122
|
|
- IMapView<hstring, int64_t> ReactWebViewManager::Commands() noexcept {
|
123
|
|
- auto commands = winrt::single_threaded_map<hstring, int64_t>();
|
124
|
|
- commands.Insert(L"goForward", 0);
|
125
|
|
- commands.Insert(L"goBack", 1);
|
126
|
|
- commands.Insert(L"reload", 2);
|
127
|
|
- return commands.GetView();
|
128
|
|
- }
|
129
|
|
-
|
130
|
|
- void ReactWebViewManager::DispatchCommand(
|
131
|
|
- FrameworkElement const& view,
|
132
|
|
- int64_t commandId,
|
133
|
|
- winrt::Microsoft::ReactNative::IJSValueReader const& commandArgsReader) noexcept {
|
134
|
|
- if (auto webView = view.try_as<winrt::WebView>()) {
|
135
|
|
- switch (commandId) {
|
136
|
|
- case 0: // goForward
|
137
|
|
- webView.GoForward();
|
138
|
|
- break;
|
139
|
|
- case 1: // goBack
|
140
|
|
- webView.GoBack();
|
141
|
|
- break;
|
142
|
|
- case 2: // reload
|
143
|
|
- webView.Refresh();
|
144
|
|
- break;
|
145
|
|
- }
|
146
|
|
- }
|
147
|
|
- }
|
148
|
|
-
|
149
|
|
- void ReactWebViewManager::OnNavigationCompleted(winrt::WebView const& webView, winrt::WebViewNavigationCompletedEventArgs const& args) {
|
150
|
|
- m_reactContext.DispatchEvent(
|
151
|
|
- webView,
|
152
|
|
- L"topLoadingFinish",
|
153
|
|
- [webView, args](winrt::IJSValueWriter const& eventDataWriter) noexcept {
|
154
|
|
- eventDataWriter.WriteObjectBegin();
|
155
|
|
- {
|
156
|
|
- auto tag = webView.GetValue(winrt::FrameworkElement::TagProperty()).as<winrt::IPropertyValue>().GetInt64();
|
157
|
|
- WriteProperty(eventDataWriter, L"canGoBack", webView.CanGoBack());
|
158
|
|
- WriteProperty(eventDataWriter, L"canGoForward", webView.CanGoForward());
|
159
|
|
- WriteProperty(eventDataWriter, L"loading", false);
|
160
|
|
- WriteProperty(eventDataWriter, L"target", tag);
|
161
|
|
- WriteProperty(eventDataWriter, L"title", webView.DocumentTitle());
|
162
|
|
- WriteProperty(eventDataWriter, L"url", args.Uri().ToString());
|
163
|
|
- }
|
164
|
|
- eventDataWriter.WriteObjectEnd();
|
165
|
|
- });
|
166
|
|
- }
|
167
|
|
-
|
|
1
|
+#include "pch.h"
|
|
2
|
+#include "ReactWebViewManager.h"
|
|
3
|
+#include "NativeModules.h"
|
|
4
|
+
|
|
5
|
+namespace winrt {
|
|
6
|
+ using namespace Microsoft::ReactNative;
|
|
7
|
+ using namespace Windows::Foundation;
|
|
8
|
+ using namespace Windows::Foundation::Collections;
|
|
9
|
+ using namespace Windows::UI::Xaml;
|
|
10
|
+ using namespace Windows::UI::Xaml::Controls;
|
|
11
|
+}
|
|
12
|
+
|
|
13
|
+namespace winrt::ReactNativeWebView::implementation {
|
|
14
|
+
|
|
15
|
+ ReactWebViewManager::ReactWebViewManager() {}
|
|
16
|
+
|
|
17
|
+ // IViewManager
|
|
18
|
+ winrt::hstring ReactWebViewManager::Name() noexcept {
|
|
19
|
+ return L"RCTWebView";
|
|
20
|
+ }
|
|
21
|
+
|
|
22
|
+ winrt::FrameworkElement ReactWebViewManager::CreateView() noexcept {
|
|
23
|
+ auto webView = winrt::WebView();
|
|
24
|
+ m_webView = winrt::make_weak(webView);
|
|
25
|
+ RegisterEvents();
|
|
26
|
+ return webView;
|
|
27
|
+ }
|
|
28
|
+
|
|
29
|
+ void ReactWebViewManager::RegisterEvents() {
|
|
30
|
+ if (auto webView = m_webView.get()) {
|
|
31
|
+ m_navigationCompletedRevoker = webView.NavigationCompleted(
|
|
32
|
+ winrt::auto_revoke, [=](auto const& sender, auto const& args) {
|
|
33
|
+ OnNavigationCompleted(sender, args);
|
|
34
|
+ });
|
|
35
|
+ }
|
|
36
|
+ }
|
|
37
|
+
|
|
38
|
+ // IViewManagerWithReactContext
|
|
39
|
+ winrt::IReactContext ReactWebViewManager::ReactContext() noexcept {
|
|
40
|
+ return m_reactContext;
|
|
41
|
+ }
|
|
42
|
+
|
|
43
|
+ void ReactWebViewManager::ReactContext(IReactContext reactContext) noexcept {
|
|
44
|
+ m_reactContext = reactContext;
|
|
45
|
+ }
|
|
46
|
+
|
|
47
|
+ // IViewManagerWithNativeProperties
|
|
48
|
+ IMapView<hstring, ViewManagerPropertyType> ReactWebViewManager::NativeProps() noexcept {
|
|
49
|
+ auto nativeProps = winrt::single_threaded_map<hstring, ViewManagerPropertyType>();
|
|
50
|
+ nativeProps.Insert(L"source", ViewManagerPropertyType::Map);
|
|
51
|
+ return nativeProps.GetView();
|
|
52
|
+ }
|
|
53
|
+
|
|
54
|
+ void ReactWebViewManager::UpdateProperties(
|
|
55
|
+ FrameworkElement const& view,
|
|
56
|
+ IJSValueReader const& propertyMapReader) noexcept {
|
|
57
|
+ if (auto webView = view.try_as<winrt::WebView>()) {
|
|
58
|
+ const JSValueObject& propertyMap = JSValue::ReadObjectFrom(propertyMapReader);
|
|
59
|
+
|
|
60
|
+ for (auto const& pair : propertyMap) {
|
|
61
|
+ auto const& propertyName = pair.first;
|
|
62
|
+ auto const& propertyValue = pair.second;
|
|
63
|
+
|
|
64
|
+ if (propertyName == "source") {
|
|
65
|
+ if (!propertyValue.IsNull()) {
|
|
66
|
+ auto const& srcMap = propertyValue.Object();
|
|
67
|
+
|
|
68
|
+ auto uriString = srcMap.at("uri").String();
|
|
69
|
+ // non-uri sources not yet supported
|
|
70
|
+ if (uriString.length() == 0) {
|
|
71
|
+ continue;
|
|
72
|
+ }
|
|
73
|
+
|
|
74
|
+ bool isPackagerAsset = false;
|
|
75
|
+ if (srcMap.find("__packager_asset") != srcMap.end()) {
|
|
76
|
+ isPackagerAsset = srcMap.at("__packager_asset").Boolean();
|
|
77
|
+ }
|
|
78
|
+
|
|
79
|
+ if (isPackagerAsset && uriString.find("assets") == 0) {
|
|
80
|
+ uriString.replace(0, 6, "ms-appx://");
|
|
81
|
+ }
|
|
82
|
+
|
|
83
|
+ SetSource(winrt::Uri(to_hstring(uriString)));
|
|
84
|
+ }
|
|
85
|
+ }
|
|
86
|
+ }
|
|
87
|
+ }
|
|
88
|
+ }
|
|
89
|
+
|
|
90
|
+ void ReactWebViewManager::SetSource(winrt::Uri const& uri) {
|
|
91
|
+ if (auto webView = m_webView.get()) {
|
|
92
|
+ auto tag = webView.GetValue(winrt::FrameworkElement::TagProperty()).as<winrt::IPropertyValue>().GetInt64();
|
|
93
|
+ m_reactContext.DispatchEvent(
|
|
94
|
+ webView,
|
|
95
|
+ L"topLoadingStart",
|
|
96
|
+ [webView, tag, uri](winrt::IJSValueWriter const& eventDataWriter) noexcept {
|
|
97
|
+ eventDataWriter.WriteObjectBegin();
|
|
98
|
+ {
|
|
99
|
+ WriteProperty(eventDataWriter, L"canGoBack", webView.CanGoBack());
|
|
100
|
+ WriteProperty(eventDataWriter, L"canGoForward", webView.CanGoForward());
|
|
101
|
+ WriteProperty(eventDataWriter, L"loading", false);
|
|
102
|
+ WriteProperty(eventDataWriter, L"target", tag);
|
|
103
|
+ WriteProperty(eventDataWriter, L"title", webView.DocumentTitle());
|
|
104
|
+ WriteProperty(eventDataWriter, L"url", uri.ToString());
|
|
105
|
+ }
|
|
106
|
+ eventDataWriter.WriteObjectEnd();
|
|
107
|
+ });
|
|
108
|
+
|
|
109
|
+ webView.Navigate(uri);
|
|
110
|
+ }
|
|
111
|
+ }
|
|
112
|
+
|
|
113
|
+ // IViewManagerWithExportedEventTypeConstants
|
|
114
|
+ ConstantProvider ReactWebViewManager::ExportedCustomBubblingEventTypeConstants() noexcept {
|
|
115
|
+ return nullptr;
|
|
116
|
+ }
|
|
117
|
+
|
|
118
|
+ ConstantProvider ReactWebViewManager::ExportedCustomDirectEventTypeConstants() noexcept {
|
|
119
|
+ return [](winrt::IJSValueWriter const& constantWriter) {
|
|
120
|
+ WriteCustomDirectEventTypeConstant(constantWriter, "onLoadingStart");
|
|
121
|
+ WriteCustomDirectEventTypeConstant(constantWriter, "onLoad");
|
|
122
|
+ WriteCustomDirectEventTypeConstant(constantWriter, "onLoadingFinish");
|
|
123
|
+ };
|
|
124
|
+ }
|
|
125
|
+
|
|
126
|
+ // IViewManagerWithCommands
|
|
127
|
+ IMapView<hstring, int64_t> ReactWebViewManager::Commands() noexcept {
|
|
128
|
+ auto commands = winrt::single_threaded_map<hstring, int64_t>();
|
|
129
|
+ commands.Insert(L"goForward", 0);
|
|
130
|
+ commands.Insert(L"goBack", 1);
|
|
131
|
+ commands.Insert(L"reload", 2);
|
|
132
|
+ return commands.GetView();
|
|
133
|
+ }
|
|
134
|
+
|
|
135
|
+ void ReactWebViewManager::DispatchCommand(
|
|
136
|
+ FrameworkElement const& view,
|
|
137
|
+ int64_t commandId,
|
|
138
|
+ winrt::IJSValueReader const& commandArgsReader) noexcept {
|
|
139
|
+ if (auto webView = view.try_as<winrt::WebView>()) {
|
|
140
|
+ switch (commandId) {
|
|
141
|
+ case 0: // goForward
|
|
142
|
+ webView.GoForward();
|
|
143
|
+ break;
|
|
144
|
+ case 1: // goBack
|
|
145
|
+ webView.GoBack();
|
|
146
|
+ break;
|
|
147
|
+ case 2: // reload
|
|
148
|
+ webView.Refresh();
|
|
149
|
+ break;
|
|
150
|
+ }
|
|
151
|
+ }
|
|
152
|
+ }
|
|
153
|
+
|
|
154
|
+ void ReactWebViewManager::OnNavigationCompleted(winrt::WebView const& webView, winrt::WebViewNavigationCompletedEventArgs const& args) {
|
|
155
|
+ m_reactContext.DispatchEvent(
|
|
156
|
+ webView,
|
|
157
|
+ L"topLoadingFinish",
|
|
158
|
+ [webView, args](winrt::IJSValueWriter const& eventDataWriter) noexcept {
|
|
159
|
+ eventDataWriter.WriteObjectBegin();
|
|
160
|
+ {
|
|
161
|
+ auto tag = webView.GetValue(winrt::FrameworkElement::TagProperty()).as<winrt::IPropertyValue>().GetInt64();
|
|
162
|
+ WriteProperty(eventDataWriter, L"canGoBack", webView.CanGoBack());
|
|
163
|
+ WriteProperty(eventDataWriter, L"canGoForward", webView.CanGoForward());
|
|
164
|
+ WriteProperty(eventDataWriter, L"loading", false);
|
|
165
|
+ WriteProperty(eventDataWriter, L"target", tag);
|
|
166
|
+ WriteProperty(eventDataWriter, L"title", webView.DocumentTitle());
|
|
167
|
+ WriteProperty(eventDataWriter, L"url", args.Uri().ToString());
|
|
168
|
+ }
|
|
169
|
+ eventDataWriter.WriteObjectEnd();
|
|
170
|
+ });
|
|
171
|
+ }
|
|
172
|
+
|
168
|
173
|
} // namespace winrt::ReactWebView::implementation
|