Skip to content

Commit

Permalink
Implement 'dataDetectorTypes' prop
Browse files Browse the repository at this point in the history
Summary:
When text is rendered in `WKWebView` WebKit component, the component itself can detect things like phone numbers, flight numbers, links, etc. and render them with additional functionality.

For example, when the text `apple.com` is detected, if the `link` data detector type is enabled, the web view will actually render a link that takes the user to the Apple home page.

In this diff, I implement the `dataDetectorTypes` prop. The data detector types supported are:
1. phoneNumber
1. link
1. address
1. calendarEvent
1. trackingNumber
1. flightNumber
1. lookupSuggestion

These enums are documented in the [[ https://developer.apple.com/documentation/webkit/wkdatadetectortypes | WKDataDetectorTypes docs ]].

Reviewed By: shergin

Differential Revision: D6392546

fbshipit-source-id: 4dd373f0ac52f898163cd959eeef6672e55b42a6
  • Loading branch information
RSNara authored and facebook-github-bot committed Aug 16, 2018
1 parent 7217630 commit 1af17f1
Show file tree
Hide file tree
Showing 7 changed files with 23 additions and 3 deletions.
2 changes: 2 additions & 0 deletions Libraries/Components/WKWebView/WKWebView.ios.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@ const RCTWKWebView = requireNativeComponent('RCTWKWebView');
type RCTWKWebViewProps = {
allowsInlineMediaPlayback?: boolean,
mediaPlaybackRequiresUserAction?: boolean,
dataDetectorTypes?: boolean,
};

class WKWebView extends React.Component<RCTWKWebViewProps> {
componentWillReceiveProps(nextProps: RCTWKWebViewProps) {
this.showRedboxOnPropChanges(nextProps, 'allowsInlineMediaPlayback');
this.showRedboxOnPropChanges(nextProps, 'mediaPlaybackRequiresUserAction');
this.showRedboxOnPropChanges(nextProps, 'dataDetectorTypes');
}

showRedboxOnPropChanges(nextProps: RCTWKWebViewProps, propName: string) {
Expand Down
2 changes: 2 additions & 0 deletions React/Base/RCTConvert.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#import <React/RCTPointerEvents.h>
#import <React/RCTTextDecorationLineType.h>
#import <yoga/Yoga.h>
#import <WebKit/WebKit.h>

/**
* This class provides a collection of conversion functions for mapping
Expand Down Expand Up @@ -68,6 +69,7 @@ typedef NSURL RCTFileURL;
+ (UIReturnKeyType)UIReturnKeyType:(id)json;
#if !TARGET_OS_TV
+ (UIDataDetectorTypes)UIDataDetectorTypes:(id)json;
+ (WKDataDetectorTypes)WKDataDetectorTypes:(id)json;
#endif

+ (UIViewContentMode)UIViewContentMode:(id)json;
Expand Down
12 changes: 12 additions & 0 deletions React/Base/RCTConvert.m
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,18 @@ + (NSLocale *)NSLocale:(id)json
@"none": @(UIDataDetectorTypeNone),
@"all": @(UIDataDetectorTypeAll),
}), UIDataDetectorTypePhoneNumber, unsignedLongLongValue)

RCT_MULTI_ENUM_CONVERTER(WKDataDetectorTypes, (@{
@"phoneNumber": @(WKDataDetectorTypePhoneNumber),
@"link": @(WKDataDetectorTypeLink),
@"address": @(WKDataDetectorTypeAddress),
@"calendarEvent": @(WKDataDetectorTypeCalendarEvent),
@"trackingNumber": @(WKDataDetectorTypeTrackingNumber),
@"flightNumber": @(WKDataDetectorTypeFlightNumber),
@"lookupSuggestion": @(WKDataDetectorTypeLookupSuggestion),
@"none": @(WKDataDetectorTypeNone),
@"all": @(WKDataDetectorTypeAll),
}), WKDataDetectorTypePhoneNumber, unsignedLongLongValue)
#endif

RCT_ENUM_CONVERTER(UIKeyboardAppearance, (@{
Expand Down
2 changes: 2 additions & 0 deletions React/Views/RCTWKWebView.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
*/

#import <React/RCTView.h>
#import <WebKit/WebKit.h>

@class RCTWKWebView;

Expand All @@ -30,6 +31,7 @@ shouldStartLoadForRequest:(NSMutableDictionary<NSString *, id> *)request
@property (nonatomic, assign) BOOL allowsInlineMediaPlayback;
@property (nonatomic, assign) BOOL bounces;
@property (nonatomic, assign) BOOL mediaPlaybackRequiresUserAction;
@property (nonatomic, assign) WKDataDetectorTypes dataDetectorTypes;

- (void)postMessage:(NSString *)message;
- (void)injectJavaScript:(NSString *)script;
Expand Down
2 changes: 1 addition & 1 deletion React/Views/RCTWKWebView.m
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#import "RCTWKWebView.h"
#import <WebKit/WebKit.h>
#import <React/RCTConvert.h>
#import "RCTAutoInsetsProtocol.h"

Expand Down Expand Up @@ -43,6 +42,7 @@ - (void)didMoveToWindow
wkWebViewConfig.mediaTypesRequiringUserActionForPlayback = _mediaPlaybackRequiresUserAction
? WKAudiovisualMediaTypeAll
: WKAudiovisualMediaTypeNone;
wkWebViewConfig.dataDetectorTypes = _dataDetectorTypes;

_webView = [[WKWebView alloc] initWithFrame:self.bounds configuration: wkWebViewConfig];
_webView.scrollView.delegate = self;
Expand Down
2 changes: 2 additions & 0 deletions React/Views/RCTWKWebViewManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ - (UIView *)view
RCT_EXPORT_VIEW_PROPERTY(injectedJavaScript, NSString)
RCT_EXPORT_VIEW_PROPERTY(allowsInlineMediaPlayback, BOOL)
RCT_EXPORT_VIEW_PROPERTY(mediaPlaybackRequiresUserAction, BOOL)
RCT_EXPORT_VIEW_PROPERTY(dataDetectorTypes, WKDataDetectorTypes)

/**
* Expose methods to enable messaging the webview.
*/
Expand Down
4 changes: 2 additions & 2 deletions React/Views/RCTWebViewManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ - (UIView *)view

RCT_EXPORT_METHOD(goForward:(nonnull NSNumber *)reactTag)
{
[self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
id view = viewRegistry[reactTag];
[self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, RCTWebView *> *viewRegistry) {
RCTWebView *view = viewRegistry[reactTag];
if (![view isKindOfClass:[RCTWebView class]]) {
RCTLogError(@"Invalid view returned from registry, expecting RCTWebView, got: %@", view);
} else {
Expand Down

0 comments on commit 1af17f1

Please sign in to comment.