Implement 'allowsInlineMediaPlayback` prop

Summary:
For iPhones with small screen sizes (e.g: iPhone 5s), inside the `<WKWebView/>` component, videos will play in fullscreen mode. In this diff, I introduce a prop called `allowsInlineMediaPlayback` that when set to true, will allow videos to play inline.

**Note:** For videos to play inline, the HTML video element must also have a `playsinline` attribute on it.

Reviewed By: shergin

Differential Revision: D6379770

fbshipit-source-id: a0130720ffede6c24a90cad0c97a75b657d77017
This commit is contained in:
Ramanpreet Nara 2018-08-16 13:34:18 -07:00 committed by Facebook Github Bot
parent a997c0ac16
commit 4ca949b46e
4 changed files with 80 additions and 27 deletions

View File

@ -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<RCTWKWebViewProps> {
componentWillReceiveProps(nextProps: RCTWKWebViewProps) {
if (this.props.allowsInlineMediaPlayback !== nextProps.allowsInlineMediaPlayback) {
console.error('Changes to property allowsInlineMediaPlayback do nothing after the initial render.');
}
}
render() {
return <RCTWKWebView {...this.props}/>;
}
}
module.exports = WKWebView;

View File

@ -27,6 +27,8 @@ shouldStartLoadForRequest:(NSMutableDictionary<NSString *, id> *)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;

View File

@ -27,17 +27,30 @@ static NSString *const MessageHanderName = @"ReactNative";
{
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,34 +72,41 @@ static NSString *const MessageHanderName = @"ReactNative";
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;
}
[_webView loadRequest:request];
}
}
- (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 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];
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
@ -95,6 +115,7 @@ static NSString *const MessageHanderName = @"ReactNative";
- (void)setScrollEnabled:(BOOL)scrollEnabled
{
_scrollEnabled = scrollEnabled;
_webView.scrollView.scrollEnabled = scrollEnabled;
}
@ -305,4 +326,10 @@ static NSString *const MessageHanderName = @"ReactNative";
{
[_webView stopLoading];
}
- (void)setBounces:(BOOL)bounces
{
_bounces = bounces;
_webView.scrollView.bounces = bounces;
}
@end

View File

@ -27,6 +27,7 @@ RCT_EXPORT_VIEW_PROPERTY(onLoadingFinish, RCTDirectEventBlock)
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 @@ RCT_EXPORT_METHOD(postMessage:(nonnull NSNumber *)reactTag message:(NSString *)m
}];
}
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];
}