@exodus/react-native-webview 11.26.1-exodus.9 → 13.16.0-exodus.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/README.md +36 -63
  2. package/android/build.gradle +83 -110
  3. package/android/gradle.properties +3 -4
  4. package/android/src/main/AndroidManifest.xml +12 -0
  5. package/android/src/main/AndroidManifestNew.xml +26 -0
  6. package/android/src/main/java/com/reactnativecommunity/webview/RNCBasicAuthCredential.java +11 -0
  7. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebChromeClient.java +407 -0
  8. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebView.java +468 -0
  9. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewClient.java +330 -0
  10. package/android/src/main/java/com/reactnativecommunity/webview/{WebViewConfig.java → RNCWebViewConfig.java} +3 -4
  11. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewFileProvider.java +1 -1
  12. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManagerImpl.kt +746 -0
  13. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewMessagingModule.kt +9 -0
  14. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewModuleImpl.java +554 -0
  15. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewPackage.java +57 -12
  16. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewWrapper.kt +39 -0
  17. package/android/src/main/java/com/reactnativecommunity/webview/events/SubResourceErrorEvent.kt +25 -0
  18. package/android/src/main/java/com/reactnativecommunity/webview/events/TopCustomMenuSelectionEvent.kt +24 -0
  19. package/android/src/main/java/com/reactnativecommunity/webview/events/TopHttpErrorEvent.kt +25 -0
  20. package/android/src/main/java/com/reactnativecommunity/webview/events/TopNewWindowEvent.kt +25 -0
  21. package/android/src/main/java/com/reactnativecommunity/webview/events/TopRenderProcessGoneEvent.kt +25 -0
  22. package/android/src/newarch/com/reactnativecommunity/webview/RNCWebViewManager.java +570 -0
  23. package/android/src/newarch/com/reactnativecommunity/webview/RNCWebViewModule.java +57 -0
  24. package/android/src/oldarch/com/reactnativecommunity/webview/RNCWebViewManager.java +341 -0
  25. package/android/src/oldarch/com/reactnativecommunity/webview/RNCWebViewModule.java +59 -0
  26. package/apple/RCTConvert+WKDataDetectorTypes.h +11 -0
  27. package/apple/RCTConvert+WKDataDetectorTypes.m +27 -0
  28. package/apple/RNCWebView.h +26 -100
  29. package/apple/RNCWebView.mm +555 -0
  30. package/apple/RNCWebViewDecisionManager.h +20 -0
  31. package/apple/RNCWebViewDecisionManager.m +47 -0
  32. package/apple/RNCWebViewImpl.h +164 -0
  33. package/apple/{RNCWebView.m → RNCWebViewImpl.m} +802 -225
  34. package/apple/RNCWebViewManager.h +4 -8
  35. package/apple/RNCWebViewManager.mm +221 -0
  36. package/apple/RNCWebViewModule.h +23 -0
  37. package/apple/RNCWebViewModule.mm +34 -0
  38. package/index.d.ts +2 -3
  39. package/lib/NativeRNCWebViewModule.d.ts +8 -0
  40. package/lib/NativeRNCWebViewModule.js +1 -0
  41. package/lib/RNCWebViewNativeComponent.d.ts +245 -0
  42. package/lib/RNCWebViewNativeComponent.js +1 -0
  43. package/lib/WebView.android.d.ts +0 -1
  44. package/lib/WebView.android.js +1 -135
  45. package/lib/WebView.d.ts +2 -3
  46. package/lib/WebView.ios.d.ts +0 -1
  47. package/lib/WebView.ios.js +1 -114
  48. package/lib/WebView.js +1 -11
  49. package/lib/WebView.macos.d.ts +6 -0
  50. package/lib/WebView.macos.js +1 -0
  51. package/lib/WebView.styles.d.ts +37 -11
  52. package/lib/WebView.styles.js +1 -33
  53. package/lib/WebView.windows.d.ts +17 -0
  54. package/lib/WebView.windows.js +1 -0
  55. package/lib/WebViewNativeComponent.macos.d.ts +3 -0
  56. package/lib/WebViewNativeComponent.macos.js +1 -0
  57. package/lib/WebViewNativeComponent.windows.d.ts +3 -0
  58. package/lib/WebViewNativeComponent.windows.js +1 -0
  59. package/lib/WebViewShared.d.ts +30 -9
  60. package/lib/WebViewShared.js +1 -174
  61. package/lib/WebViewTypes.d.ts +514 -98
  62. package/lib/WebViewTypes.js +1 -6
  63. package/lib/index.d.ts +0 -1
  64. package/lib/index.js +1 -3
  65. package/lib/validation.d.ts +3 -0
  66. package/lib/validation.js +1 -0
  67. package/package.json +57 -33
  68. package/react-native-webview.podspec +32 -5
  69. package/react-native.config.js +22 -18
  70. package/src/NativeRNCWebViewModule.ts +13 -0
  71. package/src/RNCWebViewNativeComponent.ts +348 -0
  72. package/src/WebView.android.tsx +345 -0
  73. package/src/WebView.ios.tsx +341 -0
  74. package/src/WebView.macos.tsx +252 -0
  75. package/src/WebView.styles.ts +41 -0
  76. package/src/WebView.tsx +25 -0
  77. package/src/WebView.windows.tsx +217 -0
  78. package/src/WebViewNativeComponent.macos.ts +7 -0
  79. package/src/WebViewNativeComponent.windows.ts +8 -0
  80. package/src/WebViewShared.tsx +476 -0
  81. package/src/WebViewTypes.ts +1402 -0
  82. package/src/__tests__/WebViewShared-test.js +323 -0
  83. package/src/__tests__/__snapshots__/WebViewShared-test.js.snap +8 -0
  84. package/src/__tests__/validation-test.js +38 -0
  85. package/src/index.ts +4 -0
  86. package/src/validation.ts +20 -0
  87. package/android/.editorconfig +0 -6
  88. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManager.java +0 -1408
  89. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewModule.java +0 -506
  90. package/apple/RNCWebViewManager.m +0 -278
  91. package/lib/WebViewNativeComponent.android.d.ts +0 -4
  92. package/lib/WebViewNativeComponent.android.js +0 -3
  93. package/lib/WebViewNativeComponent.ios.d.ts +0 -4
  94. package/lib/WebViewNativeComponent.ios.js +0 -3
@@ -0,0 +1,323 @@
1
+ import { Linking } from 'react-native';
2
+
3
+ import {
4
+ defaultOriginWhitelist,
5
+ createOnShouldStartLoadWithRequest,
6
+ } from '../WebViewShared';
7
+
8
+ Linking.openURL.mockResolvedValue(undefined);
9
+ Linking.canOpenURL.mockResolvedValue(true);
10
+
11
+ // The tests that call createOnShouldStartLoadWithRequest will cause a promise
12
+ // to get kicked off (by calling the mocked `Linking.canOpenURL`) that the tests
13
+ // _need_ to get run to completion _before_ doing any `expect`ing. The reason
14
+ // is: once that promise is resolved another function should get run which will
15
+ // call `Linking.openURL`, and we want to test that.
16
+ //
17
+ // Normally we would probably do something like `await
18
+ // createShouldStartLoadWithRequest(...)` in the tests, but that doesn't work
19
+ // here because the promise that gets kicked off is not returned (because
20
+ // non-test code doesn't need to know about it).
21
+ //
22
+ // The tests thus need a way to "flush any pending promises" (to make sure
23
+ // pending promises run to completion) before doing any `expect`ing. `jest`
24
+ // doesn't provide a way to do this out of the box, but we can use this function
25
+ // to do it.
26
+ //
27
+ // See this issue for more discussion: https://github.com/facebook/jest/issues/2157
28
+ function flushPromises() {
29
+ return new Promise((resolve) => setImmediate(resolve));
30
+ }
31
+
32
+ describe('WebViewShared', () => {
33
+ test('exports defaultOriginWhitelist', () => {
34
+ expect(defaultOriginWhitelist).toMatchSnapshot();
35
+ });
36
+
37
+ describe('createOnShouldStartLoadWithRequest', () => {
38
+ const alwaysTrueOnShouldStartLoadWithRequest = (nativeEvent) => {
39
+ return true;
40
+ };
41
+
42
+ const alwaysFalseOnShouldStartLoadWithRequest = (nativeEvent) => {
43
+ return false;
44
+ };
45
+
46
+ const loadRequest = jest.fn();
47
+
48
+ test('loadRequest is called without onShouldStartLoadWithRequest override', async () => {
49
+ const onShouldStartLoadWithRequest = createOnShouldStartLoadWithRequest(
50
+ loadRequest,
51
+ defaultOriginWhitelist
52
+ );
53
+
54
+ onShouldStartLoadWithRequest({
55
+ nativeEvent: { url: 'https://www.example.com/', lockIdentifier: 1 },
56
+ });
57
+
58
+ await flushPromises();
59
+
60
+ expect(Linking.openURL).toHaveBeenCalledTimes(0);
61
+ expect(loadRequest).toHaveBeenCalledWith(
62
+ true,
63
+ 'https://www.example.com/',
64
+ 1
65
+ );
66
+ });
67
+
68
+ test('Linking.openURL is called without onShouldStartLoadWithRequest override', async () => {
69
+ const onShouldStartLoadWithRequest = createOnShouldStartLoadWithRequest(
70
+ loadRequest,
71
+ defaultOriginWhitelist
72
+ );
73
+
74
+ onShouldStartLoadWithRequest({
75
+ nativeEvent: { url: 'invalid://example.com/', lockIdentifier: 2 },
76
+ });
77
+
78
+ await flushPromises();
79
+
80
+ expect(Linking.openURL).toHaveBeenCalledWith('invalid://example.com/');
81
+ expect(loadRequest).toHaveBeenCalledWith(
82
+ false,
83
+ 'invalid://example.com/',
84
+ 2
85
+ );
86
+ });
87
+
88
+ test('loadRequest with true onShouldStartLoadWithRequest override is called', async () => {
89
+ const onShouldStartLoadWithRequest = createOnShouldStartLoadWithRequest(
90
+ loadRequest,
91
+ defaultOriginWhitelist,
92
+ alwaysTrueOnShouldStartLoadWithRequest
93
+ );
94
+
95
+ onShouldStartLoadWithRequest({
96
+ nativeEvent: { url: 'https://www.example.com/', lockIdentifier: 1 },
97
+ });
98
+
99
+ await flushPromises();
100
+
101
+ expect(Linking.openURL).toHaveBeenCalledTimes(0);
102
+ expect(loadRequest).toHaveBeenLastCalledWith(
103
+ true,
104
+ 'https://www.example.com/',
105
+ 1
106
+ );
107
+ });
108
+
109
+ test('Linking.openURL with true onShouldStartLoadWithRequest override is called for links not passing the whitelist', async () => {
110
+ const onShouldStartLoadWithRequest = createOnShouldStartLoadWithRequest(
111
+ loadRequest,
112
+ defaultOriginWhitelist,
113
+ alwaysTrueOnShouldStartLoadWithRequest
114
+ );
115
+
116
+ onShouldStartLoadWithRequest({
117
+ nativeEvent: { url: 'invalid://example.com/', lockIdentifier: 1 },
118
+ });
119
+
120
+ await flushPromises();
121
+
122
+ expect(Linking.openURL).toHaveBeenLastCalledWith(
123
+ 'invalid://example.com/'
124
+ );
125
+ // We don't expect the URL to have been loaded in the WebView because it
126
+ // is not in the origin whitelist
127
+ expect(loadRequest).toHaveBeenLastCalledWith(
128
+ false,
129
+ 'invalid://example.com/',
130
+ 1
131
+ );
132
+ });
133
+
134
+ test('loadRequest with false onShouldStartLoadWithRequest override is called', async () => {
135
+ const onShouldStartLoadWithRequest = createOnShouldStartLoadWithRequest(
136
+ loadRequest,
137
+ defaultOriginWhitelist,
138
+ alwaysFalseOnShouldStartLoadWithRequest
139
+ );
140
+
141
+ onShouldStartLoadWithRequest({
142
+ nativeEvent: { url: 'https://www.example.com/', lockIdentifier: 1 },
143
+ });
144
+
145
+ await flushPromises();
146
+
147
+ expect(Linking.openURL).toHaveBeenCalledTimes(0);
148
+ expect(loadRequest).toHaveBeenLastCalledWith(
149
+ false,
150
+ 'https://www.example.com/',
151
+ 1
152
+ );
153
+ });
154
+
155
+ test('loadRequest with limited whitelist', async () => {
156
+ const onShouldStartLoadWithRequest = createOnShouldStartLoadWithRequest(
157
+ loadRequest,
158
+ ['https://*']
159
+ );
160
+
161
+ onShouldStartLoadWithRequest({
162
+ nativeEvent: { url: 'https://www.example.com/', lockIdentifier: 1 },
163
+ });
164
+
165
+ await flushPromises();
166
+
167
+ expect(Linking.openURL).toHaveBeenCalledTimes(0);
168
+ expect(loadRequest).toHaveBeenLastCalledWith(
169
+ true,
170
+ 'https://www.example.com/',
171
+ 1
172
+ );
173
+
174
+ onShouldStartLoadWithRequest({
175
+ nativeEvent: { url: 'http://insecure.com/', lockIdentifier: 2 },
176
+ });
177
+
178
+ await flushPromises();
179
+
180
+ expect(Linking.openURL).toHaveBeenLastCalledWith('http://insecure.com/');
181
+ expect(loadRequest).toHaveBeenLastCalledWith(
182
+ false,
183
+ 'http://insecure.com/',
184
+ 2
185
+ );
186
+
187
+ onShouldStartLoadWithRequest({
188
+ nativeEvent: { url: 'git+https://insecure.com/', lockIdentifier: 3 },
189
+ });
190
+
191
+ await flushPromises();
192
+
193
+ expect(Linking.openURL).toHaveBeenLastCalledWith(
194
+ 'git+https://insecure.com/'
195
+ );
196
+ expect(loadRequest).toHaveBeenLastCalledWith(
197
+ false,
198
+ 'git+https://insecure.com/',
199
+ 3
200
+ );
201
+
202
+ onShouldStartLoadWithRequest({
203
+ nativeEvent: { url: 'fakehttps://insecure.com/', lockIdentifier: 4 },
204
+ });
205
+
206
+ await flushPromises();
207
+
208
+ expect(Linking.openURL).toHaveBeenLastCalledWith(
209
+ 'fakehttps://insecure.com/'
210
+ );
211
+ expect(loadRequest).toHaveBeenLastCalledWith(
212
+ false,
213
+ 'fakehttps://insecure.com/',
214
+ 4
215
+ );
216
+ });
217
+
218
+ test('loadRequest allows for valid URIs', async () => {
219
+ const onShouldStartLoadWithRequest = createOnShouldStartLoadWithRequest(
220
+ loadRequest,
221
+ [
222
+ 'plus+https://*',
223
+ 'DOT.https://*',
224
+ 'dash-https://*',
225
+ '0invalid://*',
226
+ '+invalid://*',
227
+ ]
228
+ );
229
+
230
+ onShouldStartLoadWithRequest({
231
+ nativeEvent: {
232
+ url: 'plus+https://www.example.com/',
233
+ lockIdentifier: 1,
234
+ },
235
+ });
236
+
237
+ await flushPromises();
238
+ expect(Linking.openURL).toHaveBeenCalledTimes(0);
239
+ expect(loadRequest).toHaveBeenLastCalledWith(
240
+ true,
241
+ 'plus+https://www.example.com/',
242
+ 1
243
+ );
244
+
245
+ onShouldStartLoadWithRequest({
246
+ nativeEvent: { url: 'DOT.https://www.example.com/', lockIdentifier: 2 },
247
+ });
248
+
249
+ await flushPromises();
250
+
251
+ expect(Linking.openURL).toHaveBeenCalledTimes(0);
252
+ expect(loadRequest).toHaveBeenLastCalledWith(
253
+ true,
254
+ 'DOT.https://www.example.com/',
255
+ 2
256
+ );
257
+
258
+ onShouldStartLoadWithRequest({
259
+ nativeEvent: {
260
+ url: 'dash-https://www.example.com/',
261
+ lockIdentifier: 3,
262
+ },
263
+ });
264
+
265
+ await flushPromises();
266
+
267
+ expect(Linking.openURL).toHaveBeenCalledTimes(0);
268
+ expect(loadRequest).toHaveBeenLastCalledWith(
269
+ true,
270
+ 'dash-https://www.example.com/',
271
+ 3
272
+ );
273
+
274
+ onShouldStartLoadWithRequest({
275
+ nativeEvent: { url: '0invalid://www.example.com/', lockIdentifier: 4 },
276
+ });
277
+
278
+ await flushPromises();
279
+
280
+ expect(Linking.openURL).toHaveBeenLastCalledWith(
281
+ '0invalid://www.example.com/'
282
+ );
283
+ expect(loadRequest).toHaveBeenLastCalledWith(
284
+ false,
285
+ '0invalid://www.example.com/',
286
+ 4
287
+ );
288
+
289
+ onShouldStartLoadWithRequest({
290
+ nativeEvent: { url: '+invalid://www.example.com/', lockIdentifier: 5 },
291
+ });
292
+
293
+ await flushPromises();
294
+
295
+ expect(Linking.openURL).toHaveBeenLastCalledWith(
296
+ '+invalid://www.example.com/'
297
+ );
298
+ expect(loadRequest).toHaveBeenLastCalledWith(
299
+ false,
300
+ '+invalid://www.example.com/',
301
+ 5
302
+ );
303
+
304
+ onShouldStartLoadWithRequest({
305
+ nativeEvent: {
306
+ url: 'FAKE+plus+https://www.example.com/',
307
+ lockIdentifier: 6,
308
+ },
309
+ });
310
+
311
+ await flushPromises();
312
+
313
+ expect(Linking.openURL).toHaveBeenLastCalledWith(
314
+ 'FAKE+plus+https://www.example.com/'
315
+ );
316
+ expect(loadRequest).toHaveBeenLastCalledWith(
317
+ false,
318
+ 'FAKE+plus+https://www.example.com/',
319
+ 6
320
+ );
321
+ });
322
+ });
323
+ });
@@ -0,0 +1,8 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`WebViewShared exports defaultOriginWhitelist 1`] = `
4
+ [
5
+ "http://*",
6
+ "https://*",
7
+ ]
8
+ `;
@@ -0,0 +1,38 @@
1
+ import validateProps from '../validation';
2
+
3
+ describe('validateProps', () => {
4
+ test('throws when providing static html without origin whitelist', () => {
5
+ expect(() => {
6
+ validateProps({
7
+ source: { html: '<h1>Wayne Foundation</h1>' },
8
+ });
9
+ }).toThrow('originWhitelist');
10
+ });
11
+
12
+ test('throws when providing static html with wildcard whitelist', () => {
13
+ expect(() => {
14
+ validateProps({
15
+ originWhitelist: ['*', 'http://localhost'],
16
+ source: { html: '<h1>Wayne Foundation</h1>' },
17
+ });
18
+ }).toThrow('originWhitelist');
19
+ });
20
+
21
+ test('throws when providing static html with empty whitelist', () => {
22
+ expect(() => {
23
+ validateProps({
24
+ originWhitelist: [],
25
+ source: { html: '<h1>Wayne Foundation</h1>' },
26
+ });
27
+ }).toThrow('originWhitelist');
28
+ });
29
+
30
+ test('returns props when origin whitelist present', () => {
31
+ const props = {
32
+ originWhitelist: ['http://localhost'],
33
+ source: { html: '<h1>Wayne Foundation</h1>' },
34
+ };
35
+
36
+ expect(validateProps(props)).toBe(props);
37
+ });
38
+ });
package/src/index.ts ADDED
@@ -0,0 +1,4 @@
1
+ import WebView from './WebView';
2
+
3
+ export { WebView };
4
+ export default WebView;
@@ -0,0 +1,20 @@
1
+ import invariant from 'invariant';
2
+ import type { AndroidWebViewProps, IOSWebViewProps } from './WebViewTypes';
3
+
4
+ const validateProps = <P extends IOSWebViewProps | AndroidWebViewProps>(
5
+ props: P
6
+ ): P => {
7
+ if (props.source && 'html' in props.source) {
8
+ const { originWhitelist } = props;
9
+ invariant(
10
+ originWhitelist &&
11
+ originWhitelist.length > 0 &&
12
+ !originWhitelist.includes('*'),
13
+ 'originWhitelist is required when using source.html prop and cannot include *'
14
+ );
15
+ }
16
+
17
+ return props;
18
+ };
19
+
20
+ export default validateProps;
@@ -1,6 +0,0 @@
1
- [*]
2
- charset=utf-8
3
- end_of_line=lf
4
- insert_final_newline=false
5
- indent_style=space
6
- indent_size=2