Skip to content

Commit

Permalink
Add WebView2 Control Support to Windows (react-native-webview#2304)
Browse files Browse the repository at this point in the history
* Create ReactNativeWebView2 Project

* Adjust Component Name

* Update example app

* Add WebView Type Toggle

* Attempt to Update to 0.65

* Finish Upgrade of Example to 0.65

* Add WinUI Dependency

* Update pch.h

* Update to WebView2 Control

* Finish WebView2 Control Addition

* Update README

* Remove Remaining WebBridge Methods

* Add Event Handling for WebView2

* Remove DefaultBackgroundColor Handling

* Fix Type Checks

* Fix Example

* Address Feedback

* Add to packages.config

* Fix Package Config

* Adjust Packages

* Resolve Conflict

* Delete NuGet.Config

* Delete Package.appxmanifest

* Delete example.sln

* Delete App.h

* Delete .gitignore

* Delete App.cpp

* Delete App.xaml

* Remove Old Example

* Update JS to handle Versioned Support

* Finish Versioning

* Coding Adjustments

* Test Appium Id

* Alter Test

* Fix Appium

* Adjust RCT Imports

* Adjust Macros

* Final Adjustments

* Adjust Macros

* Delete launch.json

* Delete ExperimentalFeatures.props

* Fix Spacing

* Add CppLib for PkgRef Support

* Update docs/Getting-Started.md

Co-authored-by: Alexander Sklar <asklar@microsoft.com>

* Update docs/Getting-Started.md

Co-authored-by: Alexander Sklar <asklar@microsoft.com>

* Update docs/Getting-Started.md

Co-authored-by: Alexander Sklar <asklar@microsoft.com>

* Update docs/Getting-Started.md

Co-authored-by: Alexander Sklar <asklar@microsoft.com>

* Address JS Feedback

* Address Native Feedback

* Update Config Instructions

* Fix Typo

* Restore Package.appxmanifest

* Address Feedback

* Fix Format

* Restore Idl Changes

* Address Feedback

* Remove AdditionalIncludeDirectories

Co-authored-by: Alexander Sklar <asklar@microsoft.com>
  • Loading branch information
chiaramooney and asklar authored Mar 22, 2022
1 parent 5c49dbc commit a7d2c66
Show file tree
Hide file tree
Showing 25 changed files with 597 additions and 174 deletions.
1 change: 0 additions & 1 deletion __tests__/Alert.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,4 @@ describe('Alert Tests', () => {
expect(dismissMessage).not.toBeNull();
await driver.quit();
});

});
21 changes: 17 additions & 4 deletions docs/Getting-Started.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,16 +56,15 @@ For Android manual installation, please refer to [this article](https://engineer

### Windows:

Autolinking is not yet supported for ReactNativeWindows. Make following additions to the given files manually:
Autolinking is supported for React Native Windows v0.63 and higher. If your app uses a React Native Windows version that does not have autolinking support, make the following additions to the given files manually:

#### **windows/myapp.sln**

Add the `ReactNativeWebView` and `WebViewBridgeComponent` project to your solution.
Add the `ReactNativeWebView` project to your solution.

1. Open the solution in Visual Studio 2019
2. Right-click Solution icon in Solution Explorer > Add > Existing Project
Select `node_modules\react-native-webview\windows\ReactNativeWebView\ReactNativeWebView.vcxproj`
Select `node_modules\react-native-webview\windows\WebViewBridgeComponent\WebViewBridgeComponent.vcxproj`

#### **windows/myapp/myapp.vcxproj**

Expand All @@ -86,7 +85,21 @@ Add `PackageProviders().Append(winrt::ReactNativeWebView::ReactPackageProvider()

Note if you want to enable scroll with Touch for the WebView component you must disable perspective for your app using [ReactRootView.IsPerspectiveEnabled](https://microsoft.github.io/react-native-windows/docs/ReactRootView#isperspectiveenabled).

## 3. Import the webview into your component
## 3. Decide if you want access to WebView2
The WebView2 control is a [WinUI](https://docs.microsoft.com/windows/apps/winui/) control that renders web content using the Microsoft Edge (Chromium) rendering engine. We have added support for the WebView2 control to the react-native-webview community module.
If you want access to the WebView2 control in your app, follow these steps:

i. Ensure your React Native Windows version is v0.68 or higher.

ii. Let autolinking handle adding the `ReactNativeWebView2` project to your app.

iii. Customize your app's WinUI 2.x version to version 2.8.0-prerelease.210927001 or higher. See [here](https://microsoft.github.io/react-native-windows/docs/customizing-sdk-versions) for instructions. The WinUI 2.x support for WebView2 is not yet available in "stable" releases, so for now you will need to use a prerelease version.

iv. You may need to specify the `Microsoft.Web.WebView2` package in your app's `packages.config` file. If this is needed, you will get a build error listing the version of the package that you needed to specify. Simply add the package to your `packages.config`, and you should be good to go.

Now you can access the WinUI WebView2 control from your app's JavaScript via the `useWebView2` prop.

## 4. Import the webview into your component

```js
import React, { Component } from 'react';
Expand Down
14 changes: 14 additions & 0 deletions docs/Reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ This document lays out the current public properties and methods for the React N
- [`basicAuthCredential`](Reference.md#basicAuthCredential)
- [`enableApplePay`](Reference.md#enableApplePay)
- [`forceDarkOn`](Reference.md#forceDarkOn)
- [`useWebView2`](Reference.md#useWebView2)
- [`minimumFontSize`](Reference.md#minimumFontSize)

## Methods Index
Expand Down Expand Up @@ -1526,6 +1527,19 @@ An object that specifies the credentials of a user to be used for basic authenti
| ------ | -------- |
| object | No |

### `useWebView2`

Use WinUI WebView2 control instead of WebView control as the native webview. The WebView2 control is a WinUI control that renders web content using the Microsoft Edge (Chromium) rendering engine. Option can be toggled at runtime and supports Fast Refresh.

| Type | Required | Platform |
| ------- | -------- | -------- |
| boolean | No | Windows |

Example:

```javascript
<WebView useWebView2 />

### `minimumFontSize`

Android enforces a minimum font size based on this value. A non-negative integer between 1 and 72. Any number outside the specified range will be pinned. Default value is 8. If you are using smaller font sizes and are having trouble fitting the whole window onto one screen, try setting this to a smaller value.
Expand Down
1 change: 0 additions & 1 deletion example/examples/NativeWebpage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ export default class NativeWebpage extends Component<Props, State> {
<WebView
source={{uri: 'https://infinite.red'}}
style={{width: '100%', height: '100%'}}
// setSupportMultipleWindows={false}
/>
</View>
);
Expand Down
4 changes: 2 additions & 2 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Component } from 'react';
// eslint-disable-next-line
import { IOSWebViewProps, AndroidWebViewProps } from './lib/WebViewTypes';
import { IOSWebViewProps, AndroidWebViewProps, WindowsWebViewProps } from './lib/WebViewTypes';

export { FileDownload, WebViewMessageEvent, WebViewNavigation } from "./lib/WebViewTypes";

export type WebViewProps = IOSWebViewProps & AndroidWebViewProps;
export type WebViewProps = IOSWebViewProps & AndroidWebViewProps & WindowsWebViewProps;

declare class WebView<P = {}> extends Component<WebViewProps & P> {
/**
Expand Down
1 change: 0 additions & 1 deletion react-native.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ module.exports = {
// `project` was only used to infer `sourceDir` and `podfile`.
return 'example/ios/ReactTestApp-Dummy.xcodeproj';
}

// `sourceDir` and `podfile` detection was fixed in
// @react-native-community/cli-platform-ios v5.0.2 (see
// https://github.com/react-native-community/cli/pull/1444).
Expand Down
4 changes: 2 additions & 2 deletions src/WebView.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React from 'react';
import { View } from 'react-native';
import { IOSWebViewProps, AndroidWebViewProps } from './WebViewTypes';
import { IOSWebViewProps, AndroidWebViewProps, WindowsWebViewProps } from './WebViewTypes';

export type WebViewProps = IOSWebViewProps & AndroidWebViewProps;
export type WebViewProps = IOSWebViewProps & AndroidWebViewProps & WindowsWebViewProps;

// This "dummy" WebView is to render something for unsupported platforms,
// like for example Expo SDK "web" platform. It matches the previous react-native
Expand Down
26 changes: 16 additions & 10 deletions src/WebView.windows.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ import {
ImageSourcePropType,
findNodeHandle,
} from 'react-native';
import RCTWebView from "./WebViewNativeComponent.windows";
import {RCTWebView, RCTWebView2} from "./WebViewNativeComponent.windows";
import { createOnShouldStartLoadWithRequest } from './WebViewShared';
import {
NativeWebViewWindows,
WebViewSharedProps,
WindowsWebViewProps,
WebViewProgressEvent,
WebViewNavigationEvent,
WebViewErrorEvent,
Expand All @@ -33,6 +33,8 @@ import {
State,
} from './WebViewTypes';

const {version} = require('react-native/Libraries/Core/ReactNativeVersion');

const UIManager = NotTypedUIManager as RNCWebViewUIManagerWindows;
const { resolveAssetSource } = Image;

Expand All @@ -54,7 +56,7 @@ const styles = StyleSheet.create({
},
});

export default class WebView extends React.Component<WebViewSharedProps, State> {
export default class WebView extends React.Component<WindowsWebViewProps, State> {

static defaultProps = {
javaScriptEnabled: true,
Expand All @@ -67,34 +69,38 @@ export default class WebView extends React.Component<WebViewSharedProps, State>

webViewRef = React.createRef<NativeWebViewWindows>();

RnwVersionSupportsWebView2 = (version.major>1 || version.minor>=68);

RCTWebViewString = (this.RnwVersionSupportsWebView2 && this.props.useWebView2) ? 'RCTWebView2' : 'RCTWebView';

goForward = () => {
UIManager.dispatchViewManagerCommand(
this.getWebViewHandle(),
UIManager.getViewManagerConfig('RCTWebView').Commands.goForward,
UIManager.getViewManagerConfig(this.RCTWebViewString).Commands.goForward,
undefined,
);
}

goBack = () => {
UIManager.dispatchViewManagerCommand(
this.getWebViewHandle(),
UIManager.getViewManagerConfig('RCTWebView').Commands.goBack,
UIManager.getViewManagerConfig(this.RCTWebViewString).Commands.goBack,
undefined,
);
}

reload = () => {
UIManager.dispatchViewManagerCommand(
this.getWebViewHandle(),
UIManager.getViewManagerConfig('RCTWebView').Commands.reload,
UIManager.getViewManagerConfig(this.RCTWebViewString).Commands.reload,
undefined,
);
}

injectJavaScript = (data: string) => {
UIManager.dispatchViewManagerCommand(
this.getWebViewHandle(),
UIManager.getViewManagerConfig('RCTWebView').Commands.injectJavaScript,
UIManager.getViewManagerConfig(this.RCTWebViewString).Commands.injectJavaScript,
[data],
);
}
Expand All @@ -103,7 +109,7 @@ export default class WebView extends React.Component<WebViewSharedProps, State>
const message = this.getInjectableJSMessage(data);
UIManager.dispatchViewManagerCommand(
this.getWebViewHandle(),
UIManager.getViewManagerConfig('RCTWebView').Commands.injectJavaScript,
UIManager.getViewManagerConfig(this.RCTWebViewString).Commands.injectJavaScript,
[message],
);
};
Expand Down Expand Up @@ -204,6 +210,7 @@ export default class WebView extends React.Component<WebViewSharedProps, State>
renderLoading,
style,
containerStyle,
useWebView2,
...otherProps
} = this.props;

Expand Down Expand Up @@ -240,8 +247,7 @@ export default class WebView extends React.Component<WebViewSharedProps, State>
);

const NativeWebView
= (nativeConfig.component as typeof NativeWebViewWindows | undefined)
|| RCTWebView;
= (this.RnwVersionSupportsWebView2 && this.props.useWebView2)? RCTWebView2 : RCTWebView;

const webView = (
<NativeWebView
Expand Down
6 changes: 4 additions & 2 deletions src/WebViewNativeComponent.windows.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { requireNativeComponent } from "react-native";
import type { NativeWebViewWindows } from "./WebViewTypes";

const RCTWebView: typeof NativeWebViewWindows = requireNativeComponent(
export const RCTWebView: typeof NativeWebViewWindows = requireNativeComponent(
'RCTWebView',
);

export default RCTWebView;
export const RCTWebView2: typeof NativeWebViewWindows = requireNativeComponent(
'RCTWebView2',
);
6 changes: 5 additions & 1 deletion src/WebViewTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,11 @@ export interface MacOSNativeWebViewProps extends CommonNativeWebViewProps {
}

export interface WindowsNativeWebViewProps extends CommonNativeWebViewProps {
testID?: string
testID?: string;
}

export interface WindowsWebViewProps extends WebViewSharedProps {
useWebView2?: boolean;
}

export interface IOSWebViewProps extends WebViewSharedProps {
Expand Down
12 changes: 12 additions & 0 deletions windows/ExperimentalFeatures.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<!-- Flags can be added here to effect the compilation of Microsoft.ReactNative -->
<PropertyGroup Label="Microsoft.ReactNative Build Flags">
<UseWinUI3>false</UseWinUI3>
<UseHermes>false</UseHermes>
<WinUI2xVersion>2.8.0-prerelease.210927001</WinUI2xVersion>
<WebView2Version>1.0.1020.30</WebView2Version>
</PropertyGroup>

</Project>
Loading

0 comments on commit a7d2c66

Please sign in to comment.