@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,403 +1,403 @@
|
|
|
1
|
-
#import "RenderContext.h"
|
|
2
|
-
#import "CodeBackground.h"
|
|
3
|
-
#import "FontUtils.h"
|
|
4
|
-
#import <React/RCTFont.h>
|
|
5
|
-
|
|
6
|
-
@implementation BlockStyle
|
|
7
|
-
@end
|
|
8
|
-
|
|
9
|
-
static NSArray<NSString *> *ENRMScopedKeyPaths(void)
|
|
10
|
-
{
|
|
11
|
-
static NSArray<NSString *> *keyPaths;
|
|
12
|
-
static dispatch_once_t onceToken;
|
|
13
|
-
dispatch_once(&onceToken, ^{
|
|
14
|
-
keyPaths = @[
|
|
15
|
-
@"currentBlockType",
|
|
16
|
-
@"currentHeadingLevel",
|
|
17
|
-
@"currentBlockStyle.fontSize",
|
|
18
|
-
@"currentBlockStyle.fontFamily",
|
|
19
|
-
@"currentBlockStyle.fontWeight",
|
|
20
|
-
@"currentBlockStyle.color",
|
|
21
|
-
@"currentBlockStyle.cachedFont",
|
|
22
|
-
@"currentBlockStyle.cachedTextAttributes",
|
|
23
|
-
@"blockquoteDepth",
|
|
24
|
-
@"listDepth",
|
|
25
|
-
@"listType",
|
|
26
|
-
@"listItemNumber",
|
|
27
|
-
@"listMarkerWidth",
|
|
28
|
-
@"listMarkerExtra",
|
|
29
|
-
@"ancestorMarkerOffset",
|
|
30
|
-
@"listItemMarkerExtra",
|
|
31
|
-
@"accumulatedIndent",
|
|
32
|
-
];
|
|
33
|
-
});
|
|
34
|
-
return keyPaths;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
@implementation RenderContext {
|
|
38
|
-
NSMutableDictionary<NSString *, UIFont *> *_fontCache;
|
|
39
|
-
NSParagraphStyle *_baseSpacerTemplate;
|
|
40
|
-
NSParagraphStyle *_baseBlockSpacerTemplate;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
- (instancetype)init
|
|
44
|
-
{
|
|
45
|
-
if (self = [super init]) {
|
|
46
|
-
_linkRanges = [NSMutableArray array];
|
|
47
|
-
_linkURLs = [NSMutableArray array];
|
|
48
|
-
_headingRanges = [NSMutableArray array];
|
|
49
|
-
_headingLevels = [NSMutableArray array];
|
|
50
|
-
_imageRanges = [NSMutableArray array];
|
|
51
|
-
_imageAltTexts = [NSMutableArray array];
|
|
52
|
-
_imageURLs = [NSMutableArray array];
|
|
53
|
-
_listItemRanges = [NSMutableArray array];
|
|
54
|
-
_listItemPositions = [NSMutableArray array];
|
|
55
|
-
_listItemDepths = [NSMutableArray array];
|
|
56
|
-
_listItemOrdered = [NSMutableArray array];
|
|
57
|
-
_mathReporters = [NSMutableArray array];
|
|
58
|
-
_fontCache = [NSMutableDictionary dictionary];
|
|
59
|
-
_currentBlockStyle = [[BlockStyle alloc] init];
|
|
60
|
-
_allowFontScaling = YES;
|
|
61
|
-
_maxFontSizeMultiplier = 0;
|
|
62
|
-
|
|
63
|
-
NSMutableParagraphStyle *spacerTemplate = [[NSMutableParagraphStyle alloc] init];
|
|
64
|
-
_baseSpacerTemplate = [spacerTemplate copy];
|
|
65
|
-
|
|
66
|
-
NSMutableParagraphStyle *blockSpacerTemplate = [[NSMutableParagraphStyle alloc] init];
|
|
67
|
-
blockSpacerTemplate.minimumLineHeight = 1;
|
|
68
|
-
blockSpacerTemplate.maximumLineHeight = 1;
|
|
69
|
-
_baseBlockSpacerTemplate = [blockSpacerTemplate copy];
|
|
70
|
-
|
|
71
|
-
[self reset];
|
|
72
|
-
}
|
|
73
|
-
return self;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
#pragma mark - Font Cache
|
|
77
|
-
|
|
78
|
-
- (UIFont *)cachedFontForSize:(CGFloat)fontSize family:(NSString *)fontFamily weight:(NSString *)fontWeight
|
|
79
|
-
{
|
|
80
|
-
CGFloat effectiveMultiplier = _allowFontScaling ? RCTFontSizeMultiplierWithMax(_maxFontSizeMultiplier) : 1.0;
|
|
81
|
-
|
|
82
|
-
NSString *weightKey = (fontWeight.length > 0) ? fontWeight : @"";
|
|
83
|
-
NSString *key =
|
|
84
|
-
[NSString stringWithFormat:@"%.1f|%@|%@|%.2f", fontSize, fontFamily ?: @"", weightKey, effectiveMultiplier];
|
|
85
|
-
|
|
86
|
-
UIFont *cached = _fontCache[key];
|
|
87
|
-
if (cached) {
|
|
88
|
-
return cached;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
NSString *effectiveWeight = (fontWeight.length > 0) ? fontWeight : nil;
|
|
92
|
-
|
|
93
|
-
UIFont *font = [RCTFont updateFont:nil
|
|
94
|
-
withFamily:fontFamily
|
|
95
|
-
size:@(fontSize)
|
|
96
|
-
weight:effectiveWeight
|
|
97
|
-
style:nil
|
|
98
|
-
variant:nil
|
|
99
|
-
scaleMultiplier:effectiveMultiplier];
|
|
100
|
-
|
|
101
|
-
if (font) {
|
|
102
|
-
_fontCache[key] = font;
|
|
103
|
-
}
|
|
104
|
-
return font;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
#pragma mark - Paragraph Style Factory
|
|
108
|
-
|
|
109
|
-
- (NSMutableParagraphStyle *)spacerStyleWithHeight:(CGFloat)height spacing:(CGFloat)spacing
|
|
110
|
-
{
|
|
111
|
-
NSMutableParagraphStyle *style = [_baseSpacerTemplate mutableCopy];
|
|
112
|
-
style.minimumLineHeight = height;
|
|
113
|
-
style.maximumLineHeight = height;
|
|
114
|
-
style.paragraphSpacing = spacing;
|
|
115
|
-
return style;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
- (NSMutableParagraphStyle *)blockSpacerStyleWithMargin:(CGFloat)margin
|
|
119
|
-
{
|
|
120
|
-
NSMutableParagraphStyle *style = [_baseBlockSpacerTemplate mutableCopy];
|
|
121
|
-
style.paragraphSpacing = margin;
|
|
122
|
-
return style;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
#pragma mark - Link Registry
|
|
126
|
-
|
|
127
|
-
- (void)registerLinkRange:(NSRange)range url:(NSString *)url
|
|
128
|
-
{
|
|
129
|
-
if (range.length == 0)
|
|
130
|
-
return;
|
|
131
|
-
[self.linkRanges addObject:[NSValue valueWithRange:range]];
|
|
132
|
-
[self.linkURLs addObject:url ?: @""];
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
- (void)applyLinkAttributesToString:(NSMutableAttributedString *)attributedString
|
|
136
|
-
{
|
|
137
|
-
NSUInteger length = attributedString.length;
|
|
138
|
-
for (NSUInteger i = 0; i < self.linkRanges.count; i++) {
|
|
139
|
-
NSRange range = [self.linkRanges[i] rangeValue];
|
|
140
|
-
if (NSMaxRange(range) > length)
|
|
141
|
-
continue;
|
|
142
|
-
[attributedString addAttribute:@"linkURL" value:self.linkURLs[i] range:range];
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
- (void)applyImageAttributesToString:(NSMutableAttributedString *)attributedString
|
|
147
|
-
{
|
|
148
|
-
NSUInteger length = attributedString.length;
|
|
149
|
-
for (NSUInteger i = 0; i < self.imageRanges.count; i++) {
|
|
150
|
-
NSRange range = [self.imageRanges[i] rangeValue];
|
|
151
|
-
if (NSMaxRange(range) > length)
|
|
152
|
-
continue;
|
|
153
|
-
[attributedString addAttribute:@"imageURL" value:self.imageURLs[i] range:range];
|
|
154
|
-
[attributedString addAttribute:@"imageAltText" value:self.imageAltTexts[i] range:range];
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
- (void)registerHeadingRange:(NSRange)range level:(NSInteger)level text:(NSString *)text
|
|
159
|
-
{
|
|
160
|
-
if (range.length == 0)
|
|
161
|
-
return;
|
|
162
|
-
[self.headingRanges addObject:[NSValue valueWithRange:range]];
|
|
163
|
-
[self.headingLevels addObject:@(level)];
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
- (void)registerImageRange:(NSRange)range altText:(NSString *)altText url:(NSString *)url
|
|
167
|
-
{
|
|
168
|
-
if (range.length == 0)
|
|
169
|
-
return;
|
|
170
|
-
[self.imageRanges addObject:[NSValue valueWithRange:range]];
|
|
171
|
-
[self.imageAltTexts addObject:altText ?: @""];
|
|
172
|
-
[self.imageURLs addObject:url ?: @""];
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
#pragma mark - Registration Helpers
|
|
176
|
-
|
|
177
|
-
- (void)registerListItemRange:(NSRange)range
|
|
178
|
-
position:(NSInteger)position
|
|
179
|
-
depth:(NSInteger)depth
|
|
180
|
-
isOrdered:(BOOL)isOrdered
|
|
181
|
-
{
|
|
182
|
-
if (![self isValidRange:range])
|
|
183
|
-
return;
|
|
184
|
-
|
|
185
|
-
[self.listItemRanges addObject:[NSValue valueWithRange:range]];
|
|
186
|
-
[self.listItemPositions addObject:@(position)];
|
|
187
|
-
[self.listItemDepths addObject:@(depth)];
|
|
188
|
-
[self.listItemOrdered addObject:@(isOrdered)];
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
#pragma mark - Private
|
|
192
|
-
|
|
193
|
-
- (BOOL)isValidRange:(NSRange)range
|
|
194
|
-
{
|
|
195
|
-
return range.length > 0 && range.location != NSNotFound;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
#pragma mark - Block Style Management
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* Updates the shared BlockStyle object with new traits.
|
|
202
|
-
* This avoids allocating a new object for every block node in the AST.
|
|
203
|
-
*/
|
|
204
|
-
- (void)setBlockStyle:(BlockType)type
|
|
205
|
-
fontSize:(CGFloat)fontSize
|
|
206
|
-
fontFamily:(NSString *)fontFamily
|
|
207
|
-
fontWeight:(NSString *)fontWeight
|
|
208
|
-
color:(RCTUIColor *)color
|
|
209
|
-
headingLevel:(NSInteger)headingLevel
|
|
210
|
-
{
|
|
211
|
-
_currentBlockType = type;
|
|
212
|
-
_currentHeadingLevel = headingLevel;
|
|
213
|
-
|
|
214
|
-
_currentBlockStyle.fontSize = fontSize;
|
|
215
|
-
_currentBlockStyle.fontFamily = fontFamily ?: @"";
|
|
216
|
-
_currentBlockStyle.fontWeight = fontWeight ?: @"normal";
|
|
217
|
-
_currentBlockStyle.color = color ?: [RCTUIColor blackColor];
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
- (void)setBlockStyle:(BlockType)type
|
|
221
|
-
fontSize:(CGFloat)fontSize
|
|
222
|
-
fontFamily:(NSString *)fontFamily
|
|
223
|
-
fontWeight:(NSString *)fontWeight
|
|
224
|
-
color:(RCTUIColor *)color
|
|
225
|
-
{
|
|
226
|
-
[self setBlockStyle:type fontSize:fontSize fontFamily:fontFamily fontWeight:fontWeight color:color headingLevel:0];
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
- (void)setBlockStyle:(BlockType)type font:(UIFont *)font color:(RCTUIColor *)color headingLevel:(NSInteger)headingLevel
|
|
230
|
-
{
|
|
231
|
-
_currentBlockType = type;
|
|
232
|
-
_currentHeadingLevel = headingLevel;
|
|
233
|
-
|
|
234
|
-
RCTUIColor *finalColor = color ?: [RCTUIColor blackColor];
|
|
235
|
-
_currentBlockStyle.cachedFont = font;
|
|
236
|
-
_currentBlockStyle.color = finalColor;
|
|
237
|
-
|
|
238
|
-
// Pre-create text attributes dictionary if we have both font and color
|
|
239
|
-
if (font) {
|
|
240
|
-
_currentBlockStyle.cachedTextAttributes =
|
|
241
|
-
@{NSFontAttributeName : font, NSForegroundColorAttributeName : finalColor};
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
- (BlockStyle *)getBlockStyle
|
|
246
|
-
{
|
|
247
|
-
return _currentBlockStyle;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
- (NSDictionary *)getTextAttributes
|
|
251
|
-
{
|
|
252
|
-
BlockStyle *style = _currentBlockStyle;
|
|
253
|
-
|
|
254
|
-
// Return pre-cached attributes if available
|
|
255
|
-
if (style.cachedTextAttributes) {
|
|
256
|
-
return style.cachedTextAttributes;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
// Fall back to creating attributes from font cache
|
|
260
|
-
UIFont *font = style.cachedFont;
|
|
261
|
-
if (!font) {
|
|
262
|
-
font = [self cachedFontForSize:style.fontSize family:style.fontFamily weight:style.fontWeight];
|
|
263
|
-
}
|
|
264
|
-
RCTUIColor *color = style.color ?: [RCTUIColor blackColor];
|
|
265
|
-
|
|
266
|
-
// Cache for future calls within same block
|
|
267
|
-
style.cachedTextAttributes = @{NSFontAttributeName : font, NSForegroundColorAttributeName : color};
|
|
268
|
-
return style.cachedTextAttributes;
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
- (void)clearBlockStyle
|
|
272
|
-
{
|
|
273
|
-
_currentBlockType = BlockTypeNone;
|
|
274
|
-
_currentHeadingLevel = 0;
|
|
275
|
-
_currentBlockStyle.cachedFont = nil;
|
|
276
|
-
_currentBlockStyle.cachedTextAttributes = nil;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
- (id)snapshotScope
|
|
280
|
-
{
|
|
281
|
-
NSArray<NSString *> *keyPaths = ENRMScopedKeyPaths();
|
|
282
|
-
NSMutableDictionary *snapshot = [NSMutableDictionary dictionaryWithCapacity:keyPaths.count];
|
|
283
|
-
for (NSString *keyPath in keyPaths) {
|
|
284
|
-
snapshot[keyPath] = [self valueForKeyPath:keyPath] ?: [NSNull null];
|
|
285
|
-
}
|
|
286
|
-
return snapshot;
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
- (void)restoreScope:(id)snapshot
|
|
290
|
-
{
|
|
291
|
-
NSDictionary *frame = snapshot;
|
|
292
|
-
for (NSString *keyPath in ENRMScopedKeyPaths()) {
|
|
293
|
-
id value = frame[keyPath];
|
|
294
|
-
[self setValue:(value == [NSNull null] ? nil : value) forKeyPath:keyPath];
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
#pragma mark - Reset
|
|
299
|
-
|
|
300
|
-
- (void)reset
|
|
301
|
-
{
|
|
302
|
-
[_linkRanges removeAllObjects];
|
|
303
|
-
[_linkURLs removeAllObjects];
|
|
304
|
-
[_headingRanges removeAllObjects];
|
|
305
|
-
[_headingLevels removeAllObjects];
|
|
306
|
-
[_imageRanges removeAllObjects];
|
|
307
|
-
[_imageAltTexts removeAllObjects];
|
|
308
|
-
[_imageURLs removeAllObjects];
|
|
309
|
-
[_listItemRanges removeAllObjects];
|
|
310
|
-
[_listItemPositions removeAllObjects];
|
|
311
|
-
[_listItemDepths removeAllObjects];
|
|
312
|
-
[_listItemOrdered removeAllObjects];
|
|
313
|
-
[_mathReporters removeAllObjects];
|
|
314
|
-
[self clearBlockStyle];
|
|
315
|
-
|
|
316
|
-
_blockquoteDepth = 0;
|
|
317
|
-
_listDepth = 0;
|
|
318
|
-
_listType = ListTypeUnordered;
|
|
319
|
-
_listItemNumber = 0;
|
|
320
|
-
_listMarkerWidth = 0;
|
|
321
|
-
_listMarkerExtra = 0;
|
|
322
|
-
_ancestorMarkerOffset = 0;
|
|
323
|
-
_listItemMarkerExtra = 0;
|
|
324
|
-
_accumulatedIndent = 0;
|
|
325
|
-
_taskItemCount = 0;
|
|
326
|
-
|
|
327
|
-
// Revert shared style object to baseline defaults
|
|
328
|
-
_currentBlockStyle.fontSize = 0;
|
|
329
|
-
_currentBlockStyle.fontFamily = @"";
|
|
330
|
-
_currentBlockStyle.fontWeight = @"";
|
|
331
|
-
_currentBlockStyle.color = [RCTUIColor blackColor];
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
#pragma mark - Static Utilities
|
|
335
|
-
|
|
336
|
-
/**
|
|
337
|
-
* Determines if specific inline attributes should protect the current color.
|
|
338
|
-
*/
|
|
339
|
-
+ (BOOL)shouldPreserveColors:(NSDictionary *)attrs
|
|
340
|
-
{
|
|
341
|
-
return (attrs[NSLinkAttributeName] != nil || attrs[CodeAttributeName] != nil);
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
// TODO: Unify calculateStrongColor and calculateHighlightColor into a single helper that
|
|
345
|
-
// resolves inline foreground color from (configColor, inheritanceBaseline, blockColor).
|
|
346
|
-
|
|
347
|
-
/**
|
|
348
|
-
* Calculates whether a strong color should override the block color.
|
|
349
|
-
*/
|
|
350
|
-
+ (RCTUIColor *)calculateStrongColor:(RCTUIColor *)configStrongColor blockColor:(RCTUIColor *)blockColor
|
|
351
|
-
{
|
|
352
|
-
if (!configStrongColor || [configStrongColor isEqual:blockColor]) {
|
|
353
|
-
return blockColor;
|
|
354
|
-
}
|
|
355
|
-
return configStrongColor;
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
+ (RCTUIColor *)calculateHighlightColor:(RCTUIColor *)configHighlightColor
|
|
359
|
-
paragraphColor:(RCTUIColor *)paragraphColor
|
|
360
|
-
blockColor:(RCTUIColor *)blockColor
|
|
361
|
-
{
|
|
362
|
-
if ([configHighlightColor isEqual:paragraphColor]) {
|
|
363
|
-
return blockColor;
|
|
364
|
-
}
|
|
365
|
-
return configHighlightColor;
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
/**
|
|
369
|
-
* Safely calculates a range based on a start point and the current output length.
|
|
370
|
-
*/
|
|
371
|
-
+ (NSRange)rangeForRenderedContent:(NSMutableAttributedString *)output start:(NSUInteger)start
|
|
372
|
-
{
|
|
373
|
-
if (output.length < start)
|
|
374
|
-
return NSMakeRange(start, 0);
|
|
375
|
-
return NSMakeRange(start, output.length - start);
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
/**
|
|
379
|
-
* Surgically applies attributes only if they differ from current values.
|
|
380
|
-
* This minimizes "dirtying" the AttributedString, which improves layout performance.
|
|
381
|
-
*/
|
|
382
|
-
+ (void)applyFontAndColorAttributes:(NSMutableAttributedString *)output
|
|
383
|
-
range:(NSRange)range
|
|
384
|
-
font:(UIFont *)font
|
|
385
|
-
color:(RCTUIColor *)color
|
|
386
|
-
existingAttributes:(NSDictionary *)attrs
|
|
387
|
-
shouldPreserveColors:(BOOL)shouldPreserve
|
|
388
|
-
{
|
|
389
|
-
if (range.length == 0)
|
|
390
|
-
return;
|
|
391
|
-
|
|
392
|
-
// Font Update: Only if it exists and is different
|
|
393
|
-
if (font && ![font isEqual:attrs[NSFontAttributeName]]) {
|
|
394
|
-
[output addAttribute:NSFontAttributeName value:font range:range];
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
// Color Update: Only if not a link/code and different from existing
|
|
398
|
-
if (color && !shouldPreserve && ![color isEqual:attrs[NSForegroundColorAttributeName]]) {
|
|
399
|
-
[output addAttribute:NSForegroundColorAttributeName value:color range:range];
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
|
|
1
|
+
#import "RenderContext.h"
|
|
2
|
+
#import "CodeBackground.h"
|
|
3
|
+
#import "FontUtils.h"
|
|
4
|
+
#import <React/RCTFont.h>
|
|
5
|
+
|
|
6
|
+
@implementation BlockStyle
|
|
7
|
+
@end
|
|
8
|
+
|
|
9
|
+
static NSArray<NSString *> *ENRMScopedKeyPaths(void)
|
|
10
|
+
{
|
|
11
|
+
static NSArray<NSString *> *keyPaths;
|
|
12
|
+
static dispatch_once_t onceToken;
|
|
13
|
+
dispatch_once(&onceToken, ^{
|
|
14
|
+
keyPaths = @[
|
|
15
|
+
@"currentBlockType",
|
|
16
|
+
@"currentHeadingLevel",
|
|
17
|
+
@"currentBlockStyle.fontSize",
|
|
18
|
+
@"currentBlockStyle.fontFamily",
|
|
19
|
+
@"currentBlockStyle.fontWeight",
|
|
20
|
+
@"currentBlockStyle.color",
|
|
21
|
+
@"currentBlockStyle.cachedFont",
|
|
22
|
+
@"currentBlockStyle.cachedTextAttributes",
|
|
23
|
+
@"blockquoteDepth",
|
|
24
|
+
@"listDepth",
|
|
25
|
+
@"listType",
|
|
26
|
+
@"listItemNumber",
|
|
27
|
+
@"listMarkerWidth",
|
|
28
|
+
@"listMarkerExtra",
|
|
29
|
+
@"ancestorMarkerOffset",
|
|
30
|
+
@"listItemMarkerExtra",
|
|
31
|
+
@"accumulatedIndent",
|
|
32
|
+
];
|
|
33
|
+
});
|
|
34
|
+
return keyPaths;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@implementation RenderContext {
|
|
38
|
+
NSMutableDictionary<NSString *, UIFont *> *_fontCache;
|
|
39
|
+
NSParagraphStyle *_baseSpacerTemplate;
|
|
40
|
+
NSParagraphStyle *_baseBlockSpacerTemplate;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
- (instancetype)init
|
|
44
|
+
{
|
|
45
|
+
if (self = [super init]) {
|
|
46
|
+
_linkRanges = [NSMutableArray array];
|
|
47
|
+
_linkURLs = [NSMutableArray array];
|
|
48
|
+
_headingRanges = [NSMutableArray array];
|
|
49
|
+
_headingLevels = [NSMutableArray array];
|
|
50
|
+
_imageRanges = [NSMutableArray array];
|
|
51
|
+
_imageAltTexts = [NSMutableArray array];
|
|
52
|
+
_imageURLs = [NSMutableArray array];
|
|
53
|
+
_listItemRanges = [NSMutableArray array];
|
|
54
|
+
_listItemPositions = [NSMutableArray array];
|
|
55
|
+
_listItemDepths = [NSMutableArray array];
|
|
56
|
+
_listItemOrdered = [NSMutableArray array];
|
|
57
|
+
_mathReporters = [NSMutableArray array];
|
|
58
|
+
_fontCache = [NSMutableDictionary dictionary];
|
|
59
|
+
_currentBlockStyle = [[BlockStyle alloc] init];
|
|
60
|
+
_allowFontScaling = YES;
|
|
61
|
+
_maxFontSizeMultiplier = 0;
|
|
62
|
+
|
|
63
|
+
NSMutableParagraphStyle *spacerTemplate = [[NSMutableParagraphStyle alloc] init];
|
|
64
|
+
_baseSpacerTemplate = [spacerTemplate copy];
|
|
65
|
+
|
|
66
|
+
NSMutableParagraphStyle *blockSpacerTemplate = [[NSMutableParagraphStyle alloc] init];
|
|
67
|
+
blockSpacerTemplate.minimumLineHeight = 1;
|
|
68
|
+
blockSpacerTemplate.maximumLineHeight = 1;
|
|
69
|
+
_baseBlockSpacerTemplate = [blockSpacerTemplate copy];
|
|
70
|
+
|
|
71
|
+
[self reset];
|
|
72
|
+
}
|
|
73
|
+
return self;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
#pragma mark - Font Cache
|
|
77
|
+
|
|
78
|
+
- (UIFont *)cachedFontForSize:(CGFloat)fontSize family:(NSString *)fontFamily weight:(NSString *)fontWeight
|
|
79
|
+
{
|
|
80
|
+
CGFloat effectiveMultiplier = _allowFontScaling ? RCTFontSizeMultiplierWithMax(_maxFontSizeMultiplier) : 1.0;
|
|
81
|
+
|
|
82
|
+
NSString *weightKey = (fontWeight.length > 0) ? fontWeight : @"";
|
|
83
|
+
NSString *key =
|
|
84
|
+
[NSString stringWithFormat:@"%.1f|%@|%@|%.2f", fontSize, fontFamily ?: @"", weightKey, effectiveMultiplier];
|
|
85
|
+
|
|
86
|
+
UIFont *cached = _fontCache[key];
|
|
87
|
+
if (cached) {
|
|
88
|
+
return cached;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
NSString *effectiveWeight = (fontWeight.length > 0) ? fontWeight : nil;
|
|
92
|
+
|
|
93
|
+
UIFont *font = [RCTFont updateFont:nil
|
|
94
|
+
withFamily:fontFamily
|
|
95
|
+
size:@(fontSize)
|
|
96
|
+
weight:effectiveWeight
|
|
97
|
+
style:nil
|
|
98
|
+
variant:nil
|
|
99
|
+
scaleMultiplier:effectiveMultiplier];
|
|
100
|
+
|
|
101
|
+
if (font) {
|
|
102
|
+
_fontCache[key] = font;
|
|
103
|
+
}
|
|
104
|
+
return font;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
#pragma mark - Paragraph Style Factory
|
|
108
|
+
|
|
109
|
+
- (NSMutableParagraphStyle *)spacerStyleWithHeight:(CGFloat)height spacing:(CGFloat)spacing
|
|
110
|
+
{
|
|
111
|
+
NSMutableParagraphStyle *style = [_baseSpacerTemplate mutableCopy];
|
|
112
|
+
style.minimumLineHeight = height;
|
|
113
|
+
style.maximumLineHeight = height;
|
|
114
|
+
style.paragraphSpacing = spacing;
|
|
115
|
+
return style;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
- (NSMutableParagraphStyle *)blockSpacerStyleWithMargin:(CGFloat)margin
|
|
119
|
+
{
|
|
120
|
+
NSMutableParagraphStyle *style = [_baseBlockSpacerTemplate mutableCopy];
|
|
121
|
+
style.paragraphSpacing = margin;
|
|
122
|
+
return style;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
#pragma mark - Link Registry
|
|
126
|
+
|
|
127
|
+
- (void)registerLinkRange:(NSRange)range url:(NSString *)url
|
|
128
|
+
{
|
|
129
|
+
if (range.length == 0)
|
|
130
|
+
return;
|
|
131
|
+
[self.linkRanges addObject:[NSValue valueWithRange:range]];
|
|
132
|
+
[self.linkURLs addObject:url ?: @""];
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
- (void)applyLinkAttributesToString:(NSMutableAttributedString *)attributedString
|
|
136
|
+
{
|
|
137
|
+
NSUInteger length = attributedString.length;
|
|
138
|
+
for (NSUInteger i = 0; i < self.linkRanges.count; i++) {
|
|
139
|
+
NSRange range = [self.linkRanges[i] rangeValue];
|
|
140
|
+
if (NSMaxRange(range) > length)
|
|
141
|
+
continue;
|
|
142
|
+
[attributedString addAttribute:@"linkURL" value:self.linkURLs[i] range:range];
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
- (void)applyImageAttributesToString:(NSMutableAttributedString *)attributedString
|
|
147
|
+
{
|
|
148
|
+
NSUInteger length = attributedString.length;
|
|
149
|
+
for (NSUInteger i = 0; i < self.imageRanges.count; i++) {
|
|
150
|
+
NSRange range = [self.imageRanges[i] rangeValue];
|
|
151
|
+
if (NSMaxRange(range) > length)
|
|
152
|
+
continue;
|
|
153
|
+
[attributedString addAttribute:@"imageURL" value:self.imageURLs[i] range:range];
|
|
154
|
+
[attributedString addAttribute:@"imageAltText" value:self.imageAltTexts[i] range:range];
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
- (void)registerHeadingRange:(NSRange)range level:(NSInteger)level text:(NSString *)text
|
|
159
|
+
{
|
|
160
|
+
if (range.length == 0)
|
|
161
|
+
return;
|
|
162
|
+
[self.headingRanges addObject:[NSValue valueWithRange:range]];
|
|
163
|
+
[self.headingLevels addObject:@(level)];
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
- (void)registerImageRange:(NSRange)range altText:(NSString *)altText url:(NSString *)url
|
|
167
|
+
{
|
|
168
|
+
if (range.length == 0)
|
|
169
|
+
return;
|
|
170
|
+
[self.imageRanges addObject:[NSValue valueWithRange:range]];
|
|
171
|
+
[self.imageAltTexts addObject:altText ?: @""];
|
|
172
|
+
[self.imageURLs addObject:url ?: @""];
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
#pragma mark - Registration Helpers
|
|
176
|
+
|
|
177
|
+
- (void)registerListItemRange:(NSRange)range
|
|
178
|
+
position:(NSInteger)position
|
|
179
|
+
depth:(NSInteger)depth
|
|
180
|
+
isOrdered:(BOOL)isOrdered
|
|
181
|
+
{
|
|
182
|
+
if (![self isValidRange:range])
|
|
183
|
+
return;
|
|
184
|
+
|
|
185
|
+
[self.listItemRanges addObject:[NSValue valueWithRange:range]];
|
|
186
|
+
[self.listItemPositions addObject:@(position)];
|
|
187
|
+
[self.listItemDepths addObject:@(depth)];
|
|
188
|
+
[self.listItemOrdered addObject:@(isOrdered)];
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
#pragma mark - Private
|
|
192
|
+
|
|
193
|
+
- (BOOL)isValidRange:(NSRange)range
|
|
194
|
+
{
|
|
195
|
+
return range.length > 0 && range.location != NSNotFound;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
#pragma mark - Block Style Management
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Updates the shared BlockStyle object with new traits.
|
|
202
|
+
* This avoids allocating a new object for every block node in the AST.
|
|
203
|
+
*/
|
|
204
|
+
- (void)setBlockStyle:(BlockType)type
|
|
205
|
+
fontSize:(CGFloat)fontSize
|
|
206
|
+
fontFamily:(NSString *)fontFamily
|
|
207
|
+
fontWeight:(NSString *)fontWeight
|
|
208
|
+
color:(RCTUIColor *)color
|
|
209
|
+
headingLevel:(NSInteger)headingLevel
|
|
210
|
+
{
|
|
211
|
+
_currentBlockType = type;
|
|
212
|
+
_currentHeadingLevel = headingLevel;
|
|
213
|
+
|
|
214
|
+
_currentBlockStyle.fontSize = fontSize;
|
|
215
|
+
_currentBlockStyle.fontFamily = fontFamily ?: @"";
|
|
216
|
+
_currentBlockStyle.fontWeight = fontWeight ?: @"normal";
|
|
217
|
+
_currentBlockStyle.color = color ?: [RCTUIColor blackColor];
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
- (void)setBlockStyle:(BlockType)type
|
|
221
|
+
fontSize:(CGFloat)fontSize
|
|
222
|
+
fontFamily:(NSString *)fontFamily
|
|
223
|
+
fontWeight:(NSString *)fontWeight
|
|
224
|
+
color:(RCTUIColor *)color
|
|
225
|
+
{
|
|
226
|
+
[self setBlockStyle:type fontSize:fontSize fontFamily:fontFamily fontWeight:fontWeight color:color headingLevel:0];
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
- (void)setBlockStyle:(BlockType)type font:(UIFont *)font color:(RCTUIColor *)color headingLevel:(NSInteger)headingLevel
|
|
230
|
+
{
|
|
231
|
+
_currentBlockType = type;
|
|
232
|
+
_currentHeadingLevel = headingLevel;
|
|
233
|
+
|
|
234
|
+
RCTUIColor *finalColor = color ?: [RCTUIColor blackColor];
|
|
235
|
+
_currentBlockStyle.cachedFont = font;
|
|
236
|
+
_currentBlockStyle.color = finalColor;
|
|
237
|
+
|
|
238
|
+
// Pre-create text attributes dictionary if we have both font and color
|
|
239
|
+
if (font) {
|
|
240
|
+
_currentBlockStyle.cachedTextAttributes =
|
|
241
|
+
@{NSFontAttributeName : font, NSForegroundColorAttributeName : finalColor};
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
- (BlockStyle *)getBlockStyle
|
|
246
|
+
{
|
|
247
|
+
return _currentBlockStyle;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
- (NSDictionary *)getTextAttributes
|
|
251
|
+
{
|
|
252
|
+
BlockStyle *style = _currentBlockStyle;
|
|
253
|
+
|
|
254
|
+
// Return pre-cached attributes if available
|
|
255
|
+
if (style.cachedTextAttributes) {
|
|
256
|
+
return style.cachedTextAttributes;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Fall back to creating attributes from font cache
|
|
260
|
+
UIFont *font = style.cachedFont;
|
|
261
|
+
if (!font) {
|
|
262
|
+
font = [self cachedFontForSize:style.fontSize family:style.fontFamily weight:style.fontWeight];
|
|
263
|
+
}
|
|
264
|
+
RCTUIColor *color = style.color ?: [RCTUIColor blackColor];
|
|
265
|
+
|
|
266
|
+
// Cache for future calls within same block
|
|
267
|
+
style.cachedTextAttributes = @{NSFontAttributeName : font, NSForegroundColorAttributeName : color};
|
|
268
|
+
return style.cachedTextAttributes;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
- (void)clearBlockStyle
|
|
272
|
+
{
|
|
273
|
+
_currentBlockType = BlockTypeNone;
|
|
274
|
+
_currentHeadingLevel = 0;
|
|
275
|
+
_currentBlockStyle.cachedFont = nil;
|
|
276
|
+
_currentBlockStyle.cachedTextAttributes = nil;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
- (id)snapshotScope
|
|
280
|
+
{
|
|
281
|
+
NSArray<NSString *> *keyPaths = ENRMScopedKeyPaths();
|
|
282
|
+
NSMutableDictionary *snapshot = [NSMutableDictionary dictionaryWithCapacity:keyPaths.count];
|
|
283
|
+
for (NSString *keyPath in keyPaths) {
|
|
284
|
+
snapshot[keyPath] = [self valueForKeyPath:keyPath] ?: [NSNull null];
|
|
285
|
+
}
|
|
286
|
+
return snapshot;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
- (void)restoreScope:(id)snapshot
|
|
290
|
+
{
|
|
291
|
+
NSDictionary *frame = snapshot;
|
|
292
|
+
for (NSString *keyPath in ENRMScopedKeyPaths()) {
|
|
293
|
+
id value = frame[keyPath];
|
|
294
|
+
[self setValue:(value == [NSNull null] ? nil : value) forKeyPath:keyPath];
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
#pragma mark - Reset
|
|
299
|
+
|
|
300
|
+
- (void)reset
|
|
301
|
+
{
|
|
302
|
+
[_linkRanges removeAllObjects];
|
|
303
|
+
[_linkURLs removeAllObjects];
|
|
304
|
+
[_headingRanges removeAllObjects];
|
|
305
|
+
[_headingLevels removeAllObjects];
|
|
306
|
+
[_imageRanges removeAllObjects];
|
|
307
|
+
[_imageAltTexts removeAllObjects];
|
|
308
|
+
[_imageURLs removeAllObjects];
|
|
309
|
+
[_listItemRanges removeAllObjects];
|
|
310
|
+
[_listItemPositions removeAllObjects];
|
|
311
|
+
[_listItemDepths removeAllObjects];
|
|
312
|
+
[_listItemOrdered removeAllObjects];
|
|
313
|
+
[_mathReporters removeAllObjects];
|
|
314
|
+
[self clearBlockStyle];
|
|
315
|
+
|
|
316
|
+
_blockquoteDepth = 0;
|
|
317
|
+
_listDepth = 0;
|
|
318
|
+
_listType = ListTypeUnordered;
|
|
319
|
+
_listItemNumber = 0;
|
|
320
|
+
_listMarkerWidth = 0;
|
|
321
|
+
_listMarkerExtra = 0;
|
|
322
|
+
_ancestorMarkerOffset = 0;
|
|
323
|
+
_listItemMarkerExtra = 0;
|
|
324
|
+
_accumulatedIndent = 0;
|
|
325
|
+
_taskItemCount = 0;
|
|
326
|
+
|
|
327
|
+
// Revert shared style object to baseline defaults
|
|
328
|
+
_currentBlockStyle.fontSize = 0;
|
|
329
|
+
_currentBlockStyle.fontFamily = @"";
|
|
330
|
+
_currentBlockStyle.fontWeight = @"";
|
|
331
|
+
_currentBlockStyle.color = [RCTUIColor blackColor];
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
#pragma mark - Static Utilities
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Determines if specific inline attributes should protect the current color.
|
|
338
|
+
*/
|
|
339
|
+
+ (BOOL)shouldPreserveColors:(NSDictionary *)attrs
|
|
340
|
+
{
|
|
341
|
+
return (attrs[NSLinkAttributeName] != nil || attrs[CodeAttributeName] != nil);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// TODO: Unify calculateStrongColor and calculateHighlightColor into a single helper that
|
|
345
|
+
// resolves inline foreground color from (configColor, inheritanceBaseline, blockColor).
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Calculates whether a strong color should override the block color.
|
|
349
|
+
*/
|
|
350
|
+
+ (RCTUIColor *)calculateStrongColor:(RCTUIColor *)configStrongColor blockColor:(RCTUIColor *)blockColor
|
|
351
|
+
{
|
|
352
|
+
if (!configStrongColor || [configStrongColor isEqual:blockColor]) {
|
|
353
|
+
return blockColor;
|
|
354
|
+
}
|
|
355
|
+
return configStrongColor;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
+ (RCTUIColor *)calculateHighlightColor:(RCTUIColor *)configHighlightColor
|
|
359
|
+
paragraphColor:(RCTUIColor *)paragraphColor
|
|
360
|
+
blockColor:(RCTUIColor *)blockColor
|
|
361
|
+
{
|
|
362
|
+
if ([configHighlightColor isEqual:paragraphColor]) {
|
|
363
|
+
return blockColor;
|
|
364
|
+
}
|
|
365
|
+
return configHighlightColor;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Safely calculates a range based on a start point and the current output length.
|
|
370
|
+
*/
|
|
371
|
+
+ (NSRange)rangeForRenderedContent:(NSMutableAttributedString *)output start:(NSUInteger)start
|
|
372
|
+
{
|
|
373
|
+
if (output.length < start)
|
|
374
|
+
return NSMakeRange(start, 0);
|
|
375
|
+
return NSMakeRange(start, output.length - start);
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Surgically applies attributes only if they differ from current values.
|
|
380
|
+
* This minimizes "dirtying" the AttributedString, which improves layout performance.
|
|
381
|
+
*/
|
|
382
|
+
+ (void)applyFontAndColorAttributes:(NSMutableAttributedString *)output
|
|
383
|
+
range:(NSRange)range
|
|
384
|
+
font:(UIFont *)font
|
|
385
|
+
color:(RCTUIColor *)color
|
|
386
|
+
existingAttributes:(NSDictionary *)attrs
|
|
387
|
+
shouldPreserveColors:(BOOL)shouldPreserve
|
|
388
|
+
{
|
|
389
|
+
if (range.length == 0)
|
|
390
|
+
return;
|
|
391
|
+
|
|
392
|
+
// Font Update: Only if it exists and is different
|
|
393
|
+
if (font && ![font isEqual:attrs[NSFontAttributeName]]) {
|
|
394
|
+
[output addAttribute:NSFontAttributeName value:font range:range];
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// Color Update: Only if not a link/code and different from existing
|
|
398
|
+
if (color && !shouldPreserve && ![color isEqual:attrs[NSForegroundColorAttributeName]]) {
|
|
399
|
+
[output addAttribute:NSForegroundColorAttributeName value:color range:range];
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
403
403
|
@end
|