react-native-enriched 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -17
- package/android/build.gradle +77 -72
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerDelegate.java +21 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerInterface.java +7 -0
- package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/EventEmitters.cpp +156 -0
- package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/EventEmitters.h +147 -0
- package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/Props.cpp +10 -0
- package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/Props.h +194 -0
- package/android/lint.gradle +70 -0
- package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputConnectionWrapper.kt +140 -0
- package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputView.kt +304 -83
- package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewLayoutManager.kt +3 -1
- package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewManager.kt +166 -51
- package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewPackage.kt +1 -3
- package/android/src/main/java/com/swmansion/enriched/MeasurementStore.kt +70 -21
- package/android/src/main/java/com/swmansion/enriched/events/MentionHandler.kt +21 -11
- package/android/src/main/java/com/swmansion/enriched/events/OnChangeHtmlEvent.kt +8 -9
- package/android/src/main/java/com/swmansion/enriched/events/OnChangeSelectionEvent.kt +10 -9
- package/android/src/main/java/com/swmansion/enriched/events/OnChangeStateDeprecatedEvent.kt +21 -0
- package/android/src/main/java/com/swmansion/enriched/events/OnChangeStateEvent.kt +9 -12
- package/android/src/main/java/com/swmansion/enriched/events/OnChangeTextEvent.kt +10 -10
- package/android/src/main/java/com/swmansion/enriched/events/OnInputBlurEvent.kt +7 -9
- package/android/src/main/java/com/swmansion/enriched/events/OnInputFocusEvent.kt +7 -9
- package/android/src/main/java/com/swmansion/enriched/events/OnInputKeyPressEvent.kt +27 -0
- package/android/src/main/java/com/swmansion/enriched/events/OnLinkDetectedEvent.kt +13 -11
- package/android/src/main/java/com/swmansion/enriched/events/OnMentionDetectedEvent.kt +10 -9
- package/android/src/main/java/com/swmansion/enriched/events/OnMentionEvent.kt +9 -8
- package/android/src/main/java/com/swmansion/enriched/events/OnRequestHtmlResultEvent.kt +32 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedBlockQuoteSpan.kt +24 -5
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedBoldSpan.kt +8 -1
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedCodeBlockSpan.kt +10 -2
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH1Span.kt +8 -1
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH2Span.kt +8 -1
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH3Span.kt +8 -1
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH4Span.kt +24 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH5Span.kt +24 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH6Span.kt +24 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedImageSpan.kt +34 -17
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedInlineCodeSpan.kt +8 -1
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedItalicSpan.kt +7 -1
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedLinkSpan.kt +10 -4
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedMentionSpan.kt +14 -11
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedOrderedListSpan.kt +18 -11
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedSpans.kt +174 -72
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedStrikeThroughSpan.kt +7 -1
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedUnderlineSpan.kt +7 -1
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedUnorderedListSpan.kt +11 -5
- package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedBlockSpan.kt +3 -2
- package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedHeadingSpan.kt +1 -2
- package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedInlineSpan.kt +1 -2
- package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedParagraphSpan.kt +3 -2
- package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedSpan.kt +5 -0
- package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedZeroWidthSpaceSpan.kt +1 -2
- package/android/src/main/java/com/swmansion/enriched/spans/utils/ForceRedrawSpan.kt +2 -1
- package/android/src/main/java/com/swmansion/enriched/styles/HtmlStyle.kt +155 -20
- package/android/src/main/java/com/swmansion/enriched/styles/InlineStyles.kt +25 -8
- package/android/src/main/java/com/swmansion/enriched/styles/ListStyles.kt +60 -20
- package/android/src/main/java/com/swmansion/enriched/styles/ParagraphStyles.kt +161 -25
- package/android/src/main/java/com/swmansion/enriched/styles/ParametrizedStyles.kt +128 -52
- package/android/src/main/java/com/swmansion/enriched/utils/AsyncDrawable.kt +10 -7
- package/android/src/main/java/com/swmansion/enriched/utils/EnrichedConstants.kt +11 -0
- package/android/src/main/java/com/swmansion/enriched/utils/EnrichedEditableFactory.kt +17 -0
- package/android/src/main/java/com/swmansion/enriched/utils/EnrichedParser.java +136 -87
- package/android/src/main/java/com/swmansion/enriched/utils/EnrichedSelection.kt +71 -42
- package/android/src/main/java/com/swmansion/enriched/utils/EnrichedSpanState.kt +183 -48
- package/android/src/main/java/com/swmansion/enriched/utils/EnrichedSpannable.kt +82 -0
- package/android/src/main/java/com/swmansion/enriched/utils/EnrichedSpannableStringBuilder.kt +15 -0
- package/android/src/main/java/com/swmansion/enriched/utils/Utils.kt +0 -70
- package/android/src/main/java/com/swmansion/enriched/watchers/EnrichedSpanWatcher.kt +46 -14
- package/android/src/main/java/com/swmansion/enriched/watchers/EnrichedTextWatcher.kt +34 -11
- package/android/src/main/new_arch/CMakeLists.txt +6 -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 +33 -14
- package/ios/EnrichedTextInputView.h +26 -14
- package/ios/EnrichedTextInputView.mm +1209 -586
- package/ios/config/InputConfig.h +24 -6
- package/ios/config/InputConfig.mm +154 -38
- package/ios/{utils → extensions}/ColorExtension.mm +7 -5
- package/ios/extensions/FontExtension.mm +106 -0
- package/ios/{utils → extensions}/LayoutManagerExtension.h +1 -1
- package/ios/extensions/LayoutManagerExtension.mm +396 -0
- package/ios/{utils → extensions}/StringExtension.mm +19 -16
- package/ios/generated/RNEnrichedTextInputViewSpec/EventEmitters.cpp +156 -0
- package/ios/generated/RNEnrichedTextInputViewSpec/EventEmitters.h +147 -0
- package/ios/generated/RNEnrichedTextInputViewSpec/Props.cpp +10 -0
- package/ios/generated/RNEnrichedTextInputViewSpec/Props.h +194 -0
- package/ios/generated/RNEnrichedTextInputViewSpec/RCTComponentViewHelpers.h +95 -0
- package/ios/inputParser/InputParser.h +5 -5
- package/ios/inputParser/InputParser.mm +864 -380
- package/ios/inputTextView/InputTextView.h +1 -1
- package/ios/inputTextView/InputTextView.mm +100 -59
- package/ios/{utils → interfaces}/BaseStyleProtocol.h +2 -2
- package/ios/interfaces/ImageAttachment.h +10 -0
- package/ios/interfaces/ImageAttachment.mm +36 -0
- package/ios/interfaces/LinkRegexConfig.h +19 -0
- package/ios/interfaces/LinkRegexConfig.mm +37 -0
- package/ios/interfaces/MediaAttachment.h +23 -0
- package/ios/interfaces/MediaAttachment.mm +31 -0
- package/ios/{utils → interfaces}/MentionParams.h +0 -1
- package/ios/{utils → interfaces}/MentionStyleProps.mm +27 -20
- package/ios/{utils → interfaces}/StyleHeaders.h +37 -15
- package/ios/{utils → interfaces}/StyleTypeEnum.h +3 -0
- package/ios/internals/EnrichedTextInputViewComponentDescriptor.h +11 -9
- package/ios/internals/EnrichedTextInputViewShadowNode.h +28 -25
- package/ios/internals/EnrichedTextInputViewShadowNode.mm +45 -40
- package/ios/internals/EnrichedTextInputViewState.h +3 -1
- package/ios/styles/BlockQuoteStyle.mm +189 -118
- package/ios/styles/BoldStyle.mm +110 -63
- package/ios/styles/CodeBlockStyle.mm +204 -128
- package/ios/styles/H1Style.mm +10 -4
- package/ios/styles/H2Style.mm +10 -4
- package/ios/styles/H3Style.mm +10 -4
- package/ios/styles/H4Style.mm +17 -0
- package/ios/styles/H5Style.mm +17 -0
- package/ios/styles/H6Style.mm +17 -0
- package/ios/styles/HeadingStyleBase.mm +148 -86
- package/ios/styles/ImageStyle.mm +75 -73
- package/ios/styles/InlineCodeStyle.mm +162 -88
- package/ios/styles/ItalicStyle.mm +76 -52
- package/ios/styles/LinkStyle.mm +411 -232
- package/ios/styles/MentionStyle.mm +363 -246
- package/ios/styles/OrderedListStyle.mm +171 -106
- package/ios/styles/StrikethroughStyle.mm +52 -35
- package/ios/styles/UnderlineStyle.mm +68 -46
- package/ios/styles/UnorderedListStyle.mm +169 -106
- package/ios/utils/OccurenceUtils.h +42 -42
- package/ios/utils/OccurenceUtils.mm +142 -119
- package/ios/utils/ParagraphAttributesUtils.h +10 -2
- package/ios/utils/ParagraphAttributesUtils.mm +182 -71
- package/ios/utils/ParagraphsUtils.h +2 -1
- package/ios/utils/ParagraphsUtils.mm +41 -27
- 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 +145 -79
- package/lib/module/EnrichedTextInput.js +61 -2
- package/lib/module/EnrichedTextInput.js.map +1 -1
- package/lib/module/EnrichedTextInputNativeComponent.ts +149 -12
- package/lib/module/{normalizeHtmlStyle.js → utils/normalizeHtmlStyle.js} +12 -0
- package/lib/module/utils/normalizeHtmlStyle.js.map +1 -0
- package/lib/module/utils/regexParser.js +46 -0
- package/lib/module/utils/regexParser.js.map +1 -0
- package/lib/typescript/src/EnrichedTextInput.d.ts +24 -14
- package/lib/typescript/src/EnrichedTextInput.d.ts.map +1 -1
- package/lib/typescript/src/EnrichedTextInputNativeComponent.d.ts +129 -12
- package/lib/typescript/src/EnrichedTextInputNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/utils/normalizeHtmlStyle.d.ts +4 -0
- package/lib/typescript/src/utils/normalizeHtmlStyle.d.ts.map +1 -0
- package/lib/typescript/src/utils/regexParser.d.ts +3 -0
- package/lib/typescript/src/utils/regexParser.d.ts.map +1 -0
- package/package.json +17 -6
- package/src/EnrichedTextInput.tsx +96 -13
- package/src/EnrichedTextInputNativeComponent.ts +149 -12
- package/src/index.tsx +2 -0
- package/src/{normalizeHtmlStyle.ts → utils/normalizeHtmlStyle.ts} +14 -2
- package/src/utils/regexParser.ts +56 -0
- package/ios/utils/FontExtension.mm +0 -91
- package/ios/utils/LayoutManagerExtension.mm +0 -286
- package/lib/module/normalizeHtmlStyle.js.map +0 -1
- package/lib/typescript/src/normalizeHtmlStyle.d.ts +0 -4
- package/lib/typescript/src/normalizeHtmlStyle.d.ts.map +0 -1
- package/ios/{utils → extensions}/ColorExtension.h +0 -0
- package/ios/{utils → extensions}/FontExtension.h +0 -0
- package/ios/{utils → extensions}/StringExtension.h +1 -1
- package/ios/{utils → interfaces}/ImageData.h +0 -0
- package/ios/{utils → interfaces}/ImageData.mm +0 -0
- package/ios/{utils → interfaces}/LinkData.h +0 -0
- package/ios/{utils → interfaces}/LinkData.mm +0 -0
- package/ios/{utils → interfaces}/MentionParams.mm +0 -0
- package/ios/{utils → interfaces}/MentionStyleProps.h +1 -1
- /package/ios/{utils → interfaces}/StylePair.h +0 -0
- /package/ios/{utils → interfaces}/StylePair.mm +0 -0
- /package/ios/{utils → interfaces}/TextDecorationLineEnum.h +0 -0
- /package/ios/{utils → interfaces}/TextDecorationLineEnum.mm +0 -0
|
@@ -28,6 +28,15 @@ class HtmlStyle {
|
|
|
28
28
|
var h3FontSize: Int = 56
|
|
29
29
|
var h3Bold: Boolean = false
|
|
30
30
|
|
|
31
|
+
var h4FontSize: Int = 48
|
|
32
|
+
var h4Bold: Boolean = false
|
|
33
|
+
|
|
34
|
+
var h5FontSize: Int = 40
|
|
35
|
+
var h5Bold: Boolean = false
|
|
36
|
+
|
|
37
|
+
var h6FontSize: Int = 32
|
|
38
|
+
var h6Bold: Boolean = false
|
|
39
|
+
|
|
31
40
|
var blockquoteColor: Int? = null
|
|
32
41
|
var blockquoteBorderColor: Int = Color.BLACK
|
|
33
42
|
var blockquoteStripeWidth: Int = 2
|
|
@@ -77,6 +86,18 @@ class HtmlStyle {
|
|
|
77
86
|
h3FontSize = parseFloat(h3Style, "fontSize").toInt()
|
|
78
87
|
h3Bold = h3Style?.getBoolean("bold") == true
|
|
79
88
|
|
|
89
|
+
val h4Style = style.getMap("h4")
|
|
90
|
+
h4FontSize = parseFloat(h4Style, "fontSize").toInt()
|
|
91
|
+
h4Bold = h4Style?.getBoolean("bold") == true
|
|
92
|
+
|
|
93
|
+
val h5Style = style.getMap("h5")
|
|
94
|
+
h5FontSize = parseFloat(h5Style, "fontSize").toInt()
|
|
95
|
+
h5Bold = h5Style?.getBoolean("bold") == true
|
|
96
|
+
|
|
97
|
+
val h6Style = style.getMap("h6")
|
|
98
|
+
h6FontSize = parseFloat(h6Style, "fontSize").toInt()
|
|
99
|
+
h6Bold = h6Style?.getBoolean("bold") == true
|
|
100
|
+
|
|
80
101
|
val blockquoteStyle = style.getMap("blockquote")
|
|
81
102
|
blockquoteColor = parseOptionalColor(blockquoteStyle, "color")
|
|
82
103
|
blockquoteBorderColor = parseColor(blockquoteStyle, "borderColor")
|
|
@@ -114,19 +135,29 @@ class HtmlStyle {
|
|
|
114
135
|
mentionsStyle = parseMentionsStyle(mentionStyle)
|
|
115
136
|
}
|
|
116
137
|
|
|
117
|
-
private fun parseFloat(
|
|
138
|
+
private fun parseFloat(
|
|
139
|
+
map: ReadableMap?,
|
|
140
|
+
key: String,
|
|
141
|
+
): Float {
|
|
118
142
|
val safeMap = ensureValueIsSet(map, key)
|
|
119
143
|
|
|
120
144
|
val value = safeMap.getDouble(key)
|
|
121
145
|
return ceil(PixelUtil.toPixelFromSP(value))
|
|
122
146
|
}
|
|
123
147
|
|
|
124
|
-
private fun parseColorWithOpacity(
|
|
148
|
+
private fun parseColorWithOpacity(
|
|
149
|
+
map: ReadableMap?,
|
|
150
|
+
key: String,
|
|
151
|
+
opacity: Int,
|
|
152
|
+
): Int {
|
|
125
153
|
val color = parseColor(map, key)
|
|
126
154
|
return withOpacity(color, opacity)
|
|
127
155
|
}
|
|
128
156
|
|
|
129
|
-
private fun parseOptionalColor(
|
|
157
|
+
private fun parseOptionalColor(
|
|
158
|
+
map: ReadableMap?,
|
|
159
|
+
key: String,
|
|
160
|
+
): Int? {
|
|
130
161
|
if (map == null) return null
|
|
131
162
|
if (!map.hasKey(key)) return null
|
|
132
163
|
if (map.isNull(key)) return null
|
|
@@ -134,7 +165,10 @@ class HtmlStyle {
|
|
|
134
165
|
return parseColor(map, key)
|
|
135
166
|
}
|
|
136
167
|
|
|
137
|
-
private fun parseColor(
|
|
168
|
+
private fun parseColor(
|
|
169
|
+
map: ReadableMap?,
|
|
170
|
+
key: String,
|
|
171
|
+
): Int {
|
|
138
172
|
val safeMap = ensureValueIsSet(map, key)
|
|
139
173
|
|
|
140
174
|
val color = safeMap.getDouble(key)
|
|
@@ -146,7 +180,10 @@ class HtmlStyle {
|
|
|
146
180
|
return parsedColor
|
|
147
181
|
}
|
|
148
182
|
|
|
149
|
-
private fun withOpacity(
|
|
183
|
+
private fun withOpacity(
|
|
184
|
+
color: Int,
|
|
185
|
+
alpha: Int,
|
|
186
|
+
): Int {
|
|
150
187
|
// Do not apply opacity to transparent color
|
|
151
188
|
if (Color.alpha(color) == 0) return color
|
|
152
189
|
val a = alpha.coerceIn(0, 255)
|
|
@@ -164,14 +201,20 @@ class HtmlStyle {
|
|
|
164
201
|
throw Error("Specified textDecorationLine value is not supported: $underline. Supported values are 'underline' and 'none'.")
|
|
165
202
|
}
|
|
166
203
|
|
|
167
|
-
private fun calculateOlMarginLeft(
|
|
204
|
+
private fun calculateOlMarginLeft(
|
|
205
|
+
view: EnrichedTextInputView?,
|
|
206
|
+
userMargin: Int,
|
|
207
|
+
): Int {
|
|
168
208
|
val fontSize = view?.fontSize?.toInt() ?: 0
|
|
169
209
|
val leadMargin = fontSize / 2
|
|
170
210
|
|
|
171
211
|
return leadMargin + userMargin
|
|
172
212
|
}
|
|
173
213
|
|
|
174
|
-
private fun ensureValueIsSet(
|
|
214
|
+
private fun ensureValueIsSet(
|
|
215
|
+
map: ReadableMap?,
|
|
216
|
+
key: String,
|
|
217
|
+
): ReadableMap {
|
|
175
218
|
if (map == null) throw Error("Style map cannot be null")
|
|
176
219
|
|
|
177
220
|
if (!map.hasKey(key)) throw Error("Style map must contain key: $key")
|
|
@@ -186,24 +229,27 @@ class HtmlStyle {
|
|
|
186
229
|
|
|
187
230
|
val parsedMentionsStyle: MutableMap<String, MentionStyle> = mutableMapOf()
|
|
188
231
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
232
|
+
val iterator = mentionsStyle.keySetIterator()
|
|
233
|
+
while (iterator.hasNextKey()) {
|
|
234
|
+
val key = iterator.nextKey()
|
|
235
|
+
val value = mentionsStyle.getMap(key)
|
|
193
236
|
|
|
194
|
-
|
|
237
|
+
if (value == null) throw Error("Mention style for key '$key' cannot be null")
|
|
195
238
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
239
|
+
val color = parseColor(value, "color")
|
|
240
|
+
val backgroundColor = parseColorWithOpacity(value, "backgroundColor", 80)
|
|
241
|
+
val isUnderline = parseIsUnderline(value)
|
|
242
|
+
val parsedStyle = MentionStyle(color, backgroundColor, isUnderline)
|
|
243
|
+
parsedMentionsStyle.put(key, parsedStyle)
|
|
244
|
+
}
|
|
202
245
|
|
|
203
246
|
return parsedMentionsStyle
|
|
204
247
|
}
|
|
205
248
|
|
|
206
|
-
private fun parseOptionalFontWeight(
|
|
249
|
+
private fun parseOptionalFontWeight(
|
|
250
|
+
map: ReadableMap?,
|
|
251
|
+
key: String,
|
|
252
|
+
): Int? {
|
|
207
253
|
if (map == null) return null
|
|
208
254
|
if (!map.hasKey(key)) return null
|
|
209
255
|
if (map.isNull(key)) return null
|
|
@@ -212,11 +258,100 @@ class HtmlStyle {
|
|
|
212
258
|
return parseFontWeight(fontWeight)
|
|
213
259
|
}
|
|
214
260
|
|
|
261
|
+
override fun equals(other: Any?): Boolean {
|
|
262
|
+
if (this === other) return true
|
|
263
|
+
if (other !is HtmlStyle) return false
|
|
264
|
+
|
|
265
|
+
return h1FontSize == other.h1FontSize &&
|
|
266
|
+
h1Bold == other.h1Bold &&
|
|
267
|
+
h2FontSize == other.h2FontSize &&
|
|
268
|
+
h2Bold == other.h2Bold &&
|
|
269
|
+
h3FontSize == other.h3FontSize &&
|
|
270
|
+
h3Bold == other.h3Bold &&
|
|
271
|
+
h4FontSize == other.h4FontSize &&
|
|
272
|
+
h4Bold == other.h4Bold &&
|
|
273
|
+
h5FontSize == other.h5FontSize &&
|
|
274
|
+
h5Bold == other.h5Bold &&
|
|
275
|
+
h6FontSize == other.h6FontSize &&
|
|
276
|
+
h6Bold == other.h6Bold &&
|
|
277
|
+
|
|
278
|
+
blockquoteColor == other.blockquoteColor &&
|
|
279
|
+
blockquoteBorderColor == other.blockquoteBorderColor &&
|
|
280
|
+
blockquoteStripeWidth == other.blockquoteStripeWidth &&
|
|
281
|
+
blockquoteGapWidth == other.blockquoteGapWidth &&
|
|
282
|
+
|
|
283
|
+
olGapWidth == other.olGapWidth &&
|
|
284
|
+
olMarginLeft == other.olMarginLeft &&
|
|
285
|
+
olMarkerFontWeight == other.olMarkerFontWeight &&
|
|
286
|
+
olMarkerColor == other.olMarkerColor &&
|
|
287
|
+
|
|
288
|
+
ulGapWidth == other.ulGapWidth &&
|
|
289
|
+
ulMarginLeft == other.ulMarginLeft &&
|
|
290
|
+
ulBulletSize == other.ulBulletSize &&
|
|
291
|
+
ulBulletColor == other.ulBulletColor &&
|
|
292
|
+
|
|
293
|
+
aColor == other.aColor &&
|
|
294
|
+
aUnderline == other.aUnderline &&
|
|
295
|
+
|
|
296
|
+
codeBlockColor == other.codeBlockColor &&
|
|
297
|
+
codeBlockBackgroundColor == other.codeBlockBackgroundColor &&
|
|
298
|
+
codeBlockRadius == other.codeBlockRadius &&
|
|
299
|
+
|
|
300
|
+
inlineCodeColor == other.inlineCodeColor &&
|
|
301
|
+
inlineCodeBackgroundColor == other.inlineCodeBackgroundColor &&
|
|
302
|
+
|
|
303
|
+
mentionsStyle == other.mentionsStyle
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
override fun hashCode(): Int {
|
|
307
|
+
var result = h1FontSize.hashCode()
|
|
308
|
+
result = 31 * result + h1Bold.hashCode()
|
|
309
|
+
result = 31 * result + h2FontSize.hashCode()
|
|
310
|
+
result = 31 * result + h2Bold.hashCode()
|
|
311
|
+
result = 31 * result + h3FontSize.hashCode()
|
|
312
|
+
result = 31 * result + h3Bold.hashCode()
|
|
313
|
+
result = 31 * result + h4FontSize.hashCode()
|
|
314
|
+
result = 31 * result + h4Bold.hashCode()
|
|
315
|
+
result = 31 * result + h5FontSize.hashCode()
|
|
316
|
+
result = 31 * result + h5Bold.hashCode()
|
|
317
|
+
result = 31 * result + h6FontSize.hashCode()
|
|
318
|
+
result = 31 * result + h6Bold.hashCode()
|
|
319
|
+
|
|
320
|
+
result = 31 * result + (blockquoteColor ?: 0)
|
|
321
|
+
result = 31 * result + blockquoteBorderColor.hashCode()
|
|
322
|
+
result = 31 * result + blockquoteStripeWidth.hashCode()
|
|
323
|
+
result = 31 * result + blockquoteGapWidth.hashCode()
|
|
324
|
+
|
|
325
|
+
result = 31 * result + olGapWidth.hashCode()
|
|
326
|
+
result = 31 * result + olMarginLeft.hashCode()
|
|
327
|
+
result = 31 * result + (olMarkerFontWeight?.hashCode() ?: 0)
|
|
328
|
+
result = 31 * result + (olMarkerColor ?: 0)
|
|
329
|
+
|
|
330
|
+
result = 31 * result + ulGapWidth.hashCode()
|
|
331
|
+
result = 31 * result + ulMarginLeft.hashCode()
|
|
332
|
+
result = 31 * result + ulBulletSize.hashCode()
|
|
333
|
+
result = 31 * result + ulBulletColor.hashCode()
|
|
334
|
+
|
|
335
|
+
result = 31 * result + aColor.hashCode()
|
|
336
|
+
result = 31 * result + aUnderline.hashCode()
|
|
337
|
+
|
|
338
|
+
result = 31 * result + codeBlockColor.hashCode()
|
|
339
|
+
result = 31 * result + codeBlockBackgroundColor.hashCode()
|
|
340
|
+
result = 31 * result + codeBlockRadius.hashCode()
|
|
341
|
+
|
|
342
|
+
result = 31 * result + inlineCodeColor.hashCode()
|
|
343
|
+
result = 31 * result + inlineCodeBackgroundColor.hashCode()
|
|
344
|
+
|
|
345
|
+
result = 31 * result + mentionsStyle.hashCode()
|
|
346
|
+
|
|
347
|
+
return result
|
|
348
|
+
}
|
|
349
|
+
|
|
215
350
|
companion object {
|
|
216
351
|
data class MentionStyle(
|
|
217
352
|
val color: Int,
|
|
218
353
|
val backgroundColor: Int,
|
|
219
|
-
val underline: Boolean
|
|
354
|
+
val underline: Boolean,
|
|
220
355
|
)
|
|
221
356
|
}
|
|
222
357
|
}
|
|
@@ -6,8 +6,15 @@ import com.swmansion.enriched.EnrichedTextInputView
|
|
|
6
6
|
import com.swmansion.enriched.spans.EnrichedSpans
|
|
7
7
|
import com.swmansion.enriched.utils.getSafeSpanBoundaries
|
|
8
8
|
|
|
9
|
-
class InlineStyles(
|
|
10
|
-
private
|
|
9
|
+
class InlineStyles(
|
|
10
|
+
private val view: EnrichedTextInputView,
|
|
11
|
+
) {
|
|
12
|
+
private fun <T> setSpan(
|
|
13
|
+
spannable: Spannable,
|
|
14
|
+
type: Class<T>,
|
|
15
|
+
start: Int,
|
|
16
|
+
end: Int,
|
|
17
|
+
) {
|
|
11
18
|
val previousSpanStart = (start - 1).coerceAtLeast(0)
|
|
12
19
|
val previousSpanEnd = previousSpanStart + 1
|
|
13
20
|
val nextSpanStart = (end + 1).coerceAtMost(spannable.length)
|
|
@@ -37,7 +44,12 @@ class InlineStyles(private val view: EnrichedTextInputView) {
|
|
|
37
44
|
spannable.setSpan(span, safeStart, safeEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
|
38
45
|
}
|
|
39
46
|
|
|
40
|
-
private fun <T>setAndMergeSpans(
|
|
47
|
+
private fun <T> setAndMergeSpans(
|
|
48
|
+
spannable: Spannable,
|
|
49
|
+
type: Class<T>,
|
|
50
|
+
start: Int,
|
|
51
|
+
end: Int,
|
|
52
|
+
) {
|
|
41
53
|
val spans = spannable.getSpans(start, end, type)
|
|
42
54
|
|
|
43
55
|
// No spans setup for current selection, means we just need to assign new span
|
|
@@ -89,7 +101,10 @@ class InlineStyles(private val view: EnrichedTextInputView) {
|
|
|
89
101
|
}
|
|
90
102
|
}
|
|
91
103
|
|
|
92
|
-
fun afterTextChanged(
|
|
104
|
+
fun afterTextChanged(
|
|
105
|
+
s: Editable,
|
|
106
|
+
endCursorPosition: Int,
|
|
107
|
+
) {
|
|
93
108
|
for ((style, config) in EnrichedSpans.inlineSpans) {
|
|
94
109
|
val start = view.spanState?.getStart(style) ?: continue
|
|
95
110
|
var end = endCursorPosition
|
|
@@ -128,7 +143,11 @@ class InlineStyles(private val view: EnrichedTextInputView) {
|
|
|
128
143
|
view.selection.validateStyles()
|
|
129
144
|
}
|
|
130
145
|
|
|
131
|
-
fun removeStyle(
|
|
146
|
+
fun removeStyle(
|
|
147
|
+
name: String,
|
|
148
|
+
start: Int,
|
|
149
|
+
end: Int,
|
|
150
|
+
): Boolean {
|
|
132
151
|
val config = EnrichedSpans.inlineSpans[name] ?: return false
|
|
133
152
|
val spannable = view.text as Spannable
|
|
134
153
|
val spans = spannable.getSpans(start, end, config.clazz)
|
|
@@ -141,7 +160,5 @@ class InlineStyles(private val view: EnrichedTextInputView) {
|
|
|
141
160
|
return true
|
|
142
161
|
}
|
|
143
162
|
|
|
144
|
-
fun getStyleRange(): Pair<Int, Int>
|
|
145
|
-
return view.selection?.getInlineSelection() ?: Pair(0, 0)
|
|
146
|
-
}
|
|
163
|
+
fun getStyleRange(): Pair<Int, Int> = view.selection?.getInlineSelection() ?: Pair(0, 0)
|
|
147
164
|
}
|
|
@@ -8,11 +8,19 @@ import com.swmansion.enriched.EnrichedTextInputView
|
|
|
8
8
|
import com.swmansion.enriched.spans.EnrichedOrderedListSpan
|
|
9
9
|
import com.swmansion.enriched.spans.EnrichedSpans
|
|
10
10
|
import com.swmansion.enriched.spans.EnrichedUnorderedListSpan
|
|
11
|
+
import com.swmansion.enriched.utils.EnrichedConstants
|
|
11
12
|
import com.swmansion.enriched.utils.getParagraphBounds
|
|
12
13
|
import com.swmansion.enriched.utils.getSafeSpanBoundaries
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
import com.swmansion.enriched.utils.removeZWS
|
|
15
|
+
|
|
16
|
+
class ListStyles(
|
|
17
|
+
private val view: EnrichedTextInputView,
|
|
18
|
+
) {
|
|
19
|
+
private fun <T> getPreviousParagraphSpan(
|
|
20
|
+
spannable: Spannable,
|
|
21
|
+
s: Int,
|
|
22
|
+
type: Class<T>,
|
|
23
|
+
): T? {
|
|
16
24
|
if (s <= 0) return null
|
|
17
25
|
|
|
18
26
|
val (previousParagraphStart, previousParagraphEnd) = spannable.getParagraphBounds(s - 1)
|
|
@@ -25,19 +33,31 @@ class ListStyles(private val view: EnrichedTextInputView) {
|
|
|
25
33
|
return null
|
|
26
34
|
}
|
|
27
35
|
|
|
28
|
-
private fun <T>isPreviousParagraphList(
|
|
36
|
+
private fun <T> isPreviousParagraphList(
|
|
37
|
+
spannable: Spannable,
|
|
38
|
+
s: Int,
|
|
39
|
+
type: Class<T>,
|
|
40
|
+
): Boolean {
|
|
29
41
|
val previousSpan = getPreviousParagraphSpan(spannable, s, type)
|
|
30
42
|
|
|
31
43
|
return previousSpan != null
|
|
32
44
|
}
|
|
33
45
|
|
|
34
|
-
private fun getOrderedListIndex(
|
|
46
|
+
private fun getOrderedListIndex(
|
|
47
|
+
spannable: Spannable,
|
|
48
|
+
s: Int,
|
|
49
|
+
): Int {
|
|
35
50
|
val span = getPreviousParagraphSpan(spannable, s, EnrichedOrderedListSpan::class.java)
|
|
36
51
|
val index = span?.getIndex() ?: 0
|
|
37
52
|
return index + 1
|
|
38
53
|
}
|
|
39
54
|
|
|
40
|
-
private fun setSpan(
|
|
55
|
+
private fun setSpan(
|
|
56
|
+
spannable: Spannable,
|
|
57
|
+
name: String,
|
|
58
|
+
start: Int,
|
|
59
|
+
end: Int,
|
|
60
|
+
) {
|
|
41
61
|
val (safeStart, safeEnd) = spannable.getSafeSpanBoundaries(start, end)
|
|
42
62
|
|
|
43
63
|
if (name == EnrichedSpans.UNORDERED_LIST) {
|
|
@@ -53,7 +73,12 @@ class ListStyles(private val view: EnrichedTextInputView) {
|
|
|
53
73
|
}
|
|
54
74
|
}
|
|
55
75
|
|
|
56
|
-
private fun <T>removeSpansForRange(
|
|
76
|
+
private fun <T> removeSpansForRange(
|
|
77
|
+
spannable: Spannable,
|
|
78
|
+
start: Int,
|
|
79
|
+
end: Int,
|
|
80
|
+
clazz: Class<T>,
|
|
81
|
+
): Boolean {
|
|
57
82
|
val ssb = spannable as SpannableStringBuilder
|
|
58
83
|
val spans = ssb.getSpans(start, end, clazz)
|
|
59
84
|
if (spans.isEmpty()) return false
|
|
@@ -62,13 +87,17 @@ class ListStyles(private val view: EnrichedTextInputView) {
|
|
|
62
87
|
ssb.removeSpan(span)
|
|
63
88
|
}
|
|
64
89
|
|
|
65
|
-
ssb.
|
|
90
|
+
ssb.removeZWS(start, end)
|
|
66
91
|
return true
|
|
67
92
|
}
|
|
68
93
|
|
|
69
|
-
fun updateOrderedListIndexes(
|
|
94
|
+
fun updateOrderedListIndexes(
|
|
95
|
+
text: Spannable,
|
|
96
|
+
position: Int,
|
|
97
|
+
) {
|
|
70
98
|
val spans = text.getSpans(position + 1, text.length, EnrichedOrderedListSpan::class.java)
|
|
71
|
-
|
|
99
|
+
val sortedSpans = spans.sortedBy { text.getSpanStart(it) }
|
|
100
|
+
for (span in sortedSpans) {
|
|
72
101
|
val spanStart = text.getSpanStart(span)
|
|
73
102
|
val index = getOrderedListIndex(text, spanStart)
|
|
74
103
|
span.setIndex(index)
|
|
@@ -91,7 +120,7 @@ class ListStyles(private val view: EnrichedTextInputView) {
|
|
|
91
120
|
}
|
|
92
121
|
|
|
93
122
|
if (start == end) {
|
|
94
|
-
spannable.insert(start,
|
|
123
|
+
spannable.insert(start, EnrichedConstants.ZWS_STRING)
|
|
95
124
|
view.spanState?.setStart(name, start + 1)
|
|
96
125
|
removeSpansForRange(spannable, start, end, config.clazz)
|
|
97
126
|
setSpan(spannable, name, start, end + 1)
|
|
@@ -104,7 +133,7 @@ class ListStyles(private val view: EnrichedTextInputView) {
|
|
|
104
133
|
removeSpansForRange(spannable, start, end, config.clazz)
|
|
105
134
|
|
|
106
135
|
for (paragraph in paragraphs) {
|
|
107
|
-
spannable.insert(currentStart,
|
|
136
|
+
spannable.insert(currentStart, EnrichedConstants.ZWS_STRING)
|
|
108
137
|
val currentEnd = currentStart + paragraph.length + 1
|
|
109
138
|
setSpan(spannable, name, currentStart, currentEnd)
|
|
110
139
|
|
|
@@ -114,7 +143,12 @@ class ListStyles(private val view: EnrichedTextInputView) {
|
|
|
114
143
|
view.spanState?.setStart(name, currentStart)
|
|
115
144
|
}
|
|
116
145
|
|
|
117
|
-
private fun handleAfterTextChanged(
|
|
146
|
+
private fun handleAfterTextChanged(
|
|
147
|
+
s: Editable,
|
|
148
|
+
name: String,
|
|
149
|
+
endCursorPosition: Int,
|
|
150
|
+
previousTextLength: Int,
|
|
151
|
+
) {
|
|
118
152
|
val config = EnrichedSpans.listSpans[name] ?: return
|
|
119
153
|
val cursorPosition = endCursorPosition.coerceAtMost(s.length)
|
|
120
154
|
val (start, end) = s.getParagraphBounds(cursorPosition)
|
|
@@ -131,7 +165,7 @@ class ListStyles(private val view: EnrichedTextInputView) {
|
|
|
131
165
|
}
|
|
132
166
|
|
|
133
167
|
if (!isBackspace && isShortcut) {
|
|
134
|
-
s.replace(start, cursorPosition,
|
|
168
|
+
s.replace(start, cursorPosition, EnrichedConstants.ZWS_STRING)
|
|
135
169
|
setSpan(s, name, start, start + 1)
|
|
136
170
|
// Inform that new span has been added
|
|
137
171
|
view.selection?.validateStyles()
|
|
@@ -139,7 +173,7 @@ class ListStyles(private val view: EnrichedTextInputView) {
|
|
|
139
173
|
}
|
|
140
174
|
|
|
141
175
|
if (!isBackspace && isNewLine && isPreviousParagraphList(s, start, config.clazz)) {
|
|
142
|
-
s.insert(cursorPosition,
|
|
176
|
+
s.insert(cursorPosition, EnrichedConstants.ZWS_STRING)
|
|
143
177
|
setSpan(s, name, start, end + 1)
|
|
144
178
|
// Inform that new span has been added
|
|
145
179
|
view.selection?.validateStyles()
|
|
@@ -155,16 +189,22 @@ class ListStyles(private val view: EnrichedTextInputView) {
|
|
|
155
189
|
}
|
|
156
190
|
}
|
|
157
191
|
|
|
158
|
-
fun afterTextChanged(
|
|
192
|
+
fun afterTextChanged(
|
|
193
|
+
s: Editable,
|
|
194
|
+
endCursorPosition: Int,
|
|
195
|
+
previousTextLength: Int,
|
|
196
|
+
) {
|
|
159
197
|
handleAfterTextChanged(s, EnrichedSpans.ORDERED_LIST, endCursorPosition, previousTextLength)
|
|
160
198
|
handleAfterTextChanged(s, EnrichedSpans.UNORDERED_LIST, endCursorPosition, previousTextLength)
|
|
161
199
|
}
|
|
162
200
|
|
|
163
|
-
fun getStyleRange(): Pair<Int, Int>
|
|
164
|
-
return view.selection?.getParagraphSelection() ?: Pair(0, 0)
|
|
165
|
-
}
|
|
201
|
+
fun getStyleRange(): Pair<Int, Int> = view.selection?.getParagraphSelection() ?: Pair(0, 0)
|
|
166
202
|
|
|
167
|
-
fun removeStyle(
|
|
203
|
+
fun removeStyle(
|
|
204
|
+
name: String,
|
|
205
|
+
start: Int,
|
|
206
|
+
end: Int,
|
|
207
|
+
): Boolean {
|
|
168
208
|
val config = EnrichedSpans.listSpans[name] ?: return false
|
|
169
209
|
val spannable = view.text as Spannable
|
|
170
210
|
return removeSpansForRange(spannable, start, end, config.clazz)
|