@mathers101/react-native-render-rich-text 0.0.0-stage → 0.1.9
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,216 @@
|
|
|
1
|
+
package com.renderrichtext.spans
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.graphics.Canvas
|
|
5
|
+
import android.graphics.Paint
|
|
6
|
+
import android.graphics.Path
|
|
7
|
+
import android.graphics.RectF
|
|
8
|
+
import android.text.Layout
|
|
9
|
+
import android.text.Spanned
|
|
10
|
+
import android.text.TextPaint
|
|
11
|
+
import android.text.style.LeadingMarginSpan
|
|
12
|
+
import android.text.style.LineBackgroundSpan
|
|
13
|
+
import android.text.style.MetricAffectingSpan
|
|
14
|
+
import androidx.core.graphics.withSave
|
|
15
|
+
import com.renderrichtext.renderer.SpanStyleCache
|
|
16
|
+
import com.renderrichtext.styles.CodeBlockStyle
|
|
17
|
+
import com.renderrichtext.utils.text.extensions.applyCodeBlockTextStyle
|
|
18
|
+
import com.renderrichtext.utils.text.extensions.applyColorPreserving
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Draws the commonmark-flavor code block box as per-line strips. The visual
|
|
22
|
+
* conventions (half-stroke border inset, radius reduced by that inset) must
|
|
23
|
+
* stay in sync with the whole-rect box the github flavor draws in
|
|
24
|
+
* CodeBlockContainerView.
|
|
25
|
+
*/
|
|
26
|
+
class CodeBlockSpan(
|
|
27
|
+
private val codeBlockStyle: CodeBlockStyle,
|
|
28
|
+
private val context: Context,
|
|
29
|
+
private val styleCache: SpanStyleCache,
|
|
30
|
+
private val leadingIndent: Int = 0,
|
|
31
|
+
// Recovered by a tap on this span for onCodeBlockPress; unused by drawing.
|
|
32
|
+
val code: String = "",
|
|
33
|
+
val language: String = "",
|
|
34
|
+
) : MetricAffectingSpan(),
|
|
35
|
+
LineBackgroundSpan,
|
|
36
|
+
LeadingMarginSpan {
|
|
37
|
+
private val path = Path()
|
|
38
|
+
private val rect = RectF()
|
|
39
|
+
private val arcRect = RectF()
|
|
40
|
+
private val radiiArray = FloatArray(8)
|
|
41
|
+
|
|
42
|
+
companion object {
|
|
43
|
+
private val sharedBackgroundPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply { style = Paint.Style.FILL }
|
|
44
|
+
private val sharedBorderPaint =
|
|
45
|
+
Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
|
46
|
+
style = Paint.Style.STROKE
|
|
47
|
+
strokeCap = Paint.Cap.BUTT
|
|
48
|
+
strokeJoin = Paint.Join.ROUND
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
private fun configureBackgroundPaint(): Paint =
|
|
53
|
+
sharedBackgroundPaint.apply {
|
|
54
|
+
color = codeBlockStyle.backgroundColor
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
private fun configureBorderPaint(): Paint =
|
|
58
|
+
sharedBorderPaint.apply {
|
|
59
|
+
strokeWidth = codeBlockStyle.borderWidth
|
|
60
|
+
color = codeBlockStyle.borderColor
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
override fun getLeadingMargin(first: Boolean): Int = codeBlockStyle.padding.toInt() + leadingIndent
|
|
64
|
+
|
|
65
|
+
override fun drawLeadingMargin(
|
|
66
|
+
c: Canvas?,
|
|
67
|
+
p: Paint?,
|
|
68
|
+
x: Int,
|
|
69
|
+
dir: Int,
|
|
70
|
+
top: Int,
|
|
71
|
+
baseline: Int,
|
|
72
|
+
bottom: Int,
|
|
73
|
+
text: CharSequence?,
|
|
74
|
+
start: Int,
|
|
75
|
+
end: Int,
|
|
76
|
+
first: Boolean,
|
|
77
|
+
layout: Layout?,
|
|
78
|
+
) { /* Leading margin is handled by getLeadingMargin */ }
|
|
79
|
+
|
|
80
|
+
override fun updateMeasureState(tp: TextPaint) = applyTextStyle(tp)
|
|
81
|
+
|
|
82
|
+
override fun updateDrawState(tp: TextPaint) = applyTextStyle(tp)
|
|
83
|
+
|
|
84
|
+
override fun drawBackground(
|
|
85
|
+
canvas: Canvas,
|
|
86
|
+
p: Paint,
|
|
87
|
+
left: Int,
|
|
88
|
+
right: Int,
|
|
89
|
+
top: Int,
|
|
90
|
+
baseline: Int,
|
|
91
|
+
bottom: Int,
|
|
92
|
+
text: CharSequence,
|
|
93
|
+
start: Int,
|
|
94
|
+
end: Int,
|
|
95
|
+
lineNum: Int,
|
|
96
|
+
) {
|
|
97
|
+
if (text !is Spanned) return
|
|
98
|
+
|
|
99
|
+
val spanStart = text.getSpanStart(this)
|
|
100
|
+
val spanEnd = text.getSpanEnd(this)
|
|
101
|
+
if (spanStart !in 0 until spanEnd) return
|
|
102
|
+
|
|
103
|
+
val isFirstLine = start == spanStart
|
|
104
|
+
val isLastLine = isLastDrawnLine(text, end, spanEnd)
|
|
105
|
+
|
|
106
|
+
val inset = codeBlockStyle.borderWidth / 2f
|
|
107
|
+
|
|
108
|
+
rect.set(
|
|
109
|
+
left.toFloat() + leadingIndent + inset,
|
|
110
|
+
top.toFloat() + (if (isFirstLine) inset else 0f),
|
|
111
|
+
right.toFloat() - inset,
|
|
112
|
+
bottom.toFloat() - (if (isLastLine) inset else 0f),
|
|
113
|
+
)
|
|
114
|
+
if (rect.left >= rect.right) return
|
|
115
|
+
|
|
116
|
+
val radius = codeBlockStyle.borderRadius
|
|
117
|
+
val adjRadius = if (radius > inset) radius - inset else radius
|
|
118
|
+
|
|
119
|
+
// Reset and fill radii array based on boundary state
|
|
120
|
+
radiiArray.fill(0f)
|
|
121
|
+
if (isFirstLine) {
|
|
122
|
+
radiiArray[0] = adjRadius
|
|
123
|
+
radiiArray[1] = adjRadius // Top-Left
|
|
124
|
+
radiiArray[2] = adjRadius
|
|
125
|
+
radiiArray[3] = adjRadius // Top-Right
|
|
126
|
+
}
|
|
127
|
+
if (isLastLine) {
|
|
128
|
+
radiiArray[4] = adjRadius
|
|
129
|
+
radiiArray[5] = adjRadius // Bottom-Right
|
|
130
|
+
radiiArray[6] = adjRadius
|
|
131
|
+
radiiArray[7] = adjRadius // Bottom-Left
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
path.reset()
|
|
135
|
+
path.addRoundRect(rect, radiiArray, Path.Direction.CW)
|
|
136
|
+
|
|
137
|
+
val backgroundPaint = configureBackgroundPaint()
|
|
138
|
+
val borderPaint = configureBorderPaint()
|
|
139
|
+
|
|
140
|
+
canvas.withSave {
|
|
141
|
+
drawPath(path, backgroundPaint)
|
|
142
|
+
|
|
143
|
+
if (codeBlockStyle.borderWidth > 0) {
|
|
144
|
+
val bLeft = rect.left
|
|
145
|
+
val bRight = rect.right
|
|
146
|
+
val bTop = rect.top
|
|
147
|
+
val bBottom = rect.bottom
|
|
148
|
+
|
|
149
|
+
when {
|
|
150
|
+
// Case: Single-line code block
|
|
151
|
+
isFirstLine && isLastLine -> {
|
|
152
|
+
drawPath(path, borderPaint)
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Case: Top of a multi-line block
|
|
156
|
+
isFirstLine -> {
|
|
157
|
+
drawLine(bLeft + adjRadius, bTop, bRight - adjRadius, bTop, borderPaint)
|
|
158
|
+
drawLine(bLeft, bTop + adjRadius, bLeft, bBottom, borderPaint)
|
|
159
|
+
drawLine(bRight, bTop + adjRadius, bRight, bBottom, borderPaint)
|
|
160
|
+
|
|
161
|
+
arcRect.set(bLeft, bTop, bLeft + 2 * adjRadius, bTop + 2 * adjRadius)
|
|
162
|
+
drawArc(arcRect, 180f, 90f, false, borderPaint)
|
|
163
|
+
|
|
164
|
+
arcRect.set(bRight - 2 * adjRadius, bTop, bRight, bTop + 2 * adjRadius)
|
|
165
|
+
drawArc(arcRect, 270f, 90f, false, borderPaint)
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Case: Bottom of a multi-line block
|
|
169
|
+
isLastLine -> {
|
|
170
|
+
drawLine(bLeft + adjRadius, bBottom, bRight - adjRadius, bBottom, borderPaint)
|
|
171
|
+
drawLine(bLeft, bTop, bLeft, bBottom - adjRadius, borderPaint)
|
|
172
|
+
drawLine(bRight, bTop, bRight, bBottom - adjRadius, borderPaint)
|
|
173
|
+
|
|
174
|
+
arcRect.set(bLeft, bBottom - 2 * adjRadius, bLeft + 2 * adjRadius, bBottom)
|
|
175
|
+
drawArc(arcRect, 90f, 90f, false, borderPaint)
|
|
176
|
+
|
|
177
|
+
arcRect.set(bRight - 2 * adjRadius, bBottom - 2 * adjRadius, bRight, bBottom)
|
|
178
|
+
drawArc(arcRect, 0f, 90f, false, borderPaint)
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Case: Middle lines only need vertical sides
|
|
182
|
+
else -> {
|
|
183
|
+
drawLine(bLeft, bTop, bLeft, bBottom, borderPaint)
|
|
184
|
+
drawLine(bRight, bTop, bRight, bBottom, borderPaint)
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
private fun applyTextStyle(tp: TextPaint) {
|
|
192
|
+
tp.applyCodeBlockTextStyle(codeBlockStyle, context)
|
|
193
|
+
|
|
194
|
+
tp.applyColorPreserving(codeBlockStyle.color, *styleCache.colorsToPreserve)
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* True when [lineEnd] is the last drawn line of a span ending at [spanEnd].
|
|
200
|
+
*
|
|
201
|
+
* The span range can include a trailing '\n' that belongs to the last content
|
|
202
|
+
* line rather than forming a line of its own, and the margin newline after the
|
|
203
|
+
* span can push the line end past getSpanEnd. Compare against the end of the
|
|
204
|
+
* visible content, same as [BlockquoteSpan]'s last-line check.
|
|
205
|
+
*/
|
|
206
|
+
internal fun isLastDrawnLine(
|
|
207
|
+
text: CharSequence,
|
|
208
|
+
lineEnd: Int,
|
|
209
|
+
spanEnd: Int,
|
|
210
|
+
): Boolean {
|
|
211
|
+
var visibleEnd = spanEnd.coerceAtMost(text.length)
|
|
212
|
+
while (visibleEnd > 0 && text[visibleEnd - 1] == '\n') {
|
|
213
|
+
visibleEnd--
|
|
214
|
+
}
|
|
215
|
+
return lineEnd >= visibleEnd
|
|
216
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
package com.renderrichtext.spans
|
|
2
|
+
|
|
3
|
+
import android.graphics.Typeface
|
|
4
|
+
import android.text.TextPaint
|
|
5
|
+
import android.text.style.MetricAffectingSpan
|
|
6
|
+
import com.renderrichtext.renderer.BlockStyle
|
|
7
|
+
import com.renderrichtext.renderer.SpanStyleCache
|
|
8
|
+
|
|
9
|
+
class CodeSpan(
|
|
10
|
+
private val styleCache: SpanStyleCache,
|
|
11
|
+
private val blockStyle: BlockStyle,
|
|
12
|
+
) : MetricAffectingSpan() {
|
|
13
|
+
override fun updateDrawState(tp: TextPaint) {
|
|
14
|
+
applyMonospacedFont(tp)
|
|
15
|
+
tp.color = styleCache.codeColor
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
override fun updateMeasureState(tp: TextPaint) {
|
|
19
|
+
applyMonospacedFont(tp)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
private fun applyMonospacedFont(paint: TextPaint) {
|
|
23
|
+
paint.textSize = if (styleCache.codeFontSize > 0) styleCache.codeFontSize else blockStyle.fontSize
|
|
24
|
+
val preservedStyle = (paint.typeface?.style ?: 0) and (Typeface.BOLD or Typeface.ITALIC)
|
|
25
|
+
paint.typeface =
|
|
26
|
+
if (styleCache.codeFontFamily.isNotEmpty()) {
|
|
27
|
+
styleCache.getTypeface(styleCache.codeFontFamily, preservedStyle)
|
|
28
|
+
} else {
|
|
29
|
+
SpanStyleCache.getMonospaceTypeface(preservedStyle)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
package com.renderrichtext.spans
|
|
2
|
+
|
|
3
|
+
import android.graphics.Typeface
|
|
4
|
+
import android.text.TextPaint
|
|
5
|
+
import android.text.style.MetricAffectingSpan
|
|
6
|
+
import com.renderrichtext.renderer.BlockStyle
|
|
7
|
+
import com.renderrichtext.renderer.SpanStyleCache
|
|
8
|
+
import com.renderrichtext.utils.text.extensions.applyColorPreserving
|
|
9
|
+
|
|
10
|
+
class EmphasisSpan(
|
|
11
|
+
private val styleCache: SpanStyleCache,
|
|
12
|
+
private val blockStyle: BlockStyle,
|
|
13
|
+
) : MetricAffectingSpan() {
|
|
14
|
+
override fun updateDrawState(tp: TextPaint) {
|
|
15
|
+
applyEmphasisStyle(tp)
|
|
16
|
+
applyEmphasisColor(tp)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
override fun updateMeasureState(tp: TextPaint) {
|
|
20
|
+
applyEmphasisStyle(tp)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
private fun applyEmphasisStyle(tp: TextPaint) {
|
|
24
|
+
val currentTypeface = tp.typeface ?: Typeface.DEFAULT
|
|
25
|
+
val isBold = (currentTypeface.style) and Typeface.BOLD != 0
|
|
26
|
+
val style = if (isBold) Typeface.BOLD_ITALIC else Typeface.ITALIC
|
|
27
|
+
tp.typeface =
|
|
28
|
+
if (styleCache.emphasisFontFamily.isNotEmpty()) {
|
|
29
|
+
val resolvedStyle = if (styleCache.emphasisFontStyle == "normal") Typeface.NORMAL else style
|
|
30
|
+
styleCache.getTypeface(styleCache.emphasisFontFamily, resolvedStyle)
|
|
31
|
+
} else if (styleCache.emphasisFontStyle == "normal") {
|
|
32
|
+
currentTypeface
|
|
33
|
+
} else {
|
|
34
|
+
Typeface.create(currentTypeface, style)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
private fun applyEmphasisColor(tp: TextPaint) {
|
|
39
|
+
val colorToUse = styleCache.getEmphasisColorFor(blockStyle.color, tp.color)
|
|
40
|
+
tp.applyColorPreserving(colorToUse, *styleCache.colorsToPreserve)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
package com.renderrichtext.spans
|
|
2
|
+
|
|
3
|
+
import android.graphics.Canvas
|
|
4
|
+
import android.graphics.Color
|
|
5
|
+
import android.graphics.Paint
|
|
6
|
+
import android.graphics.Path
|
|
7
|
+
import android.graphics.RectF
|
|
8
|
+
import android.text.Spanned
|
|
9
|
+
import android.text.style.LineBackgroundSpan
|
|
10
|
+
import com.renderrichtext.spoiler.isConcealedBySpoiler
|
|
11
|
+
import com.renderrichtext.styles.StyleConfig
|
|
12
|
+
import kotlin.math.max
|
|
13
|
+
import kotlin.math.min
|
|
14
|
+
|
|
15
|
+
class FactoidBackgroundSpan(
|
|
16
|
+
private val styleConfig: StyleConfig,
|
|
17
|
+
private val backgroundColorOverride: Int? = null,
|
|
18
|
+
private val borderColorOverride: Int? = null,
|
|
19
|
+
) : LineBackgroundSpan {
|
|
20
|
+
companion object {
|
|
21
|
+
private const val CORNER_RADIUS = 10.0f
|
|
22
|
+
private const val BORDER_WIDTH = 1.0f
|
|
23
|
+
private const val PRESSED_DARKEN = 0.82f
|
|
24
|
+
|
|
25
|
+
private val sharedBackgroundPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply { style = Paint.Style.FILL }
|
|
26
|
+
private val sharedBorderPaint =
|
|
27
|
+
Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
|
28
|
+
style = Paint.Style.STROKE
|
|
29
|
+
strokeWidth = BORDER_WIDTH
|
|
30
|
+
strokeJoin = Paint.Join.ROUND
|
|
31
|
+
strokeCap = Paint.Cap.ROUND
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Reusable drawing objects per instance
|
|
36
|
+
private val rect = RectF()
|
|
37
|
+
private val path = Path()
|
|
38
|
+
|
|
39
|
+
override fun drawBackground(
|
|
40
|
+
canvas: Canvas,
|
|
41
|
+
p: Paint,
|
|
42
|
+
left: Int,
|
|
43
|
+
right: Int,
|
|
44
|
+
top: Int,
|
|
45
|
+
baseline: Int,
|
|
46
|
+
bottom: Int,
|
|
47
|
+
text: CharSequence,
|
|
48
|
+
start: Int,
|
|
49
|
+
end: Int,
|
|
50
|
+
lineNum: Int,
|
|
51
|
+
) {
|
|
52
|
+
if (text !is Spanned) return
|
|
53
|
+
|
|
54
|
+
val spanStart = text.getSpanStart(this)
|
|
55
|
+
val spanEnd = text.getSpanEnd(this)
|
|
56
|
+
if (spanStart !in 0 until spanEnd) return
|
|
57
|
+
|
|
58
|
+
// The spoiler overlay only covers the text's glyph box, so a background drawn to the line's bounds
|
|
59
|
+
// would outline the hidden text around it.
|
|
60
|
+
if (text.isConcealedBySpoiler(maxOf(spanStart, start), minOf(spanEnd, end))) return
|
|
61
|
+
|
|
62
|
+
// Keep this span intact for semantic extraction. Draw only portions outside replacement pills,
|
|
63
|
+
// including a factoid surrounding a partially covered run.
|
|
64
|
+
fun drawUncoveredRange(
|
|
65
|
+
rangeStart: Int,
|
|
66
|
+
rangeEnd: Int,
|
|
67
|
+
) {
|
|
68
|
+
if (max(rangeStart, start) >= min(rangeEnd, end)) return
|
|
69
|
+
// A padding mark that the line breaker left behind has no glyphs. Drawing it paints a
|
|
70
|
+
// chip on the previous line after the word has wrapped.
|
|
71
|
+
val inkStart = firstInk(text, rangeStart, rangeEnd)
|
|
72
|
+
val inkEnd = lastInk(text, rangeStart, rangeEnd)
|
|
73
|
+
if (max(inkStart, start) >= min(inkEnd, end)) return
|
|
74
|
+
val isFirst = inkStart in start until end
|
|
75
|
+
val isLast = inkEnd > start && inkEnd <= end
|
|
76
|
+
|
|
77
|
+
val finalBottom = adjustBottomForMargin(text, end, bottom)
|
|
78
|
+
val leadingMargin = InlineBackgroundGeometry.leadingMarginAt(text, start)
|
|
79
|
+
val origin = if (rangeStart >= start) rangeStart else inkStart.coerceAtLeast(start)
|
|
80
|
+
val startX =
|
|
81
|
+
if (isFirst) {
|
|
82
|
+
InlineBackgroundGeometry.horizontalOffset(text, start, end, origin, p, leadingMargin) + left
|
|
83
|
+
} else {
|
|
84
|
+
left.toFloat() + leadingMargin
|
|
85
|
+
}
|
|
86
|
+
// A line break used to run the background out to the line's right edge. Stop at the last glyph.
|
|
87
|
+
// When the edge mark is still on this line, measure through it so the gap stays inside the chip.
|
|
88
|
+
val glyphEnd = if (isLast && rangeEnd <= end) rangeEnd else lastGlyphOffset(text, start, end)
|
|
89
|
+
val endX = InlineBackgroundGeometry.horizontalOffset(text, start, end, glyphEnd, p, leadingMargin) + left
|
|
90
|
+
|
|
91
|
+
rect.set(min(startX, endX), top.toFloat(), max(startX, endX), finalBottom.toFloat())
|
|
92
|
+
// The stroke is centered on the path. Flush with the line edge, its outer half is clipped.
|
|
93
|
+
if (isFirst) {
|
|
94
|
+
val contentLeft = left + leadingMargin.toFloat()
|
|
95
|
+
if (rect.left <= contentLeft) rect.left = contentLeft + BORDER_WIDTH / 2f
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
val factoidStyle = styleConfig.factoidStyle
|
|
99
|
+
var fill = backgroundColorOverride ?: factoidStyle.backgroundColor
|
|
100
|
+
if (isPressed(text)) fill = darken(fill)
|
|
101
|
+
sharedBackgroundPaint.color = fill
|
|
102
|
+
sharedBorderPaint.color = borderColorOverride ?: factoidStyle.borderColor
|
|
103
|
+
drawShapes(canvas, isFirst, isLast)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Runs per factoid span, per line, per draw: only query for pills if the style can produce any.
|
|
107
|
+
val pills =
|
|
108
|
+
if (styleConfig.hasLinkPills) text.getSpans(spanStart, spanEnd, LinkPillSpan::class.java) else emptyArray()
|
|
109
|
+
if (pills.isEmpty()) {
|
|
110
|
+
drawUncoveredRange(spanStart, spanEnd)
|
|
111
|
+
return
|
|
112
|
+
}
|
|
113
|
+
if (pills.size > 1) pills.sortBy { text.getSpanStart(it) }
|
|
114
|
+
var cursor = spanStart
|
|
115
|
+
for (pill in pills) {
|
|
116
|
+
val coveredStart = max(spanStart, text.getSpanStart(pill))
|
|
117
|
+
val coveredEnd = min(spanEnd, text.getSpanEnd(pill))
|
|
118
|
+
if (coveredStart >= coveredEnd) continue
|
|
119
|
+
if (cursor < coveredStart) drawUncoveredRange(cursor, coveredStart)
|
|
120
|
+
cursor = max(cursor, coveredEnd)
|
|
121
|
+
}
|
|
122
|
+
drawUncoveredRange(cursor, spanEnd)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
private fun drawShapes(
|
|
126
|
+
canvas: Canvas,
|
|
127
|
+
isFirst: Boolean,
|
|
128
|
+
isLast: Boolean,
|
|
129
|
+
) {
|
|
130
|
+
path.reset()
|
|
131
|
+
path.addRoundRect(rect, createRadii(isFirst, isLast), Path.Direction.CW)
|
|
132
|
+
canvas.drawPath(path, sharedBackgroundPaint)
|
|
133
|
+
if (isFirst && isLast) {
|
|
134
|
+
canvas.drawPath(path, sharedBorderPaint)
|
|
135
|
+
} else {
|
|
136
|
+
drawOpenBorders(canvas, isFirst, isLast)
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
private fun drawOpenBorders(
|
|
141
|
+
canvas: Canvas,
|
|
142
|
+
isFirst: Boolean,
|
|
143
|
+
isLast: Boolean,
|
|
144
|
+
) {
|
|
145
|
+
val r = CORNER_RADIUS
|
|
146
|
+
path.reset()
|
|
147
|
+
|
|
148
|
+
if (isFirst) {
|
|
149
|
+
path.moveTo(rect.right, rect.top)
|
|
150
|
+
path.lineTo(rect.left + r, rect.top)
|
|
151
|
+
path.quadTo(rect.left, rect.top, rect.left, rect.top + r)
|
|
152
|
+
path.lineTo(rect.left, rect.bottom - r)
|
|
153
|
+
path.quadTo(rect.left, rect.bottom, rect.left + r, rect.bottom)
|
|
154
|
+
path.lineTo(rect.right, rect.bottom)
|
|
155
|
+
} else if (isLast) {
|
|
156
|
+
path.moveTo(rect.left, rect.top)
|
|
157
|
+
path.lineTo(rect.right - r, rect.top)
|
|
158
|
+
path.quadTo(rect.right, rect.top, rect.right, rect.top + r)
|
|
159
|
+
path.lineTo(rect.right, rect.bottom - r)
|
|
160
|
+
path.quadTo(rect.right, rect.bottom, rect.right - r, rect.bottom)
|
|
161
|
+
path.lineTo(rect.left, rect.bottom)
|
|
162
|
+
} else {
|
|
163
|
+
path.moveTo(rect.left, rect.top)
|
|
164
|
+
path.lineTo(rect.right, rect.top)
|
|
165
|
+
path.moveTo(rect.left, rect.bottom)
|
|
166
|
+
path.lineTo(rect.right, rect.bottom)
|
|
167
|
+
}
|
|
168
|
+
canvas.drawPath(path, sharedBorderPaint)
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
private fun createRadii(
|
|
172
|
+
isFirst: Boolean,
|
|
173
|
+
isLast: Boolean,
|
|
174
|
+
) = when {
|
|
175
|
+
isFirst && isLast -> {
|
|
176
|
+
floatArrayOf(
|
|
177
|
+
CORNER_RADIUS,
|
|
178
|
+
CORNER_RADIUS,
|
|
179
|
+
CORNER_RADIUS,
|
|
180
|
+
CORNER_RADIUS,
|
|
181
|
+
CORNER_RADIUS,
|
|
182
|
+
CORNER_RADIUS,
|
|
183
|
+
CORNER_RADIUS,
|
|
184
|
+
CORNER_RADIUS,
|
|
185
|
+
)
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
isFirst -> {
|
|
189
|
+
floatArrayOf(CORNER_RADIUS, CORNER_RADIUS, 0f, 0f, 0f, 0f, CORNER_RADIUS, CORNER_RADIUS)
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
isLast -> {
|
|
193
|
+
floatArrayOf(0f, 0f, CORNER_RADIUS, CORNER_RADIUS, CORNER_RADIUS, CORNER_RADIUS, 0f, 0f)
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
else -> {
|
|
197
|
+
floatArrayOf(0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f)
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
private fun isPressed(text: Spanned): Boolean {
|
|
202
|
+
val spanStart = text.getSpanStart(this)
|
|
203
|
+
val spanEnd = text.getSpanEnd(this)
|
|
204
|
+
return text.getSpans(spanStart, spanEnd, FactoidSpan::class.java).any { span ->
|
|
205
|
+
span.pressed && text.getSpanStart(span) == spanStart && text.getSpanEnd(span) == spanEnd
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
private fun darken(color: Int): Int =
|
|
210
|
+
Color.argb(
|
|
211
|
+
Color.alpha(color),
|
|
212
|
+
(Color.red(color) * PRESSED_DARKEN).toInt(),
|
|
213
|
+
(Color.green(color) * PRESSED_DARKEN).toInt(),
|
|
214
|
+
(Color.blue(color) * PRESSED_DARKEN).toInt(),
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
/** First factoid character in [from, to) that is not a padding mark or whitespace. */
|
|
218
|
+
private fun firstInk(
|
|
219
|
+
text: CharSequence,
|
|
220
|
+
from: Int,
|
|
221
|
+
to: Int,
|
|
222
|
+
): Int {
|
|
223
|
+
var index = from
|
|
224
|
+
while (index < to && isPaddingOrSpace(text[index])) index++
|
|
225
|
+
return index
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/** Exclusive end of the last factoid character in [from, to) that is not a padding mark or whitespace. */
|
|
229
|
+
private fun lastInk(
|
|
230
|
+
text: CharSequence,
|
|
231
|
+
from: Int,
|
|
232
|
+
to: Int,
|
|
233
|
+
): Int {
|
|
234
|
+
var index = to
|
|
235
|
+
while (index > from && isPaddingOrSpace(text[index - 1])) index--
|
|
236
|
+
return index
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
private fun isPaddingOrSpace(c: Char): Boolean = c == FactoidPaddingSpan.MARK || c.isWhitespace()
|
|
240
|
+
|
|
241
|
+
/** End of the visible glyphs on this line, before the break and any trailing space. */
|
|
242
|
+
private fun lastGlyphOffset(
|
|
243
|
+
text: CharSequence,
|
|
244
|
+
lineStart: Int,
|
|
245
|
+
lineEnd: Int,
|
|
246
|
+
): Int {
|
|
247
|
+
var offset = lineEnd
|
|
248
|
+
while (offset > lineStart && text[offset - 1].isWhitespace()) offset--
|
|
249
|
+
return offset
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
private fun adjustBottomForMargin(
|
|
253
|
+
text: Spanned,
|
|
254
|
+
lineEnd: Int,
|
|
255
|
+
bottom: Int,
|
|
256
|
+
): Int {
|
|
257
|
+
if (lineEnd <= 0 || lineEnd > text.length || text[lineEnd - 1] != '\n') return bottom
|
|
258
|
+
val marginSpans = text.getSpans(lineEnd - 1, lineEnd, MarginBottomSpan::class.java)
|
|
259
|
+
var adjusted = bottom
|
|
260
|
+
for (span in marginSpans) {
|
|
261
|
+
if (text.getSpanEnd(span) == lineEnd) adjusted -= span.marginBottom.toInt()
|
|
262
|
+
}
|
|
263
|
+
return adjusted
|
|
264
|
+
}
|
|
265
|
+
}
|