mirror of
https://github.com/status-im/react-native-webview.git
synced 2025-02-21 16:28:33 +00:00
Don't allow camera and mic permissions by default.
Notify user about permission request
This commit is contained in:
parent
4d8a76f369
commit
e2cf5fdc76
2
.gitignore
vendored
2
.gitignore
vendored
@ -53,7 +53,7 @@ android/gradle
|
||||
android/gradlew
|
||||
android/gradlew.bat
|
||||
|
||||
lib/
|
||||
#lib/
|
||||
.classpath
|
||||
.project
|
||||
.settings/
|
||||
|
@ -77,6 +77,7 @@ import com.reactnativecommunity.webview.events.TopLoadingStartEvent;
|
||||
import com.reactnativecommunity.webview.events.TopMessageEvent;
|
||||
import com.reactnativecommunity.webview.events.TopShouldStartLoadWithRequestEvent;
|
||||
import com.reactnativecommunity.webview.events.TopRenderProcessGoneEvent;
|
||||
import com.reactnativecommunity.webview.events.TopPermissionRequestEvent;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
@ -127,6 +128,7 @@ public class RNCWebViewManager extends SimpleViewManager<WebView> {
|
||||
public static final int COMMAND_INJECT_JAVASCRIPT = 6;
|
||||
public static final int COMMAND_LOAD_URL = 7;
|
||||
public static final int COMMAND_FOCUS = 8;
|
||||
public static final int COMMAND_ANSWER_PERMISSION_REQUEST = 9;
|
||||
|
||||
// android commands
|
||||
public static final int COMMAND_CLEAR_FORM_DATA = 1000;
|
||||
@ -604,6 +606,7 @@ public class RNCWebViewManager extends SimpleViewManager<WebView> {
|
||||
export.put(TopShouldStartLoadWithRequestEvent.EVENT_NAME, MapBuilder.of("registrationName", "onShouldStartLoadWithRequest"));
|
||||
export.put(ScrollEventType.getJSEventName(ScrollEventType.SCROLL), MapBuilder.of("registrationName", "onScroll"));
|
||||
export.put(TopHttpErrorEvent.EVENT_NAME, MapBuilder.of("registrationName", "onHttpError"));
|
||||
export.put(TopPermissionRequestEvent.EVENT_NAME, MapBuilder.of("registrationName", "onPermissionRequest"));
|
||||
export.put(TopRenderProcessGoneEvent.EVENT_NAME, MapBuilder.of("registrationName", "onRenderProcessGone"));
|
||||
return export;
|
||||
}
|
||||
@ -618,6 +621,7 @@ public class RNCWebViewManager extends SimpleViewManager<WebView> {
|
||||
.put("stopLoading", COMMAND_STOP_LOADING)
|
||||
.put("postMessage", COMMAND_POST_MESSAGE)
|
||||
.put("injectJavaScript", COMMAND_INJECT_JAVASCRIPT)
|
||||
.put("answerPermissionRequest", COMMAND_ANSWER_PERMISSION_REQUEST)
|
||||
.put("loadUrl", COMMAND_LOAD_URL)
|
||||
.put("requestFocus", COMMAND_FOCUS)
|
||||
.put("clearFormData", COMMAND_CLEAR_FORM_DATA)
|
||||
@ -665,6 +669,23 @@ public class RNCWebViewManager extends SimpleViewManager<WebView> {
|
||||
RNCWebView reactWebView = (RNCWebView) root;
|
||||
reactWebView.evaluateJavascriptWithFallback(args.getString(0));
|
||||
break;
|
||||
case COMMAND_ANSWER_PERMISSION_REQUEST:
|
||||
if (args == null || args.size() < 1) {
|
||||
throw new RuntimeException("Arguments for answerPermissionRequest are null!");
|
||||
}
|
||||
|
||||
boolean answer = args.getBoolean(0);
|
||||
ArrayList<String> resources = new ArrayList<String>();
|
||||
for(int i=1; i<args.size(); ++i) {
|
||||
resources.add(args.getString(i));
|
||||
}
|
||||
|
||||
RNCWebChromeClient client = (RNCWebChromeClient) root.getWebChromeClient();
|
||||
if(null != client) {
|
||||
client.answerPermissionRequest(answer, resources.toArray(new String[resources.size()]));
|
||||
}
|
||||
|
||||
break;
|
||||
case COMMAND_LOAD_URL:
|
||||
if (args == null) {
|
||||
throw new RuntimeException("Arguments for loading an url are null!");
|
||||
@ -1050,6 +1071,12 @@ public class RNCWebViewManager extends SimpleViewManager<WebView> {
|
||||
protected View mVideoView;
|
||||
protected WebChromeClient.CustomViewCallback mCustomViewCallback;
|
||||
|
||||
/**
|
||||
* This field stores the PermissionRequest from the web application until it is allowed
|
||||
* or denied by user.
|
||||
*/
|
||||
private PermissionRequest mPermissionRequest;
|
||||
|
||||
protected RNCWebView.ProgressChangedFilter progressChangedFilter = null;
|
||||
|
||||
public RNCWebChromeClient(ReactContext reactContext, WebView webView) {
|
||||
@ -1065,41 +1092,47 @@ public class RNCWebViewManager extends SimpleViewManager<WebView> {
|
||||
// Ignore console logs in non debug builds.
|
||||
return true;
|
||||
}
|
||||
|
||||
public void answerPermissionRequest(boolean allowed, String[] resources) {
|
||||
if(null == mPermissionRequest )
|
||||
return;
|
||||
|
||||
if (allowed) {
|
||||
mPermissionRequest.grant(resources);
|
||||
} else {
|
||||
mPermissionRequest.deny();
|
||||
}
|
||||
mPermissionRequest = null;
|
||||
}
|
||||
|
||||
// This method is called when the permission request is canceled by the web content.
|
||||
@Override
|
||||
public void onPermissionRequestCanceled(PermissionRequest request) {
|
||||
// We dismiss the prompt UI here as the request is no longer valid.
|
||||
mPermissionRequest = null;
|
||||
}
|
||||
|
||||
// Fix WebRTC permission request error.
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
@Override
|
||||
public void onPermissionRequest(final PermissionRequest request) {
|
||||
|
||||
mPermissionRequest = request;
|
||||
String[] requestedResources = request.getResources();
|
||||
ArrayList<String> permissions = new ArrayList<>();
|
||||
ArrayList<String> grantedPermissions = new ArrayList<String>();
|
||||
|
||||
WebView wv = (WebView) mWebView;
|
||||
WritableMap event = Arguments.createMap();
|
||||
WritableNativeArray params = new WritableNativeArray();
|
||||
for (int i = 0; i < requestedResources.length; i++) {
|
||||
if (requestedResources[i].equals(PermissionRequest.RESOURCE_AUDIO_CAPTURE)) {
|
||||
permissions.add(Manifest.permission.RECORD_AUDIO);
|
||||
} else if (requestedResources[i].equals(PermissionRequest.RESOURCE_VIDEO_CAPTURE)) {
|
||||
permissions.add(Manifest.permission.CAMERA);
|
||||
}
|
||||
// TODO: RESOURCE_MIDI_SYSEX, RESOURCE_PROTECTED_MEDIA_ID.
|
||||
params.pushString(requestedResources[i]);
|
||||
}
|
||||
event.putArray("resources", params);
|
||||
|
||||
for (int i = 0; i < permissions.size(); i++) {
|
||||
if (ContextCompat.checkSelfPermission(mReactContext, permissions.get(i)) != PackageManager.PERMISSION_GRANTED) {
|
||||
continue;
|
||||
}
|
||||
if (permissions.get(i).equals(Manifest.permission.RECORD_AUDIO)) {
|
||||
grantedPermissions.add(PermissionRequest.RESOURCE_AUDIO_CAPTURE);
|
||||
} else if (permissions.get(i).equals(Manifest.permission.CAMERA)) {
|
||||
grantedPermissions.add(PermissionRequest.RESOURCE_VIDEO_CAPTURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (grantedPermissions.isEmpty()) {
|
||||
request.deny();
|
||||
} else {
|
||||
String[] grantedPermissionsArray = new String[grantedPermissions.size()];
|
||||
grantedPermissionsArray = grantedPermissions.toArray(grantedPermissionsArray);
|
||||
request.grant(grantedPermissionsArray);
|
||||
}
|
||||
dispatchEvent(
|
||||
wv,
|
||||
new TopPermissionRequestEvent(
|
||||
wv.getId(),
|
||||
event));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -0,0 +1,24 @@
|
||||
package com.reactnativecommunity.webview.events
|
||||
|
||||
import com.facebook.react.bridge.WritableMap
|
||||
import com.facebook.react.uimanager.events.Event
|
||||
import com.facebook.react.uimanager.events.RCTEventEmitter
|
||||
|
||||
/**
|
||||
* Event emitted when there is an error in loading.
|
||||
*/
|
||||
class TopPermissionRequestEvent(viewId: Int, private val mEventData: WritableMap) : Event<TopPermissionRequestEvent>(viewId) {
|
||||
companion object {
|
||||
const val EVENT_NAME = "topPermissionRequest"
|
||||
}
|
||||
|
||||
override fun getEventName(): String = EVENT_NAME
|
||||
|
||||
override fun canCoalesce(): Boolean = false
|
||||
|
||||
override fun getCoalescingKey(): Short = 0
|
||||
|
||||
override fun dispatch(rctEventEmitter: RCTEventEmitter) {
|
||||
rctEventEmitter.receiveEvent(viewTag, EVENT_NAME, mEventData)
|
||||
}
|
||||
}
|
@ -10,6 +10,7 @@ import {
|
||||
Platform,
|
||||
} from 'react-native';
|
||||
|
||||
import Permission from './examples/Permission';
|
||||
import Alerts from './examples/Alerts';
|
||||
import Scrolling from './examples/Scrolling';
|
||||
import Background from './examples/Background';
|
||||
@ -19,6 +20,14 @@ import Injection from './examples/Injection';
|
||||
import LocalPageLoad from './examples/LocalPageLoad';
|
||||
|
||||
const TESTS = {
|
||||
Permission: {
|
||||
title: 'Permission',
|
||||
testId: 'permission',
|
||||
description: 'Permission tests',
|
||||
render() {
|
||||
return <Permission />;
|
||||
},
|
||||
},
|
||||
Alerts: {
|
||||
title: 'Alerts',
|
||||
testId: 'alerts',
|
||||
@ -113,6 +122,11 @@ export default class App extends Component<Props, State> {
|
||||
</TouchableOpacity>
|
||||
|
||||
<View style={styles.testPickerContainer}>
|
||||
<Button
|
||||
testID="testType_permission"
|
||||
title="Permission"
|
||||
onPress={() => this._changeTest('Permission')}
|
||||
/>
|
||||
<Button
|
||||
testID="testType_alerts"
|
||||
title="Alerts"
|
||||
|
27
example/examples/Permission.tsx
Normal file
27
example/examples/Permission.tsx
Normal file
@ -0,0 +1,27 @@
|
||||
import React, {Component} from 'react';
|
||||
import {Text, View} from 'react-native';
|
||||
|
||||
import WebView from 'react-native-webview';
|
||||
|
||||
type Props = {};
|
||||
type State = {};
|
||||
|
||||
export default class Permission extends Component<Props, State> {
|
||||
state = {};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View style={{ height: 120 }}>
|
||||
<WebView
|
||||
ref={(ref) => (this.webview = ref)}
|
||||
onPermissionRequest={(event) => {
|
||||
console.log("!!! JS: onPermissionRequest, event: ", event.nativeEvent);
|
||||
this.webview.answerPermissionRequest(false, event.nativeEvent.resources );
|
||||
}}
|
||||
source={{uri: 'https://fatal0.netlify.app/android/webviewvideo.html'}}
|
||||
automaticallyAdjustContentInsets={false}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
80
lib/WebView.android.d.ts
vendored
Normal file
80
lib/WebView.android.d.ts
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
import React from 'react';
|
||||
import { createOnShouldStartLoadWithRequest } from './WebViewShared';
|
||||
import { WebViewRenderProcessGoneEvent, WebViewErrorEvent, WebViewHttpErrorEvent, WebViewMessageEvent, WebViewNavigationEvent, WebViewProgressEvent, WebViewPermissionEvent, AndroidWebViewProps, NativeWebViewAndroid, State } from './WebViewTypes';
|
||||
/**
|
||||
* Renders a native WebView.
|
||||
*/
|
||||
declare class WebView extends React.Component<AndroidWebViewProps, State> {
|
||||
static defaultProps: {
|
||||
overScrollMode: string;
|
||||
javaScriptEnabled: boolean;
|
||||
thirdPartyCookiesEnabled: boolean;
|
||||
scalesPageToFit: boolean;
|
||||
allowsFullscreenVideo: boolean;
|
||||
allowFileAccess: boolean;
|
||||
saveFormDataDisabled: boolean;
|
||||
cacheEnabled: boolean;
|
||||
androidHardwareAccelerationDisabled: boolean;
|
||||
androidLayerType: string;
|
||||
originWhitelist: string[];
|
||||
};
|
||||
static isFileUploadSupported: () => Promise<any>;
|
||||
startUrl: string | null;
|
||||
state: State;
|
||||
onShouldStartLoadWithRequest: ReturnType<typeof createOnShouldStartLoadWithRequest> | null;
|
||||
webViewRef: React.RefObject<NativeWebViewAndroid>;
|
||||
messagingModuleName: string;
|
||||
componentDidMount: () => void;
|
||||
getCommands: () => {
|
||||
goForward: number;
|
||||
goBack: number;
|
||||
reload: number;
|
||||
stopLoading: number;
|
||||
postMessage: number;
|
||||
injectJavaScript: number;
|
||||
loadUrl: number;
|
||||
requestFocus: number;
|
||||
clearHistory: number;
|
||||
clearCache: number;
|
||||
clearFormData: number;
|
||||
answerPermissionRequest: number;
|
||||
};
|
||||
goForward: () => void;
|
||||
goBack: () => void;
|
||||
reload: () => void;
|
||||
stopLoading: () => void;
|
||||
requestFocus: () => void;
|
||||
postMessage: (data: string) => void;
|
||||
clearFormData: () => void;
|
||||
clearCache: (includeDiskFiles: boolean) => void;
|
||||
clearHistory: () => void;
|
||||
/**
|
||||
* Injects a javascript string into the referenced WebView. Deliberately does not
|
||||
* return a response because using eval() to return a response breaks this method
|
||||
* on pages with a Content Security Policy that disallows eval(). If you need that
|
||||
* functionality, look into postMessage/onMessage.
|
||||
*/
|
||||
injectJavaScript: (data: string) => void;
|
||||
answerPermissionRequest: (allow: boolean, resources: string[]) => void;
|
||||
/**
|
||||
* We return an event with a bunch of fields including:
|
||||
* url, title, loading, canGoBack, canGoForward
|
||||
*/
|
||||
updateNavigationState: (event: WebViewNavigationEvent) => void;
|
||||
/**
|
||||
* Returns the native `WebView` node.
|
||||
*/
|
||||
getWebViewHandle: () => number;
|
||||
onLoadingStart: (event: WebViewNavigationEvent) => void;
|
||||
onLoadingError: (event: WebViewErrorEvent) => void;
|
||||
onHttpError: (event: WebViewHttpErrorEvent) => void;
|
||||
onRenderProcessGone: (event: WebViewRenderProcessGoneEvent) => void;
|
||||
onLoadingFinish: (event: WebViewNavigationEvent) => void;
|
||||
onMessage: (event: WebViewMessageEvent) => void;
|
||||
onPermissionRequest: (event: WebViewPermissionEvent) => void;
|
||||
onLoadingProgress: (event: WebViewProgressEvent) => void;
|
||||
onShouldStartLoadWithRequestCallback: (shouldStart: boolean, url: string, lockIdentifier?: number | undefined) => void;
|
||||
render(): JSX.Element;
|
||||
}
|
||||
export default WebView;
|
||||
//# sourceMappingURL=WebView.android.d.ts.map
|
1
lib/WebView.android.d.ts.map
Normal file
1
lib/WebView.android.d.ts.map
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"WebView.android.d.ts","sourceRoot":"","sources":["../src/WebView.android.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAgB1B,OAAO,EAEL,kCAAkC,EAGnC,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,6BAA6B,EAC7B,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,EACnB,sBAAsB,EACtB,oBAAoB,EACpB,sBAAsB,EACtB,mBAAmB,EACnB,oBAAoB,EACpB,KAAK,EAEN,MAAM,gBAAgB,CAAC;AAgBxB;;GAEG;AACH,cAAM,OAAQ,SAAQ,KAAK,CAAC,SAAS,CAAC,mBAAmB,EAAE,KAAK,CAAC;IAC/D,MAAM,CAAC,YAAY;;;;;;;;;;;;MAYjB;IAEF,MAAM,CAAC,qBAAqB,qBAG1B;IAEF,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE/B,KAAK,EAAE,KAAK,CAGV;IAEF,4BAA4B,EAAE,UAAU,CAAC,OAAO,kCAAkC,CAAC,GAAG,IAAI,CAAQ;IAElG,UAAU,wCAA2C;IAErD,mBAAmB,SAA0C;IAE7D,iBAAiB,aAEf;IAEF,WAAW;;;;;;;;;;;;;MAA+D;IAE1E,SAAS,aAMP;IAEF,MAAM,aAMJ;IAEF,MAAM,aASJ;IAEF,WAAW,aAMT;IAEF,YAAY,aAMV;IAEF,WAAW,yBAMT;IAEF,aAAa,aAMZ;IAED,UAAU,sCAMR;IAEF,YAAY,aAMV;IAEF;;;;;OAKG;IACH,gBAAgB,yBAMd;IAEF,uBAAuB,gDAMtB;IAED;;;OAGG;IACH,qBAAqB,0CAInB;IAEF;;OAEG;IACH,gBAAgB,eAId;IAEF,cAAc,0CAQZ;IAEF,cAAc,qCAeZ;IAEF,WAAW,yCAKV;IAED,mBAAmB,iDAKlB;IAED,eAAe,0CAeb;IAEF,SAAS,uCAKP;IAEF,mBAAmB,0CAKlB;IAED,iBAAiB,wCAcf;IAEF,oCAAoC,mFAclC;IAEF,MAAM;CAoFP;AAED,eAAe,OAAO,CAAC"}
|
305
lib/WebView.android.js
Normal file
305
lib/WebView.android.js
Normal file
@ -0,0 +1,305 @@
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
while (_) try {
|
||||
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;
|
||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||
switch (op[0]) {
|
||||
case 0: case 1: t = op; break;
|
||||
case 4: _.label++; return { value: op[1], done: false };
|
||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||
default:
|
||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||
if (t[2]) _.ops.pop();
|
||||
_.trys.pop(); continue;
|
||||
}
|
||||
op = body.call(thisArg, _);
|
||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||
}
|
||||
};
|
||||
var __rest = (this && this.__rest) || function (s, e) {
|
||||
var t = {};
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
||||
t[p] = s[p];
|
||||
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
||||
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
||||
t[p[i]] = s[p[i]];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
var __spreadArrays = (this && this.__spreadArrays) || function () {
|
||||
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
|
||||
for (var r = Array(s), k = 0, i = 0; i < il; i++)
|
||||
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
|
||||
r[k] = a[j];
|
||||
return r;
|
||||
};
|
||||
import React from 'react';
|
||||
import { Image, requireNativeComponent, UIManager as NotTypedUIManager, View, NativeModules, findNodeHandle, } from 'react-native';
|
||||
import BatchedBridge from 'react-native/Libraries/BatchedBridge/BatchedBridge';
|
||||
import invariant from 'invariant';
|
||||
import { defaultOriginWhitelist, createOnShouldStartLoadWithRequest, defaultRenderError, defaultRenderLoading, } from './WebViewShared';
|
||||
import styles from './WebView.styles';
|
||||
var UIManager = NotTypedUIManager;
|
||||
var RNCWebView = requireNativeComponent('RNCWebView');
|
||||
var resolveAssetSource = Image.resolveAssetSource;
|
||||
/**
|
||||
* A simple counter to uniquely identify WebView instances. Do not use this for anything else.
|
||||
*/
|
||||
var uniqueRef = 0;
|
||||
/**
|
||||
* Renders a native WebView.
|
||||
*/
|
||||
var WebView = /** @class */ (function (_super) {
|
||||
__extends(WebView, _super);
|
||||
function WebView() {
|
||||
var _this = _super !== null && _super.apply(this, arguments) || this;
|
||||
_this.startUrl = null;
|
||||
_this.state = {
|
||||
viewState: _this.props.startInLoadingState ? 'LOADING' : 'IDLE',
|
||||
lastErrorEvent: null
|
||||
};
|
||||
_this.onShouldStartLoadWithRequest = null;
|
||||
_this.webViewRef = React.createRef();
|
||||
_this.messagingModuleName = "WebViewMessageHandler" + (uniqueRef += 1);
|
||||
_this.componentDidMount = function () {
|
||||
BatchedBridge.registerCallableModule(_this.messagingModuleName, _this);
|
||||
};
|
||||
_this.getCommands = function () { return UIManager.getViewManagerConfig('RNCWebView').Commands; };
|
||||
_this.goForward = function () {
|
||||
UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().goForward, undefined);
|
||||
};
|
||||
_this.goBack = function () {
|
||||
UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().goBack, undefined);
|
||||
};
|
||||
_this.reload = function () {
|
||||
_this.setState({
|
||||
viewState: 'LOADING'
|
||||
});
|
||||
UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().reload, undefined);
|
||||
};
|
||||
_this.stopLoading = function () {
|
||||
UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().stopLoading, undefined);
|
||||
};
|
||||
_this.requestFocus = function () {
|
||||
UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().requestFocus, undefined);
|
||||
};
|
||||
_this.postMessage = function (data) {
|
||||
UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().postMessage, [String(data)]);
|
||||
};
|
||||
_this.clearFormData = function () {
|
||||
UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().clearFormData, undefined);
|
||||
};
|
||||
_this.clearCache = function (includeDiskFiles) {
|
||||
UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().clearCache, [includeDiskFiles]);
|
||||
};
|
||||
_this.clearHistory = function () {
|
||||
UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().clearHistory, undefined);
|
||||
};
|
||||
/**
|
||||
* Injects a javascript string into the referenced WebView. Deliberately does not
|
||||
* return a response because using eval() to return a response breaks this method
|
||||
* on pages with a Content Security Policy that disallows eval(). If you need that
|
||||
* functionality, look into postMessage/onMessage.
|
||||
*/
|
||||
_this.injectJavaScript = function (data) {
|
||||
UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().injectJavaScript, [data]);
|
||||
};
|
||||
_this.answerPermissionRequest = function (allow, resources) {
|
||||
UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().answerPermissionRequest, __spreadArrays([allow], (resources || [])));
|
||||
};
|
||||
/**
|
||||
* We return an event with a bunch of fields including:
|
||||
* url, title, loading, canGoBack, canGoForward
|
||||
*/
|
||||
_this.updateNavigationState = function (event) {
|
||||
if (_this.props.onNavigationStateChange) {
|
||||
_this.props.onNavigationStateChange(event.nativeEvent);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Returns the native `WebView` node.
|
||||
*/
|
||||
_this.getWebViewHandle = function () {
|
||||
var nodeHandle = findNodeHandle(_this.webViewRef.current);
|
||||
invariant(nodeHandle != null, 'nodeHandle expected to be non-null');
|
||||
return nodeHandle;
|
||||
};
|
||||
_this.onLoadingStart = function (event) {
|
||||
var onLoadStart = _this.props.onLoadStart;
|
||||
var url = event.nativeEvent.url;
|
||||
_this.startUrl = url;
|
||||
if (onLoadStart) {
|
||||
onLoadStart(event);
|
||||
}
|
||||
_this.updateNavigationState(event);
|
||||
};
|
||||
_this.onLoadingError = function (event) {
|
||||
event.persist(); // persist this event because we need to store it
|
||||
var _a = _this.props, onError = _a.onError, onLoadEnd = _a.onLoadEnd;
|
||||
if (onError) {
|
||||
onError(event);
|
||||
}
|
||||
if (onLoadEnd) {
|
||||
onLoadEnd(event);
|
||||
}
|
||||
console.warn('Encountered an error loading page', event.nativeEvent);
|
||||
_this.setState({
|
||||
lastErrorEvent: event.nativeEvent,
|
||||
viewState: 'ERROR'
|
||||
});
|
||||
};
|
||||
_this.onHttpError = function (event) {
|
||||
var onHttpError = _this.props.onHttpError;
|
||||
if (onHttpError) {
|
||||
onHttpError(event);
|
||||
}
|
||||
};
|
||||
_this.onRenderProcessGone = function (event) {
|
||||
var onRenderProcessGone = _this.props.onRenderProcessGone;
|
||||
if (onRenderProcessGone) {
|
||||
onRenderProcessGone(event);
|
||||
}
|
||||
};
|
||||
_this.onLoadingFinish = function (event) {
|
||||
var _a = _this.props, onLoad = _a.onLoad, onLoadEnd = _a.onLoadEnd;
|
||||
var url = event.nativeEvent.url;
|
||||
if (onLoad) {
|
||||
onLoad(event);
|
||||
}
|
||||
if (onLoadEnd) {
|
||||
onLoadEnd(event);
|
||||
}
|
||||
if (url === _this.startUrl) {
|
||||
_this.setState({
|
||||
viewState: 'IDLE'
|
||||
});
|
||||
}
|
||||
_this.updateNavigationState(event);
|
||||
};
|
||||
_this.onMessage = function (event) {
|
||||
var onMessage = _this.props.onMessage;
|
||||
if (onMessage) {
|
||||
onMessage(event);
|
||||
}
|
||||
};
|
||||
_this.onPermissionRequest = function (event) {
|
||||
var onPermissionRequest = _this.props.onPermissionRequest;
|
||||
if (onPermissionRequest) {
|
||||
onPermissionRequest(event);
|
||||
}
|
||||
};
|
||||
_this.onLoadingProgress = function (event) {
|
||||
var onLoadProgress = _this.props.onLoadProgress;
|
||||
var progress = event.nativeEvent.progress;
|
||||
if (progress === 1) {
|
||||
_this.setState(function (state) {
|
||||
if (state.viewState === 'LOADING') {
|
||||
return { viewState: 'IDLE' };
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
if (onLoadProgress) {
|
||||
onLoadProgress(event);
|
||||
}
|
||||
};
|
||||
_this.onShouldStartLoadWithRequestCallback = function (shouldStart, url, lockIdentifier) {
|
||||
if (lockIdentifier) {
|
||||
NativeModules.RNCWebView.onShouldStartLoadWithRequestCallback(shouldStart, lockIdentifier);
|
||||
}
|
||||
else if (shouldStart) {
|
||||
UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().loadUrl, [String(url)]);
|
||||
}
|
||||
};
|
||||
return _this;
|
||||
}
|
||||
WebView.prototype.render = function () {
|
||||
var _a = this.props, onMessage = _a.onMessage, onShouldStartLoadWithRequestProp = _a.onShouldStartLoadWithRequest, originWhitelist = _a.originWhitelist, renderError = _a.renderError, renderLoading = _a.renderLoading, source = _a.source, style = _a.style, containerStyle = _a.containerStyle, _b = _a.nativeConfig, nativeConfig = _b === void 0 ? {} : _b, otherProps = __rest(_a, ["onMessage", "onShouldStartLoadWithRequest", "originWhitelist", "renderError", "renderLoading", "source", "style", "containerStyle", "nativeConfig"]);
|
||||
var otherView = null;
|
||||
if (this.state.viewState === 'LOADING') {
|
||||
otherView = (renderLoading || defaultRenderLoading)();
|
||||
}
|
||||
else if (this.state.viewState === 'ERROR') {
|
||||
var errorEvent = this.state.lastErrorEvent;
|
||||
invariant(errorEvent != null, 'lastErrorEvent expected to be non-null');
|
||||
otherView = (renderError || defaultRenderError)(errorEvent.domain, errorEvent.code, errorEvent.description);
|
||||
}
|
||||
else if (this.state.viewState !== 'IDLE') {
|
||||
console.error("RNCWebView invalid state encountered: " + this.state.viewState);
|
||||
}
|
||||
var webViewStyles = [styles.container, styles.webView, style];
|
||||
var webViewContainerStyle = [styles.container, containerStyle];
|
||||
if (typeof source !== "number" && source && 'method' in source) {
|
||||
if (source.method === 'POST' && source.headers) {
|
||||
console.warn('WebView: `source.headers` is not supported when using POST.');
|
||||
}
|
||||
else if (source.method === 'GET' && source.body) {
|
||||
console.warn('WebView: `source.body` is not supported when using GET.');
|
||||
}
|
||||
}
|
||||
var NativeWebView = nativeConfig.component || RNCWebView;
|
||||
this.onShouldStartLoadWithRequest = createOnShouldStartLoadWithRequest(this.onShouldStartLoadWithRequestCallback,
|
||||
// casting cause it's in the default props
|
||||
originWhitelist, onShouldStartLoadWithRequestProp);
|
||||
var webView = (<NativeWebView key="webViewKey" {...otherProps} messagingEnabled={typeof onMessage === 'function'} messagingModuleName={this.messagingModuleName} onLoadingError={this.onLoadingError} onLoadingFinish={this.onLoadingFinish} onLoadingProgress={this.onLoadingProgress} onLoadingStart={this.onLoadingStart} onHttpError={this.onHttpError} onRenderProcessGone={this.onRenderProcessGone} onMessage={this.onMessage} onShouldStartLoadWithRequest={this.onShouldStartLoadWithRequest} ref={this.webViewRef}
|
||||
// TODO: find a better way to type this.
|
||||
source={resolveAssetSource(source)} style={webViewStyles} {...nativeConfig.props}/>);
|
||||
return (<View style={webViewContainerStyle}>
|
||||
{webView}
|
||||
{otherView}
|
||||
</View>);
|
||||
};
|
||||
WebView.defaultProps = {
|
||||
overScrollMode: 'always',
|
||||
javaScriptEnabled: true,
|
||||
thirdPartyCookiesEnabled: true,
|
||||
scalesPageToFit: true,
|
||||
allowsFullscreenVideo: false,
|
||||
allowFileAccess: false,
|
||||
saveFormDataDisabled: false,
|
||||
cacheEnabled: true,
|
||||
androidHardwareAccelerationDisabled: false,
|
||||
androidLayerType: 'none',
|
||||
originWhitelist: defaultOriginWhitelist
|
||||
};
|
||||
WebView.isFileUploadSupported = function () { return __awaiter(void 0, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
// native implementation should return "true" only for Android 5+
|
||||
return [2 /*return*/, NativeModules.RNCWebView.isFileUploadSupported()];
|
||||
});
|
||||
}); };
|
||||
return WebView;
|
||||
}(React.Component));
|
||||
export default WebView;
|
7
lib/WebView.d.ts
vendored
Normal file
7
lib/WebView.d.ts
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
import React from 'react';
|
||||
import { IOSWebViewProps, AndroidWebViewProps } from './WebViewTypes';
|
||||
export declare type WebViewProps = IOSWebViewProps & AndroidWebViewProps;
|
||||
declare const WebView: React.FunctionComponent<WebViewProps>;
|
||||
export { WebView };
|
||||
export default WebView;
|
||||
//# sourceMappingURL=WebView.d.ts.map
|
1
lib/WebView.d.ts.map
Normal file
1
lib/WebView.d.ts.map
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"WebView.d.ts","sourceRoot":"","sources":["../src/WebView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAEtE,oBAAY,YAAY,GAAG,eAAe,GAAG,mBAAmB,CAAC;AAMjE,QAAA,MAAM,OAAO,EAAE,KAAK,CAAC,iBAAiB,CAAC,YAAY,CAMlD,CAAC;AAEF,OAAO,EAAE,OAAO,EAAE,CAAC;AACnB,eAAe,OAAO,CAAC"}
|
83
lib/WebView.ios.d.ts
vendored
Normal file
83
lib/WebView.ios.d.ts
vendored
Normal file
@ -0,0 +1,83 @@
|
||||
import React from 'react';
|
||||
import { WebViewErrorEvent, WebViewHttpErrorEvent, WebViewMessageEvent, WebViewNavigationEvent, WebViewProgressEvent, WebViewTerminatedEvent, IOSWebViewProps, NativeWebViewIOS, State } from './WebViewTypes';
|
||||
declare class WebView extends React.Component<IOSWebViewProps, State> {
|
||||
static defaultProps: {
|
||||
javaScriptEnabled: boolean;
|
||||
cacheEnabled: boolean;
|
||||
originWhitelist: string[];
|
||||
useSharedProcessPool: boolean;
|
||||
};
|
||||
static isFileUploadSupported: () => Promise<boolean>;
|
||||
state: State;
|
||||
webViewRef: React.RefObject<NativeWebViewIOS>;
|
||||
getCommands: () => {
|
||||
goForward: number;
|
||||
goBack: number;
|
||||
reload: number;
|
||||
stopLoading: number;
|
||||
postMessage: number;
|
||||
injectJavaScript: number;
|
||||
loadUrl: number;
|
||||
requestFocus: number;
|
||||
};
|
||||
/**
|
||||
* Go forward one page in the web view's history.
|
||||
*/
|
||||
goForward: () => void;
|
||||
/**
|
||||
* Go back one page in the web view's history.
|
||||
*/
|
||||
goBack: () => void;
|
||||
/**
|
||||
* Reloads the current page.
|
||||
*/
|
||||
reload: () => void;
|
||||
/**
|
||||
* Stop loading the current page.
|
||||
*/
|
||||
stopLoading: () => void;
|
||||
/**
|
||||
* Request focus on WebView rendered page.
|
||||
*/
|
||||
requestFocus: () => void;
|
||||
/**
|
||||
* Posts a message to the web view, which will emit a `message` event.
|
||||
* Accepts one argument, `data`, which must be a string.
|
||||
*
|
||||
* In your webview, you'll need to something like the following.
|
||||
*
|
||||
* ```js
|
||||
* document.addEventListener('message', e => { document.title = e.data; });
|
||||
* ```
|
||||
*/
|
||||
postMessage: (data: string) => void;
|
||||
/**
|
||||
* Injects a javascript string into the referenced WebView. Deliberately does not
|
||||
* return a response because using eval() to return a response breaks this method
|
||||
* on pages with a Content Security Policy that disallows eval(). If you need that
|
||||
* functionality, look into postMessage/onMessage.
|
||||
*/
|
||||
injectJavaScript: (data: string) => void;
|
||||
/**
|
||||
* We return an event with a bunch of fields including:
|
||||
* url, title, loading, canGoBack, canGoForward
|
||||
*/
|
||||
updateNavigationState: (event: WebViewNavigationEvent) => void;
|
||||
/**
|
||||
* Returns the native `WebView` node.
|
||||
*/
|
||||
getWebViewHandle: () => number;
|
||||
onLoadingStart: (event: WebViewNavigationEvent) => void;
|
||||
onLoadingError: (event: WebViewErrorEvent) => void;
|
||||
onHttpError: (event: WebViewHttpErrorEvent) => void;
|
||||
onLoadingFinish: (event: WebViewNavigationEvent) => void;
|
||||
onMessage: (event: WebViewMessageEvent) => void;
|
||||
onLoadingProgress: (event: WebViewProgressEvent) => void;
|
||||
onShouldStartLoadWithRequestCallback: (shouldStart: boolean, _url: string, lockIdentifier: number) => void;
|
||||
onContentProcessDidTerminate: (event: WebViewTerminatedEvent) => void;
|
||||
componentDidUpdate(prevProps: IOSWebViewProps): void;
|
||||
showRedboxOnPropChanges(prevProps: IOSWebViewProps, propName: keyof IOSWebViewProps): void;
|
||||
render(): JSX.Element;
|
||||
}
|
||||
export default WebView;
|
||||
//# sourceMappingURL=WebView.ios.d.ts.map
|
1
lib/WebView.ios.d.ts.map
Normal file
1
lib/WebView.ios.d.ts.map
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"WebView.ios.d.ts","sourceRoot":"","sources":["../src/WebView.ios.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAkB1B,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,EACnB,sBAAsB,EACtB,oBAAoB,EACpB,sBAAsB,EACtB,eAAe,EAEf,gBAAgB,EAEhB,KAAK,EAEN,MAAM,gBAAgB,CAAC;AAyBxB,cAAM,OAAQ,SAAQ,KAAK,CAAC,SAAS,CAAC,eAAe,EAAE,KAAK,CAAC;IAC3D,MAAM,CAAC,YAAY;;;;;MAKjB;IAEF,MAAM,CAAC,qBAAqB,yBAG1B;IAEF,KAAK,EAAE,KAAK,CAGV;IAEF,UAAU,oCAAuC;IAGjD,WAAW;;;;;;;;;MAA+D;IAE1E;;OAEG;IACH,SAAS,aAMP;IAEF;;OAEG;IACH,MAAM,aAMJ;IAEF;;OAEG;IACH,MAAM,aAOJ;IAEF;;OAEG;IACH,WAAW,aAMT;IAEF;;OAEG;IACH,YAAY,aAMV;IAEF;;;;;;;;;OASG;IACH,WAAW,yBAMT;IAEF;;;;;OAKG;IACH,gBAAgB,yBAMd;IAEF;;;OAGG;IACH,qBAAqB,0CAInB;IAEF;;OAEG;IACH,gBAAgB,eAId;IAEF,cAAc,0CAMZ;IAEF,cAAc,qCAeZ;IAEF,WAAW,yCAKV;IAED,eAAe,0CAYb;IAEF,SAAS,uCAKP;IAEF,iBAAiB,wCAKf;IAEF,oCAAoC,uEAUlC;IAEF,4BAA4B,0CAK1B;IAEF,kBAAkB,CAAC,SAAS,EAAE,eAAe;IAO7C,uBAAuB,CACrB,SAAS,EAAE,eAAe,EAC1B,QAAQ,EAAE,MAAM,eAAe;IASjC,MAAM;CAqFP;AAED,eAAe,OAAO,CAAC"}
|
282
lib/WebView.ios.js
Normal file
282
lib/WebView.ios.js
Normal file
@ -0,0 +1,282 @@
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
while (_) try {
|
||||
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;
|
||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||
switch (op[0]) {
|
||||
case 0: case 1: t = op; break;
|
||||
case 4: _.label++; return { value: op[1], done: false };
|
||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||
default:
|
||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||
if (t[2]) _.ops.pop();
|
||||
_.trys.pop(); continue;
|
||||
}
|
||||
op = body.call(thisArg, _);
|
||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||
}
|
||||
};
|
||||
var __rest = (this && this.__rest) || function (s, e) {
|
||||
var t = {};
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
||||
t[p] = s[p];
|
||||
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
||||
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
||||
t[p[i]] = s[p[i]];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
import React from 'react';
|
||||
import { UIManager as NotTypedUIManager, View, requireNativeComponent, NativeModules, Image, findNodeHandle, } from 'react-native';
|
||||
import invariant from 'invariant';
|
||||
import { defaultOriginWhitelist, createOnShouldStartLoadWithRequest, defaultRenderError, defaultRenderLoading, } from './WebViewShared';
|
||||
import styles from './WebView.styles';
|
||||
var UIManager = NotTypedUIManager;
|
||||
var resolveAssetSource = Image.resolveAssetSource;
|
||||
var processDecelerationRate = function (decelerationRate) {
|
||||
var newDecelerationRate = decelerationRate;
|
||||
if (newDecelerationRate === 'normal') {
|
||||
newDecelerationRate = 0.998;
|
||||
}
|
||||
else if (newDecelerationRate === 'fast') {
|
||||
newDecelerationRate = 0.99;
|
||||
}
|
||||
return newDecelerationRate;
|
||||
};
|
||||
var RNCWebViewManager = NativeModules.RNCWebViewManager;
|
||||
var RNCWebView = requireNativeComponent('RNCWebView');
|
||||
var WebView = /** @class */ (function (_super) {
|
||||
__extends(WebView, _super);
|
||||
function WebView() {
|
||||
var _this = _super !== null && _super.apply(this, arguments) || this;
|
||||
_this.state = {
|
||||
viewState: _this.props.startInLoadingState ? 'LOADING' : 'IDLE',
|
||||
lastErrorEvent: null
|
||||
};
|
||||
_this.webViewRef = React.createRef();
|
||||
// eslint-disable-next-line react/sort-comp
|
||||
_this.getCommands = function () { return UIManager.getViewManagerConfig('RNCWebView').Commands; };
|
||||
/**
|
||||
* Go forward one page in the web view's history.
|
||||
*/
|
||||
_this.goForward = function () {
|
||||
UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().goForward, undefined);
|
||||
};
|
||||
/**
|
||||
* Go back one page in the web view's history.
|
||||
*/
|
||||
_this.goBack = function () {
|
||||
UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().goBack, undefined);
|
||||
};
|
||||
/**
|
||||
* Reloads the current page.
|
||||
*/
|
||||
_this.reload = function () {
|
||||
_this.setState({ viewState: 'LOADING' });
|
||||
UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().reload, undefined);
|
||||
};
|
||||
/**
|
||||
* Stop loading the current page.
|
||||
*/
|
||||
_this.stopLoading = function () {
|
||||
UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().stopLoading, undefined);
|
||||
};
|
||||
/**
|
||||
* Request focus on WebView rendered page.
|
||||
*/
|
||||
_this.requestFocus = function () {
|
||||
UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().requestFocus, undefined);
|
||||
};
|
||||
/**
|
||||
* Posts a message to the web view, which will emit a `message` event.
|
||||
* Accepts one argument, `data`, which must be a string.
|
||||
*
|
||||
* In your webview, you'll need to something like the following.
|
||||
*
|
||||
* ```js
|
||||
* document.addEventListener('message', e => { document.title = e.data; });
|
||||
* ```
|
||||
*/
|
||||
_this.postMessage = function (data) {
|
||||
UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().postMessage, [String(data)]);
|
||||
};
|
||||
/**
|
||||
* Injects a javascript string into the referenced WebView. Deliberately does not
|
||||
* return a response because using eval() to return a response breaks this method
|
||||
* on pages with a Content Security Policy that disallows eval(). If you need that
|
||||
* functionality, look into postMessage/onMessage.
|
||||
*/
|
||||
_this.injectJavaScript = function (data) {
|
||||
UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().injectJavaScript, [data]);
|
||||
};
|
||||
/**
|
||||
* We return an event with a bunch of fields including:
|
||||
* url, title, loading, canGoBack, canGoForward
|
||||
*/
|
||||
_this.updateNavigationState = function (event) {
|
||||
if (_this.props.onNavigationStateChange) {
|
||||
_this.props.onNavigationStateChange(event.nativeEvent);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Returns the native `WebView` node.
|
||||
*/
|
||||
_this.getWebViewHandle = function () {
|
||||
var nodeHandle = findNodeHandle(_this.webViewRef.current);
|
||||
invariant(nodeHandle != null, 'nodeHandle expected to be non-null');
|
||||
return nodeHandle;
|
||||
};
|
||||
_this.onLoadingStart = function (event) {
|
||||
var onLoadStart = _this.props.onLoadStart;
|
||||
if (onLoadStart) {
|
||||
onLoadStart(event);
|
||||
}
|
||||
_this.updateNavigationState(event);
|
||||
};
|
||||
_this.onLoadingError = function (event) {
|
||||
event.persist(); // persist this event because we need to store it
|
||||
var _a = _this.props, onError = _a.onError, onLoadEnd = _a.onLoadEnd;
|
||||
if (onLoadEnd) {
|
||||
onLoadEnd(event);
|
||||
}
|
||||
if (onError) {
|
||||
onError(event);
|
||||
}
|
||||
console.warn('Encountered an error loading page', event.nativeEvent);
|
||||
_this.setState({
|
||||
lastErrorEvent: event.nativeEvent,
|
||||
viewState: 'ERROR'
|
||||
});
|
||||
};
|
||||
_this.onHttpError = function (event) {
|
||||
var onHttpError = _this.props.onHttpError;
|
||||
if (onHttpError) {
|
||||
onHttpError(event);
|
||||
}
|
||||
};
|
||||
_this.onLoadingFinish = function (event) {
|
||||
var _a = _this.props, onLoad = _a.onLoad, onLoadEnd = _a.onLoadEnd;
|
||||
if (onLoad) {
|
||||
onLoad(event);
|
||||
}
|
||||
if (onLoadEnd) {
|
||||
onLoadEnd(event);
|
||||
}
|
||||
_this.setState({
|
||||
viewState: 'IDLE'
|
||||
});
|
||||
_this.updateNavigationState(event);
|
||||
};
|
||||
_this.onMessage = function (event) {
|
||||
var onMessage = _this.props.onMessage;
|
||||
if (onMessage) {
|
||||
onMessage(event);
|
||||
}
|
||||
};
|
||||
_this.onLoadingProgress = function (event) {
|
||||
var onLoadProgress = _this.props.onLoadProgress;
|
||||
if (onLoadProgress) {
|
||||
onLoadProgress(event);
|
||||
}
|
||||
};
|
||||
_this.onShouldStartLoadWithRequestCallback = function (shouldStart, _url, lockIdentifier) {
|
||||
var viewManager = (_this.props.nativeConfig && _this.props.nativeConfig.viewManager)
|
||||
|| RNCWebViewManager;
|
||||
viewManager.startLoadWithResult(!!shouldStart, lockIdentifier);
|
||||
};
|
||||
_this.onContentProcessDidTerminate = function (event) {
|
||||
var onContentProcessDidTerminate = _this.props.onContentProcessDidTerminate;
|
||||
if (onContentProcessDidTerminate) {
|
||||
onContentProcessDidTerminate(event);
|
||||
}
|
||||
};
|
||||
return _this;
|
||||
}
|
||||
WebView.prototype.componentDidUpdate = function (prevProps) {
|
||||
this.showRedboxOnPropChanges(prevProps, 'allowsInlineMediaPlayback');
|
||||
this.showRedboxOnPropChanges(prevProps, 'incognito');
|
||||
this.showRedboxOnPropChanges(prevProps, 'mediaPlaybackRequiresUserAction');
|
||||
this.showRedboxOnPropChanges(prevProps, 'dataDetectorTypes');
|
||||
};
|
||||
WebView.prototype.showRedboxOnPropChanges = function (prevProps, propName) {
|
||||
if (this.props[propName] !== prevProps[propName]) {
|
||||
console.error("Changes to property " + propName + " do nothing after the initial render.");
|
||||
}
|
||||
};
|
||||
WebView.prototype.render = function () {
|
||||
var _a = this.props, decelerationRateProp = _a.decelerationRate, _b = _a.nativeConfig, nativeConfig = _b === void 0 ? {} : _b, onMessage = _a.onMessage, onShouldStartLoadWithRequestProp = _a.onShouldStartLoadWithRequest, originWhitelist = _a.originWhitelist, renderError = _a.renderError, renderLoading = _a.renderLoading, _c = _a.injectedJavaScriptForMainFrameOnly, injectedJavaScriptForMainFrameOnly = _c === void 0 ? true : _c, _d = _a.injectedJavaScriptBeforeContentLoadedForMainFrameOnly, injectedJavaScriptBeforeContentLoadedForMainFrameOnly = _d === void 0 ? true : _d, style = _a.style, containerStyle = _a.containerStyle, otherProps = __rest(_a, ["decelerationRate", "nativeConfig", "onMessage", "onShouldStartLoadWithRequest", "originWhitelist", "renderError", "renderLoading", "injectedJavaScriptForMainFrameOnly", "injectedJavaScriptBeforeContentLoadedForMainFrameOnly", "style", "containerStyle"]);
|
||||
var otherView = null;
|
||||
if (this.state.viewState === 'LOADING') {
|
||||
otherView = (renderLoading || defaultRenderLoading)();
|
||||
}
|
||||
else if (this.state.viewState === 'ERROR') {
|
||||
var errorEvent = this.state.lastErrorEvent;
|
||||
invariant(errorEvent != null, 'lastErrorEvent expected to be non-null');
|
||||
otherView = (renderError || defaultRenderError)(errorEvent.domain, errorEvent.code, errorEvent.description);
|
||||
}
|
||||
else if (this.state.viewState !== 'IDLE') {
|
||||
console.error("RNCWebView invalid state encountered: " + this.state.viewState);
|
||||
}
|
||||
var webViewStyles = [styles.container, styles.webView, style];
|
||||
var webViewContainerStyle = [styles.container, containerStyle];
|
||||
var onShouldStartLoadWithRequest = createOnShouldStartLoadWithRequest(this.onShouldStartLoadWithRequestCallback,
|
||||
// casting cause it's in the default props
|
||||
originWhitelist, onShouldStartLoadWithRequestProp);
|
||||
var decelerationRate = processDecelerationRate(decelerationRateProp);
|
||||
var NativeWebView = nativeConfig.component
|
||||
|| RNCWebView;
|
||||
var webView = (<NativeWebView key="webViewKey" {...otherProps} decelerationRate={decelerationRate} messagingEnabled={typeof onMessage === 'function'} onLoadingError={this.onLoadingError} onLoadingFinish={this.onLoadingFinish} onLoadingProgress={this.onLoadingProgress} onFileDownload={this.props.onFileDownload} onLoadingStart={this.onLoadingStart} onHttpError={this.onHttpError} onMessage={this.onMessage} onScroll={this.props.onScroll} onShouldStartLoadWithRequest={onShouldStartLoadWithRequest} onContentProcessDidTerminate={this.onContentProcessDidTerminate} injectedJavaScript={this.props.injectedJavaScript} injectedJavaScriptBeforeContentLoaded={this.props.injectedJavaScriptBeforeContentLoaded} injectedJavaScriptForMainFrameOnly={injectedJavaScriptForMainFrameOnly} injectedJavaScriptBeforeContentLoadedForMainFrameOnly={injectedJavaScriptBeforeContentLoadedForMainFrameOnly} ref={this.webViewRef}
|
||||
// TODO: find a better way to type this.
|
||||
source={resolveAssetSource(this.props.source)} style={webViewStyles} {...nativeConfig.props}/>);
|
||||
return (<View style={webViewContainerStyle}>
|
||||
{webView}
|
||||
{otherView}
|
||||
</View>);
|
||||
};
|
||||
WebView.defaultProps = {
|
||||
javaScriptEnabled: true,
|
||||
cacheEnabled: true,
|
||||
originWhitelist: defaultOriginWhitelist,
|
||||
useSharedProcessPool: true
|
||||
};
|
||||
WebView.isFileUploadSupported = function () { return __awaiter(void 0, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
// no native implementation for iOS, depends only on permissions
|
||||
return [2 /*return*/, true];
|
||||
});
|
||||
}); };
|
||||
return WebView;
|
||||
}(React.Component));
|
||||
export default WebView;
|
13
lib/WebView.js
Normal file
13
lib/WebView.js
Normal file
@ -0,0 +1,13 @@
|
||||
import React from 'react';
|
||||
import { View } from 'react-native';
|
||||
// This "dummy" WebView is to render something for unsupported platforms,
|
||||
// like for example Expo SDK "web" platform. It matches the previous react-native
|
||||
// implementation which is produced by Expo SDK 37.0.0.1 implementation, with
|
||||
// similar interface than the native ones have.
|
||||
var WebView = function () { return (<View style={{
|
||||
alignSelf: 'flex-start',
|
||||
borderColor: 'rgb(255, 0, 0)',
|
||||
borderWidth: 1
|
||||
}}/>); };
|
||||
export { WebView };
|
||||
export default WebView;
|
83
lib/WebView.macos.d.ts
vendored
Normal file
83
lib/WebView.macos.d.ts
vendored
Normal file
@ -0,0 +1,83 @@
|
||||
import React from 'react';
|
||||
import { WebViewErrorEvent, WebViewHttpErrorEvent, WebViewMessageEvent, WebViewNavigationEvent, WebViewProgressEvent, WebViewTerminatedEvent, MacOSWebViewProps, NativeWebViewMacOS, State } from './WebViewTypes';
|
||||
declare class WebView extends React.Component<MacOSWebViewProps, State> {
|
||||
static defaultProps: {
|
||||
javaScriptEnabled: boolean;
|
||||
cacheEnabled: boolean;
|
||||
originWhitelist: string[];
|
||||
useSharedProcessPool: boolean;
|
||||
};
|
||||
static isFileUploadSupported: () => Promise<boolean>;
|
||||
state: State;
|
||||
webViewRef: React.RefObject<NativeWebViewMacOS>;
|
||||
getCommands: () => {
|
||||
goForward: number;
|
||||
goBack: number;
|
||||
reload: number;
|
||||
stopLoading: number;
|
||||
postMessage: number;
|
||||
injectJavaScript: number;
|
||||
loadUrl: number;
|
||||
requestFocus: number;
|
||||
};
|
||||
/**
|
||||
* Go forward one page in the web view's history.
|
||||
*/
|
||||
goForward: () => void;
|
||||
/**
|
||||
* Go back one page in the web view's history.
|
||||
*/
|
||||
goBack: () => void;
|
||||
/**
|
||||
* Reloads the current page.
|
||||
*/
|
||||
reload: () => void;
|
||||
/**
|
||||
* Stop loading the current page.
|
||||
*/
|
||||
stopLoading: () => void;
|
||||
/**
|
||||
* Request focus on WebView rendered page.
|
||||
*/
|
||||
requestFocus: () => void;
|
||||
/**
|
||||
* Posts a message to the web view, which will emit a `message` event.
|
||||
* Accepts one argument, `data`, which must be a string.
|
||||
*
|
||||
* In your webview, you'll need to something like the following.
|
||||
*
|
||||
* ```js
|
||||
* document.addEventListener('message', e => { document.title = e.data; });
|
||||
* ```
|
||||
*/
|
||||
postMessage: (data: string) => void;
|
||||
/**
|
||||
* Injects a javascript string into the referenced WebView. Deliberately does not
|
||||
* return a response because using eval() to return a response breaks this method
|
||||
* on pages with a Content Security Policy that disallows eval(). If you need that
|
||||
* functionality, look into postMessage/onMessage.
|
||||
*/
|
||||
injectJavaScript: (data: string) => void;
|
||||
/**
|
||||
* We return an event with a bunch of fields including:
|
||||
* url, title, loading, canGoBack, canGoForward
|
||||
*/
|
||||
updateNavigationState: (event: WebViewNavigationEvent) => void;
|
||||
/**
|
||||
* Returns the native `WebView` node.
|
||||
*/
|
||||
getWebViewHandle: () => number;
|
||||
onLoadingStart: (event: WebViewNavigationEvent) => void;
|
||||
onLoadingError: (event: WebViewErrorEvent) => void;
|
||||
onHttpError: (event: WebViewHttpErrorEvent) => void;
|
||||
onLoadingFinish: (event: WebViewNavigationEvent) => void;
|
||||
onMessage: (event: WebViewMessageEvent) => void;
|
||||
onLoadingProgress: (event: WebViewProgressEvent) => void;
|
||||
onShouldStartLoadWithRequestCallback: (shouldStart: boolean, _url: string, lockIdentifier: number) => void;
|
||||
onContentProcessDidTerminate: (event: WebViewTerminatedEvent) => void;
|
||||
componentDidUpdate(prevProps: MacOSWebViewProps): void;
|
||||
showRedboxOnPropChanges(prevProps: MacOSWebViewProps, propName: keyof MacOSWebViewProps): void;
|
||||
render(): JSX.Element;
|
||||
}
|
||||
export default WebView;
|
||||
//# sourceMappingURL=WebView.macos.d.ts.map
|
1
lib/WebView.macos.d.ts.map
Normal file
1
lib/WebView.macos.d.ts.map
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"WebView.macos.d.ts","sourceRoot":"","sources":["../src/WebView.macos.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAkB1B,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,EACnB,sBAAsB,EACtB,oBAAoB,EACpB,sBAAsB,EACtB,iBAAiB,EACjB,kBAAkB,EAElB,KAAK,EAEN,MAAM,gBAAgB,CAAC;AAcxB,cAAM,OAAQ,SAAQ,KAAK,CAAC,SAAS,CAAC,iBAAiB,EAAE,KAAK,CAAC;IAC7D,MAAM,CAAC,YAAY;;;;;MAKjB;IAEF,MAAM,CAAC,qBAAqB,yBAG1B;IAEF,KAAK,EAAE,KAAK,CAGV;IAEF,UAAU,sCAAyC;IAGnD,WAAW;;;;;;;;;MAA+D;IAE1E;;OAEG;IACH,SAAS,aAMP;IAEF;;OAEG;IACH,MAAM,aAMJ;IAEF;;OAEG;IACH,MAAM,aAOJ;IAEF;;OAEG;IACH,WAAW,aAMT;IAEF;;OAEG;IACH,YAAY,aAMV;IAEF;;;;;;;;;OASG;IACH,WAAW,yBAMT;IAEF;;;;;OAKG;IACH,gBAAgB,yBAMd;IAEF;;;OAGG;IACH,qBAAqB,0CAInB;IAEF;;OAEG;IACH,gBAAgB,eAId;IAEF,cAAc,0CAMZ;IAEF,cAAc,qCAeZ;IAEF,WAAW,yCAKV;IAED,eAAe,0CAYb;IAEF,SAAS,uCAKP;IAEF,iBAAiB,wCAKf;IAEF,oCAAoC,uEAUlC;IAEF,4BAA4B,0CAK1B;IAEF,kBAAkB,CAAC,SAAS,EAAE,iBAAiB;IAM/C,uBAAuB,CACrB,SAAS,EAAE,iBAAiB,EAC5B,QAAQ,EAAE,MAAM,iBAAiB;IASnC,MAAM;CA0EP;AAED,eAAe,OAAO,CAAC"}
|
270
lib/WebView.macos.js
Normal file
270
lib/WebView.macos.js
Normal file
@ -0,0 +1,270 @@
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
while (_) try {
|
||||
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;
|
||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||
switch (op[0]) {
|
||||
case 0: case 1: t = op; break;
|
||||
case 4: _.label++; return { value: op[1], done: false };
|
||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||
default:
|
||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||
if (t[2]) _.ops.pop();
|
||||
_.trys.pop(); continue;
|
||||
}
|
||||
op = body.call(thisArg, _);
|
||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||
}
|
||||
};
|
||||
var __rest = (this && this.__rest) || function (s, e) {
|
||||
var t = {};
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
||||
t[p] = s[p];
|
||||
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
||||
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
||||
t[p[i]] = s[p[i]];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
import React from 'react';
|
||||
import { UIManager as NotTypedUIManager, View, requireNativeComponent, NativeModules, Image, findNodeHandle, } from 'react-native';
|
||||
import invariant from 'invariant';
|
||||
import { defaultOriginWhitelist, createOnShouldStartLoadWithRequest, defaultRenderError, defaultRenderLoading, } from './WebViewShared';
|
||||
import styles from './WebView.styles';
|
||||
var UIManager = NotTypedUIManager;
|
||||
var resolveAssetSource = Image.resolveAssetSource;
|
||||
var RNCWebViewManager = NativeModules.RNCWebViewManager;
|
||||
var RNCWebView = requireNativeComponent('RNCWebView');
|
||||
var WebView = /** @class */ (function (_super) {
|
||||
__extends(WebView, _super);
|
||||
function WebView() {
|
||||
var _this = _super !== null && _super.apply(this, arguments) || this;
|
||||
_this.state = {
|
||||
viewState: _this.props.startInLoadingState ? 'LOADING' : 'IDLE',
|
||||
lastErrorEvent: null
|
||||
};
|
||||
_this.webViewRef = React.createRef();
|
||||
// eslint-disable-next-line react/sort-comp
|
||||
_this.getCommands = function () { return UIManager.getViewManagerConfig('RNCWebView').Commands; };
|
||||
/**
|
||||
* Go forward one page in the web view's history.
|
||||
*/
|
||||
_this.goForward = function () {
|
||||
UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().goForward, undefined);
|
||||
};
|
||||
/**
|
||||
* Go back one page in the web view's history.
|
||||
*/
|
||||
_this.goBack = function () {
|
||||
UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().goBack, undefined);
|
||||
};
|
||||
/**
|
||||
* Reloads the current page.
|
||||
*/
|
||||
_this.reload = function () {
|
||||
_this.setState({ viewState: 'LOADING' });
|
||||
UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().reload, undefined);
|
||||
};
|
||||
/**
|
||||
* Stop loading the current page.
|
||||
*/
|
||||
_this.stopLoading = function () {
|
||||
UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().stopLoading, undefined);
|
||||
};
|
||||
/**
|
||||
* Request focus on WebView rendered page.
|
||||
*/
|
||||
_this.requestFocus = function () {
|
||||
UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().requestFocus, undefined);
|
||||
};
|
||||
/**
|
||||
* Posts a message to the web view, which will emit a `message` event.
|
||||
* Accepts one argument, `data`, which must be a string.
|
||||
*
|
||||
* In your webview, you'll need to something like the following.
|
||||
*
|
||||
* ```js
|
||||
* document.addEventListener('message', e => { document.title = e.data; });
|
||||
* ```
|
||||
*/
|
||||
_this.postMessage = function (data) {
|
||||
UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().postMessage, [String(data)]);
|
||||
};
|
||||
/**
|
||||
* Injects a javascript string into the referenced WebView. Deliberately does not
|
||||
* return a response because using eval() to return a response breaks this method
|
||||
* on pages with a Content Security Policy that disallows eval(). If you need that
|
||||
* functionality, look into postMessage/onMessage.
|
||||
*/
|
||||
_this.injectJavaScript = function (data) {
|
||||
UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().injectJavaScript, [data]);
|
||||
};
|
||||
/**
|
||||
* We return an event with a bunch of fields including:
|
||||
* url, title, loading, canGoBack, canGoForward
|
||||
*/
|
||||
_this.updateNavigationState = function (event) {
|
||||
if (_this.props.onNavigationStateChange) {
|
||||
_this.props.onNavigationStateChange(event.nativeEvent);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Returns the native `WebView` node.
|
||||
*/
|
||||
_this.getWebViewHandle = function () {
|
||||
var nodeHandle = findNodeHandle(_this.webViewRef.current);
|
||||
invariant(nodeHandle != null, 'nodeHandle expected to be non-null');
|
||||
return nodeHandle;
|
||||
};
|
||||
_this.onLoadingStart = function (event) {
|
||||
var onLoadStart = _this.props.onLoadStart;
|
||||
if (onLoadStart) {
|
||||
onLoadStart(event);
|
||||
}
|
||||
_this.updateNavigationState(event);
|
||||
};
|
||||
_this.onLoadingError = function (event) {
|
||||
event.persist(); // persist this event because we need to store it
|
||||
var _a = _this.props, onError = _a.onError, onLoadEnd = _a.onLoadEnd;
|
||||
if (onLoadEnd) {
|
||||
onLoadEnd(event);
|
||||
}
|
||||
if (onError) {
|
||||
onError(event);
|
||||
}
|
||||
console.warn('Encountered an error loading page', event.nativeEvent);
|
||||
_this.setState({
|
||||
lastErrorEvent: event.nativeEvent,
|
||||
viewState: 'ERROR'
|
||||
});
|
||||
};
|
||||
_this.onHttpError = function (event) {
|
||||
var onHttpError = _this.props.onHttpError;
|
||||
if (onHttpError) {
|
||||
onHttpError(event);
|
||||
}
|
||||
};
|
||||
_this.onLoadingFinish = function (event) {
|
||||
var _a = _this.props, onLoad = _a.onLoad, onLoadEnd = _a.onLoadEnd;
|
||||
if (onLoad) {
|
||||
onLoad(event);
|
||||
}
|
||||
if (onLoadEnd) {
|
||||
onLoadEnd(event);
|
||||
}
|
||||
_this.setState({
|
||||
viewState: 'IDLE'
|
||||
});
|
||||
_this.updateNavigationState(event);
|
||||
};
|
||||
_this.onMessage = function (event) {
|
||||
var onMessage = _this.props.onMessage;
|
||||
if (onMessage) {
|
||||
onMessage(event);
|
||||
}
|
||||
};
|
||||
_this.onLoadingProgress = function (event) {
|
||||
var onLoadProgress = _this.props.onLoadProgress;
|
||||
if (onLoadProgress) {
|
||||
onLoadProgress(event);
|
||||
}
|
||||
};
|
||||
_this.onShouldStartLoadWithRequestCallback = function (shouldStart, _url, lockIdentifier) {
|
||||
var viewManager = (_this.props.nativeConfig && _this.props.nativeConfig.viewManager)
|
||||
|| RNCWebViewManager;
|
||||
viewManager.startLoadWithResult(!!shouldStart, lockIdentifier);
|
||||
};
|
||||
_this.onContentProcessDidTerminate = function (event) {
|
||||
var onContentProcessDidTerminate = _this.props.onContentProcessDidTerminate;
|
||||
if (onContentProcessDidTerminate) {
|
||||
onContentProcessDidTerminate(event);
|
||||
}
|
||||
};
|
||||
return _this;
|
||||
}
|
||||
WebView.prototype.componentDidUpdate = function (prevProps) {
|
||||
this.showRedboxOnPropChanges(prevProps, 'allowsInlineMediaPlayback');
|
||||
this.showRedboxOnPropChanges(prevProps, 'incognito');
|
||||
this.showRedboxOnPropChanges(prevProps, 'mediaPlaybackRequiresUserAction');
|
||||
};
|
||||
WebView.prototype.showRedboxOnPropChanges = function (prevProps, propName) {
|
||||
if (this.props[propName] !== prevProps[propName]) {
|
||||
console.error("Changes to property " + propName + " do nothing after the initial render.");
|
||||
}
|
||||
};
|
||||
WebView.prototype.render = function () {
|
||||
var _a = this.props, _b = _a.nativeConfig, nativeConfig = _b === void 0 ? {} : _b, onMessage = _a.onMessage, onShouldStartLoadWithRequestProp = _a.onShouldStartLoadWithRequest, originWhitelist = _a.originWhitelist, renderError = _a.renderError, renderLoading = _a.renderLoading, style = _a.style, containerStyle = _a.containerStyle, otherProps = __rest(_a, ["nativeConfig", "onMessage", "onShouldStartLoadWithRequest", "originWhitelist", "renderError", "renderLoading", "style", "containerStyle"]);
|
||||
var otherView = null;
|
||||
if (this.state.viewState === 'LOADING') {
|
||||
otherView = (renderLoading || defaultRenderLoading)();
|
||||
}
|
||||
else if (this.state.viewState === 'ERROR') {
|
||||
var errorEvent = this.state.lastErrorEvent;
|
||||
invariant(errorEvent != null, 'lastErrorEvent expected to be non-null');
|
||||
otherView = (renderError || defaultRenderError)(errorEvent.domain, errorEvent.code, errorEvent.description);
|
||||
}
|
||||
else if (this.state.viewState !== 'IDLE') {
|
||||
console.error("RNCWebView invalid state encountered: " + this.state.viewState);
|
||||
}
|
||||
var webViewStyles = [styles.container, styles.webView, style];
|
||||
var webViewContainerStyle = [styles.container, containerStyle];
|
||||
var onShouldStartLoadWithRequest = createOnShouldStartLoadWithRequest(this.onShouldStartLoadWithRequestCallback,
|
||||
// casting cause it's in the default props
|
||||
originWhitelist, onShouldStartLoadWithRequestProp);
|
||||
var NativeWebView = nativeConfig.component
|
||||
|| RNCWebView;
|
||||
var webView = (<NativeWebView key="webViewKey" {...otherProps} messagingEnabled={typeof onMessage === 'function'} onLoadingError={this.onLoadingError} onLoadingFinish={this.onLoadingFinish} onLoadingProgress={this.onLoadingProgress} onLoadingStart={this.onLoadingStart} onHttpError={this.onHttpError} onMessage={this.onMessage} onScroll={this.props.onScroll} onShouldStartLoadWithRequest={onShouldStartLoadWithRequest} onContentProcessDidTerminate={this.onContentProcessDidTerminate} ref={this.webViewRef}
|
||||
// TODO: find a better way to type this.
|
||||
source={resolveAssetSource(this.props.source)} style={webViewStyles} {...nativeConfig.props}/>);
|
||||
return (<View style={webViewContainerStyle}>
|
||||
{webView}
|
||||
{otherView}
|
||||
</View>);
|
||||
};
|
||||
WebView.defaultProps = {
|
||||
javaScriptEnabled: true,
|
||||
cacheEnabled: true,
|
||||
originWhitelist: defaultOriginWhitelist,
|
||||
useSharedProcessPool: true
|
||||
};
|
||||
WebView.isFileUploadSupported = function () { return __awaiter(void 0, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
// no native implementation for macOS, depends only on permissions
|
||||
return [2 /*return*/, true];
|
||||
});
|
||||
}); };
|
||||
return WebView;
|
||||
}(React.Component));
|
||||
export default WebView;
|
12
lib/WebView.styles.d.ts
vendored
Normal file
12
lib/WebView.styles.d.ts
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
import { ViewStyle, TextStyle } from 'react-native';
|
||||
interface Styles {
|
||||
container: ViewStyle;
|
||||
errorText: TextStyle;
|
||||
errorTextTitle: TextStyle;
|
||||
loadingOrErrorView: ViewStyle;
|
||||
webView: ViewStyle;
|
||||
loadingProgressBar: ViewStyle;
|
||||
}
|
||||
declare const styles: Styles;
|
||||
export default styles;
|
||||
//# sourceMappingURL=WebView.styles.d.ts.map
|
1
lib/WebView.styles.d.ts.map
Normal file
1
lib/WebView.styles.d.ts.map
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"WebView.styles.d.ts","sourceRoot":"","sources":["../src/WebView.styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEhE,UAAU,MAAM;IACd,SAAS,EAAE,SAAS,CAAC;IACrB,SAAS,EAAE,SAAS,CAAC;IACrB,cAAc,EAAE,SAAS,CAAC;IAC1B,kBAAkB,EAAE,SAAS,CAAC;IAC9B,OAAO,EAAE,SAAS,CAAC;IACnB,kBAAkB,EAAE,SAAS,CAAC;CAC/B;AAED,QAAA,MAAM,MAAM,QA8BV,CAAC;AAEH,eAAe,MAAM,CAAC"}
|
33
lib/WebView.styles.js
Normal file
33
lib/WebView.styles.js
Normal file
@ -0,0 +1,33 @@
|
||||
import { StyleSheet } from 'react-native';
|
||||
var styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
overflow: 'hidden'
|
||||
},
|
||||
loadingOrErrorView: {
|
||||
position: 'absolute',
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
backgroundColor: 'white'
|
||||
},
|
||||
loadingProgressBar: {
|
||||
height: 20
|
||||
},
|
||||
errorText: {
|
||||
fontSize: 14,
|
||||
textAlign: 'center',
|
||||
marginBottom: 2
|
||||
},
|
||||
errorTextTitle: {
|
||||
fontSize: 15,
|
||||
fontWeight: '500',
|
||||
marginBottom: 10
|
||||
},
|
||||
webView: {
|
||||
backgroundColor: '#ffffff'
|
||||
}
|
||||
});
|
||||
export default styles;
|
39
lib/WebView.windows.d.ts
vendored
Normal file
39
lib/WebView.windows.d.ts
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* Portions copyright for react-native-windows:
|
||||
*
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License.
|
||||
*/
|
||||
import React from 'react';
|
||||
import { NativeWebViewWindows, WebViewSharedProps, WebViewProgressEvent, WebViewNavigationEvent, WebViewErrorEvent, WebViewHttpErrorEvent, WebViewMessageEvent, State } from './WebViewTypes';
|
||||
export default class WebView extends React.Component<WebViewSharedProps, State> {
|
||||
static defaultProps: {
|
||||
javaScriptEnabled: boolean;
|
||||
};
|
||||
state: State;
|
||||
webViewRef: React.RefObject<NativeWebViewWindows>;
|
||||
goForward: () => void;
|
||||
goBack: () => void;
|
||||
reload: () => void;
|
||||
injectJavaScript: (data: string) => void;
|
||||
postMessage: (data: string) => void;
|
||||
/**
|
||||
* We return an event with a bunch of fields including:
|
||||
* url, title, loading, canGoBack, canGoForward
|
||||
*/
|
||||
updateNavigationState: (event: WebViewNavigationEvent) => void;
|
||||
getWebViewHandle: () => number | null;
|
||||
onLoadingStart: (event: WebViewNavigationEvent) => void;
|
||||
onLoadingProgress: (event: WebViewProgressEvent) => void;
|
||||
onLoadingError: (event: WebViewErrorEvent) => void;
|
||||
onLoadingFinish: (event: WebViewNavigationEvent) => void;
|
||||
onMessage: (event: WebViewMessageEvent) => void;
|
||||
onHttpError: (event: WebViewHttpErrorEvent) => void;
|
||||
render(): JSX.Element;
|
||||
}
|
||||
//# sourceMappingURL=WebView.windows.d.ts.map
|
1
lib/WebView.windows.d.ts.map
Normal file
1
lib/WebView.windows.d.ts.map
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"WebView.windows.d.ts","sourceRoot":"","sources":["../src/WebView.windows.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAa1B,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,oBAAoB,EACpB,sBAAsB,EACtB,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,EAEnB,KAAK,EACN,MAAM,gBAAgB,CAAC;AA0BxB,MAAM,CAAC,OAAO,OAAO,OAAQ,SAAQ,KAAK,CAAC,SAAS,CAAC,kBAAkB,EAAE,KAAK,CAAC;IAE7E,MAAM,CAAC,YAAY;;MAEjB;IAEF,KAAK,EAAE,KAAK,CAGX;IAED,UAAU,wCAA2C;IAErD,SAAS,aAMR;IAED,MAAM,aAML;IAED,MAAM,aAML;IAED,gBAAgB,yBAMf;IAED,WAAW,yBAMT;IAEF;;;OAGG;IACH,qBAAqB,0CAIpB;IAED,gBAAgB,sBAGf;IAED,cAAc,0CAMb;IAED,iBAAiB,wCAKf;IAEF,cAAc,qCAcb;IAED,eAAe,0CAYd;IAED,SAAS,uCAKR;IAED,WAAW,yCAKV;IAED,MAAM;CA6EP"}
|
187
lib/WebView.windows.js
Normal file
187
lib/WebView.windows.js
Normal file
@ -0,0 +1,187 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* Portions copyright for react-native-windows:
|
||||
*
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License.
|
||||
*/
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
var __rest = (this && this.__rest) || function (s, e) {
|
||||
var t = {};
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
||||
t[p] = s[p];
|
||||
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
||||
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
||||
t[p[i]] = s[p[i]];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
import React from 'react';
|
||||
import { UIManager as NotTypedUIManager, View, requireNativeComponent, StyleSheet, Image, findNodeHandle, } from 'react-native';
|
||||
import { createOnShouldStartLoadWithRequest, } from './WebViewShared';
|
||||
var UIManager = NotTypedUIManager;
|
||||
var resolveAssetSource = Image.resolveAssetSource;
|
||||
var RCTWebView = requireNativeComponent('RCTWebView');
|
||||
var styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1
|
||||
},
|
||||
hidden: {
|
||||
height: 0,
|
||||
flex: 0
|
||||
},
|
||||
loadingView: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center'
|
||||
},
|
||||
loadingProgressBar: {
|
||||
height: 20
|
||||
}
|
||||
});
|
||||
var WebView = /** @class */ (function (_super) {
|
||||
__extends(WebView, _super);
|
||||
function WebView() {
|
||||
var _this = _super !== null && _super.apply(this, arguments) || this;
|
||||
_this.state = {
|
||||
viewState: _this.props.startInLoadingState ? 'LOADING' : 'IDLE',
|
||||
lastErrorEvent: null
|
||||
};
|
||||
_this.webViewRef = React.createRef();
|
||||
_this.goForward = function () {
|
||||
UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), UIManager.getViewManagerConfig('RCTWebView').Commands.goForward, undefined);
|
||||
};
|
||||
_this.goBack = function () {
|
||||
UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), UIManager.getViewManagerConfig('RCTWebView').Commands.goBack, undefined);
|
||||
};
|
||||
_this.reload = function () {
|
||||
UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), UIManager.getViewManagerConfig('RCTWebView').Commands.reload, undefined);
|
||||
};
|
||||
_this.injectJavaScript = function (data) {
|
||||
UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), UIManager.getViewManagerConfig('RCTWebView').Commands.injectJavaScript, [data]);
|
||||
};
|
||||
_this.postMessage = function (data) {
|
||||
UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), UIManager.getViewManagerConfig('RCTWebView').Commands.postMessage, [String(data)]);
|
||||
};
|
||||
/**
|
||||
* We return an event with a bunch of fields including:
|
||||
* url, title, loading, canGoBack, canGoForward
|
||||
*/
|
||||
_this.updateNavigationState = function (event) {
|
||||
if (_this.props.onNavigationStateChange) {
|
||||
_this.props.onNavigationStateChange(event.nativeEvent);
|
||||
}
|
||||
};
|
||||
_this.getWebViewHandle = function () {
|
||||
// eslint-disable-next-line react/no-string-refs
|
||||
return findNodeHandle(_this.webViewRef.current);
|
||||
};
|
||||
_this.onLoadingStart = function (event) {
|
||||
var onLoadStart = _this.props.onLoadStart;
|
||||
if (onLoadStart) {
|
||||
onLoadStart(event);
|
||||
}
|
||||
_this.updateNavigationState(event);
|
||||
};
|
||||
_this.onLoadingProgress = function (event) {
|
||||
var onLoadProgress = _this.props.onLoadProgress;
|
||||
if (onLoadProgress) {
|
||||
onLoadProgress(event);
|
||||
}
|
||||
};
|
||||
_this.onLoadingError = function (event) {
|
||||
event.persist(); // persist this event because we need to store it
|
||||
var _a = _this.props, onError = _a.onError, onLoadEnd = _a.onLoadEnd;
|
||||
if (onError) {
|
||||
onError(event);
|
||||
}
|
||||
if (onLoadEnd) {
|
||||
onLoadEnd(event);
|
||||
}
|
||||
console.error('Encountered an error loading page', event.nativeEvent);
|
||||
_this.setState({
|
||||
lastErrorEvent: event.nativeEvent,
|
||||
viewState: 'ERROR'
|
||||
});
|
||||
};
|
||||
_this.onLoadingFinish = function (event) {
|
||||
var _a = _this.props, onLoad = _a.onLoad, onLoadEnd = _a.onLoadEnd;
|
||||
if (onLoad) {
|
||||
onLoad(event);
|
||||
}
|
||||
if (onLoadEnd) {
|
||||
onLoadEnd(event);
|
||||
}
|
||||
_this.setState({
|
||||
viewState: 'IDLE'
|
||||
});
|
||||
_this.updateNavigationState(event);
|
||||
};
|
||||
_this.onMessage = function (event) {
|
||||
var onMessage = _this.props.onMessage;
|
||||
if (onMessage) {
|
||||
onMessage(event);
|
||||
}
|
||||
};
|
||||
_this.onHttpError = function (event) {
|
||||
var onHttpError = _this.props.onHttpError;
|
||||
if (onHttpError) {
|
||||
onHttpError(event);
|
||||
}
|
||||
};
|
||||
return _this;
|
||||
}
|
||||
WebView.prototype.render = function () {
|
||||
var _a = this.props, _b = _a.nativeConfig, nativeConfig = _b === void 0 ? {} : _b, onMessage = _a.onMessage, onShouldStartLoadWithRequestProp = _a.onShouldStartLoadWithRequest, originWhitelist = _a.originWhitelist, renderError = _a.renderError, renderLoading = _a.renderLoading, style = _a.style, containerStyle = _a.containerStyle, otherProps = __rest(_a, ["nativeConfig", "onMessage", "onShouldStartLoadWithRequest", "originWhitelist", "renderError", "renderLoading", "style", "containerStyle"]);
|
||||
var otherView = null;
|
||||
if (this.state.viewState === 'LOADING') {
|
||||
otherView = this.props.renderLoading && this.props.renderLoading();
|
||||
}
|
||||
else if (this.state.viewState === 'ERROR') {
|
||||
var errorEvent = this.state.lastErrorEvent;
|
||||
otherView = this.props.renderError
|
||||
&& this.props.renderError(errorEvent.domain, errorEvent.code, errorEvent.description);
|
||||
}
|
||||
else if (this.state.viewState !== 'IDLE') {
|
||||
console.error('RCTWebView invalid state encountered: ', this.state.viewState);
|
||||
}
|
||||
var webViewStyles = [styles.container, this.props.style];
|
||||
if (this.state.viewState === 'LOADING'
|
||||
|| this.state.viewState === 'ERROR') {
|
||||
// if we're in either LOADING or ERROR states, don't show the webView
|
||||
webViewStyles.push(styles.hidden);
|
||||
}
|
||||
var onShouldStartLoadWithRequest = createOnShouldStartLoadWithRequest(function () { },
|
||||
// casting cause it's in the default props
|
||||
originWhitelist, onShouldStartLoadWithRequestProp);
|
||||
var NativeWebView = nativeConfig.component
|
||||
|| RCTWebView;
|
||||
var webView = (<NativeWebView ref={this.webViewRef} key="webViewKey" {...otherProps} messagingEnabled={typeof onMessage === 'function'} onLoadingError={this.onLoadingError} onLoadingFinish={this.onLoadingFinish} onLoadingProgress={this.onLoadingProgress} onLoadingStart={this.onLoadingStart} onHttpError={this.onHttpError} onMessage={this.onMessage} onScroll={this.props.onScroll} onShouldStartLoadWithRequest={onShouldStartLoadWithRequest} source={resolveAssetSource(this.props.source)} style={webViewStyles} {...nativeConfig.props}/>);
|
||||
return (<View style={styles.container}>
|
||||
{webView}
|
||||
{otherView}
|
||||
</View>);
|
||||
};
|
||||
WebView.defaultProps = {
|
||||
javaScriptEnabled: true
|
||||
};
|
||||
return WebView;
|
||||
}(React.Component));
|
||||
export default WebView;
|
7
lib/WebViewShared.d.ts
vendored
Normal file
7
lib/WebViewShared.d.ts
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
import { OnShouldStartLoadWithRequest, ShouldStartLoadRequestEvent } from './WebViewTypes';
|
||||
declare const defaultOriginWhitelist: string[];
|
||||
declare const createOnShouldStartLoadWithRequest: (loadRequest: (shouldStart: boolean, url: string, lockIdentifier: number) => void, originWhitelist: readonly string[], onShouldStartLoadWithRequest?: OnShouldStartLoadWithRequest | undefined) => ({ nativeEvent }: ShouldStartLoadRequestEvent) => void;
|
||||
declare const defaultRenderLoading: () => JSX.Element;
|
||||
declare const defaultRenderError: (errorDomain: string | undefined, errorCode: number, errorDesc: string) => JSX.Element;
|
||||
export { defaultOriginWhitelist, createOnShouldStartLoadWithRequest, defaultRenderLoading, defaultRenderError, };
|
||||
//# sourceMappingURL=WebViewShared.d.ts.map
|
1
lib/WebViewShared.d.ts.map
Normal file
1
lib/WebViewShared.d.ts.map
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"WebViewShared.d.ts","sourceRoot":"","sources":["../src/WebViewShared.tsx"],"names":[],"mappings":"AAGA,OAAO,EACL,4BAA4B,EAC5B,2BAA2B,EAC5B,MAAM,gBAAgB,CAAC;AAGxB,QAAA,MAAM,sBAAsB,UAA4B,CAAC;AAuBzD,QAAA,MAAM,kCAAkC,2PA8BvC,CAAC;AAEF,QAAA,MAAM,oBAAoB,mBAIzB,CAAC;AACF,QAAA,MAAM,kBAAkB,wFAWvB,CAAC;AAEF,OAAO,EACL,sBAAsB,EACtB,kCAAkC,EAClC,oBAAoB,EACpB,kBAAkB,GACnB,CAAC"}
|
59
lib/WebViewShared.js
Normal file
59
lib/WebViewShared.js
Normal file
@ -0,0 +1,59 @@
|
||||
var __spreadArrays = (this && this.__spreadArrays) || function () {
|
||||
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
|
||||
for (var r = Array(s), k = 0, i = 0; i < il; i++)
|
||||
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
|
||||
r[k] = a[j];
|
||||
return r;
|
||||
};
|
||||
import escapeStringRegexp from 'escape-string-regexp';
|
||||
import React from 'react';
|
||||
import { Linking, View, ActivityIndicator, Text } from 'react-native';
|
||||
import styles from './WebView.styles';
|
||||
var defaultOriginWhitelist = ['http://*', 'https://*'];
|
||||
var extractOrigin = function (url) {
|
||||
var result = /^[A-Za-z][A-Za-z0-9+\-.]+:(\/\/)?[^/]*/.exec(url);
|
||||
return result === null ? '' : result[0];
|
||||
};
|
||||
var originWhitelistToRegex = function (originWhitelist) {
|
||||
return "^" + escapeStringRegexp(originWhitelist).replace(/\\\*/g, '.*');
|
||||
};
|
||||
var passesWhitelist = function (compiledWhitelist, url) {
|
||||
var origin = extractOrigin(url);
|
||||
return compiledWhitelist.some(function (x) { return new RegExp(x).test(origin); });
|
||||
};
|
||||
var compileWhitelist = function (originWhitelist) {
|
||||
return __spreadArrays(['about:blank'], (originWhitelist || [])).map(originWhitelistToRegex);
|
||||
};
|
||||
var createOnShouldStartLoadWithRequest = function (loadRequest, originWhitelist, onShouldStartLoadWithRequest) {
|
||||
return function (_a) {
|
||||
var nativeEvent = _a.nativeEvent;
|
||||
var shouldStart = true;
|
||||
var url = nativeEvent.url, lockIdentifier = nativeEvent.lockIdentifier;
|
||||
if (!passesWhitelist(compileWhitelist(originWhitelist), url)) {
|
||||
Linking.canOpenURL(url).then(function (supported) {
|
||||
if (supported) {
|
||||
return Linking.openURL(url);
|
||||
}
|
||||
console.warn("Can't open url: " + url);
|
||||
return undefined;
|
||||
})["catch"](function (e) {
|
||||
console.warn('Error opening URL: ', e);
|
||||
});
|
||||
shouldStart = false;
|
||||
}
|
||||
else if (onShouldStartLoadWithRequest) {
|
||||
shouldStart = onShouldStartLoadWithRequest(nativeEvent);
|
||||
}
|
||||
loadRequest(shouldStart, url, lockIdentifier);
|
||||
};
|
||||
};
|
||||
var defaultRenderLoading = function () { return (<View style={styles.loadingOrErrorView}>
|
||||
<ActivityIndicator />
|
||||
</View>); };
|
||||
var defaultRenderError = function (errorDomain, errorCode, errorDesc) { return (<View style={styles.loadingOrErrorView}>
|
||||
<Text style={styles.errorTextTitle}>Error loading page</Text>
|
||||
<Text style={styles.errorText}>{"Domain: " + errorDomain}</Text>
|
||||
<Text style={styles.errorText}>{"Error Code: " + errorCode}</Text>
|
||||
<Text style={styles.errorText}>{"Description: " + errorDesc}</Text>
|
||||
</View>); };
|
||||
export { defaultOriginWhitelist, createOnShouldStartLoadWithRequest, defaultRenderLoading, defaultRenderError, };
|
863
lib/WebViewTypes.d.ts
vendored
Normal file
863
lib/WebViewTypes.d.ts
vendored
Normal file
@ -0,0 +1,863 @@
|
||||
import { ReactElement, Component } from 'react';
|
||||
import { NativeSyntheticEvent, ViewProps, StyleProp, ViewStyle, NativeMethodsMixin, Constructor, UIManagerStatic, NativeScrollEvent } from 'react-native';
|
||||
declare type WebViewCommands = 'goForward' | 'goBack' | 'reload' | 'stopLoading' | 'postMessage' | 'injectJavaScript' | 'loadUrl' | 'requestFocus';
|
||||
declare type AndroidWebViewCommands = 'clearHistory' | 'clearCache' | 'clearFormData' | 'answerPermissionRequest';
|
||||
interface RNCWebViewUIManager<Commands extends string> extends UIManagerStatic {
|
||||
getViewManagerConfig: (name: string) => {
|
||||
Commands: {
|
||||
[key in Commands]: number;
|
||||
};
|
||||
};
|
||||
}
|
||||
export declare type RNCWebViewUIManagerAndroid = RNCWebViewUIManager<WebViewCommands | AndroidWebViewCommands>;
|
||||
export declare type RNCWebViewUIManagerIOS = RNCWebViewUIManager<WebViewCommands>;
|
||||
export declare type RNCWebViewUIManagerMacOS = RNCWebViewUIManager<WebViewCommands>;
|
||||
export declare type RNCWebViewUIManagerWindows = RNCWebViewUIManager<WebViewCommands>;
|
||||
declare type WebViewState = 'IDLE' | 'LOADING' | 'ERROR';
|
||||
interface BaseState {
|
||||
viewState: WebViewState;
|
||||
}
|
||||
interface NormalState extends BaseState {
|
||||
viewState: 'IDLE' | 'LOADING';
|
||||
lastErrorEvent: WebViewError | null;
|
||||
}
|
||||
interface ErrorState extends BaseState {
|
||||
viewState: 'ERROR';
|
||||
lastErrorEvent: WebViewError;
|
||||
}
|
||||
export declare type State = NormalState | ErrorState;
|
||||
declare class NativeWebViewIOSComponent extends Component<IOSNativeWebViewProps> {
|
||||
}
|
||||
declare const NativeWebViewIOSBase: Constructor<NativeMethodsMixin> & typeof NativeWebViewIOSComponent;
|
||||
export declare class NativeWebViewIOS extends NativeWebViewIOSBase {
|
||||
}
|
||||
declare class NativeWebViewMacOSComponent extends Component<MacOSNativeWebViewProps> {
|
||||
}
|
||||
declare const NativeWebViewMacOSBase: Constructor<NativeMethodsMixin> & typeof NativeWebViewMacOSComponent;
|
||||
export declare class NativeWebViewMacOS extends NativeWebViewMacOSBase {
|
||||
}
|
||||
declare class NativeWebViewAndroidComponent extends Component<AndroidNativeWebViewProps> {
|
||||
}
|
||||
declare const NativeWebViewAndroidBase: Constructor<NativeMethodsMixin> & typeof NativeWebViewAndroidComponent;
|
||||
export declare class NativeWebViewAndroid extends NativeWebViewAndroidBase {
|
||||
}
|
||||
declare class NativeWebViewWindowsComponent extends Component<WindowsNativeWebViewProps> {
|
||||
}
|
||||
declare const NativeWebViewWindowsBase: Constructor<NativeMethodsMixin> & typeof NativeWebViewWindowsComponent;
|
||||
export declare class NativeWebViewWindows extends NativeWebViewWindowsBase {
|
||||
}
|
||||
export interface ContentInsetProp {
|
||||
top?: number;
|
||||
left?: number;
|
||||
bottom?: number;
|
||||
right?: number;
|
||||
}
|
||||
export interface WebViewNativeEvent {
|
||||
url: string;
|
||||
loading: boolean;
|
||||
title: string;
|
||||
canGoBack: boolean;
|
||||
canGoForward: boolean;
|
||||
lockIdentifier: number;
|
||||
}
|
||||
export interface WebViewNativeProgressEvent extends WebViewNativeEvent {
|
||||
progress: number;
|
||||
}
|
||||
export interface WebViewNativePermissionEvent extends WebViewNativeEvent {
|
||||
resources: string[];
|
||||
}
|
||||
export interface WebViewNavigation extends WebViewNativeEvent {
|
||||
navigationType: 'click' | 'formsubmit' | 'backforward' | 'reload' | 'formresubmit' | 'other';
|
||||
mainDocumentURL?: string;
|
||||
}
|
||||
export interface ShouldStartLoadRequest extends WebViewNavigation {
|
||||
isTopFrame: boolean;
|
||||
}
|
||||
export interface FileDownload {
|
||||
downloadUrl: string;
|
||||
}
|
||||
export declare type DecelerationRateConstant = 'normal' | 'fast';
|
||||
export interface WebViewMessage extends WebViewNativeEvent {
|
||||
data: string;
|
||||
}
|
||||
export interface WebViewError extends WebViewNativeEvent {
|
||||
/**
|
||||
* `domain` is only used on iOS and macOS
|
||||
*/
|
||||
domain?: string;
|
||||
code: number;
|
||||
description: string;
|
||||
}
|
||||
export interface WebViewHttpError extends WebViewNativeEvent {
|
||||
description: string;
|
||||
statusCode: number;
|
||||
}
|
||||
export interface WebViewRenderProcessGoneDetail {
|
||||
didCrash: boolean;
|
||||
}
|
||||
export declare type WebViewEvent = NativeSyntheticEvent<WebViewNativeEvent>;
|
||||
export declare type WebViewProgressEvent = NativeSyntheticEvent<WebViewNativeProgressEvent>;
|
||||
export declare type WebViewPermissionEvent = NativeSyntheticEvent<WebViewNativePermissionEvent>;
|
||||
export declare type WebViewNavigationEvent = NativeSyntheticEvent<WebViewNavigation>;
|
||||
export declare type ShouldStartLoadRequestEvent = NativeSyntheticEvent<ShouldStartLoadRequest>;
|
||||
export declare type FileDownloadEvent = NativeSyntheticEvent<FileDownload>;
|
||||
export declare type WebViewMessageEvent = NativeSyntheticEvent<WebViewMessage>;
|
||||
export declare type WebViewErrorEvent = NativeSyntheticEvent<WebViewError>;
|
||||
export declare type WebViewTerminatedEvent = NativeSyntheticEvent<WebViewNativeEvent>;
|
||||
export declare type WebViewHttpErrorEvent = NativeSyntheticEvent<WebViewHttpError>;
|
||||
export declare type WebViewRenderProcessGoneEvent = NativeSyntheticEvent<WebViewRenderProcessGoneDetail>;
|
||||
export declare type DataDetectorTypes = 'phoneNumber' | 'link' | 'address' | 'calendarEvent' | 'trackingNumber' | 'flightNumber' | 'lookupSuggestion' | 'none' | 'all';
|
||||
export declare type OverScrollModeType = 'always' | 'content' | 'never';
|
||||
export declare type CacheMode = 'LOAD_DEFAULT' | 'LOAD_CACHE_ONLY' | 'LOAD_CACHE_ELSE_NETWORK' | 'LOAD_NO_CACHE';
|
||||
export declare type AndroidLayerType = 'none' | 'software' | 'hardware';
|
||||
export interface WebViewSourceUri {
|
||||
/**
|
||||
* The URI to load in the `WebView`. Can be a local or remote file.
|
||||
*/
|
||||
uri: string;
|
||||
/**
|
||||
* The HTTP Method to use. Defaults to GET if not specified.
|
||||
* NOTE: On Android, only GET and POST are supported.
|
||||
*/
|
||||
method?: string;
|
||||
/**
|
||||
* Additional HTTP headers to send with the request.
|
||||
* NOTE: On Android, this can only be used with GET requests.
|
||||
*/
|
||||
headers?: Object;
|
||||
/**
|
||||
* The HTTP body to send with the request. This must be a valid
|
||||
* UTF-8 string, and will be sent exactly as specified, with no
|
||||
* additional encoding (e.g. URL-escaping or base64) applied.
|
||||
* NOTE: On Android, this can only be used with POST requests.
|
||||
*/
|
||||
body?: string;
|
||||
}
|
||||
export interface WebViewSourceHtml {
|
||||
/**
|
||||
* A static HTML page to display in the WebView.
|
||||
*/
|
||||
html: string;
|
||||
/**
|
||||
* The base URL to be used for any relative links in the HTML.
|
||||
*/
|
||||
baseUrl?: string;
|
||||
}
|
||||
export declare type WebViewSource = WebViewSourceUri | WebViewSourceHtml;
|
||||
export interface ViewManager {
|
||||
startLoadWithResult: Function;
|
||||
}
|
||||
export interface WebViewNativeConfig {
|
||||
/**
|
||||
* The native component used to render the WebView.
|
||||
*/
|
||||
component?: typeof NativeWebViewIOS | typeof NativeWebViewMacOS | typeof NativeWebViewAndroid;
|
||||
/**
|
||||
* Set props directly on the native component WebView. Enables custom props which the
|
||||
* original WebView doesn't pass through.
|
||||
*/
|
||||
props?: Object;
|
||||
/**
|
||||
* Set the ViewManager to use for communication with the native side.
|
||||
* @platform ios, macos
|
||||
*/
|
||||
viewManager?: ViewManager;
|
||||
}
|
||||
export declare type OnShouldStartLoadWithRequest = (event: ShouldStartLoadRequest) => boolean;
|
||||
export interface CommonNativeWebViewProps extends ViewProps {
|
||||
cacheEnabled?: boolean;
|
||||
incognito?: boolean;
|
||||
injectedJavaScript?: string;
|
||||
injectedJavaScriptBeforeContentLoaded?: string;
|
||||
injectedJavaScriptForMainFrameOnly?: boolean;
|
||||
injectedJavaScriptBeforeContentLoadedForMainFrameOnly?: boolean;
|
||||
javaScriptCanOpenWindowsAutomatically?: boolean;
|
||||
mediaPlaybackRequiresUserAction?: boolean;
|
||||
messagingEnabled: boolean;
|
||||
onScroll?: (event: NativeScrollEvent) => void;
|
||||
onLoadingError: (event: WebViewErrorEvent) => void;
|
||||
onLoadingFinish: (event: WebViewNavigationEvent) => void;
|
||||
onLoadingProgress: (event: WebViewProgressEvent) => void;
|
||||
onLoadingStart: (event: WebViewNavigationEvent) => void;
|
||||
onHttpError: (event: WebViewHttpErrorEvent) => void;
|
||||
onMessage: (event: WebViewMessageEvent) => void;
|
||||
onShouldStartLoadWithRequest: (event: ShouldStartLoadRequestEvent) => void;
|
||||
showsHorizontalScrollIndicator?: boolean;
|
||||
showsVerticalScrollIndicator?: boolean;
|
||||
source: any;
|
||||
userAgent?: string;
|
||||
/**
|
||||
* Append to the existing user-agent. Overridden if `userAgent` is set.
|
||||
*/
|
||||
applicationNameForUserAgent?: string;
|
||||
}
|
||||
export interface AndroidNativeWebViewProps extends CommonNativeWebViewProps {
|
||||
cacheMode?: CacheMode;
|
||||
allowFileAccess?: boolean;
|
||||
scalesPageToFit?: boolean;
|
||||
allowFileAccessFromFileURLs?: boolean;
|
||||
allowUniversalAccessFromFileURLs?: boolean;
|
||||
androidHardwareAccelerationDisabled?: boolean;
|
||||
androidLayerType?: AndroidLayerType;
|
||||
domStorageEnabled?: boolean;
|
||||
geolocationEnabled?: boolean;
|
||||
javaScriptEnabled?: boolean;
|
||||
mixedContentMode?: 'never' | 'always' | 'compatibility';
|
||||
onContentSizeChange?: (event: WebViewEvent) => void;
|
||||
onPermissionRequest?: (event: WebViewPermissionEvent) => void;
|
||||
onRenderProcessGone?: (event: WebViewRenderProcessGoneEvent) => void;
|
||||
overScrollMode?: OverScrollModeType;
|
||||
saveFormDataDisabled?: boolean;
|
||||
textZoom?: number;
|
||||
thirdPartyCookiesEnabled?: boolean;
|
||||
messagingModuleName?: string;
|
||||
readonly urlPrefixesForDefaultIntent?: string[];
|
||||
}
|
||||
export declare type ContentInsetAdjustmentBehavior = 'automatic' | 'scrollableAxes' | 'never' | 'always';
|
||||
export declare type ContentMode = 'recommended' | 'mobile' | 'desktop';
|
||||
export interface IOSNativeWebViewProps extends CommonNativeWebViewProps {
|
||||
allowingReadAccessToURL?: string;
|
||||
allowsBackForwardNavigationGestures?: boolean;
|
||||
allowsInlineMediaPlayback?: boolean;
|
||||
allowsLinkPreview?: boolean;
|
||||
automaticallyAdjustContentInsets?: boolean;
|
||||
autoManageStatusBarEnabled?: boolean;
|
||||
bounces?: boolean;
|
||||
contentInset?: ContentInsetProp;
|
||||
contentInsetAdjustmentBehavior?: ContentInsetAdjustmentBehavior;
|
||||
contentMode?: ContentMode;
|
||||
readonly dataDetectorTypes?: DataDetectorTypes | DataDetectorTypes[];
|
||||
decelerationRate?: number;
|
||||
directionalLockEnabled?: boolean;
|
||||
hideKeyboardAccessoryView?: boolean;
|
||||
pagingEnabled?: boolean;
|
||||
scrollEnabled?: boolean;
|
||||
useSharedProcessPool?: boolean;
|
||||
onContentProcessDidTerminate?: (event: WebViewTerminatedEvent) => void;
|
||||
injectedJavaScriptForMainFrameOnly?: boolean;
|
||||
injectedJavaScriptBeforeContentLoadedForMainFrameOnly?: boolean;
|
||||
onFileDownload?: (event: FileDownloadEvent) => void;
|
||||
}
|
||||
export interface MacOSNativeWebViewProps extends CommonNativeWebViewProps {
|
||||
allowingReadAccessToURL?: string;
|
||||
allowsBackForwardNavigationGestures?: boolean;
|
||||
allowsInlineMediaPlayback?: boolean;
|
||||
allowsLinkPreview?: boolean;
|
||||
automaticallyAdjustContentInsets?: boolean;
|
||||
bounces?: boolean;
|
||||
contentInset?: ContentInsetProp;
|
||||
contentInsetAdjustmentBehavior?: ContentInsetAdjustmentBehavior;
|
||||
directionalLockEnabled?: boolean;
|
||||
hideKeyboardAccessoryView?: boolean;
|
||||
pagingEnabled?: boolean;
|
||||
scrollEnabled?: boolean;
|
||||
useSharedProcessPool?: boolean;
|
||||
onContentProcessDidTerminate?: (event: WebViewTerminatedEvent) => void;
|
||||
}
|
||||
export interface WindowsNativeWebViewProps extends CommonNativeWebViewProps {
|
||||
testID?: string;
|
||||
}
|
||||
export interface IOSWebViewProps extends WebViewSharedProps {
|
||||
/**
|
||||
* Does not store any data within the lifetime of the WebView.
|
||||
*/
|
||||
incognito?: boolean;
|
||||
/**
|
||||
* Boolean value that determines whether the web view bounces
|
||||
* when it reaches the edge of the content. The default value is `true`.
|
||||
* @platform ios
|
||||
*/
|
||||
bounces?: boolean;
|
||||
/**
|
||||
* A floating-point number that determines how quickly the scroll view
|
||||
* decelerates after the user lifts their finger. You may also use the
|
||||
* string shortcuts `"normal"` and `"fast"` which match the underlying iOS
|
||||
* settings for `UIScrollViewDecelerationRateNormal` and
|
||||
* `UIScrollViewDecelerationRateFast` respectively:
|
||||
*
|
||||
* - normal: 0.998
|
||||
* - fast: 0.99 (the default for iOS web view)
|
||||
* @platform ios
|
||||
*/
|
||||
decelerationRate?: DecelerationRateConstant | number;
|
||||
/**
|
||||
* Boolean value that determines whether scrolling is enabled in the
|
||||
* `WebView`. The default value is `true`.
|
||||
* @platform ios
|
||||
*/
|
||||
scrollEnabled?: boolean;
|
||||
/**
|
||||
* If the value of this property is true, the scroll view stops on multiples
|
||||
* of the scroll view’s bounds when the user scrolls.
|
||||
* The default value is false.
|
||||
* @platform ios
|
||||
*/
|
||||
pagingEnabled?: boolean;
|
||||
/**
|
||||
* Controls whether to adjust the content inset for web views that are
|
||||
* placed behind a navigation bar, tab bar, or toolbar. The default value
|
||||
* is `true`.
|
||||
* @platform ios
|
||||
*/
|
||||
automaticallyAdjustContentInsets?: boolean;
|
||||
/**
|
||||
* This property specifies how the safe area insets are used to modify the
|
||||
* content area of the scroll view. The default value of this property is
|
||||
* "never". Available on iOS 11 and later.
|
||||
*/
|
||||
contentInsetAdjustmentBehavior?: ContentInsetAdjustmentBehavior;
|
||||
/**
|
||||
* The amount by which the web view content is inset from the edges of
|
||||
* the scroll view. Defaults to {top: 0, left: 0, bottom: 0, right: 0}.
|
||||
* @platform ios
|
||||
*/
|
||||
contentInset?: ContentInsetProp;
|
||||
/**
|
||||
* Defaults to `recommended`, which loads mobile content on iPhone
|
||||
* and iPad Mini but desktop content on other iPads.
|
||||
*
|
||||
* Possible values are:
|
||||
* - `'recommended'`
|
||||
* - `'mobile'`
|
||||
* - `'desktop'`
|
||||
* @platform ios
|
||||
*/
|
||||
contentMode?: ContentMode;
|
||||
/**
|
||||
* Determines the types of data converted to clickable URLs in the web view's content.
|
||||
* By default only phone numbers are detected.
|
||||
*
|
||||
* You can provide one type or an array of many types.
|
||||
*
|
||||
* Possible values for `dataDetectorTypes` are:
|
||||
*
|
||||
* - `'phoneNumber'`
|
||||
* - `'link'`
|
||||
* - `'address'`
|
||||
* - `'calendarEvent'`
|
||||
* - `'none'`
|
||||
* - `'all'`
|
||||
*
|
||||
* With the new WebKit implementation, we have three new values:
|
||||
* - `'trackingNumber'`,
|
||||
* - `'flightNumber'`,
|
||||
* - `'lookupSuggestion'`,
|
||||
*
|
||||
* @platform ios
|
||||
*/
|
||||
readonly dataDetectorTypes?: DataDetectorTypes | DataDetectorTypes[];
|
||||
/**
|
||||
* Boolean that determines whether HTML5 videos play inline or use the
|
||||
* native full-screen controller. The default value is `false`.
|
||||
*
|
||||
* **NOTE** : In order for video to play inline, not only does this
|
||||
* property need to be set to `true`, but the video element in the HTML
|
||||
* document must also include the `webkit-playsinline` attribute.
|
||||
* @platform ios
|
||||
*/
|
||||
allowsInlineMediaPlayback?: boolean;
|
||||
/**
|
||||
* Hide the accessory view when the keyboard is open. Default is false to be
|
||||
* backward compatible.
|
||||
*/
|
||||
hideKeyboardAccessoryView?: boolean;
|
||||
/**
|
||||
* A Boolean value indicating whether horizontal swipe gestures will trigger
|
||||
* back-forward list navigations.
|
||||
*/
|
||||
allowsBackForwardNavigationGestures?: boolean;
|
||||
/**
|
||||
* A Boolean value indicating whether WebKit WebView should be created using a shared
|
||||
* process pool, enabling WebViews to share cookies and localStorage between each other.
|
||||
* Default is true but can be set to false for backwards compatibility.
|
||||
* @platform ios
|
||||
*/
|
||||
useSharedProcessPool?: boolean;
|
||||
/**
|
||||
* The custom user agent string.
|
||||
*/
|
||||
userAgent?: string;
|
||||
/**
|
||||
* A Boolean value that determines whether pressing on a link
|
||||
* displays a preview of the destination for the link.
|
||||
*
|
||||
* 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`.
|
||||
* @platform ios
|
||||
*/
|
||||
allowsLinkPreview?: boolean;
|
||||
/**
|
||||
* Set true if shared cookies from HTTPCookieStorage should used for every load request.
|
||||
* The default value is `false`.
|
||||
* @platform ios
|
||||
*/
|
||||
sharedCookiesEnabled?: boolean;
|
||||
/**
|
||||
* Set true if StatusBar should be light when user watch video fullscreen.
|
||||
* The default value is `true`.
|
||||
* @platform ios
|
||||
*/
|
||||
autoManageStatusBarEnabled?: boolean;
|
||||
/**
|
||||
* A Boolean value that determines whether scrolling is disabled in a particular direction.
|
||||
* The default value is `true`.
|
||||
* @platform ios
|
||||
*/
|
||||
directionalLockEnabled?: boolean;
|
||||
/**
|
||||
* A Boolean value indicating whether web content can programmatically display the keyboard.
|
||||
*
|
||||
* When this property is set to true, the user must explicitly tap the elements in the
|
||||
* web view to display the keyboard (or other relevant input view) for that element.
|
||||
* When set to false, a focus event on an element causes the input view to be displayed
|
||||
* and associated with that element automatically.
|
||||
*
|
||||
* The default value is `true`.
|
||||
* @platform ios
|
||||
*/
|
||||
keyboardDisplayRequiresUserAction?: boolean;
|
||||
/**
|
||||
* A String value that indicates which URLs the WebView's file can then
|
||||
* reference in scripts, AJAX requests, and CSS imports. This is only used
|
||||
* for WebViews that are loaded with a source.uri set to a `'file://'` URL.
|
||||
*
|
||||
* If not provided, the default is to only allow read access to the URL
|
||||
* provided in source.uri itself.
|
||||
* @platform ios
|
||||
*/
|
||||
allowingReadAccessToURL?: string;
|
||||
/**
|
||||
* Function that is invoked when the WebKit WebView content process gets terminated.
|
||||
* @platform ios
|
||||
*/
|
||||
onContentProcessDidTerminate?: (event: WebViewTerminatedEvent) => void;
|
||||
/**
|
||||
* If `true` (default), loads the `injectedJavaScript` only into the main frame.
|
||||
* If `false`, loads it into all frames (e.g. iframes).
|
||||
* @platform ios
|
||||
*/
|
||||
injectedJavaScriptForMainFrameOnly?: boolean;
|
||||
/**
|
||||
* If `true` (default), loads the `injectedJavaScriptBeforeContentLoaded` only into the main frame.
|
||||
* If `false`, loads it into all frames (e.g. iframes).
|
||||
* @platform ios
|
||||
*/
|
||||
injectedJavaScriptBeforeContentLoadedForMainFrameOnly?: boolean;
|
||||
/**
|
||||
* Boolean value that determines whether a pull to refresh gesture is
|
||||
* available in the `WebView`. The default value is `false`.
|
||||
* If `true`, sets `bounces` automatically to `true`
|
||||
* @platform ios
|
||||
*
|
||||
*/
|
||||
pullToRefreshEnabled?: boolean;
|
||||
/**
|
||||
* Function that is invoked when the client needs to download a file.
|
||||
*
|
||||
* iOS 13+ only: If the webview navigates to a URL that results in an HTTP
|
||||
* response with a Content-Disposition header 'attachment...', then
|
||||
* this will be called.
|
||||
*
|
||||
* iOS 8+: If the MIME type indicates that the content is not renderable by the
|
||||
* webview, that will also cause this to be called. On iOS versions before 13,
|
||||
* this is the only condition that will cause this function to be called.
|
||||
*
|
||||
* The application will need to provide its own code to actually download
|
||||
* the file.
|
||||
*
|
||||
* If not provided, the default is to let the webview try to render the file.
|
||||
*/
|
||||
onFileDownload?: (event: FileDownloadEvent) => void;
|
||||
}
|
||||
export interface MacOSWebViewProps extends WebViewSharedProps {
|
||||
/**
|
||||
* Does not store any data within the lifetime of the WebView.
|
||||
*/
|
||||
incognito?: boolean;
|
||||
/**
|
||||
* Boolean value that determines whether the web view bounces
|
||||
* when it reaches the edge of the content. The default value is `true`.
|
||||
* @platform macos
|
||||
*/
|
||||
bounces?: boolean;
|
||||
/**
|
||||
* Boolean value that determines whether scrolling is enabled in the
|
||||
* `WebView`. The default value is `true`.
|
||||
* @platform macos
|
||||
*/
|
||||
scrollEnabled?: boolean;
|
||||
/**
|
||||
* If the value of this property is true, the scroll view stops on multiples
|
||||
* of the scroll view’s bounds when the user scrolls.
|
||||
* The default value is false.
|
||||
* @platform macos
|
||||
*/
|
||||
pagingEnabled?: boolean;
|
||||
/**
|
||||
* Controls whether to adjust the content inset for web views that are
|
||||
* placed behind a navigation bar, tab bar, or toolbar. The default value
|
||||
* is `true`.
|
||||
* @platform macos
|
||||
*/
|
||||
automaticallyAdjustContentInsets?: boolean;
|
||||
/**
|
||||
* This property specifies how the safe area insets are used to modify the
|
||||
* content area of the scroll view. The default value of this property is
|
||||
* "never". Available on iOS 11 and later.
|
||||
*/
|
||||
contentInsetAdjustmentBehavior?: ContentInsetAdjustmentBehavior;
|
||||
/**
|
||||
* The amount by which the web view content is inset from the edges of
|
||||
* the scroll view. Defaults to {top: 0, left: 0, bottom: 0, right: 0}.
|
||||
* @platform macos
|
||||
*/
|
||||
contentInset?: ContentInsetProp;
|
||||
/**
|
||||
* Boolean that determines whether HTML5 videos play inline or use the
|
||||
* native full-screen controller. The default value is `false`.
|
||||
*
|
||||
* **NOTE** : In order for video to play inline, not only does this
|
||||
* property need to be set to `true`, but the video element in the HTML
|
||||
* document must also include the `webkit-playsinline` attribute.
|
||||
* @platform macos
|
||||
*/
|
||||
allowsInlineMediaPlayback?: boolean;
|
||||
/**
|
||||
* Hide the accessory view when the keyboard is open. Default is false to be
|
||||
* backward compatible.
|
||||
*/
|
||||
hideKeyboardAccessoryView?: boolean;
|
||||
/**
|
||||
* A Boolean value indicating whether horizontal swipe gestures will trigger
|
||||
* back-forward list navigations.
|
||||
*/
|
||||
allowsBackForwardNavigationGestures?: boolean;
|
||||
/**
|
||||
* A Boolean value indicating whether WebKit WebView should be created using a shared
|
||||
* process pool, enabling WebViews to share cookies and localStorage between each other.
|
||||
* Default is true but can be set to false for backwards compatibility.
|
||||
* @platform macos
|
||||
*/
|
||||
useSharedProcessPool?: boolean;
|
||||
/**
|
||||
* The custom user agent string.
|
||||
*/
|
||||
userAgent?: string;
|
||||
/**
|
||||
* A Boolean value that determines whether pressing on a link
|
||||
* displays a preview of the destination for the link.
|
||||
*
|
||||
* This property is available on devices that support Force Touch trackpad.
|
||||
* @platform macos
|
||||
*/
|
||||
allowsLinkPreview?: boolean;
|
||||
/**
|
||||
* Set true if shared cookies from HTTPCookieStorage should used for every load request.
|
||||
* The default value is `false`.
|
||||
* @platform macos
|
||||
*/
|
||||
sharedCookiesEnabled?: boolean;
|
||||
/**
|
||||
* A Boolean value that determines whether scrolling is disabled in a particular direction.
|
||||
* The default value is `true`.
|
||||
* @platform macos
|
||||
*/
|
||||
directionalLockEnabled?: boolean;
|
||||
/**
|
||||
* A Boolean value indicating whether web content can programmatically display the keyboard.
|
||||
*
|
||||
* When this property is set to true, the user must explicitly tap the elements in the
|
||||
* web view to display the keyboard (or other relevant input view) for that element.
|
||||
* When set to false, a focus event on an element causes the input view to be displayed
|
||||
* and associated with that element automatically.
|
||||
*
|
||||
* The default value is `true`.
|
||||
* @platform macos
|
||||
*/
|
||||
keyboardDisplayRequiresUserAction?: boolean;
|
||||
/**
|
||||
* A String value that indicates which URLs the WebView's file can then
|
||||
* reference in scripts, AJAX requests, and CSS imports. This is only used
|
||||
* for WebViews that are loaded with a source.uri set to a `'file://'` URL.
|
||||
*
|
||||
* If not provided, the default is to only allow read access to the URL
|
||||
* provided in source.uri itself.
|
||||
* @platform macos
|
||||
*/
|
||||
allowingReadAccessToURL?: string;
|
||||
/**
|
||||
* Function that is invoked when the WebKit WebView content process gets terminated.
|
||||
* @platform macos
|
||||
*/
|
||||
onContentProcessDidTerminate?: (event: WebViewTerminatedEvent) => void;
|
||||
}
|
||||
export interface AndroidWebViewProps extends WebViewSharedProps {
|
||||
onNavigationStateChange?: (event: WebViewNavigation) => void;
|
||||
onContentSizeChange?: (event: WebViewEvent) => void;
|
||||
onPermissionRequest?: (event: WebViewPermissionEvent) => void;
|
||||
/**
|
||||
* Function that is invoked when the `WebView` process crashes or is killed by the OS.
|
||||
* Works only on Android (minimum API level 26).
|
||||
*/
|
||||
onRenderProcessGone?: (event: WebViewRenderProcessGoneEvent) => void;
|
||||
/**
|
||||
* https://developer.android.com/reference/android/webkit/WebSettings.html#setCacheMode(int)
|
||||
* Set the cacheMode. Possible values are:
|
||||
*
|
||||
* - `'LOAD_DEFAULT'` (default)
|
||||
* - `'LOAD_CACHE_ELSE_NETWORK'`
|
||||
* - `'LOAD_NO_CACHE'`
|
||||
* - `'LOAD_CACHE_ONLY'`
|
||||
*
|
||||
* @platform android
|
||||
*/
|
||||
cacheMode?: CacheMode;
|
||||
/**
|
||||
* https://developer.android.com/reference/android/view/View#OVER_SCROLL_NEVER
|
||||
* Sets the overScrollMode. Possible values are:
|
||||
*
|
||||
* - `'always'` (default)
|
||||
* - `'content'`
|
||||
* - `'never'`
|
||||
*
|
||||
* @platform android
|
||||
*/
|
||||
overScrollMode?: OverScrollModeType;
|
||||
/**
|
||||
* Boolean that controls whether the web content is scaled to fit
|
||||
* the view and enables the user to change the scale. The default value
|
||||
* is `true`.
|
||||
*/
|
||||
scalesPageToFit?: boolean;
|
||||
/**
|
||||
* Sets whether Geolocation is enabled. The default is false.
|
||||
* @platform android
|
||||
*/
|
||||
geolocationEnabled?: boolean;
|
||||
/**
|
||||
* 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.
|
||||
* Including accessing content from other file scheme URLs
|
||||
* @platform android
|
||||
*/
|
||||
allowFileAccessFromFileURLs?: boolean;
|
||||
/**
|
||||
* Boolean that sets whether JavaScript running in the context of a file
|
||||
* scheme URL should be allowed to access content from any origin.
|
||||
* Including accessing content from other file scheme URLs
|
||||
* @platform android
|
||||
*/
|
||||
allowUniversalAccessFromFileURLs?: boolean;
|
||||
/**
|
||||
* Sets whether the webview allow access to file system.
|
||||
* @platform android
|
||||
*/
|
||||
allowFileAccess?: boolean;
|
||||
/**
|
||||
* Used on Android only, controls whether form autocomplete data should be saved
|
||||
* @platform android
|
||||
*/
|
||||
saveFormDataDisabled?: boolean;
|
||||
/**
|
||||
* Used on Android only, controls whether the given list of URL prefixes should
|
||||
* make {@link com.facebook.react.views.webview.ReactWebViewClient} to launch a
|
||||
* default activity intent for those URL instead of loading it within the webview.
|
||||
* Use this to list URLs that WebView cannot handle, e.g. a PDF url.
|
||||
* @platform android
|
||||
*/
|
||||
readonly urlPrefixesForDefaultIntent?: string[];
|
||||
/**
|
||||
* Boolean value to disable Hardware Acceleration in the `WebView`. Used on Android only
|
||||
* as Hardware Acceleration is a feature only for Android. The default value is `false`.
|
||||
* @platform android
|
||||
*/
|
||||
androidHardwareAccelerationDisabled?: boolean;
|
||||
/**
|
||||
* https://developer.android.com/reference/android/webkit/WebView#setLayerType(int,%20android.graphics.Paint)
|
||||
* Sets the layerType. Possible values are:
|
||||
*
|
||||
* - `'none'` (default)
|
||||
* - `'software'`
|
||||
* - `'hardware'`
|
||||
*
|
||||
* @platform android
|
||||
*/
|
||||
androidLayerType?: AndroidLayerType;
|
||||
/**
|
||||
* Boolean value to enable third party cookies in the `WebView`. Used on
|
||||
* Android Lollipop and above only as third party cookies are enabled by
|
||||
* default on Android Kitkat and below and on iOS. The default value is `true`.
|
||||
* @platform android
|
||||
*/
|
||||
thirdPartyCookiesEnabled?: boolean;
|
||||
/**
|
||||
* Boolean value to control whether DOM Storage is enabled. Used only in
|
||||
* Android.
|
||||
* @platform android
|
||||
*/
|
||||
domStorageEnabled?: boolean;
|
||||
/**
|
||||
* Sets the user-agent for the `WebView`.
|
||||
* @platform android
|
||||
*/
|
||||
userAgent?: string;
|
||||
/**
|
||||
* Sets number that controls text zoom of the page in percent.
|
||||
* @platform android
|
||||
*/
|
||||
textZoom?: number;
|
||||
/**
|
||||
* Specifies the mixed content mode. i.e WebView will allow a secure origin to load content from any other origin.
|
||||
*
|
||||
* Possible values for `mixedContentMode` are:
|
||||
*
|
||||
* - `'never'` (default) - WebView will not allow a secure origin to load content from an insecure origin.
|
||||
* - `'always'` - WebView will allow a secure origin to load content from any other origin, even if that origin is insecure.
|
||||
* - `'compatibility'` - WebView will attempt to be compatible with the approach of a modern web browser with regard to mixed content.
|
||||
* @platform android
|
||||
*/
|
||||
mixedContentMode?: 'never' | 'always' | 'compatibility';
|
||||
/**
|
||||
* Sets ability to open fullscreen videos on Android devices.
|
||||
*/
|
||||
allowsFullscreenVideo?: boolean;
|
||||
}
|
||||
export interface WebViewSharedProps extends ViewProps {
|
||||
/**
|
||||
* Loads static html or a uri (with optional headers) in the WebView.
|
||||
*/
|
||||
source?: WebViewSource;
|
||||
/**
|
||||
* Boolean value to enable JavaScript in the `WebView`. Used on Android only
|
||||
* as JavaScript is enabled by default on iOS. The default value is `true`.
|
||||
* @platform android
|
||||
*/
|
||||
javaScriptEnabled?: boolean;
|
||||
/**
|
||||
* A Boolean value indicating whether JavaScript can open windows without user interaction.
|
||||
* The default value is `false`.
|
||||
*/
|
||||
javaScriptCanOpenWindowsAutomatically?: boolean;
|
||||
/**
|
||||
* Stylesheet object to set the style of the container view.
|
||||
*/
|
||||
containerStyle?: StyleProp<ViewStyle>;
|
||||
/**
|
||||
* Function that returns a view to show if there's an error.
|
||||
*/
|
||||
renderError?: (errorDomain: string | undefined, errorCode: number, errorDesc: string) => ReactElement;
|
||||
/**
|
||||
* Function that returns a loading indicator.
|
||||
*/
|
||||
renderLoading?: () => ReactElement;
|
||||
/**
|
||||
* Function that is invoked when the `WebView` scrolls.
|
||||
*/
|
||||
onScroll?: (event: NativeScrollEvent) => void;
|
||||
/**
|
||||
* Function that is invoked when the `WebView` has finished loading.
|
||||
*/
|
||||
onLoad?: (event: WebViewNavigationEvent) => void;
|
||||
/**
|
||||
* Function that is invoked when the `WebView` load succeeds or fails.
|
||||
*/
|
||||
onLoadEnd?: (event: WebViewNavigationEvent | WebViewErrorEvent) => void;
|
||||
/**
|
||||
* Function that is invoked when the `WebView` starts loading.
|
||||
*/
|
||||
onLoadStart?: (event: WebViewNavigationEvent) => void;
|
||||
/**
|
||||
* Function that is invoked when the `WebView` load fails.
|
||||
*/
|
||||
onError?: (event: WebViewErrorEvent) => void;
|
||||
/**
|
||||
* Function that is invoked when the `WebView` receives an error status code.
|
||||
* Works on iOS and Android (minimum API level 23).
|
||||
*/
|
||||
onHttpError?: (event: WebViewHttpErrorEvent) => void;
|
||||
/**
|
||||
* Function that is invoked when the `WebView` loading starts or ends.
|
||||
*/
|
||||
onNavigationStateChange?: (event: WebViewNavigation) => void;
|
||||
/**
|
||||
* Function that is invoked when the webview calls `window.ReactNativeWebView.postMessage`.
|
||||
* Setting this property will inject this global into your webview.
|
||||
*
|
||||
* `window.ReactNativeWebView.postMessage` accepts one argument, `data`, which will be
|
||||
* available on the event object, `event.nativeEvent.data`. `data` must be a string.
|
||||
*/
|
||||
onMessage?: (event: WebViewMessageEvent) => void;
|
||||
/**
|
||||
* Function that is invoked when the `WebView` is loading.
|
||||
*/
|
||||
onLoadProgress?: (event: WebViewProgressEvent) => void;
|
||||
/**
|
||||
* Boolean value that forces the `WebView` to show the loading view
|
||||
* on the first load.
|
||||
*/
|
||||
startInLoadingState?: boolean;
|
||||
/**
|
||||
* Set this to provide JavaScript that will be injected into the web page
|
||||
* when the view loads.
|
||||
*/
|
||||
injectedJavaScript?: string;
|
||||
/**
|
||||
* Set this to provide JavaScript that will be injected into the web page
|
||||
* once the webview is initialized but before the view loads any content.
|
||||
*/
|
||||
injectedJavaScriptBeforeContentLoaded?: string;
|
||||
/**
|
||||
* If `true` (default; mandatory for Android), loads the `injectedJavaScript` only into the main frame.
|
||||
* If `false` (only supported on iOS and macOS), loads it into all frames (e.g. iframes).
|
||||
*/
|
||||
injectedJavaScriptForMainFrameOnly?: boolean;
|
||||
/**
|
||||
* If `true` (default; mandatory for Android), loads the `injectedJavaScriptBeforeContentLoaded` only into the main frame.
|
||||
* If `false` (only supported on iOS and macOS), loads it into all frames (e.g. iframes).
|
||||
*/
|
||||
injectedJavaScriptBeforeContentLoadedForMainFrameOnly?: boolean;
|
||||
/**
|
||||
* Boolean value that determines whether a horizontal scroll indicator is
|
||||
* shown in the `WebView`. The default value is `true`.
|
||||
*/
|
||||
showsHorizontalScrollIndicator?: boolean;
|
||||
/**
|
||||
* Boolean value that determines whether a vertical scroll indicator is
|
||||
* shown in the `WebView`. The default value is `true`.
|
||||
*/
|
||||
showsVerticalScrollIndicator?: boolean;
|
||||
/**
|
||||
* Boolean that determines whether HTML5 audio and video requires the user
|
||||
* to tap them before they start playing. The default value is `true`.
|
||||
*/
|
||||
mediaPlaybackRequiresUserAction?: boolean;
|
||||
/**
|
||||
* 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, we will open the URL in Safari.
|
||||
* The default whitelisted origins are "http://*" and "https://*".
|
||||
*/
|
||||
readonly originWhitelist?: string[];
|
||||
/**
|
||||
* Function that allows custom handling of any web view requests. Return
|
||||
* `true` from the function to continue loading the request and `false`
|
||||
* to stop loading. The `navigationType` is always `other` on android.
|
||||
*/
|
||||
onShouldStartLoadWithRequest?: OnShouldStartLoadWithRequest;
|
||||
/**
|
||||
* Override the native component used to render the WebView. Enables a custom native
|
||||
* WebView which uses the same JavaScript as the original WebView.
|
||||
*/
|
||||
nativeConfig?: WebViewNativeConfig;
|
||||
/**
|
||||
* Should caching be enabled. Default is true.
|
||||
*/
|
||||
cacheEnabled?: boolean;
|
||||
/**
|
||||
* Append to the existing user-agent. Overridden if `userAgent` is set.
|
||||
*/
|
||||
applicationNameForUserAgent?: string;
|
||||
}
|
||||
export {};
|
||||
//# sourceMappingURL=WebViewTypes.d.ts.map
|
1
lib/WebViewTypes.d.ts.map
Normal file
1
lib/WebViewTypes.d.ts.map
Normal file
File diff suppressed because one or more lines are too long
47
lib/WebViewTypes.js
Normal file
47
lib/WebViewTypes.js
Normal file
@ -0,0 +1,47 @@
|
||||
/* eslint-disable react/no-multi-comp, max-classes-per-file */
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
import { Component } from 'react';
|
||||
var NativeWebViewIOS = /** @class */ (function (_super) {
|
||||
__extends(NativeWebViewIOS, _super);
|
||||
function NativeWebViewIOS() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
return NativeWebViewIOS;
|
||||
}(NativeWebViewIOSBase));
|
||||
export { NativeWebViewIOS };
|
||||
var NativeWebViewMacOS = /** @class */ (function (_super) {
|
||||
__extends(NativeWebViewMacOS, _super);
|
||||
function NativeWebViewMacOS() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
return NativeWebViewMacOS;
|
||||
}(NativeWebViewMacOSBase));
|
||||
export { NativeWebViewMacOS };
|
||||
var NativeWebViewAndroid = /** @class */ (function (_super) {
|
||||
__extends(NativeWebViewAndroid, _super);
|
||||
function NativeWebViewAndroid() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
return NativeWebViewAndroid;
|
||||
}(NativeWebViewAndroidBase));
|
||||
export { NativeWebViewAndroid };
|
||||
var NativeWebViewWindows = /** @class */ (function (_super) {
|
||||
__extends(NativeWebViewWindows, _super);
|
||||
function NativeWebViewWindows() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
return NativeWebViewWindows;
|
||||
}(NativeWebViewWindowsBase));
|
||||
export { NativeWebViewWindows };
|
@ -27,6 +27,7 @@ import {
|
||||
WebViewMessageEvent,
|
||||
WebViewNavigationEvent,
|
||||
WebViewProgressEvent,
|
||||
WebViewPermissionEvent,
|
||||
AndroidWebViewProps,
|
||||
NativeWebViewAndroid,
|
||||
State,
|
||||
@ -178,6 +179,14 @@ class WebView extends React.Component<AndroidWebViewProps, State> {
|
||||
);
|
||||
};
|
||||
|
||||
answerPermissionRequest = (allow: boolean, resources: string[]) => {
|
||||
UIManager.dispatchViewManagerCommand(
|
||||
this.getWebViewHandle(),
|
||||
this.getCommands().answerPermissionRequest,
|
||||
[allow, ...(resources || [])],
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* We return an event with a bunch of fields including:
|
||||
* url, title, loading, canGoBack, canGoForward
|
||||
@ -262,6 +271,13 @@ class WebView extends React.Component<AndroidWebViewProps, State> {
|
||||
}
|
||||
};
|
||||
|
||||
onPermissionRequest = (event: WebViewPermissionEvent) => {
|
||||
const { onPermissionRequest } = this.props;
|
||||
if (onPermissionRequest) {
|
||||
onPermissionRequest(event);
|
||||
}
|
||||
}
|
||||
|
||||
onLoadingProgress = (event: WebViewProgressEvent) => {
|
||||
const { onLoadProgress } = this.props;
|
||||
const { nativeEvent: { progress } } = event;
|
||||
|
@ -14,7 +14,7 @@ import {
|
||||
|
||||
type WebViewCommands = 'goForward' | 'goBack' | 'reload' | 'stopLoading' | 'postMessage' | 'injectJavaScript' | 'loadUrl' | 'requestFocus';
|
||||
|
||||
type AndroidWebViewCommands = 'clearHistory' | 'clearCache' | 'clearFormData';
|
||||
type AndroidWebViewCommands = 'clearHistory' | 'clearCache' | 'clearFormData' | 'answerPermissionRequest';
|
||||
|
||||
|
||||
|
||||
@ -102,6 +102,10 @@ export interface WebViewNativeProgressEvent extends WebViewNativeEvent {
|
||||
progress: number;
|
||||
}
|
||||
|
||||
export interface WebViewNativePermissionEvent extends WebViewNativeEvent {
|
||||
resources: string[];
|
||||
}
|
||||
|
||||
export interface WebViewNavigation extends WebViewNativeEvent {
|
||||
navigationType:
|
||||
| 'click'
|
||||
@ -151,6 +155,10 @@ export type WebViewProgressEvent = NativeSyntheticEvent<
|
||||
WebViewNativeProgressEvent
|
||||
>;
|
||||
|
||||
export type WebViewPermissionEvent = NativeSyntheticEvent<
|
||||
WebViewNativePermissionEvent
|
||||
>;
|
||||
|
||||
export type WebViewNavigationEvent = NativeSyntheticEvent<WebViewNavigation>;
|
||||
|
||||
export type ShouldStartLoadRequestEvent = NativeSyntheticEvent<ShouldStartLoadRequest>;
|
||||
@ -292,6 +300,7 @@ export interface AndroidNativeWebViewProps extends CommonNativeWebViewProps {
|
||||
javaScriptEnabled?: boolean;
|
||||
mixedContentMode?: 'never' | 'always' | 'compatibility';
|
||||
onContentSizeChange?: (event: WebViewEvent) => void;
|
||||
onPermissionRequest?: (event: WebViewPermissionEvent) => void;
|
||||
onRenderProcessGone?: (event: WebViewRenderProcessGoneEvent) => void;
|
||||
overScrollMode?: OverScrollModeType;
|
||||
saveFormDataDisabled?: boolean;
|
||||
@ -725,6 +734,7 @@ export interface MacOSWebViewProps extends WebViewSharedProps {
|
||||
export interface AndroidWebViewProps extends WebViewSharedProps {
|
||||
onNavigationStateChange?: (event: WebViewNavigation) => void;
|
||||
onContentSizeChange?: (event: WebViewEvent) => void;
|
||||
onPermissionRequest?: (event: WebViewPermissionEvent) => void;
|
||||
|
||||
/**
|
||||
* Function that is invoked when the `WebView` process crashes or is killed by the OS.
|
||||
|
Loading…
x
Reference in New Issue
Block a user