react-native-enriched 0.1.6 → 0.2.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 (123) hide show
  1. package/README.md +4 -14
  2. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerDelegate.java +4 -1
  3. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerInterface.java +2 -1
  4. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/EventEmitters.cpp +10 -0
  5. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/EventEmitters.h +7 -0
  6. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/Props.h +0 -45
  7. package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputView.kt +111 -2
  8. package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewManager.kt +9 -3
  9. package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewPackage.kt +2 -0
  10. package/android/src/main/java/com/swmansion/enriched/events/MentionHandler.kt +1 -1
  11. package/android/src/main/java/com/swmansion/enriched/events/OnRequestHtmlResultEvent.kt +33 -0
  12. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedBlockQuoteSpan.kt +6 -0
  13. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedBoldSpan.kt +6 -0
  14. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedCodeBlockSpan.kt +42 -1
  15. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH1Span.kt +6 -0
  16. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH2Span.kt +6 -0
  17. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH3Span.kt +6 -0
  18. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedImageSpan.kt +135 -9
  19. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedInlineCodeSpan.kt +6 -0
  20. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedItalicSpan.kt +5 -0
  21. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedLinkSpan.kt +6 -0
  22. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedMentionSpan.kt +6 -0
  23. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedOrderedListSpan.kt +6 -0
  24. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedSpans.kt +13 -3
  25. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedStrikeThroughSpan.kt +5 -0
  26. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedUnderlineSpan.kt +5 -0
  27. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedUnorderedListSpan.kt +6 -0
  28. package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedSpan.kt +4 -0
  29. package/android/src/main/java/com/swmansion/enriched/spans/utils/ForceRedrawSpan.kt +13 -0
  30. package/android/src/main/java/com/swmansion/enriched/styles/HtmlStyle.kt +80 -9
  31. package/android/src/main/java/com/swmansion/enriched/styles/InlineStyles.kt +1 -0
  32. package/android/src/main/java/com/swmansion/enriched/styles/ParagraphStyles.kt +188 -5
  33. package/android/src/main/java/com/swmansion/enriched/styles/ParametrizedStyles.kt +57 -30
  34. package/android/src/main/java/com/swmansion/enriched/utils/AsyncDrawable.kt +91 -0
  35. package/android/src/main/java/com/swmansion/enriched/utils/EnrichedParser.java +24 -13
  36. package/android/src/main/java/com/swmansion/enriched/utils/ResourceManager.kt +26 -0
  37. package/android/src/main/java/com/swmansion/enriched/watchers/EnrichedSpanWatcher.kt +3 -0
  38. package/android/src/main/new_arch/RNEnrichedTextInputViewSpec.cpp +6 -6
  39. package/android/src/main/new_arch/RNEnrichedTextInputViewSpec.h +6 -6
  40. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputComponentDescriptor.h +19 -19
  41. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputMeasurementManager.cpp +40 -51
  42. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputMeasurementManager.h +13 -15
  43. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputShadowNode.cpp +23 -21
  44. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputShadowNode.h +35 -36
  45. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputState.cpp +4 -4
  46. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputState.h +13 -14
  47. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/conversions.h +12 -13
  48. package/android/src/main/res/drawable/broken_image.xml +10 -0
  49. package/ios/EnrichedTextInputView.h +27 -12
  50. package/ios/EnrichedTextInputView.mm +906 -547
  51. package/ios/attachments/ImageAttachment.h +10 -0
  52. package/ios/attachments/ImageAttachment.mm +34 -0
  53. package/ios/attachments/MediaAttachment.h +23 -0
  54. package/ios/attachments/MediaAttachment.mm +31 -0
  55. package/ios/config/InputConfig.h +12 -6
  56. package/ios/config/InputConfig.mm +71 -33
  57. package/ios/generated/RNEnrichedTextInputViewSpec/EventEmitters.cpp +10 -0
  58. package/ios/generated/RNEnrichedTextInputViewSpec/EventEmitters.h +7 -0
  59. package/ios/generated/RNEnrichedTextInputViewSpec/Props.h +0 -45
  60. package/ios/generated/RNEnrichedTextInputViewSpec/RCTComponentViewHelpers.h +41 -4
  61. package/ios/inputParser/InputParser.h +5 -5
  62. package/ios/inputParser/InputParser.mm +867 -333
  63. package/ios/inputTextView/InputTextView.h +1 -1
  64. package/ios/inputTextView/InputTextView.mm +100 -59
  65. package/ios/internals/EnrichedTextInputViewComponentDescriptor.h +11 -9
  66. package/ios/internals/EnrichedTextInputViewShadowNode.h +28 -24
  67. package/ios/internals/EnrichedTextInputViewShadowNode.mm +64 -47
  68. package/ios/internals/EnrichedTextInputViewState.h +3 -1
  69. package/ios/styles/BlockQuoteStyle.mm +192 -142
  70. package/ios/styles/BoldStyle.mm +96 -62
  71. package/ios/styles/CodeBlockStyle.mm +304 -0
  72. package/ios/styles/H1Style.mm +10 -3
  73. package/ios/styles/H2Style.mm +10 -3
  74. package/ios/styles/H3Style.mm +10 -3
  75. package/ios/styles/HeadingStyleBase.mm +129 -84
  76. package/ios/styles/ImageStyle.mm +160 -0
  77. package/ios/styles/InlineCodeStyle.mm +149 -84
  78. package/ios/styles/ItalicStyle.mm +77 -51
  79. package/ios/styles/LinkStyle.mm +353 -224
  80. package/ios/styles/MentionStyle.mm +434 -220
  81. package/ios/styles/OrderedListStyle.mm +172 -105
  82. package/ios/styles/StrikethroughStyle.mm +53 -34
  83. package/ios/styles/UnderlineStyle.mm +69 -45
  84. package/ios/styles/UnorderedListStyle.mm +170 -105
  85. package/ios/utils/BaseStyleProtocol.h +3 -2
  86. package/ios/utils/ColorExtension.mm +7 -5
  87. package/ios/utils/FontExtension.mm +42 -27
  88. package/ios/utils/ImageData.h +10 -0
  89. package/ios/utils/ImageData.mm +4 -0
  90. package/ios/utils/LayoutManagerExtension.h +1 -1
  91. package/ios/utils/LayoutManagerExtension.mm +334 -109
  92. package/ios/utils/MentionParams.h +0 -1
  93. package/ios/utils/MentionStyleProps.h +1 -1
  94. package/ios/utils/MentionStyleProps.mm +27 -20
  95. package/ios/utils/OccurenceUtils.h +42 -38
  96. package/ios/utils/OccurenceUtils.mm +177 -107
  97. package/ios/utils/ParagraphAttributesUtils.h +6 -1
  98. package/ios/utils/ParagraphAttributesUtils.mm +152 -41
  99. package/ios/utils/ParagraphsUtils.h +2 -1
  100. package/ios/utils/ParagraphsUtils.mm +40 -26
  101. package/ios/utils/StringExtension.h +1 -1
  102. package/ios/utils/StringExtension.mm +19 -16
  103. package/ios/utils/StyleHeaders.h +35 -11
  104. package/ios/utils/TextInsertionUtils.h +13 -2
  105. package/ios/utils/TextInsertionUtils.mm +38 -20
  106. package/ios/utils/WordsUtils.h +2 -1
  107. package/ios/utils/WordsUtils.mm +32 -22
  108. package/ios/utils/ZeroWidthSpaceUtils.h +3 -1
  109. package/ios/utils/ZeroWidthSpaceUtils.mm +153 -75
  110. package/lib/module/EnrichedTextInput.js +41 -3
  111. package/lib/module/EnrichedTextInput.js.map +1 -1
  112. package/lib/module/EnrichedTextInputNativeComponent.ts +17 -5
  113. package/lib/module/normalizeHtmlStyle.js +0 -4
  114. package/lib/module/normalizeHtmlStyle.js.map +1 -1
  115. package/lib/typescript/src/EnrichedTextInput.d.ts +2 -5
  116. package/lib/typescript/src/EnrichedTextInput.d.ts.map +1 -1
  117. package/lib/typescript/src/EnrichedTextInputNativeComponent.d.ts +7 -5
  118. package/lib/typescript/src/EnrichedTextInputNativeComponent.d.ts.map +1 -1
  119. package/lib/typescript/src/normalizeHtmlStyle.d.ts.map +1 -1
  120. package/package.json +8 -1
  121. package/src/EnrichedTextInput.tsx +48 -7
  122. package/src/EnrichedTextInputNativeComponent.ts +17 -5
  123. package/src/normalizeHtmlStyle.ts +0 -4
@@ -1,24 +1,35 @@
1
1
  package com.swmansion.enriched.spans
2
2
 
3
- import android.content.Context
3
+ import android.annotation.SuppressLint
4
+ import android.content.res.Resources
5
+ import android.graphics.BitmapFactory
4
6
  import android.graphics.Canvas
5
7
  import android.graphics.Paint
8
+ import android.graphics.drawable.BitmapDrawable
6
9
  import android.graphics.drawable.Drawable
7
- import android.net.Uri
10
+ import android.text.Editable
11
+ import android.text.Spannable
8
12
  import android.text.style.ImageSpan
13
+ import android.util.Log
14
+ import androidx.core.graphics.drawable.DrawableCompat
9
15
  import androidx.core.graphics.withSave
10
16
  import com.swmansion.enriched.spans.interfaces.EnrichedInlineSpan
17
+ import com.swmansion.enriched.utils.AsyncDrawable
18
+ import androidx.core.graphics.drawable.toDrawable
19
+ import com.swmansion.enriched.R
20
+ import com.swmansion.enriched.spans.utils.ForceRedrawSpan
11
21
  import com.swmansion.enriched.styles.HtmlStyle
22
+ import com.swmansion.enriched.utils.ResourceManager
12
23
 
13
24
  class EnrichedImageSpan : ImageSpan, EnrichedInlineSpan {
14
- private var htmlStyle: HtmlStyle? = null
25
+ override val dependsOnHtmlStyle: Boolean = false
15
26
 
16
- constructor(context: Context, uri: Uri, htmlStyle: HtmlStyle, ) : super(context, uri, ALIGN_BASELINE) {
17
- this.htmlStyle = htmlStyle
18
- }
27
+ private var width: Int = 0
28
+ private var height: Int = 0
19
29
 
20
- constructor(drawable: Drawable, source: String, htmlStyle: HtmlStyle) : super(drawable, source, ALIGN_BASELINE) {
21
- this.htmlStyle = htmlStyle
30
+ constructor(drawable: Drawable, source: String, width: Int, height: Int) : super(drawable, source, ALIGN_BASELINE) {
31
+ this.width = width
32
+ this.height = height
22
33
  }
23
34
 
24
35
  override fun draw(
@@ -35,7 +46,122 @@ class EnrichedImageSpan : ImageSpan, EnrichedInlineSpan {
35
46
 
36
47
  override fun getDrawable(): Drawable {
37
48
  val drawable = super.getDrawable()
38
- drawable.setBounds(0, 0, htmlStyle!!.imgWidth, htmlStyle!!.imgHeight)
49
+ val scale = Resources.getSystem().displayMetrics.density
50
+
51
+ drawable.setBounds(0, 0, (width * scale).toInt() , (height * scale).toInt())
39
52
  return drawable
40
53
  }
54
+
55
+ override fun getSize(
56
+ paint: Paint,
57
+ text: CharSequence?,
58
+ start: Int,
59
+ end: Int,
60
+ fm: Paint.FontMetricsInt?
61
+ ): Int {
62
+ val d = drawable
63
+ val rect = d.bounds
64
+
65
+ if (fm != null) {
66
+ val imageHeight = rect.bottom - rect.top
67
+
68
+ // We want the image bottom to sit on the baseline (0).
69
+ // Therefore, the image top will be at: -imageHeight.
70
+ val targetTop = -imageHeight
71
+
72
+ // Expand the line UPWARDS if the image is taller than the current font
73
+ if (targetTop < fm.ascent) {
74
+ fm.ascent = targetTop
75
+ fm.top = targetTop
76
+ }
77
+ }
78
+
79
+ return rect.right
80
+ }
81
+
82
+ private fun registerDrawableLoadCallback (d: AsyncDrawable, text: Editable?) {
83
+ d.onLoaded = onLoaded@{
84
+ val spannable = text as? Spannable
85
+
86
+ if (spannable == null) {
87
+ return@onLoaded
88
+ }
89
+
90
+ val start = spannable.getSpanStart(this@EnrichedImageSpan)
91
+ val end = spannable.getSpanEnd(this@EnrichedImageSpan)
92
+
93
+ if (start != -1 && end != -1) {
94
+ // trick for adding empty span to force redraw when image is loaded
95
+ val redrawSpan = ForceRedrawSpan()
96
+ spannable.setSpan(redrawSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
97
+ spannable.removeSpan(redrawSpan)
98
+ }
99
+ }
100
+ }
101
+
102
+ fun observeAsyncDrawableLoaded(text: Editable?) {
103
+ val d = drawable
104
+
105
+ if (d !is AsyncDrawable) {
106
+ return
107
+ }
108
+
109
+ registerDrawableLoadCallback(d, text)
110
+
111
+ // If it's already loaded (race condition), run logic immediately
112
+ if (d.isLoaded) {
113
+ d.onLoaded?.invoke()
114
+ }
115
+ }
116
+
117
+ fun getWidth(): Int {
118
+ return width
119
+ }
120
+
121
+ fun getHeight(): Int {
122
+ return height
123
+ }
124
+
125
+ override fun rebuildWithStyle(htmlStyle: HtmlStyle): EnrichedImageSpan = this
126
+
127
+ companion object {
128
+ fun createEnrichedImageSpan(src: String, width: Int, height: Int): EnrichedImageSpan {
129
+ var imgDrawable = prepareDrawableForImage(src)
130
+
131
+ if (imgDrawable == null) {
132
+ imgDrawable = ResourceManager.getDrawableResource(R.drawable.broken_image)
133
+ }
134
+
135
+ return EnrichedImageSpan(imgDrawable, src, width, height)
136
+ }
137
+
138
+ private fun prepareDrawableForImage(src: String): Drawable? {
139
+ var cleanPath = src
140
+
141
+ if (cleanPath.startsWith("http://") || cleanPath.startsWith("https://")) {
142
+ return AsyncDrawable(cleanPath)
143
+ }
144
+
145
+ if (cleanPath.startsWith("file://")) {
146
+ cleanPath = cleanPath.substring(7)
147
+ }
148
+
149
+ var drawable: BitmapDrawable? = null
150
+
151
+ try {
152
+ val bitmap = BitmapFactory.decodeFile(cleanPath)
153
+ if (bitmap != null) {
154
+ drawable = bitmap.toDrawable(Resources.getSystem())
155
+ // set bounds so it knows how big it is naturally,
156
+ // though EnrichedImageSpan will override this with the HTML width/height later.
157
+ drawable.setBounds(0, 0, bitmap.getWidth(), bitmap.getHeight())
158
+ }
159
+ } catch (e: Exception) {
160
+ // Failed to load file
161
+ Log.e("EnrichedImageSpan", "Failed to load image from path: $cleanPath", e)
162
+ }
163
+
164
+ return drawable
165
+ }
166
+ }
41
167
  }
@@ -7,6 +7,8 @@ import com.swmansion.enriched.spans.interfaces.EnrichedInlineSpan
7
7
  import com.swmansion.enriched.styles.HtmlStyle
8
8
 
9
9
  class EnrichedInlineCodeSpan(private val htmlStyle: HtmlStyle) : MetricAffectingSpan(), EnrichedInlineSpan {
10
+ override val dependsOnHtmlStyle: Boolean = true
11
+
10
12
  override fun updateDrawState(textPaint: TextPaint) {
11
13
  val typeface = Typeface.create(Typeface.MONOSPACE, Typeface.NORMAL)
12
14
  textPaint.typeface = typeface
@@ -18,4 +20,8 @@ class EnrichedInlineCodeSpan(private val htmlStyle: HtmlStyle) : MetricAffecting
18
20
  val typeface = Typeface.create(Typeface.MONOSPACE, Typeface.NORMAL)
19
21
  textPaint.typeface = typeface
20
22
  }
23
+
24
+ override fun rebuildWithStyle(htmlStyle: HtmlStyle): EnrichedInlineCodeSpan {
25
+ return EnrichedInlineCodeSpan(htmlStyle)
26
+ }
21
27
  }
@@ -7,4 +7,9 @@ import com.swmansion.enriched.styles.HtmlStyle
7
7
 
8
8
  @Suppress("UNUSED_PARAMETER")
9
9
  class EnrichedItalicSpan(private val htmlStyle: HtmlStyle) : StyleSpan(Typeface.ITALIC), EnrichedInlineSpan {
10
+ override val dependsOnHtmlStyle: Boolean = false
11
+
12
+ override fun rebuildWithStyle(htmlStyle: HtmlStyle): EnrichedItalicSpan {
13
+ return EnrichedItalicSpan(htmlStyle)
14
+ }
10
15
  }
@@ -7,6 +7,8 @@ import com.swmansion.enriched.spans.interfaces.EnrichedInlineSpan
7
7
  import com.swmansion.enriched.styles.HtmlStyle
8
8
 
9
9
  class EnrichedLinkSpan(private val url: String, private val htmlStyle: HtmlStyle) : ClickableSpan(), EnrichedInlineSpan {
10
+ override val dependsOnHtmlStyle: Boolean = true
11
+
10
12
  override fun onClick(view: View) {
11
13
  // Do nothing, links inside the input are not clickable.
12
14
  // We are using `ClickableSpan` to allow the text to be styled as a link.
@@ -21,4 +23,8 @@ class EnrichedLinkSpan(private val url: String, private val htmlStyle: HtmlStyle
21
23
  fun getUrl(): String {
22
24
  return url
23
25
  }
26
+
27
+ override fun rebuildWithStyle(htmlStyle: HtmlStyle): EnrichedLinkSpan {
28
+ return EnrichedLinkSpan(url, htmlStyle)
29
+ }
24
30
  }
@@ -8,6 +8,8 @@ import com.swmansion.enriched.styles.HtmlStyle
8
8
 
9
9
  class EnrichedMentionSpan(private val text: String, private val indicator: String, private val attributes: Map<String, String>, private val htmlStyle: HtmlStyle) :
10
10
  ClickableSpan(), EnrichedInlineSpan {
11
+ override val dependsOnHtmlStyle: Boolean = true
12
+
11
13
  override fun onClick(view: View) {
12
14
  // Do nothing. Mentions inside the input are not clickable.
13
15
  // We are using `ClickableSpan` to allow the text to be styled as a clickable element.
@@ -33,4 +35,8 @@ class EnrichedMentionSpan(private val text: String, private val indicator: Strin
33
35
  fun getIndicator(): String {
34
36
  return indicator
35
37
  }
38
+
39
+ override fun rebuildWithStyle(htmlStyle: HtmlStyle): EnrichedMentionSpan {
40
+ return EnrichedMentionSpan(text, indicator, attributes, htmlStyle)
41
+ }
36
42
  }
@@ -11,6 +11,8 @@ import com.swmansion.enriched.spans.interfaces.EnrichedParagraphSpan
11
11
  import com.swmansion.enriched.styles.HtmlStyle
12
12
 
13
13
  class EnrichedOrderedListSpan(private var index: Int, private val htmlStyle: HtmlStyle) : MetricAffectingSpan(), LeadingMarginSpan, EnrichedParagraphSpan {
14
+ override val dependsOnHtmlStyle: Boolean = true
15
+
14
16
  override fun updateMeasureState(p0: TextPaint) {
15
17
  // Do nothing, but inform layout that this span affects text metrics
16
18
  }
@@ -78,4 +80,8 @@ class EnrichedOrderedListSpan(private var index: Int, private val htmlStyle: Htm
78
80
  fun setIndex(i: Int) {
79
81
  index = i
80
82
  }
83
+
84
+ override fun rebuildWithStyle(htmlStyle: HtmlStyle): EnrichedOrderedListSpan {
85
+ return EnrichedOrderedListSpan(index, htmlStyle)
86
+ }
81
87
  }
@@ -2,9 +2,13 @@ package com.swmansion.enriched.spans
2
2
 
3
3
  import com.swmansion.enriched.styles.HtmlStyle
4
4
 
5
- data class BaseSpanConfig(val clazz: Class<*>)
6
- data class ParagraphSpanConfig(val clazz: Class<*>, val isContinuous: Boolean)
7
- data class ListSpanConfig(val clazz: Class<*>, val shortcut: String)
5
+ interface ISpanConfig {
6
+ val clazz: Class<*>
7
+ }
8
+
9
+ data class BaseSpanConfig(override val clazz: Class<*>): ISpanConfig
10
+ data class ParagraphSpanConfig(override val clazz: Class<*>, val isContinuous: Boolean): ISpanConfig
11
+ data class ListSpanConfig(override val clazz: Class<*>, val shortcut: String) : ISpanConfig
8
12
 
9
13
  data class StylesMergingConfig(
10
14
  // styles that should be removed when we apply specific style
@@ -64,6 +68,8 @@ object EnrichedSpans {
64
68
  MENTION to BaseSpanConfig(EnrichedMentionSpan::class.java),
65
69
  )
66
70
 
71
+ val allSpans: Map<String, ISpanConfig> = inlineSpans + paragraphSpans + listSpans + parametrizedStyles
72
+
67
73
  fun getMergingConfigForStyle(style: String, htmlStyle: HtmlStyle): StylesMergingConfig? {
68
74
  return when (style) {
69
75
  BOLD -> {
@@ -123,4 +129,8 @@ object EnrichedSpans {
123
129
  else -> null
124
130
  }
125
131
  }
132
+
133
+ fun isTypeContinuous(type: Class<*>): Boolean {
134
+ return paragraphSpans.values.find { it.clazz == type }?.isContinuous == true
135
+ }
126
136
  }
@@ -6,4 +6,9 @@ import com.swmansion.enriched.styles.HtmlStyle
6
6
 
7
7
  @Suppress("UNUSED_PARAMETER")
8
8
  class EnrichedStrikeThroughSpan(private val htmlStyle: HtmlStyle) : StrikethroughSpan(), EnrichedInlineSpan {
9
+ override val dependsOnHtmlStyle: Boolean = false
10
+
11
+ override fun rebuildWithStyle(htmlStyle: HtmlStyle): EnrichedStrikeThroughSpan {
12
+ return EnrichedStrikeThroughSpan(htmlStyle)
13
+ }
9
14
  }
@@ -6,4 +6,9 @@ import com.swmansion.enriched.styles.HtmlStyle
6
6
 
7
7
  @Suppress("UNUSED_PARAMETER")
8
8
  class EnrichedUnderlineSpan(private val htmlStyle: HtmlStyle) : UnderlineSpan(), EnrichedInlineSpan {
9
+ override val dependsOnHtmlStyle: Boolean = false
10
+
11
+ override fun rebuildWithStyle(htmlStyle: HtmlStyle): EnrichedUnderlineSpan {
12
+ return EnrichedUnderlineSpan(htmlStyle)
13
+ }
9
14
  }
@@ -12,6 +12,8 @@ import com.swmansion.enriched.styles.HtmlStyle
12
12
 
13
13
  // https://android.googlesource.com/platform/frameworks/base/+/refs/heads/main/core/java/android/text/style/BulletSpan.java
14
14
  class EnrichedUnorderedListSpan(private val htmlStyle: HtmlStyle) : MetricAffectingSpan(), LeadingMarginSpan, EnrichedParagraphSpan {
15
+ override val dependsOnHtmlStyle: Boolean = true
16
+
15
17
  override fun updateMeasureState(p0: TextPaint) {
16
18
  // Do nothing, but inform layout that this span affects text metrics
17
19
  }
@@ -56,4 +58,8 @@ class EnrichedUnorderedListSpan(private val htmlStyle: HtmlStyle) : MetricAffect
56
58
  paint.style = style
57
59
  }
58
60
  }
61
+
62
+ override fun rebuildWithStyle(htmlStyle: HtmlStyle): EnrichedUnorderedListSpan {
63
+ return EnrichedUnorderedListSpan(htmlStyle)
64
+ }
59
65
  }
@@ -1,4 +1,8 @@
1
1
  package com.swmansion.enriched.spans.interfaces
2
2
 
3
+ import com.swmansion.enriched.styles.HtmlStyle
4
+
3
5
  interface EnrichedSpan {
6
+ val dependsOnHtmlStyle: Boolean
7
+ fun rebuildWithStyle(htmlStyle: HtmlStyle): EnrichedSpan
4
8
  }
@@ -0,0 +1,13 @@
1
+ package com.swmansion.enriched.spans.utils
2
+
3
+ import android.text.TextPaint
4
+ import android.text.style.MetricAffectingSpan
5
+
6
+ class ForceRedrawSpan: MetricAffectingSpan() {
7
+ override fun updateMeasureState(tp: TextPaint) {
8
+ // Do nothing, we don't actually want to change how it looks
9
+ }
10
+ override fun updateDrawState(tp: TextPaint?) {
11
+ // Do nothing
12
+ }
13
+ }
@@ -43,9 +43,6 @@ class HtmlStyle {
43
43
  var ulBulletSize: Int = 8
44
44
  var ulBulletColor: Int = Color.BLACK
45
45
 
46
- var imgWidth: Int = 200
47
- var imgHeight: Int = 200
48
-
49
46
  var aColor: Int = Color.BLACK
50
47
  var aUnderline: Boolean = true
51
48
 
@@ -100,10 +97,6 @@ class HtmlStyle {
100
97
  ulMarginLeft = parseFloat(ulStyle, "marginLeft").toInt()
101
98
  ulBulletSize = parseFloat(ulStyle, "bulletSize").toInt()
102
99
 
103
- val imgStyle = style.getMap("img")
104
- imgWidth = parseFloat(imgStyle, "width").toInt()
105
- imgHeight = parseFloat(imgStyle, "height").toInt()
106
-
107
100
  val aStyle = style.getMap("a")
108
101
  aColor = parseColor(aStyle, "color")
109
102
  aUnderline = parseIsUnderline(aStyle)
@@ -124,8 +117,8 @@ class HtmlStyle {
124
117
  private fun parseFloat(map: ReadableMap?, key: String): Float {
125
118
  val safeMap = ensureValueIsSet(map, key)
126
119
 
127
- val fontSize = safeMap.getDouble(key)
128
- return ceil(PixelUtil.toPixelFromSP(fontSize))
120
+ val value = safeMap.getDouble(key)
121
+ return ceil(PixelUtil.toPixelFromSP(value))
129
122
  }
130
123
 
131
124
  private fun parseColorWithOpacity(map: ReadableMap?, key: String, opacity: Int): Int {
@@ -219,6 +212,84 @@ class HtmlStyle {
219
212
  return parseFontWeight(fontWeight)
220
213
  }
221
214
 
215
+ override fun equals(other: Any?): Boolean {
216
+ if (this === other) return true
217
+ if (other !is HtmlStyle) return false
218
+
219
+ return h1FontSize == other.h1FontSize &&
220
+ h1Bold == other.h1Bold &&
221
+ h2FontSize == other.h2FontSize &&
222
+ h2Bold == other.h2Bold &&
223
+ h3FontSize == other.h3FontSize &&
224
+ h3Bold == other.h3Bold &&
225
+
226
+ blockquoteColor == other.blockquoteColor &&
227
+ blockquoteBorderColor == other.blockquoteBorderColor &&
228
+ blockquoteStripeWidth == other.blockquoteStripeWidth &&
229
+ blockquoteGapWidth == other.blockquoteGapWidth &&
230
+
231
+ olGapWidth == other.olGapWidth &&
232
+ olMarginLeft == other.olMarginLeft &&
233
+ olMarkerFontWeight == other.olMarkerFontWeight &&
234
+ olMarkerColor == other.olMarkerColor &&
235
+
236
+ ulGapWidth == other.ulGapWidth &&
237
+ ulMarginLeft == other.ulMarginLeft &&
238
+ ulBulletSize == other.ulBulletSize &&
239
+ ulBulletColor == other.ulBulletColor &&
240
+
241
+ aColor == other.aColor &&
242
+ aUnderline == other.aUnderline &&
243
+
244
+ codeBlockColor == other.codeBlockColor &&
245
+ codeBlockBackgroundColor == other.codeBlockBackgroundColor &&
246
+ codeBlockRadius == other.codeBlockRadius &&
247
+
248
+ inlineCodeColor == other.inlineCodeColor &&
249
+ inlineCodeBackgroundColor == other.inlineCodeBackgroundColor &&
250
+
251
+ mentionsStyle == other.mentionsStyle
252
+ }
253
+
254
+
255
+ override fun hashCode(): Int {
256
+ var result = h1FontSize.hashCode()
257
+ result = 31 * result + h1Bold.hashCode()
258
+ result = 31 * result + h2FontSize.hashCode()
259
+ result = 31 * result + h2Bold.hashCode()
260
+ result = 31 * result + h3FontSize.hashCode()
261
+ result = 31 * result + h3Bold.hashCode()
262
+
263
+ result = 31 * result + (blockquoteColor ?: 0)
264
+ result = 31 * result + blockquoteBorderColor.hashCode()
265
+ result = 31 * result + blockquoteStripeWidth.hashCode()
266
+ result = 31 * result + blockquoteGapWidth.hashCode()
267
+
268
+ result = 31 * result + olGapWidth.hashCode()
269
+ result = 31 * result + olMarginLeft.hashCode()
270
+ result = 31 * result + (olMarkerFontWeight?.hashCode() ?: 0)
271
+ result = 31 * result + (olMarkerColor ?: 0)
272
+
273
+ result = 31 * result + ulGapWidth.hashCode()
274
+ result = 31 * result + ulMarginLeft.hashCode()
275
+ result = 31 * result + ulBulletSize.hashCode()
276
+ result = 31 * result + ulBulletColor.hashCode()
277
+
278
+ result = 31 * result + aColor.hashCode()
279
+ result = 31 * result + aUnderline.hashCode()
280
+
281
+ result = 31 * result + codeBlockColor.hashCode()
282
+ result = 31 * result + codeBlockBackgroundColor.hashCode()
283
+ result = 31 * result + codeBlockRadius.hashCode()
284
+
285
+ result = 31 * result + inlineCodeColor.hashCode()
286
+ result = 31 * result + inlineCodeBackgroundColor.hashCode()
287
+
288
+ result = 31 * result + mentionsStyle.hashCode()
289
+
290
+ return result
291
+ }
292
+
222
293
  companion object {
223
294
  data class MentionStyle(
224
295
  val color: Int,
@@ -54,6 +54,7 @@ class InlineStyles(private val view: EnrichedTextInputView) {
54
54
  val spanEnd = spannable.getSpanEnd(span)
55
55
  var finalStart: Int? = null
56
56
  var finalEnd: Int? = null
57
+ if (spanStart == -1 || spanEnd == -1) continue
57
58
 
58
59
  spannable.removeSpan(span)
59
60