From b436943a279f116fc8f376a377afc04aa7c5a774 Mon Sep 17 00:00:00 2001 From: Martin Konicek Date: Fri, 18 Dec 2015 03:40:51 -0800 Subject: [PATCH] Pass the correct URL to Android WebView events Summary: `WebView.getUrl()` doesn't return the correct value in WebView callbacks (e.g. `onPageFinished`). For example, when navigating to a URL, we report that loading finished, but still with the old URL. This diff fixes that. public Reviewed By: andreicoman11 Differential Revision: D2769597 fb-gh-sync-id: f14bdd405290469ac0a20d0fb89aa2a27d33e758 --- .../views/webview/ReactWebViewManager.java | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) 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 05f50dcfb..f16520e60 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 @@ -91,7 +91,7 @@ public class ReactWebViewManager extends SimpleViewManager { if (!mLastLoadFailed) { ReactWebView reactWebView = (ReactWebView) webView; reactWebView.callInjectedJavaScript(); - emitFinishEvent(webView); + emitFinishEvent(webView, url); } } @@ -107,7 +107,7 @@ public class ReactWebViewManager extends SimpleViewManager { new TopLoadingStartEvent( webView.getId(), SystemClock.uptimeMillis(), - createWebViewEvent(webView))); + createWebViewEvent(webView, url))); } @Override @@ -120,11 +120,11 @@ public class ReactWebViewManager extends SimpleViewManager { mLastLoadFailed = true; // In case of an error JS side expect to get a finish event first, and then get an error event - // Android WebView does it in the oposite way, so we need to simulate that behavior - emitFinishEvent(webView); + // Android WebView does it in the opposite way, so we need to simulate that behavior + emitFinishEvent(webView, failingUrl); ReactContext reactContext = (ReactContext) ((ReactWebView) webView).getContext(); - WritableMap eventData = createWebViewEvent(webView); + WritableMap eventData = createWebViewEvent(webView, failingUrl); eventData.putDouble("code", errorCode); eventData.putString("description", description); @@ -145,10 +145,10 @@ public class ReactWebViewManager extends SimpleViewManager { new TopLoadingStartEvent( webView.getId(), SystemClock.uptimeMillis(), - createWebViewEvent(webView))); + createWebViewEvent(webView, url))); } - private void emitFinishEvent(WebView webView) { + private void emitFinishEvent(WebView webView, String url) { ReactContext reactContext = (ReactContext) webView.getContext(); EventDispatcher eventDispatcher = @@ -157,13 +157,15 @@ public class ReactWebViewManager extends SimpleViewManager { new TopLoadingFinishEvent( webView.getId(), SystemClock.uptimeMillis(), - createWebViewEvent(webView))); + createWebViewEvent(webView, url))); } - private WritableMap createWebViewEvent(WebView webView) { + private WritableMap createWebViewEvent(WebView webView, String url) { WritableMap event = Arguments.createMap(); event.putDouble("target", webView.getId()); - event.putString("url", webView.getUrl()); + // Don't use webView.getUrl() here, the URL isn't updated to the new value yet in callbacks + // like onPageFinished + event.putString("url", url); event.putBoolean("loading", !mLastLoadFailed && webView.getProgress() != 100); event.putString("title", webView.getTitle()); event.putBoolean("canGoBack", webView.canGoBack()); @@ -279,7 +281,7 @@ public class ReactWebViewManager extends SimpleViewManager { public void setUrl(WebView view, @Nullable String url) { // TODO(8495359): url and html are coupled as they both call loadUrl, therefore in case when // property url is removed in favor of property html being added in single transaction we may - // end up in a state when blank url is loaded as it depends onthe oreder of update operations! + // end up in a state when blank url is loaded as it depends on the order of update operations! if (url != null) { view.loadUrl(url); } else {