@mathers101/react-native-render-rich-text 0.0.0-stage → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +20 -0
- package/README.md +140 -3
- package/ReactNativeRenderRichText.podspec +23 -0
- package/android/build.gradle +86 -0
- package/android/consumer-rules.pro +3 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/cpp/jni-adapter.cpp +191 -0
- package/android/src/main/java/com/renderrichtext/EnrichedTiptapText.kt +673 -0
- package/android/src/main/java/com/renderrichtext/EnrichedTiptapTextLayoutManager.kt +24 -0
- package/android/src/main/java/com/renderrichtext/EnrichedTiptapTextManager.kt +405 -0
- package/android/src/main/java/com/renderrichtext/EnrichedTiptapTextPackage.kt +13 -0
- package/android/src/main/java/com/renderrichtext/MeasurementStore.kt +644 -0
- package/android/src/main/java/com/renderrichtext/accessibility/AccessibilityLabels.kt +17 -0
- package/android/src/main/java/com/renderrichtext/accessibility/AccessibleTiptapTextView.kt +112 -0
- package/android/src/main/java/com/renderrichtext/accessibility/TiptapAccessibilityHelper.kt +576 -0
- package/android/src/main/java/com/renderrichtext/events/CodeBlockPressEvent.kt +24 -0
- package/android/src/main/java/com/renderrichtext/events/ContextMenuItemPressEvent.kt +28 -0
- package/android/src/main/java/com/renderrichtext/events/CopyPressEvent.kt +24 -0
- package/android/src/main/java/com/renderrichtext/events/FactoidPressEvent.kt +23 -0
- package/android/src/main/java/com/renderrichtext/events/ImagePressEvent.kt +25 -0
- package/android/src/main/java/com/renderrichtext/events/LatexErrorEvent.kt +29 -0
- package/android/src/main/java/com/renderrichtext/events/LinkLongPressEvent.kt +23 -0
- package/android/src/main/java/com/renderrichtext/events/LinkPressEvent.kt +23 -0
- package/android/src/main/java/com/renderrichtext/events/MentionLongPressEvent.kt +25 -0
- package/android/src/main/java/com/renderrichtext/events/MentionPressEvent.kt +25 -0
- package/android/src/main/java/com/renderrichtext/events/TaskListItemPressEvent.kt +26 -0
- package/android/src/main/java/com/renderrichtext/math/LatexErrorReporter.kt +9 -0
- package/android/src/main/java/com/renderrichtext/parser/Parser.kt +59 -0
- package/android/src/main/java/com/renderrichtext/parser/TextLinkMatching.kt +35 -0
- package/android/src/main/java/com/renderrichtext/parser/TiptapASTNode.kt +69 -0
- package/android/src/main/java/com/renderrichtext/renderer/BaselineShiftRenderer.kt +45 -0
- package/android/src/main/java/com/renderrichtext/renderer/BlankLineRenderer.kt +39 -0
- package/android/src/main/java/com/renderrichtext/renderer/BlockStyleContext.kt +181 -0
- package/android/src/main/java/com/renderrichtext/renderer/BlockquoteRenderer.kt +243 -0
- package/android/src/main/java/com/renderrichtext/renderer/BlockquoteTextRenderer.kt +56 -0
- package/android/src/main/java/com/renderrichtext/renderer/CodeBlockRenderer.kt +135 -0
- package/android/src/main/java/com/renderrichtext/renderer/CodeRenderer.kt +37 -0
- package/android/src/main/java/com/renderrichtext/renderer/EmphasisRenderer.kt +28 -0
- package/android/src/main/java/com/renderrichtext/renderer/FactoidRenderer.kt +97 -0
- package/android/src/main/java/com/renderrichtext/renderer/HeadingRenderer.kt +81 -0
- package/android/src/main/java/com/renderrichtext/renderer/HighlightRenderer.kt +26 -0
- package/android/src/main/java/com/renderrichtext/renderer/LineBreakRenderer.kt +17 -0
- package/android/src/main/java/com/renderrichtext/renderer/LinkRenderer.kt +90 -0
- package/android/src/main/java/com/renderrichtext/renderer/ListContextManager.kt +109 -0
- package/android/src/main/java/com/renderrichtext/renderer/ListItemRenderer.kt +211 -0
- package/android/src/main/java/com/renderrichtext/renderer/ListRenderer.kt +133 -0
- package/android/src/main/java/com/renderrichtext/renderer/MentionRenderer.kt +85 -0
- package/android/src/main/java/com/renderrichtext/renderer/NodeRenderer.kt +207 -0
- package/android/src/main/java/com/renderrichtext/renderer/ParagraphRenderer.kt +91 -0
- package/android/src/main/java/com/renderrichtext/renderer/Renderer.kt +148 -0
- package/android/src/main/java/com/renderrichtext/renderer/SoftBreakRenderer.kt +17 -0
- package/android/src/main/java/com/renderrichtext/renderer/SpanStyleCache.kt +143 -0
- package/android/src/main/java/com/renderrichtext/renderer/StrikethroughRenderer.kt +28 -0
- package/android/src/main/java/com/renderrichtext/renderer/StrongRenderer.kt +28 -0
- package/android/src/main/java/com/renderrichtext/renderer/TextRenderer.kt +31 -0
- package/android/src/main/java/com/renderrichtext/renderer/ThematicBreakRenderer.kt +46 -0
- package/android/src/main/java/com/renderrichtext/renderer/UnderlineRenderer.kt +28 -0
- package/android/src/main/java/com/renderrichtext/spans/BaseListSpan.kt +164 -0
- package/android/src/main/java/com/renderrichtext/spans/BaselineShiftSpan.kt +27 -0
- package/android/src/main/java/com/renderrichtext/spans/BlockquoteSpan.kt +302 -0
- package/android/src/main/java/com/renderrichtext/spans/CodeBackgroundSpan.kt +205 -0
- package/android/src/main/java/com/renderrichtext/spans/CodeBlockSpan.kt +216 -0
- package/android/src/main/java/com/renderrichtext/spans/CodeSpan.kt +32 -0
- package/android/src/main/java/com/renderrichtext/spans/EmphasisSpan.kt +42 -0
- package/android/src/main/java/com/renderrichtext/spans/FactoidBackgroundSpan.kt +265 -0
- package/android/src/main/java/com/renderrichtext/spans/FactoidPaddingSpan.kt +258 -0
- package/android/src/main/java/com/renderrichtext/spans/FactoidSpan.kt +32 -0
- package/android/src/main/java/com/renderrichtext/spans/FadeInSpan.kt +29 -0
- package/android/src/main/java/com/renderrichtext/spans/HeadingSpan.kt +38 -0
- package/android/src/main/java/com/renderrichtext/spans/HighlightSpan.kt +80 -0
- package/android/src/main/java/com/renderrichtext/spans/ImageSpan.kt +481 -0
- package/android/src/main/java/com/renderrichtext/spans/InlineBackgroundGeometry.kt +42 -0
- package/android/src/main/java/com/renderrichtext/spans/LineHeightSpan.kt +39 -0
- package/android/src/main/java/com/renderrichtext/spans/LinkPillIconCache.kt +154 -0
- package/android/src/main/java/com/renderrichtext/spans/LinkPillSpan.kt +381 -0
- package/android/src/main/java/com/renderrichtext/spans/LinkSpan.kt +68 -0
- package/android/src/main/java/com/renderrichtext/spans/ListItemSpacingSpan.kt +33 -0
- package/android/src/main/java/com/renderrichtext/spans/ListMarkerAnchorSpan.kt +38 -0
- package/android/src/main/java/com/renderrichtext/spans/MarginBottomSpan.kt +76 -0
- package/android/src/main/java/com/renderrichtext/spans/MentionChipSpan.kt +132 -0
- package/android/src/main/java/com/renderrichtext/spans/MentionSpan.kt +46 -0
- package/android/src/main/java/com/renderrichtext/spans/OrderedListSpan.kt +127 -0
- package/android/src/main/java/com/renderrichtext/spans/SpoilerSpan.kt +33 -0
- package/android/src/main/java/com/renderrichtext/spans/StrikethroughSpan.kt +12 -0
- package/android/src/main/java/com/renderrichtext/spans/StrongSpan.kt +39 -0
- package/android/src/main/java/com/renderrichtext/spans/TaskListSpan.kt +143 -0
- package/android/src/main/java/com/renderrichtext/spans/TextSpan.kt +26 -0
- package/android/src/main/java/com/renderrichtext/spans/ThematicBreakSpan.kt +69 -0
- package/android/src/main/java/com/renderrichtext/spans/UnorderedListSpan.kt +96 -0
- package/android/src/main/java/com/renderrichtext/spoiler/SpoilerStubs.kt +46 -0
- package/android/src/main/java/com/renderrichtext/styles/BaseBlockStyle.kt +11 -0
- package/android/src/main/java/com/renderrichtext/styles/BlockquoteStyle.kt +83 -0
- package/android/src/main/java/com/renderrichtext/styles/CodeBlockStyle.kt +80 -0
- package/android/src/main/java/com/renderrichtext/styles/CodeStyle.kt +26 -0
- package/android/src/main/java/com/renderrichtext/styles/EmphasisStyle.kt +21 -0
- package/android/src/main/java/com/renderrichtext/styles/FactoidStyle.kt +21 -0
- package/android/src/main/java/com/renderrichtext/styles/HeadingStyle.kt +33 -0
- package/android/src/main/java/com/renderrichtext/styles/HighlightStyle.kt +19 -0
- package/android/src/main/java/com/renderrichtext/styles/ImageStyle.kt +29 -0
- package/android/src/main/java/com/renderrichtext/styles/InlineImageStyle.kt +17 -0
- package/android/src/main/java/com/renderrichtext/styles/InlineMathStyle.kt +17 -0
- package/android/src/main/java/com/renderrichtext/styles/LinkPillContent.kt +36 -0
- package/android/src/main/java/com/renderrichtext/styles/LinkPillStyle.kt +44 -0
- package/android/src/main/java/com/renderrichtext/styles/LinkStyle.kt +23 -0
- package/android/src/main/java/com/renderrichtext/styles/LinkVariantEntry.kt +34 -0
- package/android/src/main/java/com/renderrichtext/styles/ListStyle.kt +65 -0
- package/android/src/main/java/com/renderrichtext/styles/MathStyle.kt +29 -0
- package/android/src/main/java/com/renderrichtext/styles/MentionStyle.kt +19 -0
- package/android/src/main/java/com/renderrichtext/styles/ParagraphStyle.kt +33 -0
- package/android/src/main/java/com/renderrichtext/styles/SpoilerStyle.kt +27 -0
- package/android/src/main/java/com/renderrichtext/styles/StrikethroughStyle.kt +17 -0
- package/android/src/main/java/com/renderrichtext/styles/StrongStyle.kt +21 -0
- package/android/src/main/java/com/renderrichtext/styles/StyleConfig.kt +411 -0
- package/android/src/main/java/com/renderrichtext/styles/StyleParser.kt +92 -0
- package/android/src/main/java/com/renderrichtext/styles/SubscriptStyle.kt +16 -0
- package/android/src/main/java/com/renderrichtext/styles/SuperscriptStyle.kt +16 -0
- package/android/src/main/java/com/renderrichtext/styles/TableStyle.kt +75 -0
- package/android/src/main/java/com/renderrichtext/styles/TaskListStyle.kt +29 -0
- package/android/src/main/java/com/renderrichtext/styles/TextAlignment.kt +32 -0
- package/android/src/main/java/com/renderrichtext/styles/ThematicBreakStyle.kt +23 -0
- package/android/src/main/java/com/renderrichtext/styles/UnderlineStyle.kt +17 -0
- package/android/src/main/java/com/renderrichtext/styles/VideoStyle.kt +31 -0
- package/android/src/main/java/com/renderrichtext/utils/common/BorderStyleUtils.kt +86 -0
- package/android/src/main/java/com/renderrichtext/utils/common/BreakStrategyUtils.kt +32 -0
- package/android/src/main/java/com/renderrichtext/utils/common/CodeBlockHighlighter.kt +36 -0
- package/android/src/main/java/com/renderrichtext/utils/common/CodeBlockNode.kt +42 -0
- package/android/src/main/java/com/renderrichtext/utils/common/EllipsizeUtils.kt +27 -0
- package/android/src/main/java/com/renderrichtext/utils/common/EnrichedTiptapAncestorUtils.kt +10 -0
- package/android/src/main/java/com/renderrichtext/utils/common/FeatureFlags.kt +9 -0
- package/android/src/main/java/com/renderrichtext/utils/common/LinkRecognitionProps.kt +31 -0
- package/android/src/main/java/com/renderrichtext/utils/common/LinkRegexConfig.kt +56 -0
- package/android/src/main/java/com/renderrichtext/utils/common/MotionPreferences.kt +18 -0
- package/android/src/main/java/com/renderrichtext/utils/common/ReadableMapExtensions.kt +28 -0
- package/android/src/main/java/com/renderrichtext/utils/common/TiptapViewManagerUtils.kt +242 -0
- package/android/src/main/java/com/renderrichtext/utils/common/layout/RTLUtils.kt +6 -0
- package/android/src/main/java/com/renderrichtext/utils/common/serialization/TiptapASTSerializer.kt +368 -0
- package/android/src/main/java/com/renderrichtext/utils/text/ImageCache.kt +88 -0
- package/android/src/main/java/com/renderrichtext/utils/text/ImageDownloader.kt +203 -0
- package/android/src/main/java/com/renderrichtext/utils/text/LocalImageLoader.kt +167 -0
- package/android/src/main/java/com/renderrichtext/utils/text/TailFadeInAnimator.kt +84 -0
- package/android/src/main/java/com/renderrichtext/utils/text/conversion/HTMLGenerator.kt +1105 -0
- package/android/src/main/java/com/renderrichtext/utils/text/conversion/TiptapExtractor.kt +423 -0
- package/android/src/main/java/com/renderrichtext/utils/text/extensions/ParagraphUtils.kt +9 -0
- package/android/src/main/java/com/renderrichtext/utils/text/extensions/SpannableExtensions.kt +9 -0
- package/android/src/main/java/com/renderrichtext/utils/text/extensions/TextPaintExtensions.kt +76 -0
- package/android/src/main/java/com/renderrichtext/utils/text/interaction/CheckboxTouchHelper.kt +61 -0
- package/android/src/main/java/com/renderrichtext/utils/text/interaction/TaskListTapUtils.kt +286 -0
- package/android/src/main/java/com/renderrichtext/utils/text/span/ApplyLineHeight.kt +39 -0
- package/android/src/main/java/com/renderrichtext/utils/text/span/BlockSpacing.kt +142 -0
- package/android/src/main/java/com/renderrichtext/utils/text/span/SpanFlags.kt +43 -0
- package/android/src/main/java/com/renderrichtext/utils/text/span/WidthAwareSpans.kt +30 -0
- package/android/src/main/java/com/renderrichtext/utils/text/view/CodeBlockPressHost.kt +15 -0
- package/android/src/main/java/com/renderrichtext/utils/text/view/ImagePressHost.kt +19 -0
- package/android/src/main/java/com/renderrichtext/utils/text/view/LinkEvents.kt +88 -0
- package/android/src/main/java/com/renderrichtext/utils/text/view/LinkLongPressMovementMethod.kt +449 -0
- package/android/src/main/java/com/renderrichtext/utils/text/view/SelectionActionMode.kt +235 -0
- package/android/src/main/java/com/renderrichtext/utils/text/view/TextSelectionColors.kt +48 -0
- package/android/src/main/java/com/renderrichtext/utils/text/view/TextViewSetup.kt +119 -0
- package/android/src/main/java/com/renderrichtext/views/ContextMenuPopup.kt +217 -0
- package/android/src/main/java/com/renderrichtext/views/CopyGlyph.kt +101 -0
- package/android/src/main/java/com/renderrichtext/views/WrapGlyph.kt +40 -0
- package/android/src/main/jni/CMakeLists.txt +52 -0
- package/android/src/main/jni/react/renderer/components/RichTextSpec/ComponentDescriptors.h +30 -0
- package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextComponentDescriptor.h +29 -0
- package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextMeasurementManager.cpp +45 -0
- package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextMeasurementManager.h +21 -0
- package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextShadowNode.cpp +38 -0
- package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextShadowNode.h +53 -0
- package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextState.cpp +9 -0
- package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextState.h +24 -0
- package/android/src/main/jni/react/renderer/components/RichTextSpec/conversions.h +40 -0
- package/cpp/parser/TiptapASTNode.hpp +68 -0
- package/cpp/parser/TiptapParser.cpp +233 -0
- package/cpp/parser/TiptapParser.hpp +13 -0
- package/cpp/vendor/nlohmann/json.hpp +24765 -0
- package/ios/EnrichedTiptapText.h +27 -0
- package/ios/EnrichedTiptapText.mm +1222 -0
- package/ios/attachments/ENRMImageAttachment.h +51 -0
- package/ios/attachments/ENRMImageAttachment.m +398 -0
- package/ios/attachments/ENRMLinkPillAttachment.h +47 -0
- package/ios/attachments/ENRMLinkPillAttachment.m +324 -0
- package/ios/attachments/ENRMLinkPillIconCache.h +28 -0
- package/ios/attachments/ENRMLinkPillIconCache.m +181 -0
- package/ios/attachments/ENRMLinkPillText.h +27 -0
- package/ios/attachments/ENRMLinkPillText.m +118 -0
- package/ios/attachments/ENRMMathInlineAttachment.h +7 -0
- package/ios/attachments/ENRMMathInlineAttachment.m +4 -0
- package/ios/attachments/ThematicBreakAttachment.h +15 -0
- package/ios/attachments/ThematicBreakAttachment.m +33 -0
- package/ios/internals/ENRMViewFreeMeasurement.h +208 -0
- package/ios/internals/EnrichedTiptapTextComponentDescriptor.h +19 -0
- package/ios/internals/EnrichedTiptapTextShadowNode.h +43 -0
- package/ios/internals/EnrichedTiptapTextShadowNode.mm +69 -0
- package/ios/internals/EnrichedTiptapTextState.h +24 -0
- package/ios/internals/MeasurementCache.h +308 -0
- package/ios/internals/ShadowMeasurementUtils.h +145 -0
- package/ios/parser/ENRMTextLinkAttributes.h +7 -0
- package/ios/parser/ENRMTiptapParser.h +33 -0
- package/ios/parser/ENRMTiptapParser.mm +73 -0
- package/ios/parser/TiptapASTNode.h +57 -0
- package/ios/parser/TiptapASTNode.m +52 -0
- package/ios/parser/TiptapParserBridge.mm +179 -0
- package/ios/renderer/AttributedRenderer.h +23 -0
- package/ios/renderer/AttributedRenderer.m +229 -0
- package/ios/renderer/BaseRenderer.h +33 -0
- package/ios/renderer/BaseRenderer.m +46 -0
- package/ios/renderer/BaselineShiftTextAttributes.h +10 -0
- package/ios/renderer/BaselineShiftTextAttributes.m +26 -0
- package/ios/renderer/BlankLineRenderer.h +4 -0
- package/ios/renderer/BlankLineRenderer.m +51 -0
- package/ios/renderer/BlockquoteRenderer.h +6 -0
- package/ios/renderer/BlockquoteRenderer.m +258 -0
- package/ios/renderer/CodeBlockRenderer.h +9 -0
- package/ios/renderer/CodeBlockRenderer.m +99 -0
- package/ios/renderer/CodeRenderer.h +9 -0
- package/ios/renderer/CodeRenderer.m +69 -0
- package/ios/renderer/ENRMBlockquoteTextRenderer.h +25 -0
- package/ios/renderer/ENRMBlockquoteTextRenderer.m +48 -0
- package/ios/renderer/EmphasisRenderer.h +5 -0
- package/ios/renderer/EmphasisRenderer.m +100 -0
- package/ios/renderer/FactoidRenderer.h +9 -0
- package/ios/renderer/FactoidRenderer.m +130 -0
- package/ios/renderer/HeadingRenderer.h +6 -0
- package/ios/renderer/HeadingRenderer.m +103 -0
- package/ios/renderer/HighlightRenderer.h +7 -0
- package/ios/renderer/HighlightRenderer.m +33 -0
- package/ios/renderer/LinkRenderer.h +6 -0
- package/ios/renderer/LinkRenderer.m +158 -0
- package/ios/renderer/ListItemRenderer.h +24 -0
- package/ios/renderer/ListItemRenderer.m +283 -0
- package/ios/renderer/ListRenderer.h +13 -0
- package/ios/renderer/ListRenderer.m +126 -0
- package/ios/renderer/MentionRenderer.h +9 -0
- package/ios/renderer/MentionRenderer.m +96 -0
- package/ios/renderer/NodeRenderer.h +8 -0
- package/ios/renderer/ParagraphRenderer.h +6 -0
- package/ios/renderer/ParagraphRenderer.m +85 -0
- package/ios/renderer/RenderContext.h +145 -0
- package/ios/renderer/RenderContext.m +403 -0
- package/ios/renderer/RendererFactory.h +12 -0
- package/ios/renderer/RendererFactory.m +158 -0
- package/ios/renderer/StrikethroughRenderer.h +5 -0
- package/ios/renderer/StrikethroughRenderer.m +30 -0
- package/ios/renderer/StrongRenderer.h +5 -0
- package/ios/renderer/StrongRenderer.m +88 -0
- package/ios/renderer/TextRenderer.h +6 -0
- package/ios/renderer/TextRenderer.m +18 -0
- package/ios/renderer/ThematicBreakRenderer.h +4 -0
- package/ios/renderer/ThematicBreakRenderer.m +42 -0
- package/ios/renderer/UnderlineRenderer.h +4 -0
- package/ios/renderer/UnderlineRenderer.m +41 -0
- package/ios/styles/ENRMFontSlot.h +12 -0
- package/ios/styles/ENRMFontSlot.m +24 -0
- package/ios/styles/StyleConfig.h +488 -0
- package/ios/styles/StyleConfig.mm +2820 -0
- package/ios/utils/AccessibilityInfo.h +35 -0
- package/ios/utils/AccessibilityInfo.m +24 -0
- package/ios/utils/BlockquoteBorder.h +26 -0
- package/ios/utils/BlockquoteBorder.m +294 -0
- package/ios/utils/CodeBackground.h +19 -0
- package/ios/utils/CodeBackground.m +197 -0
- package/ios/utils/CodeBlockBackground.h +17 -0
- package/ios/utils/CodeBlockBackground.m +103 -0
- package/ios/utils/ContextMenuUtils.h +76 -0
- package/ios/utils/ContextMenuUtils.mm +75 -0
- package/ios/utils/ENRMAccessibilityLabels.h +40 -0
- package/ios/utils/ENRMAccessibilityLabels.m +5 -0
- package/ios/utils/ENRMAsyncRenderCoordinator.h +24 -0
- package/ios/utils/ENRMAsyncRenderCoordinator.m +37 -0
- package/ios/utils/ENRMAtomicSize.h +65 -0
- package/ios/utils/ENRMCodeBlockContent.h +37 -0
- package/ios/utils/ENRMCodeBlockContent.mm +89 -0
- package/ios/utils/ENRMFeatureFlags.h +25 -0
- package/ios/utils/ENRMImageDownloader.h +30 -0
- package/ios/utils/ENRMImageDownloader.m +168 -0
- package/ios/utils/ENRMLatexErrorCoordinator.h +27 -0
- package/ios/utils/ENRMLatexErrorCoordinator.mm +75 -0
- package/ios/utils/ENRMLatexErrorReporting.h +13 -0
- package/ios/utils/ENRMLinkContextMenus.h +93 -0
- package/ios/utils/ENRMLinkContextMenus.m +178 -0
- package/ios/utils/ENRMLinkRegexConfig.h +30 -0
- package/ios/utils/ENRMLinkRegexConfig.mm +104 -0
- package/ios/utils/ENRMLinkRegexProps.h +23 -0
- package/ios/utils/ENRMLocalImageLoader.h +35 -0
- package/ios/utils/ENRMLocalImageLoader.m +111 -0
- package/ios/utils/ENRMMenuAction.h +27 -0
- package/ios/utils/ENRMMenuAction.m +33 -0
- package/ios/utils/ENRMSpoilerOverlayManager.h +15 -0
- package/ios/utils/ENRMSpoilerOverlayManager.m +19 -0
- package/ios/utils/ENRMSpoilerTapUtils.h +6 -0
- package/ios/utils/ENRMSpoilerTapUtils.m +11 -0
- package/ios/utils/ENRMTailFadeInAnimator.h +16 -0
- package/ios/utils/ENRMTailFadeInAnimator.m +161 -0
- package/ios/utils/ENRMTextHitTest.h +23 -0
- package/ios/utils/ENRMTextHitTest.m +20 -0
- package/ios/utils/ENRMTextInteractionUtils.h +20 -0
- package/ios/utils/ENRMTextInteractionUtils.m +15 -0
- package/ios/utils/ENRMTextRenderer.h +38 -0
- package/ios/utils/ENRMTextRenderer.m +54 -0
- package/ios/utils/ENRMTextViewSetup.h +132 -0
- package/ios/utils/ENRMUIKit.h +429 -0
- package/ios/utils/EditMenuUtils.h +105 -0
- package/ios/utils/EditMenuUtils.m +143 -0
- package/ios/utils/FactoidBackground.h +20 -0
- package/ios/utils/FactoidBackground.m +161 -0
- package/ios/utils/FontScaleObserver.h +10 -0
- package/ios/utils/FontScaleObserver.m +55 -0
- package/ios/utils/FontUtils.h +31 -0
- package/ios/utils/FontUtils.m +63 -0
- package/ios/utils/HTMLGenerator.h +25 -0
- package/ios/utils/HTMLGenerator.m +1041 -0
- package/ios/utils/HeightUpdateUtils.h +25 -0
- package/ios/utils/ImageRequestHeaderUtils.h +35 -0
- package/ios/utils/LastElementUtils.h +97 -0
- package/ios/utils/LinkContextMenuUtils.h +55 -0
- package/ios/utils/LinkPillContentUtils.h +46 -0
- package/ios/utils/LinkTapUtils.h +56 -0
- package/ios/utils/LinkTapUtils.m +139 -0
- package/ios/utils/ListMarkerDrawer.h +15 -0
- package/ios/utils/ListMarkerDrawer.m +239 -0
- package/ios/utils/MentionBackground.h +26 -0
- package/ios/utils/MentionBackground.m +86 -0
- package/ios/utils/ParagraphStyleUtils.h +87 -0
- package/ios/utils/ParagraphStyleUtils.m +484 -0
- package/ios/utils/PasteboardUtils.h +48 -0
- package/ios/utils/PasteboardUtils.m +166 -0
- package/ios/utils/RTFExportUtils.h +24 -0
- package/ios/utils/RTFExportUtils.m +299 -0
- package/ios/utils/RuntimeKeys.h +44 -0
- package/ios/utils/RuntimeKeys.m +13 -0
- package/ios/utils/SelectionColorUtils.h +14 -0
- package/ios/utils/StylePropsUtils.h +1340 -0
- package/ios/utils/TaskListTapUtils.h +6 -0
- package/ios/utils/TaskListTapUtils.m +14 -0
- package/ios/utils/TextViewLayoutManager.h +14 -0
- package/ios/utils/TextViewLayoutManager.mm +198 -0
- package/ios/utils/TiptapAccessibilityElementBuilder.h +43 -0
- package/ios/utils/TiptapAccessibilityElementBuilder.m +432 -0
- package/ios/utils/TiptapExtractor.h +17 -0
- package/ios/utils/TiptapExtractor.m +367 -0
- package/ios/views/ENRMTiptapTextView.h +25 -0
- package/ios/views/ENRMTiptapTextView.m +247 -0
- package/package.json +70 -6
- package/react-native.config.js +10 -0
- package/src/EnrichedTiptapTextNativeComponent.ts +739 -0
- package/src/RichText.tsx +164 -0
- package/src/admonitionDefaults.ts +58 -0
- package/src/darkModeTextStyle.ts +99 -0
- package/src/headingDefaults.ts +21 -0
- package/src/index.tsx +4 -0
- package/src/linkVariantUtils.ts +120 -0
- package/src/normalizeTiptapStyle.ts +397 -0
- package/src/rn-globals.d.ts +1 -0
- package/src/styleUtils.ts +107 -0
- package/src/types/TiptapStyle.ts +532 -0
- package/src/types/TiptapStyleInternal.ts +299 -0
- package/src/types/linkPill.ts +9 -0
- package/src/utils/isDev.ts +4 -0
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
package com.renderrichtext.spans
|
|
2
|
+
|
|
3
|
+
import android.graphics.Canvas
|
|
4
|
+
import android.graphics.Paint
|
|
5
|
+
import android.text.Spanned
|
|
6
|
+
import android.text.TextPaint
|
|
7
|
+
import android.text.style.CharacterStyle
|
|
8
|
+
import android.text.style.MetricAffectingSpan
|
|
9
|
+
import android.text.style.ReplacementSpan
|
|
10
|
+
import kotlin.math.ceil
|
|
11
|
+
import kotlin.math.max
|
|
12
|
+
import kotlin.math.min
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Horizontal gap at one edge of a factoid. The background is measured from the
|
|
16
|
+
* layout, so the glyphs sit inside the span and the next run starts after it.
|
|
17
|
+
*
|
|
18
|
+
* The gap is added to the edge word's advance. It is not its own character:
|
|
19
|
+
* Android splits measurement at each metric-span boundary, so a padding character
|
|
20
|
+
* before the word is an 8px run that fits on the previous line while the word
|
|
21
|
+
* wraps. [getSize] reports the word plus the gap, and the line breaker wraps
|
|
22
|
+
* that as one unit.
|
|
23
|
+
*/
|
|
24
|
+
internal class FactoidPaddingSpan(
|
|
25
|
+
private val padStart: Boolean,
|
|
26
|
+
private val padEnd: Boolean,
|
|
27
|
+
) : ReplacementSpan() {
|
|
28
|
+
override fun getSize(
|
|
29
|
+
paint: Paint,
|
|
30
|
+
text: CharSequence,
|
|
31
|
+
start: Int,
|
|
32
|
+
end: Int,
|
|
33
|
+
fm: Paint.FontMetricsInt?,
|
|
34
|
+
): Int {
|
|
35
|
+
val spanned = text as? Spanned
|
|
36
|
+
val spanStart = spanned?.getSpanStart(this)?.takeIf { it >= 0 } ?: start
|
|
37
|
+
val spanEnd = spanned?.getSpanEnd(this)?.takeIf { it >= 0 } ?: end
|
|
38
|
+
var width = 0f
|
|
39
|
+
var metricsSet = false
|
|
40
|
+
walk(text, start, end, paint) { runStart, runEnd, runPaint ->
|
|
41
|
+
width += runPaint.measureText(text, runStart, runEnd)
|
|
42
|
+
if (fm != null) {
|
|
43
|
+
val metrics = runPaint.fontMetricsInt
|
|
44
|
+
if (!metricsSet) {
|
|
45
|
+
fm.ascent = metrics.ascent
|
|
46
|
+
fm.descent = metrics.descent
|
|
47
|
+
fm.top = metrics.top
|
|
48
|
+
fm.bottom = metrics.bottom
|
|
49
|
+
metricsSet = true
|
|
50
|
+
} else {
|
|
51
|
+
fm.ascent = min(fm.ascent, metrics.ascent)
|
|
52
|
+
fm.top = min(fm.top, metrics.top)
|
|
53
|
+
fm.descent = max(fm.descent, metrics.descent)
|
|
54
|
+
fm.bottom = max(fm.bottom, metrics.bottom)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (fm != null && !metricsSet) {
|
|
59
|
+
paint.getFontMetricsInt(fm)
|
|
60
|
+
}
|
|
61
|
+
if (padStart && start <= spanStart) width += WIDTH
|
|
62
|
+
if (padEnd && end >= spanEnd) width += WIDTH
|
|
63
|
+
return ceil(width).toInt()
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
override fun draw(
|
|
67
|
+
canvas: Canvas,
|
|
68
|
+
text: CharSequence,
|
|
69
|
+
start: Int,
|
|
70
|
+
end: Int,
|
|
71
|
+
x: Float,
|
|
72
|
+
top: Int,
|
|
73
|
+
y: Int,
|
|
74
|
+
bottom: Int,
|
|
75
|
+
paint: Paint,
|
|
76
|
+
) {
|
|
77
|
+
val spanned = text as? Spanned
|
|
78
|
+
val spanStart = spanned?.getSpanStart(this)?.takeIf { it >= 0 } ?: start
|
|
79
|
+
val baseShift = (paint as? TextPaint)?.baselineShift ?: 0
|
|
80
|
+
var cursor = x
|
|
81
|
+
if (padStart && start <= spanStart) cursor += WIDTH
|
|
82
|
+
walk(text, start, end, paint) { runStart, runEnd, runPaint ->
|
|
83
|
+
val baseline = y + (runPaint.baselineShift - baseShift).toFloat()
|
|
84
|
+
canvas.drawText(text, runStart, runEnd, cursor, baseline, runPaint)
|
|
85
|
+
cursor += runPaint.measureText(text, runStart, runEnd)
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
companion object {
|
|
90
|
+
const val WIDTH = 8
|
|
91
|
+
const val MARK = '\u2060'
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
private const val MAX_GLUE = 64
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Where a leading or trailing gap attaches. [runStart] is the first text
|
|
99
|
+
* character of the word (including same-line spaces); [runEnd] is just past it.
|
|
100
|
+
* Neither range includes a line break.
|
|
101
|
+
*/
|
|
102
|
+
internal class FactoidEdge(
|
|
103
|
+
val runStart: Int,
|
|
104
|
+
val runEnd: Int,
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
internal fun leadingFactoidEdge(
|
|
108
|
+
text: CharSequence,
|
|
109
|
+
start: Int,
|
|
110
|
+
end: Int,
|
|
111
|
+
): FactoidEdge? {
|
|
112
|
+
var index = start
|
|
113
|
+
while (index < end && isLineBreak(text[index])) index++
|
|
114
|
+
if (index >= end) return null
|
|
115
|
+
val runStart = index
|
|
116
|
+
while (index < end && isInlineSpace(text[index])) index++
|
|
117
|
+
if (index >= end || isLineBreak(text[index]) || text.replacementAt(index)) return null
|
|
118
|
+
val runEnd = consumeForward(text, index, end)
|
|
119
|
+
if (runEnd <= index) return null
|
|
120
|
+
return FactoidEdge(runStart, runEnd)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
internal fun trailingFactoidEdge(
|
|
124
|
+
text: CharSequence,
|
|
125
|
+
start: Int,
|
|
126
|
+
end: Int,
|
|
127
|
+
): FactoidEdge? {
|
|
128
|
+
var limit = end
|
|
129
|
+
while (limit > start && isLineBreak(text[limit - 1])) limit--
|
|
130
|
+
if (limit <= start) return null
|
|
131
|
+
var wordEnd = limit
|
|
132
|
+
while (wordEnd > start && isInlineSpace(text[wordEnd - 1])) wordEnd--
|
|
133
|
+
if (wordEnd <= start || text.replacementAt(wordEnd - 1)) return null
|
|
134
|
+
val wordStart = consumeBackward(text, start, wordEnd)
|
|
135
|
+
if (wordStart >= wordEnd) return null
|
|
136
|
+
return FactoidEdge(wordStart, limit)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
private fun consumeForward(
|
|
140
|
+
text: CharSequence,
|
|
141
|
+
start: Int,
|
|
142
|
+
end: Int,
|
|
143
|
+
): Int {
|
|
144
|
+
if (start >= end) return start
|
|
145
|
+
var index = Character.offsetByCodePoints(text, start, 1)
|
|
146
|
+
var consumed = 1
|
|
147
|
+
while (index < end && consumed < MAX_GLUE && !canBreakBefore(text, index)) {
|
|
148
|
+
index = Character.offsetByCodePoints(text, index, 1)
|
|
149
|
+
consumed++
|
|
150
|
+
}
|
|
151
|
+
return index
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
private fun consumeBackward(
|
|
155
|
+
text: CharSequence,
|
|
156
|
+
start: Int,
|
|
157
|
+
end: Int,
|
|
158
|
+
): Int {
|
|
159
|
+
if (end <= start) return end
|
|
160
|
+
var index = end
|
|
161
|
+
var consumed = 0
|
|
162
|
+
while (index > start && consumed < MAX_GLUE) {
|
|
163
|
+
if (consumed > 0 && canBreakBefore(text, index)) break
|
|
164
|
+
index = Character.offsetByCodePoints(text, index, -1)
|
|
165
|
+
consumed++
|
|
166
|
+
}
|
|
167
|
+
return index
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
private fun canBreakBefore(
|
|
171
|
+
text: CharSequence,
|
|
172
|
+
index: Int,
|
|
173
|
+
): Boolean {
|
|
174
|
+
if (index <= 0 || index >= text.length) return false
|
|
175
|
+
val codePoint = Character.codePointAt(text, index)
|
|
176
|
+
val previous = Character.codePointBefore(text, index)
|
|
177
|
+
if (Character.isWhitespace(previous) || previous == FactoidPaddingSpan.MARK.code) return true
|
|
178
|
+
if (isCjk(codePoint) || isCjk(previous)) return true
|
|
179
|
+
if (text.replacementAt(index)) return true
|
|
180
|
+
return false
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
private fun isCjk(codePoint: Int): Boolean =
|
|
184
|
+
codePoint in 0x2E80..0x9FFF || codePoint in 0xAC00..0xD7AF || codePoint in 0xF900..0xFAFF
|
|
185
|
+
|
|
186
|
+
private fun isLineBreak(c: Char): Boolean = c == '\n' || c == '\r' || c == '\u2028' || c == '\u2029'
|
|
187
|
+
|
|
188
|
+
private fun isInlineSpace(c: Char): Boolean = c.isWhitespace() && !isLineBreak(c)
|
|
189
|
+
|
|
190
|
+
private fun CharSequence.replacementAt(index: Int): Boolean {
|
|
191
|
+
val spanned = this as? Spanned ?: return false
|
|
192
|
+
if (index < 0 || index >= length) return false
|
|
193
|
+
val next = index + 1
|
|
194
|
+
return spanned.getSpans(index, next, ReplacementSpan::class.java).isNotEmpty()
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
private fun walk(
|
|
198
|
+
text: CharSequence,
|
|
199
|
+
start: Int,
|
|
200
|
+
end: Int,
|
|
201
|
+
paint: Paint,
|
|
202
|
+
block: (runStart: Int, runEnd: Int, runPaint: TextPaint) -> Unit,
|
|
203
|
+
) {
|
|
204
|
+
val spanned = text as? Spanned
|
|
205
|
+
val base = if (paint is TextPaint) paint else TextPaint(paint)
|
|
206
|
+
var index = start
|
|
207
|
+
while (index < end) {
|
|
208
|
+
if (text[index] == FactoidPaddingSpan.MARK) {
|
|
209
|
+
index++
|
|
210
|
+
continue
|
|
211
|
+
}
|
|
212
|
+
val transition = if (spanned == null) end else spanned.nextSpanTransition(index, end, CharacterStyle::class.java)
|
|
213
|
+
var runEnd = index
|
|
214
|
+
while (runEnd < transition && text[runEnd] != FactoidPaddingSpan.MARK) runEnd++
|
|
215
|
+
if (runEnd == index) {
|
|
216
|
+
index++
|
|
217
|
+
continue
|
|
218
|
+
}
|
|
219
|
+
val runPaint = TextPaint(base)
|
|
220
|
+
if (spanned != null) applyStyles(spanned, index, runEnd, runPaint)
|
|
221
|
+
block(index, runEnd, runPaint)
|
|
222
|
+
index = if (runEnd < transition) runEnd else transition
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
private fun applyStyles(
|
|
227
|
+
text: Spanned,
|
|
228
|
+
start: Int,
|
|
229
|
+
end: Int,
|
|
230
|
+
paint: TextPaint,
|
|
231
|
+
) {
|
|
232
|
+
val spans = text.getSpans(start, end, CharacterStyle::class.java)
|
|
233
|
+
for (span in spans) {
|
|
234
|
+
if (span is ReplacementSpan) continue
|
|
235
|
+
if (span is MetricAffectingSpan) span.updateMeasureState(paint)
|
|
236
|
+
span.updateDrawState(paint)
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/** Drops factoid padding marks. A word joiner that came from the document stays. */
|
|
241
|
+
internal fun CharSequence.stripFactoidPadding(): String {
|
|
242
|
+
val spanned = this as? Spanned ?: return toString()
|
|
243
|
+
val spans = spanned.getSpans(0, length, FactoidPaddingSpan::class.java)
|
|
244
|
+
if (spans.isEmpty()) return toString()
|
|
245
|
+
val skip = BooleanArray(length)
|
|
246
|
+
for (span in spans) {
|
|
247
|
+
val spanStart = spanned.getSpanStart(span).coerceAtLeast(0)
|
|
248
|
+
val spanEnd = spanned.getSpanEnd(span).coerceAtMost(length)
|
|
249
|
+
for (index in spanStart until spanEnd) {
|
|
250
|
+
if (this[index] == FactoidPaddingSpan.MARK) skip[index] = true
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
val out = StringBuilder(length)
|
|
254
|
+
for (index in 0 until length) {
|
|
255
|
+
if (!skip[index]) out.append(this[index])
|
|
256
|
+
}
|
|
257
|
+
return out.toString()
|
|
258
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
package com.renderrichtext.spans
|
|
2
|
+
|
|
3
|
+
import android.text.TextPaint
|
|
4
|
+
import android.text.style.ClickableSpan
|
|
5
|
+
import android.view.View
|
|
6
|
+
import com.renderrichtext.EnrichedTiptapText
|
|
7
|
+
import com.renderrichtext.renderer.SpanStyleCache
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Click target for a factoid. The surrounding font is left alone. Text color is the cached
|
|
11
|
+
* factoid color, the same value [com.renderrichtext.spans.CodeSpan] reads for inline code.
|
|
12
|
+
* A link color already on the paint is left in place.
|
|
13
|
+
*/
|
|
14
|
+
class FactoidSpan(
|
|
15
|
+
private val styleCache: SpanStyleCache,
|
|
16
|
+
val factoidId: String,
|
|
17
|
+
private val onFactoidPress: ((String) -> Unit)?,
|
|
18
|
+
private val textColorOverride: Int? = null,
|
|
19
|
+
) : ClickableSpan() {
|
|
20
|
+
/** True while a finger is down on this factoid. The background span reads it while drawing. */
|
|
21
|
+
var pressed: Boolean = false
|
|
22
|
+
|
|
23
|
+
override fun onClick(widget: View) {
|
|
24
|
+
onFactoidPress?.invoke(factoidId) ?: (widget as? EnrichedTiptapText)?.emitOnFactoidPress(factoidId)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
override fun updateDrawState(textPaint: TextPaint) {
|
|
28
|
+
val color = textColorOverride ?: styleCache.factoidColor
|
|
29
|
+
if (textPaint.color != color && textPaint.color in styleCache.colorsToPreserve) return
|
|
30
|
+
textPaint.color = color
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
package com.renderrichtext.spans
|
|
2
|
+
|
|
3
|
+
import android.os.Build
|
|
4
|
+
import android.text.TextPaint
|
|
5
|
+
import android.text.style.CharacterStyle
|
|
6
|
+
import androidx.annotation.FloatRange
|
|
7
|
+
|
|
8
|
+
class FadeInSpan : CharacterStyle() {
|
|
9
|
+
@setparam:FloatRange(from = 0.0, to = 1.0)
|
|
10
|
+
var alpha: Float = 0f
|
|
11
|
+
|
|
12
|
+
override fun updateDrawState(tp: TextPaint) {
|
|
13
|
+
tp.color = multiplyAlpha(tp.color, alpha)
|
|
14
|
+
// Public from API 29; below that, underlines are drawn in `color`, which is already faded.
|
|
15
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
|
16
|
+
tp.underlineColor = multiplyAlpha(tp.underlineColor, alpha)
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
private fun multiplyAlpha(
|
|
21
|
+
color: Int,
|
|
22
|
+
alpha: Float,
|
|
23
|
+
): Int {
|
|
24
|
+
if (alpha >= 1f) return color
|
|
25
|
+
if (alpha <= 0f) return color and 0x00FFFFFF
|
|
26
|
+
val a = ((color ushr 24) * alpha).toInt()
|
|
27
|
+
return (a shl 24) or (color and 0x00FFFFFF)
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
package com.renderrichtext.spans
|
|
2
|
+
|
|
3
|
+
import android.annotation.SuppressLint
|
|
4
|
+
import android.graphics.Typeface
|
|
5
|
+
import android.text.TextPaint
|
|
6
|
+
import android.text.style.MetricAffectingSpan
|
|
7
|
+
import com.renderrichtext.styles.StyleConfig
|
|
8
|
+
|
|
9
|
+
class HeadingSpan(
|
|
10
|
+
val level: Int,
|
|
11
|
+
styleConfig: StyleConfig,
|
|
12
|
+
) : MetricAffectingSpan() {
|
|
13
|
+
private val fontSize: Float = styleConfig.headingStyles[level]!!.fontSize
|
|
14
|
+
private val color: Int = styleConfig.headingStyles[level]!!.color
|
|
15
|
+
private val cachedTypeface: Typeface? = styleConfig.headingTypefaces[level]
|
|
16
|
+
|
|
17
|
+
override fun updateDrawState(tp: TextPaint) {
|
|
18
|
+
applyHeadingStyle(tp)
|
|
19
|
+
tp.color = color
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
override fun updateMeasureState(tp: TextPaint) {
|
|
23
|
+
applyHeadingStyle(tp)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
@SuppressLint("WrongConstant") // Result of mask is always valid: 0, 1, 2, or 3
|
|
27
|
+
private fun applyHeadingStyle(tp: TextPaint) {
|
|
28
|
+
tp.textSize = fontSize
|
|
29
|
+
cachedTypeface?.let { base ->
|
|
30
|
+
val preserved = (tp.typeface?.style ?: 0) and BOLD_ITALIC_MASK
|
|
31
|
+
tp.typeface = if (preserved != 0) Typeface.create(base, preserved) else base
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
companion object {
|
|
36
|
+
private const val BOLD_ITALIC_MASK = Typeface.BOLD or Typeface.ITALIC
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
package com.renderrichtext.spans
|
|
2
|
+
|
|
3
|
+
import android.graphics.Canvas
|
|
4
|
+
import android.graphics.Color
|
|
5
|
+
import android.graphics.Paint
|
|
6
|
+
import android.text.Spanned
|
|
7
|
+
import android.text.TextPaint
|
|
8
|
+
import android.text.style.CharacterStyle
|
|
9
|
+
import android.text.style.LineBackgroundSpan
|
|
10
|
+
import com.renderrichtext.renderer.BlockStyle
|
|
11
|
+
import com.renderrichtext.renderer.SpanStyleCache
|
|
12
|
+
import kotlin.math.max
|
|
13
|
+
import kotlin.math.min
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* A plain [CharacterStyle], not a `MetricAffectingSpan`, so nested strong/emphasis spans inside
|
|
17
|
+
* ==highlight== keep their typeface and size. The background is a [LineBackgroundSpan] rather
|
|
18
|
+
* than [TextPaint.bgColor], which fills the whole line box and floats above the text once
|
|
19
|
+
* [LineHeightSpan] pads it out to the configured line height.
|
|
20
|
+
*/
|
|
21
|
+
class HighlightSpan(
|
|
22
|
+
private val styleCache: SpanStyleCache,
|
|
23
|
+
private val blockStyle: BlockStyle,
|
|
24
|
+
) : CharacterStyle(),
|
|
25
|
+
LineBackgroundSpan {
|
|
26
|
+
private val foregroundColor = styleCache.getHighlightColorFor(blockStyle.color)
|
|
27
|
+
private val backgroundPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply { style = Paint.Style.FILL }
|
|
28
|
+
|
|
29
|
+
override fun updateDrawState(textPaint: TextPaint) {
|
|
30
|
+
textPaint.color = foregroundColor
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
override fun drawBackground(
|
|
34
|
+
canvas: Canvas,
|
|
35
|
+
p: Paint,
|
|
36
|
+
left: Int,
|
|
37
|
+
right: Int,
|
|
38
|
+
top: Int,
|
|
39
|
+
baseline: Int,
|
|
40
|
+
bottom: Int,
|
|
41
|
+
text: CharSequence,
|
|
42
|
+
start: Int,
|
|
43
|
+
end: Int,
|
|
44
|
+
lineNum: Int,
|
|
45
|
+
) {
|
|
46
|
+
val backgroundColor = styleCache.highlightBackgroundColor
|
|
47
|
+
if (Color.alpha(backgroundColor) == 0) return
|
|
48
|
+
if (text !is Spanned) return
|
|
49
|
+
|
|
50
|
+
val spanStart = text.getSpanStart(this)
|
|
51
|
+
val spanEnd = text.getSpanEnd(this)
|
|
52
|
+
if (spanStart !in 0 until spanEnd) return
|
|
53
|
+
|
|
54
|
+
val isFirst = spanStart >= start
|
|
55
|
+
val isLast = spanEnd <= end
|
|
56
|
+
|
|
57
|
+
val leadingMargin = InlineBackgroundGeometry.leadingMarginAt(text, start)
|
|
58
|
+
val startX =
|
|
59
|
+
if (isFirst) {
|
|
60
|
+
InlineBackgroundGeometry.horizontalOffset(text, start, end, spanStart, p, leadingMargin) + left
|
|
61
|
+
} else {
|
|
62
|
+
left.toFloat() + leadingMargin
|
|
63
|
+
}
|
|
64
|
+
val endX =
|
|
65
|
+
if (isLast) {
|
|
66
|
+
InlineBackgroundGeometry.horizontalOffset(text, start, end, spanEnd, p, leadingMargin) + left
|
|
67
|
+
} else {
|
|
68
|
+
right.toFloat()
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Bound by the glyphs' ascent/descent, clamped to the line box so a tall line height never
|
|
72
|
+
// lets the band bleed into its neighbours.
|
|
73
|
+
val metrics = p.fontMetricsInt
|
|
74
|
+
val bandTop = max(top.toFloat(), (baseline + metrics.ascent).toFloat())
|
|
75
|
+
val bandBottom = min(bottom.toFloat(), (baseline + metrics.descent).toFloat())
|
|
76
|
+
|
|
77
|
+
backgroundPaint.color = backgroundColor
|
|
78
|
+
canvas.drawRect(min(startX, endX), bandTop, max(startX, endX), bandBottom, backgroundPaint)
|
|
79
|
+
}
|
|
80
|
+
}
|