123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- #include "pch.h"
- #include "ReactWebViewManager.h"
- #include "NativeModules.h"
-
- namespace winrt {
- using namespace Microsoft::ReactNative;
- using namespace Windows::Foundation;
- using namespace Windows::Foundation::Collections;
- using namespace Windows::UI::Xaml;
- using namespace Windows::UI::Xaml::Controls;
- }
-
- namespace winrt::ReactNativeWebView::implementation {
-
- ReactWebViewManager::ReactWebViewManager() {}
-
- // IViewManager
- winrt::hstring ReactWebViewManager::Name() noexcept {
- return L"RCTWebView";
- }
-
- winrt::FrameworkElement ReactWebViewManager::CreateView() noexcept {
- auto webView = winrt::WebView();
- m_webView = winrt::make_weak(webView);
- RegisterEvents();
- return webView;
- }
-
- void ReactWebViewManager::RegisterEvents() {
- if (auto webView = m_webView.get()) {
- m_navigationCompletedRevoker = webView.NavigationCompleted(
- winrt::auto_revoke, [=](auto const& sender, auto const& args) {
- OnNavigationCompleted(sender, args);
- });
- }
- }
-
- // IViewManagerWithReactContext
- winrt::IReactContext ReactWebViewManager::ReactContext() noexcept {
- return m_reactContext;
- }
-
- void ReactWebViewManager::ReactContext(IReactContext reactContext) noexcept {
- m_reactContext = reactContext;
- }
-
- // IViewManagerWithNativeProperties
- IMapView<hstring, ViewManagerPropertyType> ReactWebViewManager::NativeProps() noexcept {
- auto nativeProps = winrt::single_threaded_map<hstring, ViewManagerPropertyType>();
- nativeProps.Insert(L"source", ViewManagerPropertyType::Map);
- return nativeProps.GetView();
- }
-
- void ReactWebViewManager::UpdateProperties(
- FrameworkElement const& view,
- IJSValueReader const& propertyMapReader) noexcept {
- if (auto webView = view.try_as<winrt::WebView>()) {
- const JSValueObject& propertyMap = JSValue::ReadObjectFrom(propertyMapReader);
-
- for (auto const& pair : propertyMap) {
- auto const& propertyName = pair.first;
- auto const& propertyValue = pair.second;
-
- if (propertyName == "source") {
- if (!propertyValue.IsNull()) {
- auto const& srcMap = propertyValue.Object();
-
- auto uriString = srcMap.at("uri").String();
- // non-uri sources not yet supported
- if (uriString.length() == 0) {
- continue;
- }
-
- bool isPackagerAsset = false;
- if (srcMap.find("__packager_asset") != srcMap.end()) {
- isPackagerAsset = srcMap.at("__packager_asset").Boolean();
- }
-
- if (isPackagerAsset && uriString.find("assets") == 0) {
- uriString.replace(0, 6, "ms-appx://");
- }
-
- SetSource(winrt::Uri(to_hstring(uriString)));
- }
- }
- }
- }
- }
-
- void ReactWebViewManager::SetSource(winrt::Uri const& uri) {
- if (auto webView = m_webView.get()) {
- auto tag = webView.GetValue(winrt::FrameworkElement::TagProperty()).as<winrt::IPropertyValue>().GetInt64();
- m_reactContext.DispatchEvent(
- webView,
- L"topLoadingStart",
- [webView, tag, uri](winrt::IJSValueWriter const& eventDataWriter) noexcept {
- eventDataWriter.WriteObjectBegin();
- {
- WriteProperty(eventDataWriter, L"canGoBack", webView.CanGoBack());
- WriteProperty(eventDataWriter, L"canGoForward", webView.CanGoForward());
- WriteProperty(eventDataWriter, L"loading", false);
- WriteProperty(eventDataWriter, L"target", tag);
- WriteProperty(eventDataWriter, L"title", webView.DocumentTitle());
- WriteProperty(eventDataWriter, L"url", uri.ToString());
- }
- eventDataWriter.WriteObjectEnd();
- });
-
- webView.Navigate(uri);
- }
- }
-
- // IViewManagerWithExportedEventTypeConstants
- ConstantProvider ReactWebViewManager::ExportedCustomBubblingEventTypeConstants() noexcept {
- return nullptr;
- }
-
- ConstantProvider ReactWebViewManager::ExportedCustomDirectEventTypeConstants() noexcept {
- return [](winrt::IJSValueWriter const& constantWriter) {
- WriteCustomDirectEventTypeConstant(constantWriter, "onLoadingStart");
- WriteCustomDirectEventTypeConstant(constantWriter, "onLoad");
- WriteCustomDirectEventTypeConstant(constantWriter, "onLoadingFinish");
- };
- }
-
- // IViewManagerWithCommands
- IMapView<hstring, int64_t> ReactWebViewManager::Commands() noexcept {
- auto commands = winrt::single_threaded_map<hstring, int64_t>();
- commands.Insert(L"goForward", 0);
- commands.Insert(L"goBack", 1);
- commands.Insert(L"reload", 2);
- return commands.GetView();
- }
-
- void ReactWebViewManager::DispatchCommand(
- FrameworkElement const& view,
- int64_t commandId,
- winrt::IJSValueReader const& commandArgsReader) noexcept {
- if (auto webView = view.try_as<winrt::WebView>()) {
- switch (commandId) {
- case 0: // goForward
- webView.GoForward();
- break;
- case 1: // goBack
- webView.GoBack();
- break;
- case 2: // reload
- webView.Refresh();
- break;
- }
- }
- }
-
- void ReactWebViewManager::OnNavigationCompleted(winrt::WebView const& webView, winrt::WebViewNavigationCompletedEventArgs const& args) {
- m_reactContext.DispatchEvent(
- webView,
- L"topLoadingFinish",
- [webView, args](winrt::IJSValueWriter const& eventDataWriter) noexcept {
- eventDataWriter.WriteObjectBegin();
- {
- auto tag = webView.GetValue(winrt::FrameworkElement::TagProperty()).as<winrt::IPropertyValue>().GetInt64();
- WriteProperty(eventDataWriter, L"canGoBack", webView.CanGoBack());
- WriteProperty(eventDataWriter, L"canGoForward", webView.CanGoForward());
- WriteProperty(eventDataWriter, L"loading", false);
- WriteProperty(eventDataWriter, L"target", tag);
- WriteProperty(eventDataWriter, L"title", webView.DocumentTitle());
- WriteProperty(eventDataWriter, L"url", args.Uri().ToString());
- }
- eventDataWriter.WriteObjectEnd();
- });
- }
-
- } // namespace winrt::ReactWebView::implementation
|