@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,119 +1,119 @@
|
|
|
1
|
-
package com.renderrichtext.utils.text.view
|
|
2
|
-
|
|
3
|
-
import android.graphics.Color
|
|
4
|
-
import android.os.Build
|
|
5
|
-
import android.text.GetChars
|
|
6
|
-
import android.text.Spannable
|
|
7
|
-
import android.text.SpannableString
|
|
8
|
-
import android.text.SpannableStringBuilder
|
|
9
|
-
import android.view.textclassifier.TextClassifier
|
|
10
|
-
import androidx.appcompat.widget.AppCompatTextView
|
|
11
|
-
import androidx.core.view.ViewCompat
|
|
12
|
-
import com.renderrichtext.accessibility.AccessibleTiptapTextView
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Adopts the renderer's buffer instead of copying it: the default factory's copy is
|
|
16
|
-
* quadratic in span count. Safe because each segment's buffer is owned by one view.
|
|
17
|
-
*/
|
|
18
|
-
private object NoCopySpannableFactory : Spannable.Factory() {
|
|
19
|
-
override fun newSpannable(source: CharSequence): Spannable =
|
|
20
|
-
when (source) {
|
|
21
|
-
is SpannableStringBuilder -> InsertionOrderedSpannable(source)
|
|
22
|
-
is Spannable -> source
|
|
23
|
-
else -> SpannableString(source)
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Hides that [buffer] is a `SpannableStringBuilder`. Layout reads a builder's paragraph
|
|
29
|
-
* spans in position order rather than insertion order, which paints nested list margins
|
|
30
|
-
* outer-first and pushes nested checkboxes an indent right.
|
|
31
|
-
*
|
|
32
|
-
* Hiding the type has a price, and it is deliberate: every paragraph-span query from
|
|
33
|
-
* `Layout` now goes through the builder's sorted `getSpans` instead of the unsorted fast
|
|
34
|
-
* path the framework reserves for builders. The `layout` benchmark in the example app's
|
|
35
|
-
* `display-benchmark` covers that cost, so it is already accounted for. Do not
|
|
36
|
-
* "optimise" this wrapper away.
|
|
37
|
-
*/
|
|
38
|
-
private class InsertionOrderedSpannable(
|
|
39
|
-
private val buffer: SpannableStringBuilder,
|
|
40
|
-
) : Spannable,
|
|
41
|
-
GetChars {
|
|
42
|
-
override val length: Int get() = buffer.length
|
|
43
|
-
|
|
44
|
-
override fun get(index: Int): Char = buffer[index]
|
|
45
|
-
|
|
46
|
-
override fun subSequence(
|
|
47
|
-
startIndex: Int,
|
|
48
|
-
endIndex: Int,
|
|
49
|
-
): CharSequence = buffer.subSequence(startIndex, endIndex)
|
|
50
|
-
|
|
51
|
-
override fun getChars(
|
|
52
|
-
start: Int,
|
|
53
|
-
end: Int,
|
|
54
|
-
dest: CharArray,
|
|
55
|
-
destoff: Int,
|
|
56
|
-
) = buffer.getChars(start, end, dest, destoff)
|
|
57
|
-
|
|
58
|
-
override fun <T : Any?> getSpans(
|
|
59
|
-
start: Int,
|
|
60
|
-
end: Int,
|
|
61
|
-
type: Class<T>,
|
|
62
|
-
): Array<T> = buffer.getSpans(start, end, type)
|
|
63
|
-
|
|
64
|
-
override fun getSpanStart(tag: Any): Int = buffer.getSpanStart(tag)
|
|
65
|
-
|
|
66
|
-
override fun getSpanEnd(tag: Any): Int = buffer.getSpanEnd(tag)
|
|
67
|
-
|
|
68
|
-
override fun getSpanFlags(tag: Any): Int = buffer.getSpanFlags(tag)
|
|
69
|
-
|
|
70
|
-
override fun nextSpanTransition(
|
|
71
|
-
start: Int,
|
|
72
|
-
limit: Int,
|
|
73
|
-
type: Class<*>?,
|
|
74
|
-
): Int = buffer.nextSpanTransition(start, limit, type)
|
|
75
|
-
|
|
76
|
-
override fun setSpan(
|
|
77
|
-
what: Any,
|
|
78
|
-
start: Int,
|
|
79
|
-
end: Int,
|
|
80
|
-
flags: Int,
|
|
81
|
-
) = buffer.setSpan(what, start, end, flags)
|
|
82
|
-
|
|
83
|
-
override fun removeSpan(what: Any) = buffer.removeSpan(what)
|
|
84
|
-
|
|
85
|
-
override fun toString(): String = buffer.toString()
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
fun AccessibleTiptapTextView.setupAsTiptapTextView() {
|
|
89
|
-
setBackgroundColor(Color.TRANSPARENT)
|
|
90
|
-
setSpannableFactory(NoCopySpannableFactory)
|
|
91
|
-
includeFontPadding = false
|
|
92
|
-
movementMethod = LinkLongPressMovementMethod.createInstance()
|
|
93
|
-
setTextIsSelectable(true)
|
|
94
|
-
customSelectionActionModeCallback = createSelectionActionModeCallback(this)
|
|
95
|
-
// SmartSelectSprite crashes with "Center point is not inside any of the
|
|
96
|
-
// rectangles!" when Layout.getSelection returns empty rects near an
|
|
97
|
-
// ImageSpan (ReplacementSpan). NO_OP makes skipTextClassification() return
|
|
98
|
-
// true, bypassing the entire SmartSelectSprite code path. Regular text
|
|
99
|
-
// selection (long-press, handles, copy/paste) still works; only automatic
|
|
100
|
-
// entity detection (phone numbers, addresses) is disabled.
|
|
101
|
-
//
|
|
102
|
-
// TODO: Add an Android-only `enableSmartTextSelection` prop that skips this
|
|
103
|
-
// NO_OP override. This would let users who don't render images opt in to
|
|
104
|
-
// entity detection. The prop should default to false and its docs should
|
|
105
|
-
// warn that enabling it with tiptap containing images will crash.
|
|
106
|
-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
107
|
-
setTextClassifier(TextClassifier.NO_OP)
|
|
108
|
-
}
|
|
109
|
-
isVerticalScrollBarEnabled = false
|
|
110
|
-
isHorizontalScrollBarEnabled = false
|
|
111
|
-
ViewCompat.setAccessibilityDelegate(this, accessibilityHelper)
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
fun AppCompatTextView.applySelectableState(selectable: Boolean) {
|
|
115
|
-
if (isTextSelectable == selectable) return
|
|
116
|
-
setTextIsSelectable(selectable)
|
|
117
|
-
movementMethod = LinkLongPressMovementMethod.createInstance()
|
|
118
|
-
if (!selectable && !isClickable) isClickable = true
|
|
119
|
-
}
|
|
1
|
+
package com.renderrichtext.utils.text.view
|
|
2
|
+
|
|
3
|
+
import android.graphics.Color
|
|
4
|
+
import android.os.Build
|
|
5
|
+
import android.text.GetChars
|
|
6
|
+
import android.text.Spannable
|
|
7
|
+
import android.text.SpannableString
|
|
8
|
+
import android.text.SpannableStringBuilder
|
|
9
|
+
import android.view.textclassifier.TextClassifier
|
|
10
|
+
import androidx.appcompat.widget.AppCompatTextView
|
|
11
|
+
import androidx.core.view.ViewCompat
|
|
12
|
+
import com.renderrichtext.accessibility.AccessibleTiptapTextView
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Adopts the renderer's buffer instead of copying it: the default factory's copy is
|
|
16
|
+
* quadratic in span count. Safe because each segment's buffer is owned by one view.
|
|
17
|
+
*/
|
|
18
|
+
private object NoCopySpannableFactory : Spannable.Factory() {
|
|
19
|
+
override fun newSpannable(source: CharSequence): Spannable =
|
|
20
|
+
when (source) {
|
|
21
|
+
is SpannableStringBuilder -> InsertionOrderedSpannable(source)
|
|
22
|
+
is Spannable -> source
|
|
23
|
+
else -> SpannableString(source)
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Hides that [buffer] is a `SpannableStringBuilder`. Layout reads a builder's paragraph
|
|
29
|
+
* spans in position order rather than insertion order, which paints nested list margins
|
|
30
|
+
* outer-first and pushes nested checkboxes an indent right.
|
|
31
|
+
*
|
|
32
|
+
* Hiding the type has a price, and it is deliberate: every paragraph-span query from
|
|
33
|
+
* `Layout` now goes through the builder's sorted `getSpans` instead of the unsorted fast
|
|
34
|
+
* path the framework reserves for builders. The `layout` benchmark in the example app's
|
|
35
|
+
* `display-benchmark` covers that cost, so it is already accounted for. Do not
|
|
36
|
+
* "optimise" this wrapper away.
|
|
37
|
+
*/
|
|
38
|
+
private class InsertionOrderedSpannable(
|
|
39
|
+
private val buffer: SpannableStringBuilder,
|
|
40
|
+
) : Spannable,
|
|
41
|
+
GetChars {
|
|
42
|
+
override val length: Int get() = buffer.length
|
|
43
|
+
|
|
44
|
+
override fun get(index: Int): Char = buffer[index]
|
|
45
|
+
|
|
46
|
+
override fun subSequence(
|
|
47
|
+
startIndex: Int,
|
|
48
|
+
endIndex: Int,
|
|
49
|
+
): CharSequence = buffer.subSequence(startIndex, endIndex)
|
|
50
|
+
|
|
51
|
+
override fun getChars(
|
|
52
|
+
start: Int,
|
|
53
|
+
end: Int,
|
|
54
|
+
dest: CharArray,
|
|
55
|
+
destoff: Int,
|
|
56
|
+
) = buffer.getChars(start, end, dest, destoff)
|
|
57
|
+
|
|
58
|
+
override fun <T : Any?> getSpans(
|
|
59
|
+
start: Int,
|
|
60
|
+
end: Int,
|
|
61
|
+
type: Class<T>,
|
|
62
|
+
): Array<T> = buffer.getSpans(start, end, type)
|
|
63
|
+
|
|
64
|
+
override fun getSpanStart(tag: Any): Int = buffer.getSpanStart(tag)
|
|
65
|
+
|
|
66
|
+
override fun getSpanEnd(tag: Any): Int = buffer.getSpanEnd(tag)
|
|
67
|
+
|
|
68
|
+
override fun getSpanFlags(tag: Any): Int = buffer.getSpanFlags(tag)
|
|
69
|
+
|
|
70
|
+
override fun nextSpanTransition(
|
|
71
|
+
start: Int,
|
|
72
|
+
limit: Int,
|
|
73
|
+
type: Class<*>?,
|
|
74
|
+
): Int = buffer.nextSpanTransition(start, limit, type)
|
|
75
|
+
|
|
76
|
+
override fun setSpan(
|
|
77
|
+
what: Any,
|
|
78
|
+
start: Int,
|
|
79
|
+
end: Int,
|
|
80
|
+
flags: Int,
|
|
81
|
+
) = buffer.setSpan(what, start, end, flags)
|
|
82
|
+
|
|
83
|
+
override fun removeSpan(what: Any) = buffer.removeSpan(what)
|
|
84
|
+
|
|
85
|
+
override fun toString(): String = buffer.toString()
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
fun AccessibleTiptapTextView.setupAsTiptapTextView() {
|
|
89
|
+
setBackgroundColor(Color.TRANSPARENT)
|
|
90
|
+
setSpannableFactory(NoCopySpannableFactory)
|
|
91
|
+
includeFontPadding = false
|
|
92
|
+
movementMethod = LinkLongPressMovementMethod.createInstance()
|
|
93
|
+
setTextIsSelectable(true)
|
|
94
|
+
customSelectionActionModeCallback = createSelectionActionModeCallback(this)
|
|
95
|
+
// SmartSelectSprite crashes with "Center point is not inside any of the
|
|
96
|
+
// rectangles!" when Layout.getSelection returns empty rects near an
|
|
97
|
+
// ImageSpan (ReplacementSpan). NO_OP makes skipTextClassification() return
|
|
98
|
+
// true, bypassing the entire SmartSelectSprite code path. Regular text
|
|
99
|
+
// selection (long-press, handles, copy/paste) still works; only automatic
|
|
100
|
+
// entity detection (phone numbers, addresses) is disabled.
|
|
101
|
+
//
|
|
102
|
+
// TODO: Add an Android-only `enableSmartTextSelection` prop that skips this
|
|
103
|
+
// NO_OP override. This would let users who don't render images opt in to
|
|
104
|
+
// entity detection. The prop should default to false and its docs should
|
|
105
|
+
// warn that enabling it with tiptap containing images will crash.
|
|
106
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
107
|
+
setTextClassifier(TextClassifier.NO_OP)
|
|
108
|
+
}
|
|
109
|
+
isVerticalScrollBarEnabled = false
|
|
110
|
+
isHorizontalScrollBarEnabled = false
|
|
111
|
+
ViewCompat.setAccessibilityDelegate(this, accessibilityHelper)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
fun AppCompatTextView.applySelectableState(selectable: Boolean) {
|
|
115
|
+
if (isTextSelectable == selectable) return
|
|
116
|
+
setTextIsSelectable(selectable)
|
|
117
|
+
movementMethod = LinkLongPressMovementMethod.createInstance()
|
|
118
|
+
if (!selectable && !isClickable) isClickable = true
|
|
119
|
+
}
|
|
@@ -1,217 +1,217 @@
|
|
|
1
|
-
package com.renderrichtext.views
|
|
2
|
-
|
|
3
|
-
import android.content.Context
|
|
4
|
-
import android.graphics.Canvas
|
|
5
|
-
import android.graphics.Color
|
|
6
|
-
import android.graphics.ColorFilter
|
|
7
|
-
import android.graphics.Paint
|
|
8
|
-
import android.graphics.PixelFormat
|
|
9
|
-
import android.graphics.RectF
|
|
10
|
-
import android.graphics.Typeface
|
|
11
|
-
import android.graphics.drawable.ColorDrawable
|
|
12
|
-
import android.graphics.drawable.Drawable
|
|
13
|
-
import android.graphics.drawable.GradientDrawable
|
|
14
|
-
import android.util.TypedValue
|
|
15
|
-
import android.view.Gravity
|
|
16
|
-
import android.view.View
|
|
17
|
-
import android.view.View.MeasureSpec
|
|
18
|
-
import android.view.ViewGroup
|
|
19
|
-
import android.widget.ImageView
|
|
20
|
-
import android.widget.LinearLayout
|
|
21
|
-
import android.widget.PopupWindow
|
|
22
|
-
import android.widget.TextView
|
|
23
|
-
import kotlin.math.roundToInt
|
|
24
|
-
|
|
25
|
-
object ContextMenuPopup {
|
|
26
|
-
private var activePopup: PopupWindow? = null
|
|
27
|
-
|
|
28
|
-
fun dismiss() {
|
|
29
|
-
activePopup?.dismiss()
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
enum class Icon { COPY, DOCUMENT }
|
|
33
|
-
|
|
34
|
-
class Builder internal constructor() {
|
|
35
|
-
internal val items = mutableListOf<MenuItem>()
|
|
36
|
-
|
|
37
|
-
fun item(
|
|
38
|
-
icon: Icon,
|
|
39
|
-
label: String,
|
|
40
|
-
onClick: () -> Unit,
|
|
41
|
-
) {
|
|
42
|
-
items.add(MenuItem(icon, label, onClick))
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
internal data class MenuItem(
|
|
47
|
-
val icon: Icon,
|
|
48
|
-
val label: String,
|
|
49
|
-
val onClick: () -> Unit,
|
|
50
|
-
)
|
|
51
|
-
|
|
52
|
-
private var density = 1f
|
|
53
|
-
private val Float.dp get() = (this * density).roundToInt()
|
|
54
|
-
|
|
55
|
-
fun show(
|
|
56
|
-
anchor: View,
|
|
57
|
-
parent: View,
|
|
58
|
-
block: Builder.() -> Unit,
|
|
59
|
-
) {
|
|
60
|
-
activePopup?.dismiss()
|
|
61
|
-
|
|
62
|
-
val context = anchor.context
|
|
63
|
-
density = context.resources.displayMetrics.density
|
|
64
|
-
val builder = Builder().apply(block)
|
|
65
|
-
if (builder.items.isEmpty()) return
|
|
66
|
-
|
|
67
|
-
val container =
|
|
68
|
-
LinearLayout(context).apply {
|
|
69
|
-
orientation = LinearLayout.VERTICAL
|
|
70
|
-
elevation = 12f.dp.toFloat()
|
|
71
|
-
setPadding(4f.dp, 12f.dp, 4f.dp, 12f.dp)
|
|
72
|
-
background =
|
|
73
|
-
GradientDrawable().apply {
|
|
74
|
-
setColor(Color.WHITE)
|
|
75
|
-
cornerRadius = 14f.dp.toFloat()
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
builder.items.forEachIndexed { index, item ->
|
|
80
|
-
if (index > 0) container.addView(createDivider(context))
|
|
81
|
-
container.addView(createMenuItemView(context, item))
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
val popup =
|
|
85
|
-
PopupWindow(
|
|
86
|
-
container,
|
|
87
|
-
ViewGroup.LayoutParams.WRAP_CONTENT,
|
|
88
|
-
ViewGroup.LayoutParams.WRAP_CONTENT,
|
|
89
|
-
true,
|
|
90
|
-
).apply {
|
|
91
|
-
elevation = 24f.dp.toFloat()
|
|
92
|
-
isOutsideTouchable = true
|
|
93
|
-
setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
|
94
|
-
setOnDismissListener {
|
|
95
|
-
activePopup = null
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
container.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED)
|
|
100
|
-
|
|
101
|
-
val location = IntArray(2).also { anchor.getLocationOnScreen(it) }
|
|
102
|
-
val centerX = location[0] + anchor.width / 2
|
|
103
|
-
val topY = location[1]
|
|
104
|
-
|
|
105
|
-
val screenW = context.resources.displayMetrics.widthPixels
|
|
106
|
-
val margin = 8f.dp
|
|
107
|
-
|
|
108
|
-
val x =
|
|
109
|
-
(centerX - container.measuredWidth / 2)
|
|
110
|
-
.coerceIn(margin, screenW - container.measuredWidth - margin)
|
|
111
|
-
val y =
|
|
112
|
-
(topY - container.measuredHeight - margin)
|
|
113
|
-
.coerceAtLeast(margin)
|
|
114
|
-
|
|
115
|
-
activePopup = popup
|
|
116
|
-
popup.showAtLocation(parent, Gravity.NO_GRAVITY, x, y)
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
private fun createMenuItemView(
|
|
120
|
-
context: Context,
|
|
121
|
-
item: MenuItem,
|
|
122
|
-
) = LinearLayout(context).apply {
|
|
123
|
-
orientation = LinearLayout.HORIZONTAL
|
|
124
|
-
gravity = Gravity.CENTER_VERTICAL
|
|
125
|
-
setPadding(16f.dp, 0, 16f.dp, 0)
|
|
126
|
-
minimumHeight = 48f.dp
|
|
127
|
-
isClickable = true
|
|
128
|
-
isFocusable = true
|
|
129
|
-
|
|
130
|
-
val outValue = TypedValue()
|
|
131
|
-
context.theme.resolveAttribute(android.R.attr.selectableItemBackground, outValue, true)
|
|
132
|
-
foreground = context.getDrawable(outValue.resourceId)
|
|
133
|
-
|
|
134
|
-
addView(
|
|
135
|
-
ImageView(context).apply {
|
|
136
|
-
setImageDrawable(createIconDrawable(item.icon))
|
|
137
|
-
setColorFilter(Color.parseColor("#333333"))
|
|
138
|
-
},
|
|
139
|
-
LinearLayout.LayoutParams(20f.dp, 20f.dp),
|
|
140
|
-
)
|
|
141
|
-
|
|
142
|
-
addView(
|
|
143
|
-
TextView(context).apply {
|
|
144
|
-
text = item.label
|
|
145
|
-
textSize = 16f
|
|
146
|
-
setTextColor(Color.parseColor("#1C1C1E"))
|
|
147
|
-
typeface = Typeface.create("sans-serif-medium", Typeface.NORMAL)
|
|
148
|
-
},
|
|
149
|
-
LinearLayout
|
|
150
|
-
.LayoutParams(
|
|
151
|
-
ViewGroup.LayoutParams.WRAP_CONTENT,
|
|
152
|
-
ViewGroup.LayoutParams.WRAP_CONTENT,
|
|
153
|
-
).apply { marginStart = 12f.dp },
|
|
154
|
-
)
|
|
155
|
-
|
|
156
|
-
setOnClickListener {
|
|
157
|
-
item.onClick()
|
|
158
|
-
dismiss()
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
private fun createDivider(context: Context) =
|
|
163
|
-
View(context).apply {
|
|
164
|
-
setBackgroundColor(Color.parseColor("#E5E5EA"))
|
|
165
|
-
layoutParams =
|
|
166
|
-
LinearLayout
|
|
167
|
-
.LayoutParams(
|
|
168
|
-
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
169
|
-
1f.dp.coerceAtLeast(1),
|
|
170
|
-
).apply {
|
|
171
|
-
setMargins(16f.dp, 0, 16f.dp, 0)
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
private fun createIconDrawable(icon: Icon): Drawable =
|
|
176
|
-
object : Drawable() {
|
|
177
|
-
private val paint =
|
|
178
|
-
Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
|
179
|
-
style = Paint.Style.STROKE
|
|
180
|
-
strokeWidth = 1.5f * density
|
|
181
|
-
strokeJoin = Paint.Join.ROUND
|
|
182
|
-
strokeCap = Paint.Cap.ROUND
|
|
183
|
-
color = Color.parseColor("#333333")
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
private val copyGlyph = CopyGlyph()
|
|
187
|
-
|
|
188
|
-
// COPY mirrors SF Symbol doc.on.doc, DOCUMENT mirrors doc.text; the copy
|
|
189
|
-
// glyph is shared with the header button in CodeBlockContainerView.
|
|
190
|
-
override fun draw(canvas: Canvas) {
|
|
191
|
-
val u = bounds.width() / 24f
|
|
192
|
-
if (icon == Icon.COPY) {
|
|
193
|
-
copyGlyph.draw(canvas, bounds.width().toFloat(), paint)
|
|
194
|
-
} else {
|
|
195
|
-
canvas.drawRoundRect(RectF(5 * u, 3 * u, 19 * u, 21 * u), 2.5f * u, 2.5f * u, paint)
|
|
196
|
-
canvas.drawLine(8.5f * u, 9 * u, 15.5f * u, 9 * u, paint)
|
|
197
|
-
canvas.drawLine(8.5f * u, 12.5f * u, 15.5f * u, 12.5f * u, paint)
|
|
198
|
-
canvas.drawLine(8.5f * u, 16 * u, 13 * u, 16 * u, paint)
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
override fun getIntrinsicWidth() = 24f.dp
|
|
203
|
-
|
|
204
|
-
override fun getIntrinsicHeight() = 24f.dp
|
|
205
|
-
|
|
206
|
-
override fun setAlpha(alpha: Int) {
|
|
207
|
-
paint.alpha = alpha
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
override fun setColorFilter(colorFilter: ColorFilter?) {
|
|
211
|
-
paint.colorFilter = colorFilter
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
@Deprecated("Deprecated in Java")
|
|
215
|
-
override fun getOpacity() = PixelFormat.TRANSLUCENT
|
|
216
|
-
}
|
|
217
|
-
}
|
|
1
|
+
package com.renderrichtext.views
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.graphics.Canvas
|
|
5
|
+
import android.graphics.Color
|
|
6
|
+
import android.graphics.ColorFilter
|
|
7
|
+
import android.graphics.Paint
|
|
8
|
+
import android.graphics.PixelFormat
|
|
9
|
+
import android.graphics.RectF
|
|
10
|
+
import android.graphics.Typeface
|
|
11
|
+
import android.graphics.drawable.ColorDrawable
|
|
12
|
+
import android.graphics.drawable.Drawable
|
|
13
|
+
import android.graphics.drawable.GradientDrawable
|
|
14
|
+
import android.util.TypedValue
|
|
15
|
+
import android.view.Gravity
|
|
16
|
+
import android.view.View
|
|
17
|
+
import android.view.View.MeasureSpec
|
|
18
|
+
import android.view.ViewGroup
|
|
19
|
+
import android.widget.ImageView
|
|
20
|
+
import android.widget.LinearLayout
|
|
21
|
+
import android.widget.PopupWindow
|
|
22
|
+
import android.widget.TextView
|
|
23
|
+
import kotlin.math.roundToInt
|
|
24
|
+
|
|
25
|
+
object ContextMenuPopup {
|
|
26
|
+
private var activePopup: PopupWindow? = null
|
|
27
|
+
|
|
28
|
+
fun dismiss() {
|
|
29
|
+
activePopup?.dismiss()
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
enum class Icon { COPY, DOCUMENT }
|
|
33
|
+
|
|
34
|
+
class Builder internal constructor() {
|
|
35
|
+
internal val items = mutableListOf<MenuItem>()
|
|
36
|
+
|
|
37
|
+
fun item(
|
|
38
|
+
icon: Icon,
|
|
39
|
+
label: String,
|
|
40
|
+
onClick: () -> Unit,
|
|
41
|
+
) {
|
|
42
|
+
items.add(MenuItem(icon, label, onClick))
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
internal data class MenuItem(
|
|
47
|
+
val icon: Icon,
|
|
48
|
+
val label: String,
|
|
49
|
+
val onClick: () -> Unit,
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
private var density = 1f
|
|
53
|
+
private val Float.dp get() = (this * density).roundToInt()
|
|
54
|
+
|
|
55
|
+
fun show(
|
|
56
|
+
anchor: View,
|
|
57
|
+
parent: View,
|
|
58
|
+
block: Builder.() -> Unit,
|
|
59
|
+
) {
|
|
60
|
+
activePopup?.dismiss()
|
|
61
|
+
|
|
62
|
+
val context = anchor.context
|
|
63
|
+
density = context.resources.displayMetrics.density
|
|
64
|
+
val builder = Builder().apply(block)
|
|
65
|
+
if (builder.items.isEmpty()) return
|
|
66
|
+
|
|
67
|
+
val container =
|
|
68
|
+
LinearLayout(context).apply {
|
|
69
|
+
orientation = LinearLayout.VERTICAL
|
|
70
|
+
elevation = 12f.dp.toFloat()
|
|
71
|
+
setPadding(4f.dp, 12f.dp, 4f.dp, 12f.dp)
|
|
72
|
+
background =
|
|
73
|
+
GradientDrawable().apply {
|
|
74
|
+
setColor(Color.WHITE)
|
|
75
|
+
cornerRadius = 14f.dp.toFloat()
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
builder.items.forEachIndexed { index, item ->
|
|
80
|
+
if (index > 0) container.addView(createDivider(context))
|
|
81
|
+
container.addView(createMenuItemView(context, item))
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
val popup =
|
|
85
|
+
PopupWindow(
|
|
86
|
+
container,
|
|
87
|
+
ViewGroup.LayoutParams.WRAP_CONTENT,
|
|
88
|
+
ViewGroup.LayoutParams.WRAP_CONTENT,
|
|
89
|
+
true,
|
|
90
|
+
).apply {
|
|
91
|
+
elevation = 24f.dp.toFloat()
|
|
92
|
+
isOutsideTouchable = true
|
|
93
|
+
setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
|
94
|
+
setOnDismissListener {
|
|
95
|
+
activePopup = null
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
container.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED)
|
|
100
|
+
|
|
101
|
+
val location = IntArray(2).also { anchor.getLocationOnScreen(it) }
|
|
102
|
+
val centerX = location[0] + anchor.width / 2
|
|
103
|
+
val topY = location[1]
|
|
104
|
+
|
|
105
|
+
val screenW = context.resources.displayMetrics.widthPixels
|
|
106
|
+
val margin = 8f.dp
|
|
107
|
+
|
|
108
|
+
val x =
|
|
109
|
+
(centerX - container.measuredWidth / 2)
|
|
110
|
+
.coerceIn(margin, screenW - container.measuredWidth - margin)
|
|
111
|
+
val y =
|
|
112
|
+
(topY - container.measuredHeight - margin)
|
|
113
|
+
.coerceAtLeast(margin)
|
|
114
|
+
|
|
115
|
+
activePopup = popup
|
|
116
|
+
popup.showAtLocation(parent, Gravity.NO_GRAVITY, x, y)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
private fun createMenuItemView(
|
|
120
|
+
context: Context,
|
|
121
|
+
item: MenuItem,
|
|
122
|
+
) = LinearLayout(context).apply {
|
|
123
|
+
orientation = LinearLayout.HORIZONTAL
|
|
124
|
+
gravity = Gravity.CENTER_VERTICAL
|
|
125
|
+
setPadding(16f.dp, 0, 16f.dp, 0)
|
|
126
|
+
minimumHeight = 48f.dp
|
|
127
|
+
isClickable = true
|
|
128
|
+
isFocusable = true
|
|
129
|
+
|
|
130
|
+
val outValue = TypedValue()
|
|
131
|
+
context.theme.resolveAttribute(android.R.attr.selectableItemBackground, outValue, true)
|
|
132
|
+
foreground = context.getDrawable(outValue.resourceId)
|
|
133
|
+
|
|
134
|
+
addView(
|
|
135
|
+
ImageView(context).apply {
|
|
136
|
+
setImageDrawable(createIconDrawable(item.icon))
|
|
137
|
+
setColorFilter(Color.parseColor("#333333"))
|
|
138
|
+
},
|
|
139
|
+
LinearLayout.LayoutParams(20f.dp, 20f.dp),
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
addView(
|
|
143
|
+
TextView(context).apply {
|
|
144
|
+
text = item.label
|
|
145
|
+
textSize = 16f
|
|
146
|
+
setTextColor(Color.parseColor("#1C1C1E"))
|
|
147
|
+
typeface = Typeface.create("sans-serif-medium", Typeface.NORMAL)
|
|
148
|
+
},
|
|
149
|
+
LinearLayout
|
|
150
|
+
.LayoutParams(
|
|
151
|
+
ViewGroup.LayoutParams.WRAP_CONTENT,
|
|
152
|
+
ViewGroup.LayoutParams.WRAP_CONTENT,
|
|
153
|
+
).apply { marginStart = 12f.dp },
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
setOnClickListener {
|
|
157
|
+
item.onClick()
|
|
158
|
+
dismiss()
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
private fun createDivider(context: Context) =
|
|
163
|
+
View(context).apply {
|
|
164
|
+
setBackgroundColor(Color.parseColor("#E5E5EA"))
|
|
165
|
+
layoutParams =
|
|
166
|
+
LinearLayout
|
|
167
|
+
.LayoutParams(
|
|
168
|
+
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
169
|
+
1f.dp.coerceAtLeast(1),
|
|
170
|
+
).apply {
|
|
171
|
+
setMargins(16f.dp, 0, 16f.dp, 0)
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
private fun createIconDrawable(icon: Icon): Drawable =
|
|
176
|
+
object : Drawable() {
|
|
177
|
+
private val paint =
|
|
178
|
+
Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
|
179
|
+
style = Paint.Style.STROKE
|
|
180
|
+
strokeWidth = 1.5f * density
|
|
181
|
+
strokeJoin = Paint.Join.ROUND
|
|
182
|
+
strokeCap = Paint.Cap.ROUND
|
|
183
|
+
color = Color.parseColor("#333333")
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
private val copyGlyph = CopyGlyph()
|
|
187
|
+
|
|
188
|
+
// COPY mirrors SF Symbol doc.on.doc, DOCUMENT mirrors doc.text; the copy
|
|
189
|
+
// glyph is shared with the header button in CodeBlockContainerView.
|
|
190
|
+
override fun draw(canvas: Canvas) {
|
|
191
|
+
val u = bounds.width() / 24f
|
|
192
|
+
if (icon == Icon.COPY) {
|
|
193
|
+
copyGlyph.draw(canvas, bounds.width().toFloat(), paint)
|
|
194
|
+
} else {
|
|
195
|
+
canvas.drawRoundRect(RectF(5 * u, 3 * u, 19 * u, 21 * u), 2.5f * u, 2.5f * u, paint)
|
|
196
|
+
canvas.drawLine(8.5f * u, 9 * u, 15.5f * u, 9 * u, paint)
|
|
197
|
+
canvas.drawLine(8.5f * u, 12.5f * u, 15.5f * u, 12.5f * u, paint)
|
|
198
|
+
canvas.drawLine(8.5f * u, 16 * u, 13 * u, 16 * u, paint)
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
override fun getIntrinsicWidth() = 24f.dp
|
|
203
|
+
|
|
204
|
+
override fun getIntrinsicHeight() = 24f.dp
|
|
205
|
+
|
|
206
|
+
override fun setAlpha(alpha: Int) {
|
|
207
|
+
paint.alpha = alpha
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
override fun setColorFilter(colorFilter: ColorFilter?) {
|
|
211
|
+
paint.colorFilter = colorFilter
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
@Deprecated("Deprecated in Java")
|
|
215
|
+
override fun getOpacity() = PixelFormat.TRANSLUCENT
|
|
216
|
+
}
|
|
217
|
+
}
|