@mathers101/react-native-render-rich-text 0.1.10 → 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,93 +1,93 @@
|
|
|
1
|
-
#pragma once
|
|
2
|
-
#import "ENRMUIKit.h"
|
|
3
|
-
|
|
4
|
-
NS_ASSUME_NONNULL_BEGIN
|
|
5
|
-
|
|
6
|
-
/// One item of a link's long-press menu.
|
|
7
|
-
@interface ENRMLinkContextMenuItem : NSObject
|
|
8
|
-
@property (nonatomic, copy) NSString *text;
|
|
9
|
-
/// SF Symbol name; empty for no icon.
|
|
10
|
-
@property (nonatomic, copy) NSString *icon;
|
|
11
|
-
@property (nonatomic, assign) BOOL disabled;
|
|
12
|
-
@property (nonatomic, assign) BOOL destructive;
|
|
13
|
-
@end
|
|
14
|
-
|
|
15
|
-
/// The menu items for links whose URL matches `pattern`.
|
|
16
|
-
@interface ENRMLinkContextMenuEntry : NSObject
|
|
17
|
-
@property (nonatomic, copy) NSString *pattern;
|
|
18
|
-
@property (nonatomic, copy) NSArray<ENRMLinkContextMenuItem *> *items;
|
|
19
|
-
@end
|
|
20
|
-
|
|
21
|
-
typedef void (^ENRMLinkContextMenuPressHandler)(NSString *url, NSString *pattern, NSString *itemText);
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* The `linkContextMenuItems` prop: long-press menus for links, by URL pattern.
|
|
25
|
-
* Entries are tried in order, like link variants, and the first whose pattern
|
|
26
|
-
* matches a URL supplies its menu. Menus need iOS 17; below that no URL has one.
|
|
27
|
-
*/
|
|
28
|
-
@interface ENRMLinkContextMenus : NSObject
|
|
29
|
-
@property (nonatomic, copy) NSArray<ENRMLinkContextMenuEntry *> *entries;
|
|
30
|
-
@property (nonatomic, copy, nullable) ENRMLinkContextMenuPressHandler onPress;
|
|
31
|
-
- (BOOL)hasMenuForURL:(nullable NSString *)url;
|
|
32
|
-
#if !TARGET_OS_OSX
|
|
33
|
-
/// `title` is what the user sees the link as: its text, or its pill label.
|
|
34
|
-
- (nullable UIMenu *)menuForURL:(nullable NSString *)url title:(nullable NSString *)title;
|
|
35
|
-
#endif
|
|
36
|
-
@end
|
|
37
|
-
|
|
38
|
-
#if !TARGET_OS_OSX
|
|
39
|
-
/// Adopted by a text view's delegate to supply the long-press menus of its links.
|
|
40
|
-
@protocol ENRMLinkContextMenuSource <NSObject>
|
|
41
|
-
- (nullable ENRMLinkContextMenus *)linkContextMenusForTextView:(UITextView *)textView;
|
|
42
|
-
@end
|
|
43
|
-
|
|
44
|
-
/// Adopted by a text view that presents the menus of some of its links itself.
|
|
45
|
-
@protocol ENRMLinkMenuPresenting <NSObject>
|
|
46
|
-
/// UIKit must be given no menu for such a link, or it lifts the link as a text item as well.
|
|
47
|
-
- (BOOL)presentsLinkMenuAtIndex:(NSUInteger)index;
|
|
48
|
-
@end
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* The copy of a link that its long-press menu lifts.
|
|
52
|
-
*
|
|
53
|
-
* UIKit draws a menu's preview only from a view that is on screen, and hides that view for as
|
|
54
|
-
* long as the menu is open. Lifting part of a larger view through a visible path would hide
|
|
55
|
-
* all of it, and a detached view stays blank until the menu appears. So the link is lifted as
|
|
56
|
-
* an image of itself, laid over the view it belongs to and taken down when the menu ends.
|
|
57
|
-
*/
|
|
58
|
-
@interface ENRMLinkMenuLift : NSObject
|
|
59
|
-
/// Called when the image is taken down, for the owner to restore what the image stood in for.
|
|
60
|
-
@property (nonatomic, copy, nullable) void (^onEnd)(void);
|
|
61
|
-
/// Whether an image is laid over `view`.
|
|
62
|
-
- (BOOL)isOverView:(UIView *)view;
|
|
63
|
-
/// Takes down the image laid before, if any.
|
|
64
|
-
- (void)layImage:(UIImage *)image atFrame:(CGRect)frame overView:(UIView *)view;
|
|
65
|
-
/// The preview that lifts the laid image, nil when there is none. A nil `backgroundColor`
|
|
66
|
-
/// leaves UIKit's own behind the image.
|
|
67
|
-
- (nullable UITargetedPreview *)previewWithCornerRadius:(CGFloat)cornerRadius
|
|
68
|
-
backgroundColor:(nullable UIColor *)backgroundColor;
|
|
69
|
-
- (void)end;
|
|
70
|
-
/// Ends once the menu has animated away, unless another image was laid in the meantime.
|
|
71
|
-
- (void)endWithAnimator:(nullable id<UIContextMenuInteractionAnimating>)animator;
|
|
72
|
-
@end
|
|
73
|
-
|
|
74
|
-
#ifdef __cplusplus
|
|
75
|
-
extern "C" {
|
|
76
|
-
#endif
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* What a long press on a text item shows: the link's configured menu, or what links did before
|
|
80
|
-
* menus existed (the system menu with a preview, or `onLinkLongPress` when previews are off).
|
|
81
|
-
* Every text view delegate answers `textView:menuConfigurationForTextItem:defaultMenu:` with this.
|
|
82
|
-
* A link whose menu the text view presents itself (`ENRMLinkMenuPresenting`) gets none here.
|
|
83
|
-
*/
|
|
84
|
-
UITextItemMenuConfiguration *_Nullable ENRMLinkMenuConfigurationForTextItem(
|
|
85
|
-
UITextView *textView, UITextItem *textItem, UIMenu *defaultMenu, ENRMLinkContextMenus *_Nullable menus,
|
|
86
|
-
BOOL linkPreviewEnabled, void (^_Nullable onLinkLongPress)(NSString *url)) API_AVAILABLE(ios(17.0));
|
|
87
|
-
|
|
88
|
-
#ifdef __cplusplus
|
|
89
|
-
}
|
|
90
|
-
#endif
|
|
91
|
-
#endif
|
|
92
|
-
|
|
93
|
-
NS_ASSUME_NONNULL_END
|
|
1
|
+
#pragma once
|
|
2
|
+
#import "ENRMUIKit.h"
|
|
3
|
+
|
|
4
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
5
|
+
|
|
6
|
+
/// One item of a link's long-press menu.
|
|
7
|
+
@interface ENRMLinkContextMenuItem : NSObject
|
|
8
|
+
@property (nonatomic, copy) NSString *text;
|
|
9
|
+
/// SF Symbol name; empty for no icon.
|
|
10
|
+
@property (nonatomic, copy) NSString *icon;
|
|
11
|
+
@property (nonatomic, assign) BOOL disabled;
|
|
12
|
+
@property (nonatomic, assign) BOOL destructive;
|
|
13
|
+
@end
|
|
14
|
+
|
|
15
|
+
/// The menu items for links whose URL matches `pattern`.
|
|
16
|
+
@interface ENRMLinkContextMenuEntry : NSObject
|
|
17
|
+
@property (nonatomic, copy) NSString *pattern;
|
|
18
|
+
@property (nonatomic, copy) NSArray<ENRMLinkContextMenuItem *> *items;
|
|
19
|
+
@end
|
|
20
|
+
|
|
21
|
+
typedef void (^ENRMLinkContextMenuPressHandler)(NSString *url, NSString *pattern, NSString *itemText);
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* The `linkContextMenuItems` prop: long-press menus for links, by URL pattern.
|
|
25
|
+
* Entries are tried in order, like link variants, and the first whose pattern
|
|
26
|
+
* matches a URL supplies its menu. Menus need iOS 17; below that no URL has one.
|
|
27
|
+
*/
|
|
28
|
+
@interface ENRMLinkContextMenus : NSObject
|
|
29
|
+
@property (nonatomic, copy) NSArray<ENRMLinkContextMenuEntry *> *entries;
|
|
30
|
+
@property (nonatomic, copy, nullable) ENRMLinkContextMenuPressHandler onPress;
|
|
31
|
+
- (BOOL)hasMenuForURL:(nullable NSString *)url;
|
|
32
|
+
#if !TARGET_OS_OSX
|
|
33
|
+
/// `title` is what the user sees the link as: its text, or its pill label.
|
|
34
|
+
- (nullable UIMenu *)menuForURL:(nullable NSString *)url title:(nullable NSString *)title;
|
|
35
|
+
#endif
|
|
36
|
+
@end
|
|
37
|
+
|
|
38
|
+
#if !TARGET_OS_OSX
|
|
39
|
+
/// Adopted by a text view's delegate to supply the long-press menus of its links.
|
|
40
|
+
@protocol ENRMLinkContextMenuSource <NSObject>
|
|
41
|
+
- (nullable ENRMLinkContextMenus *)linkContextMenusForTextView:(UITextView *)textView;
|
|
42
|
+
@end
|
|
43
|
+
|
|
44
|
+
/// Adopted by a text view that presents the menus of some of its links itself.
|
|
45
|
+
@protocol ENRMLinkMenuPresenting <NSObject>
|
|
46
|
+
/// UIKit must be given no menu for such a link, or it lifts the link as a text item as well.
|
|
47
|
+
- (BOOL)presentsLinkMenuAtIndex:(NSUInteger)index;
|
|
48
|
+
@end
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* The copy of a link that its long-press menu lifts.
|
|
52
|
+
*
|
|
53
|
+
* UIKit draws a menu's preview only from a view that is on screen, and hides that view for as
|
|
54
|
+
* long as the menu is open. Lifting part of a larger view through a visible path would hide
|
|
55
|
+
* all of it, and a detached view stays blank until the menu appears. So the link is lifted as
|
|
56
|
+
* an image of itself, laid over the view it belongs to and taken down when the menu ends.
|
|
57
|
+
*/
|
|
58
|
+
@interface ENRMLinkMenuLift : NSObject
|
|
59
|
+
/// Called when the image is taken down, for the owner to restore what the image stood in for.
|
|
60
|
+
@property (nonatomic, copy, nullable) void (^onEnd)(void);
|
|
61
|
+
/// Whether an image is laid over `view`.
|
|
62
|
+
- (BOOL)isOverView:(UIView *)view;
|
|
63
|
+
/// Takes down the image laid before, if any.
|
|
64
|
+
- (void)layImage:(UIImage *)image atFrame:(CGRect)frame overView:(UIView *)view;
|
|
65
|
+
/// The preview that lifts the laid image, nil when there is none. A nil `backgroundColor`
|
|
66
|
+
/// leaves UIKit's own behind the image.
|
|
67
|
+
- (nullable UITargetedPreview *)previewWithCornerRadius:(CGFloat)cornerRadius
|
|
68
|
+
backgroundColor:(nullable UIColor *)backgroundColor;
|
|
69
|
+
- (void)end;
|
|
70
|
+
/// Ends once the menu has animated away, unless another image was laid in the meantime.
|
|
71
|
+
- (void)endWithAnimator:(nullable id<UIContextMenuInteractionAnimating>)animator;
|
|
72
|
+
@end
|
|
73
|
+
|
|
74
|
+
#ifdef __cplusplus
|
|
75
|
+
extern "C" {
|
|
76
|
+
#endif
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* What a long press on a text item shows: the link's configured menu, or what links did before
|
|
80
|
+
* menus existed (the system menu with a preview, or `onLinkLongPress` when previews are off).
|
|
81
|
+
* Every text view delegate answers `textView:menuConfigurationForTextItem:defaultMenu:` with this.
|
|
82
|
+
* A link whose menu the text view presents itself (`ENRMLinkMenuPresenting`) gets none here.
|
|
83
|
+
*/
|
|
84
|
+
UITextItemMenuConfiguration *_Nullable ENRMLinkMenuConfigurationForTextItem(
|
|
85
|
+
UITextView *textView, UITextItem *textItem, UIMenu *defaultMenu, ENRMLinkContextMenus *_Nullable menus,
|
|
86
|
+
BOOL linkPreviewEnabled, void (^_Nullable onLinkLongPress)(NSString *url)) API_AVAILABLE(ios(17.0));
|
|
87
|
+
|
|
88
|
+
#ifdef __cplusplus
|
|
89
|
+
}
|
|
90
|
+
#endif
|
|
91
|
+
#endif
|
|
92
|
+
|
|
93
|
+
NS_ASSUME_NONNULL_END
|
|
@@ -1,178 +1,178 @@
|
|
|
1
|
-
#import "ENRMLinkContextMenus.h"
|
|
2
|
-
#import "LinkTapUtils.h"
|
|
3
|
-
|
|
4
|
-
@implementation ENRMLinkContextMenuItem
|
|
5
|
-
@end
|
|
6
|
-
|
|
7
|
-
@implementation ENRMLinkContextMenuEntry
|
|
8
|
-
@end
|
|
9
|
-
|
|
10
|
-
@implementation ENRMLinkContextMenus {
|
|
11
|
-
NSArray<NSRegularExpression *> *_regexes;
|
|
12
|
-
// A long press asks about the same URL several times (gesture gating, then the menu).
|
|
13
|
-
NSMutableDictionary<NSString *, id> *_entriesByURL;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
- (instancetype)init
|
|
17
|
-
{
|
|
18
|
-
if (self = [super init]) {
|
|
19
|
-
_entries = @[];
|
|
20
|
-
_regexes = @[];
|
|
21
|
-
_entriesByURL = [NSMutableDictionary new];
|
|
22
|
-
}
|
|
23
|
-
return self;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
- (void)setEntries:(NSArray<ENRMLinkContextMenuEntry *> *)entries
|
|
27
|
-
{
|
|
28
|
-
NSMutableArray<ENRMLinkContextMenuEntry *> *valid = [NSMutableArray arrayWithCapacity:entries.count];
|
|
29
|
-
NSMutableArray<NSRegularExpression *> *regexes = [NSMutableArray arrayWithCapacity:entries.count];
|
|
30
|
-
for (ENRMLinkContextMenuEntry *entry in entries) {
|
|
31
|
-
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:entry.pattern options:0 error:nil];
|
|
32
|
-
if (!regex || entry.items.count == 0)
|
|
33
|
-
continue;
|
|
34
|
-
[valid addObject:entry];
|
|
35
|
-
[regexes addObject:regex];
|
|
36
|
-
}
|
|
37
|
-
_entries = [valid copy];
|
|
38
|
-
_regexes = [regexes copy];
|
|
39
|
-
[_entriesByURL removeAllObjects];
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
- (nullable ENRMLinkContextMenuEntry *)entryForURL:(NSString *)url
|
|
43
|
-
{
|
|
44
|
-
if (url.length == 0 || _entries.count == 0)
|
|
45
|
-
return nil;
|
|
46
|
-
id cached = _entriesByURL[url];
|
|
47
|
-
if (cached)
|
|
48
|
-
return cached == NSNull.null ? nil : cached;
|
|
49
|
-
|
|
50
|
-
ENRMLinkContextMenuEntry *match = nil;
|
|
51
|
-
NSRange whole = NSMakeRange(0, url.length);
|
|
52
|
-
for (NSUInteger index = 0; index < _regexes.count; index++) {
|
|
53
|
-
if ([_regexes[index] rangeOfFirstMatchInString:url options:0 range:whole].location != NSNotFound) {
|
|
54
|
-
match = _entries[index];
|
|
55
|
-
break;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
_entriesByURL[url] = match ?: NSNull.null;
|
|
59
|
-
return match;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
- (BOOL)hasMenuForURL:(NSString *)url
|
|
63
|
-
{
|
|
64
|
-
#if !TARGET_OS_OSX
|
|
65
|
-
if (@available(iOS 17.0, *))
|
|
66
|
-
return [self entryForURL:url] != nil;
|
|
67
|
-
#endif
|
|
68
|
-
return NO;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
#if !TARGET_OS_OSX
|
|
72
|
-
- (UIMenu *)menuForURL:(NSString *)url title:(NSString *)title
|
|
73
|
-
{
|
|
74
|
-
if (![self hasMenuForURL:url])
|
|
75
|
-
return nil;
|
|
76
|
-
ENRMLinkContextMenuEntry *entry = [self entryForURL:url];
|
|
77
|
-
NSString *pattern = entry.pattern;
|
|
78
|
-
NSMutableArray<UIAction *> *actions = [NSMutableArray arrayWithCapacity:entry.items.count];
|
|
79
|
-
__weak ENRMLinkContextMenus *weakSelf = self;
|
|
80
|
-
for (ENRMLinkContextMenuItem *item in entry.items) {
|
|
81
|
-
NSString *text = item.text;
|
|
82
|
-
UIAction *action = [UIAction actionWithTitle:text
|
|
83
|
-
image:item.icon.length > 0 ? [UIImage systemImageNamed:item.icon] : nil
|
|
84
|
-
identifier:nil
|
|
85
|
-
handler:^(__kindof UIAction *pressed) {
|
|
86
|
-
ENRMLinkContextMenuPressHandler onPress = weakSelf.onPress;
|
|
87
|
-
if (onPress)
|
|
88
|
-
onPress(url, pattern, text);
|
|
89
|
-
}];
|
|
90
|
-
if (item.disabled)
|
|
91
|
-
action.attributes |= UIMenuElementAttributesDisabled;
|
|
92
|
-
if (item.destructive)
|
|
93
|
-
action.attributes |= UIMenuElementAttributesDestructive;
|
|
94
|
-
[actions addObject:action];
|
|
95
|
-
}
|
|
96
|
-
return [UIMenu menuWithTitle:title ?: @"" children:actions];
|
|
97
|
-
}
|
|
98
|
-
#endif
|
|
99
|
-
@end
|
|
100
|
-
|
|
101
|
-
#if !TARGET_OS_OSX
|
|
102
|
-
@implementation ENRMLinkMenuLift {
|
|
103
|
-
UIImageView *_imageView;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
- (BOOL)isOverView:(UIView *)view
|
|
107
|
-
{
|
|
108
|
-
return _imageView != nil && _imageView.superview == view;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
- (void)layImage:(UIImage *)image atFrame:(CGRect)frame overView:(UIView *)view
|
|
112
|
-
{
|
|
113
|
-
[self end];
|
|
114
|
-
_imageView = [[UIImageView alloc] initWithImage:image];
|
|
115
|
-
_imageView.frame = frame;
|
|
116
|
-
[view addSubview:_imageView];
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
- (UITargetedPreview *)previewWithCornerRadius:(CGFloat)cornerRadius backgroundColor:(UIColor *)backgroundColor
|
|
120
|
-
{
|
|
121
|
-
if (_imageView.window == nil)
|
|
122
|
-
return nil;
|
|
123
|
-
UIPreviewParameters *parameters = [[UIPreviewParameters alloc] init];
|
|
124
|
-
if (backgroundColor)
|
|
125
|
-
parameters.backgroundColor = backgroundColor;
|
|
126
|
-
parameters.visiblePath = [UIBezierPath bezierPathWithRoundedRect:_imageView.bounds cornerRadius:cornerRadius];
|
|
127
|
-
return [[UITargetedPreview alloc] initWithView:_imageView parameters:parameters];
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
- (void)end
|
|
131
|
-
{
|
|
132
|
-
if (!_imageView)
|
|
133
|
-
return;
|
|
134
|
-
[_imageView removeFromSuperview];
|
|
135
|
-
_imageView = nil;
|
|
136
|
-
if (self.onEnd)
|
|
137
|
-
self.onEnd();
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
- (void)endWithAnimator:(id<UIContextMenuInteractionAnimating>)animator
|
|
141
|
-
{
|
|
142
|
-
UIImageView *laid = _imageView;
|
|
143
|
-
if (!laid)
|
|
144
|
-
return;
|
|
145
|
-
__weak ENRMLinkMenuLift *weakSelf = self;
|
|
146
|
-
void (^end)(void) = ^{
|
|
147
|
-
ENRMLinkMenuLift *strongSelf = weakSelf;
|
|
148
|
-
if (strongSelf && strongSelf->_imageView == laid)
|
|
149
|
-
[strongSelf end];
|
|
150
|
-
};
|
|
151
|
-
if (animator)
|
|
152
|
-
[animator addCompletion:end];
|
|
153
|
-
else
|
|
154
|
-
end();
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
@end
|
|
158
|
-
|
|
159
|
-
UITextItemMenuConfiguration *ENRMLinkMenuConfigurationForTextItem(UITextView *textView, UITextItem *textItem,
|
|
160
|
-
UIMenu *defaultMenu, ENRMLinkContextMenus *menus,
|
|
161
|
-
BOOL linkPreviewEnabled,
|
|
162
|
-
void (^onLinkLongPress)(NSString *url))
|
|
163
|
-
{
|
|
164
|
-
if ([textView conformsToProtocol:@protocol(ENRMLinkMenuPresenting)] &&
|
|
165
|
-
[(id<ENRMLinkMenuPresenting>)textView presentsLinkMenuAtIndex:textItem.range.location])
|
|
166
|
-
return nil;
|
|
167
|
-
NSString *url = linkURLAtRange(textView, textItem.range);
|
|
168
|
-
UIMenu *menu = [menus menuForURL:url title:linkTitleAtIndex(textView.textStorage, textItem.range.location)];
|
|
169
|
-
if (menu)
|
|
170
|
-
return [UITextItemMenuConfiguration configurationWithMenu:menu];
|
|
171
|
-
if (url && !linkPreviewEnabled) {
|
|
172
|
-
if (onLinkLongPress)
|
|
173
|
-
onLinkLongPress(url);
|
|
174
|
-
return nil;
|
|
175
|
-
}
|
|
176
|
-
return [UITextItemMenuConfiguration configurationWithMenu:defaultMenu];
|
|
177
|
-
}
|
|
178
|
-
#endif
|
|
1
|
+
#import "ENRMLinkContextMenus.h"
|
|
2
|
+
#import "LinkTapUtils.h"
|
|
3
|
+
|
|
4
|
+
@implementation ENRMLinkContextMenuItem
|
|
5
|
+
@end
|
|
6
|
+
|
|
7
|
+
@implementation ENRMLinkContextMenuEntry
|
|
8
|
+
@end
|
|
9
|
+
|
|
10
|
+
@implementation ENRMLinkContextMenus {
|
|
11
|
+
NSArray<NSRegularExpression *> *_regexes;
|
|
12
|
+
// A long press asks about the same URL several times (gesture gating, then the menu).
|
|
13
|
+
NSMutableDictionary<NSString *, id> *_entriesByURL;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
- (instancetype)init
|
|
17
|
+
{
|
|
18
|
+
if (self = [super init]) {
|
|
19
|
+
_entries = @[];
|
|
20
|
+
_regexes = @[];
|
|
21
|
+
_entriesByURL = [NSMutableDictionary new];
|
|
22
|
+
}
|
|
23
|
+
return self;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
- (void)setEntries:(NSArray<ENRMLinkContextMenuEntry *> *)entries
|
|
27
|
+
{
|
|
28
|
+
NSMutableArray<ENRMLinkContextMenuEntry *> *valid = [NSMutableArray arrayWithCapacity:entries.count];
|
|
29
|
+
NSMutableArray<NSRegularExpression *> *regexes = [NSMutableArray arrayWithCapacity:entries.count];
|
|
30
|
+
for (ENRMLinkContextMenuEntry *entry in entries) {
|
|
31
|
+
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:entry.pattern options:0 error:nil];
|
|
32
|
+
if (!regex || entry.items.count == 0)
|
|
33
|
+
continue;
|
|
34
|
+
[valid addObject:entry];
|
|
35
|
+
[regexes addObject:regex];
|
|
36
|
+
}
|
|
37
|
+
_entries = [valid copy];
|
|
38
|
+
_regexes = [regexes copy];
|
|
39
|
+
[_entriesByURL removeAllObjects];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
- (nullable ENRMLinkContextMenuEntry *)entryForURL:(NSString *)url
|
|
43
|
+
{
|
|
44
|
+
if (url.length == 0 || _entries.count == 0)
|
|
45
|
+
return nil;
|
|
46
|
+
id cached = _entriesByURL[url];
|
|
47
|
+
if (cached)
|
|
48
|
+
return cached == NSNull.null ? nil : cached;
|
|
49
|
+
|
|
50
|
+
ENRMLinkContextMenuEntry *match = nil;
|
|
51
|
+
NSRange whole = NSMakeRange(0, url.length);
|
|
52
|
+
for (NSUInteger index = 0; index < _regexes.count; index++) {
|
|
53
|
+
if ([_regexes[index] rangeOfFirstMatchInString:url options:0 range:whole].location != NSNotFound) {
|
|
54
|
+
match = _entries[index];
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
_entriesByURL[url] = match ?: NSNull.null;
|
|
59
|
+
return match;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
- (BOOL)hasMenuForURL:(NSString *)url
|
|
63
|
+
{
|
|
64
|
+
#if !TARGET_OS_OSX
|
|
65
|
+
if (@available(iOS 17.0, *))
|
|
66
|
+
return [self entryForURL:url] != nil;
|
|
67
|
+
#endif
|
|
68
|
+
return NO;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
#if !TARGET_OS_OSX
|
|
72
|
+
- (UIMenu *)menuForURL:(NSString *)url title:(NSString *)title
|
|
73
|
+
{
|
|
74
|
+
if (![self hasMenuForURL:url])
|
|
75
|
+
return nil;
|
|
76
|
+
ENRMLinkContextMenuEntry *entry = [self entryForURL:url];
|
|
77
|
+
NSString *pattern = entry.pattern;
|
|
78
|
+
NSMutableArray<UIAction *> *actions = [NSMutableArray arrayWithCapacity:entry.items.count];
|
|
79
|
+
__weak ENRMLinkContextMenus *weakSelf = self;
|
|
80
|
+
for (ENRMLinkContextMenuItem *item in entry.items) {
|
|
81
|
+
NSString *text = item.text;
|
|
82
|
+
UIAction *action = [UIAction actionWithTitle:text
|
|
83
|
+
image:item.icon.length > 0 ? [UIImage systemImageNamed:item.icon] : nil
|
|
84
|
+
identifier:nil
|
|
85
|
+
handler:^(__kindof UIAction *pressed) {
|
|
86
|
+
ENRMLinkContextMenuPressHandler onPress = weakSelf.onPress;
|
|
87
|
+
if (onPress)
|
|
88
|
+
onPress(url, pattern, text);
|
|
89
|
+
}];
|
|
90
|
+
if (item.disabled)
|
|
91
|
+
action.attributes |= UIMenuElementAttributesDisabled;
|
|
92
|
+
if (item.destructive)
|
|
93
|
+
action.attributes |= UIMenuElementAttributesDestructive;
|
|
94
|
+
[actions addObject:action];
|
|
95
|
+
}
|
|
96
|
+
return [UIMenu menuWithTitle:title ?: @"" children:actions];
|
|
97
|
+
}
|
|
98
|
+
#endif
|
|
99
|
+
@end
|
|
100
|
+
|
|
101
|
+
#if !TARGET_OS_OSX
|
|
102
|
+
@implementation ENRMLinkMenuLift {
|
|
103
|
+
UIImageView *_imageView;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
- (BOOL)isOverView:(UIView *)view
|
|
107
|
+
{
|
|
108
|
+
return _imageView != nil && _imageView.superview == view;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
- (void)layImage:(UIImage *)image atFrame:(CGRect)frame overView:(UIView *)view
|
|
112
|
+
{
|
|
113
|
+
[self end];
|
|
114
|
+
_imageView = [[UIImageView alloc] initWithImage:image];
|
|
115
|
+
_imageView.frame = frame;
|
|
116
|
+
[view addSubview:_imageView];
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
- (UITargetedPreview *)previewWithCornerRadius:(CGFloat)cornerRadius backgroundColor:(UIColor *)backgroundColor
|
|
120
|
+
{
|
|
121
|
+
if (_imageView.window == nil)
|
|
122
|
+
return nil;
|
|
123
|
+
UIPreviewParameters *parameters = [[UIPreviewParameters alloc] init];
|
|
124
|
+
if (backgroundColor)
|
|
125
|
+
parameters.backgroundColor = backgroundColor;
|
|
126
|
+
parameters.visiblePath = [UIBezierPath bezierPathWithRoundedRect:_imageView.bounds cornerRadius:cornerRadius];
|
|
127
|
+
return [[UITargetedPreview alloc] initWithView:_imageView parameters:parameters];
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
- (void)end
|
|
131
|
+
{
|
|
132
|
+
if (!_imageView)
|
|
133
|
+
return;
|
|
134
|
+
[_imageView removeFromSuperview];
|
|
135
|
+
_imageView = nil;
|
|
136
|
+
if (self.onEnd)
|
|
137
|
+
self.onEnd();
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
- (void)endWithAnimator:(id<UIContextMenuInteractionAnimating>)animator
|
|
141
|
+
{
|
|
142
|
+
UIImageView *laid = _imageView;
|
|
143
|
+
if (!laid)
|
|
144
|
+
return;
|
|
145
|
+
__weak ENRMLinkMenuLift *weakSelf = self;
|
|
146
|
+
void (^end)(void) = ^{
|
|
147
|
+
ENRMLinkMenuLift *strongSelf = weakSelf;
|
|
148
|
+
if (strongSelf && strongSelf->_imageView == laid)
|
|
149
|
+
[strongSelf end];
|
|
150
|
+
};
|
|
151
|
+
if (animator)
|
|
152
|
+
[animator addCompletion:end];
|
|
153
|
+
else
|
|
154
|
+
end();
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
@end
|
|
158
|
+
|
|
159
|
+
UITextItemMenuConfiguration *ENRMLinkMenuConfigurationForTextItem(UITextView *textView, UITextItem *textItem,
|
|
160
|
+
UIMenu *defaultMenu, ENRMLinkContextMenus *menus,
|
|
161
|
+
BOOL linkPreviewEnabled,
|
|
162
|
+
void (^onLinkLongPress)(NSString *url))
|
|
163
|
+
{
|
|
164
|
+
if ([textView conformsToProtocol:@protocol(ENRMLinkMenuPresenting)] &&
|
|
165
|
+
[(id<ENRMLinkMenuPresenting>)textView presentsLinkMenuAtIndex:textItem.range.location])
|
|
166
|
+
return nil;
|
|
167
|
+
NSString *url = linkURLAtRange(textView, textItem.range);
|
|
168
|
+
UIMenu *menu = [menus menuForURL:url title:linkTitleAtIndex(textView.textStorage, textItem.range.location)];
|
|
169
|
+
if (menu)
|
|
170
|
+
return [UITextItemMenuConfiguration configurationWithMenu:menu];
|
|
171
|
+
if (url && !linkPreviewEnabled) {
|
|
172
|
+
if (onLinkLongPress)
|
|
173
|
+
onLinkLongPress(url);
|
|
174
|
+
return nil;
|
|
175
|
+
}
|
|
176
|
+
return [UITextItemMenuConfiguration configurationWithMenu:defaultMenu];
|
|
177
|
+
}
|
|
178
|
+
#endif
|
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
#pragma once
|
|
2
|
-
|
|
3
|
-
#import <Foundation/Foundation.h>
|
|
4
|
-
|
|
5
|
-
NS_ASSUME_NONNULL_BEGIN
|
|
6
|
-
|
|
7
|
-
@interface ENRMLinkRegexConfig : NSObject
|
|
8
|
-
|
|
9
|
-
@property (nonatomic, copy, readonly) NSString *pattern;
|
|
10
|
-
@property (nonatomic, assign, readonly) BOOL caseInsensitive;
|
|
11
|
-
@property (nonatomic, assign, readonly) BOOL dotAll;
|
|
12
|
-
@property (nonatomic, assign, readonly) BOOL isDisabled;
|
|
13
|
-
@property (nonatomic, assign, readonly) BOOL isDefault;
|
|
14
|
-
@property (nonatomic, strong, readonly, nullable) NSRegularExpression *parsedRegex;
|
|
15
|
-
@property (nonatomic, strong, readonly, nullable) NSRegularExpression *parsedWholeSpanRegex;
|
|
16
|
-
|
|
17
|
-
- (instancetype)initWithPattern:(NSString *)pattern
|
|
18
|
-
caseInsensitive:(BOOL)caseInsensitive
|
|
19
|
-
dotAll:(BOOL)dotAll
|
|
20
|
-
isDisabled:(BOOL)isDisabled
|
|
21
|
-
isDefault:(BOOL)isDefault;
|
|
22
|
-
|
|
23
|
-
/// Shared instance per pattern and flags; the renderer's props go through here. Thread-safe.
|
|
24
|
-
+ (instancetype)cachedConfigWithPattern:(NSString *)pattern caseInsensitive:(BOOL)caseInsensitive dotAll:(BOOL)dotAll;
|
|
25
|
-
|
|
26
|
-
- (BOOL)isEqualToConfig:(nullable ENRMLinkRegexConfig *)other;
|
|
27
|
-
|
|
28
|
-
@end
|
|
29
|
-
|
|
30
|
-
NS_ASSUME_NONNULL_END
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#import <Foundation/Foundation.h>
|
|
4
|
+
|
|
5
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
6
|
+
|
|
7
|
+
@interface ENRMLinkRegexConfig : NSObject
|
|
8
|
+
|
|
9
|
+
@property (nonatomic, copy, readonly) NSString *pattern;
|
|
10
|
+
@property (nonatomic, assign, readonly) BOOL caseInsensitive;
|
|
11
|
+
@property (nonatomic, assign, readonly) BOOL dotAll;
|
|
12
|
+
@property (nonatomic, assign, readonly) BOOL isDisabled;
|
|
13
|
+
@property (nonatomic, assign, readonly) BOOL isDefault;
|
|
14
|
+
@property (nonatomic, strong, readonly, nullable) NSRegularExpression *parsedRegex;
|
|
15
|
+
@property (nonatomic, strong, readonly, nullable) NSRegularExpression *parsedWholeSpanRegex;
|
|
16
|
+
|
|
17
|
+
- (instancetype)initWithPattern:(NSString *)pattern
|
|
18
|
+
caseInsensitive:(BOOL)caseInsensitive
|
|
19
|
+
dotAll:(BOOL)dotAll
|
|
20
|
+
isDisabled:(BOOL)isDisabled
|
|
21
|
+
isDefault:(BOOL)isDefault;
|
|
22
|
+
|
|
23
|
+
/// Shared instance per pattern and flags; the renderer's props go through here. Thread-safe.
|
|
24
|
+
+ (instancetype)cachedConfigWithPattern:(NSString *)pattern caseInsensitive:(BOOL)caseInsensitive dotAll:(BOOL)dotAll;
|
|
25
|
+
|
|
26
|
+
- (BOOL)isEqualToConfig:(nullable ENRMLinkRegexConfig *)other;
|
|
27
|
+
|
|
28
|
+
@end
|
|
29
|
+
|
|
30
|
+
NS_ASSUME_NONNULL_END
|