react-native-enriched 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (186) hide show
  1. package/README.md +16 -17
  2. package/android/build.gradle +77 -72
  3. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerDelegate.java +21 -0
  4. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerInterface.java +7 -0
  5. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/EventEmitters.cpp +156 -0
  6. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/EventEmitters.h +147 -0
  7. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/Props.cpp +10 -0
  8. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/Props.h +194 -0
  9. package/android/lint.gradle +70 -0
  10. package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputConnectionWrapper.kt +140 -0
  11. package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputView.kt +304 -83
  12. package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewLayoutManager.kt +3 -1
  13. package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewManager.kt +166 -51
  14. package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewPackage.kt +1 -3
  15. package/android/src/main/java/com/swmansion/enriched/MeasurementStore.kt +70 -21
  16. package/android/src/main/java/com/swmansion/enriched/events/MentionHandler.kt +21 -11
  17. package/android/src/main/java/com/swmansion/enriched/events/OnChangeHtmlEvent.kt +8 -9
  18. package/android/src/main/java/com/swmansion/enriched/events/OnChangeSelectionEvent.kt +10 -9
  19. package/android/src/main/java/com/swmansion/enriched/events/OnChangeStateDeprecatedEvent.kt +21 -0
  20. package/android/src/main/java/com/swmansion/enriched/events/OnChangeStateEvent.kt +9 -12
  21. package/android/src/main/java/com/swmansion/enriched/events/OnChangeTextEvent.kt +10 -10
  22. package/android/src/main/java/com/swmansion/enriched/events/OnInputBlurEvent.kt +7 -9
  23. package/android/src/main/java/com/swmansion/enriched/events/OnInputFocusEvent.kt +7 -9
  24. package/android/src/main/java/com/swmansion/enriched/events/OnInputKeyPressEvent.kt +27 -0
  25. package/android/src/main/java/com/swmansion/enriched/events/OnLinkDetectedEvent.kt +13 -11
  26. package/android/src/main/java/com/swmansion/enriched/events/OnMentionDetectedEvent.kt +10 -9
  27. package/android/src/main/java/com/swmansion/enriched/events/OnMentionEvent.kt +9 -8
  28. package/android/src/main/java/com/swmansion/enriched/events/OnRequestHtmlResultEvent.kt +32 -0
  29. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedBlockQuoteSpan.kt +24 -5
  30. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedBoldSpan.kt +8 -1
  31. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedCodeBlockSpan.kt +10 -2
  32. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH1Span.kt +8 -1
  33. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH2Span.kt +8 -1
  34. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH3Span.kt +8 -1
  35. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH4Span.kt +24 -0
  36. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH5Span.kt +24 -0
  37. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH6Span.kt +24 -0
  38. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedImageSpan.kt +34 -17
  39. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedInlineCodeSpan.kt +8 -1
  40. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedItalicSpan.kt +7 -1
  41. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedLinkSpan.kt +10 -4
  42. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedMentionSpan.kt +14 -11
  43. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedOrderedListSpan.kt +18 -11
  44. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedSpans.kt +174 -72
  45. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedStrikeThroughSpan.kt +7 -1
  46. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedUnderlineSpan.kt +7 -1
  47. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedUnorderedListSpan.kt +11 -5
  48. package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedBlockSpan.kt +3 -2
  49. package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedHeadingSpan.kt +1 -2
  50. package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedInlineSpan.kt +1 -2
  51. package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedParagraphSpan.kt +3 -2
  52. package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedSpan.kt +5 -0
  53. package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedZeroWidthSpaceSpan.kt +1 -2
  54. package/android/src/main/java/com/swmansion/enriched/spans/utils/ForceRedrawSpan.kt +2 -1
  55. package/android/src/main/java/com/swmansion/enriched/styles/HtmlStyle.kt +155 -20
  56. package/android/src/main/java/com/swmansion/enriched/styles/InlineStyles.kt +25 -8
  57. package/android/src/main/java/com/swmansion/enriched/styles/ListStyles.kt +60 -20
  58. package/android/src/main/java/com/swmansion/enriched/styles/ParagraphStyles.kt +161 -25
  59. package/android/src/main/java/com/swmansion/enriched/styles/ParametrizedStyles.kt +128 -52
  60. package/android/src/main/java/com/swmansion/enriched/utils/AsyncDrawable.kt +10 -7
  61. package/android/src/main/java/com/swmansion/enriched/utils/EnrichedConstants.kt +11 -0
  62. package/android/src/main/java/com/swmansion/enriched/utils/EnrichedEditableFactory.kt +17 -0
  63. package/android/src/main/java/com/swmansion/enriched/utils/EnrichedParser.java +136 -87
  64. package/android/src/main/java/com/swmansion/enriched/utils/EnrichedSelection.kt +71 -42
  65. package/android/src/main/java/com/swmansion/enriched/utils/EnrichedSpanState.kt +183 -48
  66. package/android/src/main/java/com/swmansion/enriched/utils/EnrichedSpannable.kt +82 -0
  67. package/android/src/main/java/com/swmansion/enriched/utils/EnrichedSpannableStringBuilder.kt +15 -0
  68. package/android/src/main/java/com/swmansion/enriched/utils/Utils.kt +0 -70
  69. package/android/src/main/java/com/swmansion/enriched/watchers/EnrichedSpanWatcher.kt +46 -14
  70. package/android/src/main/java/com/swmansion/enriched/watchers/EnrichedTextWatcher.kt +34 -11
  71. package/android/src/main/new_arch/CMakeLists.txt +6 -0
  72. package/android/src/main/new_arch/RNEnrichedTextInputViewSpec.cpp +6 -6
  73. package/android/src/main/new_arch/RNEnrichedTextInputViewSpec.h +6 -6
  74. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputComponentDescriptor.h +19 -19
  75. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputMeasurementManager.cpp +40 -51
  76. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputMeasurementManager.h +13 -15
  77. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputShadowNode.cpp +23 -21
  78. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputShadowNode.h +35 -36
  79. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputState.cpp +4 -4
  80. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputState.h +13 -14
  81. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/conversions.h +33 -14
  82. package/ios/EnrichedTextInputView.h +26 -14
  83. package/ios/EnrichedTextInputView.mm +1209 -586
  84. package/ios/config/InputConfig.h +24 -6
  85. package/ios/config/InputConfig.mm +154 -38
  86. package/ios/{utils → extensions}/ColorExtension.mm +7 -5
  87. package/ios/extensions/FontExtension.mm +106 -0
  88. package/ios/{utils → extensions}/LayoutManagerExtension.h +1 -1
  89. package/ios/extensions/LayoutManagerExtension.mm +396 -0
  90. package/ios/{utils → extensions}/StringExtension.mm +19 -16
  91. package/ios/generated/RNEnrichedTextInputViewSpec/EventEmitters.cpp +156 -0
  92. package/ios/generated/RNEnrichedTextInputViewSpec/EventEmitters.h +147 -0
  93. package/ios/generated/RNEnrichedTextInputViewSpec/Props.cpp +10 -0
  94. package/ios/generated/RNEnrichedTextInputViewSpec/Props.h +194 -0
  95. package/ios/generated/RNEnrichedTextInputViewSpec/RCTComponentViewHelpers.h +95 -0
  96. package/ios/inputParser/InputParser.h +5 -5
  97. package/ios/inputParser/InputParser.mm +864 -380
  98. package/ios/inputTextView/InputTextView.h +1 -1
  99. package/ios/inputTextView/InputTextView.mm +100 -59
  100. package/ios/{utils → interfaces}/BaseStyleProtocol.h +2 -2
  101. package/ios/interfaces/ImageAttachment.h +10 -0
  102. package/ios/interfaces/ImageAttachment.mm +36 -0
  103. package/ios/interfaces/LinkRegexConfig.h +19 -0
  104. package/ios/interfaces/LinkRegexConfig.mm +37 -0
  105. package/ios/interfaces/MediaAttachment.h +23 -0
  106. package/ios/interfaces/MediaAttachment.mm +31 -0
  107. package/ios/{utils → interfaces}/MentionParams.h +0 -1
  108. package/ios/{utils → interfaces}/MentionStyleProps.mm +27 -20
  109. package/ios/{utils → interfaces}/StyleHeaders.h +37 -15
  110. package/ios/{utils → interfaces}/StyleTypeEnum.h +3 -0
  111. package/ios/internals/EnrichedTextInputViewComponentDescriptor.h +11 -9
  112. package/ios/internals/EnrichedTextInputViewShadowNode.h +28 -25
  113. package/ios/internals/EnrichedTextInputViewShadowNode.mm +45 -40
  114. package/ios/internals/EnrichedTextInputViewState.h +3 -1
  115. package/ios/styles/BlockQuoteStyle.mm +189 -118
  116. package/ios/styles/BoldStyle.mm +110 -63
  117. package/ios/styles/CodeBlockStyle.mm +204 -128
  118. package/ios/styles/H1Style.mm +10 -4
  119. package/ios/styles/H2Style.mm +10 -4
  120. package/ios/styles/H3Style.mm +10 -4
  121. package/ios/styles/H4Style.mm +17 -0
  122. package/ios/styles/H5Style.mm +17 -0
  123. package/ios/styles/H6Style.mm +17 -0
  124. package/ios/styles/HeadingStyleBase.mm +148 -86
  125. package/ios/styles/ImageStyle.mm +75 -73
  126. package/ios/styles/InlineCodeStyle.mm +162 -88
  127. package/ios/styles/ItalicStyle.mm +76 -52
  128. package/ios/styles/LinkStyle.mm +411 -232
  129. package/ios/styles/MentionStyle.mm +363 -246
  130. package/ios/styles/OrderedListStyle.mm +171 -106
  131. package/ios/styles/StrikethroughStyle.mm +52 -35
  132. package/ios/styles/UnderlineStyle.mm +68 -46
  133. package/ios/styles/UnorderedListStyle.mm +169 -106
  134. package/ios/utils/OccurenceUtils.h +42 -42
  135. package/ios/utils/OccurenceUtils.mm +142 -119
  136. package/ios/utils/ParagraphAttributesUtils.h +10 -2
  137. package/ios/utils/ParagraphAttributesUtils.mm +182 -71
  138. package/ios/utils/ParagraphsUtils.h +2 -1
  139. package/ios/utils/ParagraphsUtils.mm +41 -27
  140. package/ios/utils/TextInsertionUtils.h +13 -2
  141. package/ios/utils/TextInsertionUtils.mm +38 -20
  142. package/ios/utils/WordsUtils.h +2 -1
  143. package/ios/utils/WordsUtils.mm +32 -22
  144. package/ios/utils/ZeroWidthSpaceUtils.h +3 -1
  145. package/ios/utils/ZeroWidthSpaceUtils.mm +145 -79
  146. package/lib/module/EnrichedTextInput.js +61 -2
  147. package/lib/module/EnrichedTextInput.js.map +1 -1
  148. package/lib/module/EnrichedTextInputNativeComponent.ts +149 -12
  149. package/lib/module/{normalizeHtmlStyle.js → utils/normalizeHtmlStyle.js} +12 -0
  150. package/lib/module/utils/normalizeHtmlStyle.js.map +1 -0
  151. package/lib/module/utils/regexParser.js +46 -0
  152. package/lib/module/utils/regexParser.js.map +1 -0
  153. package/lib/typescript/src/EnrichedTextInput.d.ts +24 -14
  154. package/lib/typescript/src/EnrichedTextInput.d.ts.map +1 -1
  155. package/lib/typescript/src/EnrichedTextInputNativeComponent.d.ts +129 -12
  156. package/lib/typescript/src/EnrichedTextInputNativeComponent.d.ts.map +1 -1
  157. package/lib/typescript/src/index.d.ts +1 -1
  158. package/lib/typescript/src/index.d.ts.map +1 -1
  159. package/lib/typescript/src/utils/normalizeHtmlStyle.d.ts +4 -0
  160. package/lib/typescript/src/utils/normalizeHtmlStyle.d.ts.map +1 -0
  161. package/lib/typescript/src/utils/regexParser.d.ts +3 -0
  162. package/lib/typescript/src/utils/regexParser.d.ts.map +1 -0
  163. package/package.json +17 -6
  164. package/src/EnrichedTextInput.tsx +96 -13
  165. package/src/EnrichedTextInputNativeComponent.ts +149 -12
  166. package/src/index.tsx +2 -0
  167. package/src/{normalizeHtmlStyle.ts → utils/normalizeHtmlStyle.ts} +14 -2
  168. package/src/utils/regexParser.ts +56 -0
  169. package/ios/utils/FontExtension.mm +0 -91
  170. package/ios/utils/LayoutManagerExtension.mm +0 -286
  171. package/lib/module/normalizeHtmlStyle.js.map +0 -1
  172. package/lib/typescript/src/normalizeHtmlStyle.d.ts +0 -4
  173. package/lib/typescript/src/normalizeHtmlStyle.d.ts.map +0 -1
  174. package/ios/{utils → extensions}/ColorExtension.h +0 -0
  175. package/ios/{utils → extensions}/FontExtension.h +0 -0
  176. package/ios/{utils → extensions}/StringExtension.h +1 -1
  177. package/ios/{utils → interfaces}/ImageData.h +0 -0
  178. package/ios/{utils → interfaces}/ImageData.mm +0 -0
  179. package/ios/{utils → interfaces}/LinkData.h +0 -0
  180. package/ios/{utils → interfaces}/LinkData.mm +0 -0
  181. package/ios/{utils → interfaces}/MentionParams.mm +0 -0
  182. package/ios/{utils → interfaces}/MentionStyleProps.h +1 -1
  183. /package/ios/{utils → interfaces}/StylePair.h +0 -0
  184. /package/ios/{utils → interfaces}/StylePair.mm +0 -0
  185. /package/ios/{utils → interfaces}/TextDecorationLineEnum.h +0 -0
  186. /package/ios/{utils → interfaces}/TextDecorationLineEnum.mm +0 -0
@@ -9,13 +9,15 @@ import android.text.Spanned;
9
9
  import android.text.TextUtils;
10
10
  import android.text.style.AlignmentSpan;
11
11
  import android.text.style.ParagraphStyle;
12
-
13
12
  import com.swmansion.enriched.spans.EnrichedBlockQuoteSpan;
14
13
  import com.swmansion.enriched.spans.EnrichedBoldSpan;
15
14
  import com.swmansion.enriched.spans.EnrichedCodeBlockSpan;
16
15
  import com.swmansion.enriched.spans.EnrichedH1Span;
17
16
  import com.swmansion.enriched.spans.EnrichedH2Span;
18
17
  import com.swmansion.enriched.spans.EnrichedH3Span;
18
+ import com.swmansion.enriched.spans.EnrichedH4Span;
19
+ import com.swmansion.enriched.spans.EnrichedH5Span;
20
+ import com.swmansion.enriched.spans.EnrichedH6Span;
19
21
  import com.swmansion.enriched.spans.EnrichedImageSpan;
20
22
  import com.swmansion.enriched.spans.EnrichedInlineCodeSpan;
21
23
  import com.swmansion.enriched.spans.EnrichedItalicSpan;
@@ -26,11 +28,14 @@ import com.swmansion.enriched.spans.EnrichedStrikeThroughSpan;
26
28
  import com.swmansion.enriched.spans.EnrichedUnderlineSpan;
27
29
  import com.swmansion.enriched.spans.EnrichedUnorderedListSpan;
28
30
  import com.swmansion.enriched.spans.interfaces.EnrichedBlockSpan;
29
- import com.swmansion.enriched.spans.interfaces.EnrichedParagraphSpan;
30
31
  import com.swmansion.enriched.spans.interfaces.EnrichedInlineSpan;
32
+ import com.swmansion.enriched.spans.interfaces.EnrichedParagraphSpan;
31
33
  import com.swmansion.enriched.spans.interfaces.EnrichedZeroWidthSpaceSpan;
32
34
  import com.swmansion.enriched.styles.HtmlStyle;
33
-
35
+ import java.io.IOException;
36
+ import java.io.StringReader;
37
+ import java.util.HashMap;
38
+ import java.util.Map;
34
39
  import org.ccil.cowan.tagsoup.HTMLSchema;
35
40
  import org.ccil.cowan.tagsoup.Parser;
36
41
  import org.xml.sax.Attributes;
@@ -42,46 +47,38 @@ import org.xml.sax.SAXNotRecognizedException;
42
47
  import org.xml.sax.SAXNotSupportedException;
43
48
  import org.xml.sax.XMLReader;
44
49
 
45
- import java.io.IOException;
46
- import java.io.StringReader;
47
- import java.util.HashMap;
48
- import java.util.Map;
49
-
50
50
  /**
51
51
  * Most of the code in this file is copied from the Android source code and adjusted to our needs.
52
- * For the reference see <a href="https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/text/Html.java">docs</a>
52
+ * For the reference see <a
53
+ * href="https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/text/Html.java">docs</a>
53
54
  */
54
55
  public class EnrichedParser {
55
- /**
56
- * Retrieves images for HTML &lt;img&gt; tags.
57
- */
56
+ /** Retrieves images for HTML &lt;img&gt; tags. */
58
57
  public interface ImageGetter {
59
58
  /**
60
- * This method is called when the HTML parser encounters an
61
- * &lt;img&gt; tag. The <code>source</code> argument is the
62
- * string from the "src" attribute; the return value should be
63
- * a Drawable representation of the image or <code>null</code>
64
- * for a generic replacement image. Make sure you call
65
- * setBounds() on your Drawable if it doesn't already have
66
- * its bounds set.
59
+ * This method is called when the HTML parser encounters an &lt;img&gt; tag. The <code>source
60
+ * </code> argument is the string from the "src" attribute; the return value should be a
61
+ * Drawable representation of the image or <code>null</code> for a generic replacement image.
62
+ * Make sure you call setBounds() on your Drawable if it doesn't already have its bounds set.
67
63
  */
68
64
  Drawable getDrawable(String source);
69
65
  }
70
66
 
71
- private EnrichedParser() { }
67
+ private EnrichedParser() {}
68
+
72
69
  /**
73
- * Lazy initialization holder for HTML parser. This class will
74
- * a) be preloaded by the zygote, or b) not loaded until absolutely
75
- * necessary.
70
+ * Lazy initialization holder for HTML parser. This class will a) be preloaded by the zygote, or
71
+ * b) not loaded until absolutely necessary.
76
72
  */
77
73
  private static class HtmlParser {
78
74
  private static final HTMLSchema schema = new HTMLSchema();
79
75
  }
76
+
80
77
  /**
81
- * Returns displayable styled text from the provided HTML string. Any &lt;img&gt; tags in the
82
- * HTML will use the specified ImageGetter to request a representation of the image (use null
83
- * if you don't want this) and the specified TagHandler to handle unknown tags (specify null if
84
- * you don't want this).
78
+ * Returns displayable styled text from the provided HTML string. Any &lt;img&gt; tags in the HTML
79
+ * will use the specified ImageGetter to request a representation of the image (use null if you
80
+ * don't want this) and the specified TagHandler to handle unknown tags (specify null if you don't
81
+ * want this).
85
82
  *
86
83
  * <p>This uses TagSoup to handle real HTML, including all of the brokenness found in the wild.
87
84
  */
@@ -93,36 +90,47 @@ public class EnrichedParser {
93
90
  // Should not happen.
94
91
  throw new RuntimeException(e);
95
92
  }
96
- HtmlToSpannedConverter converter = new HtmlToSpannedConverter(source, style, imageGetter, parser);
93
+ HtmlToSpannedConverter converter =
94
+ new HtmlToSpannedConverter(source, style, imageGetter, parser);
97
95
  return converter.convert();
98
96
  }
97
+
99
98
  public static String toHtml(Spanned text) {
100
99
  StringBuilder out = new StringBuilder();
101
100
  withinHtml(out, text);
102
101
  String outString = out.toString();
103
102
  // Codeblocks and blockquotes appends a newline character by default, so we have to remove it
104
103
  String normalizedCodeBlock = outString.replaceAll("</codeblock>\\n<br>", "</codeblock>");
105
- String normalizedBlockQuote = normalizedCodeBlock.replaceAll("</blockquote>\\n<br>", "</blockquote>");
104
+ String normalizedBlockQuote =
105
+ normalizedCodeBlock.replaceAll("</blockquote>\\n<br>", "</blockquote>");
106
106
  return "<html>\n" + normalizedBlockQuote + "</html>";
107
107
  }
108
- /**
109
- * Returns an HTML escaped representation of the given plain text.
110
- */
108
+
109
+ public static String toHtmlWithDefault(CharSequence text) {
110
+ if (text instanceof Spanned) {
111
+ return toHtml((Spanned) text);
112
+ }
113
+ return "<html>\n<p></p>\n</html>";
114
+ }
115
+
116
+ /** Returns an HTML escaped representation of the given plain text. */
111
117
  public static String escapeHtml(CharSequence text) {
112
118
  StringBuilder out = new StringBuilder();
113
119
  withinStyle(out, text, 0, text.length());
114
120
  return out.toString();
115
121
  }
122
+
116
123
  private static void withinHtml(StringBuilder out, Spanned text) {
117
124
  withinDiv(out, text, 0, text.length());
118
125
  }
126
+
119
127
  private static void withinDiv(StringBuilder out, Spanned text, int start, int end) {
120
128
  int next;
121
129
  for (int i = start; i < end; i = next) {
122
130
  next = text.nextSpanTransition(i, end, EnrichedBlockSpan.class);
123
131
  EnrichedBlockSpan[] blocks = text.getSpans(i, next, EnrichedBlockSpan.class);
124
132
  String tag = "unknown";
125
- if (blocks.length > 0){
133
+ if (blocks.length > 0) {
126
134
  tag = blocks[0] instanceof EnrichedCodeBlockSpan ? "codeblock" : "blockquote";
127
135
  }
128
136
 
@@ -141,6 +149,7 @@ public class EnrichedParser {
141
149
  }
142
150
  }
143
151
  }
152
+
144
153
  private static String getBlockTag(EnrichedParagraphSpan[] spans) {
145
154
  for (EnrichedParagraphSpan span : spans) {
146
155
  if (span instanceof EnrichedUnorderedListSpan) {
@@ -153,11 +162,18 @@ public class EnrichedParser {
153
162
  return "h2";
154
163
  } else if (span instanceof EnrichedH3Span) {
155
164
  return "h3";
165
+ } else if (span instanceof EnrichedH4Span) {
166
+ return "h4";
167
+ } else if (span instanceof EnrichedH5Span) {
168
+ return "h5";
169
+ } else if (span instanceof EnrichedH6Span) {
170
+ return "h6";
156
171
  }
157
172
  }
158
173
 
159
174
  return "p";
160
175
  }
176
+
161
177
  private static void withinBlock(StringBuilder out, Spanned text, int start, int end) {
162
178
  boolean isInUlList = false;
163
179
  boolean isInOlList = false;
@@ -179,7 +195,8 @@ public class EnrichedParser {
179
195
  }
180
196
  out.append("<br>\n");
181
197
  } else {
182
- EnrichedParagraphSpan[] paragraphStyles = text.getSpans(i, next, EnrichedParagraphSpan.class);
198
+ EnrichedParagraphSpan[] paragraphStyles =
199
+ text.getSpans(i, next, EnrichedParagraphSpan.class);
183
200
  String tag = getBlockTag(paragraphStyles);
184
201
  boolean isUlListItem = tag.equals("ul");
185
202
  boolean isOlListItem = tag.equals("ol");
@@ -226,6 +243,7 @@ public class EnrichedParser {
226
243
  next++;
227
244
  }
228
245
  }
246
+
229
247
  private static void withinParagraph(StringBuilder out, Spanned text, int start, int end) {
230
248
  int next;
231
249
  for (int i = start; i < end; i = next) {
@@ -315,11 +333,11 @@ public class EnrichedParser {
315
333
  }
316
334
  }
317
335
  }
318
- private static void withinStyle(StringBuilder out, CharSequence text,
319
- int start, int end) {
336
+
337
+ private static void withinStyle(StringBuilder out, CharSequence text, int start, int end) {
320
338
  for (int i = start; i < end; i++) {
321
339
  char c = text.charAt(i);
322
- if (c == '\u200B') {
340
+ if (c == EnrichedConstants.ZWS) {
323
341
  // Do not output zero-width space characters.
324
342
  continue;
325
343
  } else if (c == '<') {
@@ -351,6 +369,7 @@ public class EnrichedParser {
351
369
  }
352
370
  }
353
371
  }
372
+
354
373
  class HtmlToSpannedConverter implements ContentHandler {
355
374
  private final HtmlStyle mStyle;
356
375
  private final String mSource;
@@ -361,7 +380,8 @@ class HtmlToSpannedConverter implements ContentHandler {
361
380
  private static Boolean isInOrderedList = false;
362
381
  private static Boolean isEmptyTag = false;
363
382
 
364
- public HtmlToSpannedConverter(String source, HtmlStyle style, EnrichedParser.ImageGetter imageGetter, Parser parser) {
383
+ public HtmlToSpannedConverter(
384
+ String source, HtmlStyle style, EnrichedParser.ImageGetter imageGetter, Parser parser) {
365
385
  mStyle = style;
366
386
  mSource = source;
367
387
  mSpannableStringBuilder = new SpannableStringBuilder();
@@ -381,14 +401,15 @@ class HtmlToSpannedConverter implements ContentHandler {
381
401
  throw new RuntimeException(e);
382
402
  }
383
403
  // Fix flags and range for paragraph-type markup.
384
- Object[] obj = mSpannableStringBuilder.getSpans(0, mSpannableStringBuilder.length(), ParagraphStyle.class);
404
+ Object[] obj =
405
+ mSpannableStringBuilder.getSpans(0, mSpannableStringBuilder.length(), ParagraphStyle.class);
385
406
  for (int i = 0; i < obj.length; i++) {
386
407
  int start = mSpannableStringBuilder.getSpanStart(obj[i]);
387
408
  int end = mSpannableStringBuilder.getSpanEnd(obj[i]);
388
409
  // If the last line of the range is blank, back off by one.
389
410
  if (end - 2 >= 0) {
390
- if (mSpannableStringBuilder.charAt(end - 1) == '\n' &&
391
- mSpannableStringBuilder.charAt(end - 2) == '\n') {
411
+ if (mSpannableStringBuilder.charAt(end - 1) == '\n'
412
+ && mSpannableStringBuilder.charAt(end - 2) == '\n') {
392
413
  end--;
393
414
  }
394
415
  }
@@ -396,25 +417,29 @@ class HtmlToSpannedConverter implements ContentHandler {
396
417
  mSpannableStringBuilder.removeSpan(obj[i]);
397
418
  } else {
398
419
  // TODO: verify if Spannable.SPAN_EXCLUSIVE_EXCLUSIVE does not break anything.
399
- // Previously it was SPAN_PARAGRAPH. I've changed that in order to fix ranges for list items.
420
+ // Previously it was SPAN_PARAGRAPH. I've changed that in order to fix ranges for list
421
+ // items.
400
422
  mSpannableStringBuilder.setSpan(obj[i], start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
401
423
  }
402
424
  }
403
425
 
404
426
  // Assign zero-width space character to the proper spans.
405
- EnrichedZeroWidthSpaceSpan[] zeroWidthSpaceSpans = mSpannableStringBuilder.getSpans(0, mSpannableStringBuilder.length(), EnrichedZeroWidthSpaceSpan.class);
427
+ EnrichedZeroWidthSpaceSpan[] zeroWidthSpaceSpans =
428
+ mSpannableStringBuilder.getSpans(
429
+ 0, mSpannableStringBuilder.length(), EnrichedZeroWidthSpaceSpan.class);
406
430
  for (EnrichedZeroWidthSpaceSpan zeroWidthSpaceSpan : zeroWidthSpaceSpans) {
407
431
  int start = mSpannableStringBuilder.getSpanStart(zeroWidthSpaceSpan);
408
432
  int end = mSpannableStringBuilder.getSpanEnd(zeroWidthSpaceSpan);
409
433
 
410
- if (mSpannableStringBuilder.charAt(start) != '\u200B') {
434
+ if (mSpannableStringBuilder.charAt(start) != EnrichedConstants.ZWS) {
411
435
  // Insert zero-width space character at the start if it's not already present.
412
- mSpannableStringBuilder.insert(start, "\u200B");
436
+ mSpannableStringBuilder.insert(start, EnrichedConstants.ZWS_STRING);
413
437
  end++; // Adjust end position due to insertion.
414
438
  }
415
439
 
416
440
  mSpannableStringBuilder.removeSpan(zeroWidthSpaceSpan);
417
- mSpannableStringBuilder.setSpan(zeroWidthSpaceSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
441
+ mSpannableStringBuilder.setSpan(
442
+ zeroWidthSpaceSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
418
443
  }
419
444
 
420
445
  return mSpannableStringBuilder;
@@ -461,6 +486,12 @@ class HtmlToSpannedConverter implements ContentHandler {
461
486
  startHeading(mSpannableStringBuilder, 2);
462
487
  } else if (tag.equalsIgnoreCase("h3")) {
463
488
  startHeading(mSpannableStringBuilder, 3);
489
+ } else if (tag.equalsIgnoreCase("h4")) {
490
+ startHeading(mSpannableStringBuilder, 4);
491
+ } else if (tag.equalsIgnoreCase("h5")) {
492
+ startHeading(mSpannableStringBuilder, 5);
493
+ } else if (tag.equalsIgnoreCase("h6")) {
494
+ startHeading(mSpannableStringBuilder, 6);
464
495
  } else if (tag.equalsIgnoreCase("img")) {
465
496
  startImg(mSpannableStringBuilder, attributes, mImageGetter);
466
497
  } else if (tag.equalsIgnoreCase("code")) {
@@ -499,6 +530,12 @@ class HtmlToSpannedConverter implements ContentHandler {
499
530
  endHeading(mSpannableStringBuilder, mStyle, 2);
500
531
  } else if (tag.equalsIgnoreCase("h3")) {
501
532
  endHeading(mSpannableStringBuilder, mStyle, 3);
533
+ } else if (tag.equalsIgnoreCase("h4")) {
534
+ endHeading(mSpannableStringBuilder, mStyle, 4);
535
+ } else if (tag.equalsIgnoreCase("h5")) {
536
+ endHeading(mSpannableStringBuilder, mStyle, 5);
537
+ } else if (tag.equalsIgnoreCase("h6")) {
538
+ endHeading(mSpannableStringBuilder, mStyle, 6);
502
539
  } else if (tag.equalsIgnoreCase("code")) {
503
540
  end(mSpannableStringBuilder, Code.class, new EnrichedInlineCodeSpan(mStyle));
504
541
  } else if (tag.equalsIgnoreCase("mention")) {
@@ -521,8 +558,8 @@ class HtmlToSpannedConverter implements ContentHandler {
521
558
  }
522
559
 
523
560
  private static void startBlockElement(Editable text) {
524
- appendNewlines(text, 1);
525
- start(text, new Newline(1));
561
+ appendNewlines(text, 1);
562
+ start(text, new Newline(1));
526
563
  }
527
564
 
528
565
  private static void endBlockElement(Editable text) {
@@ -602,6 +639,15 @@ class HtmlToSpannedConverter implements ContentHandler {
602
639
  case 3:
603
640
  start(text, new H3());
604
641
  break;
642
+ case 4:
643
+ start(text, new H4());
644
+ break;
645
+ case 5:
646
+ start(text, new H5());
647
+ break;
648
+ case 6:
649
+ start(text, new H6());
650
+ break;
605
651
  default:
606
652
  throw new IllegalArgumentException("Unsupported heading level: " + level);
607
653
  }
@@ -623,6 +669,18 @@ class HtmlToSpannedConverter implements ContentHandler {
623
669
  H3 lastH3 = getLast(text, H3.class);
624
670
  setParagraphSpanFromMark(text, lastH3, new EnrichedH3Span(style));
625
671
  break;
672
+ case 4:
673
+ H4 lastH4 = getLast(text, H4.class);
674
+ setParagraphSpanFromMark(text, lastH4, new EnrichedH4Span(style));
675
+ break;
676
+ case 5:
677
+ H5 lastH5 = getLast(text, H5.class);
678
+ setParagraphSpanFromMark(text, lastH5, new EnrichedH5Span(style));
679
+ break;
680
+ case 6:
681
+ H6 lastH6 = getLast(text, H6.class);
682
+ setParagraphSpanFromMark(text, lastH6, new EnrichedH6Span(style));
683
+ break;
626
684
  default:
627
685
  throw new IllegalArgumentException("Unsupported heading level: " + level);
628
686
  }
@@ -659,7 +717,7 @@ class HtmlToSpannedConverter implements ContentHandler {
659
717
 
660
718
  // Block spans require at least one character to be applied.
661
719
  if (isEmptyTag) {
662
- text.append("\u200B");
720
+ text.append(EnrichedConstants.ZWS);
663
721
  len++;
664
722
  }
665
723
 
@@ -687,13 +745,16 @@ class HtmlToSpannedConverter implements ContentHandler {
687
745
  }
688
746
  }
689
747
 
690
- private static void startImg(Editable text, Attributes attributes, EnrichedParser.ImageGetter img) {
748
+ private static void startImg(
749
+ Editable text, Attributes attributes, EnrichedParser.ImageGetter img) {
691
750
  String src = attributes.getValue("", "src");
692
751
  String width = attributes.getValue("", "width");
693
752
  String height = attributes.getValue("", "height");
694
753
 
695
754
  int len = text.length();
696
- EnrichedImageSpan span = EnrichedImageSpan.Companion.createEnrichedImageSpan(src, Integer.parseInt(width), Integer.parseInt(height));
755
+ EnrichedImageSpan span =
756
+ EnrichedImageSpan.Companion.createEnrichedImageSpan(
757
+ src, Integer.parseInt(width), Integer.parseInt(height));
697
758
  text.append("");
698
759
  text.setSpan(span, len, text.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
699
760
  }
@@ -737,20 +798,15 @@ class HtmlToSpannedConverter implements ContentHandler {
737
798
  setSpanFromMark(text, m, new EnrichedMentionSpan(m.mText, m.mIndicator, m.mAttributes, style));
738
799
  }
739
800
 
740
- public void setDocumentLocator(Locator locator) {
741
- }
801
+ public void setDocumentLocator(Locator locator) {}
742
802
 
743
- public void startDocument() {
744
- }
803
+ public void startDocument() {}
745
804
 
746
- public void endDocument() {
747
- }
805
+ public void endDocument() {}
748
806
 
749
- public void startPrefixMapping(String prefix, String uri) {
750
- }
807
+ public void startPrefixMapping(String prefix, String uri) {}
751
808
 
752
- public void endPrefixMapping(String prefix) {
753
- }
809
+ public void endPrefixMapping(String prefix) {}
754
810
 
755
811
  public void startElement(String uri, String localName, String qName, Attributes attributes) {
756
812
  handleStartTag(localName, attributes);
@@ -793,44 +849,37 @@ class HtmlToSpannedConverter implements ContentHandler {
793
849
  mSpannableStringBuilder.append(sb);
794
850
  }
795
851
 
796
- public void ignorableWhitespace(char[] ch, int start, int length) {
797
- }
852
+ public void ignorableWhitespace(char[] ch, int start, int length) {}
798
853
 
799
- public void processingInstruction(String target, String data) {
800
- }
854
+ public void processingInstruction(String target, String data) {}
801
855
 
802
- public void skippedEntity(String name) {
803
- }
856
+ public void skippedEntity(String name) {}
804
857
 
805
- private static class H1 {
806
- }
858
+ private static class H1 {}
807
859
 
808
- private static class H2 {
809
- }
860
+ private static class H2 {}
810
861
 
811
- private static class H3 {
812
- }
862
+ private static class H3 {}
813
863
 
814
- private static class Bold {
815
- }
864
+ private static class H4 {}
816
865
 
817
- private static class Italic {
818
- }
866
+ private static class H5 {}
819
867
 
820
- private static class Underline {
821
- }
868
+ private static class H6 {}
822
869
 
823
- private static class Code {
824
- }
870
+ private static class Bold {}
825
871
 
826
- private static class CodeBlock {
827
- }
872
+ private static class Italic {}
828
873
 
829
- private static class Strikethrough {
830
- }
874
+ private static class Underline {}
831
875
 
832
- private static class Blockquote {
833
- }
876
+ private static class Code {}
877
+
878
+ private static class CodeBlock {}
879
+
880
+ private static class Strikethrough {}
881
+
882
+ private static class Blockquote {}
834
883
 
835
884
  private static class List {
836
885
  public int mIndex;
@@ -13,14 +13,19 @@ import com.swmansion.enriched.spans.EnrichedMentionSpan
13
13
  import com.swmansion.enriched.spans.EnrichedSpans
14
14
  import org.json.JSONObject
15
15
 
16
- class EnrichedSelection(private val view: EnrichedTextInputView) {
16
+ class EnrichedSelection(
17
+ private val view: EnrichedTextInputView,
18
+ ) {
17
19
  var start: Int = 0
18
20
  var end: Int = 0
19
21
 
20
22
  private var previousLinkDetectedEvent: MutableMap<String, String> = mutableMapOf("text" to "", "url" to "")
21
23
  private var previousMentionDetectedEvent: MutableMap<String, String> = mutableMapOf("text" to "", "payload" to "")
22
24
 
23
- fun onSelection(selStart: Int, selEnd: Int) {
25
+ fun onSelection(
26
+ selStart: Int,
27
+ selEnd: Int,
28
+ ) {
24
29
  var shouldValidateStyles = false
25
30
  var newStart = start
26
31
  var newEnd = end
@@ -52,19 +57,23 @@ class EnrichedSelection(private val view: EnrichedTextInputView) {
52
57
  emitSelectionChangeEvent(view.text, finalStart, finalEnd)
53
58
  }
54
59
 
55
- private fun isZeroWidthSelection(start: Int, end: Int): Boolean {
60
+ private fun isZeroWidthSelection(
61
+ start: Int,
62
+ end: Int,
63
+ ): Boolean {
56
64
  val text = view.text ?: return false
57
65
 
58
66
  if (start != end) {
59
- return text.substring(start, end) == "\u200B"
67
+ return text.substring(start, end) == EnrichedConstants.ZWS_STRING
60
68
  }
61
69
 
62
- val isNewLine = if (start > 0 ) text.substring(start - 1, start) == "\n" else true
63
- val isNextCharacterZeroWidth = if (start < text.length) {
64
- text.substring(start, start + 1) == "\u200B"
65
- } else {
66
- false
67
- }
70
+ val isNewLine = if (start > 0) text.substring(start - 1, start) == "\n" else true
71
+ val isNextCharacterZeroWidth =
72
+ if (start < text.length) {
73
+ text.substring(start, start + 1) == EnrichedConstants.ZWS_STRING
74
+ } else {
75
+ false
76
+ }
68
77
 
69
78
  return isNewLine && isNextCharacterZeroWidth
70
79
  }
@@ -103,7 +112,7 @@ class EnrichedSelection(private val view: EnrichedTextInputView) {
103
112
  return Pair(finalStart, finalEnd)
104
113
  }
105
114
 
106
- private fun <T>getInlineStyleStart(type: Class<T>): Int? {
115
+ private fun <T> getInlineStyleStart(type: Class<T>): Int? {
107
116
  val (start, end) = getInlineSelection()
108
117
  val spannable = view.text as Spannable
109
118
  val spans = spannable.getSpans(start, end, type)
@@ -129,7 +138,7 @@ class EnrichedSelection(private val view: EnrichedTextInputView) {
129
138
  return spannable.getParagraphBounds(currentStart, currentEnd)
130
139
  }
131
140
 
132
- private fun <T>getParagraphStyleStart(type: Class<T>): Int? {
141
+ private fun <T> getParagraphStyleStart(type: Class<T>): Int? {
133
142
  val (start, end) = getParagraphSelection()
134
143
  val spannable = view.text as Spannable
135
144
  val spans = spannable.getSpans(start, end, type)
@@ -148,7 +157,7 @@ class EnrichedSelection(private val view: EnrichedTextInputView) {
148
157
  return styleStart
149
158
  }
150
159
 
151
- private fun <T>getListStyleStart(type: Class<T>): Int? {
160
+ private fun <T> getListStyleStart(type: Class<T>): Int? {
152
161
  val (start, end) = getParagraphSelection()
153
162
  val spannable = view.text as Spannable
154
163
  var styleStart: Int? = null
@@ -177,7 +186,7 @@ class EnrichedSelection(private val view: EnrichedTextInputView) {
177
186
  return styleStart
178
187
  }
179
188
 
180
- private fun <T>getParametrizedStyleStart(type: Class<T>): Int? {
189
+ private fun <T> getParametrizedStyleStart(type: Class<T>): Int? {
181
190
  val (start, end) = getInlineSelection()
182
191
  val spannable = view.text as Spannable
183
192
  val spans = spannable.getSpans(start, end, type)
@@ -212,7 +221,11 @@ class EnrichedSelection(private val view: EnrichedTextInputView) {
212
221
  return null
213
222
  }
214
223
 
215
- private fun emitSelectionChangeEvent(editable: Editable?, start: Int, end: Int) {
224
+ private fun emitSelectionChangeEvent(
225
+ editable: Editable?,
226
+ start: Int,
227
+ end: Int,
228
+ ) {
216
229
  if (editable == null) return
217
230
 
218
231
  val context = view.context as ReactContext
@@ -220,17 +233,24 @@ class EnrichedSelection(private val view: EnrichedTextInputView) {
220
233
  val dispatcher = UIManagerHelper.getEventDispatcherForReactTag(context, view.id)
221
234
 
222
235
  val text = editable.substring(start, end)
223
- dispatcher?.dispatchEvent(OnChangeSelectionEvent(
224
- surfaceId,
225
- view.id,
226
- text,
227
- start ,
228
- end,
229
- view.experimentalSynchronousEvents,
230
- ))
236
+ dispatcher?.dispatchEvent(
237
+ OnChangeSelectionEvent(
238
+ surfaceId,
239
+ view.id,
240
+ text,
241
+ start,
242
+ end,
243
+ view.experimentalSynchronousEvents,
244
+ ),
245
+ )
231
246
  }
232
247
 
233
- private fun emitLinkDetectedEvent(spannable: Spannable, span: EnrichedLinkSpan?, start: Int, end: Int) {
248
+ private fun emitLinkDetectedEvent(
249
+ spannable: Spannable,
250
+ span: EnrichedLinkSpan?,
251
+ start: Int,
252
+ end: Int,
253
+ ) {
234
254
  val text = spannable.substring(start, end)
235
255
  val url = span?.getUrl() ?: ""
236
256
 
@@ -243,18 +263,25 @@ class EnrichedSelection(private val view: EnrichedTextInputView) {
243
263
  val context = view.context as ReactContext
244
264
  val surfaceId = UIManagerHelper.getSurfaceId(context)
245
265
  val dispatcher = UIManagerHelper.getEventDispatcherForReactTag(context, view.id)
246
- dispatcher?.dispatchEvent(OnLinkDetectedEvent(
247
- surfaceId,
248
- view.id,
249
- text,
250
- url,
251
- start,
252
- end,
253
- view.experimentalSynchronousEvents,
254
- ))
266
+ dispatcher?.dispatchEvent(
267
+ OnLinkDetectedEvent(
268
+ surfaceId,
269
+ view.id,
270
+ text,
271
+ url,
272
+ start,
273
+ end,
274
+ view.experimentalSynchronousEvents,
275
+ ),
276
+ )
255
277
  }
256
278
 
257
- private fun emitMentionDetectedEvent(spannable: Spannable, span: EnrichedMentionSpan?, start: Int, end: Int) {
279
+ private fun emitMentionDetectedEvent(
280
+ spannable: Spannable,
281
+ span: EnrichedMentionSpan?,
282
+ start: Int,
283
+ end: Int,
284
+ ) {
258
285
  val text = spannable.substring(start, end)
259
286
  val attributes = span?.getAttributes() ?: emptyMap()
260
287
  val indicator = span?.getIndicator() ?: ""
@@ -273,13 +300,15 @@ class EnrichedSelection(private val view: EnrichedTextInputView) {
273
300
  val context = view.context as ReactContext
274
301
  val surfaceId = UIManagerHelper.getSurfaceId(context)
275
302
  val dispatcher = UIManagerHelper.getEventDispatcherForReactTag(context, view.id)
276
- dispatcher?.dispatchEvent(OnMentionDetectedEvent(
277
- surfaceId,
278
- view.id,
279
- text,
280
- indicator,
281
- payload,
282
- view.experimentalSynchronousEvents,
283
- ))
303
+ dispatcher?.dispatchEvent(
304
+ OnMentionDetectedEvent(
305
+ surfaceId,
306
+ view.id,
307
+ text,
308
+ indicator,
309
+ payload,
310
+ view.experimentalSynchronousEvents,
311
+ ),
312
+ )
284
313
  }
285
314
  }