Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apple/RNCWebView.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ shouldStartLoadForRequest:(NSMutableDictionary<NSString *, id> *_Nonnull)request
@property (nonatomic, copy) NSDictionary * _Nullable basicAuthCredential;
@property (nonatomic, assign) BOOL pullToRefreshEnabled;
@property (nonatomic, assign) BOOL enableApplePay;
@property (nonatomic, assign) NSInteger shouldStartLoadTimeout;
@property (nonatomic, copy) NSArray<NSDictionary *> * _Nullable menuItems;
@property (nonatomic, copy) RCTDirectEventBlock onCustomMenuSelection;
#if !TARGET_OS_OSX
Expand Down
8 changes: 6 additions & 2 deletions apple/RNCWebViewManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ - (RCTUIView *)view
RCT_EXPORT_VIEW_PROPERTY(menuItems, NSArray);
RCT_EXPORT_VIEW_PROPERTY(onCustomMenuSelection, RCTDirectEventBlock)

RCT_EXPORT_VIEW_PROPERTY(shouldStartLoadTimeout, NSInteger)

RCT_EXPORT_METHOD(postMessage:(nonnull NSNumber *)reactTag message:(NSString *)message)
{
[self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, RNCWebView *> *viewRegistry) {
Expand Down Expand Up @@ -254,8 +256,10 @@ - (BOOL) webView:(RNCWebView *)webView
request[@"lockIdentifier"] = @(_shouldStartLoadLock.condition);
callback(request);

// Block the main thread for a maximum of 500ms until the JS thread returns
if ([_shouldStartLoadLock lockWhenCondition:0 beforeDate:[NSDate dateWithTimeIntervalSinceNow:.50]]) {
NSInteger timeoutMs = webView.shouldStartLoadTimeout;
NSTimeInterval timeoutSeconds = timeoutMs / 1000.0;

if ([_shouldStartLoadLock lockWhenCondition:0 beforeDate:[NSDate dateWithTimeIntervalSinceNow:timeoutSeconds]]) {
BOOL returnValue = _shouldStartLoad;
[_shouldStartLoadLock unlock];
_shouldStartLoadLock = nil;
Expand Down
4 changes: 3 additions & 1 deletion src/WebView.ios.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ const WebViewComponent = forwardRef<{}, IOSWebViewProps>((props, ref) => {
cacheEnabled = true,
originWhitelist = defaultOriginWhitelist,
deeplinkWhitelist = defaultDeeplinkWhitelist,
textInteractionEnabled= true,
textInteractionEnabled = true,
shouldStartLoadTimeout = 500,
injectedJavaScript,
injectedJavaScriptBeforeContentLoaded,
startInLoadingState,
Expand Down Expand Up @@ -208,6 +209,7 @@ const WebViewComponent = forwardRef<{}, IOSWebViewProps>((props, ref) => {
mediaPlaybackRequiresUserAction={mediaPlaybackRequiresUserAction}
ref={webViewRef}
sharedCookiesEnabled={sharedCookiesEnabled}
shouldStartLoadTimeout={shouldStartLoadTimeout}
// TODO: find a better way to type this.
source={source}
style={webViewStyles}
Expand Down
10 changes: 10 additions & 0 deletions src/WebViewTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@ export interface IOSNativeWebViewProps extends CommonNativeWebViewProps {
enableApplePay?: boolean;
textInteractionEnabled?: boolean;
mediaCapturePermissionGrantType?: MediaCapturePermissionGrantType;
shouldStartLoadTimeout?: number;
}

export interface IOSWebViewProps extends WebViewSharedProps {
Expand Down Expand Up @@ -573,6 +574,15 @@ export interface IOSWebViewProps extends WebViewSharedProps {
* @platform ios
*/
onCustomMenuSelection?: (event: WebViewEvent) => void;

/**
* Timeout in milliseconds for the shouldStartLoad callback to respond.
* If the JS thread is busy and cannot respond within this time, navigation
* will be blocked.
* The default value is `500`.
* @platform ios
*/
shouldStartLoadTimeout?: number;
}

export interface AndroidWebViewProps extends WebViewSharedProps {
Expand Down
Loading