diff --git a/Libraries/Components/WKWebView/WKWebView.ios.js b/Libraries/Components/WKWebView/WKWebView.ios.js index d1af14bfebd6e7..d097ea48efe0ce 100644 --- a/Libraries/Components/WKWebView/WKWebView.ios.js +++ b/Libraries/Components/WKWebView/WKWebView.ios.js @@ -9,6 +9,26 @@ * @providesModule WKWebView */ +const React = require('react'); + const requireNativeComponent = require('requireNativeComponent'); -module.exports = requireNativeComponent('RCTWKWebView'); +const RCTWKWebView = requireNativeComponent('RCTWKWebView'); + +type RCTWKWebViewProps = { + allowsInlineMediaPlayback?: boolean, +}; + +class WKWebView extends React.Component { + componentWillReceiveProps(nextProps: RCTWKWebViewProps) { + if (this.props.allowsInlineMediaPlayback !== nextProps.allowsInlineMediaPlayback) { + console.error('Changes to property allowsInlineMediaPlayback do nothing after the initial render.'); + } + } + + render() { + return ; + } +} + +module.exports = WKWebView; diff --git a/React/Views/RCTWKWebView.h b/React/Views/RCTWKWebView.h index cb4971537e0e90..b19b9d10f2fac7 100644 --- a/React/Views/RCTWKWebView.h +++ b/React/Views/RCTWKWebView.h @@ -27,6 +27,8 @@ shouldStartLoadForRequest:(NSMutableDictionary *)request @property (nonatomic, copy) NSString *injectedJavaScript; @property (nonatomic, assign) BOOL scrollEnabled; @property (nonatomic, assign) CGFloat decelerationRate; +@property (nonatomic, assign) BOOL allowsInlineMediaPlayback; +@property (nonatomic, assign) BOOL bounces; - (void)postMessage:(NSString *)message; - (void)injectJavaScript:(NSString *)script; diff --git a/React/Views/RCTWKWebView.m b/React/Views/RCTWKWebView.m index 15fdd844e7e2ae..31ba395201145f 100644 --- a/React/Views/RCTWKWebView.m +++ b/React/Views/RCTWKWebView.m @@ -27,17 +27,30 @@ - (instancetype)initWithFrame:(CGRect)frame { if ((self = [super initWithFrame:frame])) { super.backgroundColor = [UIColor clearColor]; + _bounces = YES; + _scrollEnabled = YES; + } + return self; +} + +- (void)didMoveToWindow +{ + if (self.window != nil) { WKWebViewConfiguration *wkWebViewConfig = [WKWebViewConfiguration new]; wkWebViewConfig.userContentController = [WKUserContentController new]; [wkWebViewConfig.userContentController addScriptMessageHandler: self name: MessageHanderName]; + wkWebViewConfig.allowsInlineMediaPlayback = _allowsInlineMediaPlayback; _webView = [[WKWebView alloc] initWithFrame:self.bounds configuration: wkWebViewConfig]; _webView.scrollView.delegate = self; _webView.UIDelegate = self; _webView.navigationDelegate = self; + _webView.scrollView.scrollEnabled = _scrollEnabled; + _webView.scrollView.bounces = _bounces; [self addSubview:_webView]; + + [self visitSource]; } - return self; } /** @@ -59,32 +72,39 @@ - (void)setSource:(NSDictionary *)source if (![_source isEqualToDictionary:source]) { _source = [source copy]; - // Check for a static html source first - NSString *html = [RCTConvert NSString:source[@"html"]]; - if (html) { - NSURL *baseURL = [RCTConvert NSURL:source[@"baseUrl"]]; - if (!baseURL) { - baseURL = [NSURL URLWithString:@"about:blank"]; - } - [_webView loadHTMLString:html baseURL:baseURL]; - return; + if (_webView != nil) { + [self visitSource]; } + } +} - NSURLRequest *request = [RCTConvert NSURLRequest:source]; - // Because of the way React works, as pages redirect, we actually end up - // passing the redirect urls back here, so we ignore them if trying to load - // the same url. We'll expose a call to 'reload' to allow a user to load - // the existing page. - if ([request.URL isEqual:_webView.URL]) { - return; - } - if (!request.URL) { - // Clear the webview - [_webView loadHTMLString:@"" baseURL:nil]; - return; +- (void)visitSource +{ + // Check for a static html source first + NSString *html = [RCTConvert NSString:_source[@"html"]]; + if (html) { + NSURL *baseURL = [RCTConvert NSURL:_source[@"baseUrl"]]; + if (!baseURL) { + baseURL = [NSURL URLWithString:@"about:blank"]; } - [_webView loadRequest:request]; + [_webView loadHTMLString:html baseURL:baseURL]; + return; } + + NSURLRequest *request = [RCTConvert NSURLRequest:_source]; + // Because of the way React works, as pages redirect, we actually end up + // passing the redirect urls back here, so we ignore them if trying to load + // the same url. We'll expose a call to 'reload' to allow a user to load + // the existing page. + if ([request.URL isEqual:_webView.URL]) { + return; + } + if (!request.URL) { + // Clear the webview + [_webView loadHTMLString:@"" baseURL:nil]; + return; + } + [_webView loadRequest:request]; } @@ -95,6 +115,7 @@ - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView - (void)setScrollEnabled:(BOOL)scrollEnabled { + _scrollEnabled = scrollEnabled; _webView.scrollView.scrollEnabled = scrollEnabled; } @@ -305,4 +326,10 @@ - (void)stopLoading { [_webView stopLoading]; } + +- (void)setBounces:(BOOL)bounces +{ + _bounces = bounces; + _webView.scrollView.bounces = bounces; +} @end diff --git a/React/Views/RCTWKWebViewManager.m b/React/Views/RCTWKWebViewManager.m index 20244c11f0e63f..eef5b4f0612d53 100644 --- a/React/Views/RCTWKWebViewManager.m +++ b/React/Views/RCTWKWebViewManager.m @@ -27,6 +27,7 @@ - (UIView *)view RCT_EXPORT_VIEW_PROPERTY(onLoadingError, RCTDirectEventBlock) RCT_EXPORT_VIEW_PROPERTY(onShouldStartLoadWithRequest, RCTDirectEventBlock) RCT_EXPORT_VIEW_PROPERTY(injectedJavaScript, NSString) +RCT_EXPORT_VIEW_PROPERTY(allowsInlineMediaPlayback, BOOL) /** * Expose methods to enable messaging the webview. @@ -46,7 +47,10 @@ - (UIView *)view }]; } -RCT_REMAP_VIEW_PROPERTY(bounces, _webView.scrollView.bounces, BOOL) +RCT_CUSTOM_VIEW_PROPERTY(bounces, BOOL, RCTWKWebView) { + view.bounces = json == nil ? true : [RCTConvert BOOL: json]; +} + RCT_CUSTOM_VIEW_PROPERTY(scrollEnabled, BOOL, RCTWKWebView) { view.scrollEnabled = json == nil ? true : [RCTConvert BOOL: json]; }