react-native-enriched 0.2.0 → 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 +1 -5
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerDelegate.java +3 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerInterface.java +1 -0
- 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/src/main/java/com/swmansion/enriched/EnrichedTextInputView.kt +92 -0
- package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewManager.kt +6 -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 +6 -0
- 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 +5 -0
- 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 +9 -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/styles/HtmlStyle.kt +78 -0
- package/android/src/main/java/com/swmansion/enriched/styles/ParagraphStyles.kt +80 -4
- package/android/src/main/java/com/swmansion/enriched/utils/EnrichedParser.java +8 -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/ios/EnrichedTextInputView.h +25 -13
- package/ios/EnrichedTextInputView.mm +872 -581
- 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 +6 -6
- package/ios/config/InputConfig.mm +39 -33
- package/ios/generated/RNEnrichedTextInputViewSpec/EventEmitters.cpp +10 -0
- package/ios/generated/RNEnrichedTextInputViewSpec/EventEmitters.h +7 -0
- package/ios/generated/RNEnrichedTextInputViewSpec/RCTComponentViewHelpers.h +21 -0
- package/ios/inputParser/InputParser.h +5 -5
- package/ios/inputParser/InputParser.mm +789 -378
- 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 -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 +95 -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/HeadingStyleBase.mm +129 -84
- package/ios/styles/ImageStyle.mm +75 -73
- package/ios/styles/InlineCodeStyle.mm +148 -85
- package/ios/styles/ItalicStyle.mm +76 -52
- package/ios/styles/LinkStyle.mm +348 -227
- 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/BaseStyleProtocol.h +2 -2
- package/ios/utils/ColorExtension.mm +7 -5
- package/ios/utils/FontExtension.mm +42 -27
- package/ios/utils/LayoutManagerExtension.h +1 -1
- package/ios/utils/LayoutManagerExtension.mm +280 -170
- 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 -42
- package/ios/utils/OccurenceUtils.mm +142 -119
- package/ios/utils/ParagraphAttributesUtils.h +6 -2
- package/ios/utils/ParagraphAttributesUtils.mm +115 -71
- 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 +27 -15
- 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 +39 -1
- package/lib/module/EnrichedTextInput.js.map +1 -1
- package/lib/module/EnrichedTextInputNativeComponent.ts +11 -0
- package/lib/typescript/src/EnrichedTextInput.d.ts +1 -0
- package/lib/typescript/src/EnrichedTextInput.d.ts.map +1 -1
- package/lib/typescript/src/EnrichedTextInputNativeComponent.d.ts +6 -0
- package/lib/typescript/src/EnrichedTextInputNativeComponent.d.ts.map +1 -1
- package/package.json +8 -1
- package/src/EnrichedTextInput.tsx +45 -0
- package/src/EnrichedTextInputNativeComponent.ts +11 -0
package/README.md
CHANGED
|
@@ -40,7 +40,7 @@ We can help you build your next dream product –
|
|
|
40
40
|
## Prerequisites
|
|
41
41
|
|
|
42
42
|
- `react-native-enriched` currently supports only Android and iOS platforms
|
|
43
|
-
- It works only with [the React Native New Architecture (Fabric)](https://reactnative.dev/architecture/landing-page) and supports following React Native releases: `0.79`, `0.80`, `0.81` and `0.
|
|
43
|
+
- It works only with [the React Native New Architecture (Fabric)](https://reactnative.dev/architecture/landing-page) and supports following React Native releases: `0.79`, `0.80`, `0.81`, `0.82` and `0.83`
|
|
44
44
|
|
|
45
45
|
## Installation
|
|
46
46
|
|
|
@@ -238,14 +238,10 @@ See the [API Reference](docs/API_REFERENCE.md) for a detailed overview of all th
|
|
|
238
238
|
## Known limitations
|
|
239
239
|
|
|
240
240
|
- Only one level of lists is supported. We currently do not support nested lists.
|
|
241
|
-
- Inline images are supported only on Android.
|
|
242
|
-
- Codeblocks are supported only on Android.
|
|
243
241
|
- iOS headings can't have the same `fontSize` in their config as input's `fontSize`. Doing so results in incorrect headings behavior.
|
|
244
242
|
|
|
245
243
|
## Future Plans
|
|
246
244
|
|
|
247
|
-
- Adding Codeblocks and Inline Images to iOS input.
|
|
248
|
-
- Making some optimizations around `onChangeHtml` event, maybe some imperative API to get the HTML output.
|
|
249
245
|
- Creating `EnrichedText` text component that supports our HTML output format with all additional interactions like pressing links or mentions.
|
|
250
246
|
- Adding API for custom link detection regex.
|
|
251
247
|
- Web library implementation via `react-native-web`.
|
|
@@ -144,6 +144,9 @@ public class EnrichedTextInputViewManagerDelegate<T extends View, U extends Base
|
|
|
144
144
|
case "addMention":
|
|
145
145
|
mViewManager.addMention(view, args.getString(0), args.getString(1), args.getString(2));
|
|
146
146
|
break;
|
|
147
|
+
case "requestHTML":
|
|
148
|
+
mViewManager.requestHTML(view, args.getInt(0));
|
|
149
|
+
break;
|
|
147
150
|
}
|
|
148
151
|
}
|
|
149
152
|
}
|
|
@@ -53,4 +53,5 @@ public interface EnrichedTextInputViewManagerInterface<T extends View> extends V
|
|
|
53
53
|
void addImage(T view, String uri, float width, float height);
|
|
54
54
|
void startMention(T view, String indicator);
|
|
55
55
|
void addMention(T view, String indicator, String text, String payload);
|
|
56
|
+
void requestHTML(T view, int requestId);
|
|
56
57
|
}
|
|
@@ -115,4 +115,14 @@ payload.setProperty(runtime, "text", event.text);
|
|
|
115
115
|
});
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
+
|
|
119
|
+
void EnrichedTextInputViewEventEmitter::onRequestHtmlResult(OnRequestHtmlResult event) const {
|
|
120
|
+
dispatchEvent("requestHtmlResult", [event=std::move(event)](jsi::Runtime &runtime) {
|
|
121
|
+
auto payload = jsi::Object(runtime);
|
|
122
|
+
payload.setProperty(runtime, "requestId", event.requestId);
|
|
123
|
+
payload.setProperty(runtime, "html", jsi::valueFromDynamic(runtime, event.html));
|
|
124
|
+
return payload;
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
118
128
|
} // namespace facebook::react
|
package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/EventEmitters.h
CHANGED
|
@@ -74,6 +74,11 @@ class EnrichedTextInputViewEventEmitter : public ViewEventEmitter {
|
|
|
74
74
|
int end;
|
|
75
75
|
std::string text;
|
|
76
76
|
};
|
|
77
|
+
|
|
78
|
+
struct OnRequestHtmlResult {
|
|
79
|
+
int requestId;
|
|
80
|
+
folly::dynamic html;
|
|
81
|
+
};
|
|
77
82
|
void onInputFocus(OnInputFocus value) const;
|
|
78
83
|
|
|
79
84
|
void onInputBlur(OnInputBlur value) const;
|
|
@@ -91,5 +96,7 @@ class EnrichedTextInputViewEventEmitter : public ViewEventEmitter {
|
|
|
91
96
|
void onMention(OnMention value) const;
|
|
92
97
|
|
|
93
98
|
void onChangeSelection(OnChangeSelection value) const;
|
|
99
|
+
|
|
100
|
+
void onRequestHtmlResult(OnRequestHtmlResult value) const;
|
|
94
101
|
};
|
|
95
102
|
} // namespace facebook::react
|
|
@@ -29,8 +29,13 @@ import com.facebook.react.views.text.ReactTypefaceUtils.parseFontWeight
|
|
|
29
29
|
import com.swmansion.enriched.events.MentionHandler
|
|
30
30
|
import com.swmansion.enriched.events.OnInputBlurEvent
|
|
31
31
|
import com.swmansion.enriched.events.OnInputFocusEvent
|
|
32
|
+
import com.swmansion.enriched.events.OnRequestHtmlResultEvent
|
|
33
|
+
import com.swmansion.enriched.spans.EnrichedH1Span
|
|
34
|
+
import com.swmansion.enriched.spans.EnrichedH2Span
|
|
35
|
+
import com.swmansion.enriched.spans.EnrichedH3Span
|
|
32
36
|
import com.swmansion.enriched.spans.EnrichedImageSpan
|
|
33
37
|
import com.swmansion.enriched.spans.EnrichedSpans
|
|
38
|
+
import com.swmansion.enriched.spans.interfaces.EnrichedSpan
|
|
34
39
|
import com.swmansion.enriched.styles.InlineStyles
|
|
35
40
|
import com.swmansion.enriched.styles.ListStyles
|
|
36
41
|
import com.swmansion.enriched.styles.ParagraphStyles
|
|
@@ -59,6 +64,13 @@ class EnrichedTextInputView : AppCompatEditText {
|
|
|
59
64
|
|
|
60
65
|
val mentionHandler: MentionHandler? = MentionHandler(this)
|
|
61
66
|
var htmlStyle: HtmlStyle = HtmlStyle(this, null)
|
|
67
|
+
set(value) {
|
|
68
|
+
if (field != value) {
|
|
69
|
+
val prev = field
|
|
70
|
+
field = value
|
|
71
|
+
reApplyHtmlStyleForSpans(prev, value)
|
|
72
|
+
}
|
|
73
|
+
}
|
|
62
74
|
var spanWatcher: EnrichedSpanWatcher? = null
|
|
63
75
|
var layoutManager: EnrichedTextInputViewLayoutManager = EnrichedTextInputViewLayoutManager(this)
|
|
64
76
|
|
|
@@ -335,6 +347,7 @@ class EnrichedTextInputView : AppCompatEditText {
|
|
|
335
347
|
// This ensured that newly created spans will take the new font size into account
|
|
336
348
|
htmlStyle.invalidateStyles()
|
|
337
349
|
layoutManager.invalidateLayout()
|
|
350
|
+
forceScrollToSelection()
|
|
338
351
|
}
|
|
339
352
|
|
|
340
353
|
fun setFontFamily(family: String?) {
|
|
@@ -566,6 +579,19 @@ class EnrichedTextInputView : AppCompatEditText {
|
|
|
566
579
|
parametrizedStyles?.setMentionSpan(text, indicator, attributes)
|
|
567
580
|
}
|
|
568
581
|
|
|
582
|
+
fun requestHTML(requestId: Int) {
|
|
583
|
+
val html = try {
|
|
584
|
+
EnrichedParser.toHtmlWithDefault(text)
|
|
585
|
+
} catch (e: Exception) {
|
|
586
|
+
null
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
val reactContext = context as ReactContext
|
|
590
|
+
val surfaceId = UIManagerHelper.getSurfaceId(reactContext)
|
|
591
|
+
val dispatcher = UIManagerHelper.getEventDispatcherForReactTag(reactContext, id)
|
|
592
|
+
dispatcher?.dispatchEvent(OnRequestHtmlResultEvent(surfaceId, id, requestId, html, experimentalSynchronousEvents))
|
|
593
|
+
}
|
|
594
|
+
|
|
569
595
|
// Sometimes setting up style triggers many changes in sequence
|
|
570
596
|
// Eg. removing conflicting styles -> changing text -> applying spans
|
|
571
597
|
// In such scenario we want to prevent from handling side effects (eg. onTextChanged)
|
|
@@ -578,6 +604,72 @@ class EnrichedTextInputView : AppCompatEditText {
|
|
|
578
604
|
}
|
|
579
605
|
}
|
|
580
606
|
|
|
607
|
+
private fun forceScrollToSelection() {
|
|
608
|
+
val textLayout = layout ?: return
|
|
609
|
+
val cursorOffset = selectionStart
|
|
610
|
+
if (cursorOffset <= 0) return
|
|
611
|
+
|
|
612
|
+
val selectedLineIndex = textLayout.getLineForOffset(cursorOffset)
|
|
613
|
+
val selectedLineTop = textLayout.getLineTop(selectedLineIndex)
|
|
614
|
+
val selectedLineBottom = textLayout.getLineBottom(selectedLineIndex)
|
|
615
|
+
val visibleTextHeight = height - paddingTop - paddingBottom
|
|
616
|
+
|
|
617
|
+
if (visibleTextHeight <= 0) return
|
|
618
|
+
|
|
619
|
+
val visibleTop = scrollY
|
|
620
|
+
val visibleBottom = scrollY + visibleTextHeight
|
|
621
|
+
var targetScrollY = scrollY
|
|
622
|
+
|
|
623
|
+
if (selectedLineTop < visibleTop) {
|
|
624
|
+
targetScrollY = selectedLineTop
|
|
625
|
+
} else if (selectedLineBottom > visibleBottom) {
|
|
626
|
+
targetScrollY = selectedLineBottom - visibleTextHeight
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
val maxScrollY = (textLayout.height - visibleTextHeight).coerceAtLeast(0)
|
|
630
|
+
targetScrollY = targetScrollY.coerceIn(0, maxScrollY)
|
|
631
|
+
scrollTo(scrollX, targetScrollY)
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
private fun reApplyHtmlStyleForSpans(previousHtmlStyle: HtmlStyle, nextHtmlStyle: HtmlStyle) {
|
|
635
|
+
val shouldRemoveBoldSpanFromH1Span = !previousHtmlStyle.h1Bold && nextHtmlStyle.h1Bold
|
|
636
|
+
val shouldRemoveBoldSpanFromH2Span = !previousHtmlStyle.h2Bold && nextHtmlStyle.h2Bold
|
|
637
|
+
val shouldRemoveBoldSpanFromH3Span = !previousHtmlStyle.h3Bold && nextHtmlStyle.h3Bold
|
|
638
|
+
|
|
639
|
+
val spannable = text as? Spannable ?: return
|
|
640
|
+
if (spannable.isEmpty()) return
|
|
641
|
+
|
|
642
|
+
var shouldEmitStateChange = false
|
|
643
|
+
|
|
644
|
+
runAsATransaction {
|
|
645
|
+
val spans = spannable.getSpans(0, spannable.length, EnrichedSpan::class.java)
|
|
646
|
+
for (span in spans) {
|
|
647
|
+
if (!span.dependsOnHtmlStyle) continue
|
|
648
|
+
|
|
649
|
+
val start = spannable.getSpanStart(span)
|
|
650
|
+
val end = spannable.getSpanEnd(span)
|
|
651
|
+
val flags = spannable.getSpanFlags(span)
|
|
652
|
+
|
|
653
|
+
if (start == -1 || end == -1) continue
|
|
654
|
+
|
|
655
|
+
if ((span is EnrichedH1Span && shouldRemoveBoldSpanFromH1Span) || (span is EnrichedH2Span && shouldRemoveBoldSpanFromH2Span) || (span is EnrichedH3Span && shouldRemoveBoldSpanFromH3Span)) {
|
|
656
|
+
val isRemoved = removeStyle(EnrichedSpans.BOLD, start, end)
|
|
657
|
+
if (isRemoved) shouldEmitStateChange = true
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
spannable.removeSpan(span)
|
|
661
|
+
val newSpan = span.rebuildWithStyle(htmlStyle)
|
|
662
|
+
spannable.setSpan(newSpan, start, end, flags)
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
if (shouldEmitStateChange) {
|
|
666
|
+
selection?.validateStyles()
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
layoutManager.invalidateLayout()
|
|
670
|
+
forceScrollToSelection()
|
|
671
|
+
}
|
|
672
|
+
|
|
581
673
|
override fun onAttachedToWindow() {
|
|
582
674
|
super.onAttachedToWindow()
|
|
583
675
|
|
|
@@ -24,6 +24,7 @@ import com.swmansion.enriched.events.OnInputFocusEvent
|
|
|
24
24
|
import com.swmansion.enriched.events.OnLinkDetectedEvent
|
|
25
25
|
import com.swmansion.enriched.events.OnMentionDetectedEvent
|
|
26
26
|
import com.swmansion.enriched.events.OnMentionEvent
|
|
27
|
+
import com.swmansion.enriched.events.OnRequestHtmlResultEvent
|
|
27
28
|
import com.swmansion.enriched.spans.EnrichedSpans
|
|
28
29
|
import com.swmansion.enriched.styles.HtmlStyle
|
|
29
30
|
import com.swmansion.enriched.utils.jsonStringToStringMap
|
|
@@ -71,6 +72,7 @@ class EnrichedTextInputViewManager : SimpleViewManager<EnrichedTextInputView>(),
|
|
|
71
72
|
map.put(OnMentionDetectedEvent.EVENT_NAME, mapOf("registrationName" to OnMentionDetectedEvent.EVENT_NAME))
|
|
72
73
|
map.put(OnMentionEvent.EVENT_NAME, mapOf("registrationName" to OnMentionEvent.EVENT_NAME))
|
|
73
74
|
map.put(OnChangeSelectionEvent.EVENT_NAME, mapOf("registrationName" to OnChangeSelectionEvent.EVENT_NAME))
|
|
75
|
+
map.put(OnRequestHtmlResultEvent.EVENT_NAME, mapOf("registrationName" to OnRequestHtmlResultEvent.EVENT_NAME))
|
|
74
76
|
|
|
75
77
|
return map
|
|
76
78
|
}
|
|
@@ -268,6 +270,10 @@ class EnrichedTextInputViewManager : SimpleViewManager<EnrichedTextInputView>(),
|
|
|
268
270
|
view?.addMention(text, indicator, attributes)
|
|
269
271
|
}
|
|
270
272
|
|
|
273
|
+
override fun requestHTML(view: EnrichedTextInputView?, requestId: Int) {
|
|
274
|
+
view?.requestHTML(requestId)
|
|
275
|
+
}
|
|
276
|
+
|
|
271
277
|
override fun measure(
|
|
272
278
|
context: Context,
|
|
273
279
|
localData: ReadableMap?,
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
package com.swmansion.enriched.events
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.Arguments
|
|
4
|
+
import com.facebook.react.bridge.WritableMap
|
|
5
|
+
import com.facebook.react.uimanager.events.Event
|
|
6
|
+
|
|
7
|
+
class OnRequestHtmlResultEvent(
|
|
8
|
+
surfaceId: Int,
|
|
9
|
+
viewId: Int,
|
|
10
|
+
private val requestId: Int,
|
|
11
|
+
private val html: String?,
|
|
12
|
+
private val experimentalSynchronousEvents: Boolean
|
|
13
|
+
) : Event<OnRequestHtmlResultEvent>(surfaceId, viewId) {
|
|
14
|
+
|
|
15
|
+
override fun getEventName(): String = EVENT_NAME
|
|
16
|
+
|
|
17
|
+
override fun getEventData(): WritableMap {
|
|
18
|
+
val eventData: WritableMap = Arguments.createMap()
|
|
19
|
+
eventData.putInt("requestId", requestId)
|
|
20
|
+
if (html != null) {
|
|
21
|
+
eventData.putString("html", html)
|
|
22
|
+
} else {
|
|
23
|
+
eventData.putNull("html")
|
|
24
|
+
}
|
|
25
|
+
return eventData
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
override fun experimental_isSynchronous(): Boolean = experimentalSynchronousEvents
|
|
29
|
+
|
|
30
|
+
companion object {
|
|
31
|
+
const val EVENT_NAME: String = "onRequestHtmlResult"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -11,6 +11,8 @@ import com.swmansion.enriched.styles.HtmlStyle
|
|
|
11
11
|
|
|
12
12
|
// https://android.googlesource.com/platform/frameworks/base/+/refs/heads/main/core/java/android/text/style/QuoteSpan.java
|
|
13
13
|
class EnrichedBlockQuoteSpan(private val htmlStyle: HtmlStyle) : MetricAffectingSpan(), LeadingMarginSpan, EnrichedBlockSpan {
|
|
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
|
}
|
|
@@ -35,4 +37,8 @@ class EnrichedBlockQuoteSpan(private val htmlStyle: HtmlStyle) : MetricAffecting
|
|
|
35
37
|
textPaint?.color = color
|
|
36
38
|
}
|
|
37
39
|
}
|
|
40
|
+
|
|
41
|
+
override fun rebuildWithStyle(htmlStyle: HtmlStyle): EnrichedBlockQuoteSpan {
|
|
42
|
+
return EnrichedBlockQuoteSpan(htmlStyle)
|
|
43
|
+
}
|
|
38
44
|
}
|
|
@@ -2,9 +2,15 @@ package com.swmansion.enriched.spans
|
|
|
2
2
|
|
|
3
3
|
import android.graphics.Typeface
|
|
4
4
|
import android.text.style.StyleSpan
|
|
5
|
+
import com.swmansion.enriched.spans.interfaces.EnrichedBlockSpan
|
|
5
6
|
import com.swmansion.enriched.spans.interfaces.EnrichedInlineSpan
|
|
6
7
|
import com.swmansion.enriched.styles.HtmlStyle
|
|
7
8
|
|
|
8
9
|
@Suppress("UNUSED_PARAMETER")
|
|
9
10
|
class EnrichedBoldSpan(htmlStyle: HtmlStyle) : StyleSpan(Typeface.BOLD), EnrichedInlineSpan {
|
|
11
|
+
override val dependsOnHtmlStyle: Boolean = false
|
|
12
|
+
|
|
13
|
+
override fun rebuildWithStyle(htmlStyle: HtmlStyle): EnrichedBoldSpan {
|
|
14
|
+
return EnrichedBoldSpan(htmlStyle)
|
|
15
|
+
}
|
|
10
16
|
}
|
|
@@ -13,6 +13,8 @@ import com.swmansion.enriched.spans.interfaces.EnrichedBlockSpan
|
|
|
13
13
|
import com.swmansion.enriched.styles.HtmlStyle
|
|
14
14
|
|
|
15
15
|
class EnrichedCodeBlockSpan(private val htmlStyle: HtmlStyle) : MetricAffectingSpan(), LineBackgroundSpan, EnrichedBlockSpan {
|
|
16
|
+
override val dependsOnHtmlStyle: Boolean = true
|
|
17
|
+
|
|
16
18
|
override fun updateDrawState(paint: TextPaint) {
|
|
17
19
|
paint.typeface = Typeface.MONOSPACE
|
|
18
20
|
paint.color = htmlStyle.codeBlockColor
|
|
@@ -74,4 +76,8 @@ class EnrichedCodeBlockSpan(private val htmlStyle: HtmlStyle) : MetricAffectingS
|
|
|
74
76
|
canvas.drawPath(path, p)
|
|
75
77
|
p.color = previousColor
|
|
76
78
|
}
|
|
79
|
+
|
|
80
|
+
override fun rebuildWithStyle(htmlStyle: HtmlStyle): EnrichedCodeBlockSpan {
|
|
81
|
+
return EnrichedCodeBlockSpan(htmlStyle)
|
|
82
|
+
}
|
|
77
83
|
}
|
|
@@ -7,6 +7,8 @@ import com.swmansion.enriched.spans.interfaces.EnrichedHeadingSpan
|
|
|
7
7
|
import com.swmansion.enriched.styles.HtmlStyle
|
|
8
8
|
|
|
9
9
|
class EnrichedH1Span(private val style: HtmlStyle) : AbsoluteSizeSpan(style.h1FontSize), EnrichedHeadingSpan {
|
|
10
|
+
override val dependsOnHtmlStyle: Boolean = true
|
|
11
|
+
|
|
10
12
|
override fun updateDrawState(tp: TextPaint) {
|
|
11
13
|
super.updateDrawState(tp)
|
|
12
14
|
val bold = style.h1Bold
|
|
@@ -14,4 +16,8 @@ class EnrichedH1Span(private val style: HtmlStyle) : AbsoluteSizeSpan(style.h1Fo
|
|
|
14
16
|
tp.typeface = Typeface.create(tp.typeface, Typeface.BOLD)
|
|
15
17
|
}
|
|
16
18
|
}
|
|
19
|
+
|
|
20
|
+
override fun rebuildWithStyle(htmlStyle: HtmlStyle): EnrichedH1Span {
|
|
21
|
+
return EnrichedH1Span(htmlStyle)
|
|
22
|
+
}
|
|
17
23
|
}
|
|
@@ -7,6 +7,8 @@ import com.swmansion.enriched.spans.interfaces.EnrichedHeadingSpan
|
|
|
7
7
|
import com.swmansion.enriched.styles.HtmlStyle
|
|
8
8
|
|
|
9
9
|
class EnrichedH2Span(private val htmlStyle: HtmlStyle) : AbsoluteSizeSpan(htmlStyle.h2FontSize), EnrichedHeadingSpan {
|
|
10
|
+
override val dependsOnHtmlStyle: Boolean = true
|
|
11
|
+
|
|
10
12
|
override fun updateDrawState(tp: TextPaint) {
|
|
11
13
|
super.updateDrawState(tp)
|
|
12
14
|
val bold = htmlStyle.h2Bold
|
|
@@ -14,4 +16,8 @@ class EnrichedH2Span(private val htmlStyle: HtmlStyle) : AbsoluteSizeSpan(htmlSt
|
|
|
14
16
|
tp.typeface = Typeface.create(tp.typeface, Typeface.BOLD)
|
|
15
17
|
}
|
|
16
18
|
}
|
|
19
|
+
|
|
20
|
+
override fun rebuildWithStyle(htmlStyle: HtmlStyle): EnrichedH2Span {
|
|
21
|
+
return EnrichedH2Span(htmlStyle)
|
|
22
|
+
}
|
|
17
23
|
}
|
|
@@ -7,6 +7,8 @@ import com.swmansion.enriched.spans.interfaces.EnrichedHeadingSpan
|
|
|
7
7
|
import com.swmansion.enriched.styles.HtmlStyle
|
|
8
8
|
|
|
9
9
|
class EnrichedH3Span(private val htmlStyle: HtmlStyle) : AbsoluteSizeSpan(htmlStyle.h3FontSize), EnrichedHeadingSpan {
|
|
10
|
+
override val dependsOnHtmlStyle: Boolean = true
|
|
11
|
+
|
|
10
12
|
override fun updateDrawState(tp: TextPaint) {
|
|
11
13
|
super.updateDrawState(tp)
|
|
12
14
|
val bold = htmlStyle.h3Bold
|
|
@@ -14,4 +16,8 @@ class EnrichedH3Span(private val htmlStyle: HtmlStyle) : AbsoluteSizeSpan(htmlSt
|
|
|
14
16
|
tp.typeface = Typeface.create(tp.typeface, Typeface.BOLD)
|
|
15
17
|
}
|
|
16
18
|
}
|
|
19
|
+
|
|
20
|
+
override fun rebuildWithStyle(htmlStyle: HtmlStyle): EnrichedH3Span {
|
|
21
|
+
return EnrichedH3Span(htmlStyle)
|
|
22
|
+
}
|
|
17
23
|
}
|
|
@@ -18,9 +18,12 @@ import com.swmansion.enriched.utils.AsyncDrawable
|
|
|
18
18
|
import androidx.core.graphics.drawable.toDrawable
|
|
19
19
|
import com.swmansion.enriched.R
|
|
20
20
|
import com.swmansion.enriched.spans.utils.ForceRedrawSpan
|
|
21
|
+
import com.swmansion.enriched.styles.HtmlStyle
|
|
21
22
|
import com.swmansion.enriched.utils.ResourceManager
|
|
22
23
|
|
|
23
24
|
class EnrichedImageSpan : ImageSpan, EnrichedInlineSpan {
|
|
25
|
+
override val dependsOnHtmlStyle: Boolean = false
|
|
26
|
+
|
|
24
27
|
private var width: Int = 0
|
|
25
28
|
private var height: Int = 0
|
|
26
29
|
|
|
@@ -119,6 +122,8 @@ class EnrichedImageSpan : ImageSpan, EnrichedInlineSpan {
|
|
|
119
122
|
return height
|
|
120
123
|
}
|
|
121
124
|
|
|
125
|
+
override fun rebuildWithStyle(htmlStyle: HtmlStyle): EnrichedImageSpan = this
|
|
126
|
+
|
|
122
127
|
companion object {
|
|
123
128
|
fun createEnrichedImageSpan(src: String, width: Int, height: Int): EnrichedImageSpan {
|
|
124
129
|
var imgDrawable = prepareDrawableForImage(src)
|
|
@@ -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 -> {
|
|
@@ -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
|
}
|
|
@@ -212,6 +212,84 @@ class HtmlStyle {
|
|
|
212
212
|
return parseFontWeight(fontWeight)
|
|
213
213
|
}
|
|
214
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
|
+
|
|
215
293
|
companion object {
|
|
216
294
|
data class MentionStyle(
|
|
217
295
|
val color: Int,
|