From b1251d067ac58a0216fef734b55e4e36a15f5f75 Mon Sep 17 00:00:00 2001 From: Kyle Pinkham Date: Tue, 26 Mar 2019 12:25:33 -0700 Subject: [PATCH] Implement data detection for android Text elements (#19216) Summary: We want the ability to use Linkify on android text elements. This only adds this property to Text and not TextInput since there are some functional differences with how the types could be used between iOS and android - iOS allows one or many types while Linkify restricted us to providing only one option (using the masks). Performance is affected ONLY FOR TEXT ELEMENTS USING THIS FEATURE since Linkify is searching for patterns. Pull Request resolved: https://github.com/facebook/react-native/pull/19216 Differential Revision: D14621883 Pulled By: cpojer fbshipit-source-id: cb692021d314140b9a92b29e23384afd7fd1b09e --- Libraries/Text/Text.js | 1 + Libraries/Text/TextPropTypes.js | 8 +++++++ Libraries/Text/TextProps.js | 2 ++ RNTester/js/TextExample.android.js | 13 +++++++++++ .../text/ReactTextAnchorViewManager.java | 23 +++++++++++++++++++ .../react/views/text/ReactTextView.java | 15 +++++++++++- 6 files changed, 61 insertions(+), 1 deletion(-) diff --git a/Libraries/Text/Text.js b/Libraries/Text/Text.js index 9724057930b..dd1ccffc7e1 100644 --- a/Libraries/Text/Text.js +++ b/Libraries/Text/Text.js @@ -66,6 +66,7 @@ const viewConfig = { minimumFontScale: true, textBreakStrategy: true, onTextLayout: true, + dataDetectorType: true, }, directEventTypes: { topTextLayout: { diff --git a/Libraries/Text/TextPropTypes.js b/Libraries/Text/TextPropTypes.js index dddb43ea007..ea09e6a51f5 100644 --- a/Libraries/Text/TextPropTypes.js +++ b/Libraries/Text/TextPropTypes.js @@ -18,6 +18,8 @@ const TextStylePropTypes = require('TextStylePropTypes'); const stylePropType = DeprecatedStyleSheetPropType(TextStylePropTypes); +const DataDetectorTypes = ['phoneNumber', 'link', 'email', 'none', 'all']; + module.exports = { /** * When `numberOfLines` is set, this prop defines how text will be @@ -132,4 +134,10 @@ module.exports = { * See https://facebook.github.io/react-native/docs/text.html#disabled */ disabled: PropTypes.bool, + /** + * Determines the types of data converted to clickable URLs in text. + * + * See https://facebook.github.io/react-native/docs/text.html#dataDetectorType + */ + dataDetectorType: PropTypes.oneOf(DataDetectorTypes), }; diff --git a/Libraries/Text/TextProps.js b/Libraries/Text/TextProps.js index 2ffa8959f4e..bb56651a478 100644 --- a/Libraries/Text/TextProps.js +++ b/Libraries/Text/TextProps.js @@ -158,6 +158,8 @@ export type TextProps = $ReadOnly<{| */ selectionColor?: ?string, + dataDetectorType?: ?('phoneNumber' | 'link' | 'email' | 'none' | 'all'), + /** * Set text break strategy on Android. * diff --git a/RNTester/js/TextExample.android.js b/RNTester/js/TextExample.android.js index 6198077bd74..131e5343759 100644 --- a/RNTester/js/TextExample.android.js +++ b/RNTester/js/TextExample.android.js @@ -623,6 +623,19 @@ class TextExample extends React.Component<{}> { {'test🙃'.substring(0, 5)} + + Phone number: 123-123-1234 + Link: https://www.facebook.com + Email: employee@facebook.com + + Phone number: 123-123-1234 Link: https://www.facebook.com Email: + employee@facebook.com + + + Phone number: 123-123-1234 Link: https://www.facebook.com Email: + employee@facebook.com + + ); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextAnchorViewManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextAnchorViewManager.java index 4ebfc827cce..73ec4529205 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextAnchorViewManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextAnchorViewManager.java @@ -9,6 +9,7 @@ package com.facebook.react.views.text; import android.text.Spannable; import android.text.TextUtils; +import android.text.util.Linkify; import android.view.Gravity; import android.view.View; import com.facebook.react.bridge.JSApplicationIllegalArgumentException; @@ -160,4 +161,26 @@ public abstract class ReactTextAnchorViewManager 0) { + Linkify.addLinks(spannable, mLinkifyMaskType); + setMovementMethod(LinkMovementMethod.getInstance()); + } + setText(spannable); setPadding( (int) Math.floor(update.getPaddingLeft()), (int) Math.floor(update.getPaddingTop()), @@ -276,4 +285,8 @@ public class ReactTextView extends AppCompatTextView implements ReactCompoundVie public Spannable getSpanned() { return mSpanned; } + + public void setLinkifyMask(int mask) { + mLinkifyMaskType = mask; + } }