Skip to content

Commit

Permalink
Android: Set WebViewManager methods/fields as protected instead of pr…
Browse files Browse the repository at this point in the history
…ivate

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 (#10946 (comment))
Closes #14261

Differential Revision: D5413922

Pulled By: shergin

fbshipit-source-id: d2f6d478f2a147e2e7b5e05c195a8b28a0a3d576
  • Loading branch information
cbrevik authored and facebook-github-bot committed Jul 13, 2017
1 parent aafccdf commit e2c87b5
Showing 1 changed file with 26 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,11 @@ public class ReactWebViewManager extends SimpleViewManager<WebView> {

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;
Expand All @@ -102,14 +102,14 @@ public class ReactWebViewManager extends SimpleViewManager<WebView> {

// 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) {
Expand Down Expand Up @@ -185,15 +185,15 @@ public void doUpdateVisitedHistory(WebView webView, String url, boolean isReload
createWebViewEvent(webView, url)));
}

private void emitFinishEvent(WebView webView, String url) {
protected void emitFinishEvent(WebView webView, String url) {
dispatchEvent(
webView,
new TopLoadingFinishEvent(
webView.getId(),
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
Expand All @@ -212,10 +212,10 @@ private WritableMap createWebViewEvent(WebView webView, String url) {
* 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) {
Expand Down Expand Up @@ -258,14 +258,18 @@ public void setInjectedJavaScript(@Nullable String js) {
injectedJS = js;
}

protected ReactWebViewBridge createReactWebViewBridge(ReactWebView webView) {
return new ReactWebViewBridge(webView);
}

public void setMessagingEnabled(boolean enabled) {
if (messagingEnabled == enabled) {
return;
}

messagingEnabled = enabled;
if (enabled) {
addJavascriptInterface(new ReactWebViewBridge(this), BRIDGE_NAME);
addJavascriptInterface(createReactWebViewBridge(this), BRIDGE_NAME);
linkBridge();
} else {
removeJavascriptInterface(BRIDGE_NAME);
Expand Down Expand Up @@ -308,7 +312,7 @@ public void onMessage(String message) {
dispatchEvent(this, new TopMessageEvent(this.getId(), message));
}

private void cleanupCallbacksAndDestroy() {
protected void cleanupCallbacksAndDestroy() {
setWebViewClient(null);
destroy();
}
Expand All @@ -330,9 +334,13 @@ public String getName() {
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) {
Expand Down Expand Up @@ -568,7 +576,7 @@ public void onDropViewInstance(WebView webView) {
((ReactWebView) webView).cleanupCallbacksAndDestroy();
}

private WebView.PictureListener getPictureListener() {
protected WebView.PictureListener getPictureListener() {
if (mPictureListener == null) {
mPictureListener = new WebView.PictureListener() {
@Override
Expand All @@ -585,7 +593,7 @@ public void onNewPicture(WebView webView, Picture picture) {
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();
Expand Down

0 comments on commit e2c87b5

Please sign in to comment.