From 80a2f5d50fc61b8ba48169d8dcca0247f4b484f2 Mon Sep 17 00:00:00 2001 From: Michael Tostenson Date: Mon, 1 Feb 2016 10:05:26 -0800 Subject: [PATCH] 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, } ``` 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 --- .../Components/WebView/WebView.android.js | 30 ++++++++-- .../views/webview/ReactWebViewManager.java | 58 +++++++++---------- 2 files changed, 55 insertions(+), 33 deletions(-) diff --git a/Libraries/Components/WebView/WebView.android.js b/Libraries/Components/WebView/WebView.android.js index e2bbad6e5..1f6fdd980 100644 --- a/Libraries/Components/WebView/WebView.android.js +++ b/Libraries/Components/WebView/WebView.android.js @@ -17,6 +17,7 @@ var StyleSheet = require('StyleSheet'); var UIManager = require('UIManager'); var View = require('View'); +var deprecatedPropType = require('deprecatedPropType'); var keyMirror = require('keyMirror'); var merge = require('merge'); var requireNativeComponent = require('requireNativeComponent'); @@ -44,14 +45,29 @@ var WebView = React.createClass({ onLoadEnd: PropTypes.func, onLoadStart: PropTypes.func, onError: PropTypes.func, - url: PropTypes.string, - html: PropTypes.string, automaticallyAdjustContentInsets: PropTypes.bool, contentInset: EdgeInsetsPropType, onNavigationStateChange: PropTypes.func, startInLoadingState: PropTypes.bool, // force WebView to show loadingView on first load 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 }` + * @platform android + */ + source: PropTypes.object, + /** * Used on Android only, JS is enabled by default for WebView on iOS * @platform android @@ -127,13 +143,19 @@ var WebView = React.createClass({ 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 = { ((ReactWebView) view).setInjectedJavaScript(injectedJavaScript); } - @ReactProp(name = "html") - public void setHtml(WebView view, @Nullable String html) { - if (html != null) { - view.loadData(html, HTML_MIME_TYPE, HTML_ENCODING); - } else { - 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; - } - if (url != null) { - view.loadUrl(url); - } else { - view.loadUrl(BLANK_URL); + @ReactProp(name = "source") + public void setSource(WebView view, @Nullable ReadableMap source) { + if (source != null) { + if (source.hasKey("html")) { + view.loadData(source.getString("html"), HTML_MIME_TYPE, HTML_ENCODING); + return; + } + if (source.hasKey("uri")) { + HashMap headerMap = new HashMap<>(); + if (source.hasKey("headers")) { + 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