Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds support for compiling Windows module for WinAppSDK #3411

Merged
merged 3 commits into from
May 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 5 additions & 1 deletion windows/ReactNativeWebView/ReactPackageProvider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,22 @@
#endif

#include "ReactWebView2Manager.h"
#ifndef USE_WINUI3
#include "ReactWebViewManager.h"
#endif

using namespace winrt::Microsoft::ReactNative;

namespace winrt::ReactNativeWebView::implementation {

void ReactPackageProvider::CreatePackage(IReactPackageBuilder const &packageBuilder) noexcept {
#ifndef USE_WINUI3
packageBuilder.AddViewManager(L"ReactWebViewManager", []() { return winrt::make<ReactWebViewManager>(); });
#endif

#if HAS_WEBVIEW2
packageBuilder.AddViewManager(L"ReactWebView2Manager", []() { return winrt::make<ReactWebView2Manager>(); });
#endif
}

} // namespace winrt::ReactNativeWebView::implementation
} // namespace winrt::ReactNativeWebView::implementation
12 changes: 8 additions & 4 deletions windows/ReactNativeWebView/ReactWebView.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

#ifndef USE_WINUI3

#include "pch.h"
#include "JSValueXaml.h"
#include "ReactWebView.h"
Expand Down Expand Up @@ -41,7 +43,7 @@ namespace winrt::ReactNativeWebView::implementation {
if (auto self = ref.get()) {
self->OnNavigationStarting(sender, args);
}

});

m_navigationCompletedRevoker = m_webView.NavigationCompleted(
Expand All @@ -60,7 +62,7 @@ namespace winrt::ReactNativeWebView::implementation {

m_domContentLoadedRevoker = m_webView.DOMContentLoaded(
winrt::auto_revoke, [ref = get_weak()](auto const& sender, auto const& args) {
if (auto self = ref.get())
if (auto self = ref.get())
{
self->OnDOMContentLoaded(sender, args);
}
Expand Down Expand Up @@ -167,7 +169,7 @@ namespace winrt::ReactNativeWebView::implementation {
}
}
}

m_reactContext.DispatchEvent(
*this,
L"topMessage",
Expand Down Expand Up @@ -234,4 +236,6 @@ namespace winrt::ReactNativeWebView::implementation {
bool ReactWebView::MessagingEnabled() const noexcept{
return m_messagingEnabled;
}
} // namespace winrt::ReactNativeWebView::implementation
} // namespace winrt::ReactNativeWebView::implementation

#endif // USE_WINUI3
6 changes: 5 additions & 1 deletion windows/ReactNativeWebView/ReactWebView.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

#pragma once

#ifndef USE_WINUI3

#include "winrt/Microsoft.ReactNative.h"
#include "NativeModules.h"
#include "ReactWebView.g.h"
Expand Down Expand Up @@ -49,4 +51,6 @@ namespace winrt::ReactNativeWebView::implementation {

namespace winrt::ReactNativeWebView::factory_implementation {
struct ReactWebView : ReactWebViewT<ReactWebView, implementation::ReactWebView> {};
} // namespace winrt::ReactNativeWebView::factory_implementation
} // namespace winrt::ReactNativeWebView::factory_implementation

#endif // USE_WINUI3
8 changes: 6 additions & 2 deletions windows/ReactNativeWebView/ReactWebView.idl
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
#include <NamespaceRedirect.h>

namespace ReactNativeWebView{
#if !defined(USE_WINUI3)
[default_interface]
runtimeclass ReactWebView : Windows.UI.Xaml.Controls.ContentPresenter{
ReactWebView(Microsoft.ReactNative.IReactContext context);
Expand All @@ -7,15 +10,16 @@ namespace ReactNativeWebView{
void RequestFocus();
void PostMessage(String message);
};
#endif
#if __has_include(<VersionMacros.h>)
#include <VersionMacros.h>
#else
#define RNW_VERSION_AT_LEAST(x,y,z) false
#endif

#if RNW_VERSION_AT_LEAST(0,68,0) && defined(WINUI2_HAS_WEBVIEW2)
#if RNW_VERSION_AT_LEAST(0,68,0) && (defined(WINUI2_HAS_WEBVIEW2) || defined(USE_WINUI3))
[default_interface]
runtimeclass ReactWebView2 : Windows.UI.Xaml.Controls.ContentPresenter{
runtimeclass ReactWebView2 : XAML_NAMESPACE.Controls.ContentPresenter{
ReactWebView2(Microsoft.ReactNative.IReactContext context);
void NavigateToHtml(String html);
void NavigateWithWebResourceRequest(Microsoft.ReactNative.IJSValueReader request);
Expand Down
33 changes: 18 additions & 15 deletions windows/ReactNativeWebView/ReactWebView2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,32 @@
#include "JSValueXaml.h"
#include "ReactWebView2.g.cpp"
#include <winrt/Windows.Foundation.Metadata.h>
#include <winrt/Windows.System.h>
#include <optional>

namespace mux {
using namespace winrt::Microsoft::UI::Xaml::Controls;
}

namespace winrt {
using namespace Microsoft::ReactNative;
using namespace Windows::Foundation;
using namespace Windows::UI;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Microsoft::UI::Xaml::Controls;
using namespace Microsoft::Web::WebView2::Core;
using namespace Windows::Data::Json;
using namespace Windows::UI::Popups;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::Web::Http;
using namespace Windows::Storage::Streams;
using namespace Windows::Security::Cryptography;
using namespace xaml;
using namespace xaml::Controls;
using namespace xaml::Input;
using namespace xaml::Media;
} // namespace winrt

namespace winrt::ReactNativeWebView::implementation {

ReactWebView2::ReactWebView2(winrt::IReactContext const& reactContext) : m_reactContext(reactContext) {
m_webView = winrt::WebView2();
m_webView = mux::WebView2();
this->Content(m_webView);
RegisterEvents();
}
Expand All @@ -44,7 +47,7 @@ namespace winrt::ReactNativeWebView::implementation {
if (auto self = ref.get()) {
self->OnNavigationStarting(sender, args);
}

});

m_navigationCompletedRevoker = m_webView.NavigationCompleted(
Expand All @@ -60,7 +63,7 @@ namespace winrt::ReactNativeWebView::implementation {
self->OnCoreWebView2Initialized(sender, args);
}
});
}
}

void ReactWebView2::RegisterCoreWebView2Events()
{
Expand Down Expand Up @@ -136,7 +139,7 @@ namespace winrt::ReactNativeWebView::implementation {
return hasUniversalAPIContract_v7.value();
}

void ReactWebView2::WriteWebViewNavigationEventArg(winrt::WebView2 const& sender, winrt::IJSValueWriter const& eventDataWriter) {
void ReactWebView2::WriteWebViewNavigationEventArg(mux::WebView2 const& sender, winrt::IJSValueWriter const& eventDataWriter) {
auto tag = this->GetValue(winrt::FrameworkElement::TagProperty()).as<winrt::IPropertyValue>().GetInt64();
WriteProperty(eventDataWriter, L"canGoBack", sender.CanGoBack());
WriteProperty(eventDataWriter, L"canGoForward", sender.CanGoForward());
Expand All @@ -149,7 +152,7 @@ namespace winrt::ReactNativeWebView::implementation {
}
}

void ReactWebView2::OnNavigationStarting(winrt::WebView2 const& webView, winrt::CoreWebView2NavigationStartingEventArgs const& /* args */) {
void ReactWebView2::OnNavigationStarting(mux::WebView2 const& webView, winrt::CoreWebView2NavigationStartingEventArgs const& /* args */) {
m_reactContext.DispatchEvent(
*this,
L"topLoadingStart",
Expand Down Expand Up @@ -184,7 +187,7 @@ namespace winrt::ReactNativeWebView::implementation {
HandleMessageFromJS(message);
}

void ReactWebView2::OnNavigationCompleted(winrt::WebView2 const& webView, winrt::CoreWebView2NavigationCompletedEventArgs const& /* args */) {
void ReactWebView2::OnNavigationCompleted(mux::WebView2 const& webView, winrt::CoreWebView2NavigationCompletedEventArgs const& /* args */) {
m_reactContext.DispatchEvent(
*this,
L"topLoadingFinish",
Expand All @@ -195,15 +198,15 @@ namespace winrt::ReactNativeWebView::implementation {
});

if (m_messagingEnabled) {
winrt::hstring message = LR"(window.alert = function (msg) {window.chrome.webview.postMessage(`{"type":"__alert","message":"${msg}"}`)};
winrt::hstring message = LR"(window.alert = function (msg) {window.chrome.webview.postMessage(`{"type":"__alert","message":"${msg}"}`)};
window.ReactNativeWebView = {postMessage: function (data) {window.chrome.webview.postMessage(String(data))}};
const originalPostMessage = globalThis.postMessage;
globalThis.postMessage = function (data) { originalPostMessage(data); globalThis.ReactNativeWebView.postMessage(typeof data == 'string' ? data : JSON.stringify(data));};)";
webView.ExecuteScriptAsync(message);
}
}

void ReactWebView2::OnCoreWebView2Initialized(winrt::WebView2 const& sender, winrt::CoreWebView2InitializedEventArgs const& /* args */) {
void ReactWebView2::OnCoreWebView2Initialized(mux::WebView2 const& sender, mux::CoreWebView2InitializedEventArgs const& /* args */) {
assert(sender.CoreWebView2());

RegisterCoreWebView2Events();
Expand Down Expand Up @@ -407,7 +410,7 @@ namespace winrt::ReactNativeWebView::implementation {
auto method = (m_request.find("method") != m_request.end()) ? m_request.at("method").AsString() : "GET";
auto webResourceRequest = m_webView.CoreWebView2().Environment().CreateWebResourceRequest(
uri.ToString(), winrt::to_hstring(method), nullptr, L"");

SetupRequest(m_request.Copy(), webResourceRequest);

m_webView.CoreWebView2().NavigateWithWebResourceRequest(webResourceRequest);
Expand Down
22 changes: 12 additions & 10 deletions windows/ReactNativeWebView/ReactWebView2Manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,19 @@
#include "ReactWebView2.h"
#include "JSValueXaml.h"

namespace mux {
using namespace winrt::Microsoft::UI::Xaml::Controls;
}

namespace winrt {
using namespace Microsoft::ReactNative;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Input;
using namespace Microsoft::UI::Xaml::Controls;
using namespace Windows::Web::Http;
using namespace Windows::Web::Http::Headers;
using namespace xaml;
using namespace xaml::Controls;
using namespace xaml::Input;
}

namespace winrt::ReactNativeWebView::implementation {
Expand Down Expand Up @@ -57,7 +59,7 @@ namespace winrt::ReactNativeWebView::implementation {
IJSValueReader const& propertyMapReader) noexcept {
auto control = view.as<winrt::ContentPresenter>();
auto content = control.Content();
auto webView = content.as<winrt::WebView2>();
auto webView = content.as<mux::WebView2>();
const JSValueObject& propertyMap = JSValueObject::ReadFrom(propertyMapReader);

for (auto const& pair : propertyMap) {
Expand All @@ -81,7 +83,7 @@ namespace winrt::ReactNativeWebView::implementation {
}
if (isPackagerAsset && uriString.find(fileScheme) == 0) {
auto bundleRootPath = winrt::to_string(ReactNativeHost().InstanceSettings().BundleRootPath());
uriString.replace(0, std::size(fileScheme), bundleRootPath.empty() ? "ms-appx-web:///Bundle/" : bundleRootPath);
uriString.replace(0, std::size(fileScheme), bundleRootPath.empty() ? "ms-appx-web:///Bundle/" : bundleRootPath);
}
if (uriString.find("ms-appdata://") == 0 || uriString.find("ms-appx-web://") == 0) {
reactWebView2.NavigateToHtml(to_hstring(uriString));
Expand Down Expand Up @@ -110,7 +112,7 @@ namespace winrt::ReactNativeWebView::implementation {
auto reactWebView2 = view.as<ReactNativeWebView::ReactWebView2>();
reactWebView2.LinkHandlingEnabled(linkHandlingEnabled);
}
}
}
}

// IViewManagerWithExportedEventTypeConstants
Expand Down Expand Up @@ -153,7 +155,7 @@ namespace winrt::ReactNativeWebView::implementation {
winrt::IJSValueReader const& commandArgsReader) noexcept {
auto control = view.as<winrt::ContentPresenter>();
auto content = control.Content();
auto webView = content.as<winrt::WebView2>();
auto webView = content.as<mux::WebView2>();
auto commandArgs = JSValue::ReadArrayFrom(commandArgsReader);

if (commandId == L"goForward") {
Expand All @@ -179,7 +181,7 @@ namespace winrt::ReactNativeWebView::implementation {
}
else if (commandId == L"requestFocus") {
FocusManager::TryFocusAsync(webView, FocusState::Programmatic);
}
}
else if (commandId == L"clearCache") {
// There is no way to clear the cache in WebView2 because it is shared with Edge.
// The best we can do is clear the cookies, because we cannot access history or local storage.
Expand Down
8 changes: 4 additions & 4 deletions windows/ReactNativeWebView/ReactWebView2Manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#include "NativeModules.h"

namespace winrt::ReactNativeWebView::implementation {

class ReactWebView2Manager : public winrt::implements<
ReactWebView2Manager,
winrt::Microsoft::ReactNative::IViewManager,
Expand All @@ -22,7 +22,7 @@ namespace winrt::ReactNativeWebView::implementation {
ReactWebView2Manager();
// IViewManager
winrt::hstring Name() noexcept;
winrt::Windows::UI::Xaml::FrameworkElement CreateView() noexcept;
xaml::FrameworkElement CreateView() noexcept;

// IViewManagerWithReactContext
winrt::Microsoft::ReactNative::IReactContext ReactContext() noexcept;
Expand All @@ -34,7 +34,7 @@ namespace winrt::ReactNativeWebView::implementation {
NativeProps() noexcept;

void UpdateProperties(
winrt::Windows::UI::Xaml::FrameworkElement const& view,
xaml::FrameworkElement const& view,
winrt::Microsoft::ReactNative::IJSValueReader const& propertyMapReader) noexcept;

// IViewManagerWithExportedEventTypeConstants
Expand All @@ -45,7 +45,7 @@ namespace winrt::ReactNativeWebView::implementation {
winrt::Windows::Foundation::Collections::IVectorView<winrt::hstring> Commands() noexcept;

void DispatchCommand(
winrt::Windows::UI::Xaml::FrameworkElement const& view,
xaml::FrameworkElement const& view,
winrt::hstring const& commandId,
winrt::Microsoft::ReactNative::IJSValueReader const& commandArgsReader) noexcept;

Expand Down
11 changes: 9 additions & 2 deletions windows/ReactNativeWebView/ReactWebViewManager.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

#ifndef USE_WINUI3

#include "pch.h"
#include "ReactWebViewManager.h"
#include "NativeModules.h"
Expand Down Expand Up @@ -144,7 +149,7 @@ namespace winrt::ReactNativeWebView::implementation {
auto reactWebView = view.as<ReactNativeWebView::ReactWebView>();
reactWebView.MessagingEnabled(messagingEnabled);
}
}
}
}

// IViewManagerWithExportedEventTypeConstants
Expand Down Expand Up @@ -213,4 +218,6 @@ namespace winrt::ReactNativeWebView::implementation {
}
}

} // namespace winrt::ReactWebView::implementation
} // namespace winrt::ReactWebView::implementation

#endif // USE_WINUI3
5 changes: 4 additions & 1 deletion windows/ReactNativeWebView/ReactWebViewManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@
// Licensed under the MIT License.

#pragma once

#ifndef USE_WINUI3

#include "winrt/Microsoft.ReactNative.h"
#include "NativeModules.h"
#include "ReactWebView.h"

namespace winrt::ReactNativeWebView::implementation {

class ReactWebViewManager : public winrt::implements<
ReactWebViewManager,
winrt::Microsoft::ReactNative::IViewManager,
Expand Down