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 <jamonholmgren@gmail.com>
This commit is contained in:
Caleb Clarke 2020-08-15 02:21:38 -07:00 committed by GitHub
parent 621d2df72e
commit 6a9116f2d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 17 additions and 7 deletions

View File

@ -14,6 +14,8 @@ class TopShouldStartLoadWithRequestEvent(viewId: Int, private val mData: Writabl
init { init {
mData.putString("navigationType", "other") mData.putString("navigationType", "other")
// Android does not raise shouldOverrideUrlLoading for inner frames
mData.putBoolean("isTopFrame", true)
} }
override fun getEventName(): String = EVENT_NAME override fun getEventName(): String = EVENT_NAME

View File

@ -937,13 +937,15 @@ static NSDictionary* customCertificatesForHost;
WKNavigationType navigationType = navigationAction.navigationType; WKNavigationType navigationType = navigationAction.navigationType;
NSURLRequest *request = navigationAction.request; NSURLRequest *request = navigationAction.request;
BOOL isTopFrame = [request.URL isEqual:request.mainDocumentURL];
if (_onShouldStartLoadWithRequest) { if (_onShouldStartLoadWithRequest) {
NSMutableDictionary<NSString *, id> *event = [self baseEvent]; NSMutableDictionary<NSString *, id> *event = [self baseEvent];
[event addEntriesFromDictionary: @{ [event addEntriesFromDictionary: @{
@"url": (request.URL).absoluteString, @"url": (request.URL).absoluteString,
@"mainDocumentURL": (request.mainDocumentURL).absoluteString, @"mainDocumentURL": (request.mainDocumentURL).absoluteString,
@"navigationType": navigationTypes[@(navigationType)] @"navigationType": navigationTypes[@(navigationType)],
@"isTopFrame": @(isTopFrame)
}]; }];
if (![self.delegate webView:self if (![self.delegate webView:self
shouldStartLoadForRequest:event shouldStartLoadForRequest:event
@ -955,7 +957,6 @@ static NSDictionary* customCertificatesForHost;
if (_onLoadingStart) { if (_onLoadingStart) {
// We have this check to filter out iframe requests and whatnot // We have this check to filter out iframe requests and whatnot
BOOL isTopFrame = [request.URL isEqual:request.mainDocumentURL];
if (isTopFrame) { if (isTopFrame) {
NSMutableDictionary<NSString *, id> *event = [self baseEvent]; NSMutableDictionary<NSString *, id> *event = [self baseEvent];
[event addEntriesFromDictionary: @{ [event addEntriesFromDictionary: @{

View File

@ -682,6 +682,7 @@ canGoForward
lockIdentifier lockIdentifier
mainDocumentURL (iOS only) mainDocumentURL (iOS only)
navigationType navigationType
isTopFrame
``` ```
--- ---

View File

@ -2,8 +2,8 @@ import escapeStringRegexp from 'escape-string-regexp';
import React from 'react'; import React from 'react';
import { Linking, View, ActivityIndicator, Text } from 'react-native'; import { Linking, View, ActivityIndicator, Text } from 'react-native';
import { import {
WebViewNavigationEvent,
OnShouldStartLoadWithRequest, OnShouldStartLoadWithRequest,
ShouldStartLoadRequestEvent,
} from './WebViewTypes'; } from './WebViewTypes';
import styles from './WebView.styles'; import styles from './WebView.styles';
@ -39,7 +39,7 @@ const createOnShouldStartLoadWithRequest = (
originWhitelist: readonly string[], originWhitelist: readonly string[],
onShouldStartLoadWithRequest?: OnShouldStartLoadWithRequest, onShouldStartLoadWithRequest?: OnShouldStartLoadWithRequest,
) => { ) => {
return ({ nativeEvent }: WebViewNavigationEvent) => { return ({ nativeEvent }: ShouldStartLoadRequestEvent) => {
let shouldStart = true; let shouldStart = true;
const { url, lockIdentifier } = nativeEvent; const { url, lockIdentifier } = nativeEvent;

View File

@ -113,6 +113,10 @@ export interface WebViewNavigation extends WebViewNativeEvent {
mainDocumentURL?: string; mainDocumentURL?: string;
} }
export interface ShouldStartLoadRequest extends WebViewNavigation {
isTopFrame: boolean;
}
export interface FileDownload { export interface FileDownload {
downloadUrl: string; downloadUrl: string;
} }
@ -149,6 +153,8 @@ export type WebViewProgressEvent = NativeSyntheticEvent<
export type WebViewNavigationEvent = NativeSyntheticEvent<WebViewNavigation>; export type WebViewNavigationEvent = NativeSyntheticEvent<WebViewNavigation>;
export type ShouldStartLoadRequestEvent = NativeSyntheticEvent<ShouldStartLoadRequest>;
export type FileDownloadEvent = NativeSyntheticEvent<FileDownload>; export type FileDownloadEvent = NativeSyntheticEvent<FileDownload>;
export type WebViewMessageEvent = NativeSyntheticEvent<WebViewMessage>; export type WebViewMessageEvent = NativeSyntheticEvent<WebViewMessage>;
@ -238,7 +244,7 @@ export interface WebViewNativeConfig {
} }
export type OnShouldStartLoadWithRequest = ( export type OnShouldStartLoadWithRequest = (
event: WebViewNavigation, event: ShouldStartLoadRequest,
) => boolean; ) => boolean;
export interface CommonNativeWebViewProps extends ViewProps { export interface CommonNativeWebViewProps extends ViewProps {
@ -258,7 +264,7 @@ export interface CommonNativeWebViewProps extends ViewProps {
onLoadingStart: (event: WebViewNavigationEvent) => void; onLoadingStart: (event: WebViewNavigationEvent) => void;
onHttpError: (event: WebViewHttpErrorEvent) => void; onHttpError: (event: WebViewHttpErrorEvent) => void;
onMessage: (event: WebViewMessageEvent) => void; onMessage: (event: WebViewMessageEvent) => void;
onShouldStartLoadWithRequest: (event: WebViewNavigationEvent) => void; onShouldStartLoadWithRequest: (event: ShouldStartLoadRequestEvent) => void;
showsHorizontalScrollIndicator?: boolean; showsHorizontalScrollIndicator?: boolean;
showsVerticalScrollIndicator?: boolean; showsVerticalScrollIndicator?: boolean;
// TODO: find a better way to type this. // TODO: find a better way to type this.
@ -266,7 +272,7 @@ export interface CommonNativeWebViewProps extends ViewProps {
source: any; source: any;
userAgent?: string; 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; applicationNameForUserAgent?: string;
} }