Browse Source

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>
Caleb Clarke 4 years ago
parent
commit
6a9116f2d1
No account linked to committer's email address

+ 2
- 0
android/src/main/java/com/reactnativecommunity/webview/events/TopShouldStartLoadWithRequestEvent.kt View File

14
 
14
 
15
   init {
15
   init {
16
     mData.putString("navigationType", "other")
16
     mData.putString("navigationType", "other")
17
+    // Android does not raise shouldOverrideUrlLoading for inner frames
18
+    mData.putBoolean("isTopFrame", true)
17
   }
19
   }
18
 
20
 
19
   override fun getEventName(): String = EVENT_NAME
21
   override fun getEventName(): String = EVENT_NAME

+ 3
- 2
apple/RNCWebView.m View File

937
 
937
 
938
   WKNavigationType navigationType = navigationAction.navigationType;
938
   WKNavigationType navigationType = navigationAction.navigationType;
939
   NSURLRequest *request = navigationAction.request;
939
   NSURLRequest *request = navigationAction.request;
940
+  BOOL isTopFrame = [request.URL isEqual:request.mainDocumentURL];
940
 
941
 
941
   if (_onShouldStartLoadWithRequest) {
942
   if (_onShouldStartLoadWithRequest) {
942
     NSMutableDictionary<NSString *, id> *event = [self baseEvent];
943
     NSMutableDictionary<NSString *, id> *event = [self baseEvent];
943
     [event addEntriesFromDictionary: @{
944
     [event addEntriesFromDictionary: @{
944
       @"url": (request.URL).absoluteString,
945
       @"url": (request.URL).absoluteString,
945
       @"mainDocumentURL": (request.mainDocumentURL).absoluteString,
946
       @"mainDocumentURL": (request.mainDocumentURL).absoluteString,
946
-      @"navigationType": navigationTypes[@(navigationType)]
947
+      @"navigationType": navigationTypes[@(navigationType)],
948
+      @"isTopFrame": @(isTopFrame)
947
     }];
949
     }];
948
     if (![self.delegate webView:self
950
     if (![self.delegate webView:self
949
       shouldStartLoadForRequest:event
951
       shouldStartLoadForRequest:event
955
 
957
 
956
   if (_onLoadingStart) {
958
   if (_onLoadingStart) {
957
     // We have this check to filter out iframe requests and whatnot
959
     // We have this check to filter out iframe requests and whatnot
958
-    BOOL isTopFrame = [request.URL isEqual:request.mainDocumentURL];
959
     if (isTopFrame) {
960
     if (isTopFrame) {
960
       NSMutableDictionary<NSString *, id> *event = [self baseEvent];
961
       NSMutableDictionary<NSString *, id> *event = [self baseEvent];
961
       [event addEntriesFromDictionary: @{
962
       [event addEntriesFromDictionary: @{

+ 1
- 0
docs/Reference.md View File

682
 lockIdentifier
682
 lockIdentifier
683
 mainDocumentURL (iOS only)
683
 mainDocumentURL (iOS only)
684
 navigationType
684
 navigationType
685
+isTopFrame
685
 ```
686
 ```
686
 
687
 
687
 ---
688
 ---

+ 2
- 2
src/WebViewShared.tsx View File

2
 import React from 'react';
2
 import React from 'react';
3
 import { Linking, View, ActivityIndicator, Text } from 'react-native';
3
 import { Linking, View, ActivityIndicator, Text } from 'react-native';
4
 import {
4
 import {
5
-  WebViewNavigationEvent,
6
   OnShouldStartLoadWithRequest,
5
   OnShouldStartLoadWithRequest,
6
+  ShouldStartLoadRequestEvent,
7
 } from './WebViewTypes';
7
 } from './WebViewTypes';
8
 import styles from './WebView.styles';
8
 import styles from './WebView.styles';
9
 
9
 
39
   originWhitelist: readonly string[],
39
   originWhitelist: readonly string[],
40
   onShouldStartLoadWithRequest?: OnShouldStartLoadWithRequest,
40
   onShouldStartLoadWithRequest?: OnShouldStartLoadWithRequest,
41
 ) => {
41
 ) => {
42
-  return ({ nativeEvent }: WebViewNavigationEvent) => {
42
+  return ({ nativeEvent }: ShouldStartLoadRequestEvent) => {
43
     let shouldStart = true;
43
     let shouldStart = true;
44
     const { url, lockIdentifier } = nativeEvent;
44
     const { url, lockIdentifier } = nativeEvent;
45
 
45
 

+ 9
- 3
src/WebViewTypes.ts View File

113
   mainDocumentURL?: string;
113
   mainDocumentURL?: string;
114
 }
114
 }
115
 
115
 
116
+export interface ShouldStartLoadRequest extends WebViewNavigation {
117
+  isTopFrame: boolean;
118
+}
119
+
116
 export interface FileDownload {
120
 export interface FileDownload {
117
   downloadUrl: string;
121
   downloadUrl: string;
118
 }
122
 }
149
 
153
 
150
 export type WebViewNavigationEvent = NativeSyntheticEvent<WebViewNavigation>;
154
 export type WebViewNavigationEvent = NativeSyntheticEvent<WebViewNavigation>;
151
 
155
 
156
+export type ShouldStartLoadRequestEvent = NativeSyntheticEvent<ShouldStartLoadRequest>;
157
+
152
 export type FileDownloadEvent = NativeSyntheticEvent<FileDownload>;
158
 export type FileDownloadEvent = NativeSyntheticEvent<FileDownload>;
153
 
159
 
154
 export type WebViewMessageEvent = NativeSyntheticEvent<WebViewMessage>;
160
 export type WebViewMessageEvent = NativeSyntheticEvent<WebViewMessage>;
238
 }
244
 }
239
 
245
 
240
 export type OnShouldStartLoadWithRequest = (
246
 export type OnShouldStartLoadWithRequest = (
241
-  event: WebViewNavigation,
247
+  event: ShouldStartLoadRequest,
242
 ) => boolean;
248
 ) => boolean;
243
 
249
 
244
 export interface CommonNativeWebViewProps extends ViewProps {
250
 export interface CommonNativeWebViewProps extends ViewProps {
258
   onLoadingStart: (event: WebViewNavigationEvent) => void;
264
   onLoadingStart: (event: WebViewNavigationEvent) => void;
259
   onHttpError: (event: WebViewHttpErrorEvent) => void;
265
   onHttpError: (event: WebViewHttpErrorEvent) => void;
260
   onMessage: (event: WebViewMessageEvent) => void;
266
   onMessage: (event: WebViewMessageEvent) => void;
261
-  onShouldStartLoadWithRequest: (event: WebViewNavigationEvent) => void;
267
+  onShouldStartLoadWithRequest: (event: ShouldStartLoadRequestEvent) => void;
262
   showsHorizontalScrollIndicator?: boolean;
268
   showsHorizontalScrollIndicator?: boolean;
263
   showsVerticalScrollIndicator?: boolean;
269
   showsVerticalScrollIndicator?: boolean;
264
   // TODO: find a better way to type this.
270
   // TODO: find a better way to type this.
266
   source: any;
272
   source: any;
267
   userAgent?: string;
273
   userAgent?: string;
268
   /**
274
   /**
269
-   * Append to the existing user-agent. Overriden if `userAgent` is set.
275
+   * Append to the existing user-agent. Overridden if `userAgent` is set.
270
    */
276
    */
271
   applicationNameForUserAgent?: string;
277
   applicationNameForUserAgent?: string;
272
 }
278
 }