From 6a9116f2d19a8cfd76ee691c2d793b34aee963e7 Mon Sep 17 00:00:00 2001 From: Caleb Clarke Date: Sat, 15 Aug 2020 02:21:38 -0700 Subject: [PATCH] feat(events): Add isTopFrame to shouldStartLoadForRequest (#1537) * Add isTopFrame to shouldStartLoadForRequest on iOS onLoadingStart is not raised for inner frames, but onShouldStartLoadWithRequest still is. This keeps that behavior but adds isTopFrame to onShouldStartLoadWithRequest so that apps can perform their own filtering if desired. * Update docs Co-authored-by: Jamon Holmgren --- .../events/TopShouldStartLoadWithRequestEvent.kt | 2 ++ apple/RNCWebView.m | 5 +++-- docs/Reference.md | 1 + src/WebViewShared.tsx | 4 ++-- src/WebViewTypes.ts | 12 +++++++++--- 5 files changed, 17 insertions(+), 7 deletions(-) diff --git a/android/src/main/java/com/reactnativecommunity/webview/events/TopShouldStartLoadWithRequestEvent.kt b/android/src/main/java/com/reactnativecommunity/webview/events/TopShouldStartLoadWithRequestEvent.kt index 0f80ced..da4eb96 100644 --- a/android/src/main/java/com/reactnativecommunity/webview/events/TopShouldStartLoadWithRequestEvent.kt +++ b/android/src/main/java/com/reactnativecommunity/webview/events/TopShouldStartLoadWithRequestEvent.kt @@ -14,6 +14,8 @@ class TopShouldStartLoadWithRequestEvent(viewId: Int, private val mData: Writabl init { mData.putString("navigationType", "other") + // Android does not raise shouldOverrideUrlLoading for inner frames + mData.putBoolean("isTopFrame", true) } override fun getEventName(): String = EVENT_NAME diff --git a/apple/RNCWebView.m b/apple/RNCWebView.m index 0f32e94..a595fd7 100644 --- a/apple/RNCWebView.m +++ b/apple/RNCWebView.m @@ -937,13 +937,15 @@ static NSDictionary* customCertificatesForHost; WKNavigationType navigationType = navigationAction.navigationType; NSURLRequest *request = navigationAction.request; + BOOL isTopFrame = [request.URL isEqual:request.mainDocumentURL]; if (_onShouldStartLoadWithRequest) { NSMutableDictionary *event = [self baseEvent]; [event addEntriesFromDictionary: @{ @"url": (request.URL).absoluteString, @"mainDocumentURL": (request.mainDocumentURL).absoluteString, - @"navigationType": navigationTypes[@(navigationType)] + @"navigationType": navigationTypes[@(navigationType)], + @"isTopFrame": @(isTopFrame) }]; if (![self.delegate webView:self shouldStartLoadForRequest:event @@ -955,7 +957,6 @@ static NSDictionary* customCertificatesForHost; if (_onLoadingStart) { // We have this check to filter out iframe requests and whatnot - BOOL isTopFrame = [request.URL isEqual:request.mainDocumentURL]; if (isTopFrame) { NSMutableDictionary *event = [self baseEvent]; [event addEntriesFromDictionary: @{ diff --git a/docs/Reference.md b/docs/Reference.md index 22faff2..4d4f44c 100644 --- a/docs/Reference.md +++ b/docs/Reference.md @@ -682,6 +682,7 @@ canGoForward lockIdentifier mainDocumentURL (iOS only) navigationType +isTopFrame ``` --- diff --git a/src/WebViewShared.tsx b/src/WebViewShared.tsx index ff2c034..23e5c09 100644 --- a/src/WebViewShared.tsx +++ b/src/WebViewShared.tsx @@ -2,8 +2,8 @@ import escapeStringRegexp from 'escape-string-regexp'; import React from 'react'; import { Linking, View, ActivityIndicator, Text } from 'react-native'; import { - WebViewNavigationEvent, OnShouldStartLoadWithRequest, + ShouldStartLoadRequestEvent, } from './WebViewTypes'; import styles from './WebView.styles'; @@ -39,7 +39,7 @@ const createOnShouldStartLoadWithRequest = ( originWhitelist: readonly string[], onShouldStartLoadWithRequest?: OnShouldStartLoadWithRequest, ) => { - return ({ nativeEvent }: WebViewNavigationEvent) => { + return ({ nativeEvent }: ShouldStartLoadRequestEvent) => { let shouldStart = true; const { url, lockIdentifier } = nativeEvent; diff --git a/src/WebViewTypes.ts b/src/WebViewTypes.ts index 0a3c77b..05223ac 100644 --- a/src/WebViewTypes.ts +++ b/src/WebViewTypes.ts @@ -113,6 +113,10 @@ export interface WebViewNavigation extends WebViewNativeEvent { mainDocumentURL?: string; } +export interface ShouldStartLoadRequest extends WebViewNavigation { + isTopFrame: boolean; +} + export interface FileDownload { downloadUrl: string; } @@ -149,6 +153,8 @@ export type WebViewProgressEvent = NativeSyntheticEvent< export type WebViewNavigationEvent = NativeSyntheticEvent; +export type ShouldStartLoadRequestEvent = NativeSyntheticEvent; + export type FileDownloadEvent = NativeSyntheticEvent; export type WebViewMessageEvent = NativeSyntheticEvent; @@ -238,7 +244,7 @@ export interface WebViewNativeConfig { } export type OnShouldStartLoadWithRequest = ( - event: WebViewNavigation, + event: ShouldStartLoadRequest, ) => boolean; export interface CommonNativeWebViewProps extends ViewProps { @@ -258,7 +264,7 @@ export interface CommonNativeWebViewProps extends ViewProps { onLoadingStart: (event: WebViewNavigationEvent) => void; onHttpError: (event: WebViewHttpErrorEvent) => void; onMessage: (event: WebViewMessageEvent) => void; - onShouldStartLoadWithRequest: (event: WebViewNavigationEvent) => void; + onShouldStartLoadWithRequest: (event: ShouldStartLoadRequestEvent) => void; showsHorizontalScrollIndicator?: boolean; showsVerticalScrollIndicator?: boolean; // TODO: find a better way to type this. @@ -266,7 +272,7 @@ export interface CommonNativeWebViewProps extends ViewProps { source: any; userAgent?: string; /** - * Append to the existing user-agent. Overriden if `userAgent` is set. + * Append to the existing user-agent. Overridden if `userAgent` is set. */ applicationNameForUserAgent?: string; }