@mathers101/react-native-render-rich-text 0.1.9 → 0.1.14
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 -20
- package/README.md +140 -140
- package/ReactNativeRenderRichText.podspec +23 -23
- package/android/build.gradle +86 -86
- package/android/consumer-rules.pro +3 -3
- package/android/src/main/AndroidManifest.xml +2 -2
- package/android/src/main/java/com/renderrichtext/EnrichedTiptapTextLayoutManager.kt +24 -24
- package/android/src/main/java/com/renderrichtext/EnrichedTiptapTextPackage.kt +13 -13
- package/android/src/main/java/com/renderrichtext/MeasurementStore.kt +644 -644
- package/android/src/main/java/com/renderrichtext/accessibility/AccessibilityLabels.kt +17 -17
- package/android/src/main/java/com/renderrichtext/accessibility/AccessibleTiptapTextView.kt +112 -112
- package/android/src/main/java/com/renderrichtext/accessibility/TiptapAccessibilityHelper.kt +576 -576
- package/android/src/main/java/com/renderrichtext/events/CodeBlockPressEvent.kt +24 -24
- package/android/src/main/java/com/renderrichtext/events/ContextMenuItemPressEvent.kt +28 -28
- package/android/src/main/java/com/renderrichtext/events/CopyPressEvent.kt +24 -24
- package/android/src/main/java/com/renderrichtext/events/ImagePressEvent.kt +25 -25
- package/android/src/main/java/com/renderrichtext/events/LatexErrorEvent.kt +29 -29
- package/android/src/main/java/com/renderrichtext/events/LinkLongPressEvent.kt +23 -23
- package/android/src/main/java/com/renderrichtext/events/LinkPressEvent.kt +23 -23
- package/android/src/main/java/com/renderrichtext/events/MentionLongPressEvent.kt +25 -25
- package/android/src/main/java/com/renderrichtext/events/MentionPressEvent.kt +25 -25
- package/android/src/main/java/com/renderrichtext/events/TaskListItemPressEvent.kt +26 -26
- package/android/src/main/java/com/renderrichtext/math/LatexErrorReporter.kt +9 -9
- package/android/src/main/java/com/renderrichtext/parser/Parser.kt +59 -59
- package/android/src/main/java/com/renderrichtext/parser/TextLinkMatching.kt +35 -35
- package/android/src/main/java/com/renderrichtext/renderer/BaselineShiftRenderer.kt +45 -45
- package/android/src/main/java/com/renderrichtext/renderer/BlankLineRenderer.kt +39 -39
- package/android/src/main/java/com/renderrichtext/renderer/BlockquoteRenderer.kt +243 -243
- package/android/src/main/java/com/renderrichtext/renderer/BlockquoteTextRenderer.kt +56 -56
- package/android/src/main/java/com/renderrichtext/renderer/CodeBlockRenderer.kt +135 -135
- package/android/src/main/java/com/renderrichtext/renderer/CodeRenderer.kt +37 -37
- package/android/src/main/java/com/renderrichtext/renderer/EmphasisRenderer.kt +28 -28
- package/android/src/main/java/com/renderrichtext/renderer/HeadingRenderer.kt +81 -81
- package/android/src/main/java/com/renderrichtext/renderer/HighlightRenderer.kt +26 -26
- package/android/src/main/java/com/renderrichtext/renderer/LineBreakRenderer.kt +17 -17
- package/android/src/main/java/com/renderrichtext/renderer/LinkRenderer.kt +90 -90
- package/android/src/main/java/com/renderrichtext/renderer/ListContextManager.kt +109 -109
- package/android/src/main/java/com/renderrichtext/renderer/ListItemRenderer.kt +211 -211
- package/android/src/main/java/com/renderrichtext/renderer/ListRenderer.kt +133 -133
- package/android/src/main/java/com/renderrichtext/renderer/MentionRenderer.kt +85 -85
- package/android/src/main/java/com/renderrichtext/renderer/ParagraphRenderer.kt +91 -91
- package/android/src/main/java/com/renderrichtext/renderer/Renderer.kt +148 -148
- package/android/src/main/java/com/renderrichtext/renderer/SoftBreakRenderer.kt +17 -17
- package/android/src/main/java/com/renderrichtext/renderer/SpanStyleCache.kt +143 -143
- package/android/src/main/java/com/renderrichtext/renderer/StrikethroughRenderer.kt +28 -28
- package/android/src/main/java/com/renderrichtext/renderer/StrongRenderer.kt +28 -28
- package/android/src/main/java/com/renderrichtext/renderer/TextRenderer.kt +31 -31
- package/android/src/main/java/com/renderrichtext/renderer/ThematicBreakRenderer.kt +46 -46
- package/android/src/main/java/com/renderrichtext/renderer/UnderlineRenderer.kt +28 -28
- package/android/src/main/java/com/renderrichtext/spans/BaseListSpan.kt +164 -164
- package/android/src/main/java/com/renderrichtext/spans/BaselineShiftSpan.kt +27 -27
- package/android/src/main/java/com/renderrichtext/spans/BlockquoteSpan.kt +302 -302
- package/android/src/main/java/com/renderrichtext/spans/CodeBackgroundSpan.kt +205 -205
- package/android/src/main/java/com/renderrichtext/spans/CodeBlockSpan.kt +216 -216
- package/android/src/main/java/com/renderrichtext/spans/CodeSpan.kt +32 -32
- package/android/src/main/java/com/renderrichtext/spans/EmphasisSpan.kt +42 -42
- package/android/src/main/java/com/renderrichtext/spans/FadeInSpan.kt +29 -29
- package/android/src/main/java/com/renderrichtext/spans/HeadingSpan.kt +38 -38
- package/android/src/main/java/com/renderrichtext/spans/HighlightSpan.kt +80 -80
- package/android/src/main/java/com/renderrichtext/spans/ImageSpan.kt +481 -481
- package/android/src/main/java/com/renderrichtext/spans/InlineBackgroundGeometry.kt +42 -42
- package/android/src/main/java/com/renderrichtext/spans/LineHeightSpan.kt +39 -39
- package/android/src/main/java/com/renderrichtext/spans/LinkPillIconCache.kt +154 -154
- package/android/src/main/java/com/renderrichtext/spans/LinkPillSpan.kt +381 -381
- package/android/src/main/java/com/renderrichtext/spans/LinkSpan.kt +68 -68
- package/android/src/main/java/com/renderrichtext/spans/ListItemSpacingSpan.kt +33 -33
- package/android/src/main/java/com/renderrichtext/spans/ListMarkerAnchorSpan.kt +38 -38
- package/android/src/main/java/com/renderrichtext/spans/MarginBottomSpan.kt +76 -76
- package/android/src/main/java/com/renderrichtext/spans/MentionChipSpan.kt +132 -132
- package/android/src/main/java/com/renderrichtext/spans/MentionSpan.kt +46 -46
- package/android/src/main/java/com/renderrichtext/spans/OrderedListSpan.kt +127 -127
- package/android/src/main/java/com/renderrichtext/spans/SpoilerSpan.kt +33 -33
- package/android/src/main/java/com/renderrichtext/spans/StrikethroughSpan.kt +12 -12
- package/android/src/main/java/com/renderrichtext/spans/StrongSpan.kt +39 -39
- package/android/src/main/java/com/renderrichtext/spans/TaskListSpan.kt +143 -143
- package/android/src/main/java/com/renderrichtext/spans/TextSpan.kt +26 -26
- package/android/src/main/java/com/renderrichtext/spans/ThematicBreakSpan.kt +69 -69
- package/android/src/main/java/com/renderrichtext/spans/UnorderedListSpan.kt +96 -96
- package/android/src/main/java/com/renderrichtext/spoiler/SpoilerStubs.kt +46 -46
- package/android/src/main/java/com/renderrichtext/styles/BaseBlockStyle.kt +11 -11
- package/android/src/main/java/com/renderrichtext/styles/BlockquoteStyle.kt +83 -83
- package/android/src/main/java/com/renderrichtext/styles/CodeBlockStyle.kt +80 -80
- package/android/src/main/java/com/renderrichtext/styles/CodeStyle.kt +26 -26
- package/android/src/main/java/com/renderrichtext/styles/EmphasisStyle.kt +21 -21
- package/android/src/main/java/com/renderrichtext/styles/FactoidStyle.kt +21 -21
- package/android/src/main/java/com/renderrichtext/styles/HeadingStyle.kt +33 -33
- package/android/src/main/java/com/renderrichtext/styles/HighlightStyle.kt +19 -19
- package/android/src/main/java/com/renderrichtext/styles/ImageStyle.kt +29 -29
- package/android/src/main/java/com/renderrichtext/styles/InlineImageStyle.kt +17 -17
- package/android/src/main/java/com/renderrichtext/styles/InlineMathStyle.kt +17 -17
- package/android/src/main/java/com/renderrichtext/styles/LinkPillContent.kt +36 -36
- package/android/src/main/java/com/renderrichtext/styles/LinkPillStyle.kt +44 -44
- package/android/src/main/java/com/renderrichtext/styles/LinkStyle.kt +23 -23
- package/android/src/main/java/com/renderrichtext/styles/LinkVariantEntry.kt +34 -34
- package/android/src/main/java/com/renderrichtext/styles/ListStyle.kt +65 -65
- package/android/src/main/java/com/renderrichtext/styles/MathStyle.kt +29 -29
- package/android/src/main/java/com/renderrichtext/styles/MentionStyle.kt +19 -19
- package/android/src/main/java/com/renderrichtext/styles/ParagraphStyle.kt +33 -33
- package/android/src/main/java/com/renderrichtext/styles/SpoilerStyle.kt +27 -27
- package/android/src/main/java/com/renderrichtext/styles/StrikethroughStyle.kt +17 -17
- package/android/src/main/java/com/renderrichtext/styles/StrongStyle.kt +21 -21
- package/android/src/main/java/com/renderrichtext/styles/StyleConfig.kt +411 -411
- package/android/src/main/java/com/renderrichtext/styles/StyleParser.kt +92 -92
- package/android/src/main/java/com/renderrichtext/styles/SubscriptStyle.kt +16 -16
- package/android/src/main/java/com/renderrichtext/styles/SuperscriptStyle.kt +16 -16
- package/android/src/main/java/com/renderrichtext/styles/TableStyle.kt +75 -75
- package/android/src/main/java/com/renderrichtext/styles/TaskListStyle.kt +29 -29
- package/android/src/main/java/com/renderrichtext/styles/TextAlignment.kt +32 -32
- package/android/src/main/java/com/renderrichtext/styles/ThematicBreakStyle.kt +23 -23
- package/android/src/main/java/com/renderrichtext/styles/UnderlineStyle.kt +17 -17
- package/android/src/main/java/com/renderrichtext/styles/VideoStyle.kt +31 -31
- package/android/src/main/java/com/renderrichtext/utils/common/BorderStyleUtils.kt +86 -86
- package/android/src/main/java/com/renderrichtext/utils/common/BreakStrategyUtils.kt +32 -32
- package/android/src/main/java/com/renderrichtext/utils/common/CodeBlockHighlighter.kt +36 -36
- package/android/src/main/java/com/renderrichtext/utils/common/CodeBlockNode.kt +42 -42
- package/android/src/main/java/com/renderrichtext/utils/common/EllipsizeUtils.kt +27 -27
- package/android/src/main/java/com/renderrichtext/utils/common/EnrichedTiptapAncestorUtils.kt +10 -10
- package/android/src/main/java/com/renderrichtext/utils/common/FeatureFlags.kt +9 -9
- package/android/src/main/java/com/renderrichtext/utils/common/LinkRecognitionProps.kt +31 -31
- package/android/src/main/java/com/renderrichtext/utils/common/LinkRegexConfig.kt +56 -56
- package/android/src/main/java/com/renderrichtext/utils/common/MotionPreferences.kt +18 -18
- package/android/src/main/java/com/renderrichtext/utils/common/ReadableMapExtensions.kt +28 -28
- package/android/src/main/java/com/renderrichtext/utils/common/layout/RTLUtils.kt +6 -6
- package/android/src/main/java/com/renderrichtext/utils/common/serialization/TiptapASTSerializer.kt +368 -368
- package/android/src/main/java/com/renderrichtext/utils/text/ImageCache.kt +88 -88
- package/android/src/main/java/com/renderrichtext/utils/text/ImageDownloader.kt +203 -203
- package/android/src/main/java/com/renderrichtext/utils/text/LocalImageLoader.kt +167 -167
- package/android/src/main/java/com/renderrichtext/utils/text/TailFadeInAnimator.kt +84 -84
- package/android/src/main/java/com/renderrichtext/utils/text/conversion/HTMLGenerator.kt +1105 -1105
- package/android/src/main/java/com/renderrichtext/utils/text/conversion/TiptapExtractor.kt +423 -423
- package/android/src/main/java/com/renderrichtext/utils/text/extensions/ParagraphUtils.kt +9 -9
- package/android/src/main/java/com/renderrichtext/utils/text/extensions/SpannableExtensions.kt +9 -9
- package/android/src/main/java/com/renderrichtext/utils/text/extensions/TextPaintExtensions.kt +76 -76
- package/android/src/main/java/com/renderrichtext/utils/text/interaction/CheckboxTouchHelper.kt +61 -61
- package/android/src/main/java/com/renderrichtext/utils/text/interaction/TaskListTapUtils.kt +286 -286
- package/android/src/main/java/com/renderrichtext/utils/text/span/ApplyLineHeight.kt +39 -39
- package/android/src/main/java/com/renderrichtext/utils/text/span/BlockSpacing.kt +142 -142
- package/android/src/main/java/com/renderrichtext/utils/text/span/SpanFlags.kt +43 -43
- package/android/src/main/java/com/renderrichtext/utils/text/span/WidthAwareSpans.kt +30 -30
- package/android/src/main/java/com/renderrichtext/utils/text/view/CodeBlockPressHost.kt +15 -15
- package/android/src/main/java/com/renderrichtext/utils/text/view/ImagePressHost.kt +19 -19
- package/android/src/main/java/com/renderrichtext/utils/text/view/SelectionActionMode.kt +235 -235
- package/android/src/main/java/com/renderrichtext/utils/text/view/TextSelectionColors.kt +48 -48
- package/android/src/main/java/com/renderrichtext/utils/text/view/TextViewSetup.kt +119 -119
- package/android/src/main/java/com/renderrichtext/views/ContextMenuPopup.kt +217 -217
- package/android/src/main/java/com/renderrichtext/views/CopyGlyph.kt +101 -101
- package/android/src/main/java/com/renderrichtext/views/WrapGlyph.kt +40 -40
- package/android/src/main/jni/CMakeLists.txt +52 -52
- package/android/src/main/jni/react/renderer/components/RichTextSpec/ComponentDescriptors.h +30 -30
- package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextComponentDescriptor.h +29 -29
- package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextMeasurementManager.cpp +45 -45
- package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextMeasurementManager.h +21 -21
- package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextShadowNode.cpp +38 -38
- package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextShadowNode.h +53 -53
- package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextState.cpp +9 -9
- package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextState.h +24 -24
- package/android/src/main/jni/react/renderer/components/RichTextSpec/conversions.h +40 -40
- package/cpp/parser/TiptapParser.hpp +13 -13
- package/cpp/vendor/nlohmann/json.hpp +24765 -24765
- package/ios/EnrichedTiptapText.h +27 -27
- package/ios/attachments/ENRMImageAttachment.h +51 -51
- package/ios/attachments/ENRMImageAttachment.m +398 -398
- package/ios/attachments/ENRMLinkPillAttachment.h +47 -47
- package/ios/attachments/ENRMLinkPillAttachment.m +324 -324
- package/ios/attachments/ENRMLinkPillIconCache.h +28 -28
- package/ios/attachments/ENRMLinkPillIconCache.m +181 -181
- package/ios/attachments/ENRMLinkPillText.h +27 -27
- package/ios/attachments/ENRMLinkPillText.m +118 -118
- package/ios/attachments/ENRMMathInlineAttachment.h +7 -7
- package/ios/attachments/ENRMMathInlineAttachment.m +4 -4
- package/ios/attachments/ThematicBreakAttachment.h +15 -15
- package/ios/attachments/ThematicBreakAttachment.m +33 -33
- package/ios/internals/ENRMViewFreeMeasurement.h +208 -208
- package/ios/internals/EnrichedTiptapTextComponentDescriptor.h +19 -19
- package/ios/internals/EnrichedTiptapTextShadowNode.h +43 -43
- package/ios/internals/EnrichedTiptapTextShadowNode.mm +69 -69
- package/ios/internals/EnrichedTiptapTextState.h +24 -24
- package/ios/internals/MeasurementCache.h +308 -308
- package/ios/internals/ShadowMeasurementUtils.h +145 -145
- package/ios/parser/ENRMTextLinkAttributes.h +7 -7
- package/ios/parser/ENRMTiptapParser.h +33 -33
- package/ios/parser/ENRMTiptapParser.mm +73 -73
- package/ios/parser/TiptapASTNode.m +52 -52
- package/ios/renderer/AttributedRenderer.h +23 -23
- package/ios/renderer/AttributedRenderer.m +229 -229
- package/ios/renderer/BaseRenderer.h +33 -33
- package/ios/renderer/BaseRenderer.m +46 -46
- package/ios/renderer/BaselineShiftTextAttributes.h +10 -10
- package/ios/renderer/BaselineShiftTextAttributes.m +26 -26
- package/ios/renderer/BlankLineRenderer.h +4 -4
- package/ios/renderer/BlankLineRenderer.m +51 -51
- package/ios/renderer/BlockquoteRenderer.h +6 -6
- package/ios/renderer/BlockquoteRenderer.m +258 -258
- package/ios/renderer/CodeBlockRenderer.h +9 -9
- package/ios/renderer/CodeBlockRenderer.m +99 -99
- package/ios/renderer/CodeRenderer.h +9 -9
- package/ios/renderer/CodeRenderer.m +69 -69
- package/ios/renderer/ENRMBlockquoteTextRenderer.h +25 -25
- package/ios/renderer/ENRMBlockquoteTextRenderer.m +48 -48
- package/ios/renderer/EmphasisRenderer.h +5 -5
- package/ios/renderer/EmphasisRenderer.m +99 -99
- package/ios/renderer/HeadingRenderer.h +6 -6
- package/ios/renderer/HeadingRenderer.m +102 -102
- package/ios/renderer/HighlightRenderer.h +7 -7
- package/ios/renderer/HighlightRenderer.m +33 -33
- package/ios/renderer/LinkRenderer.h +6 -6
- package/ios/renderer/LinkRenderer.m +157 -157
- package/ios/renderer/ListItemRenderer.h +24 -24
- package/ios/renderer/ListItemRenderer.m +283 -283
- package/ios/renderer/ListRenderer.h +13 -13
- package/ios/renderer/ListRenderer.m +126 -126
- package/ios/renderer/MentionRenderer.h +9 -9
- package/ios/renderer/MentionRenderer.m +96 -96
- package/ios/renderer/NodeRenderer.h +8 -8
- package/ios/renderer/ParagraphRenderer.h +6 -6
- package/ios/renderer/ParagraphRenderer.m +85 -85
- package/ios/renderer/RenderContext.h +145 -145
- package/ios/renderer/RenderContext.m +402 -402
- package/ios/renderer/RendererFactory.h +12 -12
- package/ios/renderer/StrikethroughRenderer.h +5 -5
- package/ios/renderer/StrikethroughRenderer.m +30 -30
- package/ios/renderer/StrongRenderer.h +5 -5
- package/ios/renderer/StrongRenderer.m +87 -87
- package/ios/renderer/TextRenderer.h +6 -6
- package/ios/renderer/TextRenderer.m +18 -18
- package/ios/renderer/ThematicBreakRenderer.h +4 -4
- package/ios/renderer/ThematicBreakRenderer.m +41 -41
- package/ios/renderer/UnderlineRenderer.h +4 -4
- package/ios/renderer/UnderlineRenderer.m +41 -41
- package/ios/styles/ENRMFontSlot.h +12 -12
- package/ios/styles/ENRMFontSlot.m +24 -24
- package/ios/styles/StyleConfig.h +488 -488
- package/ios/styles/StyleConfig.mm +2820 -2820
- package/ios/utils/AccessibilityInfo.h +35 -35
- package/ios/utils/AccessibilityInfo.m +24 -24
- package/ios/utils/BlockquoteBorder.h +26 -26
- package/ios/utils/BlockquoteBorder.m +294 -294
- package/ios/utils/CodeBackground.h +19 -19
- package/ios/utils/CodeBackground.m +196 -196
- package/ios/utils/CodeBlockBackground.h +17 -17
- package/ios/utils/CodeBlockBackground.m +102 -102
- package/ios/utils/ContextMenuUtils.h +76 -76
- package/ios/utils/ContextMenuUtils.mm +75 -75
- package/ios/utils/ENRMAccessibilityLabels.h +40 -40
- package/ios/utils/ENRMAccessibilityLabels.m +5 -5
- package/ios/utils/ENRMAsyncRenderCoordinator.h +24 -24
- package/ios/utils/ENRMAsyncRenderCoordinator.m +37 -37
- package/ios/utils/ENRMAtomicSize.h +65 -65
- package/ios/utils/ENRMCodeBlockContent.h +37 -37
- package/ios/utils/ENRMCodeBlockContent.mm +89 -89
- package/ios/utils/ENRMFeatureFlags.h +25 -25
- package/ios/utils/ENRMImageDownloader.h +30 -30
- package/ios/utils/ENRMImageDownloader.m +168 -168
- package/ios/utils/ENRMLatexErrorCoordinator.h +27 -27
- package/ios/utils/ENRMLatexErrorCoordinator.mm +75 -75
- package/ios/utils/ENRMLatexErrorReporting.h +13 -13
- package/ios/utils/ENRMLinkContextMenus.h +93 -93
- package/ios/utils/ENRMLinkContextMenus.m +178 -178
- package/ios/utils/ENRMLinkRegexConfig.h +30 -30
- package/ios/utils/ENRMLinkRegexConfig.mm +104 -104
- package/ios/utils/ENRMLinkRegexProps.h +23 -23
- package/ios/utils/ENRMLocalImageLoader.h +35 -35
- package/ios/utils/ENRMLocalImageLoader.m +111 -111
- package/ios/utils/ENRMMenuAction.h +27 -27
- package/ios/utils/ENRMMenuAction.m +33 -33
- package/ios/utils/ENRMSpoilerOverlayManager.h +15 -15
- package/ios/utils/ENRMSpoilerOverlayManager.m +19 -19
- package/ios/utils/ENRMSpoilerTapUtils.h +6 -6
- package/ios/utils/ENRMSpoilerTapUtils.m +11 -11
- package/ios/utils/ENRMTailFadeInAnimator.h +16 -16
- package/ios/utils/ENRMTailFadeInAnimator.m +161 -161
- package/ios/utils/ENRMTextHitTest.h +23 -23
- package/ios/utils/ENRMTextHitTest.m +20 -20
- package/ios/utils/ENRMTextInteractionUtils.h +20 -20
- package/ios/utils/ENRMTextInteractionUtils.m +15 -15
- package/ios/utils/ENRMTextRenderer.h +38 -38
- package/ios/utils/ENRMTextRenderer.m +54 -54
- package/ios/utils/ENRMTextViewSetup.h +132 -132
- package/ios/utils/ENRMUIKit.h +429 -429
- package/ios/utils/EditMenuUtils.h +105 -105
- package/ios/utils/EditMenuUtils.m +143 -143
- package/ios/utils/FontScaleObserver.h +10 -10
- package/ios/utils/FontScaleObserver.m +55 -55
- package/ios/utils/FontUtils.h +31 -31
- package/ios/utils/FontUtils.m +63 -63
- package/ios/utils/HTMLGenerator.h +25 -25
- package/ios/utils/HTMLGenerator.m +1041 -1041
- package/ios/utils/HeightUpdateUtils.h +25 -25
- package/ios/utils/ImageRequestHeaderUtils.h +35 -35
- package/ios/utils/LastElementUtils.h +97 -97
- package/ios/utils/LinkContextMenuUtils.h +55 -55
- package/ios/utils/LinkPillContentUtils.h +46 -46
- package/ios/utils/ListMarkerDrawer.h +15 -15
- package/ios/utils/ListMarkerDrawer.m +239 -239
- package/ios/utils/MentionBackground.h +26 -26
- package/ios/utils/MentionBackground.m +86 -86
- package/ios/utils/ParagraphStyleUtils.h +87 -87
- package/ios/utils/ParagraphStyleUtils.m +484 -484
- package/ios/utils/PasteboardUtils.h +48 -48
- package/ios/utils/PasteboardUtils.m +166 -166
- package/ios/utils/RTFExportUtils.h +24 -24
- package/ios/utils/RTFExportUtils.m +299 -299
- package/ios/utils/SelectionColorUtils.h +14 -14
- package/ios/utils/StylePropsUtils.h +1340 -1340
- package/ios/utils/TaskListTapUtils.h +6 -6
- package/ios/utils/TaskListTapUtils.m +14 -14
- package/ios/utils/TextViewLayoutManager.h +14 -14
- package/ios/utils/TiptapAccessibilityElementBuilder.h +43 -43
- package/ios/utils/TiptapAccessibilityElementBuilder.m +432 -432
- package/ios/utils/TiptapExtractor.h +17 -17
- package/ios/utils/TiptapExtractor.m +367 -367
- package/ios/views/ENRMTiptapTextView.h +25 -25
- package/ios/views/ENRMTiptapTextView.m +247 -247
- package/package.json +65 -70
- package/react-native.config.js +10 -10
- package/src/admonitionDefaults.ts +58 -58
- package/src/darkModeTextStyle.ts +99 -99
- package/src/headingDefaults.ts +21 -21
- package/src/index.tsx +4 -4
- package/src/linkVariantUtils.ts +120 -120
- package/src/normalizeTiptapStyle.ts +397 -397
- package/src/rn-globals.d.ts +1 -1
- package/src/styleUtils.ts +107 -107
- package/src/types/TiptapStyle.ts +532 -532
- package/src/types/TiptapStyleInternal.ts +299 -299
- package/src/types/linkPill.ts +9 -9
- package/src/utils/isDev.ts +4 -4
|
@@ -1,243 +1,243 @@
|
|
|
1
|
-
package com.renderrichtext.renderer
|
|
2
|
-
|
|
3
|
-
import android.graphics.Paint
|
|
4
|
-
import android.text.SpannableStringBuilder
|
|
5
|
-
import android.text.Spanned
|
|
6
|
-
import android.text.style.LineHeightSpan
|
|
7
|
-
import com.renderrichtext.parser.TiptapASTNode
|
|
8
|
-
import com.renderrichtext.spans.BlockquoteSpan
|
|
9
|
-
import com.renderrichtext.spans.MarginBottomSpan
|
|
10
|
-
import com.renderrichtext.utils.text.span.SPAN_FLAGS_EXCLUSIVE_EXCLUSIVE
|
|
11
|
-
import com.renderrichtext.utils.text.span.SPAN_FLAGS_EXCLUSIVE_EXCLUSIVE_PRIORITY
|
|
12
|
-
import com.renderrichtext.utils.text.span.SPAN_FLAGS_LINE_HEIGHT_PRIORITY
|
|
13
|
-
import com.renderrichtext.utils.text.span.applyLineHeightSkippingImages
|
|
14
|
-
import com.renderrichtext.utils.text.span.applyMarginBottom
|
|
15
|
-
import com.renderrichtext.utils.text.span.applyMarginTop
|
|
16
|
-
|
|
17
|
-
class BlockquoteRenderer(
|
|
18
|
-
private val config: RendererConfig,
|
|
19
|
-
) : NodeRenderer {
|
|
20
|
-
override fun render(
|
|
21
|
-
node: TiptapASTNode,
|
|
22
|
-
builder: SpannableStringBuilder,
|
|
23
|
-
onLinkPress: ((String) -> Unit)?,
|
|
24
|
-
onLinkLongPress: ((String) -> Unit)?,
|
|
25
|
-
onFactoidPress: ((String) -> Unit)?,
|
|
26
|
-
factory: RendererFactory,
|
|
27
|
-
) {
|
|
28
|
-
if (builder.isNotEmpty() && builder.last() != '\n') {
|
|
29
|
-
builder.append("\n")
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
val start = builder.length
|
|
33
|
-
val style = config.style.blockquoteStyle
|
|
34
|
-
val context = factory.blockStyleContext
|
|
35
|
-
val depth = context.blockquoteDepth
|
|
36
|
-
|
|
37
|
-
// Track depth to handle nested indentation levels
|
|
38
|
-
context.blockquoteDepth = depth + 1
|
|
39
|
-
context.setBlockquoteStyle(style)
|
|
40
|
-
|
|
41
|
-
try {
|
|
42
|
-
factory.renderChildren(node, builder, onLinkPress, onLinkLongPress, onFactoidPress)
|
|
43
|
-
} finally {
|
|
44
|
-
context.popBlockStyle()
|
|
45
|
-
context.blockquoteDepth = depth
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if (builder.length == start) return
|
|
49
|
-
// The last child's margin sits on its terminating newline, so the extra
|
|
50
|
-
// descent is part of the last content line and the quote background paints
|
|
51
|
-
// it. That reads as a large gap under the text. Lift it off the box.
|
|
52
|
-
var end = detachTrailingContentMargin(builder, start, depth)
|
|
53
|
-
if (end == start) return
|
|
54
|
-
if (depth == 0 && end == builder.length && builder[end - 1] != '\n') {
|
|
55
|
-
builder.append('\n')
|
|
56
|
-
end = builder.length
|
|
57
|
-
}
|
|
58
|
-
val padding = style.padding.toInt()
|
|
59
|
-
|
|
60
|
-
var contentStart = start
|
|
61
|
-
if (padding > 0) {
|
|
62
|
-
builder.insert(start, "\n")
|
|
63
|
-
factory.shiftDeferredSpans(start, 1)
|
|
64
|
-
builder.setSpan(
|
|
65
|
-
BlockquotePaddingSpacerSpan(padding),
|
|
66
|
-
start,
|
|
67
|
-
start + 1,
|
|
68
|
-
SPAN_FLAGS_EXCLUSIVE_EXCLUSIVE,
|
|
69
|
-
)
|
|
70
|
-
contentStart = start + 1
|
|
71
|
-
end += 1
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// Find immediately nested quotes to exclude them from this level's line-height/margins
|
|
75
|
-
val nestedRanges =
|
|
76
|
-
builder
|
|
77
|
-
.getSpans(contentStart, end, BlockquoteSpan::class.java)
|
|
78
|
-
.filter { it.depth == depth + 1 }
|
|
79
|
-
.map { builder.getSpanStart(it) to builder.getSpanEnd(it) }
|
|
80
|
-
.sortedBy { it.first }
|
|
81
|
-
|
|
82
|
-
// The accent bar / background span covers the full box, incl. the top spacer.
|
|
83
|
-
// Top priority draws it first, so inline pill/chip backgrounds paint on top of its fill.
|
|
84
|
-
builder.setSpan(
|
|
85
|
-
BlockquoteSpan(style, depth, factory.context, factory.styleCache),
|
|
86
|
-
start,
|
|
87
|
-
end,
|
|
88
|
-
SPAN_FLAGS_EXCLUSIVE_EXCLUSIVE_PRIORITY,
|
|
89
|
-
)
|
|
90
|
-
|
|
91
|
-
applyLineHeightExcludingNested(builder, nestedRanges, contentStart, end, style.lineHeight)
|
|
92
|
-
|
|
93
|
-
if (padding > 0) {
|
|
94
|
-
builder.setSpan(
|
|
95
|
-
BlockquoteBoundaryPaddingSpan(padding),
|
|
96
|
-
contentStart,
|
|
97
|
-
end,
|
|
98
|
-
SPAN_FLAGS_EXCLUSIVE_EXCLUSIVE,
|
|
99
|
-
)
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// Margins are only applied by the outermost (root) quote
|
|
103
|
-
if (depth == 0) {
|
|
104
|
-
applyMarginTop(builder, start, style.marginTop)
|
|
105
|
-
applyMarginBottom(builder, style.marginBottom)
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* The last block inside the quote ends with a [MarginBottomSpan] on its
|
|
111
|
-
* terminating newline. That span adds its margin to the content line's descent,
|
|
112
|
-
* and the quote background fills the whole line, so the margin shows up as
|
|
113
|
-
* extra space under the text.
|
|
114
|
-
*
|
|
115
|
-
* A root quote drops that margin and keeps a bare newline, so the quote's own
|
|
116
|
-
* margin (applied after the box) is a separate spacer line outside the
|
|
117
|
-
* background. A nested quote keeps the margin, but on a following spacer line
|
|
118
|
-
* the box does not cover, so the parent still gets a gap before the next sibling.
|
|
119
|
-
*
|
|
120
|
-
* Returns the exclusive end index the quote box should use.
|
|
121
|
-
*/
|
|
122
|
-
private fun detachTrailingContentMargin(
|
|
123
|
-
builder: SpannableStringBuilder,
|
|
124
|
-
start: Int,
|
|
125
|
-
depth: Int,
|
|
126
|
-
): Int {
|
|
127
|
-
val end = builder.length
|
|
128
|
-
if (end <= start || builder[end - 1] != '\n') return end
|
|
129
|
-
|
|
130
|
-
val newline = end - 1
|
|
131
|
-
val marginSpans =
|
|
132
|
-
builder.getSpans(newline, end, MarginBottomSpan::class.java).filter {
|
|
133
|
-
builder.getSpanStart(it) == newline && builder.getSpanEnd(it) == end
|
|
134
|
-
}
|
|
135
|
-
if (marginSpans.isEmpty()) return end
|
|
136
|
-
|
|
137
|
-
val margin = marginSpans.maxOf { it.marginBottom }
|
|
138
|
-
val spacerLine = newline == start || builder[newline - 1] == '\n'
|
|
139
|
-
|
|
140
|
-
if (spacerLine) {
|
|
141
|
-
if (depth == 0) {
|
|
142
|
-
marginSpans.forEach { builder.removeSpan(it) }
|
|
143
|
-
builder.delete(newline, end)
|
|
144
|
-
return newline
|
|
145
|
-
}
|
|
146
|
-
return newline
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
marginSpans.forEach { builder.removeSpan(it) }
|
|
150
|
-
if (depth > 0 && margin > 0f) {
|
|
151
|
-
val spacer = builder.length
|
|
152
|
-
builder.append('\n')
|
|
153
|
-
builder.setSpan(
|
|
154
|
-
MarginBottomSpan(margin),
|
|
155
|
-
spacer,
|
|
156
|
-
builder.length,
|
|
157
|
-
SPAN_FLAGS_EXCLUSIVE_EXCLUSIVE,
|
|
158
|
-
)
|
|
159
|
-
return end
|
|
160
|
-
}
|
|
161
|
-
return builder.length
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* A blockquote's top padding, rendered as a standalone spacer line of exactly
|
|
166
|
-
* [padding] px.
|
|
167
|
-
*
|
|
168
|
-
* Top padding cannot be added by growing the first content line's ascent:
|
|
169
|
-
* StaticLayout reuses one FontMetricsInt across a paragraph's soft-wrapped lines,
|
|
170
|
-
* so the inflated first-line metrics leak into the wrapped continuation line, where
|
|
171
|
-
* the line-height clamp then skews them into overlapping baselines. A spacer sits in
|
|
172
|
-
* its own paragraph, and setting absolute metrics keeps it fixed regardless of that
|
|
173
|
-
* reuse.
|
|
174
|
-
*/
|
|
175
|
-
private class BlockquotePaddingSpacerSpan(
|
|
176
|
-
private val padding: Int,
|
|
177
|
-
) : LineHeightSpan {
|
|
178
|
-
override fun chooseHeight(
|
|
179
|
-
text: CharSequence,
|
|
180
|
-
startLine: Int,
|
|
181
|
-
endLine: Int,
|
|
182
|
-
spanstartv: Int,
|
|
183
|
-
v: Int,
|
|
184
|
-
fm: Paint.FontMetricsInt,
|
|
185
|
-
) {
|
|
186
|
-
fm.top = 0
|
|
187
|
-
fm.ascent = 0
|
|
188
|
-
fm.descent = padding
|
|
189
|
-
fm.bottom = padding
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
/**
|
|
194
|
-
* A blockquote's bottom padding, grown onto the last content line's descent (safe
|
|
195
|
-
* because no later line inherits its metrics; top padding uses
|
|
196
|
-
* [BlockquotePaddingSpacerSpan]).
|
|
197
|
-
*
|
|
198
|
-
* The span range can include trailing '\n'(s) that form no visible line, so the last
|
|
199
|
-
* drawn line ends before getSpanEnd; the comparison uses the visible content end.
|
|
200
|
-
*/
|
|
201
|
-
private class BlockquoteBoundaryPaddingSpan(
|
|
202
|
-
private val padding: Int,
|
|
203
|
-
) : LineHeightSpan {
|
|
204
|
-
override fun chooseHeight(
|
|
205
|
-
text: CharSequence,
|
|
206
|
-
startLine: Int,
|
|
207
|
-
endLine: Int,
|
|
208
|
-
spanstartv: Int,
|
|
209
|
-
v: Int,
|
|
210
|
-
fm: Paint.FontMetricsInt,
|
|
211
|
-
) {
|
|
212
|
-
if (text !is Spanned) return
|
|
213
|
-
|
|
214
|
-
var contentEnd = text.getSpanEnd(this)
|
|
215
|
-
while (contentEnd > 0 && text[contentEnd - 1] == '\n') {
|
|
216
|
-
contentEnd--
|
|
217
|
-
}
|
|
218
|
-
if (endLine >= contentEnd) {
|
|
219
|
-
fm.descent += padding
|
|
220
|
-
fm.bottom += padding
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
private fun applyLineHeightExcludingNested(
|
|
226
|
-
builder: SpannableStringBuilder,
|
|
227
|
-
nestedRanges: List<Pair<Int, Int>>,
|
|
228
|
-
start: Int,
|
|
229
|
-
end: Int,
|
|
230
|
-
lineHeight: Float,
|
|
231
|
-
) {
|
|
232
|
-
var currentPos = start
|
|
233
|
-
for ((nestedStart, nestedEnd) in nestedRanges) {
|
|
234
|
-
if (currentPos < nestedStart) {
|
|
235
|
-
applyLineHeightSkippingImages(builder, currentPos, nestedStart, lineHeight, SPAN_FLAGS_LINE_HEIGHT_PRIORITY)
|
|
236
|
-
}
|
|
237
|
-
currentPos = nestedEnd
|
|
238
|
-
}
|
|
239
|
-
if (currentPos < end) {
|
|
240
|
-
applyLineHeightSkippingImages(builder, currentPos, end, lineHeight, SPAN_FLAGS_LINE_HEIGHT_PRIORITY)
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
}
|
|
1
|
+
package com.renderrichtext.renderer
|
|
2
|
+
|
|
3
|
+
import android.graphics.Paint
|
|
4
|
+
import android.text.SpannableStringBuilder
|
|
5
|
+
import android.text.Spanned
|
|
6
|
+
import android.text.style.LineHeightSpan
|
|
7
|
+
import com.renderrichtext.parser.TiptapASTNode
|
|
8
|
+
import com.renderrichtext.spans.BlockquoteSpan
|
|
9
|
+
import com.renderrichtext.spans.MarginBottomSpan
|
|
10
|
+
import com.renderrichtext.utils.text.span.SPAN_FLAGS_EXCLUSIVE_EXCLUSIVE
|
|
11
|
+
import com.renderrichtext.utils.text.span.SPAN_FLAGS_EXCLUSIVE_EXCLUSIVE_PRIORITY
|
|
12
|
+
import com.renderrichtext.utils.text.span.SPAN_FLAGS_LINE_HEIGHT_PRIORITY
|
|
13
|
+
import com.renderrichtext.utils.text.span.applyLineHeightSkippingImages
|
|
14
|
+
import com.renderrichtext.utils.text.span.applyMarginBottom
|
|
15
|
+
import com.renderrichtext.utils.text.span.applyMarginTop
|
|
16
|
+
|
|
17
|
+
class BlockquoteRenderer(
|
|
18
|
+
private val config: RendererConfig,
|
|
19
|
+
) : NodeRenderer {
|
|
20
|
+
override fun render(
|
|
21
|
+
node: TiptapASTNode,
|
|
22
|
+
builder: SpannableStringBuilder,
|
|
23
|
+
onLinkPress: ((String) -> Unit)?,
|
|
24
|
+
onLinkLongPress: ((String) -> Unit)?,
|
|
25
|
+
onFactoidPress: ((String) -> Unit)?,
|
|
26
|
+
factory: RendererFactory,
|
|
27
|
+
) {
|
|
28
|
+
if (builder.isNotEmpty() && builder.last() != '\n') {
|
|
29
|
+
builder.append("\n")
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
val start = builder.length
|
|
33
|
+
val style = config.style.blockquoteStyle
|
|
34
|
+
val context = factory.blockStyleContext
|
|
35
|
+
val depth = context.blockquoteDepth
|
|
36
|
+
|
|
37
|
+
// Track depth to handle nested indentation levels
|
|
38
|
+
context.blockquoteDepth = depth + 1
|
|
39
|
+
context.setBlockquoteStyle(style)
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
factory.renderChildren(node, builder, onLinkPress, onLinkLongPress, onFactoidPress)
|
|
43
|
+
} finally {
|
|
44
|
+
context.popBlockStyle()
|
|
45
|
+
context.blockquoteDepth = depth
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (builder.length == start) return
|
|
49
|
+
// The last child's margin sits on its terminating newline, so the extra
|
|
50
|
+
// descent is part of the last content line and the quote background paints
|
|
51
|
+
// it. That reads as a large gap under the text. Lift it off the box.
|
|
52
|
+
var end = detachTrailingContentMargin(builder, start, depth)
|
|
53
|
+
if (end == start) return
|
|
54
|
+
if (depth == 0 && end == builder.length && builder[end - 1] != '\n') {
|
|
55
|
+
builder.append('\n')
|
|
56
|
+
end = builder.length
|
|
57
|
+
}
|
|
58
|
+
val padding = style.padding.toInt()
|
|
59
|
+
|
|
60
|
+
var contentStart = start
|
|
61
|
+
if (padding > 0) {
|
|
62
|
+
builder.insert(start, "\n")
|
|
63
|
+
factory.shiftDeferredSpans(start, 1)
|
|
64
|
+
builder.setSpan(
|
|
65
|
+
BlockquotePaddingSpacerSpan(padding),
|
|
66
|
+
start,
|
|
67
|
+
start + 1,
|
|
68
|
+
SPAN_FLAGS_EXCLUSIVE_EXCLUSIVE,
|
|
69
|
+
)
|
|
70
|
+
contentStart = start + 1
|
|
71
|
+
end += 1
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Find immediately nested quotes to exclude them from this level's line-height/margins
|
|
75
|
+
val nestedRanges =
|
|
76
|
+
builder
|
|
77
|
+
.getSpans(contentStart, end, BlockquoteSpan::class.java)
|
|
78
|
+
.filter { it.depth == depth + 1 }
|
|
79
|
+
.map { builder.getSpanStart(it) to builder.getSpanEnd(it) }
|
|
80
|
+
.sortedBy { it.first }
|
|
81
|
+
|
|
82
|
+
// The accent bar / background span covers the full box, incl. the top spacer.
|
|
83
|
+
// Top priority draws it first, so inline pill/chip backgrounds paint on top of its fill.
|
|
84
|
+
builder.setSpan(
|
|
85
|
+
BlockquoteSpan(style, depth, factory.context, factory.styleCache),
|
|
86
|
+
start,
|
|
87
|
+
end,
|
|
88
|
+
SPAN_FLAGS_EXCLUSIVE_EXCLUSIVE_PRIORITY,
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
applyLineHeightExcludingNested(builder, nestedRanges, contentStart, end, style.lineHeight)
|
|
92
|
+
|
|
93
|
+
if (padding > 0) {
|
|
94
|
+
builder.setSpan(
|
|
95
|
+
BlockquoteBoundaryPaddingSpan(padding),
|
|
96
|
+
contentStart,
|
|
97
|
+
end,
|
|
98
|
+
SPAN_FLAGS_EXCLUSIVE_EXCLUSIVE,
|
|
99
|
+
)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Margins are only applied by the outermost (root) quote
|
|
103
|
+
if (depth == 0) {
|
|
104
|
+
applyMarginTop(builder, start, style.marginTop)
|
|
105
|
+
applyMarginBottom(builder, style.marginBottom)
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* The last block inside the quote ends with a [MarginBottomSpan] on its
|
|
111
|
+
* terminating newline. That span adds its margin to the content line's descent,
|
|
112
|
+
* and the quote background fills the whole line, so the margin shows up as
|
|
113
|
+
* extra space under the text.
|
|
114
|
+
*
|
|
115
|
+
* A root quote drops that margin and keeps a bare newline, so the quote's own
|
|
116
|
+
* margin (applied after the box) is a separate spacer line outside the
|
|
117
|
+
* background. A nested quote keeps the margin, but on a following spacer line
|
|
118
|
+
* the box does not cover, so the parent still gets a gap before the next sibling.
|
|
119
|
+
*
|
|
120
|
+
* Returns the exclusive end index the quote box should use.
|
|
121
|
+
*/
|
|
122
|
+
private fun detachTrailingContentMargin(
|
|
123
|
+
builder: SpannableStringBuilder,
|
|
124
|
+
start: Int,
|
|
125
|
+
depth: Int,
|
|
126
|
+
): Int {
|
|
127
|
+
val end = builder.length
|
|
128
|
+
if (end <= start || builder[end - 1] != '\n') return end
|
|
129
|
+
|
|
130
|
+
val newline = end - 1
|
|
131
|
+
val marginSpans =
|
|
132
|
+
builder.getSpans(newline, end, MarginBottomSpan::class.java).filter {
|
|
133
|
+
builder.getSpanStart(it) == newline && builder.getSpanEnd(it) == end
|
|
134
|
+
}
|
|
135
|
+
if (marginSpans.isEmpty()) return end
|
|
136
|
+
|
|
137
|
+
val margin = marginSpans.maxOf { it.marginBottom }
|
|
138
|
+
val spacerLine = newline == start || builder[newline - 1] == '\n'
|
|
139
|
+
|
|
140
|
+
if (spacerLine) {
|
|
141
|
+
if (depth == 0) {
|
|
142
|
+
marginSpans.forEach { builder.removeSpan(it) }
|
|
143
|
+
builder.delete(newline, end)
|
|
144
|
+
return newline
|
|
145
|
+
}
|
|
146
|
+
return newline
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
marginSpans.forEach { builder.removeSpan(it) }
|
|
150
|
+
if (depth > 0 && margin > 0f) {
|
|
151
|
+
val spacer = builder.length
|
|
152
|
+
builder.append('\n')
|
|
153
|
+
builder.setSpan(
|
|
154
|
+
MarginBottomSpan(margin),
|
|
155
|
+
spacer,
|
|
156
|
+
builder.length,
|
|
157
|
+
SPAN_FLAGS_EXCLUSIVE_EXCLUSIVE,
|
|
158
|
+
)
|
|
159
|
+
return end
|
|
160
|
+
}
|
|
161
|
+
return builder.length
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* A blockquote's top padding, rendered as a standalone spacer line of exactly
|
|
166
|
+
* [padding] px.
|
|
167
|
+
*
|
|
168
|
+
* Top padding cannot be added by growing the first content line's ascent:
|
|
169
|
+
* StaticLayout reuses one FontMetricsInt across a paragraph's soft-wrapped lines,
|
|
170
|
+
* so the inflated first-line metrics leak into the wrapped continuation line, where
|
|
171
|
+
* the line-height clamp then skews them into overlapping baselines. A spacer sits in
|
|
172
|
+
* its own paragraph, and setting absolute metrics keeps it fixed regardless of that
|
|
173
|
+
* reuse.
|
|
174
|
+
*/
|
|
175
|
+
private class BlockquotePaddingSpacerSpan(
|
|
176
|
+
private val padding: Int,
|
|
177
|
+
) : LineHeightSpan {
|
|
178
|
+
override fun chooseHeight(
|
|
179
|
+
text: CharSequence,
|
|
180
|
+
startLine: Int,
|
|
181
|
+
endLine: Int,
|
|
182
|
+
spanstartv: Int,
|
|
183
|
+
v: Int,
|
|
184
|
+
fm: Paint.FontMetricsInt,
|
|
185
|
+
) {
|
|
186
|
+
fm.top = 0
|
|
187
|
+
fm.ascent = 0
|
|
188
|
+
fm.descent = padding
|
|
189
|
+
fm.bottom = padding
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* A blockquote's bottom padding, grown onto the last content line's descent (safe
|
|
195
|
+
* because no later line inherits its metrics; top padding uses
|
|
196
|
+
* [BlockquotePaddingSpacerSpan]).
|
|
197
|
+
*
|
|
198
|
+
* The span range can include trailing '\n'(s) that form no visible line, so the last
|
|
199
|
+
* drawn line ends before getSpanEnd; the comparison uses the visible content end.
|
|
200
|
+
*/
|
|
201
|
+
private class BlockquoteBoundaryPaddingSpan(
|
|
202
|
+
private val padding: Int,
|
|
203
|
+
) : LineHeightSpan {
|
|
204
|
+
override fun chooseHeight(
|
|
205
|
+
text: CharSequence,
|
|
206
|
+
startLine: Int,
|
|
207
|
+
endLine: Int,
|
|
208
|
+
spanstartv: Int,
|
|
209
|
+
v: Int,
|
|
210
|
+
fm: Paint.FontMetricsInt,
|
|
211
|
+
) {
|
|
212
|
+
if (text !is Spanned) return
|
|
213
|
+
|
|
214
|
+
var contentEnd = text.getSpanEnd(this)
|
|
215
|
+
while (contentEnd > 0 && text[contentEnd - 1] == '\n') {
|
|
216
|
+
contentEnd--
|
|
217
|
+
}
|
|
218
|
+
if (endLine >= contentEnd) {
|
|
219
|
+
fm.descent += padding
|
|
220
|
+
fm.bottom += padding
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
private fun applyLineHeightExcludingNested(
|
|
226
|
+
builder: SpannableStringBuilder,
|
|
227
|
+
nestedRanges: List<Pair<Int, Int>>,
|
|
228
|
+
start: Int,
|
|
229
|
+
end: Int,
|
|
230
|
+
lineHeight: Float,
|
|
231
|
+
) {
|
|
232
|
+
var currentPos = start
|
|
233
|
+
for ((nestedStart, nestedEnd) in nestedRanges) {
|
|
234
|
+
if (currentPos < nestedStart) {
|
|
235
|
+
applyLineHeightSkippingImages(builder, currentPos, nestedStart, lineHeight, SPAN_FLAGS_LINE_HEIGHT_PRIORITY)
|
|
236
|
+
}
|
|
237
|
+
currentPos = nestedEnd
|
|
238
|
+
}
|
|
239
|
+
if (currentPos < end) {
|
|
240
|
+
applyLineHeightSkippingImages(builder, currentPos, end, lineHeight, SPAN_FLAGS_LINE_HEIGHT_PRIORITY)
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
@@ -1,56 +1,56 @@
|
|
|
1
|
-
package com.renderrichtext.renderer
|
|
2
|
-
|
|
3
|
-
import android.text.SpannableStringBuilder
|
|
4
|
-
import com.renderrichtext.parser.TiptapASTNode
|
|
5
|
-
import com.renderrichtext.styles.BlockquoteStyle
|
|
6
|
-
import com.renderrichtext.utils.text.span.SPAN_FLAGS_LINE_HEIGHT_PRIORITY
|
|
7
|
-
import com.renderrichtext.utils.text.span.applyLineHeightSkippingImages
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Renders a GFM blockquote's own prose content - the nodes left after nested
|
|
11
|
-
* quotes, code blocks and other block segments have been split out - into a
|
|
12
|
-
* standalone buffer styled as blockquote text.
|
|
13
|
-
*
|
|
14
|
-
* It decorates a generic [Renderer.renderContent] pass rather than owning the
|
|
15
|
-
* render envelope itself: [push] enters the blockquote block style so text picks
|
|
16
|
-
* up the quote's font/color while still emitting block margins between children,
|
|
17
|
-
* matching the commonmark BlockquoteRenderer; [postProcess] applies the quote's
|
|
18
|
-
* line height once the builder is complete. It draws no border/background/padding
|
|
19
|
-
* - the BlockquoteContainerView draws the box.
|
|
20
|
-
*/
|
|
21
|
-
class BlockquoteTextRenderer(
|
|
22
|
-
private val style: BlockquoteStyle,
|
|
23
|
-
) {
|
|
24
|
-
fun render(
|
|
25
|
-
renderer: Renderer,
|
|
26
|
-
nodes: List<TiptapASTNode>,
|
|
27
|
-
onLinkPress: ((String) -> Unit)?,
|
|
28
|
-
onLinkLongPress: ((String) -> Unit)?,
|
|
29
|
-
onFactoidPress: ((String) -> Unit)?,
|
|
30
|
-
): SpannableStringBuilder = renderer.renderContent(nodes, onLinkPress, onLinkLongPress, onFactoidPress, block = this)
|
|
31
|
-
|
|
32
|
-
fun push(context: BlockStyleContext) {
|
|
33
|
-
context.blockquoteDepth += 1
|
|
34
|
-
context.setBlockquoteStyle(style)
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
fun pop(context: BlockStyleContext) {
|
|
38
|
-
context.popBlockStyle()
|
|
39
|
-
context.blockquoteDepth -= 1
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
fun postProcess(builder: SpannableStringBuilder) {
|
|
43
|
-
if (builder.isNotEmpty()) {
|
|
44
|
-
// Priority flag so this block-wide line height iterates before the per-block
|
|
45
|
-
// MarginBottomSpans, which then add their gap on top instead of being
|
|
46
|
-
// normalized away (see SPAN_FLAGS_LINE_HEIGHT_PRIORITY).
|
|
47
|
-
applyLineHeightSkippingImages(
|
|
48
|
-
builder,
|
|
49
|
-
0,
|
|
50
|
-
builder.length,
|
|
51
|
-
style.lineHeight,
|
|
52
|
-
SPAN_FLAGS_LINE_HEIGHT_PRIORITY,
|
|
53
|
-
)
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
1
|
+
package com.renderrichtext.renderer
|
|
2
|
+
|
|
3
|
+
import android.text.SpannableStringBuilder
|
|
4
|
+
import com.renderrichtext.parser.TiptapASTNode
|
|
5
|
+
import com.renderrichtext.styles.BlockquoteStyle
|
|
6
|
+
import com.renderrichtext.utils.text.span.SPAN_FLAGS_LINE_HEIGHT_PRIORITY
|
|
7
|
+
import com.renderrichtext.utils.text.span.applyLineHeightSkippingImages
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Renders a GFM blockquote's own prose content - the nodes left after nested
|
|
11
|
+
* quotes, code blocks and other block segments have been split out - into a
|
|
12
|
+
* standalone buffer styled as blockquote text.
|
|
13
|
+
*
|
|
14
|
+
* It decorates a generic [Renderer.renderContent] pass rather than owning the
|
|
15
|
+
* render envelope itself: [push] enters the blockquote block style so text picks
|
|
16
|
+
* up the quote's font/color while still emitting block margins between children,
|
|
17
|
+
* matching the commonmark BlockquoteRenderer; [postProcess] applies the quote's
|
|
18
|
+
* line height once the builder is complete. It draws no border/background/padding
|
|
19
|
+
* - the BlockquoteContainerView draws the box.
|
|
20
|
+
*/
|
|
21
|
+
class BlockquoteTextRenderer(
|
|
22
|
+
private val style: BlockquoteStyle,
|
|
23
|
+
) {
|
|
24
|
+
fun render(
|
|
25
|
+
renderer: Renderer,
|
|
26
|
+
nodes: List<TiptapASTNode>,
|
|
27
|
+
onLinkPress: ((String) -> Unit)?,
|
|
28
|
+
onLinkLongPress: ((String) -> Unit)?,
|
|
29
|
+
onFactoidPress: ((String) -> Unit)?,
|
|
30
|
+
): SpannableStringBuilder = renderer.renderContent(nodes, onLinkPress, onLinkLongPress, onFactoidPress, block = this)
|
|
31
|
+
|
|
32
|
+
fun push(context: BlockStyleContext) {
|
|
33
|
+
context.blockquoteDepth += 1
|
|
34
|
+
context.setBlockquoteStyle(style)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
fun pop(context: BlockStyleContext) {
|
|
38
|
+
context.popBlockStyle()
|
|
39
|
+
context.blockquoteDepth -= 1
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
fun postProcess(builder: SpannableStringBuilder) {
|
|
43
|
+
if (builder.isNotEmpty()) {
|
|
44
|
+
// Priority flag so this block-wide line height iterates before the per-block
|
|
45
|
+
// MarginBottomSpans, which then add their gap on top instead of being
|
|
46
|
+
// normalized away (see SPAN_FLAGS_LINE_HEIGHT_PRIORITY).
|
|
47
|
+
applyLineHeightSkippingImages(
|
|
48
|
+
builder,
|
|
49
|
+
0,
|
|
50
|
+
builder.length,
|
|
51
|
+
style.lineHeight,
|
|
52
|
+
SPAN_FLAGS_LINE_HEIGHT_PRIORITY,
|
|
53
|
+
)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|