From 95801f1eda2d723d9b87760d88fa9f1a1bb33ab1 Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Thu, 16 Aug 2018 13:34:29 -0700 Subject: [PATCH] Move WKWebView into WebView.ios.js Summary: @public This diff adds the `useWebKit` property to the `` React Native component. On iOS, when this property is true, we use `RCTWKWebView`. Otherwise, we use `RCTWebView`. On Android, this property does nothing. Reviewed By: shergin Differential Revision: D6423374 fbshipit-source-id: 006bfaaf12984fac0174c0b5bb897c009c026cd0 --- .../Components/WKWebView/WKWebView.android.js | 22 ----- .../Components/WebView/WebView.android.js | 6 ++ Libraries/Components/WebView/WebView.ios.js | 80 ++++++++++++++++--- 3 files changed, 77 insertions(+), 31 deletions(-) delete mode 100644 Libraries/Components/WKWebView/WKWebView.android.js diff --git a/Libraries/Components/WKWebView/WKWebView.android.js b/Libraries/Components/WKWebView/WKWebView.android.js deleted file mode 100644 index a4cab312304c75..00000000000000 --- a/Libraries/Components/WKWebView/WKWebView.android.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @format - * @flow - * @providesModule WKWebView - */ - -const React = require('React'); -const View = require('View'); -const Text = require('Text'); - -module.exports = () => { - return ( - - Android version not implemented. - - ); -}; diff --git a/Libraries/Components/WebView/WebView.android.js b/Libraries/Components/WebView/WebView.android.js index 4d4b65fb11fdc8..bed2179734579a 100644 --- a/Libraries/Components/WebView/WebView.android.js +++ b/Libraries/Components/WebView/WebView.android.js @@ -109,6 +109,12 @@ class WebView extends React.Component { PropTypes.number, ]), + /** + * If true, use WKWebView instead of UIWebView. + * @platform ios + */ + useWebKit: PropTypes.bool, + /** * Used on Android only, JS is enabled by default for WebView on iOS * @platform android diff --git a/Libraries/Components/WebView/WebView.ios.js b/Libraries/Components/WebView/WebView.ios.js index 413cae03950ff9..f158addaaefdbe 100644 --- a/Libraries/Components/WebView/WebView.ios.js +++ b/Libraries/Components/WebView/WebView.ios.js @@ -32,6 +32,7 @@ const requireNativeComponent = require('requireNativeComponent'); const resolveAssetSource = require('resolveAssetSource'); const RCTWebViewManager = require('NativeModules').WebViewManager; +const RCTWKWebViewManager = require('NativeModules').WKWebViewManager; const BGWASH = 'rgba(255,255,255,0.8)'; const RCT_WEBVIEW_REF = 'webview'; @@ -66,6 +67,9 @@ const DataDetectorTypes = [ 'link', 'address', 'calendarEvent', + 'trackingNumber', + 'flightNumber', + 'lookupSuggestion', 'none', 'all', ]; @@ -162,6 +166,12 @@ class WebView extends React.Component { PropTypes.number, ]), + /** + * If true, use WKWebView instead of UIWebView. + * @platform ios + */ + useWebKit: PropTypes.bool, + /** * Function that returns a view to show if there's an error. */ @@ -264,6 +274,11 @@ class WebView extends React.Component { * - `'none'` * - `'all'` * + * With the new WebKit implementation, we have three new values: + * - `'trackingNumber'`, + * - `'flightNumber'`, + * - `'lookupSuggestion'`, + * * @platform ios */ dataDetectorTypes: PropTypes.oneOfType([ @@ -433,7 +448,13 @@ class WebView extends React.Component { const nativeConfig = this.props.nativeConfig || {}; - const viewManager = nativeConfig.viewManager || RCTWebViewManager; + let viewManager = nativeConfig.viewManager; + + if (this.props.useWebKit) { + viewManager = viewManager || RCTWKWebViewManager; + } else { + viewManager = viewManager || RCTWebViewManager; + } const compiledWhitelist = [ 'about:blank', @@ -474,7 +495,13 @@ class WebView extends React.Component { const messagingEnabled = typeof this.props.onMessage === 'function'; - const NativeWebView = nativeConfig.component || RCTWebView; + let NativeWebView = nativeConfig.component; + + if (this.props.useWebKit) { + NativeWebView = NativeWebView || RCTWKWebView; + } else { + NativeWebView = NativeWebView || RCTWebView; + } const webView = ( { UIManager.dispatchViewManagerCommand( this.getWebViewHandle(), - UIManager.RCTWebView.Commands.goForward, + this._getCommands().goForward, null, ); }; @@ -531,7 +566,7 @@ class WebView extends React.Component { goBack = () => { UIManager.dispatchViewManagerCommand( this.getWebViewHandle(), - UIManager.RCTWebView.Commands.goBack, + this._getCommands().goBack, null, ); }; @@ -543,7 +578,7 @@ class WebView extends React.Component { this.setState({viewState: WebViewState.LOADING}); UIManager.dispatchViewManagerCommand( this.getWebViewHandle(), - UIManager.RCTWebView.Commands.reload, + this._getCommands().reload, null, ); }; @@ -554,7 +589,7 @@ class WebView extends React.Component { stopLoading = () => { UIManager.dispatchViewManagerCommand( this.getWebViewHandle(), - UIManager.RCTWebView.Commands.stopLoading, + this._getCommands().stopLoading, null, ); }; @@ -572,7 +607,7 @@ class WebView extends React.Component { postMessage = data => { UIManager.dispatchViewManagerCommand( this.getWebViewHandle(), - UIManager.RCTWebView.Commands.postMessage, + this._getCommands().postMessage, [String(data)], ); }; @@ -586,7 +621,7 @@ class WebView extends React.Component { injectJavaScript = data => { UIManager.dispatchViewManagerCommand( this.getWebViewHandle(), - UIManager.RCTWebView.Commands.injectJavaScript, + this._getCommands().injectJavaScript, [data], ); }; @@ -641,9 +676,36 @@ class WebView extends React.Component { const {onMessage} = this.props; onMessage && onMessage(event); }; + + componentDidUpdate(prevProps) { + if (!(prevProps.useWebKit && this.props.useWebKit)) { + return; + } + + this._showRedboxOnPropChanges(prevProps, 'allowsInlineMediaPlayback'); + this._showRedboxOnPropChanges(prevProps, 'mediaPlaybackRequiresUserAction'); + this._showRedboxOnPropChanges(prevProps, 'dataDetectorTypes'); + } + + _showRedboxOnPropChanges(prevProps, propName: string) { + if (this.props[propName] !== prevProps[propName]) { + console.error( + `Changes to property ${propName} do nothing after the initial render.`, + ); + } + } } -const RCTWebView = requireNativeComponent('RCTWebView'); +const RCTWebView = requireNativeComponent( + 'RCTWebView', + WebView, + WebView.extraNativeComponentConfig, +); +const RCTWKWebView = requireNativeComponent( + 'RCTWKWebView', + WebView, + WebView.extraNativeComponentConfig, +); const styles = StyleSheet.create({ container: {