Browse Source

Merge branch 'master' into update-ssl-error-to-top-level-only

Alesandro Ortiz 4 years ago
parent
commit
2592e5e538
No account linked to committer's email address

+ 5
- 11
.github/workflows/windows-ci.yml View File

15
       with:
15
       with:
16
         node-version: '12.9.1'
16
         node-version: '12.9.1'
17
 
17
 
18
-    - name: Install Visual Studio components
19
-      shell: powershell
20
-      run: .\.github\workflows\scripts\install-vs-features.ps1 Microsoft.VisualStudio.Component.VC.v141.x86.x64,Microsoft.VisualStudio.ComponentGroup.UWP.VC.v141
21
-
22
     - name: Setup MSBuild
18
     - name: Setup MSBuild
23
       uses: microsoft/setup-msbuild@v1.0.0
19
       uses: microsoft/setup-msbuild@v1.0.0
24
       with:
20
       with:
25
         vs-version: 16.5
21
         vs-version: 16.5
26
-       
27
-    - name: Setup NuGet
28
-      uses: NuGet/setup-nuget@v1.0.2
29
 
22
 
30
     - name: Check node modules cache
23
     - name: Check node modules cache
31
       uses: actions/cache@v1
24
       uses: actions/cache@v1
45
       run: |
38
       run: |
46
         yarn build
39
         yarn build
47
         yarn tsc
40
         yarn tsc
48
- 
49
-    - name: NuGet restore
50
-      run: nuget restore example\windows\WebViewWindows.sln
51
 
41
 
52
     - name: Build x64 release
42
     - name: Build x64 release
53
-      run: msbuild example\windows\WebViewWindows.sln /p:Configuration=Release /p:Platform=x64 -m
43
+      shell: powershell
44
+      run: npx react-native run-windows --root example --arch x64 --release --no-packager --no-deploy --logging
54
 
45
 
46
+    # Workaround for a bug in package searching during deploy.
47
+    # The deploy script only searches windows/{*/bin/x64/Release,Release/*}, but the build step above placed the pakcages at windows/x64/Release.
48
+    # Copy the packages to Windows/Release before deploying.
55
     - name: Deploy
49
     - name: Deploy
56
       shell: powershell
50
       shell: powershell
57
       run: |
51
       run: |

+ 127
- 26
android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManager.java View File

4
 import android.annotation.TargetApi;
4
 import android.annotation.TargetApi;
5
 import android.app.DownloadManager;
5
 import android.app.DownloadManager;
6
 import android.content.Context;
6
 import android.content.Context;
7
-import android.content.Intent;
8
 import android.content.pm.ActivityInfo;
7
 import android.content.pm.ActivityInfo;
9
 import android.content.pm.PackageManager;
8
 import android.content.pm.PackageManager;
10
 import android.graphics.Bitmap;
9
 import android.graphics.Bitmap;
14
 import android.net.Uri;
13
 import android.net.Uri;
15
 import android.os.Build;
14
 import android.os.Build;
16
 import android.os.Environment;
15
 import android.os.Environment;
17
-import androidx.annotation.RequiresApi;
18
-import androidx.core.content.ContextCompat;
16
+import android.os.SystemClock;
19
 import android.text.TextUtils;
17
 import android.text.TextUtils;
20
 import android.util.Log;
18
 import android.util.Log;
21
 import android.view.Gravity;
19
 import android.view.Gravity;
28
 import android.webkit.DownloadListener;
26
 import android.webkit.DownloadListener;
29
 import android.webkit.GeolocationPermissions;
27
 import android.webkit.GeolocationPermissions;
30
 import android.webkit.JavascriptInterface;
28
 import android.webkit.JavascriptInterface;
29
+import android.webkit.RenderProcessGoneDetail;
31
 import android.webkit.SslErrorHandler;
30
 import android.webkit.SslErrorHandler;
32
 import android.webkit.PermissionRequest;
31
 import android.webkit.PermissionRequest;
33
 import android.webkit.URLUtil;
32
 import android.webkit.URLUtil;
40
 import android.webkit.WebViewClient;
39
 import android.webkit.WebViewClient;
41
 import android.widget.FrameLayout;
40
 import android.widget.FrameLayout;
42
 
41
 
42
+import androidx.annotation.Nullable;
43
+import androidx.annotation.RequiresApi;
44
+import androidx.core.content.ContextCompat;
45
+import androidx.core.util.Pair;
46
+
47
+import com.facebook.common.logging.FLog;
43
 import com.facebook.react.views.scroll.ScrollEvent;
48
 import com.facebook.react.views.scroll.ScrollEvent;
44
 import com.facebook.react.views.scroll.ScrollEventType;
49
 import com.facebook.react.views.scroll.ScrollEventType;
45
 import com.facebook.react.views.scroll.OnScrollDispatchHelper;
50
 import com.facebook.react.views.scroll.OnScrollDispatchHelper;
63
 import com.facebook.react.uimanager.events.ContentSizeChangeEvent;
68
 import com.facebook.react.uimanager.events.ContentSizeChangeEvent;
64
 import com.facebook.react.uimanager.events.Event;
69
 import com.facebook.react.uimanager.events.Event;
65
 import com.facebook.react.uimanager.events.EventDispatcher;
70
 import com.facebook.react.uimanager.events.EventDispatcher;
71
+import com.reactnativecommunity.webview.RNCWebViewModule.ShouldOverrideUrlLoadingLock.ShouldOverrideCallbackState;
66
 import com.reactnativecommunity.webview.events.TopLoadingErrorEvent;
72
 import com.reactnativecommunity.webview.events.TopLoadingErrorEvent;
67
 import com.reactnativecommunity.webview.events.TopHttpErrorEvent;
73
 import com.reactnativecommunity.webview.events.TopHttpErrorEvent;
68
 import com.reactnativecommunity.webview.events.TopLoadingFinishEvent;
74
 import com.reactnativecommunity.webview.events.TopLoadingFinishEvent;
70
 import com.reactnativecommunity.webview.events.TopLoadingStartEvent;
76
 import com.reactnativecommunity.webview.events.TopLoadingStartEvent;
71
 import com.reactnativecommunity.webview.events.TopMessageEvent;
77
 import com.reactnativecommunity.webview.events.TopMessageEvent;
72
 import com.reactnativecommunity.webview.events.TopShouldStartLoadWithRequestEvent;
78
 import com.reactnativecommunity.webview.events.TopShouldStartLoadWithRequestEvent;
79
+import com.reactnativecommunity.webview.events.TopRenderProcessGoneEvent;
73
 
80
 
74
 import org.json.JSONException;
81
 import org.json.JSONException;
75
 import org.json.JSONObject;
82
 import org.json.JSONObject;
82
 import java.util.HashMap;
89
 import java.util.HashMap;
83
 import java.util.Locale;
90
 import java.util.Locale;
84
 import java.util.Map;
91
 import java.util.Map;
85
-
86
-import javax.annotation.Nullable;
92
+import java.util.concurrent.atomic.AtomicReference;
87
 
93
 
88
 /**
94
 /**
89
  * Manages instances of {@link WebView}
95
  * Manages instances of {@link WebView}
111
  */
117
  */
112
 @ReactModule(name = RNCWebViewManager.REACT_CLASS)
118
 @ReactModule(name = RNCWebViewManager.REACT_CLASS)
113
 public class RNCWebViewManager extends SimpleViewManager<WebView> {
119
 public class RNCWebViewManager extends SimpleViewManager<WebView> {
120
+  private static final String TAG = "RNCWebViewManager";
114
 
121
 
115
   public static final int COMMAND_GO_BACK = 1;
122
   public static final int COMMAND_GO_BACK = 1;
116
   public static final int COMMAND_GO_FORWARD = 2;
123
   public static final int COMMAND_GO_FORWARD = 2;
134
   // Use `webView.loadUrl("about:blank")` to reliably reset the view
141
   // Use `webView.loadUrl("about:blank")` to reliably reset the view
135
   // state and release page resources (including any running JavaScript).
142
   // state and release page resources (including any running JavaScript).
136
   protected static final String BLANK_URL = "about:blank";
143
   protected static final String BLANK_URL = "about:blank";
144
+  protected static final int SHOULD_OVERRIDE_URL_LOADING_TIMEOUT = 250;
137
   protected WebViewConfig mWebViewConfig;
145
   protected WebViewConfig mWebViewConfig;
138
 
146
 
139
   protected RNCWebChromeClient mWebChromeClient = null;
147
   protected RNCWebChromeClient mWebChromeClient = null;
297
     }
305
     }
298
   }
306
   }
299
 
307
 
308
+  @ReactProp(name = "androidLayerType")
309
+  public void setLayerType(WebView view, String layerTypeString) {
310
+    int layerType = View.LAYER_TYPE_NONE;
311
+    switch (layerTypeString) {
312
+        case "hardware":
313
+          layerType = View.LAYER_TYPE_HARDWARE;
314
+          break;
315
+        case "software":
316
+          layerType = View.LAYER_TYPE_SOFTWARE;
317
+          break;
318
+    }
319
+    view.setLayerType(layerType, null);
320
+  }
321
+
322
+
300
   @ReactProp(name = "overScrollMode")
323
   @ReactProp(name = "overScrollMode")
301
   public void setOverScrollMode(WebView view, String overScrollModeString) {
324
   public void setOverScrollMode(WebView view, String overScrollModeString) {
302
     Integer overScrollMode;
325
     Integer overScrollMode;
430
 
453
 
431
   @ReactProp(name = "incognito")
454
   @ReactProp(name = "incognito")
432
   public void setIncognito(WebView view, boolean enabled) {
455
   public void setIncognito(WebView view, boolean enabled) {
456
+    // Don't do anything when incognito is disabled
457
+    if (!enabled) {
458
+      return;
459
+    }
460
+
433
     // Remove all previous cookies
461
     // Remove all previous cookies
434
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
462
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
435
       CookieManager.getInstance().removeAllCookies(null);
463
       CookieManager.getInstance().removeAllCookies(null);
439
 
467
 
440
     // Disable caching
468
     // Disable caching
441
     view.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
469
     view.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
442
-    view.getSettings().setAppCacheEnabled(!enabled);
470
+    view.getSettings().setAppCacheEnabled(false);
443
     view.clearHistory();
471
     view.clearHistory();
444
-    view.clearCache(enabled);
472
+    view.clearCache(true);
445
 
473
 
446
     // No form data or autofill enabled
474
     // No form data or autofill enabled
447
     view.clearFormData();
475
     view.clearFormData();
448
-    view.getSettings().setSavePassword(!enabled);
449
-    view.getSettings().setSaveFormData(!enabled);
476
+    view.getSettings().setSavePassword(false);
477
+    view.getSettings().setSaveFormData(false);
450
   }
478
   }
451
 
479
 
452
   @ReactProp(name = "source")
480
   @ReactProp(name = "source")
576
     export.put(TopShouldStartLoadWithRequestEvent.EVENT_NAME, MapBuilder.of("registrationName", "onShouldStartLoadWithRequest"));
604
     export.put(TopShouldStartLoadWithRequestEvent.EVENT_NAME, MapBuilder.of("registrationName", "onShouldStartLoadWithRequest"));
577
     export.put(ScrollEventType.getJSEventName(ScrollEventType.SCROLL), MapBuilder.of("registrationName", "onScroll"));
605
     export.put(ScrollEventType.getJSEventName(ScrollEventType.SCROLL), MapBuilder.of("registrationName", "onScroll"));
578
     export.put(TopHttpErrorEvent.EVENT_NAME, MapBuilder.of("registrationName", "onHttpError"));
606
     export.put(TopHttpErrorEvent.EVENT_NAME, MapBuilder.of("registrationName", "onHttpError"));
607
+    export.put(TopRenderProcessGoneEvent.EVENT_NAME, MapBuilder.of("registrationName", "onRenderProcessGone"));
579
     return export;
608
     return export;
580
   }
609
   }
581
 
610
 
772
       mLastLoadFailed = false;
801
       mLastLoadFailed = false;
773
 
802
 
774
       RNCWebView reactWebView = (RNCWebView) webView;
803
       RNCWebView reactWebView = (RNCWebView) webView;
775
-      reactWebView.callInjectedJavaScriptBeforeContentLoaded();       
804
+      reactWebView.callInjectedJavaScriptBeforeContentLoaded();
776
 
805
 
777
       dispatchEvent(
806
       dispatchEvent(
778
         webView,
807
         webView,
783
 
812
 
784
     @Override
813
     @Override
785
     public boolean shouldOverrideUrlLoading(WebView view, String url) {
814
     public boolean shouldOverrideUrlLoading(WebView view, String url) {
786
-      progressChangedFilter.setWaitingForCommandLoadUrl(true);
787
-      dispatchEvent(
788
-        view,
789
-        new TopShouldStartLoadWithRequestEvent(
790
-          view.getId(),
791
-          createWebViewEvent(view, url)));
792
-      return true;
793
-    }
815
+      final RNCWebView rncWebView = (RNCWebView) view;
816
+      final boolean isJsDebugging = ((ReactContext) view.getContext()).getJavaScriptContextHolder().get() == 0;
817
+
818
+      if (!isJsDebugging && rncWebView.mCatalystInstance != null) {
819
+        final Pair<Integer, AtomicReference<ShouldOverrideCallbackState>> lock = RNCWebViewModule.shouldOverrideUrlLoadingLock.getNewLock();
820
+        final int lockIdentifier = lock.first;
821
+        final AtomicReference<ShouldOverrideCallbackState> lockObject = lock.second;
794
 
822
 
823
+        final WritableMap event = createWebViewEvent(view, url);
824
+        event.putInt("lockIdentifier", lockIdentifier);
825
+        rncWebView.sendDirectMessage("onShouldStartLoadWithRequest", event);
826
+
827
+        try {
828
+          assert lockObject != null;
829
+          synchronized (lockObject) {
830
+            final long startTime = SystemClock.elapsedRealtime();
831
+            while (lockObject.get() == ShouldOverrideCallbackState.UNDECIDED) {
832
+              if (SystemClock.elapsedRealtime() - startTime > SHOULD_OVERRIDE_URL_LOADING_TIMEOUT) {
833
+                FLog.w(TAG, "Did not receive response to shouldOverrideUrlLoading in time, defaulting to allow loading.");
834
+                RNCWebViewModule.shouldOverrideUrlLoadingLock.removeLock(lockIdentifier);
835
+                return false;
836
+              }
837
+              lockObject.wait(SHOULD_OVERRIDE_URL_LOADING_TIMEOUT);
838
+            }
839
+          }
840
+        } catch (InterruptedException e) {
841
+          FLog.e(TAG, "shouldOverrideUrlLoading was interrupted while waiting for result.", e);
842
+          RNCWebViewModule.shouldOverrideUrlLoadingLock.removeLock(lockIdentifier);
843
+          return false;
844
+        }
845
+
846
+        final boolean shouldOverride = lockObject.get() == ShouldOverrideCallbackState.SHOULD_OVERRIDE;
847
+        RNCWebViewModule.shouldOverrideUrlLoadingLock.removeLock(lockIdentifier);
848
+
849
+        return shouldOverride;
850
+      } else {
851
+        FLog.w(TAG, "Couldn't use blocking synchronous call for onShouldStartLoadWithRequest due to debugging or missing Catalyst instance, falling back to old event-and-load.");
852
+        progressChangedFilter.setWaitingForCommandLoadUrl(true);
853
+        dispatchEvent(
854
+          view,
855
+          new TopShouldStartLoadWithRequestEvent(
856
+            view.getId(),
857
+            createWebViewEvent(view, url)));
858
+        return true;
859
+      }
860
+    }
795
 
861
 
796
     @TargetApi(Build.VERSION_CODES.N)
862
     @TargetApi(Build.VERSION_CODES.N)
797
     @Override
863
     @Override
844
           case SslError.SSL_UNTRUSTED:
910
           case SslError.SSL_UNTRUSTED:
845
             description = "The certificate authority is not trusted";
911
             description = "The certificate authority is not trusted";
846
             break;
912
             break;
847
-          default: 
913
+          default:
848
             description = "Unknown SSL Error";
914
             description = "Unknown SSL Error";
849
             break;
915
             break;
850
         }
916
         }
851
-        
917
+
852
         description = descriptionPrefix + description;
918
         description = descriptionPrefix + description;
853
 
919
 
854
         this.onReceivedError(
920
         this.onReceivedError(
858
           failingUrl
924
           failingUrl
859
         );
925
         );
860
     }
926
     }
861
-    
927
+
862
     @Override
928
     @Override
863
     public void onReceivedError(
929
     public void onReceivedError(
864
       WebView webView,
930
       WebView webView,
915
       }
981
       }
916
     }
982
     }
917
 
983
 
984
+    @TargetApi(Build.VERSION_CODES.O)
985
+    @Override
986
+    public boolean onRenderProcessGone(WebView webView, RenderProcessGoneDetail detail) {
987
+        // WebViewClient.onRenderProcessGone was added in O.
988
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
989
+            return false;
990
+        }
991
+        super.onRenderProcessGone(webView, detail);
992
+
993
+        if(detail.didCrash()){
994
+          Log.e("RNCWebViewManager", "The WebView rendering process crashed.");
995
+        }
996
+        else{
997
+          Log.w("RNCWebViewManager", "The WebView rendering process was killed by the system.");
998
+        }
999
+
1000
+        // if webView is null, we cannot return any event
1001
+        // since the view is already dead/disposed
1002
+        // still prevent the app crash by returning true.
1003
+        if(webView == null){
1004
+          return true;
1005
+        }
1006
+
1007
+        WritableMap event = createWebViewEvent(webView, webView.getUrl());
1008
+        event.putBoolean("didCrash", detail.didCrash());
1009
+
1010
+        dispatchEvent(
1011
+          webView,
1012
+          new TopRenderProcessGoneEvent(webView.getId(), event)
1013
+        );
1014
+
1015
+        // returning false would crash the app.
1016
+        return true;
1017
+    }
1018
+
918
     protected void emitFinishEvent(WebView webView, String url) {
1019
     protected void emitFinishEvent(WebView webView, String url) {
919
       dispatchEvent(
1020
       dispatchEvent(
920
         webView,
1021
         webView,
1121
      */
1222
      */
1122
     public RNCWebView(ThemedReactContext reactContext) {
1223
     public RNCWebView(ThemedReactContext reactContext) {
1123
       super(reactContext);
1224
       super(reactContext);
1225
+      this.createCatalystInstance();
1124
       progressChangedFilter = new ProgressChangedFilter();
1226
       progressChangedFilter = new ProgressChangedFilter();
1125
     }
1227
     }
1126
 
1228
 
1229
 
1331
 
1230
       if (enabled) {
1332
       if (enabled) {
1231
         addJavascriptInterface(createRNCWebViewBridge(this), JAVASCRIPT_INTERFACE);
1333
         addJavascriptInterface(createRNCWebViewBridge(this), JAVASCRIPT_INTERFACE);
1232
-        this.createCatalystInstance();
1233
       } else {
1334
       } else {
1234
         removeJavascriptInterface(JAVASCRIPT_INTERFACE);
1335
         removeJavascriptInterface(JAVASCRIPT_INTERFACE);
1235
       }
1336
       }
1285
             data.putString("data", message);
1386
             data.putString("data", message);
1286
 
1387
 
1287
             if (mCatalystInstance != null) {
1388
             if (mCatalystInstance != null) {
1288
-              mContext.sendDirectMessage(data);
1389
+              mContext.sendDirectMessage("onMessage", data);
1289
             } else {
1390
             } else {
1290
               dispatchEvent(webView, new TopMessageEvent(webView.getId(), data));
1391
               dispatchEvent(webView, new TopMessageEvent(webView.getId(), data));
1291
             }
1392
             }
1296
         eventData.putString("data", message);
1397
         eventData.putString("data", message);
1297
 
1398
 
1298
         if (mCatalystInstance != null) {
1399
         if (mCatalystInstance != null) {
1299
-          this.sendDirectMessage(eventData);
1400
+          this.sendDirectMessage("onMessage", eventData);
1300
         } else {
1401
         } else {
1301
           dispatchEvent(this, new TopMessageEvent(this.getId(), eventData));
1402
           dispatchEvent(this, new TopMessageEvent(this.getId(), eventData));
1302
         }
1403
         }
1303
       }
1404
       }
1304
     }
1405
     }
1305
 
1406
 
1306
-    protected void sendDirectMessage(WritableMap data) {
1407
+    protected void sendDirectMessage(final String method, WritableMap data) {
1307
       WritableNativeMap event = new WritableNativeMap();
1408
       WritableNativeMap event = new WritableNativeMap();
1308
       event.putMap("nativeEvent", data);
1409
       event.putMap("nativeEvent", data);
1309
 
1410
 
1310
       WritableNativeArray params = new WritableNativeArray();
1411
       WritableNativeArray params = new WritableNativeArray();
1311
       params.pushMap(event);
1412
       params.pushMap(event);
1312
 
1413
 
1313
-      mCatalystInstance.callFunction(messagingModuleName, "onMessage", params);
1414
+      mCatalystInstance.callFunction(messagingModuleName, method, params);
1314
     }
1415
     }
1315
 
1416
 
1316
     protected void onScrollChanged(int x, int y, int oldX, int oldY) {
1417
     protected void onScrollChanged(int x, int y, int oldX, int oldY) {

+ 45
- 1
android/src/main/java/com/reactnativecommunity/webview/RNCWebViewModule.java View File

12
 import android.os.Parcelable;
12
 import android.os.Parcelable;
13
 import android.provider.MediaStore;
13
 import android.provider.MediaStore;
14
 
14
 
15
+import androidx.annotation.Nullable;
15
 import androidx.annotation.RequiresApi;
16
 import androidx.annotation.RequiresApi;
16
 import androidx.core.content.ContextCompat;
17
 import androidx.core.content.ContextCompat;
17
 import androidx.core.content.FileProvider;
18
 import androidx.core.content.FileProvider;
19
+import androidx.core.util.Pair;
18
 
20
 
19
 import android.util.Log;
21
 import android.util.Log;
20
 import android.webkit.MimeTypeMap;
22
 import android.webkit.MimeTypeMap;
35
 import java.io.IOException;
37
 import java.io.IOException;
36
 import java.util.ArrayList;
38
 import java.util.ArrayList;
37
 import java.util.Arrays;
39
 import java.util.Arrays;
40
+import java.util.HashMap;
41
+import java.util.concurrent.atomic.AtomicReference;
38
 
42
 
39
 import static android.app.Activity.RESULT_OK;
43
 import static android.app.Activity.RESULT_OK;
40
 
44
 
50
   private File outputVideo;
54
   private File outputVideo;
51
   private DownloadManager.Request downloadRequest;
55
   private DownloadManager.Request downloadRequest;
52
 
56
 
57
+  protected static class ShouldOverrideUrlLoadingLock {
58
+    protected enum ShouldOverrideCallbackState {
59
+      UNDECIDED,
60
+      SHOULD_OVERRIDE,
61
+      DO_NOT_OVERRIDE,
62
+    }
63
+
64
+    private int nextLockIdentifier = 0;
65
+    private final HashMap<Integer, AtomicReference<ShouldOverrideCallbackState>> shouldOverrideLocks = new HashMap<>();
66
+
67
+    public synchronized Pair<Integer, AtomicReference<ShouldOverrideCallbackState>> getNewLock() {
68
+      final int lockIdentifier = nextLockIdentifier++;
69
+      final AtomicReference<ShouldOverrideCallbackState> shouldOverride = new AtomicReference<>(ShouldOverrideCallbackState.UNDECIDED);
70
+      shouldOverrideLocks.put(lockIdentifier, shouldOverride);
71
+      return new Pair<>(lockIdentifier, shouldOverride);
72
+    }
73
+
74
+    @Nullable
75
+    public synchronized AtomicReference<ShouldOverrideCallbackState> getLock(Integer lockIdentifier) {
76
+      return shouldOverrideLocks.get(lockIdentifier);
77
+    }
78
+
79
+    public synchronized void removeLock(Integer lockIdentifier) {
80
+      shouldOverrideLocks.remove(lockIdentifier);
81
+    }
82
+  }
83
+
84
+  protected static final ShouldOverrideUrlLoadingLock shouldOverrideUrlLoadingLock = new ShouldOverrideUrlLoadingLock();
85
+
53
   private enum MimeType {
86
   private enum MimeType {
54
     DEFAULT("*/*"),
87
     DEFAULT("*/*"),
55
     IMAGE("image"),
88
     IMAGE("image"),
105
     promise.resolve(result);
138
     promise.resolve(result);
106
   }
139
   }
107
 
140
 
141
+  @ReactMethod(isBlockingSynchronousMethod = true)
142
+  public void onShouldStartLoadWithRequestCallback(final boolean shouldStart, final int lockIdentifier) {
143
+    final AtomicReference<ShouldOverrideUrlLoadingLock.ShouldOverrideCallbackState> lockObject = shouldOverrideUrlLoadingLock.getLock(lockIdentifier);
144
+    if (lockObject != null) {
145
+      synchronized (lockObject) {
146
+        lockObject.set(shouldStart ? ShouldOverrideUrlLoadingLock.ShouldOverrideCallbackState.DO_NOT_OVERRIDE : ShouldOverrideUrlLoadingLock.ShouldOverrideCallbackState.SHOULD_OVERRIDE);
147
+        lockObject.notify();
148
+      }
149
+    }
150
+  }
151
+
108
   public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
152
   public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
109
 
153
 
110
     if (filePathCallback == null && filePathCallbackLegacy == null) {
154
     if (filePathCallback == null && filePathCallbackLegacy == null) {
273
 
317
 
274
   public boolean grantFileDownloaderPermissions() {
318
   public boolean grantFileDownloaderPermissions() {
275
     // Permission not required for Android Q and above
319
     // Permission not required for Android Q and above
276
-    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
320
+    if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
277
       return true;
321
       return true;
278
     }
322
     }
279
 
323
 

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

1
+package com.reactnativecommunity.webview.events
2
+
3
+import com.facebook.react.bridge.WritableMap
4
+import com.facebook.react.uimanager.events.Event
5
+import com.facebook.react.uimanager.events.RCTEventEmitter
6
+
7
+/**
8
+ * Event emitted when the WebView's process has crashed or
9
+   was killed by the OS.
10
+ */
11
+class TopRenderProcessGoneEvent(viewId: Int, private val mEventData: WritableMap) :
12
+  Event<TopRenderProcessGoneEvent>(viewId) {
13
+  companion object {
14
+    const val EVENT_NAME = "topRenderProcessGone"
15
+  }
16
+
17
+  override fun getEventName(): String = EVENT_NAME
18
+
19
+  override fun canCoalesce(): Boolean = false
20
+
21
+  override fun getCoalescingKey(): Short = 0
22
+
23
+  override fun dispatch(rctEventEmitter: RCTEventEmitter) =
24
+    rctEventEmitter.receiveEvent(viewTag, eventName, mEventData)
25
+
26
+}

+ 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

+ 8
- 0
apple/RNCWebView.h View File

62
 @property (nonatomic, assign) BOOL directionalLockEnabled;
62
 @property (nonatomic, assign) BOOL directionalLockEnabled;
63
 @property (nonatomic, assign) BOOL ignoreSilentHardwareSwitch;
63
 @property (nonatomic, assign) BOOL ignoreSilentHardwareSwitch;
64
 @property (nonatomic, copy) NSString * _Nullable allowingReadAccessToURL;
64
 @property (nonatomic, copy) NSString * _Nullable allowingReadAccessToURL;
65
+@property (nonatomic, assign) BOOL pullToRefreshEnabled;
66
+@property (nonatomic, weak) UIRefreshControl * refreshControl;
67
+
68
+#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 /* iOS 13 */
69
+@property (nonatomic, assign) WKContentMode contentMode;
70
+#endif
65
 
71
 
66
 + (void)setClientAuthenticationCredential:(nullable NSURLCredential*)credential;
72
 + (void)setClientAuthenticationCredential:(nullable NSURLCredential*)credential;
67
 + (void)setCustomCertificatesForHost:(nullable NSDictionary *)certificates;
73
 + (void)setCustomCertificatesForHost:(nullable NSDictionary *)certificates;
71
 - (void)goBack;
77
 - (void)goBack;
72
 - (void)reload;
78
 - (void)reload;
73
 - (void)stopLoading;
79
 - (void)stopLoading;
80
+- (void)addPullToRefreshControl;
81
+- (void)pullToRefresh:(UIRefreshControl *)refreshControl;
74
 
82
 
75
 @end
83
 @end

+ 48
- 38
apple/RNCWebView.m View File

226
   }
226
   }
227
   wkWebViewConfig.userContentController = [WKUserContentController new];
227
   wkWebViewConfig.userContentController = [WKUserContentController new];
228
 
228
 
229
+#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 /* iOS 13 */
230
+  if (@available(iOS 13.0, *)) {
231
+    WKWebpagePreferences *pagePrefs = [[WKWebpagePreferences alloc]init];
232
+    pagePrefs.preferredContentMode = _contentMode;
233
+    wkWebViewConfig.defaultWebpagePreferences = pagePrefs;
234
+  }
235
+#endif
236
+
229
   // Shim the HTML5 history API:
237
   // Shim the HTML5 history API:
230
   [wkWebViewConfig.userContentController addScriptMessageHandler:[[RNCWeakScriptMessageDelegate alloc] initWithDelegate:self]
238
   [wkWebViewConfig.userContentController addScriptMessageHandler:[[RNCWeakScriptMessageDelegate alloc] initWithDelegate:self]
231
                                                             name:HistoryShimName];
239
                                                             name:HistoryShimName];
267
     _webView.UIDelegate = self;
275
     _webView.UIDelegate = self;
268
     _webView.navigationDelegate = self;
276
     _webView.navigationDelegate = self;
269
 #if !TARGET_OS_OSX
277
 #if !TARGET_OS_OSX
278
+    if (_pullToRefreshEnabled) {
279
+        [self addPullToRefreshControl];
280
+    }
270
     _webView.scrollView.scrollEnabled = _scrollEnabled;
281
     _webView.scrollView.scrollEnabled = _scrollEnabled;
271
     _webView.scrollView.pagingEnabled = _pagingEnabled;
282
     _webView.scrollView.pagingEnabled = _pagingEnabled;
272
-    _webView.scrollView.bounces = _bounces;
283
+      //For UIRefreshControl to work correctly, the bounces should always be true
284
+    _webView.scrollView.bounces = _pullToRefreshEnabled || _bounces; 
273
     _webView.scrollView.showsHorizontalScrollIndicator = _showsHorizontalScrollIndicator;
285
     _webView.scrollView.showsHorizontalScrollIndicator = _showsHorizontalScrollIndicator;
274
     _webView.scrollView.showsVerticalScrollIndicator = _showsVerticalScrollIndicator;
286
     _webView.scrollView.showsVerticalScrollIndicator = _showsVerticalScrollIndicator;
275
     _webView.scrollView.directionalLockEnabled = _directionalLockEnabled;
287
     _webView.scrollView.directionalLockEnabled = _directionalLockEnabled;
300
   _webView.allowsBackForwardNavigationGestures = _allowsBackForwardNavigationGestures;
312
   _webView.allowsBackForwardNavigationGestures = _allowsBackForwardNavigationGestures;
301
 }
313
 }
302
 
314
 
303
-
304
 - (void)removeFromSuperview
315
 - (void)removeFromSuperview
305
 {
316
 {
306
     if (_webView) {
317
     if (_webView) {
869
  * topViewController
880
  * topViewController
870
  */
881
  */
871
 -(UIViewController *)topViewController{
882
 -(UIViewController *)topViewController{
872
-    UIViewController *controller = [self topViewControllerWithRootViewController:[self getCurrentWindow].rootViewController];
873
-    return controller;
883
+    return RCTPresentedViewController();
874
 }
884
 }
875
 
885
 
876
-/**
877
- * topViewControllerWithRootViewController
878
- */
879
--(UIViewController *)topViewControllerWithRootViewController:(UIViewController *)viewController{
880
-  if (viewController==nil) return nil;
881
-  if (viewController.presentedViewController!=nil) {
882
-    return [self topViewControllerWithRootViewController:viewController.presentedViewController];
883
-  } else if ([viewController isKindOfClass:[UITabBarController class]]){
884
-    return [self topViewControllerWithRootViewController:[(UITabBarController *)viewController selectedViewController]];
885
-  } else if ([viewController isKindOfClass:[UINavigationController class]]){
886
-    return [self topViewControllerWithRootViewController:[(UINavigationController *)viewController visibleViewController]];
887
-  } else {
888
-    return viewController;
889
-  }
890
-}
891
-/**
892
- * getCurrentWindow
893
- */
894
--(UIWindow *)getCurrentWindow{
895
-  UIWindow *window = [UIApplication sharedApplication].keyWindow;
896
-  if (window.windowLevel!=UIWindowLevelNormal) {
897
-    for (UIWindow *wid in [UIApplication sharedApplication].windows) {
898
-      if (window.windowLevel==UIWindowLevelNormal) {
899
-        window = wid;
900
-        break;
901
-      }
902
-    }
903
-  }
904
-  return window;
905
-}
906
 #endif // !TARGET_OS_OSX
886
 #endif // !TARGET_OS_OSX
907
 
887
 
908
 /**
888
 /**
929
 
909
 
930
   WKNavigationType navigationType = navigationAction.navigationType;
910
   WKNavigationType navigationType = navigationAction.navigationType;
931
   NSURLRequest *request = navigationAction.request;
911
   NSURLRequest *request = navigationAction.request;
912
+  BOOL isTopFrame = [request.URL isEqual:request.mainDocumentURL];
932
 
913
 
933
   if (_onShouldStartLoadWithRequest) {
914
   if (_onShouldStartLoadWithRequest) {
934
     NSMutableDictionary<NSString *, id> *event = [self baseEvent];
915
     NSMutableDictionary<NSString *, id> *event = [self baseEvent];
935
     [event addEntriesFromDictionary: @{
916
     [event addEntriesFromDictionary: @{
936
       @"url": (request.URL).absoluteString,
917
       @"url": (request.URL).absoluteString,
937
       @"mainDocumentURL": (request.mainDocumentURL).absoluteString,
918
       @"mainDocumentURL": (request.mainDocumentURL).absoluteString,
938
-      @"navigationType": navigationTypes[@(navigationType)]
919
+      @"navigationType": navigationTypes[@(navigationType)],
920
+      @"isTopFrame": @(isTopFrame)
939
     }];
921
     }];
940
     if (![self.delegate webView:self
922
     if (![self.delegate webView:self
941
       shouldStartLoadForRequest:event
923
       shouldStartLoadForRequest:event
947
 
929
 
948
   if (_onLoadingStart) {
930
   if (_onLoadingStart) {
949
     // We have this check to filter out iframe requests and whatnot
931
     // We have this check to filter out iframe requests and whatnot
950
-    BOOL isTopFrame = [request.URL isEqual:request.mainDocumentURL];
951
     if (isTopFrame) {
932
     if (isTopFrame) {
952
       NSMutableDictionary<NSString *, id> *event = [self baseEvent];
933
       NSMutableDictionary<NSString *, id> *event = [self baseEvent];
953
       [event addEntriesFromDictionary: @{
934
       [event addEntriesFromDictionary: @{
1147
   }
1128
   }
1148
 }
1129
 }
1149
 
1130
 
1131
+- (void)addPullToRefreshControl
1132
+{
1133
+    UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
1134
+    _refreshControl = refreshControl;
1135
+    [_webView.scrollView addSubview: refreshControl];
1136
+    [refreshControl addTarget:self action:@selector(pullToRefresh:) forControlEvents: UIControlEventValueChanged];
1137
+}
1138
+
1139
+- (void)pullToRefresh:(UIRefreshControl *)refreshControl
1140
+{
1141
+    [self reload];
1142
+    [refreshControl endRefreshing];
1143
+}
1144
+
1145
+#if !TARGET_OS_OSX
1146
+- (void)setPullToRefreshEnabled:(BOOL)pullToRefreshEnabled
1147
+{
1148
+    _pullToRefreshEnabled = pullToRefreshEnabled;
1149
+    
1150
+    if (pullToRefreshEnabled) {
1151
+        [self addPullToRefreshControl];
1152
+    } else {
1153
+        [_refreshControl removeFromSuperview];
1154
+    }
1155
+
1156
+    [self setBounces:_bounces];
1157
+}
1158
+#endif // !TARGET_OS_OSX
1159
+
1150
 - (void)stopLoading
1160
 - (void)stopLoading
1151
 {
1161
 {
1152
   [_webView stopLoading];
1162
   [_webView stopLoading];
1156
 - (void)setBounces:(BOOL)bounces
1166
 - (void)setBounces:(BOOL)bounces
1157
 {
1167
 {
1158
   _bounces = bounces;
1168
   _bounces = bounces;
1159
-  _webView.scrollView.bounces = bounces;
1169
+    //For UIRefreshControl to work correctly, the bounces should always be true
1170
+  _webView.scrollView.bounces = _pullToRefreshEnabled || bounces;
1160
 }
1171
 }
1161
 #endif // !TARGET_OS_OSX
1172
 #endif // !TARGET_OS_OSX
1162
 
1173
 
1163
-
1164
 - (void)setInjectedJavaScript:(NSString *)source {
1174
 - (void)setInjectedJavaScript:(NSString *)source {
1165
   _injectedJavaScript = source;
1175
   _injectedJavaScript = source;
1166
 
1176
 

+ 18
- 0
apple/RNCWebViewManager.m View File

14
 @interface RNCWebViewManager () <RNCWebViewDelegate>
14
 @interface RNCWebViewManager () <RNCWebViewDelegate>
15
 @end
15
 @end
16
 
16
 
17
+@implementation RCTConvert (WKWebView)
18
+#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 /* iOS 13 */
19
+RCT_ENUM_CONVERTER(WKContentMode, (@{
20
+    @"recommended": @(WKContentModeRecommended),
21
+    @"mobile": @(WKContentModeMobile),
22
+    @"desktop": @(WKContentModeDesktop),
23
+}), WKContentModeRecommended, integerValue)
24
+#endif
25
+@end
26
+
17
 @implementation RNCWebViewManager
27
 @implementation RNCWebViewManager
18
 {
28
 {
19
   NSConditionLock *_shouldStartLoadLock;
29
   NSConditionLock *_shouldStartLoadLock;
70
 RCT_EXPORT_VIEW_PROPERTY(contentInsetAdjustmentBehavior, UIScrollViewContentInsetAdjustmentBehavior)
80
 RCT_EXPORT_VIEW_PROPERTY(contentInsetAdjustmentBehavior, UIScrollViewContentInsetAdjustmentBehavior)
71
 #endif
81
 #endif
72
 
82
 
83
+#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 /* iOS 13 */
84
+RCT_EXPORT_VIEW_PROPERTY(contentMode, WKContentMode)
85
+#endif
86
+
73
 /**
87
 /**
74
  * Expose methods to enable messaging the webview.
88
  * Expose methods to enable messaging the webview.
75
  */
89
  */
89
   }];
103
   }];
90
 }
104
 }
91
 
105
 
106
+RCT_CUSTOM_VIEW_PROPERTY(pullToRefreshEnabled, BOOL, RNCWebView) {
107
+    view.pullToRefreshEnabled = json == nil ? false : [RCTConvert BOOL: json];
108
+}
109
+
92
 RCT_CUSTOM_VIEW_PROPERTY(bounces, BOOL, RNCWebView) {
110
 RCT_CUSTOM_VIEW_PROPERTY(bounces, BOOL, RNCWebView) {
93
   view.bounces = json == nil ? true : [RCTConvert BOOL: json];
111
   view.bounces = json == nil ? true : [RCTConvert BOOL: json];
94
 }
112
 }

+ 3
- 1
docs/Debugging.md View File

15
 3. Safari -> Develop -> [device name] -> [app name] -> [url - title]
15
 3. Safari -> Develop -> [device name] -> [app name] -> [url - title]
16
 4. You can now debug the WebView contents just as you would on the web
16
 4. You can now debug the WebView contents just as you would on the web
17
 
17
 
18
-##### Note:
18
+##### Notes:
19
 
19
 
20
 When debugging on device you must enable Web Inspector in your device settings:
20
 When debugging on device you must enable Web Inspector in your device settings:
21
 
21
 
22
 Settings -> Safari -> Advanced -> Web Inspector
22
 Settings -> Safari -> Advanced -> Web Inspector
23
 
23
 
24
+Also, if you don't see your device in the Develop menu, and you started Safari before you started your simulator, try restarting Safari.
25
+
24
 ### Android & Chrome
26
 ### Android & Chrome
25
 
27
 
26
 It's possible to debug WebView contents in the Android emulator or on a device using Chrome DevTools.
28
 It's possible to debug WebView contents in the Android emulator or on a device using Chrome DevTools.

+ 2
- 1
docs/Guide.md View File

305
             uri:
305
             uri:
306
               'https://github.com/react-native-community/react-native-webview',
306
               'https://github.com/react-native-community/react-native-webview',
307
           }}
307
           }}
308
+          onMessage={(event) => {}}
308
           injectedJavaScript={runFirst}
309
           injectedJavaScript={runFirst}
309
         />
310
         />
310
       </View>
311
       </View>
313
 }
314
 }
314
 ```
315
 ```
315
 
316
 
316
-This runs the JavaScript in the `runFirst` string once the page is loaded. In this case, you can see that both the body style was changed to red and the alert showed up after 2 seconds.
317
+This runs the JavaScript in the `runFirst` string once the page is loaded. In this case, you can see that both the body style was changed to red and the alert showed up after 2 seconds. An `onMessage` event is required as well to inject the JavaScript code into the WebView.
317
 
318
 
318
 By setting `injectedJavaScriptForMainFrameOnly: false`, the JavaScript injection will occur on all frames (not just the main frame) if supported for the given platform. For example, if a page contains an iframe, the javascript will be injected into that iframe as well with this set to `false`. (Note this is not supported on Android.) There is also `injectedJavaScriptBeforeContentLoadedForMainFrameOnly` for injecting prior to content loading. Read more about this in the [Reference](./Reference.md#injectedjavascriptformainframeonly).
319
 By setting `injectedJavaScriptForMainFrameOnly: false`, the JavaScript injection will occur on all frames (not just the main frame) if supported for the given platform. For example, if a page contains an iframe, the javascript will be injected into that iframe as well with this set to `false`. (Note this is not supported on Android.) There is also `injectedJavaScriptBeforeContentLoadedForMainFrameOnly` for injecting prior to content loading. Read more about this in the [Reference](./Reference.md#injectedjavascriptformainframeonly).
319
 
320
 

+ 161
- 77
docs/Reference.md View File

13
 - [`mediaPlaybackRequiresUserAction`](Reference.md#mediaplaybackrequiresuseraction)
13
 - [`mediaPlaybackRequiresUserAction`](Reference.md#mediaplaybackrequiresuseraction)
14
 - [`nativeConfig`](Reference.md#nativeconfig)
14
 - [`nativeConfig`](Reference.md#nativeconfig)
15
 - [`onError`](Reference.md#onerror)
15
 - [`onError`](Reference.md#onerror)
16
+- [`onRenderProcessGone`](Reference.md#onRenderProcessGone)
16
 - [`onLoad`](Reference.md#onload)
17
 - [`onLoad`](Reference.md#onload)
17
 - [`onLoadEnd`](Reference.md#onloadend)
18
 - [`onLoadEnd`](Reference.md#onloadend)
18
 - [`onLoadStart`](Reference.md#onloadstart)
19
 - [`onLoadStart`](Reference.md#onloadstart)
34
 - [`javaScriptEnabled`](Reference.md#javascriptenabled)
35
 - [`javaScriptEnabled`](Reference.md#javascriptenabled)
35
 - [`javaScriptCanOpenWindowsAutomatically`](Reference.md#javascriptcanopenwindowsautomatically)
36
 - [`javaScriptCanOpenWindowsAutomatically`](Reference.md#javascriptcanopenwindowsautomatically)
36
 - [`androidHardwareAccelerationDisabled`](Reference.md#androidHardwareAccelerationDisabled)
37
 - [`androidHardwareAccelerationDisabled`](Reference.md#androidHardwareAccelerationDisabled)
38
+- [`androidLayerType`](Reference.md#androidLayerType)
37
 - [`mixedContentMode`](Reference.md#mixedcontentmode)
39
 - [`mixedContentMode`](Reference.md#mixedcontentmode)
38
 - [`thirdPartyCookiesEnabled`](Reference.md#thirdpartycookiesenabled)
40
 - [`thirdPartyCookiesEnabled`](Reference.md#thirdpartycookiesenabled)
39
 - [`userAgent`](Reference.md#useragent)
41
 - [`userAgent`](Reference.md#useragent)
44
 - [`overScrollMode`](Reference.md#overscrollmode)
46
 - [`overScrollMode`](Reference.md#overscrollmode)
45
 - [`contentInset`](Reference.md#contentinset)
47
 - [`contentInset`](Reference.md#contentinset)
46
 - [`contentInsetAdjustmentBehavior`](Reference.md#contentInsetAdjustmentBehavior)
48
 - [`contentInsetAdjustmentBehavior`](Reference.md#contentInsetAdjustmentBehavior)
49
+- [`contentMode`](Reference.md#contentMode)
47
 - [`dataDetectorTypes`](Reference.md#datadetectortypes)
50
 - [`dataDetectorTypes`](Reference.md#datadetectortypes)
48
 - [`scrollEnabled`](Reference.md#scrollenabled)
51
 - [`scrollEnabled`](Reference.md#scrollenabled)
49
 - [`directionalLockEnabled`](Reference.md#directionalLockEnabled)
52
 - [`directionalLockEnabled`](Reference.md#directionalLockEnabled)
65
 - [`allowsLinkPreview`](Reference.md#allowsLinkPreview)
68
 - [`allowsLinkPreview`](Reference.md#allowsLinkPreview)
66
 - [`sharedCookiesEnabled`](Reference.md#sharedCookiesEnabled)
69
 - [`sharedCookiesEnabled`](Reference.md#sharedCookiesEnabled)
67
 - [`textZoom`](Reference.md#textZoom)
70
 - [`textZoom`](Reference.md#textZoom)
71
+- [`pullToRefreshEnabled`](Reference.md#pullToRefreshEnabled)
68
 - [`ignoreSilentHardwareSwitch`](Reference.md#ignoreSilentHardwareSwitch)
72
 - [`ignoreSilentHardwareSwitch`](Reference.md#ignoreSilentHardwareSwitch)
69
 - [`onFileDownload`](Reference.md#onFileDownload)
73
 - [`onFileDownload`](Reference.md#onFileDownload)
70
 
74
 
88
 
92
 
89
 ## Props
93
 ## Props
90
 
94
 
91
-### `source`
95
+### `source`[⬆](#props-index)<!-- Link generated with jump2header -->
92
 
96
 
93
 Loads static HTML or a URI (with optional headers) in the WebView. Note that static HTML will require setting [`originWhitelist`](Reference.md#originwhitelist) to `["*"]`.
97
 Loads static HTML or a URI (with optional headers) in the WebView. Note that static HTML will require setting [`originWhitelist`](Reference.md#originwhitelist) to `["*"]`.
94
 
98
 
114
 
118
 
115
 ---
119
 ---
116
 
120
 
117
-### `automaticallyAdjustContentInsets`
121
+### `automaticallyAdjustContentInsets`[⬆](#props-index)<!-- Link generated with jump2header -->
118
 
122
 
119
 Controls whether to adjust the content inset for web views that are placed behind a navigation bar, tab bar, or toolbar. The default value is `true`.
123
 Controls whether to adjust the content inset for web views that are placed behind a navigation bar, tab bar, or toolbar. The default value is `true`.
120
 
124
 
124
 
128
 
125
 ---
129
 ---
126
 
130
 
127
-### `injectedJavaScript`
131
+### `injectedJavaScript`[⬆](#props-index)<!-- Link generated with jump2header -->
128
 
132
 
129
 Set this to provide JavaScript that will be injected into the web page after the document finishes loading, but before other subresources finish loading.
133
 Set this to provide JavaScript that will be injected into the web page after the document finishes loading, but before other subresources finish loading.
130
 
134
 
156
 
160
 
157
 ---
161
 ---
158
 
162
 
159
-### `injectedJavaScriptBeforeContentLoaded`
163
+### `injectedJavaScriptBeforeContentLoaded`[⬆](#props-index)<!-- Link generated with jump2header -->
160
 
164
 
161
 Set this to provide JavaScript that will be injected into the web page after the document element is created, but before other subresources finish loading.
165
 Set this to provide JavaScript that will be injected into the web page after the document element is created, but before other subresources finish loading.
162
 
166
 
188
 
192
 
189
 ---
193
 ---
190
 
194
 
191
-### `injectedJavaScriptForMainFrameOnly`
195
+### `injectedJavaScriptForMainFrameOnly`[⬆](#props-index)<!-- Link generated with jump2header -->
192
 
196
 
193
 If `true` (default; mandatory for Android), loads the `injectedJavaScript` only into the main frame.
197
 If `true` (default; mandatory for Android), loads the `injectedJavaScript` only into the main frame.
194
 
198
 
200
 
204
 
201
 ---
205
 ---
202
 
206
 
203
-### `injectedJavaScriptBeforeContentLoadedForMainFrameOnly`
207
+### `injectedJavaScriptBeforeContentLoadedForMainFrameOnly`[⬆](#props-index)<!-- Link generated with jump2header -->
204
 
208
 
205
 If `true` (default; mandatory for Android), loads the `injectedJavaScriptBeforeContentLoaded` only into the main frame.
209
 If `true` (default; mandatory for Android), loads the `injectedJavaScriptBeforeContentLoaded` only into the main frame.
206
 
210
 
212
 
216
 
213
 ---
217
 ---
214
 
218
 
215
-### `mediaPlaybackRequiresUserAction`
219
+### `mediaPlaybackRequiresUserAction`[⬆](#props-index)<!-- Link generated with jump2header -->
216
 
220
 
217
 Boolean that determines whether HTML5 audio and video requires the user to tap them before they start playing. The default value is `true`. (Android API minimum version 17).
221
 Boolean that determines whether HTML5 audio and video requires the user to tap them before they start playing. The default value is `true`. (Android API minimum version 17).
218
 
222
 
224
 
228
 
225
 ---
229
 ---
226
 
230
 
227
-### `nativeConfig`
231
+### `nativeConfig`[⬆](#props-index)<!-- Link generated with jump2header -->
228
 
232
 
229
 Override the native component used to render the WebView. Enables a custom native WebView which uses the same JavaScript as the original WebView.
233
 Override the native component used to render the WebView. Enables a custom native WebView which uses the same JavaScript as the original WebView.
230
 
234
 
240
 
244
 
241
 ---
245
 ---
242
 
246
 
243
-### `onError`
247
+### `onError`[⬆](#props-index)<!-- Link generated with jump2header -->
244
 
248
 
245
 Function that is invoked when the `WebView` load fails.
249
 Function that is invoked when the `WebView` load fails.
246
 
250
 
280
 
284
 
281
 ---
285
 ---
282
 
286
 
283
-### `onLoad`
287
+### `onLoad`[⬆](#props-index)<!-- Link generated with jump2header -->
284
 
288
 
285
 Function that is invoked when the `WebView` has finished loading.
289
 Function that is invoked when the `WebView` has finished loading.
286
 
290
 
313
 
317
 
314
 ---
318
 ---
315
 
319
 
316
-### `onLoadEnd`
320
+### `onLoadEnd`[⬆](#props-index)<!-- Link generated with jump2header -->
317
 
321
 
318
 Function that is invoked when the `WebView` load succeeds or fails.
322
 Function that is invoked when the `WebView` load succeeds or fails.
319
 
323
 
347
 
351
 
348
 ---
352
 ---
349
 
353
 
350
-### `onLoadStart`
354
+### `onLoadStart`[⬆](#props-index)<!-- Link generated with jump2header -->
351
 
355
 
352
 Function that is invoked when the `WebView` starts loading.
356
 Function that is invoked when the `WebView` starts loading.
353
 
357
 
381
 
385
 
382
 ---
386
 ---
383
 
387
 
384
-### `onLoadProgress`
388
+### `onLoadProgress`[⬆](#props-index)<!-- Link generated with jump2header -->
385
 
389
 
386
 Function that is invoked when the `WebView` is loading.
390
 Function that is invoked when the `WebView` is loading.
387
 
391
 
414
 
418
 
415
 ---
419
 ---
416
 
420
 
417
-### `onHttpError`
421
+### `onHttpError`[⬆](#props-index)<!-- Link generated with jump2header -->
418
 
422
 
419
 Function that is invoked when the `WebView` receives an http error.
423
 Function that is invoked when the `WebView` receives an http error.
420
 
424
 
458
 
462
 
459
 ---
463
 ---
460
 
464
 
461
-### `onMessage`
465
+### `onRenderProcessGone`[⬆](#props-index)<!-- Link generated with jump2header -->
466
+
467
+Function that is invoked when the `WebView` process crashes or is killed by the OS on Android.
468
+
469
+> **_Note_**
470
+> Android API minimum level 26. Android Only
471
+
472
+| Type     | Required |
473
+| -------- | -------- |
474
+| function | No       |
475
+
476
+Example:
477
+
478
+```jsx
479
+<WebView
480
+  source={{ uri: 'https://reactnative.dev' }}
481
+  onRenderProcessGone={syntheticEvent => {
482
+    const { nativeEvent } = syntheticEvent;
483
+    console.warn(
484
+      'WebView Crashed: ',
485
+      nativeEvent.didCrash,
486
+    );
487
+  }}
488
+/>
489
+```
490
+
491
+Function passed to `onRenderProcessGone` is called with a SyntheticEvent wrapping a nativeEvent with these properties:
492
+
493
+```
494
+didCrash
495
+```
496
+---
497
+
498
+### `onMessage`[⬆](#props-index)<!-- Link generated with jump2header -->
462
 
499
 
463
 Function that is invoked when the webview calls `window.ReactNativeWebView.postMessage`. Setting this property will inject this global into your webview.
500
 Function that is invoked when the webview calls `window.ReactNativeWebView.postMessage`. Setting this property will inject this global into your webview.
464
 
501
 
472
 
509
 
473
 ---
510
 ---
474
 
511
 
475
-### `onNavigationStateChange`
512
+### `onNavigationStateChange`[⬆](#props-index)<!-- Link generated with jump2header -->
476
 
513
 
477
 Function that is invoked when the `WebView` loading starts or ends.
514
 Function that is invoked when the `WebView` loading starts or ends.
478
 
515
 
508
 
545
 
509
 ---
546
 ---
510
 
547
 
511
-### `onContentProcessDidTerminate`
548
+### `onContentProcessDidTerminate`[⬆](#props-index)<!-- Link generated with jump2header -->
512
 
549
 
513
 Function that is invoked when the `WebView` content process is terminated.
550
 Function that is invoked when the `WebView` content process is terminated.
514
 
551
 
542
 
579
 
543
 ---
580
 ---
544
 
581
 
545
-### `originWhitelist`
582
+### `originWhitelist`[⬆](#props-index)<!-- Link generated with jump2header -->
546
 
583
 
547
 List of origin strings to allow being navigated to. The strings allow wildcards and get matched against _just_ the origin (not the full URL). If the user taps to navigate to a new page but the new page is not in this whitelist, the URL will be handled by the OS. The default whitelisted origins are "http://*" and "https://*".
584
 List of origin strings to allow being navigated to. The strings allow wildcards and get matched against _just_ the origin (not the full URL). If the user taps to navigate to a new page but the new page is not in this whitelist, the URL will be handled by the OS. The default whitelisted origins are "http://*" and "https://*".
548
 
585
 
562
 
599
 
563
 ---
600
 ---
564
 
601
 
565
-### `renderError`
602
+### `renderError`[⬆](#props-index)<!-- Link generated with jump2header -->
566
 
603
 
567
 Function that returns a view to show if there's an error.
604
 Function that returns a view to show if there's an error.
568
 
605
 
583
 
620
 
584
 ---
621
 ---
585
 
622
 
586
-### `renderLoading`
623
+### `renderLoading`[⬆](#props-index)<!-- Link generated with jump2header -->
587
 
624
 
588
 Function that returns a loading indicator. The startInLoadingState prop must be set to true in order to use this prop.
625
 Function that returns a loading indicator. The startInLoadingState prop must be set to true in order to use this prop.
589
 
626
 
603
 
640
 
604
 ---
641
 ---
605
 
642
 
606
-### `scalesPageToFit`
643
+### `scalesPageToFit`[⬆](#props-index)<!-- Link generated with jump2header -->
607
 
644
 
608
 Boolean that controls whether the web content is scaled to fit the view and enables the user to change the scale. The default value is `true`.
645
 Boolean that controls whether the web content is scaled to fit the view and enables the user to change the scale. The default value is `true`.
609
 
646
 
613
 
650
 
614
 ---
651
 ---
615
 
652
 
616
-### `onShouldStartLoadWithRequest`
653
+### `onShouldStartLoadWithRequest`[⬆](#props-index)<!-- Link generated with jump2header -->
617
 
654
 
618
 Function that allows custom handling of any web view requests. Return `true` from the function to continue loading the request and `false` to stop loading.
655
 Function that allows custom handling of any web view requests. Return `true` from the function to continue loading the request and `false` to stop loading.
619
 
656
 
647
 lockIdentifier
684
 lockIdentifier
648
 mainDocumentURL (iOS only)
685
 mainDocumentURL (iOS only)
649
 navigationType
686
 navigationType
687
+isTopFrame
650
 ```
688
 ```
651
 
689
 
652
 ---
690
 ---
653
 
691
 
654
-### `startInLoadingState`
692
+### `startInLoadingState`[⬆](#props-index)<!-- Link generated with jump2header -->
655
 
693
 
656
 Boolean value that forces the `WebView` to show the loading view on the first load. This prop must be set to `true` in order for the `renderLoading` prop to work.
694
 Boolean value that forces the `WebView` to show the loading view on the first load. This prop must be set to `true` in order for the `renderLoading` prop to work.
657
 
695
 
661
 
699
 
662
 ---
700
 ---
663
 
701
 
664
-### `style`
702
+### `style`[⬆](#props-index)<!-- Link generated with jump2header -->
665
 
703
 
666
 A style object that allow you to customize the `WebView` style. Please note that there are default styles (example: you need to add `flex: 0` to the style if you want to use `height` property).
704
 A style object that allow you to customize the `WebView` style. Please note that there are default styles (example: you need to add `flex: 0` to the style if you want to use `height` property).
667
 
705
 
680
 
718
 
681
 ---
719
 ---
682
 
720
 
683
-### `containerStyle`
721
+### `containerStyle`[⬆](#props-index)<!-- Link generated with jump2header -->
684
 
722
 
685
 A style object that allow you to customize the `WebView` container style. Please note that there are default styles (example: you need to add `flex: 0` to the style if you want to use `height` property).
723
 A style object that allow you to customize the `WebView` container style. Please note that there are default styles (example: you need to add `flex: 0` to the style if you want to use `height` property).
686
 
724
 
699
 
737
 
700
 ---
738
 ---
701
 
739
 
702
-### `decelerationRate`
740
+### `decelerationRate`[⬆](#props-index)<!-- Link generated with jump2header -->
703
 
741
 
704
 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:
742
 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:
705
 
743
 
712
 
750
 
713
 ---
751
 ---
714
 
752
 
715
-### `domStorageEnabled`
753
+### `domStorageEnabled`[⬆](#props-index)<!-- Link generated with jump2header -->
716
 
754
 
717
 Boolean value to control whether DOM Storage is enabled. Used only in Android.
755
 Boolean value to control whether DOM Storage is enabled. Used only in Android.
718
 
756
 
722
 
760
 
723
 ---
761
 ---
724
 
762
 
725
-### `javaScriptEnabled`
763
+### `javaScriptEnabled`[⬆](#props-index)<!-- Link generated with jump2header -->
726
 
764
 
727
 Boolean value to enable JavaScript in the `WebView`. The default value is `true`.
765
 Boolean value to enable JavaScript in the `WebView`. The default value is `true`.
728
 
766
 
732
 
770
 
733
 ---
771
 ---
734
 
772
 
735
-### `javaScriptCanOpenWindowsAutomatically`
773
+### `javaScriptCanOpenWindowsAutomatically`[⬆](#props-index)<!-- Link generated with jump2header -->
736
 
774
 
737
 A Boolean value indicating whether JavaScript can open windows without user interaction. The default value is `false`.
775
 A Boolean value indicating whether JavaScript can open windows without user interaction. The default value is `false`.
738
 
776
 
742
 
780
 
743
 ---
781
 ---
744
 
782
 
745
-### `androidHardwareAccelerationDisabled`
783
+### `androidHardwareAccelerationDisabled`[⬆](#props-index)<!-- Link generated with jump2header -->
746
 
784
 
747
-Boolean value to disable Hardware Acceleration in the `WebView`. Used on Android only as Hardware Acceleration is a feature only for Android. The default value is `false`.
785
+**Deprecated.** Use the `androidLayerType` prop instead. 
748
 
786
 
749
 | Type | Required | Platform |
787
 | Type | Required | Platform |
750
 | ---- | -------- | -------- |
788
 | ---- | -------- | -------- |
752
 
790
 
753
 ---
791
 ---
754
 
792
 
755
-### `mixedContentMode`
793
+### `androidLayerType`[⬆](#props-index)<!-- Link generated with jump2header -->
794
+
795
+Specifies the layer type. 
796
+
797
+Possible values for `androidLayerType` are:
798
+
799
+- `none` (default) - The view does not have a layer.
800
+- `software` - The view has a software layer. A software layer is backed by a bitmap and causes the view to be rendered using Android's software rendering pipeline, even if hardware acceleration is enabled.
801
+- `hardware` - The view has a hardware layer. A hardware layer is backed by a hardware specific texture and causes the view to be rendered using Android's hardware rendering pipeline, but only if hardware acceleration is turned on for the view hierarchy.
802
+
803
+Avoid setting both `androidLayerType` and `androidHardwareAccelerationDisabled` props at the same time, as this may cause undefined behaviour.
804
+
805
+| Type   | Required | Platform |
806
+| ------ | -------- | -------- |
807
+| string | No       | Android  |
808
+
809
+---
810
+
811
+### `mixedContentMode`[⬆](#props-index)<!-- Link generated with jump2header -->
756
 
812
 
757
 Specifies the mixed content mode. i.e WebView will allow a secure origin to load content from any other origin.
813
 Specifies the mixed content mode. i.e WebView will allow a secure origin to load content from any other origin.
758
 
814
 
768
 
824
 
769
 ---
825
 ---
770
 
826
 
771
-### `thirdPartyCookiesEnabled`
827
+### `thirdPartyCookiesEnabled`[⬆](#props-index)<!-- Link generated with jump2header -->
772
 
828
 
773
 Boolean value to enable third party cookies in the `WebView`. Used on Android Lollipop and above only as third party cookies are enabled by default on Android Kitkat and below and on iOS. The default value is `true`. For more on cookies, read the [Guide](Guide.md#Managing-Cookies)
829
 Boolean value to enable third party cookies in the `WebView`. Used on Android Lollipop and above only as third party cookies are enabled by default on Android Kitkat and below and on iOS. The default value is `true`. For more on cookies, read the [Guide](Guide.md#Managing-Cookies)
774
 
830
 
778
 
834
 
779
 ---
835
 ---
780
 
836
 
781
-### `userAgent`
837
+### `userAgent`[⬆](#props-index)<!-- Link generated with jump2header -->
782
 
838
 
783
 Sets the user-agent for the `WebView`.
839
 Sets the user-agent for the `WebView`.
784
 
840
 
788
 
844
 
789
 ---
845
 ---
790
 
846
 
791
-### `applicationNameForUserAgent`
847
+### `applicationNameForUserAgent`[⬆](#props-index)<!-- Link generated with jump2header -->
792
 
848
 
793
 Append to the existing user-agent. Setting `userAgent` will override this.
849
 Append to the existing user-agent. Setting `userAgent` will override this.
794
 
850
 
806
 // Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 DemoApp/1.1.0
862
 // Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 DemoApp/1.1.0
807
 ```
863
 ```
808
 
864
 
809
-### `allowsFullscreenVideo`
865
+### `allowsFullscreenVideo`[⬆](#props-index)<!-- Link generated with jump2header -->
810
 
866
 
811
 Boolean that determines whether videos are allowed to be played in fullscreen. The default value is `false`.
867
 Boolean that determines whether videos are allowed to be played in fullscreen. The default value is `false`.
812
 
868
 
816
 
872
 
817
 ---
873
 ---
818
 
874
 
819
-### `allowsInlineMediaPlayback`
875
+### `allowsInlineMediaPlayback`[⬆](#props-index)<!-- Link generated with jump2header -->
820
 
876
 
821
 Boolean that determines whether HTML5 videos play inline or use the native full-screen controller. The default value is `false`.
877
 Boolean that determines whether HTML5 videos play inline or use the native full-screen controller. The default value is `false`.
822
 
878
 
830
 
886
 
831
 ---
887
 ---
832
 
888
 
833
-### `bounces`
889
+### `bounces`[⬆](#props-index)<!-- Link generated with jump2header -->
834
 
890
 
835
 Boolean value that determines whether the web view bounces when it reaches the edge of the content. The default value is `true`.
891
 Boolean value that determines whether the web view bounces when it reaches the edge of the content. The default value is `true`.
836
 
892
 
840
 
896
 
841
 ---
897
 ---
842
 
898
 
843
-### `overScrollMode`
899
+### `overScrollMode`[⬆](#props-index)<!-- Link generated with jump2header -->
844
 
900
 
845
 Specifies the over scroll mode.
901
 Specifies the over scroll mode.
846
 
902
 
856
 
912
 
857
 ---
913
 ---
858
 
914
 
859
-### `contentInset`
915
+### `contentInset`[⬆](#props-index)<!-- Link generated with jump2header -->
860
 
916
 
861
 The amount by which the web view content is inset from the edges of the scroll view. Defaults to {top: 0, left: 0, bottom: 0, right: 0}.
917
 The amount by which the web view content is inset from the edges of the scroll view. Defaults to {top: 0, left: 0, bottom: 0, right: 0}.
862
 
918
 
866
 
922
 
867
 ---
923
 ---
868
 
924
 
869
-### `contentInsetAdjustmentBehavior`
925
+### `contentInsetAdjustmentBehavior`[⬆](#props-index)<!-- Link generated with jump2header -->
870
 
926
 
871
 This property specifies how the safe area insets are used to modify the content area of the scroll view. The default value of this property is "never". Available on iOS 11 and later. Defaults to `never`.
927
 This property specifies how the safe area insets are used to modify the content area of the scroll view. The default value of this property is "never". Available on iOS 11 and later. Defaults to `never`.
872
 
928
 
883
 
939
 
884
 ---
940
 ---
885
 
941
 
886
-### `dataDetectorTypes`
942
+### `contentMode`[⬆](#props-index)<!-- Link generated with jump2header -->
943
+
944
+Controls the type of content to load. Available on iOS 13 and later. Defaults to `recommended`, which loads mobile content on iPhone & iPad Mini but desktop content on larger iPads.
945
+
946
+See [Introducing Desktop-class Browsing on iPad](https://developer.apple.com/videos/play/wwdc2019/203/) for more.
947
+
948
+Possible values:
949
+
950
+- `recommended`
951
+- `mobile`
952
+- `desktop`
953
+
954
+| Type   | Required | Platform |
955
+| ------ | -------- | -------- |
956
+| string | No       | iOS      |
957
+
958
+---
959
+
960
+### `dataDetectorTypes`[⬆](#props-index)<!-- Link generated with jump2header -->
887
 
961
 
888
 Determines the types of data converted to clickable URLs in the web view's content. By default only phone numbers are detected.
962
 Determines the types of data converted to clickable URLs in the web view's content. By default only phone numbers are detected.
889
 
963
 
907
 
981
 
908
 ---
982
 ---
909
 
983
 
910
-### `scrollEnabled`
984
+### `scrollEnabled`[⬆](#props-index)<!-- Link generated with jump2header -->
911
 
985
 
912
 Boolean value that determines whether scrolling is enabled in the `WebView`. The default value is `true`. Setting this to `false` will prevent the webview from moving the document body when the keyboard appears over an input.
986
 Boolean value that determines whether scrolling is enabled in the `WebView`. The default value is `true`. Setting this to `false` will prevent the webview from moving the document body when the keyboard appears over an input.
913
 
987
 
917
 
991
 
918
 ---
992
 ---
919
 
993
 
920
-### `directionalLockEnabled`
994
+### `directionalLockEnabled`[⬆](#props-index)<!-- Link generated with jump2header -->
921
 
995
 
922
 A Boolean value that determines whether scrolling is disabled in a particular direction.
996
 A Boolean value that determines whether scrolling is disabled in a particular direction.
923
 The default value is `true`.
997
 The default value is `true`.
928
 
1002
 
929
 ---
1003
 ---
930
 
1004
 
931
-### `showsHorizontalScrollIndicator`
1005
+### `showsHorizontalScrollIndicator`[⬆](#props-index)<!-- Link generated with jump2header -->
932
 
1006
 
933
 Boolean value that determines whether a horizontal scroll indicator is shown in the `WebView`. The default value is `true`.
1007
 Boolean value that determines whether a horizontal scroll indicator is shown in the `WebView`. The default value is `true`.
934
 
1008
 
938
 
1012
 
939
 ---
1013
 ---
940
 
1014
 
941
-### `showsVerticalScrollIndicator`
1015
+### `showsVerticalScrollIndicator`[⬆](#props-index)<!-- Link generated with jump2header -->
942
 
1016
 
943
 Boolean value that determines whether a vertical scroll indicator is shown in the `WebView`. The default value is `true`.
1017
 Boolean value that determines whether a vertical scroll indicator is shown in the `WebView`. The default value is `true`.
944
 
1018
 
948
 
1022
 
949
 ---
1023
 ---
950
 
1024
 
951
-### `geolocationEnabled`
1025
+### `geolocationEnabled`[⬆](#props-index)<!-- Link generated with jump2header -->
952
 
1026
 
953
 Set whether Geolocation is enabled in the `WebView`. The default value is `false`. Used only in Android.
1027
 Set whether Geolocation is enabled in the `WebView`. The default value is `false`. Used only in Android.
954
 
1028
 
958
 
1032
 
959
 ---
1033
 ---
960
 
1034
 
961
-### `allowFileAccessFromFileURLs`
1035
+### `allowFileAccessFromFileURLs`[⬆](#props-index)<!-- Link generated with jump2header -->
962
 
1036
 
963
 Boolean that sets whether JavaScript running in the context of a file scheme URL should be allowed to access content from other file scheme URLs. The default value is `false`.
1037
 Boolean that sets whether JavaScript running in the context of a file scheme URL should be allowed to access content from other file scheme URLs. The default value is `false`.
964
 
1038
 
968
 
1042
 
969
 ---
1043
 ---
970
 
1044
 
971
-### `allowUniversalAccessFromFileURLs`
1045
+### `allowUniversalAccessFromFileURLs`[⬆](#props-index)<!-- Link generated with jump2header -->
972
 
1046
 
973
 Boolean that sets whether JavaScript running in the context of a file scheme URL should be allowed to access content from any origin. Including accessing content from other file scheme URLs. The default value is `false`.
1047
 Boolean that sets whether JavaScript running in the context of a file scheme URL should be allowed to access content from any origin. Including accessing content from other file scheme URLs. The default value is `false`.
974
 
1048
 
978
 
1052
 
979
 ---
1053
 ---
980
 
1054
 
981
-### `allowingReadAccessToURL`
1055
+### `allowingReadAccessToURL`[⬆](#props-index)<!-- Link generated with jump2header -->
982
 
1056
 
983
 A String value that indicates which URLs the WebView's file can then reference in scripts, AJAX requests, and CSS imports. This is only used in for WebViews that are loaded with a source.uri set to a `'file://'` URL. If not provided, the default is to only allow read access to the URL provided in source.uri itself.
1057
 A String value that indicates which URLs the WebView's file can then reference in scripts, AJAX requests, and CSS imports. This is only used in for WebViews that are loaded with a source.uri set to a `'file://'` URL. If not provided, the default is to only allow read access to the URL provided in source.uri itself.
984
 
1058
 
988
 
1062
 
989
 ---
1063
 ---
990
 
1064
 
991
-### `url`
1065
+### `url`[⬆](#props-index)<!-- Link generated with jump2header -->
992
 
1066
 
993
 **Deprecated.** Use the `source` prop instead.
1067
 **Deprecated.** Use the `source` prop instead.
994
 
1068
 
998
 
1072
 
999
 ---
1073
 ---
1000
 
1074
 
1001
-### `html`
1075
+### `html`[⬆](#props-index)<!-- Link generated with jump2header -->
1002
 
1076
 
1003
 **Deprecated.** Use the `source` prop instead.
1077
 **Deprecated.** Use the `source` prop instead.
1004
 
1078
 
1008
 
1082
 
1009
 ---
1083
 ---
1010
 
1084
 
1011
-### `keyboardDisplayRequiresUserAction`
1085
+### `keyboardDisplayRequiresUserAction`[⬆](#props-index)<!-- Link generated with jump2header -->
1012
 
1086
 
1013
 If false, web content can programmatically display the keyboard. The default value is `true`.
1087
 If false, web content can programmatically display the keyboard. The default value is `true`.
1014
 
1088
 
1018
 
1092
 
1019
 ---
1093
 ---
1020
 
1094
 
1021
-### `hideKeyboardAccessoryView`
1095
+### `hideKeyboardAccessoryView`[⬆](#props-index)<!-- Link generated with jump2header -->
1022
 
1096
 
1023
 If true, this will hide the keyboard accessory view (< > and Done).
1097
 If true, this will hide the keyboard accessory view (< > and Done).
1024
 
1098
 
1028
 
1102
 
1029
 ---
1103
 ---
1030
 
1104
 
1031
-### `allowsBackForwardNavigationGestures`
1105
+### `allowsBackForwardNavigationGestures`[⬆](#props-index)<!-- Link generated with jump2header -->
1032
 
1106
 
1033
 If true, this will be able horizontal swipe gestures. The default value is `false`.
1107
 If true, this will be able horizontal swipe gestures. The default value is `false`.
1034
 
1108
 
1038
 
1112
 
1039
 ---
1113
 ---
1040
 
1114
 
1041
-### `incognito`
1115
+### `incognito`[⬆](#props-index)<!-- Link generated with jump2header -->
1042
 
1116
 
1043
 Does not store any data within the lifetime of the WebView.
1117
 Does not store any data within the lifetime of the WebView.
1044
 
1118
 
1048
 
1122
 
1049
 ---
1123
 ---
1050
 
1124
 
1051
-### `allowFileAccess`
1125
+### `allowFileAccess`[⬆](#props-index)<!-- Link generated with jump2header -->
1052
 
1126
 
1053
 If true, this will allow access to the file system via `file://` URI's. The default value is `false`.
1127
 If true, this will allow access to the file system via `file://` URI's. The default value is `false`.
1054
 
1128
 
1058
 
1132
 
1059
 ---
1133
 ---
1060
 
1134
 
1061
-### `saveFormDataDisabled`
1135
+### `saveFormDataDisabled`[⬆](#props-index)<!-- Link generated with jump2header -->
1062
 
1136
 
1063
 Sets whether the WebView should disable saving form data. The default value is `false`. This function does not have any effect from Android API level 26 onwards as there is an Autofill feature which stores form data.
1137
 Sets whether the WebView should disable saving form data. The default value is `false`. This function does not have any effect from Android API level 26 onwards as there is an Autofill feature which stores form data.
1064
 
1138
 
1068
 
1142
 
1069
 ---
1143
 ---
1070
 
1144
 
1071
-### `cacheEnabled`
1145
+### `cacheEnabled`[⬆](#props-index)<!-- Link generated with jump2header -->
1072
 
1146
 
1073
 Sets whether WebView should use browser caching.
1147
 Sets whether WebView should use browser caching.
1074
 
1148
 
1078
 
1152
 
1079
 ---
1153
 ---
1080
 
1154
 
1081
-### `cacheMode`
1155
+### `cacheMode`[⬆](#props-index)<!-- Link generated with jump2header -->
1082
 
1156
 
1083
 Overrides the way the cache is used. The way the cache is used is based on the navigation type. For a normal page load, the cache is checked and content is re-validated as needed. When navigating back, content is not revalidated, instead the content is just retrieved from the cache. This property allows the client to override this behavior.
1157
 Overrides the way the cache is used. The way the cache is used is based on the navigation type. For a normal page load, the cache is checked and content is re-validated as needed. When navigating back, content is not revalidated, instead the content is just retrieved from the cache. This property allows the client to override this behavior.
1084
 
1158
 
1095
 
1169
 
1096
 ---
1170
 ---
1097
 
1171
 
1098
-### `pagingEnabled`
1172
+### `pagingEnabled`[⬆](#props-index)<!-- Link generated with jump2header -->
1099
 
1173
 
1100
 If the value of this property is true, the scroll view stops on multiples of the scroll view’s bounds when the user scrolls. The default value is false.
1174
 If the value of this property is true, the scroll view stops on multiples of the scroll view’s bounds when the user scrolls. The default value is false.
1101
 
1175
 
1105
 
1179
 
1106
 ---
1180
 ---
1107
 
1181
 
1108
-### `allowsLinkPreview`
1182
+### `allowsLinkPreview`[⬆](#props-index)<!-- Link generated with jump2header -->
1109
 
1183
 
1110
 A Boolean value that determines whether pressing on a link displays a preview of the destination for the link. In iOS this property is available on devices that support 3D Touch. In iOS 10 and later, the default value is true; before that, the default value is false.
1184
 A Boolean value that determines whether pressing on a link displays a preview of the destination for the link. In iOS this property is available on devices that support 3D Touch. In iOS 10 and later, the default value is true; before that, the default value is false.
1111
 
1185
 
1115
 
1189
 
1116
 ---
1190
 ---
1117
 
1191
 
1118
-### `sharedCookiesEnabled`
1192
+### `sharedCookiesEnabled`[⬆](#props-index)<!-- Link generated with jump2header -->
1119
 
1193
 
1120
 Set `true` if shared cookies from `[NSHTTPCookieStorage sharedHTTPCookieStorage]` should used for every load request in the WebView. The default value is `false`. For more on cookies, read the [Guide](Guide.md#Managing-Cookies)
1194
 Set `true` if shared cookies from `[NSHTTPCookieStorage sharedHTTPCookieStorage]` should used for every load request in the WebView. The default value is `false`. For more on cookies, read the [Guide](Guide.md#Managing-Cookies)
1121
 
1195
 
1125
 
1199
 
1126
 ---
1200
 ---
1127
 
1201
 
1128
-### `textZoom`
1202
+### `textZoom`[⬆](#props-index)<!-- Link generated with jump2header -->
1129
 
1203
 
1130
 If the user has set a custom font size in the Android system, an undesirable scale of the site interface in WebView occurs.
1204
 If the user has set a custom font size in the Android system, an undesirable scale of the site interface in WebView occurs.
1131
 
1205
 
1139
 
1213
 
1140
 `<WebView textZoom={100} />`
1214
 `<WebView textZoom={100} />`
1141
 
1215
 
1142
-### `ignoreSilentHardwareSwitch`
1216
+---
1217
+
1218
+### `pullToRefreshEnabled`[⬆](#props-index)<!-- Link generated with jump2header -->
1219
+
1220
+Boolean value that determines whether a pull to refresh gesture is available in the `WebView`. The default value is `false`. If `true`, sets `bounces` automatically to `true`.
1221
+
1222
+| Type    | Required | Platform |
1223
+| ------- | -------- | -------- |
1224
+| boolean | No       | iOS      |
1225
+
1226
+### `ignoreSilentHardwareSwitch`[⬆](#props-index)<!-- Link generated with jump2header -->
1143
 
1227
 
1144
 (ios only)
1228
 (ios only)
1145
 
1229
 
1149
 | ------- | -------- | -------- |
1233
 | ------- | -------- | -------- |
1150
 | boolean | No       | iOS      |
1234
 | boolean | No       | iOS      |
1151
 
1235
 
1152
-### `onFileDownload`
1236
+### `onFileDownload`[⬆](#props-index)<!-- Link generated with jump2header -->
1153
 This property is iOS-only.
1237
 This property is iOS-only.
1154
 
1238
 
1155
 Function that is invoked when the client needs to download a file.
1239
 Function that is invoked when the client needs to download a file.
1183
 
1267
 
1184
 ## Methods
1268
 ## Methods
1185
 
1269
 
1186
-### `extraNativeComponentConfig()`
1270
+### `extraNativeComponentConfig()`[⬆](#methods-index)<!-- Link generated with jump2header -->
1187
 
1271
 
1188
 ```javascript
1272
 ```javascript
1189
 static extraNativeComponentConfig()
1273
 static extraNativeComponentConfig()
1190
 ```
1274
 ```
1191
 
1275
 
1192
-### `goForward()`
1276
+### `goForward()`[⬆](#methods-index)<!-- Link generated with jump2header -->
1193
 
1277
 
1194
 ```javascript
1278
 ```javascript
1195
 goForward();
1279
 goForward();
1197
 
1281
 
1198
 Go forward one page in the web view's history.
1282
 Go forward one page in the web view's history.
1199
 
1283
 
1200
-### `goBack()`
1284
+### `goBack()`[⬆](#methods-index)<!-- Link generated with jump2header -->
1201
 
1285
 
1202
 ```javascript
1286
 ```javascript
1203
 goBack();
1287
 goBack();
1205
 
1289
 
1206
 Go back one page in the web view's history.
1290
 Go back one page in the web view's history.
1207
 
1291
 
1208
-### `reload()`
1292
+### `reload()`[⬆](#methods-index)<!-- Link generated with jump2header -->
1209
 
1293
 
1210
 ```javascript
1294
 ```javascript
1211
 reload();
1295
 reload();
1213
 
1297
 
1214
 Reloads the current page.
1298
 Reloads the current page.
1215
 
1299
 
1216
-### `stopLoading()`
1300
+### `stopLoading()`[⬆](#methods-index)<!-- Link generated with jump2header -->
1217
 
1301
 
1218
 ```javascript
1302
 ```javascript
1219
 stopLoading();
1303
 stopLoading();
1221
 
1305
 
1222
 Stop loading the current page.
1306
 Stop loading the current page.
1223
 
1307
 
1224
-### `injectJavaScript(str)`
1308
+### `injectJavaScript(str)`[⬆](#methods-index)<!-- Link generated with jump2header -->
1225
 
1309
 
1226
 ```javascript
1310
 ```javascript
1227
 injectJavaScript('... javascript string ...');
1311
 injectJavaScript('... javascript string ...');
1231
 
1315
 
1232
 To learn more, read the [Communicating between JS and Native](Guide.md#communicating-between-js-and-native) guide.
1316
 To learn more, read the [Communicating between JS and Native](Guide.md#communicating-between-js-and-native) guide.
1233
 
1317
 
1234
-### `requestFocus()`
1318
+### `requestFocus()`[⬆](#methods-index)<!-- Link generated with jump2header -->
1235
 
1319
 
1236
 ```javascript
1320
 ```javascript
1237
 requestFocus();
1321
 requestFocus();
1239
 
1323
 
1240
 Request the webView to ask for focus. (People working on TV apps might want having a look at this!)
1324
 Request the webView to ask for focus. (People working on TV apps might want having a look at this!)
1241
 
1325
 
1242
-### `postMessage(str)`
1326
+### `postMessage(str)`[⬆](#methods-index)<!-- Link generated with jump2header -->
1243
 
1327
 
1244
 ```javascript
1328
 ```javascript
1245
 postMessage('message');
1329
 postMessage('message');
1246
 ```
1330
 ```
1247
 Post a message to WebView, handled by [`onMessage`](Reference.md#onmessage).
1331
 Post a message to WebView, handled by [`onMessage`](Reference.md#onmessage).
1248
 
1332
 
1249
-### `clearFormData()`
1333
+### `clearFormData()`[⬆](#methods-index)<!-- Link generated with jump2header -->
1250
 
1334
 
1251
 (android only)
1335
 (android only)
1252
 
1336
 
1256
 
1340
 
1257
 Removes the autocomplete popup from the currently focused form field, if present. [developer.android.com reference](<https://developer.android.com/reference/android/webkit/WebView.html#clearFormData()>)
1341
 Removes the autocomplete popup from the currently focused form field, if present. [developer.android.com reference](<https://developer.android.com/reference/android/webkit/WebView.html#clearFormData()>)
1258
 
1342
 
1259
-### `clearCache(bool)`
1343
+### `clearCache(bool)`[⬆](#methods-index)<!-- Link generated with jump2header -->
1260
 
1344
 
1261
 (android only)
1345
 (android only)
1262
 
1346
 
1266
 
1350
 
1267
 Clears the resource cache. Note that the cache is per-application, so this will clear the cache for all WebViews used. [developer.android.com reference](<https://developer.android.com/reference/android/webkit/WebView.html#clearCache(boolean)>)
1351
 Clears the resource cache. Note that the cache is per-application, so this will clear the cache for all WebViews used. [developer.android.com reference](<https://developer.android.com/reference/android/webkit/WebView.html#clearCache(boolean)>)
1268
 
1352
 
1269
-### `clearHistory()`
1353
+### `clearHistory()`[⬆](#methods-index)<!-- Link generated with jump2header -->
1270
 
1354
 
1271
 (android only)
1355
 (android only)
1272
 
1356
 

+ 23
- 0
index.d.ts View File

41
      * Focuses on WebView redered page.
41
      * Focuses on WebView redered page.
42
      */
42
      */
43
     requestFocus: () => void;
43
     requestFocus: () => void;
44
+    
45
+     /**
46
+     * Posts a message to WebView.
47
+     */
48
+    postMessage: (message: string) => void;
49
+    
50
+     /**
51
+     * (Android only)
52
+     * Removes the autocomplete popup from the currently focused form field, if present.
53
+     */
54
+    clearFormData: () => void;
55
+
56
+     /**
57
+     * (Android only)
58
+     * Clears the resource cache. Note that the cache is per-application, so this will clear the cache for all WebViews used.
59
+     */
60
+    clearCache: (clear: boolean) => void;
61
+
62
+     /**
63
+     * (Android only)
64
+     * Tells this WebView to clear its internal back/forward list.
65
+     */
66
+    clearHistory: () => void;
44
 }
67
 }
45
 
68
 
46
 export {WebView};
69
 export {WebView};

+ 2
- 0
metro.config.windows.js View File

35
       new RegExp(
35
       new RegExp(
36
         `${path.resolve(__dirname, 'windows').replace(/[/\\]/g, '/')}.*`,
36
         `${path.resolve(__dirname, 'windows').replace(/[/\\]/g, '/')}.*`,
37
       ),
37
       ),
38
+      // Avoid error EBUSY: resource busy or locked, open '...\vnext\msbuild.ProjectImports.zip' when building 'vnext\Microsoft.ReactNative.sln' with '/bl'
39
+      /.*\.ProjectImports\.zip/,
38
     ]),
40
     ]),
39
   },
41
   },
40
   transformer: {
42
   transformer: {

+ 2
- 3
package.json View File

8
     "Thibault Malbranche <malbranche.thibault@gmail.com>"
8
     "Thibault Malbranche <malbranche.thibault@gmail.com>"
9
   ],
9
   ],
10
   "license": "MIT",
10
   "license": "MIT",
11
-  "version": "10.3.1",
11
+  "version": "10.8.3",
12
   "homepage": "https://github.com/react-native-community/react-native-webview#readme",
12
   "homepage": "https://github.com/react-native-community/react-native-webview#readme",
13
   "scripts": {
13
   "scripts": {
14
     "start": "node node_modules/react-native/local-cli/cli.js start",
14
     "start": "node node_modules/react-native/local-cli/cli.js start",
29
     "type": "Component"
29
     "type": "Component"
30
   },
30
   },
31
   "peerDependencies": {
31
   "peerDependencies": {
32
-    "react": "16.11.0",
33
-    "react-native": ">=0.60 <0.63"
32
+    "react-native": ">=0.60 <0.64"
34
   },
33
   },
35
   "dependencies": {
34
   "dependencies": {
36
     "escape-string-regexp": "2.0.0",
35
     "escape-string-regexp": "2.0.0",

+ 17
- 3
src/WebView.android.tsx View File

21
   defaultRenderLoading,
21
   defaultRenderLoading,
22
 } from './WebViewShared';
22
 } from './WebViewShared';
23
 import {
23
 import {
24
+  WebViewRenderProcessGoneEvent,
24
   WebViewErrorEvent,
25
   WebViewErrorEvent,
25
   WebViewHttpErrorEvent,
26
   WebViewHttpErrorEvent,
26
   WebViewMessageEvent,
27
   WebViewMessageEvent,
60
     saveFormDataDisabled: false,
61
     saveFormDataDisabled: false,
61
     cacheEnabled: true,
62
     cacheEnabled: true,
62
     androidHardwareAccelerationDisabled: false,
63
     androidHardwareAccelerationDisabled: false,
64
+    androidLayerType: 'none',
63
     originWhitelist: defaultOriginWhitelist,
65
     originWhitelist: defaultOriginWhitelist,
64
   };
66
   };
65
 
67
 
75
     lastErrorEvent: null,
77
     lastErrorEvent: null,
76
   };
78
   };
77
 
79
 
80
+  onShouldStartLoadWithRequest: ReturnType<typeof createOnShouldStartLoadWithRequest> | null = null;
78
 
81
 
79
   webViewRef = React.createRef<NativeWebViewAndroid>();
82
   webViewRef = React.createRef<NativeWebViewAndroid>();
80
 
83
 
228
     }
231
     }
229
   }
232
   }
230
 
233
 
234
+  onRenderProcessGone = (event: WebViewRenderProcessGoneEvent) => {
235
+    const { onRenderProcessGone } = this.props;
236
+    if (onRenderProcessGone) {
237
+      onRenderProcessGone(event);
238
+    }
239
+  }
240
+
231
   onLoadingFinish = (event: WebViewNavigationEvent) => {
241
   onLoadingFinish = (event: WebViewNavigationEvent) => {
232
     const { onLoad, onLoadEnd } = this.props;
242
     const { onLoad, onLoadEnd } = this.props;
233
     const { nativeEvent: { url } } = event;
243
     const { nativeEvent: { url } } = event;
271
   onShouldStartLoadWithRequestCallback = (
281
   onShouldStartLoadWithRequestCallback = (
272
     shouldStart: boolean,
282
     shouldStart: boolean,
273
     url: string,
283
     url: string,
284
+    lockIdentifier?: number,
274
   ) => {
285
   ) => {
275
-    if (shouldStart) {
286
+    if (lockIdentifier) {
287
+      NativeModules.RNCWebView.onShouldStartLoadWithRequestCallback(shouldStart, lockIdentifier);
288
+    } else if (shouldStart) {
276
       UIManager.dispatchViewManagerCommand(
289
       UIManager.dispatchViewManagerCommand(
277
         this.getWebViewHandle(),
290
         this.getWebViewHandle(),
278
         this.getCommands().loadUrl,
291
         this.getCommands().loadUrl,
329
     const NativeWebView
342
     const NativeWebView
330
       = (nativeConfig.component as typeof NativeWebViewAndroid) || RNCWebView;
343
       = (nativeConfig.component as typeof NativeWebViewAndroid) || RNCWebView;
331
 
344
 
332
-    const onShouldStartLoadWithRequest = createOnShouldStartLoadWithRequest(
345
+    this.onShouldStartLoadWithRequest = createOnShouldStartLoadWithRequest(
333
       this.onShouldStartLoadWithRequestCallback,
346
       this.onShouldStartLoadWithRequestCallback,
334
       // casting cause it's in the default props
347
       // casting cause it's in the default props
335
       originWhitelist as readonly string[],
348
       originWhitelist as readonly string[],
347
         onLoadingProgress={this.onLoadingProgress}
360
         onLoadingProgress={this.onLoadingProgress}
348
         onLoadingStart={this.onLoadingStart}
361
         onLoadingStart={this.onLoadingStart}
349
         onHttpError={this.onHttpError}
362
         onHttpError={this.onHttpError}
363
+        onRenderProcessGone={this.onRenderProcessGone}
350
         onMessage={this.onMessage}
364
         onMessage={this.onMessage}
351
-        onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
365
+        onShouldStartLoadWithRequest={this.onShouldStartLoadWithRequest}
352
         ref={this.webViewRef}
366
         ref={this.webViewRef}
353
         // TODO: find a better way to type this.
367
         // TODO: find a better way to type this.
354
         source={resolveAssetSource(source as ImageSourcePropType)}
368
         source={resolveAssetSource(source as ImageSourcePropType)}

+ 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
 

+ 68
- 10
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
 }
137
   statusCode: number;
141
   statusCode: number;
138
 }
142
 }
139
 
143
 
144
+export interface WebViewRenderProcessGoneDetail {
145
+  didCrash: boolean;
146
+}
147
+
140
 export type WebViewEvent = NativeSyntheticEvent<WebViewNativeEvent>;
148
 export type WebViewEvent = NativeSyntheticEvent<WebViewNativeEvent>;
141
 
149
 
142
 export type WebViewProgressEvent = NativeSyntheticEvent<
150
 export type WebViewProgressEvent = NativeSyntheticEvent<
145
 
153
 
146
 export type WebViewNavigationEvent = NativeSyntheticEvent<WebViewNavigation>;
154
 export type WebViewNavigationEvent = NativeSyntheticEvent<WebViewNavigation>;
147
 
155
 
156
+export type ShouldStartLoadRequestEvent = NativeSyntheticEvent<ShouldStartLoadRequest>;
157
+
148
 export type FileDownloadEvent = NativeSyntheticEvent<FileDownload>;
158
 export type FileDownloadEvent = NativeSyntheticEvent<FileDownload>;
149
 
159
 
150
 export type WebViewMessageEvent = NativeSyntheticEvent<WebViewMessage>;
160
 export type WebViewMessageEvent = NativeSyntheticEvent<WebViewMessage>;
155
 
165
 
156
 export type WebViewHttpErrorEvent = NativeSyntheticEvent<WebViewHttpError>;
166
 export type WebViewHttpErrorEvent = NativeSyntheticEvent<WebViewHttpError>;
157
 
167
 
168
+export type WebViewRenderProcessGoneEvent = NativeSyntheticEvent<WebViewRenderProcessGoneDetail>;
169
+
158
 export type DataDetectorTypes =
170
 export type DataDetectorTypes =
159
   | 'phoneNumber'
171
   | 'phoneNumber'
160
   | 'link'
172
   | 'link'
170
 
182
 
171
 export type CacheMode = 'LOAD_DEFAULT' | 'LOAD_CACHE_ONLY' | 'LOAD_CACHE_ELSE_NETWORK' | 'LOAD_NO_CACHE';
183
 export type CacheMode = 'LOAD_DEFAULT' | 'LOAD_CACHE_ONLY' | 'LOAD_CACHE_ELSE_NETWORK' | 'LOAD_NO_CACHE';
172
 
184
 
185
+export type AndroidLayerType = 'none' | 'software' | 'hardware';
186
+
173
 export interface WebViewSourceUri {
187
 export interface WebViewSourceUri {
174
   /**
188
   /**
175
    * The URI to load in the `WebView`. Can be a local or remote file.
189
    * The URI to load in the `WebView`. Can be a local or remote file.
232
 }
246
 }
233
 
247
 
234
 export type OnShouldStartLoadWithRequest = (
248
 export type OnShouldStartLoadWithRequest = (
235
-  event: WebViewNavigation,
249
+  event: ShouldStartLoadRequest,
236
 ) => boolean;
250
 ) => boolean;
237
 
251
 
238
 export interface CommonNativeWebViewProps extends ViewProps {
252
 export interface CommonNativeWebViewProps extends ViewProps {
252
   onLoadingStart: (event: WebViewNavigationEvent) => void;
266
   onLoadingStart: (event: WebViewNavigationEvent) => void;
253
   onHttpError: (event: WebViewHttpErrorEvent) => void;
267
   onHttpError: (event: WebViewHttpErrorEvent) => void;
254
   onMessage: (event: WebViewMessageEvent) => void;
268
   onMessage: (event: WebViewMessageEvent) => void;
255
-  onShouldStartLoadWithRequest: (event: WebViewNavigationEvent) => void;
269
+  onShouldStartLoadWithRequest: (event: ShouldStartLoadRequestEvent) => void;
256
   showsHorizontalScrollIndicator?: boolean;
270
   showsHorizontalScrollIndicator?: boolean;
257
   showsVerticalScrollIndicator?: boolean;
271
   showsVerticalScrollIndicator?: boolean;
258
   // TODO: find a better way to type this.
272
   // TODO: find a better way to type this.
260
   source: any;
274
   source: any;
261
   userAgent?: string;
275
   userAgent?: string;
262
   /**
276
   /**
263
-   * Append to the existing user-agent. Overriden if `userAgent` is set.
277
+   * Append to the existing user-agent. Overridden if `userAgent` is set.
264
    */
278
    */
265
   applicationNameForUserAgent?: string;
279
   applicationNameForUserAgent?: string;
266
 }
280
 }
272
   allowFileAccessFromFileURLs?: boolean;
286
   allowFileAccessFromFileURLs?: boolean;
273
   allowUniversalAccessFromFileURLs?: boolean;
287
   allowUniversalAccessFromFileURLs?: boolean;
274
   androidHardwareAccelerationDisabled?: boolean;
288
   androidHardwareAccelerationDisabled?: boolean;
289
+  androidLayerType?: AndroidLayerType;
275
   domStorageEnabled?: boolean;
290
   domStorageEnabled?: boolean;
276
   geolocationEnabled?: boolean;
291
   geolocationEnabled?: boolean;
277
   javaScriptEnabled?: boolean;
292
   javaScriptEnabled?: boolean;
278
   mixedContentMode?: 'never' | 'always' | 'compatibility';
293
   mixedContentMode?: 'never' | 'always' | 'compatibility';
279
   onContentSizeChange?: (event: WebViewEvent) => void;
294
   onContentSizeChange?: (event: WebViewEvent) => void;
295
+  onRenderProcessGone?: (event: WebViewRenderProcessGoneEvent) => void;
280
   overScrollMode?: OverScrollModeType;
296
   overScrollMode?: OverScrollModeType;
281
   saveFormDataDisabled?: boolean;
297
   saveFormDataDisabled?: boolean;
282
   textZoom?: number;
298
   textZoom?: number;
285
   readonly urlPrefixesForDefaultIntent?: string[];
301
   readonly urlPrefixesForDefaultIntent?: string[];
286
 }
302
 }
287
 
303
 
288
-export enum ContentInsetAdjustmentBehavior {
289
-  automatic = 'automatic',
290
-  scrollableAxes = 'scrollableAxes',
291
-  never = 'never',
292
-  always = 'always'
293
-};
304
+export declare type ContentInsetAdjustmentBehavior = 'automatic' | 'scrollableAxes' | 'never' | 'always';
305
+
306
+export declare type ContentMode = 'recommended' | 'mobile' | 'desktop';
294
 
307
 
295
 export interface IOSNativeWebViewProps extends CommonNativeWebViewProps {
308
 export interface IOSNativeWebViewProps extends CommonNativeWebViewProps {
296
   allowingReadAccessToURL?: string;
309
   allowingReadAccessToURL?: string;
301
   bounces?: boolean;
314
   bounces?: boolean;
302
   contentInset?: ContentInsetProp;
315
   contentInset?: ContentInsetProp;
303
   contentInsetAdjustmentBehavior?: ContentInsetAdjustmentBehavior;
316
   contentInsetAdjustmentBehavior?: ContentInsetAdjustmentBehavior;
317
+  contentMode?: ContentMode;
304
   readonly dataDetectorTypes?: DataDetectorTypes | DataDetectorTypes[];
318
   readonly dataDetectorTypes?: DataDetectorTypes | DataDetectorTypes[];
305
   decelerationRate?: number;
319
   decelerationRate?: number;
306
   directionalLockEnabled?: boolean;
320
   directionalLockEnabled?: boolean;
398
    */
412
    */
399
   contentInset?: ContentInsetProp;
413
   contentInset?: ContentInsetProp;
400
 
414
 
415
+  /**
416
+   * Defaults to `recommended`, which loads mobile content on iPhone
417
+   * and iPad Mini but desktop content on other iPads.
418
+   *
419
+   * Possible values are:
420
+   * - `'recommended'`
421
+   * - `'mobile'`
422
+   * - `'desktop'`
423
+   * @platform ios
424
+   */
425
+  contentMode?: ContentMode;
426
+
401
   /**
427
   /**
402
    * Determines the types of data converted to clickable URLs in the web view's content.
428
    * Determines the types of data converted to clickable URLs in the web view's content.
403
    * By default only phone numbers are detected.
429
    * By default only phone numbers are detected.
523
   */
549
   */
524
   injectedJavaScriptBeforeContentLoadedForMainFrameOnly?: boolean;
550
   injectedJavaScriptBeforeContentLoadedForMainFrameOnly?: boolean;
525
 
551
 
552
+  /**
553
+   * Boolean value that determines whether a pull to refresh gesture is
554
+   * available in the `WebView`. The default value is `false`.
555
+   * If `true`, sets `bounces` automatically to `true`
556
+   * @platform ios
557
+   *
558
+  */
559
+  pullToRefreshEnabled?: boolean;
560
+
526
   /**
561
   /**
527
    * Function that is invoked when the client needs to download a file.
562
    * Function that is invoked when the client needs to download a file.
528
    *
563
    *
683
   onNavigationStateChange?: (event: WebViewNavigation) => void;
718
   onNavigationStateChange?: (event: WebViewNavigation) => void;
684
   onContentSizeChange?: (event: WebViewEvent) => void;
719
   onContentSizeChange?: (event: WebViewEvent) => void;
685
 
720
 
721
+  /**
722
+   * Function that is invoked when the `WebView` process crashes or is killed by the OS.
723
+   * Works only on Android (minimum API level 26).
724
+   */
725
+  onRenderProcessGone?: (event: WebViewRenderProcessGoneEvent) => void;
726
+
686
   /**
727
   /**
687
    * https://developer.android.com/reference/android/webkit/WebSettings.html#setCacheMode(int)
728
    * https://developer.android.com/reference/android/webkit/WebSettings.html#setCacheMode(int)
688
    * Set the cacheMode. Possible values are:
729
    * Set the cacheMode. Possible values are:
721
    */
762
    */
722
   geolocationEnabled?: boolean;
763
   geolocationEnabled?: boolean;
723
 
764
 
724
-  
765
+
725
   /**
766
   /**
726
    * Boolean that sets whether JavaScript running in the context of a file
767
    * Boolean that sets whether JavaScript running in the context of a file
727
    * scheme URL should be allowed to access content from other file scheme URLs.
768
    * scheme URL should be allowed to access content from other file scheme URLs.
766
    */
807
    */
767
   androidHardwareAccelerationDisabled?: boolean;
808
   androidHardwareAccelerationDisabled?: boolean;
768
 
809
 
810
+    /**
811
+   * https://developer.android.com/reference/android/webkit/WebView#setLayerType(int,%20android.graphics.Paint)
812
+   * Sets the layerType. Possible values are:
813
+   *
814
+   * - `'none'` (default)
815
+   * - `'software'`
816
+   * - `'hardware'`
817
+   *
818
+   * @platform android
819
+   */
820
+  androidLayerType?: AndroidLayerType;
821
+
769
   /**
822
   /**
770
    * Boolean value to enable third party cookies in the `WebView`. Used on
823
    * Boolean value to enable third party cookies in the `WebView`. Used on
771
    * Android Lollipop and above only as third party cookies are enabled by
824
    * Android Lollipop and above only as third party cookies are enabled by
973
    * Should caching be enabled. Default is true.
1026
    * Should caching be enabled. Default is true.
974
    */
1027
    */
975
   cacheEnabled?: boolean;
1028
   cacheEnabled?: boolean;
1029
+
1030
+  /**
1031
+   * Append to the existing user-agent. Overridden if `userAgent` is set.
1032
+   */
1033
+  applicationNameForUserAgent?: string;
976
 }
1034
 }