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.
- package/README.md +4 -14
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerDelegate.java +4 -1
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerInterface.java +2 -1
- package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/EventEmitters.cpp +10 -0
- package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/EventEmitters.h +7 -0
- package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/Props.h +0 -45
- package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputView.kt +111 -2
- package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewManager.kt +9 -3
- package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewPackage.kt +2 -0
- package/android/src/main/java/com/swmansion/enriched/events/MentionHandler.kt +1 -1
- package/android/src/main/java/com/swmansion/enriched/events/OnRequestHtmlResultEvent.kt +33 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedBlockQuoteSpan.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedBoldSpan.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedCodeBlockSpan.kt +42 -1
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH1Span.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH2Span.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH3Span.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedImageSpan.kt +135 -9
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedInlineCodeSpan.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedItalicSpan.kt +5 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedLinkSpan.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedMentionSpan.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedOrderedListSpan.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedSpans.kt +13 -3
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedStrikeThroughSpan.kt +5 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedUnderlineSpan.kt +5 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedUnorderedListSpan.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedSpan.kt +4 -0
- package/android/src/main/java/com/swmansion/enriched/spans/utils/ForceRedrawSpan.kt +13 -0
- package/android/src/main/java/com/swmansion/enriched/styles/HtmlStyle.kt +80 -9
- package/android/src/main/java/com/swmansion/enriched/styles/InlineStyles.kt +1 -0
- package/android/src/main/java/com/swmansion/enriched/styles/ParagraphStyles.kt +188 -5
- package/android/src/main/java/com/swmansion/enriched/styles/ParametrizedStyles.kt +57 -30
- package/android/src/main/java/com/swmansion/enriched/utils/AsyncDrawable.kt +91 -0
- package/android/src/main/java/com/swmansion/enriched/utils/EnrichedParser.java +24 -13
- package/android/src/main/java/com/swmansion/enriched/utils/ResourceManager.kt +26 -0
- package/android/src/main/java/com/swmansion/enriched/watchers/EnrichedSpanWatcher.kt +3 -0
- package/android/src/main/new_arch/RNEnrichedTextInputViewSpec.cpp +6 -6
- package/android/src/main/new_arch/RNEnrichedTextInputViewSpec.h +6 -6
- package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputComponentDescriptor.h +19 -19
- package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputMeasurementManager.cpp +40 -51
- package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputMeasurementManager.h +13 -15
- package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputShadowNode.cpp +23 -21
- package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputShadowNode.h +35 -36
- package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputState.cpp +4 -4
- package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputState.h +13 -14
- package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/conversions.h +12 -13
- package/android/src/main/res/drawable/broken_image.xml +10 -0
- package/ios/EnrichedTextInputView.h +27 -12
- package/ios/EnrichedTextInputView.mm +906 -547
- package/ios/attachments/ImageAttachment.h +10 -0
- package/ios/attachments/ImageAttachment.mm +34 -0
- package/ios/attachments/MediaAttachment.h +23 -0
- package/ios/attachments/MediaAttachment.mm +31 -0
- package/ios/config/InputConfig.h +12 -6
- package/ios/config/InputConfig.mm +71 -33
- package/ios/generated/RNEnrichedTextInputViewSpec/EventEmitters.cpp +10 -0
- package/ios/generated/RNEnrichedTextInputViewSpec/EventEmitters.h +7 -0
- package/ios/generated/RNEnrichedTextInputViewSpec/Props.h +0 -45
- package/ios/generated/RNEnrichedTextInputViewSpec/RCTComponentViewHelpers.h +41 -4
- package/ios/inputParser/InputParser.h +5 -5
- package/ios/inputParser/InputParser.mm +867 -333
- package/ios/inputTextView/InputTextView.h +1 -1
- package/ios/inputTextView/InputTextView.mm +100 -59
- package/ios/internals/EnrichedTextInputViewComponentDescriptor.h +11 -9
- package/ios/internals/EnrichedTextInputViewShadowNode.h +28 -24
- package/ios/internals/EnrichedTextInputViewShadowNode.mm +64 -47
- package/ios/internals/EnrichedTextInputViewState.h +3 -1
- package/ios/styles/BlockQuoteStyle.mm +192 -142
- package/ios/styles/BoldStyle.mm +96 -62
- package/ios/styles/CodeBlockStyle.mm +304 -0
- package/ios/styles/H1Style.mm +10 -3
- package/ios/styles/H2Style.mm +10 -3
- package/ios/styles/H3Style.mm +10 -3
- package/ios/styles/HeadingStyleBase.mm +129 -84
- package/ios/styles/ImageStyle.mm +160 -0
- package/ios/styles/InlineCodeStyle.mm +149 -84
- package/ios/styles/ItalicStyle.mm +77 -51
- package/ios/styles/LinkStyle.mm +353 -224
- package/ios/styles/MentionStyle.mm +434 -220
- package/ios/styles/OrderedListStyle.mm +172 -105
- package/ios/styles/StrikethroughStyle.mm +53 -34
- package/ios/styles/UnderlineStyle.mm +69 -45
- package/ios/styles/UnorderedListStyle.mm +170 -105
- package/ios/utils/BaseStyleProtocol.h +3 -2
- package/ios/utils/ColorExtension.mm +7 -5
- package/ios/utils/FontExtension.mm +42 -27
- package/ios/utils/ImageData.h +10 -0
- package/ios/utils/ImageData.mm +4 -0
- package/ios/utils/LayoutManagerExtension.h +1 -1
- package/ios/utils/LayoutManagerExtension.mm +334 -109
- package/ios/utils/MentionParams.h +0 -1
- package/ios/utils/MentionStyleProps.h +1 -1
- package/ios/utils/MentionStyleProps.mm +27 -20
- package/ios/utils/OccurenceUtils.h +42 -38
- package/ios/utils/OccurenceUtils.mm +177 -107
- package/ios/utils/ParagraphAttributesUtils.h +6 -1
- package/ios/utils/ParagraphAttributesUtils.mm +152 -41
- package/ios/utils/ParagraphsUtils.h +2 -1
- package/ios/utils/ParagraphsUtils.mm +40 -26
- package/ios/utils/StringExtension.h +1 -1
- package/ios/utils/StringExtension.mm +19 -16
- package/ios/utils/StyleHeaders.h +35 -11
- package/ios/utils/TextInsertionUtils.h +13 -2
- package/ios/utils/TextInsertionUtils.mm +38 -20
- package/ios/utils/WordsUtils.h +2 -1
- package/ios/utils/WordsUtils.mm +32 -22
- package/ios/utils/ZeroWidthSpaceUtils.h +3 -1
- package/ios/utils/ZeroWidthSpaceUtils.mm +153 -75
- package/lib/module/EnrichedTextInput.js +41 -3
- package/lib/module/EnrichedTextInput.js.map +1 -1
- package/lib/module/EnrichedTextInputNativeComponent.ts +17 -5
- package/lib/module/normalizeHtmlStyle.js +0 -4
- package/lib/module/normalizeHtmlStyle.js.map +1 -1
- package/lib/typescript/src/EnrichedTextInput.d.ts +2 -5
- package/lib/typescript/src/EnrichedTextInput.d.ts.map +1 -1
- package/lib/typescript/src/EnrichedTextInputNativeComponent.d.ts +7 -5
- package/lib/typescript/src/EnrichedTextInputNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/normalizeHtmlStyle.d.ts.map +1 -1
- package/package.json +8 -1
- package/src/EnrichedTextInput.tsx +48 -7
- package/src/EnrichedTextInputNativeComponent.ts +17 -5
- package/src/normalizeHtmlStyle.ts +0 -4
|
@@ -1,24 +1,35 @@
|
|
|
1
1
|
package com.swmansion.enriched.spans
|
|
2
2
|
|
|
3
|
-
import android.
|
|
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.
|
|
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
|
-
|
|
25
|
+
override val dependsOnHtmlStyle: Boolean = false
|
|
15
26
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
27
|
+
private var width: Int = 0
|
|
28
|
+
private var height: Int = 0
|
|
19
29
|
|
|
20
|
-
constructor(drawable: Drawable, source: String,
|
|
21
|
-
this.
|
|
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
|
-
|
|
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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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
|
}
|
|
@@ -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
|
|
128
|
-
return ceil(PixelUtil.toPixelFromSP(
|
|
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,
|