Add headers prop to Android WebViews
Summary: Related to [issue #5418](https://github.com/facebook/react-native/issues/5418) This is a follow-up to [this previous pull request.](https://github.com/facebook/react-native/pull/5419) ~~Adds a new ReactProp 'urlWithHeaders' to Android WebViews that takes an object with a 'url' string and a 'headers' map.~~ [Update] Adds a new prop 'source' to Android WebViews ``` { html: string, url: string, headers: map<string, string>, } ``` Update: resolves TODO 8495359 Closes https://github.com/facebook/react-native/pull/5494 Reviewed By: svcscm Differential Revision: D2881313 Pulled By: nicklockwood fb-gh-sync-id: 7cad8490d4932d0a7ef559165f3ec279d873c537
This commit is contained in:
parent
f04882f8e4
commit
80a2f5d50f
|
@ -17,6 +17,7 @@ var StyleSheet = require('StyleSheet');
|
||||||
var UIManager = require('UIManager');
|
var UIManager = require('UIManager');
|
||||||
var View = require('View');
|
var View = require('View');
|
||||||
|
|
||||||
|
var deprecatedPropType = require('deprecatedPropType');
|
||||||
var keyMirror = require('keyMirror');
|
var keyMirror = require('keyMirror');
|
||||||
var merge = require('merge');
|
var merge = require('merge');
|
||||||
var requireNativeComponent = require('requireNativeComponent');
|
var requireNativeComponent = require('requireNativeComponent');
|
||||||
|
@ -44,14 +45,29 @@ var WebView = React.createClass({
|
||||||
onLoadEnd: PropTypes.func,
|
onLoadEnd: PropTypes.func,
|
||||||
onLoadStart: PropTypes.func,
|
onLoadStart: PropTypes.func,
|
||||||
onError: PropTypes.func,
|
onError: PropTypes.func,
|
||||||
url: PropTypes.string,
|
|
||||||
html: PropTypes.string,
|
|
||||||
automaticallyAdjustContentInsets: PropTypes.bool,
|
automaticallyAdjustContentInsets: PropTypes.bool,
|
||||||
contentInset: EdgeInsetsPropType,
|
contentInset: EdgeInsetsPropType,
|
||||||
onNavigationStateChange: PropTypes.func,
|
onNavigationStateChange: PropTypes.func,
|
||||||
startInLoadingState: PropTypes.bool, // force WebView to show loadingView on first load
|
startInLoadingState: PropTypes.bool, // force WebView to show loadingView on first load
|
||||||
style: View.propTypes.style,
|
style: View.propTypes.style,
|
||||||
|
|
||||||
|
html: deprecatedPropType(
|
||||||
|
PropTypes.string,
|
||||||
|
'Use the `source` prop instead.'
|
||||||
|
),
|
||||||
|
|
||||||
|
url: deprecatedPropType(
|
||||||
|
PropTypes.string,
|
||||||
|
'Use the `source` prop instead.'
|
||||||
|
),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used on Android only, provides html or url with optional headers to the WebView.
|
||||||
|
* `{ html: string, uri: string, headers: map<string, string> }`
|
||||||
|
* @platform android
|
||||||
|
*/
|
||||||
|
source: PropTypes.object,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used on Android only, JS is enabled by default for WebView on iOS
|
* Used on Android only, JS is enabled by default for WebView on iOS
|
||||||
* @platform android
|
* @platform android
|
||||||
|
@ -127,13 +143,19 @@ var WebView = React.createClass({
|
||||||
domStorageEnabled = this.props.domStorageEnabledAndroid;
|
domStorageEnabled = this.props.domStorageEnabledAndroid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var source = this.props.source || {};
|
||||||
|
if (this.props.html) {
|
||||||
|
source.html = this.props.html;
|
||||||
|
} else if (this.props.url) {
|
||||||
|
source.uri = this.props.url;
|
||||||
|
}
|
||||||
|
|
||||||
var webView =
|
var webView =
|
||||||
<RCTWebView
|
<RCTWebView
|
||||||
ref={RCT_WEBVIEW_REF}
|
ref={RCT_WEBVIEW_REF}
|
||||||
key="webViewKey"
|
key="webViewKey"
|
||||||
style={webViewStyles}
|
style={webViewStyles}
|
||||||
url={this.props.url}
|
source={source}
|
||||||
html={this.props.html}
|
|
||||||
injectedJavaScript={this.props.injectedJavaScript}
|
injectedJavaScript={this.props.injectedJavaScript}
|
||||||
userAgent={this.props.userAgent}
|
userAgent={this.props.userAgent}
|
||||||
javaScriptEnabled={javaScriptEnabled}
|
javaScriptEnabled={javaScriptEnabled}
|
||||||
|
|
|
@ -9,10 +9,6 @@
|
||||||
|
|
||||||
package com.facebook.react.views.webview;
|
package com.facebook.react.views.webview;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
|
@ -27,16 +23,23 @@ import com.facebook.react.bridge.Arguments;
|
||||||
import com.facebook.react.bridge.LifecycleEventListener;
|
import com.facebook.react.bridge.LifecycleEventListener;
|
||||||
import com.facebook.react.bridge.ReactContext;
|
import com.facebook.react.bridge.ReactContext;
|
||||||
import com.facebook.react.bridge.ReadableArray;
|
import com.facebook.react.bridge.ReadableArray;
|
||||||
|
import com.facebook.react.bridge.ReadableMap;
|
||||||
|
import com.facebook.react.bridge.ReadableMapKeySetIterator;
|
||||||
import com.facebook.react.bridge.WritableMap;
|
import com.facebook.react.bridge.WritableMap;
|
||||||
import com.facebook.react.common.MapBuilder;
|
import com.facebook.react.common.MapBuilder;
|
||||||
import com.facebook.react.common.build.ReactBuildConfig;
|
import com.facebook.react.common.build.ReactBuildConfig;
|
||||||
import com.facebook.react.uimanager.annotations.ReactProp;
|
|
||||||
import com.facebook.react.uimanager.SimpleViewManager;
|
import com.facebook.react.uimanager.SimpleViewManager;
|
||||||
import com.facebook.react.uimanager.ThemedReactContext;
|
import com.facebook.react.uimanager.ThemedReactContext;
|
||||||
import com.facebook.react.uimanager.UIManagerModule;
|
import com.facebook.react.uimanager.UIManagerModule;
|
||||||
|
import com.facebook.react.uimanager.annotations.ReactProp;
|
||||||
import com.facebook.react.uimanager.events.Event;
|
import com.facebook.react.uimanager.events.Event;
|
||||||
import com.facebook.react.uimanager.events.EventDispatcher;
|
import com.facebook.react.uimanager.events.EventDispatcher;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages instances of {@link WebView}
|
* Manages instances of {@link WebView}
|
||||||
*
|
*
|
||||||
|
@ -271,32 +274,29 @@ public class ReactWebViewManager extends SimpleViewManager<WebView> {
|
||||||
((ReactWebView) view).setInjectedJavaScript(injectedJavaScript);
|
((ReactWebView) view).setInjectedJavaScript(injectedJavaScript);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ReactProp(name = "html")
|
@ReactProp(name = "source")
|
||||||
public void setHtml(WebView view, @Nullable String html) {
|
public void setSource(WebView view, @Nullable ReadableMap source) {
|
||||||
if (html != null) {
|
if (source != null) {
|
||||||
view.loadData(html, HTML_MIME_TYPE, HTML_ENCODING);
|
if (source.hasKey("html")) {
|
||||||
} else {
|
view.loadData(source.getString("html"), HTML_MIME_TYPE, HTML_ENCODING);
|
||||||
view.loadUrl(BLANK_URL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ReactProp(name = "url")
|
|
||||||
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 on the order of update operations!
|
|
||||||
|
|
||||||
String currentUrl = view.getUrl();
|
|
||||||
if (currentUrl != null && currentUrl.equals(url)) {
|
|
||||||
// We are already loading it so no need to stomp over it and start again
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (url != null) {
|
if (source.hasKey("uri")) {
|
||||||
view.loadUrl(url);
|
HashMap<String, String> headerMap = new HashMap<>();
|
||||||
} else {
|
if (source.hasKey("headers")) {
|
||||||
view.loadUrl(BLANK_URL);
|
ReadableMap headers = source.getMap("headers");
|
||||||
|
ReadableMapKeySetIterator iter = headers.keySetIterator();
|
||||||
|
while (iter.hasNextKey()) {
|
||||||
|
String key = iter.nextKey();
|
||||||
|
headerMap.put(key, headers.getString(key));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
view.loadUrl(source.getString("uri"), headerMap);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
view.loadUrl(BLANK_URL);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void addEventEmitters(ThemedReactContext reactContext, WebView view) {
|
protected void addEventEmitters(ThemedReactContext reactContext, WebView view) {
|
||||||
|
|
Loading…
Reference in New Issue