From 774296b26349dbf6a1a0ccb1a870e3038ea2e046 Mon Sep 17 00:00:00 2001 From: Andrew Gray Date: Fri, 22 Apr 2016 08:14:53 -0700 Subject: [PATCH] Implemented stopLoading Summary:**Motivation:** In my app, I'm using a WebView that loads content from my mobile site. What I want to do is when a user presses a link on the loaded page, I want to stop the WebView's request, hijack the URL and open the URL in a new WebView, pushed to the top of the navigator stack. To me, this gives the overall app a more native feel, instead of implementing a rudimentary navbar on the main WebView to go back. **Attempted Workarounds:** I've attempted to get similar functionality by capturing the onNavigationStateChange event in the WebView, and then within calling goBack + pushing the new view to the navigator stack. From a functionality standpoint, this works. However, from a UI standpoint, the user can clearly see the webview change states to a new page + go back before having the new view pushed on top of their nav stack. Closes https://github.com/facebook/react-native/pull/6886 Differential Revision: D3212447 Pulled By: mkonicek fb-gh-sync-id: 05911e583d9ba54ddbd54a772153c80ed227731e fbshipit-source-id: 05911e583d9ba54ddbd54a772153c80ed227731e --- Libraries/Components/WebView/WebView.android.js | 8 ++++++++ Libraries/Components/WebView/WebView.ios.js | 8 ++++++++ React/Views/RCTWebView.h | 1 + React/Views/RCTWebView.m | 5 +++++ React/Views/RCTWebViewManager.m | 12 ++++++++++++ .../react/views/webview/ReactWebViewManager.java | 7 ++++++- 6 files changed, 40 insertions(+), 1 deletion(-) diff --git a/Libraries/Components/WebView/WebView.android.js b/Libraries/Components/WebView/WebView.android.js index 05b1cae68..c9db749a8 100644 --- a/Libraries/Components/WebView/WebView.android.js +++ b/Libraries/Components/WebView/WebView.android.js @@ -264,6 +264,14 @@ var WebView = React.createClass({ ); }, + stopLoading: function() { + UIManager.dispatchViewManagerCommand( + this.getWebViewHandle(), + UIManager.RCTWebView.Commands.stopLoading, + null + ); + }, + /** * We return an event with a bunch of fields including: * url, title, loading, canGoBack, canGoForward diff --git a/Libraries/Components/WebView/WebView.ios.js b/Libraries/Components/WebView/WebView.ios.js index 814c1e20d..09eeee0c3 100644 --- a/Libraries/Components/WebView/WebView.ios.js +++ b/Libraries/Components/WebView/WebView.ios.js @@ -362,6 +362,14 @@ var WebView = React.createClass({ ); }, + stopLoading: function() { + UIManager.dispatchViewManagerCommand( + this.getWebViewHandle(), + UIManager.RCTWebView.Commands.stopLoading, + null + ); + }, + /** * We return an event with a bunch of fields including: * url, title, loading, canGoBack, canGoForward diff --git a/React/Views/RCTWebView.h b/React/Views/RCTWebView.h index 05246a09b..f8bd2608c 100644 --- a/React/Views/RCTWebView.h +++ b/React/Views/RCTWebView.h @@ -40,5 +40,6 @@ shouldStartLoadForRequest:(NSMutableDictionary *)request - (void)goForward; - (void)goBack; - (void)reload; +- (void)stopLoading; @end diff --git a/React/Views/RCTWebView.m b/React/Views/RCTWebView.m index 3e6c16928..76c3f0960 100644 --- a/React/Views/RCTWebView.m +++ b/React/Views/RCTWebView.m @@ -77,6 +77,11 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder) } } +- (void)stopLoading +{ + [_webView stopLoading]; +} + - (void)setSource:(NSDictionary *)source { if (![_source isEqualToDictionary:source]) { diff --git a/React/Views/RCTWebViewManager.m b/React/Views/RCTWebViewManager.m index 86584a1dc..5809e24be 100644 --- a/React/Views/RCTWebViewManager.m +++ b/React/Views/RCTWebViewManager.m @@ -85,6 +85,18 @@ RCT_EXPORT_METHOD(reload:(nonnull NSNumber *)reactTag) }]; } +RCT_EXPORT_METHOD(stopLoading:(nonnull NSNumber *)reactTag) +{ + [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { + RCTWebView *view = viewRegistry[reactTag]; + if (![view isKindOfClass:[RCTWebView class]]) { + RCTLogError(@"Invalid view returned from registry, expecting RCTWebView, got: %@", view); + } else { + [view stopLoading]; + } + }]; +} + #pragma mark - Exported synchronous methods - (BOOL)webView:(__unused RCTWebView *)webView diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/webview/ReactWebViewManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/webview/ReactWebViewManager.java index 3eeb4ecdd..586b071d5 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/webview/ReactWebViewManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/webview/ReactWebViewManager.java @@ -75,6 +75,7 @@ public class ReactWebViewManager extends SimpleViewManager { public static final int COMMAND_GO_BACK = 1; public static final int COMMAND_GO_FORWARD = 2; public static final int COMMAND_RELOAD = 3; + public static final int COMMAND_STOP_LOADING = 4; // Use `webView.loadUrl("about:blank")` to reliably reset the view // state and release page resources (including any running JavaScript). @@ -350,7 +351,8 @@ public class ReactWebViewManager extends SimpleViewManager { return MapBuilder.of( "goBack", COMMAND_GO_BACK, "goForward", COMMAND_GO_FORWARD, - "reload", COMMAND_RELOAD); + "reload", COMMAND_RELOAD, + "stopLoading", COMMAND_STOP_LOADING); } @Override @@ -365,6 +367,9 @@ public class ReactWebViewManager extends SimpleViewManager { case COMMAND_RELOAD: root.reload(); break; + case COMMAND_STOP_LOADING: + root.stopLoading(); + break; } }