mirror of
https://github.com/status-im/react-native-webview.git
synced 2025-02-22 08:48:39 +00:00
feat(webview props) onLoadProgresss property (#53)
* Added the onLoadProgress property to the iOS wkwebview and Android webview
This commit is contained in:
parent
525ebfa06e
commit
b5aaf5c800
@ -37,6 +37,7 @@ class MyWebComponent extends Component {
|
||||
<WebView
|
||||
source={{ uri: 'https://infinite.red/react-native' }}
|
||||
style={{ marginTop: 20 }}
|
||||
onLoadProgress={e=>console.log(e.nativeEvent.progress)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -54,6 +54,7 @@ import com.reactnativecommunity.webview.events.TopLoadingErrorEvent;
|
||||
import com.reactnativecommunity.webview.events.TopLoadingFinishEvent;
|
||||
import com.reactnativecommunity.webview.events.TopLoadingStartEvent;
|
||||
import com.reactnativecommunity.webview.events.TopMessageEvent;
|
||||
import com.reactnativecommunity.webview.events.TopLoadingProgressEvent;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@ -74,7 +75,8 @@ import org.json.JSONObject;
|
||||
* {@link WebView} instances could emit following direct events:
|
||||
* - topLoadingFinish
|
||||
* - topLoadingStart
|
||||
* - topLoadingError
|
||||
* - topLoadingStart
|
||||
* - topLoadingProgress
|
||||
*
|
||||
* Each event will carry the following properties:
|
||||
* - target - view's react tag
|
||||
@ -409,6 +411,23 @@ public class RNCWebViewManager extends SimpleViewManager<WebView> {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(WebView webView, int newProgress) {
|
||||
super.onProgressChanged(webView, newProgress);
|
||||
WritableMap event = Arguments.createMap();
|
||||
event.putDouble("target", webView.getId());
|
||||
event.putString("title", webView.getTitle());
|
||||
event.putBoolean("canGoBack", webView.canGoBack());
|
||||
event.putBoolean("canGoForward", webView.canGoForward());
|
||||
event.putDouble("progress", (float)newProgress/100);
|
||||
dispatchEvent(
|
||||
webView,
|
||||
new TopLoadingProgressEvent(
|
||||
webView.getId(),
|
||||
event));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
|
||||
callback.invoke(origin, true, false);
|
||||
@ -623,6 +642,13 @@ public class RNCWebViewManager extends SimpleViewManager<WebView> {
|
||||
view.setWebViewClient(new RNCWebViewClient());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map getExportedCustomDirectEventTypeConstants() {
|
||||
MapBuilder.Builder builder = MapBuilder.builder();
|
||||
builder.put("topLoadingProgress", MapBuilder.of("registrationName", "onLoadingProgress"));
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Map<String, Integer> getCommandsMap() {
|
||||
return MapBuilder.of(
|
||||
|
@ -0,0 +1,36 @@
|
||||
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;
|
||||
|
||||
public class TopLoadingProgressEvent extends Event<TopLoadingProgressEvent> {
|
||||
public static final String EVENT_NAME = "topLoadingProgress";
|
||||
private WritableMap mEventData;
|
||||
|
||||
public TopLoadingProgressEvent(int viewId, WritableMap eventData) {
|
||||
super(viewId);
|
||||
mEventData = eventData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventName() {
|
||||
return EVENT_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canCoalesce() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public short getCoalescingKey() {
|
||||
// All events for a given view can be coalesced.
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatch(RCTEventEmitter rctEventEmitter) {
|
||||
rctEventEmitter.receiveEvent(getViewTag(), getEventName(), mEventData);
|
||||
}
|
||||
}
|
@ -16,6 +16,7 @@ This document lays out the current public properties and methods for the React N
|
||||
- [`onLoad`](Reference.md#onload)
|
||||
- [`onLoadEnd`](Reference.md#onloadend)
|
||||
- [`onLoadStart`](Reference.md#onloadstart)
|
||||
- [`onLoadProgress`](Reference.md#onloadprogress)
|
||||
- [`onMessage`](Reference.md#onmessage)
|
||||
- [`onNavigationStateChange`](Reference.md#onnavigationstatechange)
|
||||
- [`originWhitelist`](Reference.md#originwhitelist)
|
||||
@ -44,11 +45,11 @@ This document lays out the current public properties and methods for the React N
|
||||
|
||||
## Methods Index
|
||||
|
||||
* [`extraNativeComponentConfig`](Reference.md#extranativecomponentconfig)
|
||||
* [`goForward`](Reference.md#goforward)
|
||||
* [`goBack`](Reference.md#goback)
|
||||
* [`reload`](Reference.md#reload)
|
||||
* [`stopLoading`](Reference.md#stoploading)
|
||||
- [`extraNativeComponentConfig`](Reference.md#extranativecomponentconfig)
|
||||
- [`goForward`](Reference.md#goforward)
|
||||
- [`goBack`](Reference.md#goback)
|
||||
- [`reload`](Reference.md#reload)
|
||||
- [`stopLoading`](Reference.md#stoploading)
|
||||
|
||||
---
|
||||
|
||||
@ -64,17 +65,17 @@ The object passed to `source` can have either of the following shapes:
|
||||
|
||||
**Load uri**
|
||||
|
||||
* `uri` (string) - The URI to load in the `WebView`. Can be a local or remote file.
|
||||
* `method` (string) - The HTTP Method to use. Defaults to GET if not specified. On Android, the only supported methods are GET and POST.
|
||||
* `headers` (object) - Additional HTTP headers to send with the request. On Android, this can only be used with GET requests.
|
||||
* `body` (string) - 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. On Android, this can only be used with POST requests.
|
||||
- `uri` (string) - The URI to load in the `WebView`. Can be a local or remote file.
|
||||
- `method` (string) - The HTTP Method to use. Defaults to GET if not specified. On Android, the only supported methods are GET and POST.
|
||||
- `headers` (object) - Additional HTTP headers to send with the request. On Android, this can only be used with GET requests.
|
||||
- `body` (string) - 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. On Android, this can only be used with POST requests.
|
||||
|
||||
**Static HTML**
|
||||
|
||||
_Note that using static HTML requires the WebView property [originWhiteList](Reference.md#originWhiteList) to `['*']`._
|
||||
|
||||
* `html` (string) - A static HTML page to display in the WebView.
|
||||
* `baseUrl` (string) - The base URL to be used for any relative links in the HTML.
|
||||
- `html` (string) - A static HTML page to display in the WebView.
|
||||
- `baseUrl` (string) - The base URL to be used for any relative links in the HTML.
|
||||
|
||||
| Type | Required |
|
||||
| ------ | -------- |
|
||||
@ -128,9 +129,9 @@ Override the native component used to render the WebView. Enables a custom nativ
|
||||
|
||||
The `nativeConfig` prop expects an object with the following keys:
|
||||
|
||||
* `component` (any)
|
||||
* `props` (object)
|
||||
* `viewManager` (object)
|
||||
- `component` (any)
|
||||
- `props` (object)
|
||||
- `viewManager` (object)
|
||||
|
||||
| Type | Required |
|
||||
| ------ | -------- |
|
||||
@ -178,6 +179,21 @@ Function that is invoked when the `WebView` starts loading.
|
||||
|
||||
---
|
||||
|
||||
### `onLoadProgress`
|
||||
|
||||
Function that is invoked when the `WebView` is loading.
|
||||
|
||||
> **_Note_**
|
||||
>
|
||||
> On iOS, when useWebKit=false, this prop will not work.
|
||||
> On android, You can't get the url property, meaning that `event.nativeEvent.url` will be null.
|
||||
|
||||
| Type | Required |
|
||||
| -------- | -------- |
|
||||
| function | No |
|
||||
|
||||
---
|
||||
|
||||
### `onMessage`
|
||||
|
||||
A function that is invoked when the webview calls `window.postMessage`. Setting this property will inject a `postMessage` global into your webview, but will still call pre-existing values of `postMessage`.
|
||||
@ -266,8 +282,8 @@ Boolean value that forces the `WebView` to show the loading view on the first lo
|
||||
|
||||
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)
|
||||
- normal: 0.998
|
||||
- fast: 0.99 (the default for iOS web view)
|
||||
|
||||
| Type | Required | Platform |
|
||||
| ------ | -------- | -------- |
|
||||
@ -301,9 +317,9 @@ Specifies the mixed content mode. i.e WebView will allow a secure origin to load
|
||||
|
||||
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.
|
||||
- `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.
|
||||
|
||||
| Type | Required | Platform |
|
||||
| ------ | -------- | -------- |
|
||||
@ -373,18 +389,18 @@ You can provide one type or an array of many types.
|
||||
|
||||
Possible values for `dataDetectorTypes` are:
|
||||
|
||||
* `phoneNumber`
|
||||
* `link`
|
||||
* `address`
|
||||
* `calendarEvent`
|
||||
* `none`
|
||||
* `all`
|
||||
- `phoneNumber`
|
||||
- `link`
|
||||
- `address`
|
||||
- `calendarEvent`
|
||||
- `none`
|
||||
- `all`
|
||||
|
||||
With the [new WebKit](Reference.md#usewebkit) implementation, we have three new values:
|
||||
|
||||
* `trackingNumber`
|
||||
* `flightNumber`
|
||||
* `lookupSuggestion`
|
||||
- `trackingNumber`
|
||||
- `flightNumber`
|
||||
- `lookupSuggestion`
|
||||
|
||||
| Type | Required | Platform |
|
||||
| ---------------- | -------- | -------- |
|
||||
|
@ -15,6 +15,7 @@ static NSString *const MessageHanderName = @"ReactNative";
|
||||
@property (nonatomic, copy) RCTDirectEventBlock onLoadingStart;
|
||||
@property (nonatomic, copy) RCTDirectEventBlock onLoadingFinish;
|
||||
@property (nonatomic, copy) RCTDirectEventBlock onLoadingError;
|
||||
@property (nonatomic, copy) RCTDirectEventBlock onLoadingProgress;
|
||||
@property (nonatomic, copy) RCTDirectEventBlock onShouldStartLoadWithRequest;
|
||||
@property (nonatomic, copy) RCTDirectEventBlock onMessage;
|
||||
@property (nonatomic, copy) WKWebView *webView;
|
||||
@ -27,7 +28,9 @@ static NSString *const MessageHanderName = @"ReactNative";
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
|
||||
if(_webView){
|
||||
[_webView removeObserver:self forKeyPath:@"estimatedProgress"];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -85,6 +88,7 @@ static NSString *const MessageHanderName = @"ReactNative";
|
||||
_webView.navigationDelegate = self;
|
||||
_webView.scrollView.scrollEnabled = _scrollEnabled;
|
||||
_webView.scrollView.bounces = _bounces;
|
||||
[_webView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */
|
||||
if ([_webView.scrollView respondsToSelector:@selector(setContentInsetAdjustmentBehavior:)]) {
|
||||
@ -100,6 +104,18 @@ static NSString *const MessageHanderName = @"ReactNative";
|
||||
}
|
||||
}
|
||||
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
|
||||
if ([keyPath isEqual:@"estimatedProgress"] && object == self.webView) {
|
||||
if(_onLoadingProgress){
|
||||
NSMutableDictionary<NSString *, id> *event = [self baseEvent];
|
||||
[event addEntriesFromDictionary:@{@"progress":[NSNumber numberWithDouble:self.webView.estimatedProgress]}];
|
||||
_onLoadingProgress(event);
|
||||
}
|
||||
}else{
|
||||
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setBackgroundColor:(UIColor *)backgroundColor
|
||||
{
|
||||
_savedBackgroundColor = backgroundColor;
|
||||
|
@ -33,6 +33,7 @@ RCT_EXPORT_VIEW_PROPERTY(source, NSDictionary)
|
||||
RCT_EXPORT_VIEW_PROPERTY(onLoadingStart, RCTDirectEventBlock)
|
||||
RCT_EXPORT_VIEW_PROPERTY(onLoadingFinish, RCTDirectEventBlock)
|
||||
RCT_EXPORT_VIEW_PROPERTY(onLoadingError, RCTDirectEventBlock)
|
||||
RCT_EXPORT_VIEW_PROPERTY(onLoadingProgress, RCTDirectEventBlock)
|
||||
RCT_EXPORT_VIEW_PROPERTY(onShouldStartLoadWithRequest, RCTDirectEventBlock)
|
||||
RCT_EXPORT_VIEW_PROPERTY(injectedJavaScript, NSString)
|
||||
RCT_EXPORT_VIEW_PROPERTY(allowsInlineMediaPlayback, BOOL)
|
||||
|
@ -35,6 +35,7 @@ import type {
|
||||
WebViewNavigationEvent,
|
||||
WebViewSharedProps,
|
||||
WebViewSource,
|
||||
WebViewProgressEvent,
|
||||
} from './WebViewTypes';
|
||||
|
||||
const resolveAssetSource = Image.resolveAssetSource;
|
||||
@ -152,6 +153,7 @@ class WebView extends React.Component<WebViewSharedProps, State> {
|
||||
onLoadingStart={this.onLoadingStart}
|
||||
onLoadingFinish={this.onLoadingFinish}
|
||||
onLoadingError={this.onLoadingError}
|
||||
onLoadingProgress={this.onLoadingProgress}
|
||||
testID={this.props.testID}
|
||||
geolocationEnabled={this.props.geolocationEnabled}
|
||||
mediaPlaybackRequiresUserAction={
|
||||
@ -280,6 +282,11 @@ class WebView extends React.Component<WebViewSharedProps, State> {
|
||||
const { onMessage } = this.props;
|
||||
onMessage && onMessage(event);
|
||||
};
|
||||
|
||||
onLoadingProgress = (event: WebViewProgressEvent) => {
|
||||
const { onLoadProgress} = this.props;
|
||||
onLoadProgress && onLoadProgress(event);
|
||||
}
|
||||
}
|
||||
|
||||
const RNCWebView = requireNativeComponent('RNCWebView');
|
||||
|
@ -34,6 +34,7 @@ import type {
|
||||
WebViewNavigationEvent,
|
||||
WebViewSharedProps,
|
||||
WebViewSource,
|
||||
WebViewProgressEvent,
|
||||
} from './WebViewTypes';
|
||||
|
||||
const resolveAssetSource = Image.resolveAssetSource;
|
||||
@ -263,6 +264,7 @@ class WebView extends React.Component<WebViewSharedProps, State> {
|
||||
onLoadingStart={this._onLoadingStart}
|
||||
onLoadingFinish={this._onLoadingFinish}
|
||||
onLoadingError={this._onLoadingError}
|
||||
onLoadingProgress={this._onLoadingProgress}
|
||||
messagingEnabled={messagingEnabled}
|
||||
onMessage={this._onMessage}
|
||||
onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
|
||||
@ -420,6 +422,11 @@ class WebView extends React.Component<WebViewSharedProps, State> {
|
||||
onMessage && onMessage(event);
|
||||
};
|
||||
|
||||
_onLoadingProgress = (event: WebViewProgressEvent) => {
|
||||
const {onLoadProgress} = this.props;
|
||||
onLoadProgress && onLoadProgress(event);
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps: WebViewSharedProps) {
|
||||
if (!(prevProps.useWebKit && this.props.useWebKit)) {
|
||||
return;
|
||||
|
@ -25,6 +25,11 @@ export type WebViewNativeEvent = $ReadOnly<{|
|
||||
canGoForward: boolean,
|
||||
|}>;
|
||||
|
||||
export type WebViewProgressEvent = $ReadOnly<{|
|
||||
...WebViewNativeEvent,
|
||||
progress: number,
|
||||
|}>
|
||||
|
||||
export type WebViewNavigation = $ReadOnly<{|
|
||||
...WebViewNativeEvent,
|
||||
navigationType:
|
||||
@ -365,6 +370,11 @@ export type WebViewSharedProps = $ReadOnly<{|
|
||||
*/
|
||||
onMessage?: (event: WebViewMessageEvent) => mixed,
|
||||
|
||||
/**
|
||||
* Function that is invoked when the `WebView` is loading.
|
||||
*/
|
||||
onLoadProgress?: (event: WebViewProgressEvent) => mixed,
|
||||
|
||||
/**
|
||||
* Boolean value that forces the `WebView` to show the loading view
|
||||
* on the first load.
|
||||
|
Loading…
x
Reference in New Issue
Block a user