Skip to content

Commit

Permalink
Add onContentSizeChange prop to WebView
Browse files Browse the repository at this point in the history
Summary: Added support for WebViews to take in an onContentSizeChange prop, which will return a native event that contains the width and height of the html content in the WebView. Also moved the ContentSizeChangeEvent from the recyclerview dir to the uimanager/events dir

Reviewed By: andreicoman11

Differential Revision: D3775399

fbshipit-source-id: 19a0579f8345e5853cc7311b80f1f1393c77ab58
  • Loading branch information
ayc1 authored and Facebook Github Bot 8 committed Aug 29, 2016
1 parent 101190f commit 22de655
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 24 deletions.
2 changes: 2 additions & 0 deletions Libraries/Components/WebView/WebView.android.js
Expand Up @@ -58,6 +58,7 @@ class WebView extends React.Component {
automaticallyAdjustContentInsets: PropTypes.bool,
contentInset: EdgeInsetsPropType,
onNavigationStateChange: PropTypes.func,
onContentSizeChange: PropTypes.func,
startInLoadingState: PropTypes.bool, // force WebView to show loadingView on first load
style: View.propTypes.style,

Expand Down Expand Up @@ -219,6 +220,7 @@ class WebView extends React.Component {
domStorageEnabled={this.props.domStorageEnabled}
contentInset={this.props.contentInset}
automaticallyAdjustContentInsets={this.props.automaticallyAdjustContentInsets}
onContentSizeChange={this.props.onContentSizeChange}
onLoadingStart={this.onLoadingStart}
onLoadingFinish={this.onLoadingFinish}
onLoadingError={this.onLoadingError}
Expand Down
@@ -1,16 +1,13 @@
// Copyright 2004-present Facebook. All Rights Reserved.

package com.facebook.react.views.recyclerview;
package com.facebook.react.uimanager.events;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.uimanager.PixelUtil;
import com.facebook.react.uimanager.events.Event;
import com.facebook.react.uimanager.events.RCTEventEmitter;

/**
* Event dispatched by {@link RecyclerViewBackedScrollView} when total height of it's children
* changes
* Event dispatched when total width or height of a view's children changes
*/
public class ContentSizeChangeEvent extends Event<ContentSizeChangeEvent> {

Expand Down
Expand Up @@ -16,6 +16,7 @@
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.common.annotations.VisibleForTesting;
import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.events.ContentSizeChangeEvent;
import com.facebook.react.uimanager.events.NativeGestureUtil;
import com.facebook.react.views.scroll.ScrollEvent;
import com.facebook.react.views.scroll.ScrollEventType;
Expand Down Expand Up @@ -174,7 +175,6 @@ public int getTopOffsetForItem(int index) {
}
return mOffsetForLastPosition;
}

}

/*package*/ static class ReactListAdapter extends Adapter<ConcreteViewHolder> {
Expand Down
Expand Up @@ -15,18 +15,18 @@
import java.util.HashMap;
import java.util.Map;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Picture;
import android.net.Uri;
import android.os.Build;
import android.text.TextUtils;
import android.view.ViewGroup.LayoutParams;
import android.webkit.GeolocationPermissions;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.webkit.WebChromeClient;

import com.facebook.react.views.webview.events.TopLoadingErrorEvent;
import com.facebook.react.views.webview.events.TopLoadingFinishEvent;
import com.facebook.react.views.webview.events.TopLoadingStartEvent;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.LifecycleEventListener;
import com.facebook.react.bridge.ReactContext;
Expand All @@ -40,10 +40,12 @@
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.uimanager.events.ContentSizeChangeEvent;
import com.facebook.react.uimanager.events.Event;
import com.facebook.react.uimanager.events.EventDispatcher;
import android.content.Intent;
import android.net.Uri;
import com.facebook.react.views.webview.events.TopLoadingErrorEvent;
import com.facebook.react.views.webview.events.TopLoadingFinishEvent;
import com.facebook.react.views.webview.events.TopLoadingStartEvent;

/**
* Manages instances of {@link WebView}
Expand Down Expand Up @@ -85,6 +87,7 @@ public class ReactWebViewManager extends SimpleViewManager<WebView> {
private static final String BLANK_URL = "about:blank";

private WebViewConfig mWebViewConfig;
private @Nullable WebView.PictureListener mPictureListener;

private static class ReactWebViewClient extends WebViewClient {

Expand Down Expand Up @@ -118,11 +121,11 @@ public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.startsWith("http://") || url.startsWith("https://")) {
return false;
} else {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
view.getContext().startActivity(intent);
return true;
}
view.getContext().startActivity(intent);
return true;
}
}

@Override
Expand Down Expand Up @@ -166,13 +169,6 @@ private void emitFinishEvent(WebView webView, String url) {
createWebViewEvent(webView, url)));
}

private static void dispatchEvent(WebView webView, Event event) {
ReactContext reactContext = (ReactContext) webView.getContext();
EventDispatcher eventDispatcher =
reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher();
eventDispatcher.dispatchEvent(event);
}

private WritableMap createWebViewEvent(WebView webView, String url) {
WritableMap event = Arguments.createMap();
event.putDouble("target", webView.getId());
Expand Down Expand Up @@ -295,7 +291,6 @@ public void setDomStorageEnabled(WebView view, boolean enabled) {
view.getSettings().setDomStorageEnabled(enabled);
}


@ReactProp(name = "userAgent")
public void setUserAgent(WebView view, @Nullable String userAgent) {
if (userAgent != null) {
Expand Down Expand Up @@ -368,6 +363,15 @@ public void setSource(WebView view, @Nullable ReadableMap source) {
view.loadUrl(BLANK_URL);
}

@ReactProp(name = "onContentSizeChange")
public void setOnContentSizeChange(WebView view, boolean sendContentSizeChangeEvents) {
if (sendContentSizeChangeEvents) {
view.setPictureListener(getPictureListener());
} else {
view.setPictureListener(null);
}
}

@Override
protected void addEventEmitters(ThemedReactContext reactContext, WebView view) {
// Do not register default touch emitter and let WebView implementation handle touches
Expand Down Expand Up @@ -407,4 +411,28 @@ public void onDropViewInstance(WebView webView) {
((ThemedReactContext) webView.getContext()).removeLifecycleEventListener((ReactWebView) webView);
((ReactWebView) webView).cleanupCallbacksAndDestroy();
}

private WebView.PictureListener getPictureListener() {
if (mPictureListener == null) {
mPictureListener = new WebView.PictureListener() {
@Override
public void onNewPicture(WebView webView, Picture picture) {
dispatchEvent(
webView,
new ContentSizeChangeEvent(
webView.getId(),
webView.getWidth(),
webView.getContentHeight()));
}
};
}
return mPictureListener;
}

private static void dispatchEvent(WebView webView, Event event) {
ReactContext reactContext = (ReactContext) webView.getContext();
EventDispatcher eventDispatcher =
reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher();
eventDispatcher.dispatchEvent(event);
}
}

0 comments on commit 22de655

Please sign in to comment.