Browse Source

Merge remote-tracking branch 'upstream/master'

sunzhongliang 4 years ago
parent
commit
425bf0a210
68 changed files with 13701 additions and 10397 deletions
  1. 4
    1
      .gitignore
  2. 2
    3
      README.md
  3. 0
    1
      android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManager.java
  4. 25
    5
      android/src/main/java/com/reactnativecommunity/webview/RNCWebViewModule.java
  5. 1
    1
      bin/setup
  6. 8
    0
      docs/Contributing.md
  7. 14
    14
      docs/Custom-Android.md
  8. 38
    6
      docs/Getting-Started.md
  9. 22
    14
      docs/Guide.md
  10. 2
    4
      docs/README.portuguese.md
  11. 127
    87
      docs/Reference.md
  12. 29
    0
      example/App.tsx
  13. 2
    2
      example/android/app/build.gradle
  14. 1
    0
      example/android/app/src/main/AndroidManifest.xml
  15. 160
    0
      example/examples/Injection.tsx
  16. 69
    0
      example/examples/Uploads.tsx
  17. 2
    2
      example/ios/Podfile.lock
  18. 92
    0
      example/windows/.gitignore
  19. 227
    0
      example/windows/WebViewWindows.sln
  20. 47
    0
      example/windows/WebViewWindows/App.cpp
  21. 15
    0
      example/windows/WebViewWindows/App.h
  22. 3
    0
      example/windows/WebViewWindows/App.idl
  23. 10
    0
      example/windows/WebViewWindows/App.xaml
  24. BIN
      example/windows/WebViewWindows/Assets/LockScreenLogo.scale-200.png
  25. BIN
      example/windows/WebViewWindows/Assets/SplashScreen.scale-200.png
  26. BIN
      example/windows/WebViewWindows/Assets/Square150x150Logo.scale-200.png
  27. BIN
      example/windows/WebViewWindows/Assets/Square44x44Logo.scale-200.png
  28. BIN
      example/windows/WebViewWindows/Assets/Square44x44Logo.targetsize-24_altform-unplated.png
  29. BIN
      example/windows/WebViewWindows/Assets/StoreLogo.png
  30. BIN
      example/windows/WebViewWindows/Assets/Wide310x150Logo.scale-200.png
  31. 49
    0
      example/windows/WebViewWindows/Package.appxmanifest
  32. 16
    0
      example/windows/WebViewWindows/PropertySheet.props
  33. 2
    0
      example/windows/WebViewWindows/ReactAssets/.gitignore
  34. 20
    0
      example/windows/WebViewWindows/ReactPackageProvider.cpp
  35. 20
    0
      example/windows/WebViewWindows/ReactPackageProvider.h
  36. 180
    0
      example/windows/WebViewWindows/WebViewWindows.vcxproj
  37. 58
    0
      example/windows/WebViewWindows/WebViewWindows.vcxproj.filters
  38. BIN
      example/windows/WebViewWindows/WebViewWindows_TemporaryKey.pfx
  39. 5
    0
      example/windows/WebViewWindows/packages.config
  40. 1
    0
      example/windows/WebViewWindows/pch.cpp
  41. 25
    0
      example/windows/WebViewWindows/pch.h
  42. 2
    0
      ios/RNCWebView.h
  43. 179
    118
      ios/RNCWebView.m
  44. 2
    0
      ios/RNCWebViewManager.m
  45. 48
    0
      metro.config.windows.js
  46. 86
    80
      package.json
  47. 8
    0
      react-native.config.js
  48. 6
    0
      src/WebView.ios.tsx
  49. 258
    0
      src/WebView.windows.tsx
  50. 29
    0
      src/WebViewTypes.ts
  51. 353
    0
      windows/.gitignore
  52. 204
    0
      windows/ReactNativeWebView.sln
  53. 16
    0
      windows/ReactNativeWebView/PropertySheet.props
  54. 3
    0
      windows/ReactNativeWebView/ReactNativeWebView.def
  55. 33
    0
      windows/ReactNativeWebView/ReactNativeWebView.filters
  56. 162
    0
      windows/ReactNativeWebView/ReactNativeWebView.vcxproj
  57. 17
    0
      windows/ReactNativeWebView/ReactPackageProvider.cpp
  58. 20
    0
      windows/ReactNativeWebView/ReactPackageProvider.h
  59. 7
    0
      windows/ReactNativeWebView/ReactPackageProvider.idl
  60. 144
    0
      windows/ReactNativeWebView/ReactWebView.cpp
  61. 36
    0
      windows/ReactNativeWebView/ReactWebView.h
  62. 7
    0
      windows/ReactNativeWebView/ReactWebView.idl
  63. 144
    0
      windows/ReactNativeWebView/ReactWebViewManager.cpp
  64. 56
    0
      windows/ReactNativeWebView/ReactWebViewManager.h
  65. 4
    0
      windows/ReactNativeWebView/packages.config
  66. 1
    0
      windows/ReactNativeWebView/pch.cpp
  67. 13
    0
      windows/ReactNativeWebView/pch.h
  68. 10587
    10059
      yarn.lock

+ 4
- 1
.gitignore View File

53
 android/gradlew
53
 android/gradlew
54
 android/gradlew.bat
54
 android/gradlew.bat
55
 
55
 
56
-lib/
56
+lib/
57
+.classpath
58
+.project
59
+.settings/

+ 2
- 3
README.md View File

21
 - [x] iOS
21
 - [x] iOS
22
 - [x] Android
22
 - [x] Android
23
 - [x] macOS
23
 - [x] macOS
24
+- [x] Windows
24
 
25
 
25
 _Note: Expo support for React Native WebView started with [Expo SDK v33.0.0](https://blog.expo.io/expo-sdk-v33-0-0-is-now-available-52d1c99dfe4c)._
26
 _Note: Expo support for React Native WebView started with [Expo SDK v33.0.0](https://blog.expo.io/expo-sdk-v33-0-0-is-now-available-52d1c99dfe4c)._
26
 
27
 
65
 // ...
66
 // ...
66
 class MyWebComponent extends Component {
67
 class MyWebComponent extends Component {
67
   render() {
68
   render() {
68
-    return (
69
-      <WebView source={{ uri: 'https://facebook.github.io/react-native/' }} />
70
-    );
69
+    return <WebView source={{ uri: 'https://reactnative.dev/' }} />;
71
   }
70
   }
72
 }
71
 }
73
 ```
72
 ```

+ 0
- 1
android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManager.java View File

208
           String baseUrl = urlObj.getProtocol() + "://" + urlObj.getHost();
208
           String baseUrl = urlObj.getProtocol() + "://" + urlObj.getHost();
209
           String cookie = CookieManager.getInstance().getCookie(baseUrl);
209
           String cookie = CookieManager.getInstance().getCookie(baseUrl);
210
           request.addRequestHeader("Cookie", cookie);
210
           request.addRequestHeader("Cookie", cookie);
211
-          System.out.println("Got cookie for DownloadManager: " + cookie);
212
         } catch (MalformedURLException e) {
211
         } catch (MalformedURLException e) {
213
           System.out.println("Error getting cookie for DownloadManager: " + e.toString());
212
           System.out.println("Error getting cookie for DownloadManager: " + e.toString());
214
           e.printStackTrace();
213
           e.printStackTrace();

+ 25
- 5
android/src/main/java/com/reactnativecommunity/webview/RNCWebViewModule.java View File

32
 import java.io.File;
32
 import java.io.File;
33
 import java.io.IOException;
33
 import java.io.IOException;
34
 import java.util.ArrayList;
34
 import java.util.ArrayList;
35
+import java.util.Arrays;
35
 
36
 
36
 import static android.app.Activity.RESULT_OK;
37
 import static android.app.Activity.RESULT_OK;
37
 
38
 
180
     filePathCallback = callback;
181
     filePathCallback = callback;
181
 
182
 
182
     ArrayList<Parcelable> extraIntents = new ArrayList<>();
183
     ArrayList<Parcelable> extraIntents = new ArrayList<>();
183
-    if (acceptsImages(acceptTypes)) {
184
-      extraIntents.add(getPhotoIntent());
185
-    }
186
-    if (acceptsVideo(acceptTypes)) {
187
-      extraIntents.add(getVideoIntent());
184
+    if (! needsCameraPermission()) {
185
+      if (acceptsImages(acceptTypes)) {
186
+        extraIntents.add(getPhotoIntent());
187
+      }
188
+      if (acceptsVideo(acceptTypes)) {
189
+        extraIntents.add(getVideoIntent());
190
+      }
188
     }
191
     }
189
 
192
 
190
     Intent fileSelectionIntent = getFileChooserIntent(acceptTypes, allowMultiple);
193
     Intent fileSelectionIntent = getFileChooserIntent(acceptTypes, allowMultiple);
233
     return result;
236
     return result;
234
   }
237
   }
235
 
238
 
239
+  protected boolean needsCameraPermission() {
240
+    boolean needed = false;
241
+
242
+    PackageManager packageManager = getCurrentActivity().getPackageManager();
243
+    try {
244
+      String[] requestedPermissions = packageManager.getPackageInfo(getReactApplicationContext().getPackageName(), PackageManager.GET_PERMISSIONS).requestedPermissions;
245
+      if (Arrays.asList(requestedPermissions).contains(Manifest.permission.CAMERA)
246
+        && ContextCompat.checkSelfPermission(getCurrentActivity(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
247
+        needed = true;
248
+      }
249
+    } catch (PackageManager.NameNotFoundException e) {
250
+      needed = true;
251
+    }
252
+
253
+    return needed;
254
+  }
255
+
236
   private Intent getPhotoIntent() {
256
   private Intent getPhotoIntent() {
237
     Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
257
     Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
238
     outputFileUri = getOutputUri(MediaStore.ACTION_IMAGE_CAPTURE);
258
     outputFileUri = getOutputUri(MediaStore.ACTION_IMAGE_CAPTURE);

+ 1
- 1
bin/setup View File

18
 # React Native installed?
18
 # React Native installed?
19
 if ! [ -x "$(command -v react-native)" ]; then
19
 if ! [ -x "$(command -v react-native)" ]; then
20
   echo 'Error: React Native is not installed.' >&2
20
   echo 'Error: React Native is not installed.' >&2
21
-  echo 'Go here: https://facebook.github.io/react-native/docs/getting-started.html' >&2
21
+  echo 'Go here: https://reactnative.dev/docs/getting-started.html' >&2
22
   echo 'Use the "Building Projects With Native Code" option.'
22
   echo 'Use the "Building Projects With Native Code" option.'
23
   exit 1
23
   exit 1
24
 fi
24
 fi

+ 8
- 0
docs/Contributing.md View File

44
 
44
 
45
 The Metro Bundler will now be running in the Terminal for react-native-macos.  In XCode select the `example-macos` target and Run.
45
 The Metro Bundler will now be running in the Terminal for react-native-macos.  In XCode select the `example-macos` target and Run.
46
 
46
 
47
+#### For Windows:
48
+```
49
+$ yarn start:windows
50
+$ open example/windows/WebViewWindows.sln and click run button.
51
+```
52
+
53
+The Metro Bundler will now be running in the Terminal for react-native-windows and the example app will be install and started
54
+
47
 ### Testing in a new `react-native init` project
55
 ### Testing in a new `react-native init` project
48
 
56
 
49
 In a new `react-native init` project, do this:
57
 In a new `react-native init` project, do this:

+ 14
- 14
docs/Custom-Android.md View File

1
 While the built-in web view has a lot of features, it is not possible to handle every use-case in React Native. You can, however, extend the web view with native code without forking React Native or duplicating all the existing web view code.
1
 While the built-in web view has a lot of features, it is not possible to handle every use-case in React Native. You can, however, extend the web view with native code without forking React Native or duplicating all the existing web view code.
2
 
2
 
3
-Before you do this, you should be familiar with the concepts in [native UI components](https://facebook.github.io/react-native/docs/native-components-android). You should also familiarise yourself with the [native code for web views](https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/views/webview/ReactWebViewManager.java), as you will have to use this as a reference when implementing new features—although a deep understanding is not required.
3
+Before you do this, you should be familiar with the concepts in [native UI components](https://reactnative.dev/docs/native-components-android). You should also familiarise yourself with the [native code for web views](https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/views/webview/ReactWebViewManager.java), as you will have to use this as a reference when implementing new features—although a deep understanding is not required.
4
 
4
 
5
 ## Native Code
5
 ## Native Code
6
 
6
 
7
 To get started, you'll need to create a subclass of `RNCWebViewManager`, `RNCWebView`, and `ReactWebViewClient`. In your view manager, you'll then need to override:
7
 To get started, you'll need to create a subclass of `RNCWebViewManager`, `RNCWebView`, and `ReactWebViewClient`. In your view manager, you'll then need to override:
8
 
8
 
9
-* `createReactWebViewInstance`
10
-* `getName`
11
-* `addEventEmitters`
9
+- `createReactWebViewInstance`
10
+- `getName`
11
+- `addEventEmitters`
12
 
12
 
13
 ```java
13
 ```java
14
 @ReactModule(name = CustomWebViewManager.REACT_CLASS)
14
 @ReactModule(name = CustomWebViewManager.REACT_CLASS)
168
 
168
 
169
 To use your custom web view, you'll need to create a class for it. Your class must:
169
 To use your custom web view, you'll need to create a class for it. Your class must:
170
 
170
 
171
-* Export all the prop types from `WebView.propTypes`
172
-* Return a `WebView` component with the prop `nativeConfig.component` set to your native component (see below)
171
+- Export all the prop types from `WebView.propTypes`
172
+- Return a `WebView` component with the prop `nativeConfig.component` set to your native component (see below)
173
 
173
 
174
 To get your native component, you must use `requireNativeComponent`: the same as for regular custom components. However, you must pass in an extra third argument, `WebView.extraNativeComponentConfig`. This third argument contains prop types that are only required for native code.
174
 To get your native component, you must use `requireNativeComponent`: the same as for regular custom components. However, you must pass in an extra third argument, `WebView.extraNativeComponentConfig`. This third argument contains prop types that are only required for native code.
175
 
175
 
176
 ```javascript
176
 ```javascript
177
-import React, {Component, PropTypes} from 'react';
178
-import {requireNativeComponent} from 'react-native';
179
-import {WebView} from 'react-native-webview';
177
+import React, { Component, PropTypes } from 'react';
178
+import { requireNativeComponent } from 'react-native';
179
+import { WebView } from 'react-native-webview';
180
 
180
 
181
 export default class CustomWebView extends Component {
181
 export default class CustomWebView extends Component {
182
   static propTypes = WebView.propTypes;
182
   static propTypes = WebView.propTypes;
183
 
183
 
184
   render() {
184
   render() {
185
     return (
185
     return (
186
-      <WebView {...this.props} nativeConfig={{component: RCTCustomWebView}} />
186
+      <WebView {...this.props} nativeConfig={{ component: RCTCustomWebView }} />
187
     );
187
     );
188
   }
188
   }
189
 }
189
 }
191
 const RCTCustomWebView = requireNativeComponent(
191
 const RCTCustomWebView = requireNativeComponent(
192
   'RCTCustomWebView',
192
   'RCTCustomWebView',
193
   CustomWebView,
193
   CustomWebView,
194
-  WebView.extraNativeComponentConfig
194
+  WebView.extraNativeComponentConfig,
195
 );
195
 );
196
 ```
196
 ```
197
 
197
 
213
     finalUrl: 'about:blank',
213
     finalUrl: 'about:blank',
214
   };
214
   };
215
 
215
 
216
-  _onNavigationCompleted = (event) => {
217
-    const {onNavigationCompleted} = this.props;
216
+  _onNavigationCompleted = event => {
217
+    const { onNavigationCompleted } = this.props;
218
     onNavigationCompleted && onNavigationCompleted(event);
218
     onNavigationCompleted && onNavigationCompleted(event);
219
   };
219
   };
220
 
220
 
249
       ...WebView.extraNativeComponentConfig.nativeOnly,
249
       ...WebView.extraNativeComponentConfig.nativeOnly,
250
       onScrollToBottom: true,
250
       onScrollToBottom: true,
251
     },
251
     },
252
-  }
252
+  },
253
 );
253
 );
254
 ```
254
 ```

+ 38
- 6
docs/Getting-Started.md View File

7
 ```
7
 ```
8
 $ yarn add react-native-webview
8
 $ yarn add react-native-webview
9
 ```
9
 ```
10
- (or)
11
- 
12
- For npm use
10
+
11
+(or)
12
+
13
+For npm use
14
+
13
 ```
15
 ```
14
 $ npm install --save react-native-webview
16
 $ npm install --save react-native-webview
15
 ```
17
 ```
29
 ### iOS:
31
 ### iOS:
30
 
32
 
31
 If using cocoapods in the `ios/` directory run
33
 If using cocoapods in the `ios/` directory run
34
+
32
 ```
35
 ```
33
 $ pod install
36
 $ pod install
34
 ```
37
 ```
35
 
38
 
36
-For iOS, while you can manually link the old way using [react-native own tutorial](https://facebook.github.io/react-native/docs/linking-libraries-ios), we find it easier to use cocoapods.
39
+For iOS, while you can manually link the old way using [react-native own tutorial](https://reactnative.dev/docs/linking-libraries-ios), we find it easier to use cocoapods.
37
 If you wish to use cocoapods and haven't set it up yet, please instead refer to [that article](https://engineering.brigad.co/demystifying-react-native-modules-linking-ae6c017a6b4a).
40
 If you wish to use cocoapods and haven't set it up yet, please instead refer to [that article](https://engineering.brigad.co/demystifying-react-native-modules-linking-ae6c017a6b4a).
38
 
41
 
39
 ### Android:
42
 ### Android:
53
 
56
 
54
 ### macOS:
57
 ### macOS:
55
 
58
 
56
-Cocoapod and autolinking is not yet support for react-native macOS but is coming soon.  In the meantime you must manually link.
59
+Cocoapod and autolinking is not yet support for react-native macOS but is coming soon. In the meantime you must manually link.
60
+
61
+The method is nearly identical to the [manual linking method for iOS](https://reactnative.dev/docs/linking-libraries-ios#manual-linking) except that you will include the `node_modules/react-native-webview/macos/RNCWebView.xcodeproj` project in your main project and link the `RNCWebView-macOS.a` library.
62
+
63
+### Windows:
64
+
65
+Autolinking is not yet supported for ReactNativeWindows. Make following additions to the given files manually:
66
+
67
+#### **windows/myapp.sln**
68
+
69
+Add the `ReactNativeWebView` project to your solution.
70
+
71
+1. Open the solution in Visual Studio 2019
72
+2. Right-click Solution icon in Solution Explorer > Add > Existing Project
73
+   Select `node_modules\react-native-webview\windows\ReactNativeWebView\ReactNativeWebView.vcxproj`
74
+
75
+#### **windows/myapp/myapp.vcxproj**
76
+
77
+Add a reference to `ReactNativeWebView` to your main application project. From Visual Studio 2019:
78
+
79
+1. Right-click main application project > Add > Reference...
80
+  Check `ReactNativeWebView` from Solution Projects.
81
+
82
+2. Modify files below to add the package providers to your main application project
83
+
84
+#### **pch.h**
85
+
86
+Add `#include "winrt/ReactNativeWebView.h"`.
87
+
88
+#### **app.cpp**
57
 
89
 
58
-The method is nearly identical to the [manual linking method for iOS](https://facebook.github.io/react-native/docs/linking-libraries-ios#manual-linking) except that you will include the `node_modules/react-native-webview/macos/RNCWebView.xcodeproj` project in your main project and link the `RNCWebView-macOS.a` library. 
90
+Add `PackageProviders().Append(winrt::ReactNativeWebView::ReactPackageProvider());` before `InitializeComponent();`.
59
 
91
 
60
 ## 3. Import the webview into your component
92
 ## 3. Import the webview into your component
61
 
93
 

+ 22
- 14
docs/Guide.md View File

48
 
48
 
49
 class MyWeb extends Component {
49
 class MyWeb extends Component {
50
   render() {
50
   render() {
51
-    return (
52
-      <WebView source={{ uri: 'https://facebook.github.io/react-native/' }} />
53
-    );
51
+    return <WebView source={{ uri: 'https://reactnative.dev/' }} />;
54
   }
52
   }
55
 }
53
 }
56
 ```
54
 ```
63
 import React, { Component } from 'react';
61
 import React, { Component } from 'react';
64
 import { WebView } from 'react-native-webview';
62
 import { WebView } from 'react-native-webview';
65
 
63
 
66
-const myHtmlFile = require("./my-asset-folder/local-site.html");
64
+const myHtmlFile = require('./my-asset-folder/local-site.html');
67
 
65
 
68
 class MyWeb extends Component {
66
 class MyWeb extends Component {
69
   render() {
67
   render() {
70
-    return (
71
-      <WebView source={myHtmlFile} />
72
-    );
68
+    return <WebView source={myHtmlFile} />;
73
   }
69
   }
74
 }
70
 }
75
 ```
71
 ```
83
 class MyWeb extends Component {
79
 class MyWeb extends Component {
84
   render() {
80
   render() {
85
     return (
81
     return (
86
-      <WebView source={{ uri: "file:///android_asset/local-site.html" }} />
82
+      <WebView source={{ uri: 'file:///android_asset/local-site.html' }} />
87
     );
83
     );
88
   }
84
   }
89
 }
85
 }
104
     return (
100
     return (
105
       <WebView
101
       <WebView
106
         ref={ref => (this.webview = ref)}
102
         ref={ref => (this.webview = ref)}
107
-        source={{ uri: 'https://facebook.github.io/react-native/' }}
103
+        source={{ uri: 'https://reactnative.dev/' }}
108
         onNavigationStateChange={this.handleWebViewNavigationStateChange}
104
         onNavigationStateChange={this.handleWebViewNavigationStateChange}
109
       />
105
       />
110
     );
106
     );
141
 
137
 
142
     // redirect somewhere else
138
     // redirect somewhere else
143
     if (url.includes('google.com')) {
139
     if (url.includes('google.com')) {
144
-      const newURL = 'https://facebook.github.io/react-native/';
140
+      const newURL = 'https://reactnative.dev/';
145
       const redirectTo = 'window.location = "' + newURL + '"';
141
       const redirectTo = 'window.location = "' + newURL + '"';
146
       this.webview.injectJavaScript(redirectTo);
142
       this.webview.injectJavaScript(redirectTo);
147
     }
143
     }
191
 </manifest>
187
 </manifest>
192
 ```
188
 ```
193
 
189
 
190
+###### Camera option availability in uploading for Android
191
+
192
+If the file input indicates that images or video is desired with [`accept`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#accept), then the WebView will attempt to provide options to the user to use their camera to take a picture or video.
193
+
194
+Normally, apps that do not have permission to use the camera can prompt the user to use an external app so that the requesting app has no need for permission. However, Android has made a special exception for this around the camera to reduce confusion for users. If an app _can_ request the camera permission because it has been declared, and the user has not granted the permission, it may not fire an intent that would use the camera (`MediaStore.ACTION_IMAGE_CAPTURE` or `MediaStore.ACTION_VIDEO_CAPTURE`). In this scenario, it is up to the developer to request camera permission before a file upload directly using the camera is necessary.
195
+
194
 ##### Check for File Upload support, with `static isFileUploadSupported()`
196
 ##### Check for File Upload support, with `static isFileUploadSupported()`
195
 
197
 
196
 File Upload using `<input type="file" />` is not supported for Android 4.4 KitKat (see [details](https://github.com/delight-im/Android-AdvancedWebView/issues/4#issuecomment-70372146)):
198
 File Upload using `<input type="file" />` is not supported for Android 4.4 KitKat (see [details](https://github.com/delight-im/Android-AdvancedWebView/issues/4#issuecomment-70372146)):
291
 
293
 
292
 This runs the JavaScript in the `runFirst` string once the page is loaded. In this case, you can see that both the body style was changed to red and the alert showed up after 2 seconds.
294
 This runs the JavaScript in the `runFirst` string once the page is loaded. In this case, you can see that both the body style was changed to red and the alert showed up after 2 seconds.
293
 
295
 
296
+By setting `injectedJavaScriptForMainFrameOnly: false`, the JavaScript injection will occur on all frames (not just the top frame) if supported for the given platform.
297
+
294
 <img alt="screenshot of Github repo" width="200" src="https://user-images.githubusercontent.com/1479215/53609254-e5dc9c00-3b7a-11e9-9118-bc4e520ce6ca.png" />
298
 <img alt="screenshot of Github repo" width="200" src="https://user-images.githubusercontent.com/1479215/53609254-e5dc9c00-3b7a-11e9-9118-bc4e520ce6ca.png" />
295
 
299
 
296
 _Under the hood_
300
 _Under the hood_
297
 
301
 
298
-> On iOS, `injectedJavaScript` runs a method on WebView called `evaluateJavaScript:completionHandler:`
302
+> On iOS, ~~`injectedJavaScript` runs a method on WebView called `evaluateJavaScript:completionHandler:`~~ – this is no longer true as of version `8.2.0`. Instead, we use a `WKUserScript` with injection time `WKUserScriptInjectionTimeAtDocumentEnd`. As a consequence, `injectedJavaScript` no longer returns an evaluation value nor logs a warning to the console. In the unlikely event that your app depended upon this behaviour, please see migration steps [here](https://github.com/react-native-community/react-native-webview/pull/1119#issuecomment-574919464) to retain equivalent behaviour.
299
 > On Android, `injectedJavaScript` runs a method on the Android WebView called `evaluateJavascriptWithFallback`
303
 > On Android, `injectedJavaScript` runs a method on the Android WebView called `evaluateJavascriptWithFallback`
300
 
304
 
301
-
302
 #### The `injectedJavaScriptBeforeContentLoaded` prop
305
 #### The `injectedJavaScriptBeforeContentLoaded` prop
303
 
306
 
304
-This is a script that runs **before** the web page loads for the first time. It only runs once, even if the page is reloaded or navigated away. This is useful if you want to inject anything into the window, localstorage, or document prior to the web code executing. 
307
+This is a script that runs **before** the web page loads for the first time. It only runs once, even if the page is reloaded or navigated away. This is useful if you want to inject anything into the window, localstorage, or document prior to the web code executing.
305
 
308
 
306
 ```jsx
309
 ```jsx
307
 import React, { Component } from 'react';
310
 import React, { Component } from 'react';
329
 }
332
 }
330
 ```
333
 ```
331
 
334
 
332
-This runs the JavaScript in the `runFirst` string before the page is loaded. In this case, the value of `window.isNativeApp` will be set to true before the web code executes. 
335
+This runs the JavaScript in the `runFirst` string before the page is loaded. In this case, the value of `window.isNativeApp` will be set to true before the web code executes.
336
+
337
+By setting `injectedJavaScriptBeforeContentLoadedForMainFrameOnly: false`, the JavaScript injection will occur on all frames (not just the top frame) if supported for the given platform. Howver, although support for `injectedJavaScriptBeforeContentLoadedForMainFrameOnly: false` has been implemented for iOS and macOS, [it is not clear](https://github.com/react-native-community/react-native-webview/pull/1119#issuecomment-600275750) that it is actually possible to inject JS into iframes at this point in the page lifecycle, and so relying on the expected behaviour of this prop when set to `false` is not recommended.
338
+
339
+> On iOS, ~~`injectedJavaScriptBeforeContentLoaded` runs a method on WebView called `evaluateJavaScript:completionHandler:`~~ – this is no longer true as of version `8.2.0`. Instead, we use a `WKUserScript` with injection time `WKUserScriptInjectionTimeAtDocumentStart`. As a consequence, `injectedJavaScriptBeforeContentLoaded` no longer returns an evaluation value nor logs a warning to the console. In the unlikely event that your app depended upon this behaviour, please see migration steps [here](https://github.com/react-native-community/react-native-webview/pull/1119#issuecomment-574919464) to retain equivalent behaviour.
340
+> On Android, `injectedJavaScript` runs a method on the Android WebView called `evaluateJavascriptWithFallback`
333
 
341
 
334
 #### The `injectJavaScript` method
342
 #### The `injectJavaScript` method
335
 
343
 

+ 2
- 4
docs/README.portuguese.md View File

36
 
36
 
37
 - [7.0.1](https://github.com/react-native-community/react-native-webview/releases/tag/v7.0.1) - UIWebView removido
37
 - [7.0.1](https://github.com/react-native-community/react-native-webview/releases/tag/v7.0.1) - UIWebView removido
38
 
38
 
39
-- [6.0.**2**](https://github.com/react-native-community/react-native-webview/releases/tag/v6.0.2) - Update para AndroidX. Tenha certeza de habilitar no `android/gradle.properties` do seu projeto. Veja o [Getting Started Guide](docs/Getting-Started.md).
39
+- [6.0.**2**](https://github.com/react-native-community/react-native-webview/releases/tag/v6.0.2) - Update para AndroidX. Tenha certeza de habilitar no `android/gradle.properties` do seu projeto. Veja o [Getting Started Guide](https://github.com/react-native-community/react-native-webview/blob/master/docs/Getting-Started.md).
40
 
40
 
41
 - [5.0.**1**](https://github.com/react-native-community/react-native-webview/releases/tag/v5.0.0) - Refatorou a antiga implementação postMessage para comunicação da visualização da webview para nativa.
41
 - [5.0.**1**](https://github.com/react-native-community/react-native-webview/releases/tag/v5.0.0) - Refatorou a antiga implementação postMessage para comunicação da visualização da webview para nativa.
42
 - [4.0.0](https://github.com/react-native-community/react-native-webview/releases/tag/v4.0.0) - Cache adicionada(habilitada por padrão).
42
 - [4.0.0](https://github.com/react-native-community/react-native-webview/releases/tag/v4.0.0) - Cache adicionada(habilitada por padrão).
62
 // ...
62
 // ...
63
 class MyWebComponent extends Component {
63
 class MyWebComponent extends Component {
64
   render() {
64
   render() {
65
-    return (
66
-      <WebView source={{ uri: 'https://facebook.github.io/react-native/' }} />
67
-    );
65
+    return <WebView source={{ uri: 'https://reactnative.dev/' }} />;
68
   }
66
   }
69
 }
67
 }
70
 ```
68
 ```

+ 127
- 87
docs/Reference.md View File

7
 - [`source`](Reference.md#source)
7
 - [`source`](Reference.md#source)
8
 - [`automaticallyAdjustContentInsets`](Reference.md#automaticallyadjustcontentinsets)
8
 - [`automaticallyAdjustContentInsets`](Reference.md#automaticallyadjustcontentinsets)
9
 - [`injectedJavaScript`](Reference.md#injectedjavascript)
9
 - [`injectedJavaScript`](Reference.md#injectedjavascript)
10
-- [`injectedJavaScriptBeforeContentLoaded`](Reference.md#injectedJavaScriptBeforeContentLoaded)
10
+- [`injectedJavaScriptBeforeContentLoaded`](Reference.md#injectedjavascriptbeforecontentloaded)
11
+- [`injectedJavaScriptForMainFrameOnly`](Reference.md#injectedjavascriptformainframeonly)
12
+- [`injectedJavaScriptBeforeContentLoadedForMainFrameOnly`](Reference.md#injectedjavascriptbeforecontentloadedformainframeonly)
11
 - [`mediaPlaybackRequiresUserAction`](Reference.md#mediaplaybackrequiresuseraction)
13
 - [`mediaPlaybackRequiresUserAction`](Reference.md#mediaplaybackrequiresuseraction)
12
 - [`nativeConfig`](Reference.md#nativeconfig)
14
 - [`nativeConfig`](Reference.md#nativeconfig)
13
 - [`onError`](Reference.md#onerror)
15
 - [`onError`](Reference.md#onerror)
75
 - [`clearCache`](Reference.md#clearCache)
77
 - [`clearCache`](Reference.md#clearCache)
76
 - [`clearHistory`](Reference.md#clearHistory)
78
 - [`clearHistory`](Reference.md#clearHistory)
77
 - [`requestFocus`](Reference.md#requestFocus)
79
 - [`requestFocus`](Reference.md#requestFocus)
80
+
78
 ---
81
 ---
79
 
82
 
80
 # Reference
83
 # Reference
119
 
122
 
120
 ### `injectedJavaScript`
123
 ### `injectedJavaScript`
121
 
124
 
122
-Set this to provide JavaScript that will be injected into the web page when the view loads. Make sure the string evaluates to a valid type (`true` works) and doesn't otherwise throw an exception.
125
+Set this to provide JavaScript that will be injected into the web page after the document finishes loading, but before other subresources finish loading.
123
 
126
 
124
-| Type   | Required |
125
-| ------ | -------- |
126
-| string | No       |
127
+Make sure the string evaluates to a valid type (`true` works) and doesn't otherwise throw an exception.
128
+
129
+On iOS, see [`WKUserScriptInjectionTimeAtDocumentEnd`](https://developer.apple.com/documentation/webkit/wkuserscriptinjectiontime/wkuserscriptinjectiontimeatdocumentend?language=objc)
130
+
131
+| Type   | Required | Platform |
132
+| ------ | -------- | -------- |
133
+| string | No       | iOS, Android, macOS
127
 
134
 
128
 To learn more, read the [Communicating between JS and Native](Guide.md#communicating-between-js-and-native) guide.
135
 To learn more, read the [Communicating between JS and Native](Guide.md#communicating-between-js-and-native) guide.
129
 
136
 
137
 })();`;
144
 })();`;
138
 
145
 
139
 <WebView
146
 <WebView
140
-  source={{ uri: 'https://facebook.github.io/react-native' }}
147
+  source={{ uri: 'https://reactnative.dev' }}
141
   injectedJavaScript={INJECTED_JAVASCRIPT}
148
   injectedJavaScript={INJECTED_JAVASCRIPT}
142
   onMessage={this.onMessage}
149
   onMessage={this.onMessage}
143
 />;
150
 />;
147
 
154
 
148
 ### `injectedJavaScriptBeforeContentLoaded`
155
 ### `injectedJavaScriptBeforeContentLoaded`
149
 
156
 
150
-Set this to provide JavaScript that will be injected into the web page after the document element is created, but before any other content is loaded. Make sure the string evaluates to a valid type (`true` works) and doesn't otherwise throw an exception.
151
-On iOS, see [WKUserScriptInjectionTimeAtDocumentStart](https://developer.apple.com/documentation/webkit/wkuserscriptinjectiontime/wkuserscriptinjectiontimeatdocumentstart?language=objc)
157
+Set this to provide JavaScript that will be injected into the web page after the document element is created, but before other subresources finish loading.
152
 
158
 
153
-| Type   | Required |
154
-| ------ | -------- |
155
-| string | No       |
159
+Make sure the string evaluates to a valid type (`true` works) and doesn't otherwise throw an exception.
160
+
161
+On iOS, see [`WKUserScriptInjectionTimeAtDocumentStart`](https://developer.apple.com/documentation/webkit/wkuserscriptinjectiontime/wkuserscriptinjectiontimeatdocumentstart?language=objc)
162
+
163
+| Type   | Required | Platform |
164
+| ------ | -------- | -------- |
165
+| string | No       | iOS, macOS |
156
 
166
 
157
 To learn more, read the [Communicating between JS and Native](Guide.md#communicating-between-js-and-native) guide.
167
 To learn more, read the [Communicating between JS and Native](Guide.md#communicating-between-js-and-native) guide.
158
 
168
 
159
 Example:
169
 Example:
160
 
170
 
161
-Post message a JSON object of `window.location` to be handled by [`onMessage`](Reference.md#onmessage)
171
+Post message a JSON object of `window.location` to be handled by [`onMessage`](Reference.md#onmessage). `window.ReactNativeWebView.postMessage` *will* be available at this time.
162
 
172
 
163
 ```jsx
173
 ```jsx
164
 const INJECTED_JAVASCRIPT = `(function() {
174
 const INJECTED_JAVASCRIPT = `(function() {
166
 })();`;
176
 })();`;
167
 
177
 
168
 <WebView
178
 <WebView
169
-  source={{ uri: 'https://facebook.github.io/react-native' }}
179
+  source={{ uri: 'https://reactnative.dev' }}
170
   injectedJavaScriptBeforeContentLoaded={INJECTED_JAVASCRIPT}
180
   injectedJavaScriptBeforeContentLoaded={INJECTED_JAVASCRIPT}
171
   onMessage={this.onMessage}
181
   onMessage={this.onMessage}
172
 />;
182
 />;
174
 
184
 
175
 ---
185
 ---
176
 
186
 
187
+### `injectedJavaScriptForMainFrameOnly`
188
+
189
+If `true` (default), loads the `injectedJavaScript` only into the main frame.
190
+
191
+If `false`, loads it into all frames (e.g. iframes).
192
+
193
+| Type   | Required | Platform |
194
+| ------ | -------- | -------- |
195
+| bool | No       | iOS, macOS       |
196
+
197
+---
198
+
199
+### `injectedJavaScriptBeforeContentLoadedForMainFrameOnly`
200
+
201
+If `true` (default), loads the `injectedJavaScriptBeforeContentLoaded` only into the main frame.
202
+
203
+If `false`, loads it into all frames (e.g. iframes).
204
+
205
+Warning: although support for `injectedJavaScriptBeforeContentLoadedForMainFrameOnly: false` has been implemented for iOS and macOS, [it is not clear](https://github.com/react-native-community/react-native-webview/pull/1119#issuecomment-600275750) that it is actually possible to inject JS into iframes at this point in the page lifecycle, and so relying on the expected behaviour of this prop when set to `false` is not recommended.
206
+
207
+| Type   | Required | Platform |
208
+| ------ | -------- | -------- |
209
+| bool | No       | iOS, macOS       |
210
+
211
+---
212
+
177
 ### `mediaPlaybackRequiresUserAction`
213
 ### `mediaPlaybackRequiresUserAction`
178
 
214
 
179
 Boolean that determines whether HTML5 audio and video requires the user to tap them before they start playing. The default value is `true`. (Android API minimum version 17).
215
 Boolean that determines whether HTML5 audio and video requires the user to tap them before they start playing. The default value is `true`. (Android API minimum version 17).
180
 
216
 
181
 NOTE: the default `true` value might cause some videos to hang loading on iOS. Setting it to `false` could fix this issue.
217
 NOTE: the default `true` value might cause some videos to hang loading on iOS. Setting it to `false` could fix this issue.
182
 
218
 
183
-| Type | Required |
184
-| ---- | -------- |
185
-| bool | No       |
219
+| Type | Required | Platform |
220
+| ---- | -------- | -------- |
221
+| bool | No       | iOS, Android, macOS |
186
 
222
 
187
 ---
223
 ---
188
 
224
 
196
 - `props` (object)
232
 - `props` (object)
197
 - `viewManager` (object)
233
 - `viewManager` (object)
198
 
234
 
199
-| Type   | Required |
200
-| ------ | -------- |
201
-| object | No       |
235
+| Type   | Required | Platform |
236
+| ------ | -------- | -------- |
237
+| object | No       | iOS, Android, macOS |
202
 
238
 
203
 ---
239
 ---
204
 
240
 
214
 
250
 
215
 ```jsx
251
 ```jsx
216
 <WebView
252
 <WebView
217
-  source={{ uri: 'https://facebook.github.io/react-native' }}
253
+  source={{ uri: 'https://reactnative.dev' }}
218
   onError={syntheticEvent => {
254
   onError={syntheticEvent => {
219
     const { nativeEvent } = syntheticEvent;
255
     const { nativeEvent } = syntheticEvent;
220
     console.warn('WebView error: ', nativeEvent);
256
     console.warn('WebView error: ', nativeEvent);
254
 
290
 
255
 ```jsx
291
 ```jsx
256
 <WebView
292
 <WebView
257
-  source={{ uri: 'https://facebook.github.io/react-native' }}
293
+  source={{ uri: 'https://reactnative.dev' }}
258
   onLoad={syntheticEvent => {
294
   onLoad={syntheticEvent => {
259
     const { nativeEvent } = syntheticEvent;
295
     const { nativeEvent } = syntheticEvent;
260
     this.url = nativeEvent.url;
296
     this.url = nativeEvent.url;
287
 
323
 
288
 ```jsx
324
 ```jsx
289
 <WebView
325
 <WebView
290
-  source={{ uri: 'https://facebook.github.io/react-native' }}
326
+  source={{ uri: 'https://reactnative.dev' }}
291
   onLoadEnd={syntheticEvent => {
327
   onLoadEnd={syntheticEvent => {
292
     // update component to be aware of loading status
328
     // update component to be aware of loading status
293
     const { nativeEvent } = syntheticEvent;
329
     const { nativeEvent } = syntheticEvent;
321
 
357
 
322
 ```jsx
358
 ```jsx
323
 <WebView
359
 <WebView
324
-  source={{ uri: 'https://facebook.github.io/react-native/=' }}
360
+  source={{ uri: 'https://reactnative.dev/=' }}
325
   onLoadStart={syntheticEvent => {
361
   onLoadStart={syntheticEvent => {
326
     // update component to be aware of loading status
362
     // update component to be aware of loading status
327
     const { nativeEvent } = syntheticEvent;
363
     const { nativeEvent } = syntheticEvent;
347
 
383
 
348
 Function that is invoked when the `WebView` is loading.
384
 Function that is invoked when the `WebView` is loading.
349
 
385
 
350
-| Type     | Required |
351
-| -------- | -------- |
352
-| function | No       |
386
+| Type     | Required | Platform |
387
+| -------- | -------- | --------- |
388
+| function | No       | iOS, Android, macOS |
353
 
389
 
354
 Example:
390
 Example:
355
 
391
 
356
 ```jsx
392
 ```jsx
357
 <WebView
393
 <WebView
358
-  source={{ uri: 'https://facebook.github.io/react-native' }}
394
+  source={{ uri: 'https://reactnative.dev' }}
359
   onLoadProgress={({ nativeEvent }) => {
395
   onLoadProgress={({ nativeEvent }) => {
360
     this.loadingProgress = nativeEvent.progress;
396
     this.loadingProgress = nativeEvent.progress;
361
   }}
397
   }}
391
 
427
 
392
 ```jsx
428
 ```jsx
393
 <WebView
429
 <WebView
394
-  source={{ uri: 'https://facebook.github.io/react-native' }}
430
+  source={{ uri: 'https://reactnative.dev' }}
395
   onHttpError={syntheticEvent => {
431
   onHttpError={syntheticEvent => {
396
     const { nativeEvent } = syntheticEvent;
432
     const { nativeEvent } = syntheticEvent;
397
     console.warn(
433
     console.warn(
446
 
482
 
447
 ```jsx
483
 ```jsx
448
 <WebView
484
 <WebView
449
-  source={{ uri: 'https://facebook.github.io/react-native' }}
485
+  source={{ uri: 'https://reactnative.dev' }}
450
   onNavigationStateChange={navState => {
486
   onNavigationStateChange={navState => {
451
     // Keep track of going back navigation within component
487
     // Keep track of going back navigation within component
452
     this.canGoBack = navState.canGoBack;
488
     this.canGoBack = navState.canGoBack;
482
 
518
 
483
 ```jsx
519
 ```jsx
484
 <WebView
520
 <WebView
485
-  source={{ uri: 'https://facebook.github.io/react-native' }}
521
+  source={{ uri: 'https://reactnative.dev' }}
486
   onContentProcessDidTerminate={syntheticEvent => {
522
   onContentProcessDidTerminate={syntheticEvent => {
487
     const { nativeEvent } = syntheticEvent;
523
     const { nativeEvent } = syntheticEvent;
488
     console.warn('Content process terminated, reloading', nativeEvent);
524
     console.warn('Content process terminated, reloading', nativeEvent);
508
 
544
 
509
 List of origin strings to allow being navigated to. The strings allow wildcards and get matched against _just_ the origin (not the full URL). If the user taps to navigate to a new page but the new page is not in this whitelist, the URL will be handled by the OS. The default whitelisted origins are "http://*" and "https://*".
545
 List of origin strings to allow being navigated to. The strings allow wildcards and get matched against _just_ the origin (not the full URL). If the user taps to navigate to a new page but the new page is not in this whitelist, the URL will be handled by the OS. The default whitelisted origins are "http://*" and "https://*".
510
 
546
 
511
-| Type             | Required |
512
-| ---------------- | -------- |
513
-| array of strings | No       |
547
+| Type             | Required | Platform |
548
+| ---------------- | -------- | -------- |
549
+| array of strings | No       | iOS, Android, macOS |
514
 
550
 
515
 Example:
551
 Example:
516
 
552
 
517
 ```jsx
553
 ```jsx
518
 //only allow URIs that begin with https:// or git://
554
 //only allow URIs that begin with https:// or git://
519
 <WebView
555
 <WebView
520
-  source={{ uri: 'https://facebook.github.io/react-native' }}
556
+  source={{ uri: 'https://reactnative.dev' }}
521
   originWhitelist={['https://*', 'git://*']}
557
   originWhitelist={['https://*', 'git://*']}
522
 />
558
 />
523
 ```
559
 ```
528
 
564
 
529
 Function that returns a view to show if there's an error.
565
 Function that returns a view to show if there's an error.
530
 
566
 
531
-| Type     | Required |
532
-| -------- | -------- |
533
-| function | No       |
567
+| Type     | Required | Platform |
568
+| -------- | -------- | -------- |
569
+| function | No       | iOS, Android, macOS |
534
 
570
 
535
 Example:
571
 Example:
536
 
572
 
537
 ```jsx
573
 ```jsx
538
 <WebView
574
 <WebView
539
-  source={{ uri: 'https://facebook.github.io/react-native' }}
575
+  source={{ uri: 'https://reactnative.dev' }}
540
   renderError={errorName => <Error name={errorName} />}
576
   renderError={errorName => <Error name={errorName} />}
541
 />
577
 />
542
 ```
578
 ```
549
 
585
 
550
 Function that returns a loading indicator. The startInLoadingState prop must be set to true in order to use this prop.
586
 Function that returns a loading indicator. The startInLoadingState prop must be set to true in order to use this prop.
551
 
587
 
552
-| Type     | Required |
553
-| -------- | -------- |
554
-| function | No       |
588
+| Type     | Required | Platform |
589
+| -------- | -------- | -------- |
590
+| function | No       | iOS, Android, macOS |
555
 
591
 
556
 Example:
592
 Example:
557
 
593
 
558
 ```jsx
594
 ```jsx
559
 <WebView
595
 <WebView
560
-  source={{ uri: 'https://facebook.github.io/react-native' }}
596
+  source={{ uri: 'https://reactnative.dev' }}
561
   startInLoadingState={true}
597
   startInLoadingState={true}
562
   renderLoading={() => <Loading />}
598
   renderLoading={() => <Loading />}
563
 />
599
 />
581
 
617
 
582
 On Android, is not called on the first load.
618
 On Android, is not called on the first load.
583
 
619
 
584
-| Type     | Required |
585
-| -------- | -------- |
586
-| function | No       |
620
+| Type     | Required | Platform |
621
+| -------- | -------- | -------- |
622
+| function | No       | iOS, Android, macOS |
587
 
623
 
588
 Example:
624
 Example:
589
 
625
 
590
 ```jsx
626
 ```jsx
591
 <WebView
627
 <WebView
592
-  source={{ uri: 'https://facebook.github.io/react-native' }}
628
+  source={{ uri: 'https://reactnative.dev' }}
593
   onShouldStartLoadWithRequest={request => {
629
   onShouldStartLoadWithRequest={request => {
594
     // Only allow navigating within this website
630
     // Only allow navigating within this website
595
-    return request.url.startsWith('https://facebook.github.io/react-native');
631
+    return request.url.startsWith('https://reactnative.dev');
596
   }}
632
   }}
597
 />
633
 />
598
 ```
634
 ```
617
 
653
 
618
 Boolean value that forces the `WebView` to show the loading view on the first load. This prop must be set to `true` in order for the `renderLoading` prop to work.
654
 Boolean value that forces the `WebView` to show the loading view on the first load. This prop must be set to `true` in order for the `renderLoading` prop to work.
619
 
655
 
620
-| Type | Required |
621
-| ---- | -------- |
622
-| bool | No       |
656
+| Type | Required | Platform |
657
+| ---- | -------- | -------- |
658
+| bool | No       | iOS, Android, macOS |
623
 
659
 
624
 ---
660
 ---
625
 
661
 
635
 
671
 
636
 ```jsx
672
 ```jsx
637
 <WebView
673
 <WebView
638
-  source={{ uri: 'https://facebook.github.io/react-native' }}
674
+  source={{ uri: 'https://reactnative.dev' }}
639
   style={{ marginTop: 20 }}
675
   style={{ marginTop: 20 }}
640
 />
676
 />
641
 ```
677
 ```
654
 
690
 
655
 ```jsx
691
 ```jsx
656
 <WebView
692
 <WebView
657
-  source={{ uri: 'https://facebook.github.io/react-native' }}
693
+  source={{ uri: 'https://reactnative.dev' }}
658
   containerStyle={{ marginTop: 20 }}
694
   containerStyle={{ marginTop: 20 }}
659
 />
695
 />
660
 ```
696
 ```
734
 
770
 
735
 Sets the user-agent for the `WebView`.
771
 Sets the user-agent for the `WebView`.
736
 
772
 
737
-| Type   | Required |
738
-| ------ | -------- |
739
-| string | No       |
773
+| Type   | Required | Platform |
774
+| ------ | -------- | -------- |
775
+| string | No       | iOS, Android, macOS |
740
 
776
 
741
 ---
777
 ---
742
 
778
 
744
 
780
 
745
 Append to the existing user-agent. Setting `userAgent` will override this.
781
 Append to the existing user-agent. Setting `userAgent` will override this.
746
 
782
 
747
-| Type   | Required |
748
-| ------ | -------- |
749
-| string | No       |
783
+| Type   | Required | Platform |
784
+| ------ | -------- | -------- |
785
+| string | No       | iOS, Android, macOS |
750
 
786
 
751
 ```jsx
787
 ```jsx
752
 <WebView
788
 <WebView
753
-  source={{ uri: 'https://facebook.github.io/react-native' }}
789
+  source={{ uri: 'https://reactnative.dev' }}
754
   applicationNameForUserAgent={'DemoApp/1.1.0'}
790
   applicationNameForUserAgent={'DemoApp/1.1.0'}
755
 />
791
 />
756
 // Resulting User-Agent will look like:
792
 // Resulting User-Agent will look like:
884
 
920
 
885
 Boolean value that determines whether a horizontal scroll indicator is shown in the `WebView`. The default value is `true`.
921
 Boolean value that determines whether a horizontal scroll indicator is shown in the `WebView`. The default value is `true`.
886
 
922
 
887
-| Type | Required |
888
-| ---- | -------- |
889
-| bool | No       |
923
+| Type | Required | Platform |
924
+| ---- | -------- | -------- |
925
+| bool | No       | iOS, Android, macOS |
890
 
926
 
891
 ---
927
 ---
892
 
928
 
894
 
930
 
895
 Boolean value that determines whether a vertical scroll indicator is shown in the `WebView`. The default value is `true`.
931
 Boolean value that determines whether a vertical scroll indicator is shown in the `WebView`. The default value is `true`.
896
 
932
 
897
-| Type | Required |
898
-| ---- | -------- |
899
-| bool | No       |
933
+| Type | Required | Platform |
934
+| ---- | -------- | -------- |
935
+| bool | No       | iOS, Android, macOS |
900
 
936
 
901
 ---
937
 ---
902
 
938
 
914
 
950
 
915
 Boolean that sets whether JavaScript running in the context of a file scheme URL should be allowed to access content from other file scheme URLs. The default value is `false`.
951
 Boolean that sets whether JavaScript running in the context of a file scheme URL should be allowed to access content from other file scheme URLs. The default value is `false`.
916
 
952
 
917
-| Type | Required |
918
-| ---- | -------- |
919
-| bool | No       |
953
+| Type | Required | Platform |
954
+| ---- | -------- | -------- |
955
+| bool | No       | iOS, Android, macOS |
920
 
956
 
921
 ---
957
 ---
922
 
958
 
984
 
1020
 
985
 If true, this will be able horizontal swipe gestures. The default value is `false`.
1021
 If true, this will be able horizontal swipe gestures. The default value is `false`.
986
 
1022
 
987
-| Type    | Required | Platform          |
988
-| ------- | -------- | ----------------- |
989
-| boolean | No       | iOS and macOS     |
1023
+| Type    | Required | Platform      |
1024
+| ------- | -------- | ------------- |
1025
+| boolean | No       | iOS and macOS |
990
 
1026
 
991
 ---
1027
 ---
992
 
1028
 
994
 
1030
 
995
 Does not store any data within the lifetime of the WebView.
1031
 Does not store any data within the lifetime of the WebView.
996
 
1032
 
997
-| Type    | Required |
998
-| ------- | -------- |
999
-| boolean | No       |
1033
+| Type    | Required | Platform |
1034
+| ------- | -------- | -------- |
1035
+| boolean | No       | iOS, Android, macOS |
1000
 
1036
 
1001
 ---
1037
 ---
1002
 
1038
 
1024
 
1060
 
1025
 Sets whether WebView should use browser caching.
1061
 Sets whether WebView should use browser caching.
1026
 
1062
 
1027
-| Type    | Required | Default |
1028
-| ------- | -------- | ------- |
1029
-| boolean | No       | true    |
1063
+| Type    | Required | Default | Platform |
1064
+| ------- | -------- | ------- | -------- |
1065
+| boolean | No       | true    | iOS, Android, macOS |
1030
 
1066
 
1031
 ---
1067
 ---
1032
 
1068
 
1061
 
1097
 
1062
 A Boolean value that determines whether pressing on a link displays a preview of the destination for the link. In iOS this property is available on devices that support 3D Touch. In iOS 10 and later, the default value is true; before that, the default value is false.
1098
 A Boolean value that determines whether pressing on a link displays a preview of the destination for the link. In iOS this property is available on devices that support 3D Touch. In iOS 10 and later, the default value is true; before that, the default value is false.
1063
 
1099
 
1064
-| Type    | Required | Platform          |
1065
-| ------- | -------- | ----------------- |
1066
-| boolean | No       | iOS and macOS     |
1100
+| Type    | Required | Platform      |
1101
+| ------- | -------- | ------------- |
1102
+| boolean | No       | iOS and macOS |
1067
 
1103
 
1068
 ---
1104
 ---
1069
 
1105
 
1071
 
1107
 
1072
 Set `true` if shared cookies from `[NSHTTPCookieStorage sharedHTTPCookieStorage]` should used for every load request in the WebView. The default value is `false`. For more on cookies, read the [Guide](Guide.md#Managing-Cookies)
1108
 Set `true` if shared cookies from `[NSHTTPCookieStorage sharedHTTPCookieStorage]` should used for every load request in the WebView. The default value is `false`. For more on cookies, read the [Guide](Guide.md#Managing-Cookies)
1073
 
1109
 
1074
-| Type    | Required | Platform          |
1075
-| ------- | -------- | ----------------- |
1076
-| boolean | No       | iOS and macOS     |
1110
+| Type    | Required | Platform      |
1111
+| ------- | -------- | ------------- |
1112
+| boolean | No       | iOS and macOS |
1077
 
1113
 
1078
 ---
1114
 ---
1079
 
1115
 
1150
 Request the webView to ask for focus. (People working on TV apps might want having a look at this!)
1186
 Request the webView to ask for focus. (People working on TV apps might want having a look at this!)
1151
 
1187
 
1152
 ### `clearFormData()`
1188
 ### `clearFormData()`
1189
+
1153
 (android only)
1190
 (android only)
1154
 
1191
 
1155
 ```javascript
1192
 ```javascript
1156
 clearFormData();
1193
 clearFormData();
1157
 ```
1194
 ```
1158
-Removes the autocomplete popup from the currently focused form field, if present. [developer.android.com reference](https://developer.android.com/reference/android/webkit/WebView.html#clearFormData())
1159
 
1195
 
1196
+Removes the autocomplete popup from the currently focused form field, if present. [developer.android.com reference](<https://developer.android.com/reference/android/webkit/WebView.html#clearFormData()>)
1160
 
1197
 
1161
 ### `clearCache(bool)`
1198
 ### `clearCache(bool)`
1199
+
1162
 (android only)
1200
 (android only)
1201
+
1163
 ```javascript
1202
 ```javascript
1164
 clearCache(true);
1203
 clearCache(true);
1165
 ```
1204
 ```
1166
 
1205
 
1167
-Clears the resource cache. Note that the cache is per-application, so this will clear the cache for all WebViews used. [developer.android.com reference](https://developer.android.com/reference/android/webkit/WebView.html#clearCache(boolean))
1168
-
1206
+Clears the resource cache. Note that the cache is per-application, so this will clear the cache for all WebViews used. [developer.android.com reference](<https://developer.android.com/reference/android/webkit/WebView.html#clearCache(boolean)>)
1169
 
1207
 
1170
 ### `clearHistory()`
1208
 ### `clearHistory()`
1209
+
1171
 (android only)
1210
 (android only)
1211
+
1172
 ```javascript
1212
 ```javascript
1173
 clearHistory();
1213
 clearHistory();
1174
 ```
1214
 ```
1175
 
1215
 
1176
-Tells this WebView to clear its internal back/forward list. [developer.android.com reference](https://developer.android.com/reference/android/webkit/WebView.html#clearHistory())
1216
+Tells this WebView to clear its internal back/forward list. [developer.android.com reference](<https://developer.android.com/reference/android/webkit/WebView.html#clearHistory()>)
1177
 
1217
 
1178
 ## Other Docs
1218
 ## Other Docs
1179
 
1219
 

+ 29
- 0
example/App.tsx View File

7
   View,
7
   View,
8
   Keyboard,
8
   Keyboard,
9
   Button,
9
   Button,
10
+  Platform,
10
 } from 'react-native';
11
 } from 'react-native';
11
 
12
 
12
 import Alerts from './examples/Alerts';
13
 import Alerts from './examples/Alerts';
13
 import Scrolling from './examples/Scrolling';
14
 import Scrolling from './examples/Scrolling';
14
 import Background from './examples/Background';
15
 import Background from './examples/Background';
16
+import Uploads from './examples/Uploads';
17
+import Injection from './examples/Injection';
15
 
18
 
16
 const TESTS = {
19
 const TESTS = {
17
   Alerts: {
20
   Alerts: {
38
       return <Background />;
41
       return <Background />;
39
     },
42
     },
40
   },
43
   },
44
+  Uploads: {
45
+    title: 'Uploads',
46
+    testId: 'uploads',
47
+    description: 'Upload test',
48
+    render() {
49
+      return <Uploads />;
50
+    },
51
+  },
52
+  Injection: {
53
+    title: 'Injection',
54
+    testId: 'injection',
55
+    description: 'Injection test',
56
+    render() {
57
+      return <Injection />;
58
+    },
59
+  },
41
 };
60
 };
42
 
61
 
43
 type Props = {};
62
 type Props = {};
91
             title="Background"
110
             title="Background"
92
             onPress={() => this._changeTest('Background')}
111
             onPress={() => this._changeTest('Background')}
93
           />
112
           />
113
+          <Button
114
+            testID="testType_injection"
115
+            title="Injection"
116
+            onPress={() => this._changeTest('Injection')}
117
+          />
118
+          {Platform.OS === 'android' && <Button
119
+            testID="testType_uploads"
120
+            title="Uploads"
121
+            onPress={() => this._changeTest('Uploads')}
122
+          />}
94
         </View>
123
         </View>
95
 
124
 
96
         {restarting ? null : (
125
         {restarting ? null : (

+ 2
- 2
example/android/app/build.gradle View File

18
  *   // the entry file for bundle generation
18
  *   // the entry file for bundle generation
19
  *   entryFile: "index.android.js",
19
  *   entryFile: "index.android.js",
20
  *
20
  *
21
- *   // https://facebook.github.io/react-native/docs/performance#enable-the-ram-format
21
+ *   // https://reactnative.dev/docs/performance#enable-the-ram-format
22
  *   bundleCommand: "ram-bundle",
22
  *   bundleCommand: "ram-bundle",
23
  *
23
  *
24
  *   // whether to bundle JS and assets in debug mode
24
  *   // whether to bundle JS and assets in debug mode
158
         }
158
         }
159
         release {
159
         release {
160
             // Caution! In production, you need to generate your own keystore file.
160
             // Caution! In production, you need to generate your own keystore file.
161
-            // see https://facebook.github.io/react-native/docs/signed-apk-android.
161
+            // see https://reactnative.dev/docs/signed-apk-android.
162
             signingConfig signingConfigs.debug
162
             signingConfig signingConfigs.debug
163
             minifyEnabled enableProguardInReleaseBuilds
163
             minifyEnabled enableProguardInReleaseBuilds
164
             proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
164
             proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"

+ 1
- 0
example/android/app/src/main/AndroidManifest.xml View File

2
   package="com.example">
2
   package="com.example">
3
 
3
 
4
     <uses-permission android:name="android.permission.INTERNET" />
4
     <uses-permission android:name="android.permission.INTERNET" />
5
+    <uses-permission android:name="android.permission.CAMERA" />
5
 
6
 
6
     <application
7
     <application
7
       android:name=".MainApplication"
8
       android:name=".MainApplication"

+ 160
- 0
example/examples/Injection.tsx View File

1
+import React, {Component} from 'react';
2
+import {Text, View, ScrollView} from 'react-native';
3
+
4
+import WebView from 'react-native-webview';
5
+
6
+// const HTML = `
7
+// <!DOCTYPE html>
8
+// <html>
9
+//   <head>
10
+//       <meta charset="utf-8">
11
+//       <meta name="viewport" content="width=device-width, initial-scale=1">
12
+//       <title>iframe test</title>
13
+//   </head>
14
+//   <body>
15
+//     <p style="">beforeContentLoaded on the top frame <span id="before_failed" style="display: inline-block;">failed</span><span id="before_succeeded" style="display: none;">succeeded</span>!</p>
16
+//     <p style="">afterContentLoaded on the top frame <span id="after_failed" style="display: inline-block;">failed</span><span id="after_succeeded" style="display: none;">succeeded</span>!</p>
17
+//     <iframe src="https://birchlabs.co.uk/linguabrowse/infopages/obsol/iframe.html?v=1" name="iframe_0" style="width: 100%; height: 25px;"></iframe>
18
+//     <iframe src="https://birchlabs.co.uk/linguabrowse/infopages/obsol/iframe2.html?v=1" name="iframe_1" style="width: 100%; height: 25px;"></iframe>
19
+//     <iframe src="https://www.ebay.co.uk" name="iframe_2" style="width: 100%; height: 25px;"></iframe>
20
+//   </body>
21
+// </html>
22
+// `;
23
+
24
+type Props = {};
25
+type State = {
26
+  backgroundColor: string,
27
+};
28
+
29
+export default class Injection extends Component<Props, State> {
30
+  state = {
31
+    backgroundColor: '#FF00FF00'
32
+  };
33
+
34
+  render() {
35
+    return (
36
+      <ScrollView>
37
+        <View style={{ }}>
38
+          <View style={{ height: 300 }}>
39
+            <WebView
40
+              /**
41
+               * This HTML is a copy of a multi-frame JS injection test that I had lying around.
42
+               * @see https://birchlabs.co.uk/linguabrowse/infopages/obsol/iframeTest.html
43
+               */
44
+              // source={{ html: HTML }}
45
+              source={{ uri: "https://birchlabs.co.uk/linguabrowse/infopages/obsol/rnw_iframe_test.html" }}
46
+              automaticallyAdjustContentInsets={false}
47
+              style={{backgroundColor:'#00000000'}}
48
+              
49
+              /* Must be populated in order for `messagingEnabled` to be `true` to activate the
50
+               * JS injection user scripts, consistent with current behaviour. This is undesirable,
51
+               * so needs addressing in a follow-up PR. */
52
+              onMessage={() => {}}
53
+
54
+              /* We set this property in each frame */
55
+              injectedJavaScriptBeforeContentLoaded={`
56
+              console.log("executing injectedJavaScriptBeforeContentLoaded...");
57
+              if(typeof window.top.injectedIframesBeforeContentLoaded === "undefined"){
58
+                window.top.injectedIframesBeforeContentLoaded = [];
59
+              }
60
+              window.self.colourToUse = "orange";
61
+              if(window.self === window.top){
62
+                console.log("Was window.top. window.frames.length is:", window.frames.length);
63
+                window.self.numberOfFramesAtBeforeContentLoaded = window.frames.length;
64
+                function declareSuccessOfBeforeContentLoaded(head){
65
+                  var style = window.self.document.createElement('style');
66
+                  style.type = 'text/css';
67
+                  style.innerHTML = "#before_failed { display: none !important; }#before_succeeded { display: inline-block !important; }";
68
+                  head.appendChild(style);
69
+                }
70
+
71
+                const head = (window.self.document.head || window.self.document.getElementsByTagName('head')[0]);
72
+
73
+                if(head){
74
+                  declareSuccessOfBeforeContentLoaded(head);
75
+                } else {
76
+                  window.self.document.addEventListener("DOMContentLoaded", function (event) {
77
+                    const head = (window.self.document.head || window.self.document.getElementsByTagName('head')[0]);
78
+                    declareSuccessOfBeforeContentLoaded(head);
79
+                  });
80
+                }
81
+              } else {
82
+                window.top.injectedIframesBeforeContentLoaded.push(window.self.name);
83
+                console.log("wasn't window.top.");
84
+                console.log("wasn't window.top. Still going...");
85
+              }
86
+              `}
87
+              
88
+              injectedJavaScriptForMainFrameOnly={false}
89
+
90
+              /* We read the colourToUse property in each frame to recolour each frame */
91
+              injectedJavaScript={`
92
+              console.log("executing injectedJavaScript...");
93
+              if(typeof window.top.injectedIframesAfterContentLoaded === "undefined"){
94
+                window.top.injectedIframesAfterContentLoaded = [];
95
+              }
96
+
97
+              if(window.self.colourToUse){
98
+                window.self.document.body.style.backgroundColor = window.self.colourToUse;
99
+              } else {
100
+                window.self.document.body.style.backgroundColor = "cyan";
101
+              }
102
+
103
+              if(window.self === window.top){
104
+                function declareSuccessOfAfterContentLoaded(head){
105
+                  var style = window.self.document.createElement('style');
106
+                  style.type = 'text/css';
107
+                  style.innerHTML = "#after_failed { display: none !important; }#after_succeeded { display: inline-block !important; }";
108
+                  head.appendChild(style);
109
+                }
110
+
111
+                declareSuccessOfAfterContentLoaded(window.self.document.head || window.self.document.getElementsByTagName('head')[0]);
112
+
113
+                // var numberOfFramesAtBeforeContentLoadedEle = document.createElement('p');
114
+                // numberOfFramesAtBeforeContentLoadedEle.textContent = "Number of iframes upon the main frame's beforeContentLoaded: " +
115
+                // window.self.numberOfFramesAtBeforeContentLoaded;
116
+
117
+                // var numberOfFramesAtAfterContentLoadedEle = document.createElement('p');
118
+                // numberOfFramesAtAfterContentLoadedEle.textContent = "Number of iframes upon the main frame's afterContentLoaded: " + window.frames.length;
119
+                // numberOfFramesAtAfterContentLoadedEle.id = "numberOfFramesAtAfterContentLoadedEle";
120
+
121
+                var namedFramesAtBeforeContentLoadedEle = document.createElement('p');
122
+                namedFramesAtBeforeContentLoadedEle.textContent = "Names of iframes that called beforeContentLoaded: " + JSON.stringify(window.top.injectedIframesBeforeContentLoaded);
123
+                namedFramesAtBeforeContentLoadedEle.id = "namedFramesAtBeforeContentLoadedEle";
124
+
125
+                var namedFramesAtAfterContentLoadedEle = document.createElement('p');
126
+                namedFramesAtAfterContentLoadedEle.textContent = "Names of iframes that called afterContentLoaded: " + JSON.stringify(window.top.injectedIframesAfterContentLoaded);
127
+                namedFramesAtAfterContentLoadedEle.id = "namedFramesAtAfterContentLoadedEle";
128
+
129
+                // document.body.appendChild(numberOfFramesAtBeforeContentLoadedEle);
130
+                // document.body.appendChild(numberOfFramesAtAfterContentLoadedEle);
131
+                document.body.appendChild(namedFramesAtBeforeContentLoadedEle);
132
+                document.body.appendChild(namedFramesAtAfterContentLoadedEle);
133
+              } else {
134
+                window.top.injectedIframesAfterContentLoaded.push(window.self.name);
135
+                window.top.document.getElementById('namedFramesAtAfterContentLoadedEle').textContent = "Names of iframes that called afterContentLoaded: " + JSON.stringify(window.top.injectedIframesAfterContentLoaded);
136
+              }
137
+              `}
138
+            />
139
+          </View>
140
+        </View>
141
+        <Text>This test presents three iframes: iframe_0 (yellow); iframe_1 (pink); and iframe_2 (transparent, because its 'X-Frame-Options' is set to 'SAMEORIGIN').</Text>
142
+        <Text>Before injection, the main frame's background is the browser's default value (transparent or white) and each frame has its natural colour.</Text>
143
+        {/*<Text>1a) At injection time "beforeContentLoaded", a variable will be set in each frame to set 'orange' as the "colour to be used".</Text>*/}
144
+        {/*<Text>1b) Also upon "beforeContentLoaded", a style element to change the text "beforeContentLoaded failed" -> "beforeContentLoaded succeeded" will be applied as soon as the head has loaded.</Text>*/}
145
+        {/*<Text>2a) At injection time "afterContentLoaded", that variable will be read – if present, the colour orange will be injected into all frames. Otherwise, cyan.</Text>*/}
146
+        {/*<Text>2b) Also upon "afterContentLoaded", a style element to change the text "afterContentLoaded failed" -> "afterContentLoaded succeeded" will be applied as soon as the head has loaded.</Text>*/}
147
+        <Text>✅ If the main frame becomes orange, then top-frame injection both beforeContentLoaded and afterContentLoaded is supported.</Text>
148
+        <Text>✅ If iframe_0, and iframe_1 become orange, then multi-frame injection beforeContentLoaded and afterContentLoaded is supported.</Text>
149
+        <Text>✅ If the two texts say "beforeContentLoaded on the top frame succeeded!" and "afterContentLoaded on the top frame succeeded!", then both injection times are supported at least on the main frame.</Text>
150
+        <Text>⚠️ If either of the two iframes become coloured cyan, then for that given frame, JS injection succeeded after the content loaded, but didn't occur before the content loaded - please note that for iframes, this may not be a test failure, as it is not clear whether we would expect iframes to support an injection time of beforeContentLoaded anyway.</Text>
151
+        <Text>⚠️ If "Names of iframes that called beforeContentLoaded: " is [], then see above.</Text>
152
+        <Text>❌ If "Names of iframes that called afterContentLoaded: " is [], then afterContentLoaded is not supported in iframes.</Text>
153
+        <Text>❌ If the main frame becomes coloured cyan, then JS injection succeeded after the content loaded, but didn't occur before the content loaded.</Text>
154
+        <Text>❌ If the text "beforeContentLoaded on the top frame failed" remains unchanged, then JS injection has failed on the main frame before the content loaded.</Text>
155
+        <Text>❌ If the text "afterContentLoaded on the top frame failed" remains unchanged, then JS injection has failed on the main frame after the content loaded.</Text>
156
+        <Text>❌ If the iframes remain their original colours (yellow and pink), then multi-frame injection is not supported at all.</Text>
157
+      </ScrollView>
158
+    );
159
+  }
160
+}

+ 69
- 0
example/examples/Uploads.tsx View File

1
+import React, {Component} from 'react';
2
+import {Button, Linking, Text, View} from 'react-native';
3
+
4
+import WebView from 'react-native-webview';
5
+
6
+const HTML = `
7
+<!DOCTYPE html>\n
8
+<html>
9
+  <head>
10
+    <title>Uploads</title>
11
+    <meta http-equiv="content-type" content="text/html; charset=utf-8">
12
+    <meta name="viewport" content="width=320, user-scalable=no">
13
+    <style type="text/css">
14
+      body {
15
+        margin: 0;
16
+        padding: 0;
17
+        font: 62.5% arial, sans-serif;
18
+        background: #ccc;
19
+      }
20
+    </style>
21
+  </head>
22
+  <body>
23
+    <p>
24
+      <label for="images-only">Images only file upload</label>
25
+      <input name="images-only" type="file" accept="image/*">
26
+    </p>
27
+    <p>
28
+      <label for="video-only">Video only file upload</label>
29
+      <input name="video-only" type="file" accept="video/*">
30
+    </p>
31
+    <p>
32
+      <label for="any-file">Any file upload</label>
33
+      <input name="any-file" type="file">
34
+    </p>
35
+  </body>
36
+</html>
37
+`;
38
+
39
+type Props = {};
40
+type State = {};
41
+
42
+export default class Uploads extends Component<Props, State> {
43
+  state = {};
44
+
45
+  render() {
46
+    return (
47
+      <View>
48
+        <View style={{ height: 120 }}>
49
+          <WebView
50
+            source={{html: HTML}}
51
+            automaticallyAdjustContentInsets={false}
52
+          />
53
+        </View>
54
+        <Text>
55
+            Android limitation: If the file input should show camera options for the user,
56
+            and the app has the ability to request the camera permission, then the user must
57
+            grant permission first in order to see the options. Since this example app does
58
+            have the permission declared, you must allow it in settings to be able to see
59
+            camera options. If your app does not have the camera permission declared, then
60
+            there is no restriction to showing the camera options.
61
+        </Text>
62
+        <Button
63
+          title="Open settings"
64
+          onPress={() => Linking.openSettings()}
65
+        />
66
+      </View>
67
+    );
68
+  }
69
+}

+ 2
- 2
example/ios/Podfile.lock View File

182
     - React-cxxreact (= 0.61.5)
182
     - React-cxxreact (= 0.61.5)
183
     - React-jsi (= 0.61.5)
183
     - React-jsi (= 0.61.5)
184
   - React-jsinspector (0.61.5)
184
   - React-jsinspector (0.61.5)
185
-  - react-native-webview (8.0.6):
185
+  - react-native-webview (8.2.0):
186
     - React
186
     - React
187
   - React-RCTActionSheet (0.61.5):
187
   - React-RCTActionSheet (0.61.5):
188
     - React-Core/RCTActionSheetHeaders (= 0.61.5)
188
     - React-Core/RCTActionSheetHeaders (= 0.61.5)
326
   React-jsi: cb2cd74d7ccf4cffb071a46833613edc79cdf8f7
326
   React-jsi: cb2cd74d7ccf4cffb071a46833613edc79cdf8f7
327
   React-jsiexecutor: d5525f9ed5f782fdbacb64b9b01a43a9323d2386
327
   React-jsiexecutor: d5525f9ed5f782fdbacb64b9b01a43a9323d2386
328
   React-jsinspector: fa0ecc501688c3c4c34f28834a76302233e29dc0
328
   React-jsinspector: fa0ecc501688c3c4c34f28834a76302233e29dc0
329
-  react-native-webview: 222d83c9c489e09b5d3541519110a637490ad4fa
329
+  react-native-webview: 1db33907230d0eb344964d6f3bb56b9ee77e25a4
330
   React-RCTActionSheet: 600b4d10e3aea0913b5a92256d2719c0cdd26d76
330
   React-RCTActionSheet: 600b4d10e3aea0913b5a92256d2719c0cdd26d76
331
   React-RCTAnimation: 791a87558389c80908ed06cc5dfc5e7920dfa360
331
   React-RCTAnimation: 791a87558389c80908ed06cc5dfc5e7920dfa360
332
   React-RCTBlob: d89293cc0236d9cb0933d85e430b0bbe81ad1d72
332
   React-RCTBlob: d89293cc0236d9cb0933d85e430b0bbe81ad1d72

+ 92
- 0
example/windows/.gitignore View File

1
+*AppPackages*
2
+*BundleArtifacts*
3
+
4
+#OS junk files
5
+[Tt]humbs.db
6
+*.DS_Store
7
+
8
+#Visual Studio files
9
+*.[Oo]bj
10
+*.user
11
+*.aps
12
+*.pch
13
+*.vspscc
14
+*.vssscc
15
+*_i.c
16
+*_p.c
17
+*.ncb
18
+*.suo
19
+*.tlb
20
+*.tlh
21
+*.bak
22
+*.[Cc]ache
23
+*.ilk
24
+*.log
25
+*.lib
26
+*.sbr
27
+*.sdf
28
+*.opensdf
29
+*.opendb
30
+*.unsuccessfulbuild
31
+ipch/
32
+[Oo]bj/
33
+[Bb]in
34
+[Dd]ebug*/
35
+[Rr]elease*/
36
+Ankh.NoLoad
37
+
38
+# Visual C++ cache files
39
+ipch/
40
+*.aps
41
+*.ncb
42
+*.opendb
43
+*.opensdf
44
+*.sdf
45
+*.cachefile
46
+*.VC.db
47
+*.VC.VC.opendb
48
+
49
+#MonoDevelop
50
+*.pidb
51
+*.userprefs
52
+
53
+#Tooling
54
+_ReSharper*/
55
+*.resharper
56
+[Tt]est[Rr]esult*
57
+*.sass-cache
58
+
59
+#Project files
60
+[Bb]uild/
61
+
62
+#Subversion files
63
+.svn
64
+
65
+# Office Temp Files
66
+~$*
67
+
68
+# vim Temp Files
69
+*~
70
+
71
+#NuGet
72
+packages/
73
+*.nupkg
74
+
75
+#ncrunch
76
+*ncrunch*
77
+*crunch*.local.xml
78
+
79
+# visual studio database projects
80
+*.dbmdl
81
+
82
+#Test files
83
+*.testsettings
84
+
85
+#Other files
86
+*.DotSettings
87
+.vs/
88
+*project.lock.json
89
+
90
+#Files generated by the VS build
91
+**/Generated Files/**
92
+

+ 227
- 0
example/windows/WebViewWindows.sln View File

1
+
2
+Microsoft Visual Studio Solution File, Format Version 12.00
3
+# Visual Studio Version 16
4
+VisualStudioVersion = 16.0.29215.179
5
+MinimumVisualStudioVersion = 10.0.40219.1
6
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WebViewWindows", "WebViewWindows\WebViewWindows.vcxproj", "{AC6C354F-8C80-47EA-9E40-996ABE271843}"
7
+	ProjectSection(ProjectDependencies) = postProject
8
+		{F7D32BD0-2749-483E-9A0D-1635EF7E3136} = {F7D32BD0-2749-483E-9A0D-1635EF7E3136}
9
+	EndProjectSection
10
+EndProject
11
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Folly", "..\..\node_modules\react-native-windows\Folly\Folly.vcxproj", "{A990658C-CE31-4BCC-976F-0FC6B1AF693D}"
12
+EndProject
13
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ReactCommon", "..\..\node_modules\react-native-windows\ReactCommon\ReactCommon.vcxproj", "{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}"
14
+	ProjectSection(ProjectDependencies) = postProject
15
+		{A990658C-CE31-4BCC-976F-0FC6B1AF693D} = {A990658C-CE31-4BCC-976F-0FC6B1AF693D}
16
+	EndProjectSection
17
+EndProject
18
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ReactWindowsCore", "..\..\node_modules\react-native-windows\ReactWindowsCore\ReactWindowsCore.vcxproj", "{11C084A3-A57C-4296-A679-CAC17B603144}"
19
+	ProjectSection(ProjectDependencies) = postProject
20
+		{A990658C-CE31-4BCC-976F-0FC6B1AF693D} = {A990658C-CE31-4BCC-976F-0FC6B1AF693D}
21
+	EndProjectSection
22
+EndProject
23
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Chakra", "..\..\node_modules\react-native-windows\Chakra\Chakra.vcxitems", "{C38970C0-5FBF-4D69-90D8-CBAC225AE895}"
24
+EndProject
25
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.ReactNative", "..\..\node_modules\react-native-windows\Microsoft.ReactNative\Microsoft.ReactNative.vcxproj", "{F7D32BD0-2749-483E-9A0D-1635EF7E3136}"
26
+EndProject
27
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JSI.Shared", "..\..\node_modules\react-native-windows\JSI\Shared\JSI.Shared.vcxitems", "{0CC28589-39E4-4288-B162-97B959F8B843}"
28
+EndProject
29
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JSI.Universal", "..\..\node_modules\react-native-windows\JSI\Universal\JSI.Universal.vcxproj", "{A62D504A-16B8-41D2-9F19-E2E86019E5E4}"
30
+EndProject
31
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.ReactNative.Cxx", "..\..\node_modules\react-native-windows\Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems", "{DA8B35B3-DA00-4B02-BDE6-6A397B3FD46B}"
32
+EndProject
33
+Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Microsoft.ReactNative.SharedManaged", "..\..\node_modules\react-native-windows\Microsoft.ReactNative.SharedManaged\Microsoft.ReactNative.SharedManaged.shproj", "{67A1076F-7790-4203-86EA-4402CCB5E782}"
34
+EndProject
35
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Common", "..\..\node_modules\react-native-windows\Common\Common.vcxproj", "{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}"
36
+EndProject
37
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ReactNative", "ReactNative", "{5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}"
38
+EndProject
39
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Shared", "..\..\node_modules\react-native-windows\Shared\Shared.vcxitems", "{2049DBE9-8D13-42C9-AE4B-413AE38FFFD0}"
40
+EndProject
41
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Mso", "..\..\node_modules\react-native-windows\Mso\Mso.vcxitems", "{84E05BFA-CBAF-4F0D-BFB6-4CE85742A57E}"
42
+EndProject
43
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ReactNativeWebView", "..\..\windows\ReactNativeWebView\ReactNativeWebView.vcxproj", "{729D9AF8-CD9E-4427-9F6C-FB757E287729}"
44
+EndProject
45
+Global
46
+	GlobalSection(SharedMSBuildProjectFiles) = preSolution
47
+		..\..\node_modules\react-native-windows\JSI\Shared\JSI.Shared.vcxitems*{0cc28589-39e4-4288-b162-97b959f8b843}*SharedItemsImports = 9
48
+		..\..\node_modules\react-native-windows\Shared\Shared.vcxitems*{2049dbe9-8d13-42c9-ae4b-413ae38fffd0}*SharedItemsImports = 9
49
+		..\..\node_modules\react-native-windows\Microsoft.ReactNative.SharedManaged\Microsoft.ReactNative.SharedManaged.projitems*{67a1076f-7790-4203-86ea-4402ccb5e782}*SharedItemsImports = 13
50
+		..\..\node_modules\react-native-windows\Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems*{729d9af8-cd9e-4427-9f6c-fb757e287729}*SharedItemsImports = 4
51
+		..\..\node_modules\react-native-windows\Mso\Mso.vcxitems*{84e05bfa-cbaf-4f0d-bfb6-4ce85742a57e}*SharedItemsImports = 9
52
+		..\..\node_modules\react-native-windows\JSI\Shared\JSI.Shared.vcxitems*{a62d504a-16b8-41d2-9f19-e2e86019e5e4}*SharedItemsImports = 4
53
+		..\..\node_modules\react-native-windows\Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems*{ac6c354f-8c80-47ea-9e40-996abe271843}*SharedItemsImports = 4
54
+		..\..\node_modules\react-native-windows\Chakra\Chakra.vcxitems*{c38970c0-5fbf-4d69-90d8-cbac225ae895}*SharedItemsImports = 9
55
+		..\..\node_modules\react-native-windows\Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems*{da8b35b3-da00-4b02-bde6-6a397b3fd46b}*SharedItemsImports = 9
56
+		..\..\node_modules\react-native-windows\Chakra\Chakra.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4
57
+		..\..\node_modules\react-native-windows\JSI\Shared\JSI.Shared.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4
58
+		..\..\node_modules\react-native-windows\Mso\Mso.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4
59
+		..\..\node_modules\react-native-windows\Shared\Shared.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4
60
+	EndGlobalSection
61
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
62
+		Debug|ARM = Debug|ARM
63
+		Debug|ARM64 = Debug|ARM64
64
+		Debug|x64 = Debug|x64
65
+		Debug|x86 = Debug|x86
66
+		Release|ARM = Release|ARM
67
+		Release|ARM64 = Release|ARM64
68
+		Release|x64 = Release|x64
69
+		Release|x86 = Release|x86
70
+	EndGlobalSection
71
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
72
+		{AC6C354F-8C80-47EA-9E40-996ABE271843}.Debug|ARM.ActiveCfg = Debug|ARM
73
+		{AC6C354F-8C80-47EA-9E40-996ABE271843}.Debug|ARM.Build.0 = Debug|ARM
74
+		{AC6C354F-8C80-47EA-9E40-996ABE271843}.Debug|ARM.Deploy.0 = Debug|ARM
75
+		{AC6C354F-8C80-47EA-9E40-996ABE271843}.Debug|ARM64.ActiveCfg = Debug|ARM64
76
+		{AC6C354F-8C80-47EA-9E40-996ABE271843}.Debug|ARM64.Build.0 = Debug|ARM64
77
+		{AC6C354F-8C80-47EA-9E40-996ABE271843}.Debug|ARM64.Deploy.0 = Debug|ARM64
78
+		{AC6C354F-8C80-47EA-9E40-996ABE271843}.Debug|x64.ActiveCfg = Debug|x64
79
+		{AC6C354F-8C80-47EA-9E40-996ABE271843}.Debug|x64.Build.0 = Debug|x64
80
+		{AC6C354F-8C80-47EA-9E40-996ABE271843}.Debug|x64.Deploy.0 = Debug|x64
81
+		{AC6C354F-8C80-47EA-9E40-996ABE271843}.Debug|x86.ActiveCfg = Debug|Win32
82
+		{AC6C354F-8C80-47EA-9E40-996ABE271843}.Debug|x86.Build.0 = Debug|Win32
83
+		{AC6C354F-8C80-47EA-9E40-996ABE271843}.Debug|x86.Deploy.0 = Debug|Win32
84
+		{AC6C354F-8C80-47EA-9E40-996ABE271843}.Release|ARM.ActiveCfg = Release|ARM
85
+		{AC6C354F-8C80-47EA-9E40-996ABE271843}.Release|ARM.Build.0 = Release|ARM
86
+		{AC6C354F-8C80-47EA-9E40-996ABE271843}.Release|ARM.Deploy.0 = Release|ARM
87
+		{AC6C354F-8C80-47EA-9E40-996ABE271843}.Release|ARM64.ActiveCfg = Release|ARM64
88
+		{AC6C354F-8C80-47EA-9E40-996ABE271843}.Release|ARM64.Build.0 = Release|ARM64
89
+		{AC6C354F-8C80-47EA-9E40-996ABE271843}.Release|ARM64.Deploy.0 = Release|ARM64
90
+		{AC6C354F-8C80-47EA-9E40-996ABE271843}.Release|x64.ActiveCfg = Release|x64
91
+		{AC6C354F-8C80-47EA-9E40-996ABE271843}.Release|x64.Build.0 = Release|x64
92
+		{AC6C354F-8C80-47EA-9E40-996ABE271843}.Release|x64.Deploy.0 = Release|x64
93
+		{AC6C354F-8C80-47EA-9E40-996ABE271843}.Release|x86.ActiveCfg = Release|Win32
94
+		{AC6C354F-8C80-47EA-9E40-996ABE271843}.Release|x86.Build.0 = Release|Win32
95
+		{AC6C354F-8C80-47EA-9E40-996ABE271843}.Release|x86.Deploy.0 = Release|Win32
96
+		{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|ARM.ActiveCfg = Debug|ARM
97
+		{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|ARM.Build.0 = Debug|ARM
98
+		{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|ARM64.ActiveCfg = Debug|ARM64
99
+		{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|ARM64.Build.0 = Debug|ARM64
100
+		{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|x64.ActiveCfg = Debug|x64
101
+		{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|x64.Build.0 = Debug|x64
102
+		{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|x86.ActiveCfg = Debug|Win32
103
+		{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|x86.Build.0 = Debug|Win32
104
+		{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|ARM.ActiveCfg = Release|ARM
105
+		{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|ARM.Build.0 = Release|ARM
106
+		{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|ARM64.ActiveCfg = Release|ARM64
107
+		{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|ARM64.Build.0 = Release|ARM64
108
+		{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x64.ActiveCfg = Release|x64
109
+		{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x64.Build.0 = Release|x64
110
+		{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x86.ActiveCfg = Release|Win32
111
+		{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x86.Build.0 = Release|Win32
112
+		{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM.ActiveCfg = Debug|ARM
113
+		{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM.Build.0 = Debug|ARM
114
+		{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM64.ActiveCfg = Debug|ARM64
115
+		{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM64.Build.0 = Debug|ARM64
116
+		{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x64.ActiveCfg = Debug|x64
117
+		{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x64.Build.0 = Debug|x64
118
+		{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x86.ActiveCfg = Debug|Win32
119
+		{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x86.Build.0 = Debug|Win32
120
+		{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|ARM.ActiveCfg = Release|ARM
121
+		{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|ARM.Build.0 = Release|ARM
122
+		{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|ARM64.ActiveCfg = Release|ARM64
123
+		{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|ARM64.Build.0 = Release|ARM64
124
+		{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|x64.ActiveCfg = Release|x64
125
+		{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|x64.Build.0 = Release|x64
126
+		{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|x86.ActiveCfg = Release|Win32
127
+		{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|x86.Build.0 = Release|Win32
128
+		{11C084A3-A57C-4296-A679-CAC17B603144}.Debug|ARM.ActiveCfg = Debug|ARM
129
+		{11C084A3-A57C-4296-A679-CAC17B603144}.Debug|ARM.Build.0 = Debug|ARM
130
+		{11C084A3-A57C-4296-A679-CAC17B603144}.Debug|ARM64.ActiveCfg = Debug|ARM64
131
+		{11C084A3-A57C-4296-A679-CAC17B603144}.Debug|ARM64.Build.0 = Debug|ARM64
132
+		{11C084A3-A57C-4296-A679-CAC17B603144}.Debug|x64.ActiveCfg = Debug|x64
133
+		{11C084A3-A57C-4296-A679-CAC17B603144}.Debug|x64.Build.0 = Debug|x64
134
+		{11C084A3-A57C-4296-A679-CAC17B603144}.Debug|x86.ActiveCfg = Debug|Win32
135
+		{11C084A3-A57C-4296-A679-CAC17B603144}.Debug|x86.Build.0 = Debug|Win32
136
+		{11C084A3-A57C-4296-A679-CAC17B603144}.Release|ARM.ActiveCfg = Release|ARM
137
+		{11C084A3-A57C-4296-A679-CAC17B603144}.Release|ARM.Build.0 = Release|ARM
138
+		{11C084A3-A57C-4296-A679-CAC17B603144}.Release|ARM64.ActiveCfg = Release|ARM64
139
+		{11C084A3-A57C-4296-A679-CAC17B603144}.Release|ARM64.Build.0 = Release|ARM64
140
+		{11C084A3-A57C-4296-A679-CAC17B603144}.Release|x64.ActiveCfg = Release|x64
141
+		{11C084A3-A57C-4296-A679-CAC17B603144}.Release|x64.Build.0 = Release|x64
142
+		{11C084A3-A57C-4296-A679-CAC17B603144}.Release|x86.ActiveCfg = Release|Win32
143
+		{11C084A3-A57C-4296-A679-CAC17B603144}.Release|x86.Build.0 = Release|Win32
144
+		{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|ARM.ActiveCfg = Debug|ARM
145
+		{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|ARM.Build.0 = Debug|ARM
146
+		{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|ARM64.ActiveCfg = Debug|ARM64
147
+		{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|ARM64.Build.0 = Debug|ARM64
148
+		{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|x64.ActiveCfg = Debug|x64
149
+		{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|x64.Build.0 = Debug|x64
150
+		{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|x86.ActiveCfg = Debug|Win32
151
+		{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|x86.Build.0 = Debug|Win32
152
+		{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|ARM.ActiveCfg = Release|ARM
153
+		{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|ARM.Build.0 = Release|ARM
154
+		{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|ARM64.ActiveCfg = Release|ARM64
155
+		{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|ARM64.Build.0 = Release|ARM64
156
+		{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|x64.ActiveCfg = Release|x64
157
+		{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|x64.Build.0 = Release|x64
158
+		{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|x86.ActiveCfg = Release|Win32
159
+		{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|x86.Build.0 = Release|Win32
160
+		{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|ARM.ActiveCfg = Debug|ARM
161
+		{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|ARM.Build.0 = Debug|ARM
162
+		{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|ARM64.ActiveCfg = Debug|ARM64
163
+		{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|ARM64.Build.0 = Debug|ARM64
164
+		{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|x64.ActiveCfg = Debug|x64
165
+		{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|x64.Build.0 = Debug|x64
166
+		{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|x86.ActiveCfg = Debug|Win32
167
+		{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|x86.Build.0 = Debug|Win32
168
+		{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|ARM.ActiveCfg = Release|ARM
169
+		{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|ARM.Build.0 = Release|ARM
170
+		{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|ARM64.ActiveCfg = Release|ARM64
171
+		{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|ARM64.Build.0 = Release|ARM64
172
+		{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|x64.ActiveCfg = Release|x64
173
+		{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|x64.Build.0 = Release|x64
174
+		{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|x86.ActiveCfg = Release|Win32
175
+		{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|x86.Build.0 = Release|Win32
176
+		{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|ARM.ActiveCfg = Debug|ARM
177
+		{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|ARM.Build.0 = Debug|ARM
178
+		{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|ARM64.ActiveCfg = Debug|ARM64
179
+		{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|ARM64.Build.0 = Debug|ARM64
180
+		{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|x64.ActiveCfg = Debug|x64
181
+		{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|x64.Build.0 = Debug|x64
182
+		{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|x86.ActiveCfg = Debug|Win32
183
+		{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|x86.Build.0 = Debug|Win32
184
+		{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|ARM.ActiveCfg = Release|ARM
185
+		{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|ARM.Build.0 = Release|ARM
186
+		{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|ARM64.ActiveCfg = Release|ARM64
187
+		{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|ARM64.Build.0 = Release|ARM64
188
+		{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x64.ActiveCfg = Release|x64
189
+		{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x64.Build.0 = Release|x64
190
+		{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x86.ActiveCfg = Release|Win32
191
+		{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x86.Build.0 = Release|Win32
192
+		{729D9AF8-CD9E-4427-9F6C-FB757E287729}.Debug|ARM.ActiveCfg = Debug|ARM
193
+		{729D9AF8-CD9E-4427-9F6C-FB757E287729}.Debug|ARM.Build.0 = Debug|ARM
194
+		{729D9AF8-CD9E-4427-9F6C-FB757E287729}.Debug|ARM64.ActiveCfg = Debug|Win32
195
+		{729D9AF8-CD9E-4427-9F6C-FB757E287729}.Debug|x64.ActiveCfg = Debug|x64
196
+		{729D9AF8-CD9E-4427-9F6C-FB757E287729}.Debug|x64.Build.0 = Debug|x64
197
+		{729D9AF8-CD9E-4427-9F6C-FB757E287729}.Debug|x86.ActiveCfg = Debug|Win32
198
+		{729D9AF8-CD9E-4427-9F6C-FB757E287729}.Debug|x86.Build.0 = Debug|Win32
199
+		{729D9AF8-CD9E-4427-9F6C-FB757E287729}.Release|ARM.ActiveCfg = Release|ARM
200
+		{729D9AF8-CD9E-4427-9F6C-FB757E287729}.Release|ARM.Build.0 = Release|ARM
201
+		{729D9AF8-CD9E-4427-9F6C-FB757E287729}.Release|ARM64.ActiveCfg = Release|Win32
202
+		{729D9AF8-CD9E-4427-9F6C-FB757E287729}.Release|x64.ActiveCfg = Release|x64
203
+		{729D9AF8-CD9E-4427-9F6C-FB757E287729}.Release|x64.Build.0 = Release|x64
204
+		{729D9AF8-CD9E-4427-9F6C-FB757E287729}.Release|x86.ActiveCfg = Release|Win32
205
+		{729D9AF8-CD9E-4427-9F6C-FB757E287729}.Release|x86.Build.0 = Release|Win32
206
+	EndGlobalSection
207
+	GlobalSection(SolutionProperties) = preSolution
208
+		HideSolutionNode = FALSE
209
+	EndGlobalSection
210
+	GlobalSection(NestedProjects) = preSolution
211
+		{A990658C-CE31-4BCC-976F-0FC6B1AF693D} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
212
+		{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
213
+		{11C084A3-A57C-4296-A679-CAC17B603144} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
214
+		{C38970C0-5FBF-4D69-90D8-CBAC225AE895} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
215
+		{F7D32BD0-2749-483E-9A0D-1635EF7E3136} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
216
+		{0CC28589-39E4-4288-B162-97B959F8B843} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
217
+		{A62D504A-16B8-41D2-9F19-E2E86019E5E4} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
218
+		{DA8B35B3-DA00-4B02-BDE6-6A397B3FD46B} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
219
+		{67A1076F-7790-4203-86EA-4402CCB5E782} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
220
+		{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
221
+		{2049DBE9-8D13-42C9-AE4B-413AE38FFFD0} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
222
+		{84E05BFA-CBAF-4F0D-BFB6-4CE85742A57E} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
223
+	EndGlobalSection
224
+	GlobalSection(ExtensibilityGlobals) = postSolution
225
+		SolutionGuid = {D43FAD39-F619-437D-BB40-04A3982ACB6A}
226
+	EndGlobalSection
227
+EndGlobal

+ 47
- 0
example/windows/WebViewWindows/App.cpp View File

1
+#include "pch.h"
2
+
3
+#include "App.h"
4
+#include "ReactPackageProvider.h"
5
+#include "winrt/ReactNativeWebView.h"
6
+
7
+
8
+using namespace winrt::WebViewWindows;
9
+using namespace winrt::WebViewWindows::implementation;
10
+
11
+/// <summary>
12
+/// Initializes the singleton application object.  This is the first line of
13
+/// authored code executed, and as such is the logical equivalent of main() or
14
+/// WinMain().
15
+/// </summary>
16
+App::App() noexcept
17
+{
18
+    MainComponentName(L"example");
19
+
20
+#if BUNDLE
21
+    JavaScriptBundleFile(L"index.windows");
22
+    InstanceSettings().UseWebDebugger(false);
23
+    InstanceSettings().UseLiveReload(false);
24
+#else
25
+    JavaScriptMainModuleName(L"example/index");
26
+    InstanceSettings().UseWebDebugger(true);
27
+    InstanceSettings().UseLiveReload(true);
28
+#endif
29
+
30
+#if _DEBUG
31
+    InstanceSettings().EnableDeveloperMenu(true);
32
+#else
33
+    InstanceSettings().EnableDeveloperMenu(false);
34
+#endif
35
+
36
+    PackageProviders().Append(make<ReactPackageProvider>()); // Includes all modules in this project
37
+    PackageProviders().Append(winrt::ReactNativeWebView::ReactPackageProvider());
38
+
39
+    InitializeComponent();
40
+
41
+    // This works around a cpp/winrt bug with composable/aggregable types tracked
42
+    // by 22116519
43
+    AddRef();
44
+    m_inner.as<::IUnknown>()->Release();
45
+}
46
+
47
+

+ 15
- 0
example/windows/WebViewWindows/App.h View File

1
+#pragma once
2
+
3
+#include "App.xaml.g.h"
4
+
5
+
6
+
7
+namespace winrt::WebViewWindows::implementation
8
+{
9
+    struct App : AppT<App>
10
+    {
11
+        App() noexcept;
12
+    };
13
+} // namespace winrt::WebViewWindows::implementation
14
+
15
+

+ 3
- 0
example/windows/WebViewWindows/App.idl View File

1
+namespace WebViewWindows
2
+{
3
+}

+ 10
- 0
example/windows/WebViewWindows/App.xaml View File

1
+<react:ReactApplication
2
+    x:Class="WebViewWindows.App"
3
+    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
4
+    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
5
+    xmlns:local="using:WebViewWindows"
6
+    xmlns:react="using:Microsoft.ReactNative">
7
+    <Application.Resources>
8
+        <XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
9
+    </Application.Resources>
10
+</react:ReactApplication>

BIN
example/windows/WebViewWindows/Assets/LockScreenLogo.scale-200.png View File


BIN
example/windows/WebViewWindows/Assets/SplashScreen.scale-200.png View File


BIN
example/windows/WebViewWindows/Assets/Square150x150Logo.scale-200.png View File


BIN
example/windows/WebViewWindows/Assets/Square44x44Logo.scale-200.png View File


BIN
example/windows/WebViewWindows/Assets/Square44x44Logo.targetsize-24_altform-unplated.png View File


BIN
example/windows/WebViewWindows/Assets/StoreLogo.png View File


BIN
example/windows/WebViewWindows/Assets/Wide310x150Logo.scale-200.png View File


+ 49
- 0
example/windows/WebViewWindows/Package.appxmanifest View File

1
+<?xml version="1.0" encoding="utf-8"?>
2
+
3
+<Package
4
+  xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
5
+  xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
6
+  xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
7
+  IgnorableNamespaces="uap mp">
8
+
9
+ <Identity
10
+    Name="6b4ef5e9-85c1-4006-87d7-77c61c62f84f"
11
+    Publisher="CN=kaigu"
12
+    Version="1.0.0.0" />
13
+
14
+  <mp:PhoneIdentity PhoneProductId="6b4ef5e9-85c1-4006-87d7-77c61c62f84f" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
15
+
16
+  <Properties>
17
+    <DisplayName>WebViewWindows</DisplayName>
18
+    <PublisherDisplayName>kaigu</PublisherDisplayName>
19
+    <Logo>Assets\StoreLogo.png</Logo>
20
+  </Properties>
21
+
22
+  <Dependencies>
23
+    <TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
24
+  </Dependencies>
25
+
26
+  <Resources>
27
+    <Resource Language="x-generate"/>
28
+  </Resources>
29
+
30
+  <Applications>
31
+    <Application Id="App"
32
+      Executable="$targetnametoken$.exe"
33
+      EntryPoint="WebViewWindows.App">
34
+      <uap:VisualElements
35
+        DisplayName="WebViewWindows"
36
+        Square150x150Logo="Assets\Square150x150Logo.png"
37
+        Square44x44Logo="Assets\Square44x44Logo.png"
38
+        Description="WebViewWindows"
39
+        BackgroundColor="transparent">
40
+        <uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png"/>
41
+        <uap:SplashScreen Image="Assets\SplashScreen.png" />
42
+      </uap:VisualElements>
43
+    </Application>
44
+  </Applications>
45
+
46
+  <Capabilities>
47
+    <Capability Name="internetClient" />
48
+  </Capabilities>
49
+</Package>

+ 16
- 0
example/windows/WebViewWindows/PropertySheet.props View File

1
+<?xml version="1.0" encoding="utf-8"?>
2
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3
+  <ImportGroup Label="PropertySheets" />
4
+  <PropertyGroup Label="UserMacros" />
5
+  <!--
6
+    To customize common C++/WinRT project properties: 
7
+    * right-click the project node
8
+    * expand the Common Properties item
9
+    * select the C++/WinRT property page
10
+
11
+    For more advanced scenarios, and complete documentation, please see:
12
+    https://github.com/Microsoft/xlang/tree/master/src/package/cppwinrt/nuget 
13
+    -->
14
+  <PropertyGroup />
15
+  <ItemDefinitionGroup />
16
+</Project>

+ 2
- 0
example/windows/WebViewWindows/ReactAssets/.gitignore View File

1
+*
2
+!.gitignore

+ 20
- 0
example/windows/WebViewWindows/ReactPackageProvider.cpp View File

1
+#include "pch.h"
2
+#include "ReactPackageProvider.h"
3
+
4
+#include "NativeModules.h"
5
+
6
+
7
+
8
+using namespace winrt::Microsoft::ReactNative;
9
+
10
+namespace winrt::WebViewWindows::implementation
11
+{
12
+
13
+void ReactPackageProvider::CreatePackage(IReactPackageBuilder const &packageBuilder) noexcept
14
+{
15
+    AddAttributedModules(packageBuilder);
16
+}
17
+
18
+} // namespace winrt::WebViewWindows::implementation
19
+
20
+

+ 20
- 0
example/windows/WebViewWindows/ReactPackageProvider.h View File

1
+#pragma once
2
+
3
+#include "winrt/Microsoft.ReactNative.h"
4
+
5
+
6
+
7
+using namespace winrt::Microsoft::ReactNative;
8
+
9
+namespace winrt::WebViewWindows::implementation
10
+{
11
+
12
+    struct ReactPackageProvider : winrt::implements<ReactPackageProvider, IReactPackageProvider>
13
+    {
14
+    public: // IReactPackageProvider
15
+        void CreatePackage(IReactPackageBuilder const &packageBuilder) noexcept;
16
+    };
17
+
18
+} // namespace winrt::WebViewWindows::implementation
19
+
20
+

+ 180
- 0
example/windows/WebViewWindows/WebViewWindows.vcxproj View File

1
+<?xml version="1.0" encoding="utf-8"?>
2
+<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3
+  <Import Project="$(SolutionDir)packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('$(SolutionDir)packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.props')" />
4
+  <PropertyGroup Label="Globals">
5
+    <CppWinRTOptimized>true</CppWinRTOptimized>
6
+    <CppWinRTRootNamespaceAutoMerge>true</CppWinRTRootNamespaceAutoMerge>
7
+    <MinimalCoreWin>true</MinimalCoreWin>
8
+    <ProjectGuid>{ac6c354f-8c80-47ea-9e40-996abe271843}</ProjectGuid>
9
+    <ProjectName>WebViewWindows</ProjectName>
10
+    <RootNamespace>WebViewWindows</RootNamespace>
11
+    <DefaultLanguage>en-US</DefaultLanguage>
12
+    <MinimumVisualStudioVersion>15.0</MinimumVisualStudioVersion>
13
+    <AppContainerApplication>true</AppContainerApplication>
14
+    <ApplicationType>Windows Store</ApplicationType>
15
+    <ApplicationTypeRevision>10.0</ApplicationTypeRevision>
16
+    <WindowsTargetPlatformVersion Condition=" '$(WindowsTargetPlatformVersion)' == '' ">10.0.18362.0</WindowsTargetPlatformVersion>
17
+    <WindowsTargetPlatformMinVersion>10.0.15063.0</WindowsTargetPlatformMinVersion>
18
+    <PackageCertificateKeyFile>WebViewWindows_TemporaryKey.pfx</PackageCertificateKeyFile>
19
+    <PackageCertificateThumbprint>82A0D300B0912A62746FFB3E6E04F88985BC2798</PackageCertificateThumbprint>
20
+    <PackageCertificatePassword>password</PackageCertificatePassword>
21
+  </PropertyGroup>
22
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
23
+  <ItemGroup Label="ProjectConfigurations">
24
+    <ProjectConfiguration Include="Debug|ARM">
25
+      <Configuration>Debug</Configuration>
26
+      <Platform>ARM</Platform>
27
+    </ProjectConfiguration>
28
+    <ProjectConfiguration Include="Debug|ARM64">
29
+      <Configuration>Debug</Configuration>
30
+      <Platform>ARM64</Platform>
31
+    </ProjectConfiguration>
32
+    <ProjectConfiguration Include="Debug|Win32">
33
+      <Configuration>Debug</Configuration>
34
+      <Platform>Win32</Platform>
35
+    </ProjectConfiguration>
36
+    <ProjectConfiguration Include="Debug|x64">
37
+      <Configuration>Debug</Configuration>
38
+      <Platform>x64</Platform>
39
+    </ProjectConfiguration>
40
+    <ProjectConfiguration Include="Release|ARM">
41
+      <Configuration>Release</Configuration>
42
+      <Platform>ARM</Platform>
43
+    </ProjectConfiguration>
44
+    <ProjectConfiguration Include="Release|ARM64">
45
+      <Configuration>Release</Configuration>
46
+      <Platform>ARM64</Platform>
47
+    </ProjectConfiguration>
48
+    <ProjectConfiguration Include="Release|Win32">
49
+      <Configuration>Release</Configuration>
50
+      <Platform>Win32</Platform>
51
+    </ProjectConfiguration>
52
+    <ProjectConfiguration Include="Release|x64">
53
+      <Configuration>Release</Configuration>
54
+      <Platform>x64</Platform>
55
+    </ProjectConfiguration>
56
+  </ItemGroup>
57
+  <PropertyGroup Label="Configuration">
58
+    <ConfigurationType>Application</ConfigurationType>
59
+    <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
60
+    <CharacterSet>Unicode</CharacterSet>
61
+  </PropertyGroup>
62
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
63
+    <UseDebugLibraries>true</UseDebugLibraries>
64
+    <LinkIncremental>true</LinkIncremental>
65
+  </PropertyGroup>
66
+  <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
67
+    <UseDebugLibraries>false</UseDebugLibraries>
68
+    <WholeProgramOptimization>true</WholeProgramOptimization>
69
+    <LinkIncremental>false</LinkIncremental>
70
+  </PropertyGroup>
71
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
72
+  <ImportGroup Label="ExtensionSettings">
73
+  </ImportGroup>
74
+  <ImportGroup Label="Shared">
75
+    <Import Project="..\..\..\node_modules\react-native-windows\Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems" Label="Shared" />
76
+  </ImportGroup>
77
+  <ImportGroup Label="PropertySheets">
78
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
79
+  </ImportGroup>
80
+  <ImportGroup Label="PropertySheets">
81
+    <Import Project="PropertySheet.props" />
82
+  </ImportGroup>
83
+  <PropertyGroup Label="UserMacros" />
84
+  <ItemDefinitionGroup>
85
+    <ClCompile>
86
+      <PrecompiledHeader>Use</PrecompiledHeader>
87
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
88
+      <PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
89
+      <WarningLevel>Level4</WarningLevel>
90
+      <AdditionalOptions>%(AdditionalOptions) /bigobj</AdditionalOptions>
91
+      <DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
92
+    </ClCompile>
93
+  </ItemDefinitionGroup>
94
+  <ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
95
+    <ClCompile>
96
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
97
+    </ClCompile>
98
+  </ItemDefinitionGroup>
99
+  <ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
100
+    <ClCompile>
101
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
102
+    </ClCompile>
103
+  </ItemDefinitionGroup>
104
+  <ItemGroup>
105
+    <ClInclude Include="ReactPackageProvider.h" />
106
+    <ClInclude Include="pch.h" />
107
+    <ClInclude Include="App.h">
108
+      <DependentUpon>App.xaml</DependentUpon>
109
+    </ClInclude>
110
+  </ItemGroup>
111
+  <ItemGroup>
112
+    <ApplicationDefinition Include="App.xaml">
113
+      <SubType>Designer</SubType>
114
+    </ApplicationDefinition>
115
+  </ItemGroup>
116
+  <ItemGroup>
117
+    <AppxManifest Include="Package.appxmanifest">
118
+      <SubType>Designer</SubType>
119
+    </AppxManifest>
120
+  </ItemGroup>
121
+  <ItemGroup>
122
+    <Image Include="Assets\LockScreenLogo.scale-200.png" />
123
+    <Image Include="Assets\SplashScreen.scale-200.png" />
124
+    <Image Include="Assets\Square150x150Logo.scale-200.png" />
125
+    <Image Include="Assets\Square44x44Logo.scale-200.png" />
126
+    <Image Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png" />
127
+    <Image Include="Assets\StoreLogo.png" />
128
+    <Image Include="Assets\Wide310x150Logo.scale-200.png" />
129
+  </ItemGroup>
130
+  <ItemGroup>
131
+    <ClCompile Include="ReactPackageProvider.cpp" />
132
+    <ClCompile Include="pch.cpp">
133
+      <PrecompiledHeader>Create</PrecompiledHeader>
134
+    </ClCompile>
135
+    <ClCompile Include="App.cpp">
136
+      <DependentUpon>App.xaml</DependentUpon>
137
+    </ClCompile>
138
+    <ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
139
+  </ItemGroup>
140
+  <ItemGroup>
141
+    <Midl Include="App.idl">
142
+      <DependentUpon>App.xaml</DependentUpon>
143
+    </Midl>
144
+  </ItemGroup>
145
+  <ItemGroup>
146
+    <None Include="packages.config" />
147
+    <None Include="PropertySheet.props" />
148
+    <Text Include="readme.txt">
149
+      <DeploymentContent>false</DeploymentContent>
150
+    </Text>
151
+  </ItemGroup>
152
+  <ItemGroup>
153
+    <ProjectReference Include="..\..\..\node_modules\react-native-windows\Microsoft.ReactNative\Microsoft.ReactNative.vcxproj">
154
+      <Project>{f7d32bd0-2749-483e-9a0d-1635ef7e3136}</Project>
155
+    </ProjectReference>
156
+    <ProjectReference Include="..\..\..\windows\ReactNativeWebView\ReactNativeWebView.vcxproj">
157
+      <Project>{729d9af8-cd9e-4427-9f6c-fb757e287729}</Project>
158
+    </ProjectReference>
159
+  </ItemGroup>
160
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
161
+  <PropertyGroup>
162
+    <BundleCommand>
163
+      cd $(SolutionDir)..
164
+      react-native bundle --platform windows --entry-file example/index.js --bundle-output windows/$(SolutionName)/Bundle/index.windows.bundle --assets-dest windows/$(SolutionName)/Bundle
165
+    </BundleCommand>
166
+  </PropertyGroup>
167
+  <Import Project="..\..\..\node_modules\react-native-windows\PropertySheets\Bundle.Cpp.targets" />
168
+  <ImportGroup Label="ExtensionTargets">
169
+    <Import Project="$(SolutionDir)packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(SolutionDir)packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.targets')" />
170
+    <Import Project="$(SolutionDir)packages\Microsoft.UI.Xaml.2.3.191129002\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('$(SolutionDir)packages\Microsoft.UI.Xaml.2.3.191129002\build\native\Microsoft.UI.Xaml.targets')" />
171
+  </ImportGroup>
172
+  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
173
+    <PropertyGroup>
174
+      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
175
+    </PropertyGroup>
176
+    <Error Condition="!Exists('$(SolutionDir)packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.props'))" />
177
+    <Error Condition="!Exists('$(SolutionDir)packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.targets'))" />
178
+    <Error Condition="!Exists('$(SolutionDir)packages\Microsoft.UI.Xaml.2.3.191129002\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)packages\Microsoft.UI.Xaml.2.3.191129002\build\native\Microsoft.UI.Xaml.targets'))" />
179
+  </Target>
180
+</Project>

+ 58
- 0
example/windows/WebViewWindows/WebViewWindows.vcxproj.filters View File

1
+<?xml version="1.0" encoding="utf-8"?>
2
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3
+  <ItemGroup>
4
+    <ApplicationDefinition Include="App.xaml" />
5
+  </ItemGroup>
6
+  <ItemGroup>
7
+    <Midl Include="App.idl" />
8
+  </ItemGroup>
9
+  <ItemGroup>
10
+    <ClCompile Include="pch.cpp" />
11
+    <ClCompile Include="App.cpp" />
12
+    <ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
13
+    <ClCompile Include="ReactPackageProvider.cpp" />
14
+  </ItemGroup>
15
+  <ItemGroup>
16
+    <ClInclude Include="pch.h" />
17
+    <ClInclude Include="App.h" />
18
+    <ClInclude Include="ReactPackageProvider.h" />
19
+  </ItemGroup>
20
+  <ItemGroup>
21
+    <Image Include="Assets\Wide310x150Logo.scale-200.png">
22
+      <Filter>Assets</Filter>
23
+    </Image>
24
+    <Image Include="Assets\StoreLogo.png">
25
+      <Filter>Assets</Filter>
26
+    </Image>
27
+    <Image Include="Assets\Square150x150Logo.scale-200.png">
28
+      <Filter>Assets</Filter>
29
+    </Image>
30
+    <Image Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png">
31
+      <Filter>Assets</Filter>
32
+    </Image>
33
+    <Image Include="Assets\Square44x44Logo.scale-200.png">
34
+      <Filter>Assets</Filter>
35
+    </Image>
36
+    <Image Include="Assets\SplashScreen.scale-200.png">
37
+      <Filter>Assets</Filter>
38
+    </Image>
39
+    <Image Include="Assets\LockScreenLogo.scale-200.png">
40
+      <Filter>Assets</Filter>
41
+    </Image>
42
+  </ItemGroup>
43
+  <ItemGroup>
44
+    <AppxManifest Include="Package.appxmanifest" />
45
+  </ItemGroup>
46
+  <ItemGroup>
47
+    <Filter Include="Assets">
48
+      <UniqueIdentifier>{e48dc53e-40b1-40cb-970a-f89935452892}</UniqueIdentifier>
49
+    </Filter>
50
+  </ItemGroup>
51
+  <ItemGroup>
52
+    <None Include="PropertySheet.props" />
53
+    <None Include="packages.config" />
54
+  </ItemGroup>
55
+  <ItemGroup>
56
+    <Text Include="readme.txt" />
57
+  </ItemGroup>
58
+</Project>

BIN
example/windows/WebViewWindows/WebViewWindows_TemporaryKey.pfx View File


+ 5
- 0
example/windows/WebViewWindows/packages.config View File

1
+<?xml version="1.0" encoding="utf-8"?>
2
+<packages>
3
+  <package id="Microsoft.Windows.CppWinRT" version="2.0.190730.2" targetFramework="native" />
4
+  <package id="Microsoft.UI.Xaml" version="2.3.191129002" targetFramework="native" />
5
+</packages>

+ 1
- 0
example/windows/WebViewWindows/pch.cpp View File

1
+#include "pch.h"

+ 25
- 0
example/windows/WebViewWindows/pch.h View File

1
+#pragma once
2
+
3
+#define NOMINMAX
4
+#include <hstring.h>
5
+#include <restrictederrorinfo.h>
6
+#include <unknwn.h>
7
+#include <windows.h>
8
+#include <winrt/Windows.ApplicationModel.Activation.h>
9
+#include <winrt/Windows.Foundation.Collections.h>
10
+#include <winrt/Windows.Foundation.h>
11
+#include <winrt/Windows.UI.Xaml.Controls.Primitives.h>
12
+#include <winrt/Windows.UI.Xaml.Controls.h>
13
+#include <winrt/Windows.UI.Xaml.Data.h>
14
+#include <winrt/Windows.UI.Xaml.Interop.h>
15
+#include <winrt/Windows.UI.Xaml.Markup.h>
16
+#include <winrt/Windows.UI.Xaml.Navigation.h>
17
+#include <winrt/Windows.UI.Xaml.h>
18
+
19
+#include <winrt/Microsoft.ReactNative.h>
20
+
21
+#include <winrt/Microsoft.UI.Xaml.Automation.Peers.h>
22
+#include <winrt/Microsoft.UI.Xaml.Controls.Primitives.h>
23
+#include <winrt/Microsoft.UI.Xaml.Controls.h>
24
+#include <winrt/Microsoft.UI.Xaml.Media.h>
25
+#include <winrt/Microsoft.UI.Xaml.XamlTypeInfo.h>

+ 2
- 0
ios/RNCWebView.h View File

31
 @property (nonatomic, assign) BOOL messagingEnabled;
31
 @property (nonatomic, assign) BOOL messagingEnabled;
32
 @property (nonatomic, copy) NSString * _Nullable injectedJavaScript;
32
 @property (nonatomic, copy) NSString * _Nullable injectedJavaScript;
33
 @property (nonatomic, copy) NSString * _Nullable injectedJavaScriptBeforeContentLoaded;
33
 @property (nonatomic, copy) NSString * _Nullable injectedJavaScriptBeforeContentLoaded;
34
+@property (nonatomic, assign) BOOL injectedJavaScriptForMainFrameOnly;
35
+@property (nonatomic, assign) BOOL injectedJavaScriptBeforeContentLoadedForMainFrameOnly;
34
 @property (nonatomic, assign) BOOL scrollEnabled;
36
 @property (nonatomic, assign) BOOL scrollEnabled;
35
 @property (nonatomic, assign) BOOL sharedCookiesEnabled;
37
 @property (nonatomic, assign) BOOL sharedCookiesEnabled;
36
 @property (nonatomic, assign) BOOL pagingEnabled;
38
 @property (nonatomic, assign) BOOL pagingEnabled;

+ 179
- 118
ios/RNCWebView.m View File

81
 #else
81
 #else
82
 @property (nonatomic, copy) RNCWKWebView *webView;
82
 @property (nonatomic, copy) RNCWKWebView *webView;
83
 #endif // !TARGET_OS_OSX
83
 #endif // !TARGET_OS_OSX
84
+@property (nonatomic, strong) WKUserScript *postMessageScript;
85
+@property (nonatomic, strong) WKUserScript *atStartScript;
86
+@property (nonatomic, strong) WKUserScript *atEndScript;
84
 @end
87
 @end
85
 
88
 
86
 @implementation RNCWebView
89
 @implementation RNCWebView
122
     _automaticallyAdjustContentInsets = YES;
125
     _automaticallyAdjustContentInsets = YES;
123
     _contentInset = UIEdgeInsetsZero;
126
     _contentInset = UIEdgeInsetsZero;
124
     _savedKeyboardDisplayRequiresUserAction = YES;
127
     _savedKeyboardDisplayRequiresUserAction = YES;
125
-#if !TARGET_OS_OSX
128
+    #if !TARGET_OS_OSX
126
     _savedStatusBarStyle = RCTSharedApplication().statusBarStyle;
129
     _savedStatusBarStyle = RCTSharedApplication().statusBarStyle;
127
     _savedStatusBarHidden = RCTSharedApplication().statusBarHidden;
130
     _savedStatusBarHidden = RCTSharedApplication().statusBarHidden;
128
-#endif // !TARGET_OS_OSX
131
+    #endif // !TARGET_OS_OSX
132
+    _injectedJavaScript = nil;
133
+    _injectedJavaScriptForMainFrameOnly = YES;
134
+    _injectedJavaScriptBeforeContentLoaded = nil;
135
+    _injectedJavaScriptBeforeContentLoadedForMainFrameOnly = YES;
129
 
136
 
130
 #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */
137
 #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */
131
     _savedContentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
138
     _savedContentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
206
   // Shim the HTML5 history API:
213
   // Shim the HTML5 history API:
207
   [wkWebViewConfig.userContentController addScriptMessageHandler:[[RNCWeakScriptMessageDelegate alloc] initWithDelegate:self]
214
   [wkWebViewConfig.userContentController addScriptMessageHandler:[[RNCWeakScriptMessageDelegate alloc] initWithDelegate:self]
208
                                                             name:HistoryShimName];
215
                                                             name:HistoryShimName];
209
-  NSString *source = [NSString stringWithFormat:
210
-    @"(function(history) {\n"
211
-    "  function notify(type) {\n"
212
-    "    setTimeout(function() {\n"
213
-    "      window.webkit.messageHandlers.%@.postMessage(type)\n"
214
-    "    }, 0)\n"
215
-    "  }\n"
216
-    "  function shim(f) {\n"
217
-    "    return function pushState() {\n"
218
-    "      notify('other')\n"
219
-    "      return f.apply(history, arguments)\n"
220
-    "    }\n"
221
-    "  }\n"
222
-    "  history.pushState = shim(history.pushState)\n"
223
-    "  history.replaceState = shim(history.replaceState)\n"
224
-    "  window.addEventListener('popstate', function() {\n"
225
-    "    notify('backforward')\n"
226
-    "  })\n"
227
-    "})(window.history)\n", HistoryShimName
228
-  ];
229
-  WKUserScript *script = [[WKUserScript alloc] initWithSource:source injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:YES];
230
-  [wkWebViewConfig.userContentController addUserScript:script];
231
-
232
-  if (_messagingEnabled) {
233
-    [wkWebViewConfig.userContentController addScriptMessageHandler:[[RNCWeakScriptMessageDelegate alloc] initWithDelegate:self]
234
-                                                              name:MessageHandlerName];
235
-
236
-    NSString *source = [NSString stringWithFormat:
237
-      @"window.%@ = {"
238
-       "  postMessage: function (data) {"
239
-       "    window.webkit.messageHandlers.%@.postMessage(String(data));"
240
-       "  }"
241
-       "};", MessageHandlerName, MessageHandlerName
242
-    ];
243
-
244
-    WKUserScript *script = [[WKUserScript alloc] initWithSource:source injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:YES];
245
-    [wkWebViewConfig.userContentController addUserScript:script];
246
-      
247
-    if (_injectedJavaScriptBeforeContentLoaded) {
248
-      // If user has provided an injectedJavascript prop, execute it at the start of the document
249
-      WKUserScript *injectedScript = [[WKUserScript alloc] initWithSource:_injectedJavaScriptBeforeContentLoaded injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:YES];
250
-      [wkWebViewConfig.userContentController addUserScript:injectedScript];
251
-    }
252
-  }
216
+  [self resetupScripts:wkWebViewConfig];
253
 
217
 
254
 #if !TARGET_OS_OSX
218
 #if !TARGET_OS_OSX
255
   wkWebViewConfig.allowsInlineMediaPlayback = _allowsInlineMediaPlayback;
219
   wkWebViewConfig.allowsInlineMediaPlayback = _allowsInlineMediaPlayback;
266
   if (_applicationNameForUserAgent) {
230
   if (_applicationNameForUserAgent) {
267
       wkWebViewConfig.applicationNameForUserAgent = [NSString stringWithFormat:@"%@ %@", wkWebViewConfig.applicationNameForUserAgent, _applicationNameForUserAgent];
231
       wkWebViewConfig.applicationNameForUserAgent = [NSString stringWithFormat:@"%@ %@", wkWebViewConfig.applicationNameForUserAgent, _applicationNameForUserAgent];
268
   }
232
   }
269
-
270
-  if(_sharedCookiesEnabled) {
271
-    // More info to sending cookies with WKWebView
272
-    // https://stackoverflow.com/questions/26573137/can-i-set-the-cookies-to-be-used-by-a-wkwebview/26577303#26577303
273
-    if (@available(iOS 11.0, *)) {
274
-      // Set Cookies in iOS 11 and above, initialize websiteDataStore before setting cookies
275
-      // See also https://forums.developer.apple.com/thread/97194
276
-      // check if websiteDataStore has not been initialized before
277
-      if(!_incognito && !_cacheEnabled) {
278
-        wkWebViewConfig.websiteDataStore = [WKWebsiteDataStore nonPersistentDataStore];
279
-      }
280
-      for (NSHTTPCookie *cookie in [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]) {
281
-        [wkWebViewConfig.websiteDataStore.httpCookieStore setCookie:cookie completionHandler:nil];
282
-      }
283
-    } else {
284
-      NSMutableString *script = [NSMutableString string];
285
-
286
-      // Clear all existing cookies in a direct called function. This ensures that no
287
-      // javascript error will break the web content javascript.
288
-      // We keep this code here, if someone requires that Cookies are also removed within the
289
-      // the WebView and want to extends the current sharedCookiesEnabled option with an
290
-      // additional property.
291
-      // Generates JS: document.cookie = "key=; Expires=Thu, 01 Jan 1970 00:00:01 GMT;"
292
-      // for each cookie which is already available in the WebView context.
293
-      /*
294
-      [script appendString:@"(function () {\n"];
295
-      [script appendString:@"  var cookies = document.cookie.split('; ');\n"];
296
-      [script appendString:@"  for (var i = 0; i < cookies.length; i++) {\n"];
297
-      [script appendString:@"    if (cookies[i].indexOf('=') !== -1) {\n"];
298
-      [script appendString:@"      document.cookie = cookies[i].split('=')[0] + '=; Expires=Thu, 01 Jan 1970 00:00:01 GMT';\n"];
299
-      [script appendString:@"    }\n"];
300
-      [script appendString:@"  }\n"];
301
-      [script appendString:@"})();\n\n"];
302
-      */
303
-
304
-      // Set cookies in a direct called function. This ensures that no
305
-      // javascript error will break the web content javascript.
306
-        // Generates JS: document.cookie = "key=value; Path=/; Expires=Thu, 01 Jan 20xx 00:00:01 GMT;"
307
-      // for each cookie which is available in the application context.
308
-      [script appendString:@"(function () {\n"];
309
-      for (NSHTTPCookie *cookie in [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]) {
310
-        [script appendFormat:@"document.cookie = %@ + '=' + %@",
311
-          RCTJSONStringify(cookie.name, NULL),
312
-          RCTJSONStringify(cookie.value, NULL)];
313
-        if (cookie.path) {
314
-          [script appendFormat:@" + '; Path=' + %@", RCTJSONStringify(cookie.path, NULL)];
315
-        }
316
-        if (cookie.expiresDate) {
317
-          [script appendFormat:@" + '; Expires=' + new Date(%f).toUTCString()",
318
-            cookie.expiresDate.timeIntervalSince1970 * 1000
319
-          ];
320
-        }
321
-        [script appendString:@";\n"];
322
-      }
323
-      [script appendString:@"})();\n"];
324
-
325
-      WKUserScript* cookieInScript = [[WKUserScript alloc] initWithSource:script
326
-                                                            injectionTime:WKUserScriptInjectionTimeAtDocumentStart
327
-                                                         forMainFrameOnly:YES];
328
-      [wkWebViewConfig.userContentController addUserScript:cookieInScript];
329
-    }
330
-  }
331
   
233
   
332
   return wkWebViewConfig;
234
   return wkWebViewConfig;
333
 }
235
 }
1136
 - (void)webView:(WKWebView *)webView
1038
 - (void)webView:(WKWebView *)webView
1137
   didFinishNavigation:(WKNavigation *)navigation
1039
   didFinishNavigation:(WKNavigation *)navigation
1138
 {
1040
 {
1139
-   if (_injectedJavaScript) {
1140
-     [self evaluateJS: _injectedJavaScript thenCall: ^(NSString *jsEvaluationValue) {
1141
-       NSMutableDictionary *event = [self baseEvent];
1142
-       event[@"jsEvaluationValue"] = jsEvaluationValue;
1143
-
1144
-       if (self.onLoadingFinish) {
1145
-         self.onLoadingFinish(event);
1146
-       }
1147
-     }];
1148
-   } else if (_onLoadingFinish) {
1041
+  if (_onLoadingFinish) {
1149
     _onLoadingFinish([self baseEvent]);
1042
     _onLoadingFinish([self baseEvent]);
1150
   }
1043
   }
1151
 }
1044
 }
1194
 }
1087
 }
1195
 #endif // !TARGET_OS_OSX
1088
 #endif // !TARGET_OS_OSX
1196
 
1089
 
1090
+
1091
+- (void)setInjectedJavaScript:(NSString *)source {
1092
+  _injectedJavaScript = source;
1093
+  
1094
+  self.atEndScript = source == nil ? nil : [[WKUserScript alloc] initWithSource:source
1095
+      injectionTime:WKUserScriptInjectionTimeAtDocumentEnd
1096
+    forMainFrameOnly:_injectedJavaScriptForMainFrameOnly];
1097
+  
1098
+  if(_webView != nil){
1099
+    [self resetupScripts:_webView.configuration];
1100
+  }
1101
+}
1102
+
1103
+- (void)setInjectedJavaScriptBeforeContentLoaded:(NSString *)source {
1104
+  _injectedJavaScriptBeforeContentLoaded = source;
1105
+  
1106
+  self.atStartScript = source == nil ? nil : [[WKUserScript alloc] initWithSource:source
1107
+       injectionTime:WKUserScriptInjectionTimeAtDocumentStart
1108
+    forMainFrameOnly:_injectedJavaScriptBeforeContentLoadedForMainFrameOnly];
1109
+  
1110
+  if(_webView != nil){
1111
+    [self resetupScripts:_webView.configuration];
1112
+  }
1113
+}
1114
+
1115
+- (void)setInjectedJavaScriptForMainFrameOnly:(BOOL)mainFrameOnly {
1116
+  _injectedJavaScriptForMainFrameOnly = mainFrameOnly;
1117
+  [self setInjectedJavaScript:_injectedJavaScript];
1118
+}
1119
+
1120
+- (void)setInjectedJavaScriptBeforeContentLoadedForMainFrameOnly:(BOOL)mainFrameOnly {
1121
+  _injectedJavaScriptBeforeContentLoadedForMainFrameOnly = mainFrameOnly;
1122
+  [self setInjectedJavaScriptBeforeContentLoaded:_injectedJavaScriptBeforeContentLoaded];
1123
+}
1124
+
1125
+- (void)setMessagingEnabled:(BOOL)messagingEnabled {
1126
+  _messagingEnabled = messagingEnabled;
1127
+  
1128
+  self.postMessageScript = _messagingEnabled ?
1129
+  [
1130
+   [WKUserScript alloc]
1131
+   initWithSource: [
1132
+                    NSString
1133
+                    stringWithFormat:
1134
+                    @"window.%@ = {"
1135
+                    "  postMessage: function (data) {"
1136
+                    "    window.webkit.messageHandlers.%@.postMessage(String(data));"
1137
+                    "  }"
1138
+                    "};", MessageHandlerName, MessageHandlerName
1139
+                    ]
1140
+   injectionTime:WKUserScriptInjectionTimeAtDocumentStart
1141
+   /* TODO: For a separate (minor) PR: use logic like this (as react-native-wkwebview does) so that messaging can be used in all frames if desired.
1142
+    *       I am keeping it as YES for consistency with previous behaviour. */
1143
+   // forMainFrameOnly:_messagingEnabledForMainFrameOnly
1144
+   forMainFrameOnly:YES
1145
+   ] :
1146
+  nil;
1147
+  
1148
+  if(_webView != nil){
1149
+    [self resetupScripts:_webView.configuration];
1150
+  }
1151
+}
1152
+
1153
+- (void)resetupScripts:(WKWebViewConfiguration *)wkWebViewConfig {
1154
+  [wkWebViewConfig.userContentController removeAllUserScripts];
1155
+  [wkWebViewConfig.userContentController removeScriptMessageHandlerForName:MessageHandlerName];
1156
+  
1157
+  NSString *html5HistoryAPIShimSource = [NSString stringWithFormat:
1158
+    @"(function(history) {\n"
1159
+    "  function notify(type) {\n"
1160
+    "    setTimeout(function() {\n"
1161
+    "      window.webkit.messageHandlers.%@.postMessage(type)\n"
1162
+    "    }, 0)\n"
1163
+    "  }\n"
1164
+    "  function shim(f) {\n"
1165
+    "    return function pushState() {\n"
1166
+    "      notify('other')\n"
1167
+    "      return f.apply(history, arguments)\n"
1168
+    "    }\n"
1169
+    "  }\n"
1170
+    "  history.pushState = shim(history.pushState)\n"
1171
+    "  history.replaceState = shim(history.replaceState)\n"
1172
+    "  window.addEventListener('popstate', function() {\n"
1173
+    "    notify('backforward')\n"
1174
+    "  })\n"
1175
+    "})(window.history)\n", HistoryShimName
1176
+  ];
1177
+  WKUserScript *script = [[WKUserScript alloc] initWithSource:html5HistoryAPIShimSource injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:YES];
1178
+  [wkWebViewConfig.userContentController addUserScript:script];
1179
+  
1180
+  if(_sharedCookiesEnabled) {
1181
+    // More info to sending cookies with WKWebView
1182
+    // https://stackoverflow.com/questions/26573137/can-i-set-the-cookies-to-be-used-by-a-wkwebview/26577303#26577303
1183
+    if (@available(iOS 11.0, *)) {
1184
+      // Set Cookies in iOS 11 and above, initialize websiteDataStore before setting cookies
1185
+      // See also https://forums.developer.apple.com/thread/97194
1186
+      // check if websiteDataStore has not been initialized before
1187
+      if(!_incognito && !_cacheEnabled) {
1188
+        wkWebViewConfig.websiteDataStore = [WKWebsiteDataStore nonPersistentDataStore];
1189
+      }
1190
+      for (NSHTTPCookie *cookie in [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]) {
1191
+        [wkWebViewConfig.websiteDataStore.httpCookieStore setCookie:cookie completionHandler:nil];
1192
+      }
1193
+    } else {
1194
+      NSMutableString *script = [NSMutableString string];
1195
+
1196
+      // Clear all existing cookies in a direct called function. This ensures that no
1197
+      // javascript error will break the web content javascript.
1198
+      // We keep this code here, if someone requires that Cookies are also removed within the
1199
+      // the WebView and want to extends the current sharedCookiesEnabled option with an
1200
+      // additional property.
1201
+      // Generates JS: document.cookie = "key=; Expires=Thu, 01 Jan 1970 00:00:01 GMT;"
1202
+      // for each cookie which is already available in the WebView context.
1203
+      /*
1204
+      [script appendString:@"(function () {\n"];
1205
+      [script appendString:@"  var cookies = document.cookie.split('; ');\n"];
1206
+      [script appendString:@"  for (var i = 0; i < cookies.length; i++) {\n"];
1207
+      [script appendString:@"    if (cookies[i].indexOf('=') !== -1) {\n"];
1208
+      [script appendString:@"      document.cookie = cookies[i].split('=')[0] + '=; Expires=Thu, 01 Jan 1970 00:00:01 GMT';\n"];
1209
+      [script appendString:@"    }\n"];
1210
+      [script appendString:@"  }\n"];
1211
+      [script appendString:@"})();\n\n"];
1212
+      */
1213
+
1214
+      // Set cookies in a direct called function. This ensures that no
1215
+      // javascript error will break the web content javascript.
1216
+        // Generates JS: document.cookie = "key=value; Path=/; Expires=Thu, 01 Jan 20xx 00:00:01 GMT;"
1217
+      // for each cookie which is available in the application context.
1218
+      [script appendString:@"(function () {\n"];
1219
+      for (NSHTTPCookie *cookie in [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]) {
1220
+        [script appendFormat:@"document.cookie = %@ + '=' + %@",
1221
+          RCTJSONStringify(cookie.name, NULL),
1222
+          RCTJSONStringify(cookie.value, NULL)];
1223
+        if (cookie.path) {
1224
+          [script appendFormat:@" + '; Path=' + %@", RCTJSONStringify(cookie.path, NULL)];
1225
+        }
1226
+        if (cookie.expiresDate) {
1227
+          [script appendFormat:@" + '; Expires=' + new Date(%f).toUTCString()",
1228
+            cookie.expiresDate.timeIntervalSince1970 * 1000
1229
+          ];
1230
+        }
1231
+        [script appendString:@";\n"];
1232
+      }
1233
+      [script appendString:@"})();\n"];
1234
+
1235
+      WKUserScript* cookieInScript = [[WKUserScript alloc] initWithSource:script
1236
+                                                            injectionTime:WKUserScriptInjectionTimeAtDocumentStart
1237
+                                                         forMainFrameOnly:YES];
1238
+      [wkWebViewConfig.userContentController addUserScript:cookieInScript];
1239
+    }
1240
+  }
1241
+  
1242
+  if(_messagingEnabled){
1243
+    if (self.postMessageScript){
1244
+      [wkWebViewConfig.userContentController addScriptMessageHandler:[[RNCWeakScriptMessageDelegate alloc] initWithDelegate:self]
1245
+                                                                       name:MessageHandlerName];
1246
+      [wkWebViewConfig.userContentController addUserScript:self.postMessageScript];
1247
+    }
1248
+    // FIXME: For a separate (minor) PR: these two shouldn't be gated by messagingEnabled; just keeping consistency with previous behaviour.
1249
+    if (self.atStartScript) {
1250
+      [wkWebViewConfig.userContentController addUserScript:self.atStartScript];
1251
+    }
1252
+    if (self.atEndScript) {
1253
+      [wkWebViewConfig.userContentController addUserScript:self.atEndScript];
1254
+    }
1255
+  }
1256
+}
1257
+
1197
 - (NSURLRequest *)requestForSource:(id)json {
1258
 - (NSURLRequest *)requestForSource:(id)json {
1198
   NSURLRequest *request = [RCTConvert NSURLRequest:self.source];
1259
   NSURLRequest *request = [RCTConvert NSURLRequest:self.source];
1199
 
1260
 

+ 2
- 0
ios/RNCWebViewManager.m View File

43
 RCT_EXPORT_VIEW_PROPERTY(onContentProcessDidTerminate, RCTDirectEventBlock)
43
 RCT_EXPORT_VIEW_PROPERTY(onContentProcessDidTerminate, RCTDirectEventBlock)
44
 RCT_EXPORT_VIEW_PROPERTY(injectedJavaScript, NSString)
44
 RCT_EXPORT_VIEW_PROPERTY(injectedJavaScript, NSString)
45
 RCT_EXPORT_VIEW_PROPERTY(injectedJavaScriptBeforeContentLoaded, NSString)
45
 RCT_EXPORT_VIEW_PROPERTY(injectedJavaScriptBeforeContentLoaded, NSString)
46
+RCT_EXPORT_VIEW_PROPERTY(injectedJavaScriptForMainFrameOnly, BOOL)
47
+RCT_EXPORT_VIEW_PROPERTY(injectedJavaScriptBeforeContentLoadedForMainFrameOnly, BOOL)
46
 RCT_EXPORT_VIEW_PROPERTY(javaScriptEnabled, BOOL)
48
 RCT_EXPORT_VIEW_PROPERTY(javaScriptEnabled, BOOL)
47
 RCT_EXPORT_VIEW_PROPERTY(allowFileAccessFromFileURLs, BOOL)
49
 RCT_EXPORT_VIEW_PROPERTY(allowFileAccessFromFileURLs, BOOL)
48
 RCT_EXPORT_VIEW_PROPERTY(allowsInlineMediaPlayback, BOOL)
50
 RCT_EXPORT_VIEW_PROPERTY(allowsInlineMediaPlayback, BOOL)

+ 48
- 0
metro.config.windows.js View File

1
+/**
2
+ * Metro configuration for React Native
3
+ * https://github.com/facebook/react-native
4
+ *
5
+ * @format
6
+ */
7
+const fs = require('fs');
8
+const path = require('path');
9
+const blacklist = require('metro-config/src/defaults/blacklist');
10
+
11
+const rnPath = fs.realpathSync(
12
+  path.resolve(require.resolve('react-native/package.json'), '..'),
13
+);
14
+const rnwPath = fs.realpathSync(
15
+  path.resolve(require.resolve('react-native-windows/package.json'), '..'),
16
+);
17
+
18
+module.exports = {
19
+  resolver: {
20
+    extraNodeModules: {
21
+      // Redirect react-native to react-native-windows
22
+      'react-native': rnwPath,
23
+      'react-native-windows': rnwPath,
24
+    },
25
+    // Include the macos platform in addition to the defaults because the fork includes macos, but doesn't declare it
26
+    platforms: ['ios', 'android', 'windesktop', 'windows', 'web', 'macos'],
27
+    // Since there are multiple copies of react-native, we need to ensure that metro only sees one of them
28
+    // This should go in RN 0.61 when haste is removed
29
+    blacklistRE: blacklist([
30
+      new RegExp(
31
+        `${(path.resolve(rnPath) + path.sep).replace(/[/\\]/g, '/')}.*`,
32
+      ),
33
+
34
+      // This stops "react-native run-windows" from causing the metro server to crash if its already running
35
+      new RegExp(
36
+        `${path.resolve(__dirname, 'windows').replace(/[/\\]/g, '/')}.*`,
37
+      ),
38
+    ]),
39
+  },
40
+  transformer: {
41
+    getTransformOptions: async () => ({
42
+      transform: {
43
+        experimentalImportSupport: false,
44
+        inlineRequires: false,
45
+      },
46
+    }),
47
+  },
48
+};

+ 86
- 80
package.json View File

1
-{
2
-  "name": "react-native-webview",
3
-  "description": "React Native WebView component for iOS, Android, and macOS",
4
-  "main": "index.js",
5
-  "typings": "index.d.ts",
6
-  "author": "Jamon Holmgren <jamon@infinite.red>",
7
-  "contributors": [
8
-    "Thibault Malbranche <malbranche.thibault@gmail.com>"
9
-  ],
10
-  "license": "MIT",
11
-  "version": "8.1.0",
12
-  "homepage": "https://github.com/react-native-community/react-native-webview#readme",
13
-  "scripts": {
14
-    "start": "node node_modules/react-native/local-cli/cli.js start",
15
-    "start:android": "react-native run-android --root example/",
16
-    "start:ios": "react-native run-ios --project-path example/ios --scheme example",
17
-    "start:macos": "node node_modules/react-native-macos/local-cli/cli.js start --use-react-native-macos",
18
-    "ci": "CI=true && yarn lint && yarn test",
19
-    "ci:publish": "yarn semantic-release",
20
-    "lint": "yarn tsc --noEmit && yarn eslint ./src --ext .ts,.tsx",
21
-    "build": "yarn tsc",
22
-    "prepare": "yarn build",
23
-    "test": "yarn jest"
24
-  },
25
-  "rn-docs": {
26
-    "title": "Webview",
27
-    "type": "Component"
28
-  },
29
-  "peerDependencies": {
30
-    "react": "^16.9",
31
-    "react-native": ">=0.60 <0.62"
32
-  },
33
-  "dependencies": {
34
-    "escape-string-regexp": "2.0.0",
35
-    "invariant": "2.2.4"
36
-  },
37
-  "devDependencies": {
38
-    "@babel/core": "7.4.5",
39
-    "@babel/runtime": "7.4.5",
40
-    "@react-native-community/cli-platform-ios": "^3.0.0",
41
-    "@react-native-community/cli-platform-android": "^3.0.0",
42
-    "@semantic-release/git": "7.0.16",
43
-    "@types/invariant": "^2.2.30",
44
-    "@types/jest": "24.0.18",
45
-    "@types/react": "16.8.8",
46
-    "@types/react-native": "0.60.11",
47
-    "@typescript-eslint/eslint-plugin": "2.1.0",
48
-    "@typescript-eslint/parser": "2.1.0",
49
-    "babel-eslint": "10.0.3",
50
-    "babel-jest": "24.8.0",
51
-    "babel-plugin-module-resolver": "3.1.3",
52
-    "eslint": "6.3.0",
53
-    "eslint-config-airbnb": "18.0.1",
54
-    "eslint-config-prettier": "6.2.0",
55
-    "eslint-plugin-import": "2.18.2",
56
-    "eslint-plugin-jsx-a11y": "6.2.3",
57
-    "eslint-plugin-react": "7.14.3",
58
-    "eslint-plugin-react-native": "3.7.0",
59
-    "jest": "24.9.0",
60
-    "metro-react-native-babel-preset": "0.54.1",
61
-    "react": "16.9.0",
62
-    "react-native": "0.61.5",
63
-    "react-native-macos": "0.60.0-microsoft.49",
64
-    "semantic-release": "15.13.24",
65
-    "typescript": "3.6.2"
66
-  },
67
-  "repository": {
68
-    "type": "git",
69
-    "url": "https://github.com/react-native-community/react-native-webview.git"
70
-  },
71
-  "files": [
72
-    "android",
73
-    "ios",
74
-    "macos",
75
-    "lib",
76
-    "index.js",
77
-    "index.d.ts",
78
-    "react-native-webview.podspec"
79
-  ]
80
-}
1
+{
2
+  "name": "react-native-webview",
3
+  "description": "React Native WebView component for iOS, Android, macOS, and Windows",
4
+  "main": "index.js",
5
+  "typings": "index.d.ts",
6
+  "author": "Jamon Holmgren <jamon@infinite.red>",
7
+  "contributors": [
8
+    "Thibault Malbranche <malbranche.thibault@gmail.com>"
9
+  ],
10
+  "license": "MIT",
11
+  "version": "9.0.1",
12
+  "homepage": "https://github.com/react-native-community/react-native-webview#readme",
13
+  "scripts": {
14
+    "start": "node node_modules/react-native/local-cli/cli.js start",
15
+    "start:android": "react-native run-android --root example/",
16
+    "start:ios": "react-native run-ios --project-path example/ios --scheme example",
17
+    "start:macos": "node node_modules/react-native-macos/local-cli/cli.js start --use-react-native-macos",
18
+    "start:windows": "react-native start --use-react-native-windows",
19
+    "ci": "CI=true && yarn lint && yarn test",
20
+    "ci:publish": "yarn semantic-release",
21
+    "lint": "yarn tsc --noEmit && yarn eslint ./src --ext .ts,.tsx",
22
+    "build": "yarn tsc",
23
+    "prepare": "yarn build",
24
+    "test": "yarn jest"
25
+  },
26
+  "rn-docs": {
27
+    "title": "Webview",
28
+    "type": "Component"
29
+  },
30
+  "peerDependencies": {
31
+    "react": "^16.9",
32
+    "react-native": ">=0.60 <0.62",
33
+    "react-native-windows": "^0.61.0-beta.58"
34
+  },
35
+  "dependencies": {
36
+    "escape-string-regexp": "2.0.0",
37
+    "invariant": "2.2.4",
38
+    "rnpm-plugin-windows": "^0.5.1-0"
39
+  },
40
+  "devDependencies": {
41
+    "@babel/core": "7.4.5",
42
+    "@babel/runtime": "7.4.5",
43
+    "@react-native-community/cli": "^3.2.0",
44
+    "@react-native-community/cli-platform-android": "^3.0.0",
45
+    "@react-native-community/cli-platform-ios": "^3.0.0",
46
+    "@semantic-release/git": "7.0.16",
47
+    "@types/invariant": "^2.2.30",
48
+    "@types/jest": "24.0.18",
49
+    "@types/react": "16.8.8",
50
+    "@types/react-native": "0.60.11",
51
+    "@typescript-eslint/eslint-plugin": "2.1.0",
52
+    "@typescript-eslint/parser": "2.1.0",
53
+    "babel-eslint": "10.0.3",
54
+    "babel-jest": "24.8.0",
55
+    "babel-plugin-module-resolver": "3.1.3",
56
+    "eslint": "6.3.0",
57
+    "eslint-config-airbnb": "18.0.1",
58
+    "eslint-config-prettier": "6.2.0",
59
+    "eslint-plugin-import": "2.18.2",
60
+    "eslint-plugin-jsx-a11y": "6.2.3",
61
+    "eslint-plugin-react": "7.14.3",
62
+    "eslint-plugin-react-native": "3.7.0",
63
+    "jest": "24.9.0",
64
+    "metro-react-native-babel-preset": "0.54.1",
65
+    "react": "16.9.0",
66
+    "react-native": "0.61.5",
67
+    "react-native-macos": "0.60.0-microsoft.49",
68
+    "react-native-windows": "^0.61.0-beta.58",
69
+    "semantic-release": "15.13.24",
70
+    "typescript": "3.6.2"
71
+  },
72
+  "repository": {
73
+    "type": "git",
74
+    "url": "https://github.com/react-native-community/react-native-webview.git"
75
+  },
76
+  "files": [
77
+    "android",
78
+    "ios",
79
+    "macos",
80
+    "windows",
81
+    "lib",
82
+    "index.js",
83
+    "index.d.ts",
84
+    "react-native-webview.podspec"
85
+  ]
86
+}

+ 8
- 0
react-native.config.js View File

16
 'use strict';
16
 'use strict';
17
 
17
 
18
 const macSwitch = '--use-react-native-macos';
18
 const macSwitch = '--use-react-native-macos';
19
+const windowsSwitch = '--use-react-native-windows';
19
 
20
 
20
 if (process.argv.includes(macSwitch)) {
21
 if (process.argv.includes(macSwitch)) {
21
   process.argv = process.argv.filter(arg => arg !== macSwitch);
22
   process.argv = process.argv.filter(arg => arg !== macSwitch);
23
   module.exports = {
24
   module.exports = {
24
     reactNativePath: 'node_modules/react-native-macos',
25
     reactNativePath: 'node_modules/react-native-macos',
25
   };
26
   };
27
+}
28
+else if (process.argv.includes(windowsSwitch)) {
29
+  process.argv = process.argv.filter(arg => arg !== windowsSwitch);
30
+  process.argv.push('--config=metro.config.windows.js');
31
+  module.exports = {
32
+    reactNativePath: 'node_modules/react-native-windows',
33
+  };
26
 }
34
 }

+ 6
- 0
src/WebView.ios.tsx View File

290
       originWhitelist,
290
       originWhitelist,
291
       renderError,
291
       renderError,
292
       renderLoading,
292
       renderLoading,
293
+      injectedJavaScriptForMainFrameOnly = true,
294
+      injectedJavaScriptBeforeContentLoadedForMainFrameOnly = true,
293
       style,
295
       style,
294
       containerStyle,
296
       containerStyle,
295
       ...otherProps
297
       ...otherProps
344
         onScroll={this.props.onScroll}
346
         onScroll={this.props.onScroll}
345
         onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
347
         onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
346
         onContentProcessDidTerminate={this.onContentProcessDidTerminate}
348
         onContentProcessDidTerminate={this.onContentProcessDidTerminate}
349
+        injectedJavaScript={this.props.injectedJavaScript}
350
+        injectedJavaScriptBeforeContentLoaded={this.props.injectedJavaScriptBeforeContentLoaded}
351
+        injectedJavaScriptForMainFrameOnly={injectedJavaScriptForMainFrameOnly}
352
+        injectedJavaScriptBeforeContentLoadedForMainFrameOnly={injectedJavaScriptBeforeContentLoadedForMainFrameOnly}
347
         ref={this.webViewRef}
353
         ref={this.webViewRef}
348
         // TODO: find a better way to type this.
354
         // TODO: find a better way to type this.
349
         source={resolveAssetSource(this.props.source as ImageSourcePropType)}
355
         source={resolveAssetSource(this.props.source as ImageSourcePropType)}

+ 258
- 0
src/WebView.windows.tsx View File

1
+/**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * Portions copyright for react-native-windows:
8
+ *
9
+ * Copyright (c) Microsoft Corporation. All rights reserved.
10
+ * Licensed under the MIT License.
11
+ */
12
+
13
+import React from 'react';
14
+import {
15
+  UIManager as NotTypedUIManager,
16
+  View,
17
+  requireNativeComponent,
18
+  StyleSheet,
19
+  Image,
20
+  ImageSourcePropType,
21
+  findNodeHandle,
22
+} from 'react-native';
23
+import {
24
+  createOnShouldStartLoadWithRequest,
25
+} from './WebViewShared';
26
+import {
27
+  NativeWebViewWindows,
28
+  WebViewSharedProps,
29
+  WebViewProgressEvent,
30
+  WebViewNavigationEvent,
31
+  WebViewErrorEvent,
32
+  WebViewHttpErrorEvent,
33
+  WebViewMessageEvent,
34
+  RNCWebViewUIManagerWindows,
35
+  State,
36
+} from './WebViewTypes';
37
+
38
+const UIManager = NotTypedUIManager as RNCWebViewUIManagerWindows;
39
+const { resolveAssetSource } = Image;
40
+const RCTWebView: typeof NativeWebViewWindows = requireNativeComponent(
41
+  'RCTWebView',
42
+);
43
+
44
+const styles = StyleSheet.create({
45
+  container: {
46
+    flex: 1,
47
+  },
48
+  hidden: {
49
+    height: 0,
50
+    flex: 0, // disable 'flex:1' when hiding a View
51
+  },
52
+  loadingView: {
53
+    flex: 1,
54
+    justifyContent: 'center',
55
+    alignItems: 'center',
56
+  },
57
+  loadingProgressBar: {
58
+    height: 20,
59
+  },
60
+});
61
+
62
+export default class WebView extends React.Component<WebViewSharedProps, State> {
63
+
64
+  static defaultProps = {
65
+    javaScriptEnabled: true,
66
+  };
67
+
68
+  state: State = {
69
+    viewState: this.props.startInLoadingState ? 'LOADING' : 'IDLE',
70
+    lastErrorEvent: null,
71
+  }
72
+
73
+  webViewRef = React.createRef<NativeWebViewWindows>();
74
+
75
+  goForward = () => {
76
+    UIManager.dispatchViewManagerCommand(
77
+      this.getWebViewHandle(),
78
+      UIManager.getViewManagerConfig('RCTWebView').Commands.goForward,
79
+      undefined,
80
+    );
81
+  }
82
+
83
+  goBack = () => {
84
+    UIManager.dispatchViewManagerCommand(
85
+      this.getWebViewHandle(),
86
+      UIManager.getViewManagerConfig('RCTWebView').Commands.goBack,
87
+      undefined,
88
+    );
89
+  }
90
+
91
+  reload = () => {
92
+    UIManager.dispatchViewManagerCommand(
93
+      this.getWebViewHandle(),
94
+      UIManager.getViewManagerConfig('RCTWebView').Commands.reload,
95
+      undefined,
96
+    );
97
+  }
98
+
99
+  injectJavaScript = (data: string) => {
100
+    UIManager.dispatchViewManagerCommand(
101
+      this.getWebViewHandle(),
102
+      UIManager.getViewManagerConfig('RCTWebView').Commands.injectJavaScript,
103
+      [data],
104
+    );
105
+  }
106
+
107
+  /**
108
+   * We return an event with a bunch of fields including:
109
+   *  url, title, loading, canGoBack, canGoForward
110
+   */
111
+  updateNavigationState = (event: WebViewNavigationEvent) => {
112
+    if (this.props.onNavigationStateChange) {
113
+      this.props.onNavigationStateChange(event.nativeEvent);
114
+    }
115
+  }
116
+
117
+  getWebViewHandle = () => {
118
+    // eslint-disable-next-line react/no-string-refs
119
+    return findNodeHandle(this.webViewRef.current);
120
+  }
121
+
122
+  onLoadingStart = (event: WebViewNavigationEvent) => {
123
+    const { onLoadStart } = this.props;
124
+    if(onLoadStart) {
125
+      onLoadStart(event);
126
+    }
127
+    this.updateNavigationState(event);
128
+  }
129
+
130
+  onLoadingProgress = (event: WebViewProgressEvent) => {
131
+    const { onLoadProgress } = this.props;
132
+    if (onLoadProgress) {
133
+      onLoadProgress(event);
134
+    }
135
+  };
136
+
137
+  onLoadingError = (event: WebViewErrorEvent) => {
138
+    event.persist(); // persist this event because we need to store it
139
+    const {onError, onLoadEnd} = this.props;
140
+    if(onError) {
141
+      onError(event);
142
+    }
143
+    if(onLoadEnd) {
144
+      onLoadEnd(event);
145
+    }
146
+    console.error('Encountered an error loading page', event.nativeEvent);
147
+    this.setState({
148
+      lastErrorEvent: event.nativeEvent,
149
+      viewState: 'ERROR',
150
+    });
151
+  }
152
+
153
+  onLoadingFinish =(event: WebViewNavigationEvent) => {
154
+    const {onLoad, onLoadEnd} = this.props;
155
+    if(onLoad) {
156
+      onLoad(event);
157
+    }
158
+    if(onLoadEnd) {
159
+      onLoadEnd(event);
160
+    }
161
+    this.setState({
162
+      viewState: 'IDLE',
163
+    });
164
+    this.updateNavigationState(event);
165
+  }
166
+
167
+  onMessage = (event: WebViewMessageEvent) => {
168
+    const { onMessage } = this.props;
169
+    if (onMessage) {
170
+      onMessage(event);
171
+    }
172
+  }
173
+
174
+  onHttpError = (event: WebViewHttpErrorEvent) => {
175
+    const { onHttpError } = this.props;
176
+    if (onHttpError) {
177
+      onHttpError(event);
178
+    }
179
+  }
180
+
181
+  render () {
182
+    const {
183
+      nativeConfig = {},
184
+      onMessage,
185
+      onShouldStartLoadWithRequest: onShouldStartLoadWithRequestProp,
186
+      originWhitelist,
187
+      renderError,
188
+      renderLoading,
189
+      style,
190
+      containerStyle,
191
+      ...otherProps
192
+    } = this.props;
193
+
194
+    let otherView = null;
195
+
196
+    if (this.state.viewState === 'LOADING') {
197
+      otherView = this.props.renderLoading && this.props.renderLoading();
198
+    } else if (this.state.viewState === 'ERROR') {
199
+      const errorEvent = this.state.lastErrorEvent;
200
+      otherView = this.props.renderError
201
+        && this.props.renderError(
202
+          errorEvent.domain,
203
+          errorEvent.code,
204
+          errorEvent.description,
205
+        );
206
+    } else if (this.state.viewState !== 'IDLE') {
207
+      console.error('RCTWebView invalid state encountered: ', this.state.viewState);
208
+    }
209
+
210
+    const webViewStyles = [styles.container, this.props.style];
211
+    if (
212
+      this.state.viewState === 'LOADING'
213
+      || this.state.viewState === 'ERROR'
214
+    ) {
215
+      // if we're in either LOADING or ERROR states, don't show the webView
216
+      webViewStyles.push(styles.hidden);
217
+    }
218
+
219
+    const onShouldStartLoadWithRequest = createOnShouldStartLoadWithRequest(
220
+      ()=>{},
221
+      // casting cause it's in the default props
222
+      originWhitelist as readonly string[],
223
+      onShouldStartLoadWithRequestProp,
224
+    );
225
+
226
+    const NativeWebView
227
+    = (nativeConfig.component as typeof NativeWebViewWindows | undefined)
228
+    || RCTWebView;
229
+
230
+    const webView = (
231
+      <NativeWebView
232
+        ref={this.webViewRef}
233
+        key="webViewKey"
234
+        {...otherProps}
235
+        messagingEnabled={typeof onMessage === 'function'}
236
+        onLoadingError={this.onLoadingError}
237
+        onLoadingFinish={this.onLoadingFinish}
238
+        onLoadingProgress={this.onLoadingProgress}
239
+        onLoadingStart={this.onLoadingStart}
240
+        onHttpError={this.onHttpError}
241
+        onMessage={this.onMessage}
242
+        onScroll={this.props.onScroll}
243
+        onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
244
+        source={resolveAssetSource(this.props.source as ImageSourcePropType)}
245
+        style={webViewStyles}
246
+        {...nativeConfig.props}
247
+      />
248
+    );
249
+
250
+    return (
251
+      <View style={styles.container}>
252
+        {webView}
253
+        {otherView}
254
+      </View>
255
+    );
256
+  }
257
+
258
+}

+ 29
- 0
src/WebViewTypes.ts View File

29
 export type RNCWebViewUIManagerAndroid = RNCWebViewUIManager<WebViewCommands | AndroidWebViewCommands>
29
 export type RNCWebViewUIManagerAndroid = RNCWebViewUIManager<WebViewCommands | AndroidWebViewCommands>
30
 export type RNCWebViewUIManagerIOS = RNCWebViewUIManager<WebViewCommands>
30
 export type RNCWebViewUIManagerIOS = RNCWebViewUIManager<WebViewCommands>
31
 export type RNCWebViewUIManagerMacOS = RNCWebViewUIManager<WebViewCommands>
31
 export type RNCWebViewUIManagerMacOS = RNCWebViewUIManager<WebViewCommands>
32
+export type RNCWebViewUIManagerWindows = RNCWebViewUIManager<WebViewCommands>
32
 
33
 
33
 
34
 
34
 type WebViewState = 'IDLE' | 'LOADING' | 'ERROR';
35
 type WebViewState = 'IDLE' | 'LOADING' | 'ERROR';
73
   typeof NativeWebViewAndroidComponent;
74
   typeof NativeWebViewAndroidComponent;
74
 export class NativeWebViewAndroid extends NativeWebViewAndroidBase {}
75
 export class NativeWebViewAndroid extends NativeWebViewAndroidBase {}
75
 
76
 
77
+// eslint-disable-next-line react/prefer-stateless-function
78
+declare class NativeWebViewWindowsComponent extends Component<
79
+  WindowsNativeWebViewProps
80
+> {}
81
+declare const NativeWebViewWindowsBase: Constructor<NativeMethodsMixin> &
82
+  typeof NativeWebViewWindowsComponent;
83
+export class NativeWebViewWindows extends NativeWebViewWindowsBase {}
84
+
76
 export interface ContentInsetProp {
85
 export interface ContentInsetProp {
77
   top?: number;
86
   top?: number;
78
   left?: number;
87
   left?: number;
290
   scrollEnabled?: boolean;
299
   scrollEnabled?: boolean;
291
   useSharedProcessPool?: boolean;
300
   useSharedProcessPool?: boolean;
292
   onContentProcessDidTerminate?: (event: WebViewTerminatedEvent) => void;
301
   onContentProcessDidTerminate?: (event: WebViewTerminatedEvent) => void;
302
+  injectedJavaScriptForMainFrameOnly?: boolean;
303
+  injectedJavaScriptBeforeContentLoadedForMainFrameOnly?: boolean;
293
 }
304
 }
294
 
305
 
295
 export interface MacOSNativeWebViewProps extends CommonNativeWebViewProps {
306
 export interface MacOSNativeWebViewProps extends CommonNativeWebViewProps {
309
   onContentProcessDidTerminate?: (event: WebViewTerminatedEvent) => void;
320
   onContentProcessDidTerminate?: (event: WebViewTerminatedEvent) => void;
310
 }
321
 }
311
 
322
 
323
+export interface WindowsNativeWebViewProps extends CommonNativeWebViewProps {
324
+  testID?: string
325
+}
326
+
312
 export interface IOSWebViewProps extends WebViewSharedProps {
327
 export interface IOSWebViewProps extends WebViewSharedProps {
313
   /**
328
   /**
314
    * Does not store any data within the lifetime of the WebView.
329
    * Does not store any data within the lifetime of the WebView.
482
    * @platform ios
497
    * @platform ios
483
    */
498
    */
484
   onContentProcessDidTerminate?: (event: WebViewTerminatedEvent) => void;
499
   onContentProcessDidTerminate?: (event: WebViewTerminatedEvent) => void;
500
+
501
+  /**
502
+   * If `true` (default), loads the `injectedJavaScript` only into the main frame.
503
+   * If `false`, loads it into all frames (e.g. iframes).
504
+   * @platform ios
505
+  */
506
+  injectedJavaScriptForMainFrameOnly?: boolean;
507
+
508
+  /**
509
+   * If `true` (default), loads the `injectedJavaScriptBeforeContentLoaded` only into the main frame.
510
+   * If `false`, loads it into all frames (e.g. iframes).
511
+   * @platform ios
512
+  */
513
+  injectedJavaScriptBeforeContentLoadedForMainFrameOnly?: boolean;
485
 }
514
 }
486
 
515
 
487
 export interface MacOSWebViewProps extends WebViewSharedProps {
516
 export interface MacOSWebViewProps extends WebViewSharedProps {

+ 353
- 0
windows/.gitignore View File

1
+## Ignore Visual Studio temporary files, build results, and
2
+## files generated by popular Visual Studio add-ons.
3
+##
4
+## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5
+
6
+# User-specific files
7
+*.rsuser
8
+*.suo
9
+*.user
10
+*.userosscache
11
+*.sln.docstates
12
+
13
+# User-specific files (MonoDevelop/Xamarin Studio)
14
+*.userprefs
15
+
16
+# Mono auto generated files
17
+mono_crash.*
18
+
19
+# Build results
20
+[Dd]ebug/
21
+[Dd]ebugPublic/
22
+[Rr]elease/
23
+[Rr]eleases/
24
+x64/
25
+x86/
26
+[Aa][Rr][Mm]/
27
+[Aa][Rr][Mm]64/
28
+bld/
29
+[Bb]in/
30
+[Oo]bj/
31
+[Ll]og/
32
+[Ll]ogs/
33
+
34
+# Visual Studio 2015/2017 cache/options directory
35
+.vs/
36
+# Uncomment if you have tasks that create the project's static files in wwwroot
37
+#wwwroot/
38
+
39
+# Visual Studio 2017 auto generated files
40
+Generated\ Files/
41
+
42
+# MSTest test Results
43
+[Tt]est[Rr]esult*/
44
+[Bb]uild[Ll]og.*
45
+
46
+# NUnit
47
+*.VisualState.xml
48
+TestResult.xml
49
+nunit-*.xml
50
+
51
+# Build Results of an ATL Project
52
+[Dd]ebugPS/
53
+[Rr]eleasePS/
54
+dlldata.c
55
+
56
+# Benchmark Results
57
+BenchmarkDotNet.Artifacts/
58
+
59
+# .NET Core
60
+project.lock.json
61
+project.fragment.lock.json
62
+artifacts/
63
+
64
+# StyleCop
65
+StyleCopReport.xml
66
+
67
+# Files built by Visual Studio
68
+*_i.c
69
+*_p.c
70
+*_h.h
71
+*.ilk
72
+*.meta
73
+*.obj
74
+*.iobj
75
+*.pch
76
+*.pdb
77
+*.ipdb
78
+*.pgc
79
+*.pgd
80
+*.rsp
81
+*.sbr
82
+*.tlb
83
+*.tli
84
+*.tlh
85
+*.tmp
86
+*.tmp_proj
87
+*_wpftmp.csproj
88
+*.log
89
+*.vspscc
90
+*.vssscc
91
+.builds
92
+*.pidb
93
+*.svclog
94
+*.scc
95
+
96
+# Chutzpah Test files
97
+_Chutzpah*
98
+
99
+# Visual C++ cache files
100
+ipch/
101
+*.aps
102
+*.ncb
103
+*.opendb
104
+*.opensdf
105
+*.sdf
106
+*.cachefile
107
+*.VC.db
108
+*.VC.VC.opendb
109
+
110
+# Visual Studio profiler
111
+*.psess
112
+*.vsp
113
+*.vspx
114
+*.sap
115
+
116
+# Visual Studio Trace Files
117
+*.e2e
118
+
119
+# TFS 2012 Local Workspace
120
+$tf/
121
+
122
+# Guidance Automation Toolkit
123
+*.gpState
124
+
125
+# ReSharper is a .NET coding add-in
126
+_ReSharper*/
127
+*.[Rr]e[Ss]harper
128
+*.DotSettings.user
129
+
130
+# TeamCity is a build add-in
131
+_TeamCity*
132
+
133
+# DotCover is a Code Coverage Tool
134
+*.dotCover
135
+
136
+# AxoCover is a Code Coverage Tool
137
+.axoCover/*
138
+!.axoCover/settings.json
139
+
140
+# Coverlet is a free, cross platform Code Coverage Tool
141
+coverage*[.json, .xml, .info]
142
+
143
+# Visual Studio code coverage results
144
+*.coverage
145
+*.coveragexml
146
+
147
+# NCrunch
148
+_NCrunch_*
149
+.*crunch*.local.xml
150
+nCrunchTemp_*
151
+
152
+# MightyMoose
153
+*.mm.*
154
+AutoTest.Net/
155
+
156
+# Web workbench (sass)
157
+.sass-cache/
158
+
159
+# Installshield output folder
160
+[Ee]xpress/
161
+
162
+# DocProject is a documentation generator add-in
163
+DocProject/buildhelp/
164
+DocProject/Help/*.HxT
165
+DocProject/Help/*.HxC
166
+DocProject/Help/*.hhc
167
+DocProject/Help/*.hhk
168
+DocProject/Help/*.hhp
169
+DocProject/Help/Html2
170
+DocProject/Help/html
171
+
172
+# Click-Once directory
173
+publish/
174
+
175
+# Publish Web Output
176
+*.[Pp]ublish.xml
177
+*.azurePubxml
178
+# Note: Comment the next line if you want to checkin your web deploy settings,
179
+# but database connection strings (with potential passwords) will be unencrypted
180
+*.pubxml
181
+*.publishproj
182
+
183
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
184
+# checkin your Azure Web App publish settings, but sensitive information contained
185
+# in these scripts will be unencrypted
186
+PublishScripts/
187
+
188
+# NuGet Packages
189
+*.nupkg
190
+# NuGet Symbol Packages
191
+*.snupkg
192
+# The packages folder can be ignored because of Package Restore
193
+**/[Pp]ackages/*
194
+# except build/, which is used as an MSBuild target.
195
+!**/[Pp]ackages/build/
196
+# Uncomment if necessary however generally it will be regenerated when needed
197
+#!**/[Pp]ackages/repositories.config
198
+# NuGet v3's project.json files produces more ignorable files
199
+*.nuget.props
200
+*.nuget.targets
201
+
202
+# Microsoft Azure Build Output
203
+csx/
204
+*.build.csdef
205
+
206
+# Microsoft Azure Emulator
207
+ecf/
208
+rcf/
209
+
210
+# Windows Store app package directories and files
211
+AppPackages/
212
+BundleArtifacts/
213
+Package.StoreAssociation.xml
214
+_pkginfo.txt
215
+*.appx
216
+*.appxbundle
217
+*.appxupload
218
+
219
+# Visual Studio cache files
220
+# files ending in .cache can be ignored
221
+*.[Cc]ache
222
+# but keep track of directories ending in .cache
223
+!?*.[Cc]ache/
224
+
225
+# Others
226
+ClientBin/
227
+~$*
228
+*~
229
+*.dbmdl
230
+*.dbproj.schemaview
231
+*.jfm
232
+*.pfx
233
+*.publishsettings
234
+orleans.codegen.cs
235
+
236
+# Including strong name files can present a security risk
237
+# (https://github.com/github/gitignore/pull/2483#issue-259490424)
238
+#*.snk
239
+
240
+# Since there are multiple workflows, uncomment next line to ignore bower_components
241
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
242
+#bower_components/
243
+
244
+# RIA/Silverlight projects
245
+Generated_Code/
246
+
247
+# Backup & report files from converting an old project file
248
+# to a newer Visual Studio version. Backup files are not needed,
249
+# because we have git ;-)
250
+_UpgradeReport_Files/
251
+Backup*/
252
+UpgradeLog*.XML
253
+UpgradeLog*.htm
254
+ServiceFabricBackup/
255
+*.rptproj.bak
256
+
257
+# SQL Server files
258
+*.mdf
259
+*.ldf
260
+*.ndf
261
+
262
+# Business Intelligence projects
263
+*.rdl.data
264
+*.bim.layout
265
+*.bim_*.settings
266
+*.rptproj.rsuser
267
+*- [Bb]ackup.rdl
268
+*- [Bb]ackup ([0-9]).rdl
269
+*- [Bb]ackup ([0-9][0-9]).rdl
270
+
271
+# Microsoft Fakes
272
+FakesAssemblies/
273
+
274
+# GhostDoc plugin setting file
275
+*.GhostDoc.xml
276
+
277
+# Node.js Tools for Visual Studio
278
+.ntvs_analysis.dat
279
+node_modules/
280
+
281
+# Visual Studio 6 build log
282
+*.plg
283
+
284
+# Visual Studio 6 workspace options file
285
+*.opt
286
+
287
+# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
288
+*.vbw
289
+
290
+# Visual Studio LightSwitch build output
291
+**/*.HTMLClient/GeneratedArtifacts
292
+**/*.DesktopClient/GeneratedArtifacts
293
+**/*.DesktopClient/ModelManifest.xml
294
+**/*.Server/GeneratedArtifacts
295
+**/*.Server/ModelManifest.xml
296
+_Pvt_Extensions
297
+
298
+# Paket dependency manager
299
+.paket/paket.exe
300
+paket-files/
301
+
302
+# FAKE - F# Make
303
+.fake/
304
+
305
+# CodeRush personal settings
306
+.cr/personal
307
+
308
+# Python Tools for Visual Studio (PTVS)
309
+__pycache__/
310
+*.pyc
311
+
312
+# Cake - Uncomment if you are using it
313
+# tools/**
314
+# !tools/packages.config
315
+
316
+# Tabs Studio
317
+*.tss
318
+
319
+# Telerik's JustMock configuration file
320
+*.jmconfig
321
+
322
+# BizTalk build output
323
+*.btp.cs
324
+*.btm.cs
325
+*.odx.cs
326
+*.xsd.cs
327
+
328
+# OpenCover UI analysis results
329
+OpenCover/
330
+
331
+# Azure Stream Analytics local run output
332
+ASALocalRun/
333
+
334
+# MSBuild Binary and Structured Log
335
+*.binlog
336
+
337
+# NVidia Nsight GPU debugger configuration file
338
+*.nvuser
339
+
340
+# MFractors (Xamarin productivity tool) working folder
341
+.mfractor/
342
+
343
+# Local History for Visual Studio
344
+.localhistory/
345
+
346
+# BeatPulse healthcheck temp database
347
+healthchecksdb
348
+
349
+# Backup folder for Package Reference Convert tool in Visual Studio 2017
350
+MigrationBackup/
351
+
352
+# Ionide (cross platform F# VS Code tools) working folder
353
+.ionide/

+ 204
- 0
windows/ReactNativeWebView.sln View File

1
+
2
+Microsoft Visual Studio Solution File, Format Version 12.00
3
+# Visual Studio Version 16
4
+VisualStudioVersion = 16.0.29609.76
5
+MinimumVisualStudioVersion = 10.0.40219.1
6
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ReactNativeWebView", "ReactNativeWebView\ReactNativeWebView.vcxproj", "{729D9AF8-CD9E-4427-9F6C-FB757E287729}"
7
+EndProject
8
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ReactNative", "ReactNative", "{6030669C-4F4D-4889-B38E-0299826D8C01}"
9
+EndProject
10
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Chakra", "..\node_modules\react-native-windows\Chakra\Chakra.vcxitems", "{C38970C0-5FBF-4D69-90D8-CBAC225AE895}"
11
+EndProject
12
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Common", "..\node_modules\react-native-windows\Common\Common.vcxproj", "{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}"
13
+EndProject
14
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Folly", "..\node_modules\react-native-windows\Folly\Folly.vcxproj", "{A990658C-CE31-4BCC-976F-0FC6B1AF693D}"
15
+EndProject
16
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JSI.Shared", "..\node_modules\react-native-windows\JSI\Shared\JSI.Shared.vcxitems", "{0CC28589-39E4-4288-B162-97B959F8B843}"
17
+EndProject
18
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JSI.Universal", "..\node_modules\react-native-windows\JSI\Universal\JSI.Universal.vcxproj", "{A62D504A-16B8-41D2-9F19-E2E86019E5E4}"
19
+EndProject
20
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.ReactNative", "..\node_modules\react-native-windows\Microsoft.ReactNative\Microsoft.ReactNative.vcxproj", "{F7D32BD0-2749-483E-9A0D-1635EF7E3136}"
21
+EndProject
22
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.ReactNative.Cxx", "..\node_modules\react-native-windows\Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems", "{DA8B35B3-DA00-4B02-BDE6-6A397B3FD46B}"
23
+EndProject
24
+Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Microsoft.ReactNative.SharedManaged", "..\node_modules\react-native-windows\Microsoft.ReactNative.SharedManaged\Microsoft.ReactNative.SharedManaged.shproj", "{67A1076F-7790-4203-86EA-4402CCB5E782}"
25
+EndProject
26
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ReactCommon", "..\node_modules\react-native-windows\ReactCommon\ReactCommon.vcxproj", "{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}"
27
+EndProject
28
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ReactUWP", "..\node_modules\react-native-windows\ReactUWP\ReactUWP.vcxproj", "{2D5D43D9-CFFC-4C40-B4CD-02EFB4E2742B}"
29
+EndProject
30
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ReactWindowsCore", "..\node_modules\react-native-windows\ReactWindowsCore\ReactWindowsCore.vcxproj", "{11C084A3-A57C-4296-A679-CAC17B603144}"
31
+EndProject
32
+Global
33
+	GlobalSection(SharedMSBuildProjectFiles) = preSolution
34
+		..\node_modules\react-native-windows\JSI\Shared\JSI.Shared.vcxitems*{0cc28589-39e4-4288-b162-97b959f8b843}*SharedItemsImports = 9
35
+		..\node_modules\react-native-windows\Chakra\Chakra.vcxitems*{2d5d43d9-cffc-4c40-b4cd-02efb4e2742b}*SharedItemsImports = 4
36
+		..\node_modules\react-native-windows\Shared\Shared.vcxitems*{2d5d43d9-cffc-4c40-b4cd-02efb4e2742b}*SharedItemsImports = 4
37
+		..\node_modules\react-native-windows\Microsoft.ReactNative.SharedManaged\Microsoft.ReactNative.SharedManaged.projitems*{67a1076f-7790-4203-86ea-4402ccb5e782}*SharedItemsImports = 13
38
+		..\node_modules\react-native-windows\Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems*{729d9af8-cd9e-4427-9f6c-fb757e287729}*SharedItemsImports = 4
39
+		..\node_modules\react-native-windows\JSI\Shared\JSI.Shared.vcxitems*{a62d504a-16b8-41d2-9f19-e2e86019e5e4}*SharedItemsImports = 4
40
+		..\node_modules\react-native-windows\Chakra\Chakra.vcxitems*{c38970c0-5fbf-4d69-90d8-cbac225ae895}*SharedItemsImports = 9
41
+		..\node_modules\react-native-windows\Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems*{da8b35b3-da00-4b02-bde6-6a397b3fd46b}*SharedItemsImports = 9
42
+		..\node_modules\react-native-windows\Chakra\Chakra.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4
43
+		..\node_modules\react-native-windows\JSI\Shared\JSI.Shared.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4
44
+		..\node_modules\react-native-windows\Mso\Mso.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4
45
+		..\node_modules\react-native-windows\Shared\Shared.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4
46
+	EndGlobalSection
47
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
48
+		Debug|ARM = Debug|ARM
49
+		Debug|ARM64 = Debug|ARM64
50
+		Debug|x64 = Debug|x64
51
+		Debug|x86 = Debug|x86
52
+		Release|ARM = Release|ARM
53
+		Release|ARM64 = Release|ARM64
54
+		Release|x64 = Release|x64
55
+		Release|x86 = Release|x86
56
+	EndGlobalSection
57
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
58
+		{729D9AF8-CD9E-4427-9F6C-FB757E287729}.Debug|ARM.ActiveCfg = Debug|ARM
59
+		{729D9AF8-CD9E-4427-9F6C-FB757E287729}.Debug|ARM.Build.0 = Debug|ARM
60
+		{729D9AF8-CD9E-4427-9F6C-FB757E287729}.Debug|ARM64.ActiveCfg = Debug|Win32
61
+		{729D9AF8-CD9E-4427-9F6C-FB757E287729}.Debug|x64.ActiveCfg = Debug|x64
62
+		{729D9AF8-CD9E-4427-9F6C-FB757E287729}.Debug|x64.Build.0 = Debug|x64
63
+		{729D9AF8-CD9E-4427-9F6C-FB757E287729}.Debug|x86.ActiveCfg = Debug|Win32
64
+		{729D9AF8-CD9E-4427-9F6C-FB757E287729}.Debug|x86.Build.0 = Debug|Win32
65
+		{729D9AF8-CD9E-4427-9F6C-FB757E287729}.Release|ARM.ActiveCfg = Release|ARM
66
+		{729D9AF8-CD9E-4427-9F6C-FB757E287729}.Release|ARM.Build.0 = Release|ARM
67
+		{729D9AF8-CD9E-4427-9F6C-FB757E287729}.Release|ARM64.ActiveCfg = Release|Win32
68
+		{729D9AF8-CD9E-4427-9F6C-FB757E287729}.Release|x64.ActiveCfg = Release|x64
69
+		{729D9AF8-CD9E-4427-9F6C-FB757E287729}.Release|x64.Build.0 = Release|x64
70
+		{729D9AF8-CD9E-4427-9F6C-FB757E287729}.Release|x86.ActiveCfg = Release|Win32
71
+		{729D9AF8-CD9E-4427-9F6C-FB757E287729}.Release|x86.Build.0 = Release|Win32
72
+		{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|ARM.ActiveCfg = Debug|ARM
73
+		{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|ARM.Build.0 = Debug|ARM
74
+		{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|ARM64.ActiveCfg = Debug|ARM64
75
+		{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|ARM64.Build.0 = Debug|ARM64
76
+		{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|x64.ActiveCfg = Debug|x64
77
+		{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|x64.Build.0 = Debug|x64
78
+		{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|x86.ActiveCfg = Debug|Win32
79
+		{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|x86.Build.0 = Debug|Win32
80
+		{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|ARM.ActiveCfg = Release|ARM
81
+		{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|ARM.Build.0 = Release|ARM
82
+		{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|ARM64.ActiveCfg = Release|ARM64
83
+		{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|ARM64.Build.0 = Release|ARM64
84
+		{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x64.ActiveCfg = Release|x64
85
+		{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x64.Build.0 = Release|x64
86
+		{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x86.ActiveCfg = Release|Win32
87
+		{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x86.Build.0 = Release|Win32
88
+		{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|ARM.ActiveCfg = Debug|ARM
89
+		{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|ARM.Build.0 = Debug|ARM
90
+		{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|ARM64.ActiveCfg = Debug|ARM64
91
+		{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|ARM64.Build.0 = Debug|ARM64
92
+		{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|x64.ActiveCfg = Debug|x64
93
+		{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|x64.Build.0 = Debug|x64
94
+		{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|x86.ActiveCfg = Debug|Win32
95
+		{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|x86.Build.0 = Debug|Win32
96
+		{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|ARM.ActiveCfg = Release|ARM
97
+		{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|ARM.Build.0 = Release|ARM
98
+		{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|ARM64.ActiveCfg = Release|ARM64
99
+		{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|ARM64.Build.0 = Release|ARM64
100
+		{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x64.ActiveCfg = Release|x64
101
+		{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x64.Build.0 = Release|x64
102
+		{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x86.ActiveCfg = Release|Win32
103
+		{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x86.Build.0 = Release|Win32
104
+		{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|ARM.ActiveCfg = Debug|ARM
105
+		{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|ARM.Build.0 = Debug|ARM
106
+		{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|ARM64.ActiveCfg = Debug|ARM64
107
+		{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|ARM64.Build.0 = Debug|ARM64
108
+		{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|x64.ActiveCfg = Debug|x64
109
+		{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|x64.Build.0 = Debug|x64
110
+		{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|x86.ActiveCfg = Debug|Win32
111
+		{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|x86.Build.0 = Debug|Win32
112
+		{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|ARM.ActiveCfg = Release|ARM
113
+		{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|ARM.Build.0 = Release|ARM
114
+		{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|ARM64.ActiveCfg = Release|ARM64
115
+		{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|ARM64.Build.0 = Release|ARM64
116
+		{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|x64.ActiveCfg = Release|x64
117
+		{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|x64.Build.0 = Release|x64
118
+		{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|x86.ActiveCfg = Release|Win32
119
+		{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|x86.Build.0 = Release|Win32
120
+		{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|ARM.ActiveCfg = Debug|ARM
121
+		{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|ARM.Build.0 = Debug|ARM
122
+		{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|ARM64.ActiveCfg = Debug|ARM64
123
+		{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|ARM64.Build.0 = Debug|ARM64
124
+		{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|x64.ActiveCfg = Debug|x64
125
+		{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|x64.Build.0 = Debug|x64
126
+		{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|x86.ActiveCfg = Debug|Win32
127
+		{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|x86.Build.0 = Debug|Win32
128
+		{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|ARM.ActiveCfg = Release|ARM
129
+		{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|ARM.Build.0 = Release|ARM
130
+		{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|ARM64.ActiveCfg = Release|ARM64
131
+		{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|ARM64.Build.0 = Release|ARM64
132
+		{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|x64.ActiveCfg = Release|x64
133
+		{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|x64.Build.0 = Release|x64
134
+		{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|x86.ActiveCfg = Release|Win32
135
+		{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|x86.Build.0 = Release|Win32
136
+		{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM.ActiveCfg = Debug|ARM
137
+		{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM.Build.0 = Debug|ARM
138
+		{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM64.ActiveCfg = Debug|ARM64
139
+		{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM64.Build.0 = Debug|ARM64
140
+		{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x64.ActiveCfg = Debug|x64
141
+		{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x64.Build.0 = Debug|x64
142
+		{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x86.ActiveCfg = Debug|Win32
143
+		{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x86.Build.0 = Debug|Win32
144
+		{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|ARM.ActiveCfg = Release|ARM
145
+		{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|ARM.Build.0 = Release|ARM
146
+		{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|ARM64.ActiveCfg = Release|ARM64
147
+		{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|ARM64.Build.0 = Release|ARM64
148
+		{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|x64.ActiveCfg = Release|x64
149
+		{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|x64.Build.0 = Release|x64
150
+		{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|x86.ActiveCfg = Release|Win32
151
+		{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|x86.Build.0 = Release|Win32
152
+		{2D5D43D9-CFFC-4C40-B4CD-02EFB4E2742B}.Debug|ARM.ActiveCfg = Debug|ARM
153
+		{2D5D43D9-CFFC-4C40-B4CD-02EFB4E2742B}.Debug|ARM.Build.0 = Debug|ARM
154
+		{2D5D43D9-CFFC-4C40-B4CD-02EFB4E2742B}.Debug|ARM64.ActiveCfg = Debug|ARM64
155
+		{2D5D43D9-CFFC-4C40-B4CD-02EFB4E2742B}.Debug|ARM64.Build.0 = Debug|ARM64
156
+		{2D5D43D9-CFFC-4C40-B4CD-02EFB4E2742B}.Debug|x64.ActiveCfg = Debug|x64
157
+		{2D5D43D9-CFFC-4C40-B4CD-02EFB4E2742B}.Debug|x64.Build.0 = Debug|x64
158
+		{2D5D43D9-CFFC-4C40-B4CD-02EFB4E2742B}.Debug|x86.ActiveCfg = Debug|Win32
159
+		{2D5D43D9-CFFC-4C40-B4CD-02EFB4E2742B}.Debug|x86.Build.0 = Debug|Win32
160
+		{2D5D43D9-CFFC-4C40-B4CD-02EFB4E2742B}.Release|ARM.ActiveCfg = Release|ARM
161
+		{2D5D43D9-CFFC-4C40-B4CD-02EFB4E2742B}.Release|ARM.Build.0 = Release|ARM
162
+		{2D5D43D9-CFFC-4C40-B4CD-02EFB4E2742B}.Release|ARM64.ActiveCfg = Release|ARM64
163
+		{2D5D43D9-CFFC-4C40-B4CD-02EFB4E2742B}.Release|ARM64.Build.0 = Release|ARM64
164
+		{2D5D43D9-CFFC-4C40-B4CD-02EFB4E2742B}.Release|x64.ActiveCfg = Release|x64
165
+		{2D5D43D9-CFFC-4C40-B4CD-02EFB4E2742B}.Release|x64.Build.0 = Release|x64
166
+		{2D5D43D9-CFFC-4C40-B4CD-02EFB4E2742B}.Release|x86.ActiveCfg = Release|Win32
167
+		{2D5D43D9-CFFC-4C40-B4CD-02EFB4E2742B}.Release|x86.Build.0 = Release|Win32
168
+		{11C084A3-A57C-4296-A679-CAC17B603144}.Debug|ARM.ActiveCfg = Debug|ARM
169
+		{11C084A3-A57C-4296-A679-CAC17B603144}.Debug|ARM.Build.0 = Debug|ARM
170
+		{11C084A3-A57C-4296-A679-CAC17B603144}.Debug|ARM64.ActiveCfg = Debug|ARM64
171
+		{11C084A3-A57C-4296-A679-CAC17B603144}.Debug|ARM64.Build.0 = Debug|ARM64
172
+		{11C084A3-A57C-4296-A679-CAC17B603144}.Debug|x64.ActiveCfg = Debug|x64
173
+		{11C084A3-A57C-4296-A679-CAC17B603144}.Debug|x64.Build.0 = Debug|x64
174
+		{11C084A3-A57C-4296-A679-CAC17B603144}.Debug|x86.ActiveCfg = Debug|Win32
175
+		{11C084A3-A57C-4296-A679-CAC17B603144}.Debug|x86.Build.0 = Debug|Win32
176
+		{11C084A3-A57C-4296-A679-CAC17B603144}.Release|ARM.ActiveCfg = Release|ARM
177
+		{11C084A3-A57C-4296-A679-CAC17B603144}.Release|ARM.Build.0 = Release|ARM
178
+		{11C084A3-A57C-4296-A679-CAC17B603144}.Release|ARM64.ActiveCfg = Release|ARM64
179
+		{11C084A3-A57C-4296-A679-CAC17B603144}.Release|ARM64.Build.0 = Release|ARM64
180
+		{11C084A3-A57C-4296-A679-CAC17B603144}.Release|x64.ActiveCfg = Release|x64
181
+		{11C084A3-A57C-4296-A679-CAC17B603144}.Release|x64.Build.0 = Release|x64
182
+		{11C084A3-A57C-4296-A679-CAC17B603144}.Release|x86.ActiveCfg = Release|Win32
183
+		{11C084A3-A57C-4296-A679-CAC17B603144}.Release|x86.Build.0 = Release|Win32
184
+	EndGlobalSection
185
+	GlobalSection(SolutionProperties) = preSolution
186
+		HideSolutionNode = FALSE
187
+	EndGlobalSection
188
+	GlobalSection(NestedProjects) = preSolution
189
+		{C38970C0-5FBF-4D69-90D8-CBAC225AE895} = {6030669C-4F4D-4889-B38E-0299826D8C01}
190
+		{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D} = {6030669C-4F4D-4889-B38E-0299826D8C01}
191
+		{A990658C-CE31-4BCC-976F-0FC6B1AF693D} = {6030669C-4F4D-4889-B38E-0299826D8C01}
192
+		{0CC28589-39E4-4288-B162-97B959F8B843} = {6030669C-4F4D-4889-B38E-0299826D8C01}
193
+		{A62D504A-16B8-41D2-9F19-E2E86019E5E4} = {6030669C-4F4D-4889-B38E-0299826D8C01}
194
+		{F7D32BD0-2749-483E-9A0D-1635EF7E3136} = {6030669C-4F4D-4889-B38E-0299826D8C01}
195
+		{DA8B35B3-DA00-4B02-BDE6-6A397B3FD46B} = {6030669C-4F4D-4889-B38E-0299826D8C01}
196
+		{67A1076F-7790-4203-86EA-4402CCB5E782} = {6030669C-4F4D-4889-B38E-0299826D8C01}
197
+		{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD} = {6030669C-4F4D-4889-B38E-0299826D8C01}
198
+		{2D5D43D9-CFFC-4C40-B4CD-02EFB4E2742B} = {6030669C-4F4D-4889-B38E-0299826D8C01}
199
+		{11C084A3-A57C-4296-A679-CAC17B603144} = {6030669C-4F4D-4889-B38E-0299826D8C01}
200
+	EndGlobalSection
201
+	GlobalSection(ExtensibilityGlobals) = postSolution
202
+		SolutionGuid = {D1E18B0A-0D27-4F39-8A8B-7E3D784A99FC}
203
+	EndGlobalSection
204
+EndGlobal

+ 16
- 0
windows/ReactNativeWebView/PropertySheet.props View File

1
+<?xml version="1.0" encoding="utf-8"?>
2
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3
+  <ImportGroup Label="PropertySheets" />
4
+  <PropertyGroup Label="UserMacros" />
5
+  <!--
6
+    To customize common C++/WinRT project properties: 
7
+    * right-click the project node
8
+    * expand the Common Properties item
9
+    * select the C++/WinRT property page
10
+
11
+    For more advanced scenarios, and complete documentation, please see:
12
+    https://github.com/Microsoft/cppwinrt/tree/master/nuget 
13
+    -->
14
+  <PropertyGroup />
15
+  <ItemDefinitionGroup />
16
+</Project>

+ 3
- 0
windows/ReactNativeWebView/ReactNativeWebView.def View File

1
+EXPORTS
2
+DllCanUnloadNow = WINRT_CanUnloadNow                    PRIVATE
3
+DllGetActivationFactory = WINRT_GetActivationFactory    PRIVATE

+ 33
- 0
windows/ReactNativeWebView/ReactNativeWebView.filters View File

1
+<?xml version="1.0" encoding="utf-8"?>
2
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3
+  <ItemGroup>
4
+    <Filter Include="Resources">
5
+      <UniqueIdentifier>accd3aa8-1ba0-4223-9bbe-0c431709210b</UniqueIdentifier>
6
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms</Extensions>
7
+    </Filter>
8
+    <Filter Include="Generated Files">
9
+      <UniqueIdentifier>{926ab91d-31b4-48c3-b9a4-e681349f27f0}</UniqueIdentifier>
10
+    </Filter>
11
+  </ItemGroup>
12
+  <ItemGroup>
13
+    <ClCompile Include="pch.cpp" />
14
+    <ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
15
+    <ClCompile Include="ReactPackageProvider.cpp" />
16
+    <ClCompile Include="WebViewManager.cpp" />
17
+  </ItemGroup>
18
+  <ItemGroup>
19
+    <ClInclude Include="pch.h" />
20
+    <ClInclude Include="ReactPackageProvider.h" />
21
+    <ClInclude Include="WebViewManager.h" />
22
+  </ItemGroup>
23
+  <ItemGroup>
24
+    <None Include="ReactNativeWebView.def" />
25
+    <None Include="packages.config" />
26
+  </ItemGroup>
27
+  <ItemGroup>
28
+    <None Include="PropertySheet.props" />
29
+  </ItemGroup>
30
+  <ItemGroup>
31
+    <Midl Include="ReactPackageProvider.idl" />
32
+  </ItemGroup>
33
+</Project>

+ 162
- 0
windows/ReactNativeWebView/ReactNativeWebView.vcxproj View File

1
+<?xml version="1.0" encoding="utf-8"?>
2
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3
+  <Import Project="$(SolutionDir)packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('$(SolutionDir)packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.props')" />
4
+  <PropertyGroup Label="Globals">
5
+    <CppWinRTOptimized>true</CppWinRTOptimized>
6
+    <CppWinRTRootNamespaceAutoMerge>true</CppWinRTRootNamespaceAutoMerge>
7
+    <MinimalCoreWin>true</MinimalCoreWin>
8
+    <ProjectGuid>{729d9af8-cd9e-4427-9f6c-fb757e287729}</ProjectGuid>
9
+    <ProjectName>ReactNativeWebView</ProjectName>
10
+    <RootNamespace>ReactNativeWebView</RootNamespace>
11
+    <DefaultLanguage>en-US</DefaultLanguage>
12
+    <MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
13
+    <AppContainerApplication>true</AppContainerApplication>
14
+    <ApplicationType>Windows Store</ApplicationType>
15
+    <ApplicationTypeRevision>10.0</ApplicationTypeRevision>
16
+    <WindowsTargetPlatformVersion Condition=" '$(WindowsTargetPlatformVersion)' == '' ">10.0.18362.0</WindowsTargetPlatformVersion>
17
+    <WindowsTargetPlatformMinVersion>10.0.15063.0</WindowsTargetPlatformMinVersion>
18
+  </PropertyGroup>
19
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
20
+  <ItemGroup Label="ProjectConfigurations">
21
+    <ProjectConfiguration Include="Debug|ARM">
22
+      <Configuration>Debug</Configuration>
23
+      <Platform>ARM</Platform>
24
+    </ProjectConfiguration>
25
+    <ProjectConfiguration Include="Debug|Win32">
26
+      <Configuration>Debug</Configuration>
27
+      <Platform>Win32</Platform>
28
+    </ProjectConfiguration>
29
+    <ProjectConfiguration Include="Debug|x64">
30
+      <Configuration>Debug</Configuration>
31
+      <Platform>x64</Platform>
32
+    </ProjectConfiguration>
33
+    <ProjectConfiguration Include="Release|ARM">
34
+      <Configuration>Release</Configuration>
35
+      <Platform>ARM</Platform>
36
+    </ProjectConfiguration>
37
+    <ProjectConfiguration Include="Release|Win32">
38
+      <Configuration>Release</Configuration>
39
+      <Platform>Win32</Platform>
40
+    </ProjectConfiguration>
41
+    <ProjectConfiguration Include="Release|x64">
42
+      <Configuration>Release</Configuration>
43
+      <Platform>x64</Platform>
44
+    </ProjectConfiguration>
45
+  </ItemGroup>
46
+  <PropertyGroup Label="Configuration">
47
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
48
+    <PlatformToolset>v140</PlatformToolset>
49
+    <PlatformToolset Condition="'$(VisualStudioVersion)' == '15.0'">v141</PlatformToolset>
50
+    <PlatformToolset Condition="'$(VisualStudioVersion)' == '16.0'">v142</PlatformToolset>
51
+    <CharacterSet>Unicode</CharacterSet>
52
+    <GenerateManifest>false</GenerateManifest>
53
+  </PropertyGroup>
54
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
55
+    <UseDebugLibraries>true</UseDebugLibraries>
56
+    <LinkIncremental>true</LinkIncremental>
57
+  </PropertyGroup>
58
+  <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
59
+    <UseDebugLibraries>false</UseDebugLibraries>
60
+    <WholeProgramOptimization>true</WholeProgramOptimization>
61
+    <LinkIncremental>false</LinkIncremental>
62
+  </PropertyGroup>
63
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
64
+  <ImportGroup Label="ExtensionSettings">
65
+  </ImportGroup>
66
+  <ImportGroup Label="Shared">
67
+    <Import Project="..\..\..\react-native-windows\Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems" Label="Shared" Condition="Exists('..\..\..\react-native-windows\Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems')" />
68
+    <Import Project="..\..\node_modules\react-native-windows\Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems" Label="Shared" Condition="Exists('..\..\node_modules\react-native-windows\Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems')"/>
69
+  </ImportGroup>
70
+  <ImportGroup Label="PropertySheets">
71
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
72
+  </ImportGroup>
73
+  <ImportGroup Label="PropertySheets">
74
+    <Import Project="PropertySheet.props" />
75
+  </ImportGroup>
76
+  <PropertyGroup Label="UserMacros" />
77
+  <PropertyGroup />
78
+  <ItemDefinitionGroup>
79
+    <ClCompile>
80
+      <PrecompiledHeader>Use</PrecompiledHeader>
81
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
82
+      <PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
83
+      <WarningLevel>Level4</WarningLevel>
84
+      <AdditionalOptions>%(AdditionalOptions) /bigobj</AdditionalOptions>
85
+      <!--Temporarily disable cppwinrt heap enforcement to work around xaml compiler generated std::shared_ptr use -->
86
+      <AdditionalOptions Condition="'$(CppWinRTHeapEnforcement)'==''">/DWINRT_NO_MAKE_DETECTION %(AdditionalOptions)</AdditionalOptions>
87
+      <DisableSpecificWarnings>28204</DisableSpecificWarnings>
88
+      <PreprocessorDefinitions>_WINRT_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
89
+      <AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
90
+    </ClCompile>
91
+    <Link>
92
+      <SubSystem>Console</SubSystem>
93
+      <GenerateWindowsMetadata>true</GenerateWindowsMetadata>
94
+      <ModuleDefinitionFile>ReactNativeWebView.def</ModuleDefinitionFile>
95
+    </Link>
96
+  </ItemDefinitionGroup>
97
+  <ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
98
+    <ClCompile>
99
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
100
+    </ClCompile>
101
+  </ItemDefinitionGroup>
102
+  <ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
103
+    <ClCompile>
104
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
105
+    </ClCompile>
106
+  </ItemDefinitionGroup>
107
+  <ItemGroup>
108
+    <ClInclude Include="ReactWebView.h">
109
+      <DependentUpon>ReactWebView.idl</DependentUpon>
110
+    </ClInclude>
111
+    <ClInclude Include="ReactWebViewManager.h" />
112
+    <ClInclude Include="pch.h" />
113
+    <ClInclude Include="ReactPackageProvider.h">
114
+      <DependentUpon>ReactPackageProvider.idl</DependentUpon>
115
+    </ClInclude>
116
+  </ItemGroup>
117
+  <ItemGroup>
118
+    <ClCompile Include="ReactWebView.cpp">
119
+      <DependentUpon>ReactWebView.idl</DependentUpon>
120
+    </ClCompile>
121
+    <ClCompile Include="ReactWebViewManager.cpp" />
122
+    <ClCompile Include="pch.cpp">
123
+      <PrecompiledHeader>Create</PrecompiledHeader>
124
+    </ClCompile>
125
+    <ClCompile Include="ReactPackageProvider.cpp">
126
+      <DependentUpon>ReactPackageProvider.idl</DependentUpon>
127
+    </ClCompile>
128
+    <ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
129
+  </ItemGroup>
130
+  <ItemGroup>
131
+    <Midl Include="ReactWebView.idl" />
132
+    <Midl Include="ReactPackageProvider.idl" />
133
+  </ItemGroup>
134
+  <ItemGroup>
135
+    <None Include="packages.config" />
136
+    <None Include="ReactNativeWebView.def" />
137
+  </ItemGroup>
138
+  <ItemGroup>
139
+    <None Include="PropertySheet.props" />
140
+  </ItemGroup>
141
+  <ItemGroup>
142
+    <ProjectReference Include="..\..\..\react-native-windows\Microsoft.ReactNative\Microsoft.ReactNative.vcxproj" Condition="Exists('..\..\..\react-native-windows\Microsoft.ReactNative\Microsoft.ReactNative.vcxproj')">
143
+      <Project>{f7d32bd0-2749-483e-9a0d-1635ef7e3136}</Project>
144
+      <Private>false</Private>
145
+    </ProjectReference>
146
+    <ProjectReference Include="..\..\node_modules\react-native-windows\Microsoft.ReactNative\Microsoft.ReactNative.vcxproj" Condition="Exists('..\..\node_modules\react-native-windows\Microsoft.ReactNative\Microsoft.ReactNative.vcxproj')">
147
+      <Project>{f7d32bd0-2749-483e-9a0d-1635ef7e3136}</Project>
148
+      <Private>false</Private>
149
+    </ProjectReference>
150
+  </ItemGroup>
151
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
152
+  <ImportGroup Label="ExtensionTargets">
153
+    <Import Project="$(SolutionDir)packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(SolutionDir)packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.targets')" />
154
+  </ImportGroup>
155
+  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
156
+    <PropertyGroup>
157
+      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
158
+    </PropertyGroup>
159
+    <Error Condition="!Exists('$(SolutionDir)packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.props'))" />
160
+    <Error Condition="!Exists('$(SolutionDir)packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.targets'))" />
161
+  </Target>
162
+</Project>

+ 17
- 0
windows/ReactNativeWebView/ReactPackageProvider.cpp View File

1
+#include "pch.h"
2
+#include "ReactPackageProvider.h"
3
+#if __has_include("ReactPackageProvider.g.cpp")
4
+#include "ReactPackageProvider.g.cpp"
5
+#endif
6
+
7
+#include "ReactWebViewManager.h"
8
+
9
+using namespace winrt::Microsoft::ReactNative;
10
+
11
+namespace winrt::ReactNativeWebView::implementation {
12
+
13
+void ReactPackageProvider::CreatePackage(IReactPackageBuilder const &packageBuilder) noexcept {
14
+  packageBuilder.AddViewManager(L"ReactWebViewManager", []() { return winrt::make<ReactWebViewManager>(); });
15
+}
16
+
17
+} // namespace winrt::ReactNativeWebView::implementation

+ 20
- 0
windows/ReactNativeWebView/ReactPackageProvider.h View File

1
+#pragma once
2
+#include "ReactPackageProvider.g.h"
3
+
4
+using namespace winrt::Microsoft::ReactNative;
5
+
6
+namespace winrt::ReactNativeWebView::implementation {
7
+
8
+struct ReactPackageProvider : ReactPackageProviderT<ReactPackageProvider> {
9
+  ReactPackageProvider() = default;
10
+
11
+  void CreatePackage(IReactPackageBuilder const &packageBuilder) noexcept;
12
+};
13
+
14
+} // namespace winrt::ReactNativeWebView::implementation
15
+
16
+namespace winrt::ReactNativeWebView::factory_implementation {
17
+
18
+struct ReactPackageProvider : ReactPackageProviderT<ReactPackageProvider, implementation::ReactPackageProvider> {};
19
+
20
+} // namespace winrt::ReactNativeWebView::factory_implementation

+ 7
- 0
windows/ReactNativeWebView/ReactPackageProvider.idl View File

1
+namespace ReactNativeWebView {
2
+[webhosthidden]
3
+[default_interface] 
4
+runtimeclass ReactPackageProvider : Microsoft.ReactNative.IReactPackageProvider {
5
+  ReactPackageProvider();
6
+};
7
+} // namespace ReactNativeWebView

+ 144
- 0
windows/ReactNativeWebView/ReactWebView.cpp View File

1
+// Copyright (c) Microsoft Corporation. All rights reserved.
2
+// Licensed under the MIT License.
3
+
4
+#include "pch.h"
5
+#include "JSValueXaml.h"
6
+#include "ReactWebView.h"
7
+#include "ReactWebView.g.cpp"
8
+
9
+namespace winrt {
10
+    using namespace Microsoft::ReactNative;
11
+    using namespace Windows::Data::Json;
12
+    using namespace Windows::Foundation;
13
+    using namespace Windows::UI;
14
+    using namespace Windows::UI::Popups;
15
+    using namespace Windows::UI::Xaml;
16
+    using namespace Windows::UI::Xaml::Controls;
17
+    using namespace Windows::UI::Xaml::Input;
18
+    using namespace Windows::UI::Xaml::Media;
19
+} // namespace winrt
20
+
21
+namespace winrt::ReactNativeWebView::implementation {
22
+
23
+    ReactWebView::ReactWebView(winrt::IReactContext const& reactContext) : m_reactContext(reactContext) {
24
+#ifdef CHAKRACORE_UWP
25
+        m_webView = winrt::WebView(winrt::WebViewExecutionMode::SeparateProcess);
26
+#else
27
+        m_webView = winrt::WebView();
28
+#endif
29
+        RegisterEvents();
30
+    }
31
+
32
+    winrt::WebView ReactWebView::GetView() {
33
+        return m_webView;
34
+    }
35
+
36
+    void ReactWebView::RegisterEvents() {
37
+        m_navigationStartingRevoker = m_webView.NavigationStarting(
38
+            winrt::auto_revoke, [ref = get_weak()](auto const& sender, auto const& args) {
39
+                if (auto self = ref.get()) {
40
+                    self->OnNavigationStarting(sender, args);
41
+                }
42
+                
43
+            });
44
+
45
+        m_navigationCompletedRevoker = m_webView.NavigationCompleted(
46
+            winrt::auto_revoke, [ref = get_weak()](auto const& sender, auto const& args) {
47
+                if (auto self = ref.get()) {
48
+                    self->OnNavigationCompleted(sender, args);
49
+                }
50
+            });
51
+
52
+        m_navigationFailedRevoker = m_webView.NavigationFailed(
53
+            winrt::auto_revoke, [ref = get_weak()](auto const& sender, auto const& args) {
54
+                if (auto self = ref.get()) {
55
+                    self->OnNavigationFailed(sender, args);
56
+                }
57
+            });
58
+
59
+        m_scriptNotifyRevoker = m_webView.ScriptNotify(
60
+            winrt::auto_revoke, [ref = get_weak()](auto const& sender, auto const& args) {
61
+                if (auto self = ref.get()) {
62
+                    self->OnScriptNotify(sender, args);
63
+                }
64
+            });
65
+    }
66
+
67
+    void ReactWebView::WriteWebViewNavigationEventArg(winrt::IJSValueWriter const& eventDataWriter) {
68
+        auto tag = m_webView.GetValue(winrt::FrameworkElement::TagProperty()).as<winrt::IPropertyValue>().GetInt64();
69
+        WriteProperty(eventDataWriter, L"canGoBack", m_webView.CanGoBack());
70
+        WriteProperty(eventDataWriter, L"canGoForward", m_webView.CanGoForward());
71
+        WriteProperty(eventDataWriter, L"loading", !m_webView.IsLoaded());
72
+        WriteProperty(eventDataWriter, L"target", tag);
73
+        WriteProperty(eventDataWriter, L"title", m_webView.DocumentTitle());
74
+        if (auto uri = m_webView.Source()) {
75
+            WriteProperty(eventDataWriter, L"url", uri.AbsoluteCanonicalUri());
76
+        }
77
+    }
78
+
79
+    void ReactWebView::OnNavigationStarting(winrt::WebView const& webView, winrt::WebViewNavigationStartingEventArgs const& /*args*/) {
80
+        m_reactContext.DispatchEvent(
81
+            webView,
82
+            L"topLoadingStart",
83
+            [&](winrt::IJSValueWriter const& eventDataWriter) noexcept {
84
+                eventDataWriter.WriteObjectBegin();
85
+                WriteWebViewNavigationEventArg(eventDataWriter);
86
+                eventDataWriter.WriteObjectEnd();
87
+            });
88
+    }
89
+
90
+    void ReactWebView::OnNavigationCompleted(winrt::WebView const& webView, winrt::WebViewNavigationCompletedEventArgs const& /*args*/) {
91
+        m_reactContext.DispatchEvent(
92
+            webView,
93
+            L"topLoadingFinish",
94
+            [&](winrt::IJSValueWriter const& eventDataWriter) noexcept {
95
+                eventDataWriter.WriteObjectBegin();
96
+                WriteWebViewNavigationEventArg(eventDataWriter);
97
+                eventDataWriter.WriteObjectEnd();
98
+            });
99
+
100
+        winrt::hstring windowAlert = L"window.alert = function (msg) {window.external.notify(`{\"type\":\"alert\",\"message\":\"${msg}\"}`)};";
101
+        winrt::hstring postMessage = L"window.ReactNativeWebView = {postMessage: function (data) {window.external.notify(String(data))}};";
102
+        m_webView.InvokeScriptAsync(L"eval", { windowAlert + postMessage });
103
+    }
104
+
105
+    void ReactWebView::OnNavigationFailed(winrt::IInspectable const& /*sender*/, winrt::WebViewNavigationFailedEventArgs const& args) {
106
+        m_reactContext.DispatchEvent(
107
+            m_webView,
108
+            L"topLoadingError",
109
+            [&](winrt::IJSValueWriter const& eventDataWriter) noexcept {
110
+                auto httpCode = static_cast<int32_t>(args.WebErrorStatus());
111
+                eventDataWriter.WriteObjectBegin();
112
+                {
113
+                    WriteProperty(eventDataWriter, L"code", httpCode);
114
+                    WriteWebViewNavigationEventArg(eventDataWriter);
115
+                }
116
+                eventDataWriter.WriteObjectEnd();
117
+            });
118
+    }
119
+
120
+    void ReactWebView::OnScriptNotify(winrt::IInspectable const& /*sender*/, winrt::Windows::UI::Xaml::Controls::NotifyEventArgs const& args) {
121
+        winrt::JsonObject jsonObject;
122
+        if (winrt::JsonObject::TryParse(args.Value(), jsonObject)) {
123
+            auto type = jsonObject.GetNamedString(L"type");
124
+            if (type == L"alert") {
125
+                auto dialog = winrt::MessageDialog(jsonObject.GetNamedString(L"message"));
126
+                dialog.Commands().Append(winrt::UICommand(L"OK"));
127
+                dialog.ShowAsync();
128
+            }
129
+        }
130
+        else {
131
+            m_reactContext.DispatchEvent(
132
+                m_webView,
133
+                L"topMessage",
134
+                [&](winrt::Microsoft::ReactNative::IJSValueWriter const& eventDataWriter) noexcept {
135
+                    eventDataWriter.WriteObjectBegin();
136
+                    {
137
+                        WriteProperty(eventDataWriter, L"data", winrt::to_string(args.Value()));
138
+                    }
139
+                    eventDataWriter.WriteObjectEnd();
140
+                });
141
+        }
142
+    }
143
+
144
+} // namespace winrt::ReactNativeWebView::implementation

+ 36
- 0
windows/ReactNativeWebView/ReactWebView.h View File

1
+// Copyright (c) Microsoft Corporation. All rights reserved.
2
+// Licensed under the MIT License.
3
+
4
+#pragma once
5
+
6
+#include "winrt/Microsoft.ReactNative.h"
7
+#include "NativeModules.h"
8
+#include "ReactWebView.g.h"
9
+
10
+namespace winrt::ReactNativeWebView::implementation {
11
+
12
+    class ReactWebView : public ReactWebViewT<ReactWebView> {
13
+    public:
14
+        ReactWebView(Microsoft::ReactNative::IReactContext const& reactContext);
15
+        winrt::Windows::UI::Xaml::Controls::WebView GetView();
16
+
17
+    private:
18
+        winrt::Windows::UI::Xaml::Controls::WebView m_webView{ nullptr };
19
+        Microsoft::ReactNative::IReactContext m_reactContext{ nullptr };
20
+        winrt::Windows::UI::Xaml::Controls::WebView::NavigationStarting_revoker m_navigationStartingRevoker{};
21
+        winrt::Windows::UI::Xaml::Controls::WebView::NavigationCompleted_revoker m_navigationCompletedRevoker{};
22
+        winrt::Windows::UI::Xaml::Controls::WebView::NavigationFailed_revoker m_navigationFailedRevoker{};
23
+        winrt::Windows::UI::Xaml::Controls::WebView::ScriptNotify_revoker m_scriptNotifyRevoker{};
24
+
25
+        void RegisterEvents();
26
+        void WriteWebViewNavigationEventArg(winrt::Microsoft::ReactNative::IJSValueWriter const& eventDataWriter);
27
+        void OnNavigationStarting(winrt::Windows::UI::Xaml::Controls::WebView const& sender, winrt::Windows::UI::Xaml::Controls::WebViewNavigationStartingEventArgs const& args);
28
+        void OnNavigationCompleted(winrt::Windows::UI::Xaml::Controls::WebView const& sender, winrt::Windows::UI::Xaml::Controls::WebViewNavigationCompletedEventArgs const& args);
29
+        void OnNavigationFailed(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::Controls::WebViewNavigationFailedEventArgs const& args);
30
+        void OnScriptNotify(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::Controls::NotifyEventArgs const& args);
31
+    };
32
+} // namespace winrt::ReactNativeWebView::implementation
33
+
34
+namespace winrt::ReactNativeWebView::factory_implementation {
35
+    struct ReactWebView : ReactWebViewT<ReactWebView, implementation::ReactWebView> {};
36
+} // namespace winrt::ReactNativeWebView::factory_implementation

+ 7
- 0
windows/ReactNativeWebView/ReactWebView.idl View File

1
+namespace ReactNativeWebView{
2
+    [default_interface]
3
+    runtimeclass ReactWebView : Windows.UI.Xaml.Controls.UserControl{
4
+        ReactWebView(Microsoft.ReactNative.IReactContext context);
5
+        Windows.UI.Xaml.Controls.WebView GetView();
6
+    };
7
+} // namespace ReactNativeWebView

+ 144
- 0
windows/ReactNativeWebView/ReactWebViewManager.cpp View File

1
+#include "pch.h"
2
+#include "ReactWebViewManager.h"
3
+#include "NativeModules.h"
4
+#include "ReactWebView.h"
5
+#include "JSValueXaml.h"
6
+
7
+namespace winrt {
8
+    using namespace Microsoft::ReactNative;
9
+    using namespace Windows::Foundation;
10
+    using namespace Windows::Foundation::Collections;
11
+    using namespace Windows::UI;
12
+    using namespace Windows::UI::Xaml;
13
+    using namespace Windows::UI::Xaml::Controls;
14
+}
15
+
16
+namespace winrt::ReactNativeWebView::implementation {
17
+
18
+    ReactWebViewManager::ReactWebViewManager() {}
19
+
20
+    // IViewManager
21
+    winrt::hstring ReactWebViewManager::Name() noexcept {
22
+        return L"RCTWebView";
23
+    }
24
+
25
+    winrt::FrameworkElement ReactWebViewManager::CreateView() noexcept {
26
+        m_reactWebView = *winrt::make_self<ReactWebView>(m_reactContext);
27
+        return m_reactWebView.GetView();
28
+    }
29
+
30
+    // IViewManagerWithReactContext
31
+    winrt::IReactContext ReactWebViewManager::ReactContext() noexcept {
32
+        return m_reactContext;
33
+    }
34
+
35
+    void ReactWebViewManager::ReactContext(IReactContext reactContext) noexcept {
36
+        m_reactContext = reactContext;
37
+    }
38
+
39
+    // IViewManagerWithNativeProperties
40
+    IMapView<hstring, ViewManagerPropertyType> ReactWebViewManager::NativeProps() noexcept {
41
+        auto nativeProps = winrt::single_threaded_map<hstring, ViewManagerPropertyType>();
42
+        nativeProps.Insert(L"source", ViewManagerPropertyType::Map);
43
+        return nativeProps.GetView();
44
+    }
45
+
46
+    void ReactWebViewManager::UpdateProperties(
47
+        FrameworkElement const& view,
48
+        IJSValueReader const& propertyMapReader) noexcept {
49
+        if (auto webView = view.try_as<winrt::WebView>()) {
50
+            const JSValueObject& propertyMap = JSValueObject::ReadFrom(propertyMapReader);
51
+
52
+            for (auto const& pair : propertyMap) {
53
+                auto const& propertyName = pair.first;
54
+                auto const& propertyValue = pair.second;
55
+                if (propertyValue.IsNull()) continue;
56
+
57
+                if (propertyName == "source") {
58
+                    auto const& srcMap = propertyValue.AsObject();
59
+                    if (srcMap.find("uri") != srcMap.end()) {
60
+                        auto uriString = srcMap.at("uri").AsString();
61
+                        // non-uri sources not yet supported
62
+                        if (uriString.length() == 0) {
63
+                            continue;
64
+                        }
65
+
66
+                        bool isPackagerAsset = false;
67
+                        if (srcMap.find("__packager_asset") != srcMap.end()) {
68
+                            isPackagerAsset = srcMap.at("__packager_asset").AsBoolean();
69
+                        }
70
+
71
+                        if (isPackagerAsset && uriString.find("assets") == 0) {
72
+                            uriString.replace(0, 6, "ms-appx://");
73
+                        }
74
+
75
+                        webView.Navigate(winrt::Uri(to_hstring(uriString)));
76
+                    }
77
+                    else if (srcMap.find("html") != srcMap.end()) {
78
+                        auto htmlString = srcMap.at("html").AsString();
79
+                        webView.NavigateToString(to_hstring(htmlString));
80
+                    }
81
+                }
82
+                else if (propertyName == "backgroundColor") {
83
+                    auto color = propertyValue.To<winrt::Color>();
84
+                    webView.DefaultBackgroundColor(color.A==0 ? winrt::Colors::Transparent() : color);
85
+                }
86
+            }
87
+        }
88
+    }
89
+
90
+    // IViewManagerWithExportedEventTypeConstants
91
+    ConstantProviderDelegate ReactWebViewManager::ExportedCustomBubblingEventTypeConstants() noexcept {
92
+        return nullptr;
93
+    }
94
+
95
+    ConstantProviderDelegate ReactWebViewManager::ExportedCustomDirectEventTypeConstants() noexcept {
96
+        return [](winrt::IJSValueWriter const& constantWriter) {
97
+            WriteCustomDirectEventTypeConstant(constantWriter, "onLoadingStart");
98
+            WriteCustomDirectEventTypeConstant(constantWriter, "onLoadingFinish");
99
+            WriteCustomDirectEventTypeConstant(constantWriter, "onLoadingError");
100
+            WriteCustomDirectEventTypeConstant(constantWriter, "onMessage");
101
+        };
102
+    }
103
+
104
+    // IViewManagerWithCommands
105
+    IMapView<hstring, int64_t> ReactWebViewManager::Commands() noexcept {
106
+        auto commands = winrt::single_threaded_map<hstring, int64_t>();
107
+        commands.Insert(L"goForward", static_cast<int32_t>(WebViewCommands::GoForward));
108
+        commands.Insert(L"goBack", static_cast<int32_t>(WebViewCommands::GoBack));
109
+        commands.Insert(L"reload", static_cast<int32_t>(WebViewCommands::Reload));
110
+        commands.Insert(L"stopLoading", static_cast<int32_t>(WebViewCommands::StopLoading));
111
+        commands.Insert(L"injectJavaScript", static_cast<int32_t>(WebViewCommands::InjectJavaScript));
112
+        return commands.GetView();
113
+    }
114
+
115
+    void ReactWebViewManager::DispatchCommand(
116
+        FrameworkElement const& view,
117
+        int64_t commandId,
118
+        winrt::IJSValueReader const& commandArgsReader) noexcept {
119
+        if (auto webView = view.try_as<winrt::WebView>()) {
120
+            switch (commandId) {
121
+                case static_cast<int64_t>(WebViewCommands::GoForward) :
122
+                    if (webView.CanGoForward()) {
123
+                        webView.GoForward();
124
+                    }
125
+                    break;
126
+                case static_cast<int64_t>(WebViewCommands::GoBack) :
127
+                    if (webView.CanGoBack()) {
128
+                        webView.GoBack();
129
+                    }
130
+                    break;
131
+                case static_cast<int64_t>(WebViewCommands::Reload) :
132
+                    webView.Refresh();
133
+                    break;
134
+                case static_cast<int64_t>(WebViewCommands::StopLoading) :
135
+                    webView.Stop();
136
+                    break;
137
+                case static_cast<int64_t>(WebViewCommands::InjectJavaScript) :
138
+                    webView.InvokeScriptAsync(L"eval", { commandArgsReader.GetString() });
139
+                    break;
140
+            }
141
+        }
142
+    }
143
+
144
+} // namespace winrt::ReactWebView::implementation

+ 56
- 0
windows/ReactNativeWebView/ReactWebViewManager.h View File

1
+// Copyright (c) Microsoft Corporation. All rights reserved.
2
+// Licensed under the MIT License.
3
+
4
+#pragma once
5
+#include "winrt/Microsoft.ReactNative.h"
6
+#include "NativeModules.h"
7
+#include "ReactWebView.h"
8
+
9
+namespace winrt::ReactNativeWebView::implementation {
10
+    
11
+    enum class WebViewCommands : int32_t { GoForward = 0, GoBack = 1,  Reload = 2, StopLoading = 3, InjectJavaScript = 4 };
12
+
13
+    class ReactWebViewManager : public winrt::implements<
14
+        ReactWebViewManager,
15
+        winrt::Microsoft::ReactNative::IViewManager,
16
+        winrt::Microsoft::ReactNative::IViewManagerWithReactContext,
17
+        winrt::Microsoft::ReactNative::IViewManagerWithNativeProperties,
18
+        winrt::Microsoft::ReactNative::IViewManagerWithExportedEventTypeConstants,
19
+        winrt::Microsoft::ReactNative::IViewManagerWithCommands> {
20
+    public:
21
+        ReactWebViewManager();
22
+        // IViewManager
23
+        winrt::hstring Name() noexcept;
24
+        winrt::Windows::UI::Xaml::FrameworkElement CreateView() noexcept;
25
+
26
+        // IViewManagerWithReactContext
27
+        winrt::Microsoft::ReactNative::IReactContext ReactContext() noexcept;
28
+        void ReactContext(winrt::Microsoft::ReactNative::IReactContext reactContext) noexcept;
29
+
30
+        // IViewManagerWithNativeProperties
31
+        winrt::Windows::Foundation::Collections::
32
+            IMapView<winrt::hstring, winrt::Microsoft::ReactNative::ViewManagerPropertyType>
33
+            NativeProps() noexcept;
34
+
35
+        void UpdateProperties(
36
+            winrt::Windows::UI::Xaml::FrameworkElement const& view,
37
+            winrt::Microsoft::ReactNative::IJSValueReader const& propertyMapReader) noexcept;
38
+
39
+        // IViewManagerWithExportedEventTypeConstants
40
+        winrt::Microsoft::ReactNative::ConstantProviderDelegate ExportedCustomBubblingEventTypeConstants() noexcept;
41
+        winrt::Microsoft::ReactNative::ConstantProviderDelegate ExportedCustomDirectEventTypeConstants() noexcept;
42
+
43
+        // IViewManagerWithCommands
44
+        winrt::Windows::Foundation::Collections::IMapView<winrt::hstring, int64_t> Commands() noexcept;
45
+
46
+        void DispatchCommand(
47
+            winrt::Windows::UI::Xaml::FrameworkElement const& view,
48
+            int64_t commandId,
49
+            winrt::Microsoft::ReactNative::IJSValueReader const& commandArgsReader) noexcept;
50
+
51
+    private:
52
+        winrt::ReactNativeWebView::ReactWebView m_reactWebView{ nullptr };
53
+        winrt::Microsoft::ReactNative::IReactContext m_reactContext{ nullptr };
54
+
55
+    };
56
+} // namespace winrt::ReactWebView::implementation

+ 4
- 0
windows/ReactNativeWebView/packages.config View File

1
+<?xml version="1.0" encoding="utf-8"?>
2
+<packages>
3
+  <package id="Microsoft.Windows.CppWinRT" version="2.0.190730.2" targetFramework="native" />
4
+</packages>

+ 1
- 0
windows/ReactNativeWebView/pch.cpp View File

1
+#include "pch.h"

+ 13
- 0
windows/ReactNativeWebView/pch.h View File

1
+#pragma once
2
+
3
+#define NOMINMAX
4
+#include <unknwn.h>
5
+#include <winrt/Windows.Data.Json.h>
6
+#include <winrt/Windows.Foundation.h>
7
+#include <winrt/Windows.Foundation.Collections.h>
8
+#include <winrt/Windows.UI.Popups.h>
9
+#include <winrt/Windows.UI.Xaml.h>
10
+#include <winrt/Windows.UI.Xaml.Controls.h>
11
+#include <winrt/Windows.UI.Xaml.Markup.h>
12
+#include <winrt/Windows.UI.Xaml.Navigation.h>
13
+#include <winrt/Microsoft.ReactNative.h>

+ 10587
- 10059
yarn.lock
File diff suppressed because it is too large
View File