react-native-enriched 0.0.0 → 0.1.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.
- package/LICENSE +20 -0
- package/README.md +869 -0
- package/ReactNativeEnriched.podspec +27 -0
- package/android/build.gradle +101 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerDelegate.java +146 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerInterface.java +55 -0
- package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/ComponentDescriptors.cpp +22 -0
- package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/ComponentDescriptors.h +24 -0
- package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/EventEmitters.cpp +118 -0
- package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/EventEmitters.h +95 -0
- package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/Props.cpp +128 -0
- package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/Props.h +577 -0
- package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/ShadowNodes.cpp +17 -0
- package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/ShadowNodes.h +23 -0
- package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/States.cpp +16 -0
- package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/States.h +20 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +3 -0
- package/android/src/main/AndroidManifestNew.xml +2 -0
- package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputView.kt +535 -0
- package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewLayoutManager.kt +64 -0
- package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewManager.kt +292 -0
- package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewPackage.kt +19 -0
- package/android/src/main/java/com/swmansion/enriched/events/MentionHandler.kt +40 -0
- package/android/src/main/java/com/swmansion/enriched/events/OnChangeHtmlEvent.kt +28 -0
- package/android/src/main/java/com/swmansion/enriched/events/OnChangeSelectionEvent.kt +29 -0
- package/android/src/main/java/com/swmansion/enriched/events/OnChangeStateEvent.kt +24 -0
- package/android/src/main/java/com/swmansion/enriched/events/OnChangeTextEvent.kt +30 -0
- package/android/src/main/java/com/swmansion/enriched/events/OnInputBlurEvent.kt +27 -0
- package/android/src/main/java/com/swmansion/enriched/events/OnInputFocusEvent.kt +27 -0
- package/android/src/main/java/com/swmansion/enriched/events/OnLinkDetectedEvent.kt +30 -0
- package/android/src/main/java/com/swmansion/enriched/events/OnMentionDetectedEvent.kt +29 -0
- package/android/src/main/java/com/swmansion/enriched/events/OnMentionEvent.kt +33 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedBlockQuoteSpan.kt +34 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedBoldSpan.kt +10 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedCodeBlockSpan.kt +38 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH1Span.kt +17 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH2Span.kt +17 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH3Span.kt +17 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedImageSpan.kt +41 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedInlineCodeSpan.kt +16 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedItalicSpan.kt +10 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedLinkSpan.kt +24 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedMentionSpan.kt +36 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedOrderedListSpan.kt +71 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedSpans.kt +111 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedStrikeThroughSpan.kt +9 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedUnderlineSpan.kt +9 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedUnorderedListSpan.kt +49 -0
- package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedBlockSpan.kt +4 -0
- package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedHeadingSpan.kt +4 -0
- package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedInlineSpan.kt +4 -0
- package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedParagraphSpan.kt +4 -0
- package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedSpan.kt +4 -0
- package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedZeroWidthSpaceSpan.kt +5 -0
- package/android/src/main/java/com/swmansion/enriched/styles/HtmlStyle.kt +227 -0
- package/android/src/main/java/com/swmansion/enriched/styles/InlineStyles.kt +146 -0
- package/android/src/main/java/com/swmansion/enriched/styles/ListStyles.kt +173 -0
- package/android/src/main/java/com/swmansion/enriched/styles/ParagraphStyles.kt +186 -0
- package/android/src/main/java/com/swmansion/enriched/styles/ParametrizedStyles.kt +223 -0
- package/android/src/main/java/com/swmansion/enriched/utils/EnrichedParser.java +857 -0
- package/android/src/main/java/com/swmansion/enriched/utils/EnrichedSelection.kt +285 -0
- package/android/src/main/java/com/swmansion/enriched/utils/EnrichedSpanState.kt +204 -0
- package/android/src/main/java/com/swmansion/enriched/utils/Utils.kt +91 -0
- package/android/src/main/java/com/swmansion/enriched/watchers/EnrichedSpanWatcher.kt +73 -0
- package/android/src/main/java/com/swmansion/enriched/watchers/EnrichedTextWatcher.kt +51 -0
- package/android/src/main/new_arch/CMakeLists.txt +56 -0
- package/android/src/main/new_arch/RNEnrichedTextInputViewSpec.cpp +22 -0
- package/android/src/main/new_arch/RNEnrichedTextInputViewSpec.h +26 -0
- package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputComponentDescriptor.h +35 -0
- package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputMeasurementManager.cpp +51 -0
- package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputMeasurementManager.h +26 -0
- package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputShadowNode.cpp +34 -0
- package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputShadowNode.h +54 -0
- package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputState.cpp +9 -0
- package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputState.h +25 -0
- package/ios/EnrichedTextInputView.h +33 -0
- package/ios/EnrichedTextInputView.mm +1190 -0
- package/ios/EnrichedTextInputViewManager.mm +13 -0
- package/ios/config/InputConfig.h +67 -0
- package/ios/config/InputConfig.mm +382 -0
- package/ios/generated/RNEnrichedTextInputViewSpec/ComponentDescriptors.cpp +22 -0
- package/ios/generated/RNEnrichedTextInputViewSpec/ComponentDescriptors.h +24 -0
- package/ios/generated/RNEnrichedTextInputViewSpec/EventEmitters.cpp +118 -0
- package/ios/generated/RNEnrichedTextInputViewSpec/EventEmitters.h +95 -0
- package/ios/generated/RNEnrichedTextInputViewSpec/Props.cpp +128 -0
- package/ios/generated/RNEnrichedTextInputViewSpec/Props.h +577 -0
- package/ios/generated/RNEnrichedTextInputViewSpec/RCTComponentViewHelpers.h +384 -0
- package/ios/generated/RNEnrichedTextInputViewSpec/ShadowNodes.cpp +17 -0
- package/ios/generated/RNEnrichedTextInputViewSpec/ShadowNodes.h +23 -0
- package/ios/generated/RNEnrichedTextInputViewSpec/States.cpp +16 -0
- package/ios/generated/RNEnrichedTextInputViewSpec/States.h +20 -0
- package/ios/inputParser/InputParser.h +11 -0
- package/ios/inputParser/InputParser.mm +669 -0
- package/ios/inputTextView/InputTextView.h +6 -0
- package/ios/inputTextView/InputTextView.mm +115 -0
- package/ios/internals/EnrichedTextInputViewComponentDescriptor.h +17 -0
- package/ios/internals/EnrichedTextInputViewShadowNode.h +40 -0
- package/ios/internals/EnrichedTextInputViewShadowNode.mm +83 -0
- package/ios/internals/EnrichedTextInputViewState.cpp +10 -0
- package/ios/internals/EnrichedTextInputViewState.h +20 -0
- package/ios/styles/BlockQuoteStyle.mm +248 -0
- package/ios/styles/BoldStyle.mm +122 -0
- package/ios/styles/H1Style.mm +10 -0
- package/ios/styles/H2Style.mm +10 -0
- package/ios/styles/H3Style.mm +10 -0
- package/ios/styles/HeadingStyleBase.mm +144 -0
- package/ios/styles/InlineCodeStyle.mm +163 -0
- package/ios/styles/ItalicStyle.mm +110 -0
- package/ios/styles/LinkStyle.mm +463 -0
- package/ios/styles/MentionStyle.mm +476 -0
- package/ios/styles/OrderedListStyle.mm +225 -0
- package/ios/styles/StrikethroughStyle.mm +80 -0
- package/ios/styles/UnderlineStyle.mm +112 -0
- package/ios/styles/UnorderedListStyle.mm +225 -0
- package/ios/utils/BaseStyleProtocol.h +16 -0
- package/ios/utils/ColorExtension.h +6 -0
- package/ios/utils/ColorExtension.mm +27 -0
- package/ios/utils/FontExtension.h +13 -0
- package/ios/utils/FontExtension.mm +91 -0
- package/ios/utils/LayoutManagerExtension.h +6 -0
- package/ios/utils/LayoutManagerExtension.mm +171 -0
- package/ios/utils/LinkData.h +9 -0
- package/ios/utils/LinkData.mm +4 -0
- package/ios/utils/MentionParams.h +9 -0
- package/ios/utils/MentionParams.mm +4 -0
- package/ios/utils/MentionStyleProps.h +13 -0
- package/ios/utils/MentionStyleProps.mm +56 -0
- package/ios/utils/OccurenceUtils.h +37 -0
- package/ios/utils/OccurenceUtils.mm +124 -0
- package/ios/utils/ParagraphsUtils.h +7 -0
- package/ios/utils/ParagraphsUtils.mm +54 -0
- package/ios/utils/StringExtension.h +15 -0
- package/ios/utils/StringExtension.mm +57 -0
- package/ios/utils/StyleHeaders.h +74 -0
- package/ios/utils/StylePair.h +9 -0
- package/ios/utils/StylePair.mm +4 -0
- package/ios/utils/StyleTypeEnum.h +22 -0
- package/ios/utils/TextDecorationLineEnum.h +6 -0
- package/ios/utils/TextDecorationLineEnum.mm +4 -0
- package/ios/utils/TextInsertionUtils.h +6 -0
- package/ios/utils/TextInsertionUtils.mm +48 -0
- package/ios/utils/WordsUtils.h +6 -0
- package/ios/utils/WordsUtils.mm +88 -0
- package/ios/utils/ZeroWidthSpaceUtils.h +7 -0
- package/ios/utils/ZeroWidthSpaceUtils.mm +164 -0
- package/lib/module/EnrichedTextInput.js +191 -0
- package/lib/module/EnrichedTextInput.js.map +1 -0
- package/lib/module/EnrichedTextInputNativeComponent.ts +235 -0
- package/lib/module/index.js +4 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/normalizeHtmlStyle.js +141 -0
- package/lib/module/normalizeHtmlStyle.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/EnrichedTextInput.d.ts +113 -0
- package/lib/typescript/src/EnrichedTextInput.d.ts.map +1 -0
- package/lib/typescript/src/EnrichedTextInputNativeComponent.d.ts +160 -0
- package/lib/typescript/src/EnrichedTextInputNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +3 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/normalizeHtmlStyle.d.ts +4 -0
- package/lib/typescript/src/normalizeHtmlStyle.d.ts.map +1 -0
- package/package.json +172 -1
- package/react-native.config.js +13 -0
- package/src/EnrichedTextInput.tsx +358 -0
- package/src/EnrichedTextInputNativeComponent.ts +235 -0
- package/src/index.tsx +9 -0
- 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
|
+
}
|