From e2c87b59be3424dfadcb03ca931374d915a47e1f Mon Sep 17 00:00:00 2001 From: Christian Brevik Date: Wed, 12 Jul 2017 20:33:12 -0700 Subject: [PATCH] Android: Set WebViewManager methods/fields as protected instead of private Summary: **Motivation** See discussion in #10946. The motivation is to make `ReactWebViewManager` more extensible. Re-using logic from the ReactWebViewManager when implementing your own custom WebView is a pain since so much of the logic is set as `private`. This PR makes for easier extension/overriding of behavior, and less duplication of code, since most of the methods/fields are set as `protected` instead. I've also made some "create" methods for the `WebView` and `WebViewBridge` so they can more easily be overridden. **Test plan** The test plan is the same as the other PR (#10946). I've made an simple test app which extends `RCTWebViewManager`: https://github.com/cbrevik/overrideWebview See [CustomWebViewManager.java](https://github.com/cbrevik/overrideWebview/blob/master/android/app/src/main/java/com/overridewebview/CustomWebViewManager.java) for a simple implementation. CC shergin (https://github.com/facebook/react-native/pull/10946#issuecomment-304763562) Closes https://github.com/facebook/react-native/pull/14261 Differential Revision: D5413922 Pulled By: shergin fbshipit-source-id: d2f6d478f2a147e2e7b5e05c195a8b28a0a3d576 --- .../views/webview/ReactWebViewManager.java | 44 +++++++++++-------- 1 file changed, 26 insertions(+), 18 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 584751579..c25987bc9 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 @@ -87,11 +87,11 @@ public class ReactWebViewManager extends SimpleViewManager { protected static final String REACT_CLASS = "RCTWebView"; - private static final String HTML_ENCODING = "UTF-8"; - private static final String HTML_MIME_TYPE = "text/html; charset=utf-8"; - private static final String BRIDGE_NAME = "__REACT_WEB_VIEW_BRIDGE"; + protected static final String HTML_ENCODING = "UTF-8"; + protected static final String HTML_MIME_TYPE = "text/html; charset=utf-8"; + protected static final String BRIDGE_NAME = "__REACT_WEB_VIEW_BRIDGE"; - private static final String HTTP_METHOD_POST = "POST"; + protected static final String HTTP_METHOD_POST = "POST"; public static final int COMMAND_GO_BACK = 1; public static final int COMMAND_GO_FORWARD = 2; @@ -102,14 +102,14 @@ public class ReactWebViewManager extends SimpleViewManager { // Use `webView.loadUrl("about:blank")` to reliably reset the view // state and release page resources (including any running JavaScript). - private static final String BLANK_URL = "about:blank"; + protected static final String BLANK_URL = "about:blank"; - private WebViewConfig mWebViewConfig; - private @Nullable WebView.PictureListener mPictureListener; + protected WebViewConfig mWebViewConfig; + protected @Nullable WebView.PictureListener mPictureListener; protected static class ReactWebViewClient extends WebViewClient { - private boolean mLastLoadFailed = false; + protected boolean mLastLoadFailed = false; @Override public void onPageFinished(WebView webView, String url) { @@ -185,7 +185,7 @@ public class ReactWebViewManager extends SimpleViewManager { createWebViewEvent(webView, url))); } - private void emitFinishEvent(WebView webView, String url) { + protected void emitFinishEvent(WebView webView, String url) { dispatchEvent( webView, new TopLoadingFinishEvent( @@ -193,7 +193,7 @@ public class ReactWebViewManager extends SimpleViewManager { createWebViewEvent(webView, url))); } - private WritableMap createWebViewEvent(WebView webView, String url) { + protected WritableMap createWebViewEvent(WebView webView, String url) { WritableMap event = Arguments.createMap(); event.putDouble("target", webView.getId()); // Don't use webView.getUrl() here, the URL isn't updated to the new value yet in callbacks @@ -212,10 +212,10 @@ public class ReactWebViewManager extends SimpleViewManager { * to call {@link WebView#destroy} on activty destroy event and also to clear the client */ protected static class ReactWebView extends WebView implements LifecycleEventListener { - private @Nullable String injectedJS; - private boolean messagingEnabled = false; + protected @Nullable String injectedJS; + protected boolean messagingEnabled = false; - private class ReactWebViewBridge { + protected class ReactWebViewBridge { ReactWebView mContext; ReactWebViewBridge(ReactWebView c) { @@ -258,6 +258,10 @@ public class ReactWebViewManager extends SimpleViewManager { injectedJS = js; } + protected ReactWebViewBridge createReactWebViewBridge(ReactWebView webView) { + return new ReactWebViewBridge(webView); + } + public void setMessagingEnabled(boolean enabled) { if (messagingEnabled == enabled) { return; @@ -265,7 +269,7 @@ public class ReactWebViewManager extends SimpleViewManager { messagingEnabled = enabled; if (enabled) { - addJavascriptInterface(new ReactWebViewBridge(this), BRIDGE_NAME); + addJavascriptInterface(createReactWebViewBridge(this), BRIDGE_NAME); linkBridge(); } else { removeJavascriptInterface(BRIDGE_NAME); @@ -308,7 +312,7 @@ public class ReactWebViewManager extends SimpleViewManager { dispatchEvent(this, new TopMessageEvent(this.getId(), message)); } - private void cleanupCallbacksAndDestroy() { + protected void cleanupCallbacksAndDestroy() { setWebViewClient(null); destroy(); } @@ -330,9 +334,13 @@ public class ReactWebViewManager extends SimpleViewManager { return REACT_CLASS; } + protected ReactWebView createReactWebViewInstance(ThemedReactContext reactContext) { + return new ReactWebView(reactContext); + } + @Override protected WebView createViewInstance(ThemedReactContext reactContext) { - ReactWebView webView = new ReactWebView(reactContext); + ReactWebView webView = createReactWebViewInstance(reactContext); webView.setWebChromeClient(new WebChromeClient() { @Override public boolean onConsoleMessage(ConsoleMessage message) { @@ -568,7 +576,7 @@ public class ReactWebViewManager extends SimpleViewManager { ((ReactWebView) webView).cleanupCallbacksAndDestroy(); } - private WebView.PictureListener getPictureListener() { + protected WebView.PictureListener getPictureListener() { if (mPictureListener == null) { mPictureListener = new WebView.PictureListener() { @Override @@ -585,7 +593,7 @@ public class ReactWebViewManager extends SimpleViewManager { return mPictureListener; } - private static void dispatchEvent(WebView webView, Event event) { + protected static void dispatchEvent(WebView webView, Event event) { ReactContext reactContext = (ReactContext) webView.getContext(); EventDispatcher eventDispatcher = reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher();