@exodus/react-native-webview 11.26.1-exodus.1 → 11.26.1-exodus.11

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.
@@ -1,65 +1,17 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- var __generator = (this && this.__generator) || function (thisArg, body) {
11
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
12
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
13
- function verb(n) { return function (v) { return step([n, v]); }; }
14
- function step(op) {
15
- if (f) throw new TypeError("Generator is already executing.");
16
- while (_) try {
17
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
18
- if (y = 0, t) op = [op[0] & 2, t.value];
19
- switch (op[0]) {
20
- case 0: case 1: t = op; break;
21
- case 4: _.label++; return { value: op[1], done: false };
22
- case 5: _.label++; y = op[1]; op = [0]; continue;
23
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
24
- default:
25
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
26
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
27
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
28
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
29
- if (t[2]) _.ops.pop();
30
- _.trys.pop(); continue;
31
- }
32
- op = body.call(thisArg, _);
33
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
34
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
35
- }
36
- };
37
- var __rest = (this && this.__rest) || function (s, e) {
38
- var t = {};
39
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
40
- t[p] = s[p];
41
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
42
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
43
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
44
- t[p[i]] = s[p[i]];
45
- }
46
- return t;
47
- };
48
1
  import React, { forwardRef, useCallback, useImperativeHandle, useRef } from 'react';
49
- import { Image, View, NativeModules, } from 'react-native';
2
+ import { Text, View, NativeModules, Platform, } from 'react-native';
50
3
  import invariant from 'invariant';
51
4
  // @ts-expect-error react-native doesn't have this type
52
5
  import codegenNativeCommandsUntyped from 'react-native/Libraries/Utilities/codegenNativeCommands';
53
6
  import RNCWebView from "./WebViewNativeComponent.ios";
54
- import { defaultOriginWhitelist, defaultRenderError, defaultRenderLoading, useWebWiewLogic, } from './WebViewShared';
7
+ import { defaultOriginWhitelist, defaultRenderError, defaultRenderLoading, useWebWiewLogic, versionPasses, } from './WebViewShared';
55
8
  import styles from './WebView.styles';
56
- var codegenNativeCommands = codegenNativeCommandsUntyped;
57
- var Commands = codegenNativeCommands({
58
- supportedCommands: ['goBack', 'goForward', 'reload', 'stopLoading', /* 'injectJavaScript', */ 'requestFocus', 'postMessage', 'loadUrl']
9
+ const codegenNativeCommands = codegenNativeCommandsUntyped;
10
+ const Commands = codegenNativeCommands({
11
+ supportedCommands: ['goBack', 'goForward', 'reload', 'stopLoading', /* 'injectJavaScript', */ 'requestFocus', 'postMessage', 'loadUrl'],
59
12
  });
60
- var resolveAssetSource = Image.resolveAssetSource;
61
- var processDecelerationRate = function (decelerationRate) {
62
- var newDecelerationRate = decelerationRate;
13
+ const processDecelerationRate = (decelerationRate) => {
14
+ let newDecelerationRate = decelerationRate;
63
15
  if (newDecelerationRate === 'normal') {
64
16
  newDecelerationRate = 0.998;
65
17
  }
@@ -68,71 +20,72 @@ var processDecelerationRate = function (decelerationRate) {
68
20
  }
69
21
  return newDecelerationRate;
70
22
  };
71
- var RNCWebViewManager = NativeModules.RNCWebViewManager;
72
- var useWarnIfChanges = function (value, name) {
73
- var ref = useRef(value);
23
+ const RNCWebViewManager = NativeModules.RNCWebViewManager;
24
+ const useWarnIfChanges = (value, name) => {
25
+ const ref = useRef(value);
74
26
  if (ref.current !== value) {
75
- console.warn("Changes to property ".concat(name, " do nothing after the initial render."));
27
+ console.warn(`Changes to property ${name} do nothing after the initial render.`);
76
28
  ref.current = value;
77
29
  }
78
30
  };
79
31
  /**
80
32
  * Harcoded defaults for security.
81
33
  */
82
- var allowFileAccessFromFileURLs = false;
83
- var allowUniversalAccessFromFileURLs = false;
84
- var injectedJavaScriptForMainFrameOnly = true;
85
- var injectedJavaScriptBeforeContentLoadedForMainFrameOnly = true;
86
- var mediaPlaybackRequiresUserAction = true;
34
+ const mediaPlaybackRequiresUserAction = true;
87
35
  // iOS only configs
88
- var allowsInlineMediaPlayback = true;
89
- var allowsAirPlayForMediaPlayback = false;
90
- var useSharedProcessPool = false;
91
- var sharedCookiesEnabled = false;
92
- var enableApplePay = false;
93
- var onFileDownload = function () { return console.error('tried to download file'); };
94
- var dataDetectorTypes = 'none';
95
- var WebViewComponent = forwardRef(function (_a, ref) {
96
- var _b = _a.javaScriptEnabled, javaScriptEnabled = _b === void 0 ? true : _b, _c = _a.cacheEnabled, cacheEnabled = _c === void 0 ? true : _c, _d = _a.originWhitelist, originWhitelist = _d === void 0 ? defaultOriginWhitelist : _d, _e = _a.textInteractionEnabled, textInteractionEnabled = _e === void 0 ? true : _e, injectedJavaScript = _a.injectedJavaScript, injectedJavaScriptBeforeContentLoaded = _a.injectedJavaScriptBeforeContentLoaded, startInLoadingState = _a.startInLoadingState, onNavigationStateChange = _a.onNavigationStateChange, onLoadStart = _a.onLoadStart, onError = _a.onError, onLoad = _a.onLoad, onLoadEnd = _a.onLoadEnd, onLoadProgress = _a.onLoadProgress, onContentProcessDidTerminateProp = _a.onContentProcessDidTerminate, onHttpErrorProp = _a.onHttpError, onMessageProp = _a.onMessage, renderLoading = _a.renderLoading, renderError = _a.renderError, style = _a.style, containerStyle = _a.containerStyle, source = _a.source, incognito = _a.incognito, decelerationRateProp = _a.decelerationRate, onShouldStartLoadWithRequestProp = _a.onShouldStartLoadWithRequest, otherProps = __rest(_a, ["javaScriptEnabled", "cacheEnabled", "originWhitelist", "textInteractionEnabled", "injectedJavaScript", "injectedJavaScriptBeforeContentLoaded", "startInLoadingState", "onNavigationStateChange", "onLoadStart", "onError", "onLoad", "onLoadEnd", "onLoadProgress", "onContentProcessDidTerminate", "onHttpError", "onMessage", "renderLoading", "renderError", "style", "containerStyle", "source", "incognito", "decelerationRate", "onShouldStartLoadWithRequest"]);
97
- var webViewRef = useRef(null);
98
- var onShouldStartLoadWithRequestCallback = useCallback(function (shouldStart, _url, lockIdentifier) {
99
- if (lockIdentifier === void 0) { lockIdentifier = 0; }
100
- var viewManager = RNCWebViewManager;
36
+ const allowsInlineMediaPlayback = true;
37
+ const useSharedProcessPool = false;
38
+ const sharedCookiesEnabled = false;
39
+ const enableApplePay = false;
40
+ const dataDetectorTypes = 'none';
41
+ const hardMinimumIOSVersion = '12.5.6 <13, 13.6.1 <14, 14.8.1 <15, 15.7.1';
42
+ const WebViewComponent = forwardRef(({ javaScriptEnabled = true, cacheEnabled = true, originWhitelist = defaultOriginWhitelist, textInteractionEnabled = true, injectedJavaScript, injectedJavaScriptBeforeContentLoaded, startInLoadingState, onLoadStart, onError, onLoad, onLoadEnd, onMessage: onMessageProp, renderLoading, renderError, style, containerStyle, source, incognito, validateMeta, validateData, decelerationRate: decelerationRateProp, onShouldStartLoadWithRequest: onShouldStartLoadWithRequestProp, minimumIOSVersion, unsupportedVersionComponent: UnsupportedVersionComponent, ...otherProps }, ref) => {
43
+ const webViewRef = useRef(null);
44
+ const onShouldStartLoadWithRequestCallback = useCallback((shouldStart, _url, lockIdentifier = 0) => {
45
+ const viewManager = RNCWebViewManager;
101
46
  viewManager.startLoadWithResult(!!shouldStart, lockIdentifier);
102
47
  }, []);
103
- var _f = useWebWiewLogic({
104
- onNavigationStateChange: onNavigationStateChange,
105
- onLoad: onLoad,
106
- onError: onError,
107
- onHttpErrorProp: onHttpErrorProp,
108
- onLoadEnd: onLoadEnd,
109
- onLoadProgress: onLoadProgress,
110
- onLoadStart: onLoadStart,
111
- onMessageProp: onMessageProp,
112
- startInLoadingState: startInLoadingState,
113
- originWhitelist: originWhitelist,
114
- onShouldStartLoadWithRequestProp: onShouldStartLoadWithRequestProp,
115
- onShouldStartLoadWithRequestCallback: onShouldStartLoadWithRequestCallback,
116
- onContentProcessDidTerminateProp: onContentProcessDidTerminateProp
117
- }), onLoadingStart = _f.onLoadingStart, onShouldStartLoadWithRequest = _f.onShouldStartLoadWithRequest, onMessage = _f.onMessage, viewState = _f.viewState, setViewState = _f.setViewState, lastErrorEvent = _f.lastErrorEvent, onHttpError = _f.onHttpError, onLoadingError = _f.onLoadingError, onLoadingFinish = _f.onLoadingFinish, onLoadingProgress = _f.onLoadingProgress, onContentProcessDidTerminate = _f.onContentProcessDidTerminate;
118
- useImperativeHandle(ref, function () { return ({
119
- goForward: function () { return Commands.goForward(webViewRef.current); },
120
- goBack: function () { return Commands.goBack(webViewRef.current); },
121
- reload: function () {
48
+ const { onLoadingStart, onShouldStartLoadWithRequest, onMessage, viewState, setViewState, lastErrorEvent, onLoadingError, onLoadingFinish, onLoadingProgress } = useWebWiewLogic({
49
+ onLoad,
50
+ onError,
51
+ onLoadEnd,
52
+ onLoadStart,
53
+ onMessageProp,
54
+ startInLoadingState,
55
+ originWhitelist,
56
+ onShouldStartLoadWithRequestProp,
57
+ onShouldStartLoadWithRequestCallback,
58
+ validateMeta,
59
+ validateData,
60
+ });
61
+ useImperativeHandle(ref, () => ({
62
+ goForward: () => Commands.goForward(webViewRef.current),
63
+ goBack: () => Commands.goBack(webViewRef.current),
64
+ reload: () => {
122
65
  setViewState('LOADING');
123
66
  Commands.reload(webViewRef.current);
124
67
  },
125
- stopLoading: function () { return Commands.stopLoading(webViewRef.current); },
126
- postMessage: function (data) { return Commands.postMessage(webViewRef.current, data); },
68
+ stopLoading: () => Commands.stopLoading(webViewRef.current),
69
+ postMessage: (data) => Commands.postMessage(webViewRef.current, data),
127
70
  // injectJavaScript: (data: string) => Commands.injectJavaScript(webViewRef.current, data),
128
- requestFocus: function () { return Commands.requestFocus(webViewRef.current); }
129
- }); }, [setViewState, webViewRef]);
71
+ requestFocus: () => Commands.requestFocus(webViewRef.current),
72
+ }), [setViewState, webViewRef]);
130
73
  useWarnIfChanges(allowsInlineMediaPlayback, 'allowsInlineMediaPlayback');
131
- useWarnIfChanges(allowsAirPlayForMediaPlayback, 'allowsAirPlayForMediaPlayback');
132
74
  useWarnIfChanges(incognito, 'incognito');
133
75
  useWarnIfChanges(mediaPlaybackRequiresUserAction, 'mediaPlaybackRequiresUserAction');
134
76
  useWarnIfChanges(dataDetectorTypes, 'dataDetectorTypes');
135
- var otherView = null;
77
+ const version = String(Platform.Version);
78
+ if (!(versionPasses(version, minimumIOSVersion) && versionPasses(version, hardMinimumIOSVersion))) {
79
+ if (UnsupportedVersionComponent) {
80
+ return <UnsupportedVersionComponent />;
81
+ }
82
+ return (<View style={{ alignSelf: 'flex-start' }}>
83
+ <Text style={{ color: 'red' }}>
84
+ iOS version is outdated and insecure. Update it to continue.
85
+ </Text>
86
+ </View>);
87
+ }
88
+ let otherView = null;
136
89
  if (viewState === 'LOADING') {
137
90
  otherView = (renderLoading || defaultRenderLoading)();
138
91
  }
@@ -141,23 +94,21 @@ var WebViewComponent = forwardRef(function (_a, ref) {
141
94
  otherView = (renderError || defaultRenderError)(lastErrorEvent.domain, lastErrorEvent.code, lastErrorEvent.description);
142
95
  }
143
96
  else if (viewState !== 'IDLE') {
144
- console.error("RNCWebView invalid state encountered: ".concat(viewState));
97
+ console.error(`RNCWebView invalid state encountered: ${viewState}`);
145
98
  }
146
- var webViewStyles = [styles.container, styles.webView, style];
147
- var webViewContainerStyle = [styles.container, containerStyle];
148
- var decelerationRate = processDecelerationRate(decelerationRateProp);
149
- var NativeWebView = RNCWebView;
150
- var webView = (<NativeWebView key="webViewKey" {...otherProps} allowFileAccessFromFileURLs={allowFileAccessFromFileURLs} allowUniversalAccessFromFileURLs={allowUniversalAccessFromFileURLs} enableApplePay={enableApplePay} javaScriptEnabled={javaScriptEnabled} cacheEnabled={cacheEnabled} dataDetectorTypes={dataDetectorTypes} useSharedProcessPool={useSharedProcessPool} textInteractionEnabled={textInteractionEnabled} decelerationRate={decelerationRate} messagingEnabled={typeof onMessageProp === 'function'} onLoadingError={onLoadingError} onLoadingFinish={onLoadingFinish} onLoadingProgress={onLoadingProgress} onFileDownload={onFileDownload} onLoadingStart={onLoadingStart} onHttpError={onHttpError} onMessage={onMessage} onShouldStartLoadWithRequest={onShouldStartLoadWithRequest} onContentProcessDidTerminate={onContentProcessDidTerminate} injectedJavaScript={injectedJavaScript} injectedJavaScriptBeforeContentLoaded={injectedJavaScriptBeforeContentLoaded} injectedJavaScriptForMainFrameOnly={injectedJavaScriptForMainFrameOnly} injectedJavaScriptBeforeContentLoadedForMainFrameOnly={injectedJavaScriptBeforeContentLoadedForMainFrameOnly} allowsAirPlayForMediaPlayback={allowsAirPlayForMediaPlayback} allowsInlineMediaPlayback={allowsInlineMediaPlayback} incognito={incognito} mediaPlaybackRequiresUserAction={mediaPlaybackRequiresUserAction} ref={webViewRef} sharedCookiesEnabled={sharedCookiesEnabled}
99
+ const webViewStyles = [styles.container, styles.webView, style];
100
+ const webViewContainerStyle = [styles.container, containerStyle];
101
+ const decelerationRate = processDecelerationRate(decelerationRateProp);
102
+ const NativeWebView = RNCWebView;
103
+ const webView = (<NativeWebView key="webViewKey" {...otherProps} enableApplePay={enableApplePay} javaScriptEnabled={javaScriptEnabled} cacheEnabled={cacheEnabled} dataDetectorTypes={dataDetectorTypes} useSharedProcessPool={useSharedProcessPool} textInteractionEnabled={textInteractionEnabled} decelerationRate={decelerationRate} messagingEnabled={typeof onMessageProp === 'function'} onLoadingError={onLoadingError} onLoadingFinish={onLoadingFinish} onLoadingProgress={onLoadingProgress} onLoadingStart={onLoadingStart} onMessage={onMessage} onShouldStartLoadWithRequest={onShouldStartLoadWithRequest} injectedJavaScript={injectedJavaScript} injectedJavaScriptBeforeContentLoaded={injectedJavaScriptBeforeContentLoaded} allowsInlineMediaPlayback={allowsInlineMediaPlayback} incognito={incognito} mediaPlaybackRequiresUserAction={mediaPlaybackRequiresUserAction} ref={webViewRef} sharedCookiesEnabled={sharedCookiesEnabled}
151
104
  // TODO: find a better way to type this.
152
- source={resolveAssetSource(source)} style={webViewStyles}/>);
105
+ source={source} style={webViewStyles}/>);
153
106
  return (<View style={webViewContainerStyle}>
154
107
  {webView}
155
108
  {otherView}
156
109
  </View>);
157
110
  });
158
111
  // no native implementation for iOS, depends only on permissions
159
- var isFileUploadSupported = function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) {
160
- return [2 /*return*/, true];
161
- }); }); };
162
- var WebView = Object.assign(WebViewComponent, { isFileUploadSupported: isFileUploadSupported });
112
+ const isFileUploadSupported = async () => true;
113
+ const WebView = Object.assign(WebViewComponent, { isFileUploadSupported });
163
114
  export default WebView;
package/lib/WebView.js CHANGED
@@ -2,10 +2,10 @@ import React from 'react';
2
2
  import { Text, View } from 'react-native';
3
3
  // This "dummy" WebView is to render something for unsupported platforms,
4
4
  // like for example Expo SDK "web" platform.
5
- var WebView = function () { return (<View style={{ alignSelf: 'flex-start' }}>
5
+ const WebView = () => (<View style={{ alignSelf: 'flex-start' }}>
6
6
  <Text style={{ color: 'red' }}>
7
7
  React Native WebView does not support this platform.
8
8
  </Text>
9
- </View>); };
9
+ </View>);
10
10
  export { WebView };
11
11
  export default WebView;
@@ -1,8 +1,8 @@
1
1
  import { StyleSheet } from 'react-native';
2
- var styles = StyleSheet.create({
2
+ const styles = StyleSheet.create({
3
3
  container: {
4
4
  flex: 1,
5
- overflow: 'hidden'
5
+ overflow: 'hidden',
6
6
  },
7
7
  loadingOrErrorView: {
8
8
  position: 'absolute',
@@ -14,20 +14,20 @@ var styles = StyleSheet.create({
14
14
  backgroundColor: 'white'
15
15
  },
16
16
  loadingProgressBar: {
17
- height: 20
17
+ height: 20,
18
18
  },
19
19
  errorText: {
20
20
  fontSize: 14,
21
21
  textAlign: 'center',
22
- marginBottom: 2
22
+ marginBottom: 2,
23
23
  },
24
24
  errorTextTitle: {
25
25
  fontSize: 15,
26
26
  fontWeight: '500',
27
- marginBottom: 10
27
+ marginBottom: 10,
28
28
  },
29
29
  webView: {
30
- backgroundColor: '#ffffff'
31
- }
30
+ backgroundColor: '#ffffff',
31
+ },
32
32
  });
33
33
  export default styles;
@@ -1,3 +1,3 @@
1
1
  import { requireNativeComponent } from "react-native";
2
- var RNCWebView = requireNativeComponent('RNCWebView');
2
+ const RNCWebView = requireNativeComponent('RNCWebView');
3
3
  export default RNCWebView;
@@ -1,3 +1,3 @@
1
1
  import { requireNativeComponent } from "react-native";
2
- var RNCWebView = requireNativeComponent('RNCWebView');
2
+ const RNCWebView = requireNativeComponent('RNCWebView');
3
3
  export default RNCWebView;
@@ -1,37 +1,33 @@
1
1
  import React from 'react';
2
- import { OnShouldStartLoadWithRequest, ShouldStartLoadRequestEvent, WebViewError, WebViewErrorEvent, WebViewHttpErrorEvent, WebViewMessageEvent, WebViewNavigation, WebViewNavigationEvent, WebViewProgressEvent, WebViewRenderProcessGoneEvent, WebViewTerminatedEvent } from './WebViewTypes';
3
- declare const defaultOriginWhitelist: readonly ["http://*", "https://*"];
2
+ import { OnShouldStartLoadWithRequest, ShouldStartLoadRequestEvent, WebViewError, WebViewErrorEvent, WebViewMessageEvent, WebViewMessage, WebViewNavigationEvent, WebViewProgressEvent, WebViewNativeEvent } from './WebViewTypes';
3
+ declare const defaultOriginWhitelist: readonly ["https://*"];
4
4
  declare const createOnShouldStartLoadWithRequest: (loadRequest: (shouldStart: boolean, url: string, lockIdentifier: number) => void, originWhitelist: readonly string[], onShouldStartLoadWithRequest?: OnShouldStartLoadWithRequest | undefined) => ({ nativeEvent }: ShouldStartLoadRequestEvent) => void;
5
5
  declare const defaultRenderLoading: () => JSX.Element;
6
6
  declare const defaultRenderError: (errorDomain: string | undefined, errorCode: number, errorDesc: string) => JSX.Element;
7
7
  export { defaultOriginWhitelist, createOnShouldStartLoadWithRequest, defaultRenderLoading, defaultRenderError, };
8
- export declare const useWebWiewLogic: ({ startInLoadingState, onNavigationStateChange, onLoadStart, onLoad, onLoadProgress, onLoadEnd, onError, onHttpErrorProp, onMessageProp, onRenderProcessGoneProp, onContentProcessDidTerminateProp, originWhitelist, onShouldStartLoadWithRequestProp, onShouldStartLoadWithRequestCallback, }: {
8
+ export declare const useWebWiewLogic: ({ startInLoadingState, onLoadStart, onLoad, onLoadEnd, onError, onMessageProp, originWhitelist, onShouldStartLoadWithRequestProp, onShouldStartLoadWithRequestCallback, validateMeta, validateData, }: {
9
9
  startInLoadingState?: boolean | undefined;
10
- onNavigationStateChange?: ((event: WebViewNavigation) => void) | undefined;
11
10
  onLoadStart?: ((event: WebViewNavigationEvent) => void) | undefined;
12
11
  onLoad?: ((event: WebViewNavigationEvent) => void) | undefined;
13
- onLoadProgress?: ((event: WebViewProgressEvent) => void) | undefined;
14
12
  onLoadEnd?: ((event: WebViewNavigationEvent | WebViewErrorEvent) => void) | undefined;
15
13
  onError?: ((event: WebViewErrorEvent) => void) | undefined;
16
- onHttpErrorProp?: ((event: WebViewHttpErrorEvent) => void) | undefined;
17
- onMessageProp?: ((event: WebViewMessageEvent) => void) | undefined;
18
- onRenderProcessGoneProp?: ((event: WebViewRenderProcessGoneEvent) => void) | undefined;
19
- onContentProcessDidTerminateProp?: ((event: WebViewTerminatedEvent) => void) | undefined;
14
+ onMessageProp?: ((event: WebViewMessage) => void) | undefined;
20
15
  originWhitelist: readonly string[];
21
16
  onShouldStartLoadWithRequestProp?: OnShouldStartLoadWithRequest | undefined;
22
17
  onShouldStartLoadWithRequestCallback: (shouldStart: boolean, url: string, lockIdentifier?: number | undefined) => void;
18
+ validateMeta: (event: WebViewNativeEvent) => WebViewNativeEvent;
19
+ validateData: (data: object) => object;
23
20
  }) => {
24
21
  onShouldStartLoadWithRequest: ({ nativeEvent }: ShouldStartLoadRequestEvent) => void;
25
22
  onLoadingStart: (event: WebViewNavigationEvent) => void;
26
23
  onLoadingProgress: (event: WebViewProgressEvent) => void;
27
24
  onLoadingError: (event: WebViewErrorEvent) => void;
28
25
  onLoadingFinish: (event: WebViewNavigationEvent) => void;
29
- onHttpError: (event: WebViewHttpErrorEvent) => void;
30
- onRenderProcessGone: (event: WebViewRenderProcessGoneEvent) => void;
31
- onContentProcessDidTerminate: (event: WebViewTerminatedEvent) => void;
32
26
  onMessage: (event: WebViewMessageEvent) => void;
27
+ passesWhitelist: (url: string) => boolean | null;
33
28
  viewState: "IDLE" | "LOADING" | "ERROR";
34
29
  setViewState: React.Dispatch<React.SetStateAction<"IDLE" | "LOADING" | "ERROR">>;
35
30
  lastErrorEvent: WebViewError | null;
36
31
  };
32
+ export declare const versionPasses: (version: string | undefined, minimum: string | undefined) => boolean;
37
33
  //# sourceMappingURL=WebViewShared.d.ts.map
@@ -1,44 +1,34 @@
1
- var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
2
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
3
- if (ar || !(i in from)) {
4
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
5
- ar[i] = from[i];
6
- }
7
- }
8
- return to.concat(ar || Array.prototype.slice.call(from));
9
- };
10
1
  import escapeStringRegexp from 'escape-string-regexp';
11
2
  import React, { useCallback, useMemo, useRef, useState } from 'react';
12
3
  import { Linking, View, ActivityIndicator, Text, Platform } from 'react-native';
13
4
  import styles from './WebView.styles';
14
- var defaultOriginWhitelist = ['http://*', 'https://*'];
15
- var extractOrigin = function (url) {
16
- var result = /^[A-Za-z][A-Za-z0-9+\-.]+:(\/\/)?[^/]*/.exec(url);
5
+ const defaultOriginWhitelist = ['https://*'];
6
+ const extractOrigin = (url) => {
7
+ const result = /^[A-Za-z][A-Za-z0-9+\-.]+:(\/\/)?[^/]*/.exec(url);
17
8
  return result === null ? '' : result[0];
18
9
  };
19
- var originWhitelistToRegex = function (originWhitelist) {
20
- return "^".concat(escapeStringRegexp(originWhitelist).replace(/\\\*/g, '.*'));
21
- };
22
- var passesWhitelist = function (compiledWhitelist, url) {
23
- var origin = extractOrigin(url);
24
- return compiledWhitelist.some(function (x) { return new RegExp(x).test(origin); });
10
+ const originWhitelistToRegex = (originWhitelist) => `^${escapeStringRegexp(originWhitelist).replace(/\\\*/g, '.*')}$`;
11
+ const _passesWhitelist = (compiledWhitelist, url) => {
12
+ const origin = extractOrigin(url);
13
+ if (!origin)
14
+ return false;
15
+ if (origin !== new URL(url).origin)
16
+ return null;
17
+ return compiledWhitelist.some(x => new RegExp(x).test(origin));
25
18
  };
26
- var compileWhitelist = function (originWhitelist) {
27
- return __spreadArray(['about:blank'], (originWhitelist || []), true).map(originWhitelistToRegex);
28
- };
29
- var createOnShouldStartLoadWithRequest = function (loadRequest, originWhitelist, onShouldStartLoadWithRequest) {
30
- return function (_a) {
31
- var nativeEvent = _a.nativeEvent;
32
- var shouldStart = true;
33
- var url = nativeEvent.url, lockIdentifier = nativeEvent.lockIdentifier;
34
- if (!passesWhitelist(compileWhitelist(originWhitelist), url)) {
35
- Linking.canOpenURL(url).then(function (supported) {
36
- if (supported) {
19
+ const compileWhitelist = (originWhitelist) => ['about:blank', ...(originWhitelist || [])].map(originWhitelistToRegex);
20
+ const createOnShouldStartLoadWithRequest = (loadRequest, originWhitelist, onShouldStartLoadWithRequest) => {
21
+ return ({ nativeEvent }) => {
22
+ let shouldStart = true;
23
+ const { url, lockIdentifier, isTopFrame } = nativeEvent;
24
+ if (!_passesWhitelist(compileWhitelist(originWhitelist), url)) {
25
+ Linking.canOpenURL(url).then((supported) => {
26
+ if (supported && isTopFrame && /^https:\/\//.test(url)) {
37
27
  return Linking.openURL(url);
38
28
  }
39
- console.warn("Can't open url: ".concat(url));
29
+ console.warn(`Can't open url: ${url}`);
40
30
  return undefined;
41
- })["catch"](function (e) {
31
+ }).catch(e => {
42
32
  console.warn('Error opening URL: ', e);
43
33
  });
44
34
  shouldStart = false;
@@ -49,32 +39,41 @@ var createOnShouldStartLoadWithRequest = function (loadRequest, originWhitelist,
49
39
  loadRequest(shouldStart, url, lockIdentifier);
50
40
  };
51
41
  };
52
- var defaultRenderLoading = function () { return (<View style={styles.loadingOrErrorView}>
42
+ const defaultRenderLoading = () => (<View style={styles.loadingOrErrorView}>
53
43
  <ActivityIndicator />
54
- </View>); };
55
- var defaultRenderError = function (errorDomain, errorCode, errorDesc) { return (<View style={styles.loadingOrErrorView}>
44
+ </View>);
45
+ const defaultRenderError = (errorDomain, errorCode, errorDesc) => (<View style={styles.loadingOrErrorView}>
56
46
  <Text style={styles.errorTextTitle}>Error loading page</Text>
57
- <Text style={styles.errorText}>{"Domain: ".concat(errorDomain)}</Text>
58
- <Text style={styles.errorText}>{"Error Code: ".concat(errorCode)}</Text>
59
- <Text style={styles.errorText}>{"Description: ".concat(errorDesc)}</Text>
60
- </View>); };
47
+ <Text style={styles.errorText}>{`Domain: ${errorDomain}`}</Text>
48
+ <Text style={styles.errorText}>{`Error Code: ${errorCode}`}</Text>
49
+ <Text style={styles.errorText}>{`Description: ${errorDesc}`}</Text>
50
+ </View>);
61
51
  export { defaultOriginWhitelist, createOnShouldStartLoadWithRequest, defaultRenderLoading, defaultRenderError, };
62
- export var useWebWiewLogic = function (_a) {
63
- var startInLoadingState = _a.startInLoadingState, onNavigationStateChange = _a.onNavigationStateChange, onLoadStart = _a.onLoadStart, onLoad = _a.onLoad, onLoadProgress = _a.onLoadProgress, onLoadEnd = _a.onLoadEnd, onError = _a.onError, onHttpErrorProp = _a.onHttpErrorProp, onMessageProp = _a.onMessageProp, onRenderProcessGoneProp = _a.onRenderProcessGoneProp, onContentProcessDidTerminateProp = _a.onContentProcessDidTerminateProp, originWhitelist = _a.originWhitelist, onShouldStartLoadWithRequestProp = _a.onShouldStartLoadWithRequestProp, onShouldStartLoadWithRequestCallback = _a.onShouldStartLoadWithRequestCallback;
64
- var _b = useState(startInLoadingState ? "LOADING" : "IDLE"), viewState = _b[0], setViewState = _b[1];
65
- var _c = useState(null), lastErrorEvent = _c[0], setLastErrorEvent = _c[1];
66
- var startUrl = useRef(null);
67
- var updateNavigationState = useCallback(function (event) {
68
- onNavigationStateChange === null || onNavigationStateChange === void 0 ? void 0 : onNavigationStateChange(event.nativeEvent);
69
- }, [onNavigationStateChange]);
70
- var onLoadingStart = useCallback(function (event) {
52
+ export const useWebWiewLogic = ({ startInLoadingState, onLoadStart, onLoad, onLoadEnd, onError, onMessageProp, originWhitelist, onShouldStartLoadWithRequestProp, onShouldStartLoadWithRequestCallback, validateMeta, validateData, }) => {
53
+ const [viewState, setViewState] = useState(startInLoadingState ? "LOADING" : "IDLE");
54
+ const [lastErrorEvent, setLastErrorEvent] = useState(null);
55
+ const startUrl = useRef(null);
56
+ const passesWhitelist = (url) => {
57
+ if (!url || typeof url !== 'string')
58
+ return false;
59
+ return _passesWhitelist(compileWhitelist(originWhitelist), url);
60
+ };
61
+ const passesWhitelistUse = useCallback(passesWhitelist, [originWhitelist]);
62
+ const extractMeta = (nativeEvent) => ({
63
+ url: String(nativeEvent.url),
64
+ loading: Boolean(nativeEvent.loading),
65
+ title: String(nativeEvent.title),
66
+ canGoBack: Boolean(nativeEvent.canGoBack),
67
+ canGoForward: Boolean(nativeEvent.canGoForward),
68
+ lockIdentifier: Number(nativeEvent.lockIdentifier),
69
+ });
70
+ const onLoadingStart = useCallback((event) => {
71
71
  // Needed for android
72
72
  startUrl.current = event.nativeEvent.url;
73
73
  // !Needed for android
74
74
  onLoadStart === null || onLoadStart === void 0 ? void 0 : onLoadStart(event);
75
- updateNavigationState(event);
76
- }, [onLoadStart, updateNavigationState]);
77
- var onLoadingError = useCallback(function (event) {
75
+ }, [onLoadStart]);
76
+ const onLoadingError = useCallback((event) => {
78
77
  event.persist();
79
78
  if (onError) {
80
79
  onError(event);
@@ -90,55 +89,86 @@ export var useWebWiewLogic = function (_a) {
90
89
  setViewState('ERROR');
91
90
  setLastErrorEvent(event.nativeEvent);
92
91
  }, [onError, onLoadEnd]);
93
- var onHttpError = useCallback(function (event) {
94
- onHttpErrorProp === null || onHttpErrorProp === void 0 ? void 0 : onHttpErrorProp(event);
95
- }, [onHttpErrorProp]);
96
- // Android Only
97
- var onRenderProcessGone = useCallback(function (event) {
98
- onRenderProcessGoneProp === null || onRenderProcessGoneProp === void 0 ? void 0 : onRenderProcessGoneProp(event);
99
- }, [onRenderProcessGoneProp]);
100
- // !Android Only
101
- // iOS Only
102
- var onContentProcessDidTerminate = useCallback(function (event) {
103
- onContentProcessDidTerminateProp === null || onContentProcessDidTerminateProp === void 0 ? void 0 : onContentProcessDidTerminateProp(event);
104
- }, [onContentProcessDidTerminateProp]);
105
- // !iOS Only
106
- var onLoadingFinish = useCallback(function (event) {
92
+ const onLoadingFinish = useCallback((event) => {
107
93
  onLoad === null || onLoad === void 0 ? void 0 : onLoad(event);
108
94
  onLoadEnd === null || onLoadEnd === void 0 ? void 0 : onLoadEnd(event);
109
- var url = event.nativeEvent.url;
95
+ const { nativeEvent: { url } } = event;
96
+ if (!passesWhitelistUse(url))
97
+ return;
110
98
  // on Android, only if url === startUrl
111
99
  if (Platform.OS !== "android" || url === startUrl.current) {
112
100
  setViewState('IDLE');
113
101
  }
114
102
  // !on Android, only if url === startUrl
115
- updateNavigationState(event);
116
- }, [onLoad, onLoadEnd, updateNavigationState]);
117
- var onMessage = useCallback(function (event) {
118
- onMessageProp === null || onMessageProp === void 0 ? void 0 : onMessageProp(event);
119
- }, [onMessageProp]);
120
- var onLoadingProgress = useCallback(function (event) {
121
- var progress = event.nativeEvent.progress;
103
+ // REMOVED: updateNavigationState(event);
104
+ }, [onLoad, onLoadEnd, passesWhitelistUse]);
105
+ const onMessage = useCallback((event) => {
106
+ const { nativeEvent } = event;
107
+ if (!passesWhitelistUse(nativeEvent.url))
108
+ return;
109
+ // TODO: can/should we perform any other validation?
110
+ const data = JSON.stringify(validateData(JSON.parse(nativeEvent.data)));
111
+ const meta = validateMeta(extractMeta(nativeEvent));
112
+ onMessageProp === null || onMessageProp === void 0 ? void 0 : onMessageProp({ ...meta, data });
113
+ }, [onMessageProp, passesWhitelistUse, validateData, validateMeta]);
114
+ const onLoadingProgress = useCallback((event) => {
115
+ const { nativeEvent: { progress } } = event;
116
+ if (!passesWhitelistUse(event.nativeEvent.url))
117
+ return;
122
118
  // patch for Android only
123
119
  if (Platform.OS === "android" && progress === 1) {
124
- setViewState(function (prevViewState) { return prevViewState === 'LOADING' ? 'IDLE' : prevViewState; });
120
+ setViewState(prevViewState => prevViewState === 'LOADING' ? 'IDLE' : prevViewState);
125
121
  }
126
122
  // !patch for Android only
127
- onLoadProgress === null || onLoadProgress === void 0 ? void 0 : onLoadProgress(event);
128
- }, [onLoadProgress]);
129
- var onShouldStartLoadWithRequest = useMemo(function () { return createOnShouldStartLoadWithRequest(onShouldStartLoadWithRequestCallback, originWhitelist, onShouldStartLoadWithRequestProp); }, [originWhitelist, onShouldStartLoadWithRequestProp, onShouldStartLoadWithRequestCallback]);
123
+ // REMOVED: onLoadProgress?.(event);
124
+ }, [passesWhitelistUse]);
125
+ const onShouldStartLoadWithRequest = useMemo(() => createOnShouldStartLoadWithRequest(onShouldStartLoadWithRequestCallback, originWhitelist, onShouldStartLoadWithRequestProp), [originWhitelist, onShouldStartLoadWithRequestProp, onShouldStartLoadWithRequestCallback]);
130
126
  return {
131
- onShouldStartLoadWithRequest: onShouldStartLoadWithRequest,
132
- onLoadingStart: onLoadingStart,
133
- onLoadingProgress: onLoadingProgress,
134
- onLoadingError: onLoadingError,
135
- onLoadingFinish: onLoadingFinish,
136
- onHttpError: onHttpError,
137
- onRenderProcessGone: onRenderProcessGone,
138
- onContentProcessDidTerminate: onContentProcessDidTerminate,
139
- onMessage: onMessage,
140
- viewState: viewState,
141
- setViewState: setViewState,
142
- lastErrorEvent: lastErrorEvent
127
+ onShouldStartLoadWithRequest,
128
+ onLoadingStart,
129
+ onLoadingProgress,
130
+ onLoadingError,
131
+ onLoadingFinish,
132
+ onMessage,
133
+ passesWhitelist,
134
+ viewState,
135
+ setViewState,
136
+ lastErrorEvent,
143
137
  };
144
138
  };
139
+ export const versionPasses = (version, minimum) => {
140
+ if (!version || !minimum)
141
+ return false;
142
+ if (typeof version !== 'string' || typeof minimum !== 'string')
143
+ return false;
144
+ if (minimum.includes(', ')) {
145
+ // We have a set of possible versions
146
+ const variants = minimum.split(', ');
147
+ // Every entry but the last one should be with an upper bound
148
+ if (!variants.slice(0, -1).every(x => x.includes(' <')))
149
+ return false;
150
+ return variants.some(x => versionPasses(version, x)); // Any match passes
151
+ }
152
+ if (minimum.includes(' <')) {
153
+ const [min, max, ...rest] = minimum.split(' <');
154
+ if (rest.length > 0)
155
+ return false;
156
+ // Last check is required for correctness/formatting validation
157
+ return versionPasses(version, min) && !versionPasses(version, max) && versionPasses(max, version);
158
+ }
159
+ const versionRegex = /^[0-9]+(\.[0-9]+)*$/;
160
+ if (!versionRegex.test(version) || !versionRegex.test(minimum))
161
+ return false;
162
+ const versionParts = version.split('.').map(Number);
163
+ const minimumParts = minimum.split('.').map(Number);
164
+ const len = Math.max(versionParts.length, minimumParts.length);
165
+ for (let i = 0; i < len; i += 1) {
166
+ const ver = versionParts[i] || 0;
167
+ const min = minimumParts[i] || 0;
168
+ if (ver > min)
169
+ return true;
170
+ if (ver < min)
171
+ return false;
172
+ }
173
+ return true; // equals
174
+ };