react-native-enriched 0.0.0 → 0.1.1

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 (169) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +875 -0
  3. package/ReactNativeEnriched.podspec +27 -0
  4. package/android/build.gradle +101 -0
  5. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerDelegate.java +146 -0
  6. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerInterface.java +55 -0
  7. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/ComponentDescriptors.cpp +22 -0
  8. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/ComponentDescriptors.h +24 -0
  9. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/EventEmitters.cpp +118 -0
  10. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/EventEmitters.h +95 -0
  11. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/Props.cpp +128 -0
  12. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/Props.h +577 -0
  13. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/ShadowNodes.cpp +17 -0
  14. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/ShadowNodes.h +23 -0
  15. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/States.cpp +16 -0
  16. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/States.h +20 -0
  17. package/android/gradle.properties +5 -0
  18. package/android/src/main/AndroidManifest.xml +3 -0
  19. package/android/src/main/AndroidManifestNew.xml +2 -0
  20. package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputView.kt +535 -0
  21. package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewLayoutManager.kt +64 -0
  22. package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewManager.kt +292 -0
  23. package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewPackage.kt +19 -0
  24. package/android/src/main/java/com/swmansion/enriched/events/MentionHandler.kt +40 -0
  25. package/android/src/main/java/com/swmansion/enriched/events/OnChangeHtmlEvent.kt +28 -0
  26. package/android/src/main/java/com/swmansion/enriched/events/OnChangeSelectionEvent.kt +29 -0
  27. package/android/src/main/java/com/swmansion/enriched/events/OnChangeStateEvent.kt +24 -0
  28. package/android/src/main/java/com/swmansion/enriched/events/OnChangeTextEvent.kt +30 -0
  29. package/android/src/main/java/com/swmansion/enriched/events/OnInputBlurEvent.kt +27 -0
  30. package/android/src/main/java/com/swmansion/enriched/events/OnInputFocusEvent.kt +27 -0
  31. package/android/src/main/java/com/swmansion/enriched/events/OnLinkDetectedEvent.kt +30 -0
  32. package/android/src/main/java/com/swmansion/enriched/events/OnMentionDetectedEvent.kt +29 -0
  33. package/android/src/main/java/com/swmansion/enriched/events/OnMentionEvent.kt +33 -0
  34. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedBlockQuoteSpan.kt +34 -0
  35. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedBoldSpan.kt +10 -0
  36. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedCodeBlockSpan.kt +38 -0
  37. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH1Span.kt +17 -0
  38. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH2Span.kt +17 -0
  39. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH3Span.kt +17 -0
  40. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedImageSpan.kt +41 -0
  41. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedInlineCodeSpan.kt +16 -0
  42. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedItalicSpan.kt +10 -0
  43. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedLinkSpan.kt +24 -0
  44. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedMentionSpan.kt +36 -0
  45. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedOrderedListSpan.kt +71 -0
  46. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedSpans.kt +111 -0
  47. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedStrikeThroughSpan.kt +9 -0
  48. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedUnderlineSpan.kt +9 -0
  49. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedUnorderedListSpan.kt +49 -0
  50. package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedBlockSpan.kt +4 -0
  51. package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedHeadingSpan.kt +4 -0
  52. package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedInlineSpan.kt +4 -0
  53. package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedParagraphSpan.kt +4 -0
  54. package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedSpan.kt +4 -0
  55. package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedZeroWidthSpaceSpan.kt +5 -0
  56. package/android/src/main/java/com/swmansion/enriched/styles/HtmlStyle.kt +227 -0
  57. package/android/src/main/java/com/swmansion/enriched/styles/InlineStyles.kt +146 -0
  58. package/android/src/main/java/com/swmansion/enriched/styles/ListStyles.kt +173 -0
  59. package/android/src/main/java/com/swmansion/enriched/styles/ParagraphStyles.kt +186 -0
  60. package/android/src/main/java/com/swmansion/enriched/styles/ParametrizedStyles.kt +223 -0
  61. package/android/src/main/java/com/swmansion/enriched/utils/EnrichedParser.java +857 -0
  62. package/android/src/main/java/com/swmansion/enriched/utils/EnrichedSelection.kt +285 -0
  63. package/android/src/main/java/com/swmansion/enriched/utils/EnrichedSpanState.kt +204 -0
  64. package/android/src/main/java/com/swmansion/enriched/utils/Utils.kt +91 -0
  65. package/android/src/main/java/com/swmansion/enriched/watchers/EnrichedSpanWatcher.kt +73 -0
  66. package/android/src/main/java/com/swmansion/enriched/watchers/EnrichedTextWatcher.kt +51 -0
  67. package/android/src/main/new_arch/CMakeLists.txt +56 -0
  68. package/android/src/main/new_arch/RNEnrichedTextInputViewSpec.cpp +22 -0
  69. package/android/src/main/new_arch/RNEnrichedTextInputViewSpec.h +26 -0
  70. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputComponentDescriptor.h +35 -0
  71. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputMeasurementManager.cpp +51 -0
  72. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputMeasurementManager.h +26 -0
  73. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputShadowNode.cpp +34 -0
  74. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputShadowNode.h +54 -0
  75. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputState.cpp +9 -0
  76. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputState.h +25 -0
  77. package/ios/EnrichedTextInputView.h +33 -0
  78. package/ios/EnrichedTextInputView.mm +1190 -0
  79. package/ios/EnrichedTextInputViewManager.mm +13 -0
  80. package/ios/config/InputConfig.h +67 -0
  81. package/ios/config/InputConfig.mm +382 -0
  82. package/ios/generated/RNEnrichedTextInputViewSpec/ComponentDescriptors.cpp +22 -0
  83. package/ios/generated/RNEnrichedTextInputViewSpec/ComponentDescriptors.h +24 -0
  84. package/ios/generated/RNEnrichedTextInputViewSpec/EventEmitters.cpp +118 -0
  85. package/ios/generated/RNEnrichedTextInputViewSpec/EventEmitters.h +95 -0
  86. package/ios/generated/RNEnrichedTextInputViewSpec/Props.cpp +128 -0
  87. package/ios/generated/RNEnrichedTextInputViewSpec/Props.h +577 -0
  88. package/ios/generated/RNEnrichedTextInputViewSpec/RCTComponentViewHelpers.h +384 -0
  89. package/ios/generated/RNEnrichedTextInputViewSpec/ShadowNodes.cpp +17 -0
  90. package/ios/generated/RNEnrichedTextInputViewSpec/ShadowNodes.h +23 -0
  91. package/ios/generated/RNEnrichedTextInputViewSpec/States.cpp +16 -0
  92. package/ios/generated/RNEnrichedTextInputViewSpec/States.h +20 -0
  93. package/ios/inputParser/InputParser.h +11 -0
  94. package/ios/inputParser/InputParser.mm +659 -0
  95. package/ios/inputTextView/InputTextView.h +6 -0
  96. package/ios/inputTextView/InputTextView.mm +115 -0
  97. package/ios/internals/EnrichedTextInputViewComponentDescriptor.h +17 -0
  98. package/ios/internals/EnrichedTextInputViewShadowNode.h +40 -0
  99. package/ios/internals/EnrichedTextInputViewShadowNode.mm +83 -0
  100. package/ios/internals/EnrichedTextInputViewState.cpp +10 -0
  101. package/ios/internals/EnrichedTextInputViewState.h +20 -0
  102. package/ios/styles/BlockQuoteStyle.mm +248 -0
  103. package/ios/styles/BoldStyle.mm +122 -0
  104. package/ios/styles/H1Style.mm +10 -0
  105. package/ios/styles/H2Style.mm +10 -0
  106. package/ios/styles/H3Style.mm +10 -0
  107. package/ios/styles/HeadingStyleBase.mm +144 -0
  108. package/ios/styles/InlineCodeStyle.mm +163 -0
  109. package/ios/styles/ItalicStyle.mm +110 -0
  110. package/ios/styles/LinkStyle.mm +463 -0
  111. package/ios/styles/MentionStyle.mm +476 -0
  112. package/ios/styles/OrderedListStyle.mm +225 -0
  113. package/ios/styles/StrikethroughStyle.mm +80 -0
  114. package/ios/styles/UnderlineStyle.mm +112 -0
  115. package/ios/styles/UnorderedListStyle.mm +225 -0
  116. package/ios/utils/BaseStyleProtocol.h +16 -0
  117. package/ios/utils/ColorExtension.h +6 -0
  118. package/ios/utils/ColorExtension.mm +27 -0
  119. package/ios/utils/FontExtension.h +13 -0
  120. package/ios/utils/FontExtension.mm +91 -0
  121. package/ios/utils/LayoutManagerExtension.h +6 -0
  122. package/ios/utils/LayoutManagerExtension.mm +171 -0
  123. package/ios/utils/LinkData.h +9 -0
  124. package/ios/utils/LinkData.mm +4 -0
  125. package/ios/utils/MentionParams.h +9 -0
  126. package/ios/utils/MentionParams.mm +4 -0
  127. package/ios/utils/MentionStyleProps.h +13 -0
  128. package/ios/utils/MentionStyleProps.mm +56 -0
  129. package/ios/utils/OccurenceUtils.h +37 -0
  130. package/ios/utils/OccurenceUtils.mm +124 -0
  131. package/ios/utils/ParagraphsUtils.h +7 -0
  132. package/ios/utils/ParagraphsUtils.mm +54 -0
  133. package/ios/utils/StringExtension.h +15 -0
  134. package/ios/utils/StringExtension.mm +57 -0
  135. package/ios/utils/StyleHeaders.h +74 -0
  136. package/ios/utils/StylePair.h +9 -0
  137. package/ios/utils/StylePair.mm +4 -0
  138. package/ios/utils/StyleTypeEnum.h +22 -0
  139. package/ios/utils/TextDecorationLineEnum.h +6 -0
  140. package/ios/utils/TextDecorationLineEnum.mm +4 -0
  141. package/ios/utils/TextInsertionUtils.h +6 -0
  142. package/ios/utils/TextInsertionUtils.mm +48 -0
  143. package/ios/utils/WordsUtils.h +6 -0
  144. package/ios/utils/WordsUtils.mm +88 -0
  145. package/ios/utils/ZeroWidthSpaceUtils.h +7 -0
  146. package/ios/utils/ZeroWidthSpaceUtils.mm +164 -0
  147. package/lib/module/EnrichedTextInput.js +191 -0
  148. package/lib/module/EnrichedTextInput.js.map +1 -0
  149. package/lib/module/EnrichedTextInputNativeComponent.ts +235 -0
  150. package/lib/module/index.js +4 -0
  151. package/lib/module/index.js.map +1 -0
  152. package/lib/module/normalizeHtmlStyle.js +141 -0
  153. package/lib/module/normalizeHtmlStyle.js.map +1 -0
  154. package/lib/module/package.json +1 -0
  155. package/lib/typescript/package.json +1 -0
  156. package/lib/typescript/src/EnrichedTextInput.d.ts +113 -0
  157. package/lib/typescript/src/EnrichedTextInput.d.ts.map +1 -0
  158. package/lib/typescript/src/EnrichedTextInputNativeComponent.d.ts +160 -0
  159. package/lib/typescript/src/EnrichedTextInputNativeComponent.d.ts.map +1 -0
  160. package/lib/typescript/src/index.d.ts +3 -0
  161. package/lib/typescript/src/index.d.ts.map +1 -0
  162. package/lib/typescript/src/normalizeHtmlStyle.d.ts +4 -0
  163. package/lib/typescript/src/normalizeHtmlStyle.d.ts.map +1 -0
  164. package/package.json +172 -1
  165. package/react-native.config.js +13 -0
  166. package/src/EnrichedTextInput.tsx +358 -0
  167. package/src/EnrichedTextInputNativeComponent.ts +235 -0
  168. package/src/index.tsx +9 -0
  169. package/src/normalizeHtmlStyle.ts +188 -0
@@ -0,0 +1,38 @@
1
+ package com.swmansion.enriched.spans
2
+
3
+ import android.graphics.Canvas
4
+ import android.graphics.Paint
5
+ import android.graphics.RectF
6
+ import android.graphics.Typeface
7
+ import android.text.TextPaint
8
+ import android.text.style.CharacterStyle
9
+ import android.text.style.LineBackgroundSpan
10
+ import com.swmansion.enriched.spans.interfaces.EnrichedBlockSpan
11
+ import com.swmansion.enriched.styles.HtmlStyle
12
+
13
+ class EnrichedCodeBlockSpan(private val htmlStyle: HtmlStyle) : CharacterStyle(), LineBackgroundSpan, EnrichedBlockSpan {
14
+ override fun updateDrawState(paint: TextPaint?) {
15
+ paint?.typeface = Typeface.MONOSPACE
16
+ paint?.color = htmlStyle.codeBlockColor
17
+ }
18
+
19
+ override fun drawBackground(
20
+ canvas: Canvas,
21
+ p: Paint,
22
+ left: Int,
23
+ right: Int,
24
+ top: Int,
25
+ baseline: Int,
26
+ bottom: Int,
27
+ text: CharSequence,
28
+ start: Int,
29
+ end: Int,
30
+ lineNum: Int
31
+ ) {
32
+ val previousColor = p.color
33
+ p.color = htmlStyle.codeBlockBackgroundColor
34
+ val rect = RectF(left.toFloat(), top.toFloat(), right.toFloat(), bottom.toFloat())
35
+ canvas.drawRoundRect(rect, htmlStyle.codeBlockRadius, htmlStyle.codeBlockRadius, p)
36
+ p.color = previousColor
37
+ }
38
+ }
@@ -0,0 +1,17 @@
1
+ package com.swmansion.enriched.spans
2
+
3
+ import android.graphics.Typeface
4
+ import android.text.TextPaint
5
+ import android.text.style.AbsoluteSizeSpan
6
+ import com.swmansion.enriched.spans.interfaces.EnrichedHeadingSpan
7
+ import com.swmansion.enriched.styles.HtmlStyle
8
+
9
+ class EnrichedH1Span(private val style: HtmlStyle) : AbsoluteSizeSpan(style.h1FontSize), EnrichedHeadingSpan {
10
+ override fun updateDrawState(tp: TextPaint) {
11
+ super.updateDrawState(tp)
12
+ val bold = style.h1Bold
13
+ if (bold) {
14
+ tp.typeface = Typeface.create(tp.typeface, Typeface.BOLD)
15
+ }
16
+ }
17
+ }
@@ -0,0 +1,17 @@
1
+ package com.swmansion.enriched.spans
2
+
3
+ import android.graphics.Typeface
4
+ import android.text.TextPaint
5
+ import android.text.style.AbsoluteSizeSpan
6
+ import com.swmansion.enriched.spans.interfaces.EnrichedHeadingSpan
7
+ import com.swmansion.enriched.styles.HtmlStyle
8
+
9
+ class EnrichedH2Span(private val htmlStyle: HtmlStyle) : AbsoluteSizeSpan(htmlStyle.h2FontSize), EnrichedHeadingSpan {
10
+ override fun updateDrawState(tp: TextPaint) {
11
+ super.updateDrawState(tp)
12
+ val bold = htmlStyle.h2Bold
13
+ if (bold) {
14
+ tp.typeface = Typeface.create(tp.typeface, Typeface.BOLD)
15
+ }
16
+ }
17
+ }
@@ -0,0 +1,17 @@
1
+ package com.swmansion.enriched.spans
2
+
3
+ import android.graphics.Typeface
4
+ import android.text.TextPaint
5
+ import android.text.style.AbsoluteSizeSpan
6
+ import com.swmansion.enriched.spans.interfaces.EnrichedHeadingSpan
7
+ import com.swmansion.enriched.styles.HtmlStyle
8
+
9
+ class EnrichedH3Span(private val htmlStyle: HtmlStyle) : AbsoluteSizeSpan(htmlStyle.h3FontSize), EnrichedHeadingSpan {
10
+ override fun updateDrawState(tp: TextPaint) {
11
+ super.updateDrawState(tp)
12
+ val bold = htmlStyle.h3Bold
13
+ if (bold) {
14
+ tp.typeface = Typeface.create(tp.typeface, Typeface.BOLD)
15
+ }
16
+ }
17
+ }
@@ -0,0 +1,41 @@
1
+ package com.swmansion.enriched.spans
2
+
3
+ import android.content.Context
4
+ import android.graphics.Canvas
5
+ import android.graphics.Paint
6
+ import android.graphics.drawable.Drawable
7
+ import android.net.Uri
8
+ import android.text.style.ImageSpan
9
+ import androidx.core.graphics.withSave
10
+ import com.swmansion.enriched.spans.interfaces.EnrichedInlineSpan
11
+ import com.swmansion.enriched.styles.HtmlStyle
12
+
13
+ class EnrichedImageSpan : ImageSpan, EnrichedInlineSpan {
14
+ private var htmlStyle: HtmlStyle? = null
15
+
16
+ constructor(context: Context, uri: Uri, htmlStyle: HtmlStyle, ) : super(context, uri, ALIGN_BASELINE) {
17
+ this.htmlStyle = htmlStyle
18
+ }
19
+
20
+ constructor(drawable: Drawable, source: String, htmlStyle: HtmlStyle) : super(drawable, source, ALIGN_BASELINE) {
21
+ this.htmlStyle = htmlStyle
22
+ }
23
+
24
+ override fun draw(
25
+ canvas: Canvas, text: CharSequence?, start: Int, end: Int, x: Float,
26
+ top: Int, y: Int, bottom: Int, paint: Paint
27
+ ) {
28
+ val drawable = drawable
29
+ canvas.withSave() {
30
+ val transY = bottom - drawable.bounds.bottom - paint.fontMetricsInt.descent
31
+ translate(x, transY.toFloat())
32
+ drawable.draw(this)
33
+ }
34
+ }
35
+
36
+ override fun getDrawable(): Drawable {
37
+ val drawable = super.getDrawable()
38
+ drawable.setBounds(0, 0, htmlStyle!!.imgWidth, htmlStyle!!.imgHeight)
39
+ return drawable
40
+ }
41
+ }
@@ -0,0 +1,16 @@
1
+ package com.swmansion.enriched.spans
2
+
3
+ import android.graphics.Typeface
4
+ import android.text.TextPaint
5
+ import android.text.style.BackgroundColorSpan
6
+ import com.swmansion.enriched.spans.interfaces.EnrichedInlineSpan
7
+ import com.swmansion.enriched.styles.HtmlStyle
8
+
9
+ class EnrichedInlineCodeSpan(private val htmlStyle: HtmlStyle) : BackgroundColorSpan(htmlStyle.inlineCodeBackgroundColor), EnrichedInlineSpan {
10
+ override fun updateDrawState(textPaint: TextPaint) {
11
+ super.updateDrawState(textPaint)
12
+
13
+ textPaint.color = htmlStyle.inlineCodeColor
14
+ textPaint.typeface = Typeface.create(Typeface.MONOSPACE, Typeface.NORMAL)
15
+ }
16
+ }
@@ -0,0 +1,10 @@
1
+ package com.swmansion.enriched.spans
2
+
3
+ import android.graphics.Typeface
4
+ import android.text.style.StyleSpan
5
+ import com.swmansion.enriched.spans.interfaces.EnrichedInlineSpan
6
+ import com.swmansion.enriched.styles.HtmlStyle
7
+
8
+ @Suppress("UNUSED_PARAMETER")
9
+ class EnrichedItalicSpan(private val htmlStyle: HtmlStyle) : StyleSpan(Typeface.ITALIC), EnrichedInlineSpan {
10
+ }
@@ -0,0 +1,24 @@
1
+ package com.swmansion.enriched.spans
2
+
3
+ import android.text.TextPaint
4
+ import android.text.style.ClickableSpan
5
+ import android.view.View
6
+ import com.swmansion.enriched.spans.interfaces.EnrichedInlineSpan
7
+ import com.swmansion.enriched.styles.HtmlStyle
8
+
9
+ class EnrichedLinkSpan(private val url: String, private val htmlStyle: HtmlStyle) : ClickableSpan(), EnrichedInlineSpan {
10
+ override fun onClick(view: View) {
11
+ // Do nothing, links inside the input are not clickable.
12
+ // We are using `ClickableSpan` to allow the text to be styled as a link.
13
+ }
14
+
15
+ override fun updateDrawState(textPaint: TextPaint) {
16
+ super.updateDrawState(textPaint)
17
+ textPaint.color = htmlStyle.aColor
18
+ textPaint.isUnderlineText = htmlStyle.aUnderline
19
+ }
20
+
21
+ fun getUrl(): String {
22
+ return url
23
+ }
24
+ }
@@ -0,0 +1,36 @@
1
+ package com.swmansion.enriched.spans
2
+
3
+ import android.text.TextPaint
4
+ import android.text.style.ClickableSpan
5
+ import android.view.View
6
+ import com.swmansion.enriched.spans.interfaces.EnrichedInlineSpan
7
+ import com.swmansion.enriched.styles.HtmlStyle
8
+
9
+ class EnrichedMentionSpan(private val text: String, private val indicator: String, private val attributes: Map<String, String>, private val htmlStyle: HtmlStyle) :
10
+ ClickableSpan(), EnrichedInlineSpan {
11
+ override fun onClick(view: View) {
12
+ // Do nothing. Mentions inside the input are not clickable.
13
+ // We are using `ClickableSpan` to allow the text to be styled as a clickable element.
14
+ }
15
+
16
+ override fun updateDrawState(textPaint: TextPaint) {
17
+ super.updateDrawState(textPaint)
18
+
19
+ val mentionsStyle = htmlStyle.mentionsStyle[indicator] ?: return
20
+ textPaint.color = mentionsStyle.color
21
+ textPaint.bgColor = mentionsStyle.backgroundColor
22
+ textPaint.isUnderlineText = mentionsStyle.underline
23
+ }
24
+
25
+ fun getAttributes(): Map<String, String> {
26
+ return attributes
27
+ }
28
+
29
+ fun getText(): String {
30
+ return text
31
+ }
32
+
33
+ fun getIndicator(): String {
34
+ return indicator
35
+ }
36
+ }
@@ -0,0 +1,71 @@
1
+ package com.swmansion.enriched.spans
2
+
3
+ import android.graphics.Canvas
4
+ import android.graphics.Paint
5
+ import android.graphics.Typeface
6
+ import android.text.Layout
7
+ import android.text.style.LeadingMarginSpan
8
+ import com.swmansion.enriched.spans.interfaces.EnrichedParagraphSpan
9
+ import com.swmansion.enriched.styles.HtmlStyle
10
+
11
+ class EnrichedOrderedListSpan(private var index: Int, private val htmlStyle: HtmlStyle) : LeadingMarginSpan, EnrichedParagraphSpan {
12
+ override fun getLeadingMargin(first: Boolean): Int {
13
+ return htmlStyle.olMarginLeft + htmlStyle.olGapWidth
14
+ }
15
+
16
+ override fun drawLeadingMargin(
17
+ canvas: Canvas,
18
+ paint: Paint,
19
+ x: Int,
20
+ dir: Int,
21
+ top: Int,
22
+ baseline: Int,
23
+ bottom: Int,
24
+ t: CharSequence?,
25
+ start: Int,
26
+ end: Int,
27
+ first: Boolean,
28
+ layout: Layout?
29
+ ) {
30
+ if (first) {
31
+ val text = "$index."
32
+ val width = paint.measureText(text)
33
+
34
+ val yPosition = baseline.toFloat()
35
+ val xPosition = (htmlStyle.olMarginLeft + x - width / 2) * dir
36
+
37
+ val originalColor = paint.color
38
+ val originalTypeface = paint.typeface
39
+
40
+ paint.color = htmlStyle.olMarkerColor ?: originalColor
41
+ paint.typeface = getTypeface(htmlStyle.olMarkerFontWeight, originalTypeface)
42
+ canvas.drawText(text, xPosition, yPosition, paint)
43
+
44
+ paint.color = originalColor
45
+ paint.typeface = originalTypeface
46
+ }
47
+ }
48
+
49
+ private fun getTypeface(fontWeight: Int?, originalTypeface: Typeface): Typeface {
50
+ return if (fontWeight == null) {
51
+ originalTypeface
52
+ } else if (android.os.Build.VERSION.SDK_INT >= 28) {
53
+ Typeface.create(originalTypeface, fontWeight, false)
54
+ } else {
55
+ // Fallback for API < 28: only bold/normal supported
56
+ if (fontWeight == Typeface.BOLD) {
57
+ Typeface.create(originalTypeface, Typeface.BOLD)
58
+ } else {
59
+ Typeface.create(originalTypeface, Typeface.NORMAL)
60
+ }
61
+ }
62
+ }
63
+
64
+ fun getIndex(): Int {
65
+ return index
66
+ }
67
+
68
+ fun setIndex(i: Int) {
69
+ index = i
70
+ }
71
+ }
@@ -0,0 +1,111 @@
1
+ package com.swmansion.enriched.spans
2
+
3
+ data class BaseSpanConfig(val clazz: Class<*>)
4
+ data class ParagraphSpanConfig(val clazz: Class<*>, val isContinuous: Boolean)
5
+ data class ListSpanConfig(val clazz: Class<*>, val shortcut: String)
6
+
7
+ data class StylesMergingConfig(
8
+ // styles that should be removed when we apply specific style
9
+ val conflictingStyles: Array<String> = emptyArray(),
10
+ // styles that should block setting specific style
11
+ val blockingStyles: Array<String> = emptyArray(),
12
+ )
13
+
14
+ object EnrichedSpans {
15
+ // inline styles
16
+ const val BOLD = "bold"
17
+ const val ITALIC = "italic"
18
+ const val UNDERLINE = "underline"
19
+ const val STRIKETHROUGH = "strikethrough"
20
+ const val INLINE_CODE = "inline_code"
21
+
22
+ // paragraph styles
23
+ const val H1 = "h1"
24
+ const val H2 = "h2"
25
+ const val H3 = "h3"
26
+ const val BLOCK_QUOTE = "block_quote"
27
+ const val CODE_BLOCK = "code_block"
28
+
29
+ // list styles
30
+ const val UNORDERED_LIST = "unordered_list"
31
+ const val ORDERED_LIST = "ordered_list"
32
+
33
+ // parametrized styles
34
+ const val LINK = "link"
35
+ const val IMAGE = "image"
36
+ const val MENTION = "mention"
37
+
38
+ val inlineSpans: Map<String, BaseSpanConfig> = mapOf(
39
+ BOLD to BaseSpanConfig(EnrichedBoldSpan::class.java),
40
+ ITALIC to BaseSpanConfig(EnrichedItalicSpan::class.java),
41
+ UNDERLINE to BaseSpanConfig(EnrichedUnderlineSpan::class.java),
42
+ STRIKETHROUGH to BaseSpanConfig(EnrichedStrikeThroughSpan::class.java),
43
+ INLINE_CODE to BaseSpanConfig(EnrichedInlineCodeSpan::class.java),
44
+ )
45
+
46
+ val paragraphSpans: Map<String, ParagraphSpanConfig> = mapOf(
47
+ H1 to ParagraphSpanConfig(EnrichedH1Span::class.java, false),
48
+ H2 to ParagraphSpanConfig(EnrichedH2Span::class.java, false),
49
+ H3 to ParagraphSpanConfig(EnrichedH3Span::class.java, false),
50
+ BLOCK_QUOTE to ParagraphSpanConfig(EnrichedBlockQuoteSpan::class.java, true),
51
+ CODE_BLOCK to ParagraphSpanConfig(EnrichedCodeBlockSpan::class.java, true),
52
+ )
53
+
54
+ val listSpans: Map<String, ListSpanConfig> = mapOf(
55
+ UNORDERED_LIST to ListSpanConfig(EnrichedUnorderedListSpan::class.java, "- "),
56
+ ORDERED_LIST to ListSpanConfig(EnrichedOrderedListSpan::class.java, "1. "),
57
+ )
58
+
59
+ val parametrizedStyles: Map<String, BaseSpanConfig> = mapOf(
60
+ LINK to BaseSpanConfig(EnrichedLinkSpan::class.java),
61
+ IMAGE to BaseSpanConfig(EnrichedImageSpan::class.java),
62
+ MENTION to BaseSpanConfig(EnrichedMentionSpan::class.java),
63
+ )
64
+
65
+ val mergingConfig: Map<String, StylesMergingConfig> = mapOf(
66
+ BOLD to StylesMergingConfig(
67
+ blockingStyles = arrayOf(CODE_BLOCK)
68
+ ),
69
+ ITALIC to StylesMergingConfig(
70
+ blockingStyles = arrayOf(CODE_BLOCK)
71
+ ),
72
+ UNDERLINE to StylesMergingConfig(
73
+ blockingStyles = arrayOf(CODE_BLOCK)
74
+ ),
75
+ STRIKETHROUGH to StylesMergingConfig(
76
+ blockingStyles = arrayOf(CODE_BLOCK)
77
+ ),
78
+ INLINE_CODE to StylesMergingConfig(
79
+ conflictingStyles = arrayOf(MENTION, LINK),
80
+ blockingStyles = arrayOf(CODE_BLOCK)
81
+ ),
82
+ H1 to StylesMergingConfig(
83
+ conflictingStyles = arrayOf(H2, H3, ORDERED_LIST, UNORDERED_LIST, BLOCK_QUOTE, CODE_BLOCK),
84
+ ),
85
+ H2 to StylesMergingConfig(
86
+ conflictingStyles = arrayOf(H1, H3, ORDERED_LIST, UNORDERED_LIST, BLOCK_QUOTE, CODE_BLOCK),
87
+ ),
88
+ H3 to StylesMergingConfig(
89
+ conflictingStyles = arrayOf(H1, H2, ORDERED_LIST, UNORDERED_LIST, BLOCK_QUOTE, CODE_BLOCK),
90
+ ),
91
+ BLOCK_QUOTE to StylesMergingConfig(
92
+ conflictingStyles = arrayOf(H1, H2, H3, CODE_BLOCK, ORDERED_LIST, UNORDERED_LIST),
93
+ ),
94
+ CODE_BLOCK to StylesMergingConfig(
95
+ conflictingStyles = arrayOf(H1, H2, H3, BOLD, ITALIC, UNDERLINE, STRIKETHROUGH, UNORDERED_LIST, ORDERED_LIST, BLOCK_QUOTE, INLINE_CODE),
96
+ ),
97
+ UNORDERED_LIST to StylesMergingConfig(
98
+ conflictingStyles = arrayOf(H1, H2, H3, ORDERED_LIST, CODE_BLOCK, BLOCK_QUOTE),
99
+ ),
100
+ ORDERED_LIST to StylesMergingConfig(
101
+ conflictingStyles = arrayOf(H1, H2, H3, UNORDERED_LIST, CODE_BLOCK, BLOCK_QUOTE),
102
+ ),
103
+ LINK to StylesMergingConfig(
104
+ blockingStyles = arrayOf(INLINE_CODE, CODE_BLOCK, MENTION)
105
+ ),
106
+ IMAGE to StylesMergingConfig(),
107
+ MENTION to StylesMergingConfig(
108
+ blockingStyles = arrayOf(INLINE_CODE, CODE_BLOCK, LINK)
109
+ ),
110
+ )
111
+ }
@@ -0,0 +1,9 @@
1
+ package com.swmansion.enriched.spans
2
+
3
+ import android.text.style.StrikethroughSpan
4
+ import com.swmansion.enriched.spans.interfaces.EnrichedInlineSpan
5
+ import com.swmansion.enriched.styles.HtmlStyle
6
+
7
+ @Suppress("UNUSED_PARAMETER")
8
+ class EnrichedStrikeThroughSpan(private val htmlStyle: HtmlStyle) : StrikethroughSpan(), EnrichedInlineSpan {
9
+ }
@@ -0,0 +1,9 @@
1
+ package com.swmansion.enriched.spans
2
+
3
+ import android.text.style.UnderlineSpan
4
+ import com.swmansion.enriched.spans.interfaces.EnrichedInlineSpan
5
+ import com.swmansion.enriched.styles.HtmlStyle
6
+
7
+ @Suppress("UNUSED_PARAMETER")
8
+ class EnrichedUnderlineSpan(private val htmlStyle: HtmlStyle) : UnderlineSpan(), EnrichedInlineSpan {
9
+ }
@@ -0,0 +1,49 @@
1
+ package com.swmansion.enriched.spans
2
+
3
+ import android.graphics.Canvas
4
+ import android.graphics.Paint
5
+ import android.text.Layout
6
+ import android.text.Spanned
7
+ import android.text.style.LeadingMarginSpan
8
+ import com.swmansion.enriched.spans.interfaces.EnrichedParagraphSpan
9
+ import com.swmansion.enriched.styles.HtmlStyle
10
+
11
+ // https://android.googlesource.com/platform/frameworks/base/+/refs/heads/main/core/java/android/text/style/BulletSpan.java
12
+ class EnrichedUnorderedListSpan(private val htmlStyle: HtmlStyle) : LeadingMarginSpan, EnrichedParagraphSpan {
13
+ override fun getLeadingMargin(p0: Boolean): Int {
14
+ return htmlStyle.ulBulletSize + htmlStyle.ulGapWidth + htmlStyle.ulMarginLeft
15
+ }
16
+
17
+ override fun drawLeadingMargin(
18
+ canvas: Canvas,
19
+ paint: Paint,
20
+ x: Int,
21
+ dir: Int,
22
+ top: Int,
23
+ baseline: Int,
24
+ bottom: Int,
25
+ text: CharSequence,
26
+ start: Int,
27
+ end: Int,
28
+ first: Boolean,
29
+ layout: Layout?
30
+ ) {
31
+ val spannedText = text as Spanned
32
+
33
+ if (spannedText.getSpanStart(this) == start) {
34
+ val style = paint.style
35
+ val oldColor = paint.color
36
+ paint.color = htmlStyle.ulBulletColor
37
+ paint.style = Paint.Style.FILL
38
+
39
+ val bulletRadius = htmlStyle.ulBulletSize / 2f
40
+ val yPosition = (top + bottom) / 2f
41
+ val xPosition = x + dir * bulletRadius + htmlStyle.ulMarginLeft
42
+
43
+ canvas.drawCircle(xPosition, yPosition, bulletRadius, paint)
44
+
45
+ paint.color = oldColor
46
+ paint.style = style
47
+ }
48
+ }
49
+ }
@@ -0,0 +1,4 @@
1
+ package com.swmansion.enriched.spans.interfaces
2
+
3
+ interface EnrichedBlockSpan : EnrichedSpan, EnrichedZeroWidthSpaceSpan {
4
+ }
@@ -0,0 +1,4 @@
1
+ package com.swmansion.enriched.spans.interfaces
2
+
3
+ interface EnrichedHeadingSpan : EnrichedParagraphSpan {
4
+ }
@@ -0,0 +1,4 @@
1
+ package com.swmansion.enriched.spans.interfaces
2
+
3
+ interface EnrichedInlineSpan : EnrichedSpan {
4
+ }
@@ -0,0 +1,4 @@
1
+ package com.swmansion.enriched.spans.interfaces
2
+
3
+ interface EnrichedParagraphSpan : EnrichedSpan, EnrichedZeroWidthSpaceSpan {
4
+ }
@@ -0,0 +1,4 @@
1
+ package com.swmansion.enriched.spans.interfaces
2
+
3
+ interface EnrichedSpan {
4
+ }
@@ -0,0 +1,5 @@
1
+ package com.swmansion.enriched.spans.interfaces
2
+
3
+ // Spans that are prefixed with zero-width space (\u200B) to ensure that they are visible even when empty.
4
+ interface EnrichedZeroWidthSpaceSpan {
5
+ }