@mathers101/react-native-render-rich-text 0.0.0-stage → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +20 -0
- package/README.md +140 -3
- package/ReactNativeRenderRichText.podspec +23 -0
- package/android/build.gradle +86 -0
- package/android/consumer-rules.pro +3 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/cpp/jni-adapter.cpp +191 -0
- package/android/src/main/java/com/renderrichtext/EnrichedTiptapText.kt +673 -0
- package/android/src/main/java/com/renderrichtext/EnrichedTiptapTextLayoutManager.kt +24 -0
- package/android/src/main/java/com/renderrichtext/EnrichedTiptapTextManager.kt +405 -0
- package/android/src/main/java/com/renderrichtext/EnrichedTiptapTextPackage.kt +13 -0
- package/android/src/main/java/com/renderrichtext/MeasurementStore.kt +644 -0
- package/android/src/main/java/com/renderrichtext/accessibility/AccessibilityLabels.kt +17 -0
- package/android/src/main/java/com/renderrichtext/accessibility/AccessibleTiptapTextView.kt +112 -0
- package/android/src/main/java/com/renderrichtext/accessibility/TiptapAccessibilityHelper.kt +576 -0
- package/android/src/main/java/com/renderrichtext/events/CodeBlockPressEvent.kt +24 -0
- package/android/src/main/java/com/renderrichtext/events/ContextMenuItemPressEvent.kt +28 -0
- package/android/src/main/java/com/renderrichtext/events/CopyPressEvent.kt +24 -0
- package/android/src/main/java/com/renderrichtext/events/FactoidPressEvent.kt +23 -0
- package/android/src/main/java/com/renderrichtext/events/ImagePressEvent.kt +25 -0
- package/android/src/main/java/com/renderrichtext/events/LatexErrorEvent.kt +29 -0
- package/android/src/main/java/com/renderrichtext/events/LinkLongPressEvent.kt +23 -0
- package/android/src/main/java/com/renderrichtext/events/LinkPressEvent.kt +23 -0
- package/android/src/main/java/com/renderrichtext/events/MentionLongPressEvent.kt +25 -0
- package/android/src/main/java/com/renderrichtext/events/MentionPressEvent.kt +25 -0
- package/android/src/main/java/com/renderrichtext/events/TaskListItemPressEvent.kt +26 -0
- package/android/src/main/java/com/renderrichtext/math/LatexErrorReporter.kt +9 -0
- package/android/src/main/java/com/renderrichtext/parser/Parser.kt +59 -0
- package/android/src/main/java/com/renderrichtext/parser/TextLinkMatching.kt +35 -0
- package/android/src/main/java/com/renderrichtext/parser/TiptapASTNode.kt +69 -0
- package/android/src/main/java/com/renderrichtext/renderer/BaselineShiftRenderer.kt +45 -0
- package/android/src/main/java/com/renderrichtext/renderer/BlankLineRenderer.kt +39 -0
- package/android/src/main/java/com/renderrichtext/renderer/BlockStyleContext.kt +181 -0
- package/android/src/main/java/com/renderrichtext/renderer/BlockquoteRenderer.kt +243 -0
- package/android/src/main/java/com/renderrichtext/renderer/BlockquoteTextRenderer.kt +56 -0
- package/android/src/main/java/com/renderrichtext/renderer/CodeBlockRenderer.kt +135 -0
- package/android/src/main/java/com/renderrichtext/renderer/CodeRenderer.kt +37 -0
- package/android/src/main/java/com/renderrichtext/renderer/EmphasisRenderer.kt +28 -0
- package/android/src/main/java/com/renderrichtext/renderer/FactoidRenderer.kt +97 -0
- package/android/src/main/java/com/renderrichtext/renderer/HeadingRenderer.kt +81 -0
- package/android/src/main/java/com/renderrichtext/renderer/HighlightRenderer.kt +26 -0
- package/android/src/main/java/com/renderrichtext/renderer/LineBreakRenderer.kt +17 -0
- package/android/src/main/java/com/renderrichtext/renderer/LinkRenderer.kt +90 -0
- package/android/src/main/java/com/renderrichtext/renderer/ListContextManager.kt +109 -0
- package/android/src/main/java/com/renderrichtext/renderer/ListItemRenderer.kt +211 -0
- package/android/src/main/java/com/renderrichtext/renderer/ListRenderer.kt +133 -0
- package/android/src/main/java/com/renderrichtext/renderer/MentionRenderer.kt +85 -0
- package/android/src/main/java/com/renderrichtext/renderer/NodeRenderer.kt +207 -0
- package/android/src/main/java/com/renderrichtext/renderer/ParagraphRenderer.kt +91 -0
- package/android/src/main/java/com/renderrichtext/renderer/Renderer.kt +148 -0
- package/android/src/main/java/com/renderrichtext/renderer/SoftBreakRenderer.kt +17 -0
- package/android/src/main/java/com/renderrichtext/renderer/SpanStyleCache.kt +143 -0
- package/android/src/main/java/com/renderrichtext/renderer/StrikethroughRenderer.kt +28 -0
- package/android/src/main/java/com/renderrichtext/renderer/StrongRenderer.kt +28 -0
- package/android/src/main/java/com/renderrichtext/renderer/TextRenderer.kt +31 -0
- package/android/src/main/java/com/renderrichtext/renderer/ThematicBreakRenderer.kt +46 -0
- package/android/src/main/java/com/renderrichtext/renderer/UnderlineRenderer.kt +28 -0
- package/android/src/main/java/com/renderrichtext/spans/BaseListSpan.kt +164 -0
- package/android/src/main/java/com/renderrichtext/spans/BaselineShiftSpan.kt +27 -0
- package/android/src/main/java/com/renderrichtext/spans/BlockquoteSpan.kt +302 -0
- package/android/src/main/java/com/renderrichtext/spans/CodeBackgroundSpan.kt +205 -0
- package/android/src/main/java/com/renderrichtext/spans/CodeBlockSpan.kt +216 -0
- package/android/src/main/java/com/renderrichtext/spans/CodeSpan.kt +32 -0
- package/android/src/main/java/com/renderrichtext/spans/EmphasisSpan.kt +42 -0
- package/android/src/main/java/com/renderrichtext/spans/FactoidBackgroundSpan.kt +265 -0
- package/android/src/main/java/com/renderrichtext/spans/FactoidPaddingSpan.kt +258 -0
- package/android/src/main/java/com/renderrichtext/spans/FactoidSpan.kt +32 -0
- package/android/src/main/java/com/renderrichtext/spans/FadeInSpan.kt +29 -0
- package/android/src/main/java/com/renderrichtext/spans/HeadingSpan.kt +38 -0
- package/android/src/main/java/com/renderrichtext/spans/HighlightSpan.kt +80 -0
- package/android/src/main/java/com/renderrichtext/spans/ImageSpan.kt +481 -0
- package/android/src/main/java/com/renderrichtext/spans/InlineBackgroundGeometry.kt +42 -0
- package/android/src/main/java/com/renderrichtext/spans/LineHeightSpan.kt +39 -0
- package/android/src/main/java/com/renderrichtext/spans/LinkPillIconCache.kt +154 -0
- package/android/src/main/java/com/renderrichtext/spans/LinkPillSpan.kt +381 -0
- package/android/src/main/java/com/renderrichtext/spans/LinkSpan.kt +68 -0
- package/android/src/main/java/com/renderrichtext/spans/ListItemSpacingSpan.kt +33 -0
- package/android/src/main/java/com/renderrichtext/spans/ListMarkerAnchorSpan.kt +38 -0
- package/android/src/main/java/com/renderrichtext/spans/MarginBottomSpan.kt +76 -0
- package/android/src/main/java/com/renderrichtext/spans/MentionChipSpan.kt +132 -0
- package/android/src/main/java/com/renderrichtext/spans/MentionSpan.kt +46 -0
- package/android/src/main/java/com/renderrichtext/spans/OrderedListSpan.kt +127 -0
- package/android/src/main/java/com/renderrichtext/spans/SpoilerSpan.kt +33 -0
- package/android/src/main/java/com/renderrichtext/spans/StrikethroughSpan.kt +12 -0
- package/android/src/main/java/com/renderrichtext/spans/StrongSpan.kt +39 -0
- package/android/src/main/java/com/renderrichtext/spans/TaskListSpan.kt +143 -0
- package/android/src/main/java/com/renderrichtext/spans/TextSpan.kt +26 -0
- package/android/src/main/java/com/renderrichtext/spans/ThematicBreakSpan.kt +69 -0
- package/android/src/main/java/com/renderrichtext/spans/UnorderedListSpan.kt +96 -0
- package/android/src/main/java/com/renderrichtext/spoiler/SpoilerStubs.kt +46 -0
- package/android/src/main/java/com/renderrichtext/styles/BaseBlockStyle.kt +11 -0
- package/android/src/main/java/com/renderrichtext/styles/BlockquoteStyle.kt +83 -0
- package/android/src/main/java/com/renderrichtext/styles/CodeBlockStyle.kt +80 -0
- package/android/src/main/java/com/renderrichtext/styles/CodeStyle.kt +26 -0
- package/android/src/main/java/com/renderrichtext/styles/EmphasisStyle.kt +21 -0
- package/android/src/main/java/com/renderrichtext/styles/FactoidStyle.kt +21 -0
- package/android/src/main/java/com/renderrichtext/styles/HeadingStyle.kt +33 -0
- package/android/src/main/java/com/renderrichtext/styles/HighlightStyle.kt +19 -0
- package/android/src/main/java/com/renderrichtext/styles/ImageStyle.kt +29 -0
- package/android/src/main/java/com/renderrichtext/styles/InlineImageStyle.kt +17 -0
- package/android/src/main/java/com/renderrichtext/styles/InlineMathStyle.kt +17 -0
- package/android/src/main/java/com/renderrichtext/styles/LinkPillContent.kt +36 -0
- package/android/src/main/java/com/renderrichtext/styles/LinkPillStyle.kt +44 -0
- package/android/src/main/java/com/renderrichtext/styles/LinkStyle.kt +23 -0
- package/android/src/main/java/com/renderrichtext/styles/LinkVariantEntry.kt +34 -0
- package/android/src/main/java/com/renderrichtext/styles/ListStyle.kt +65 -0
- package/android/src/main/java/com/renderrichtext/styles/MathStyle.kt +29 -0
- package/android/src/main/java/com/renderrichtext/styles/MentionStyle.kt +19 -0
- package/android/src/main/java/com/renderrichtext/styles/ParagraphStyle.kt +33 -0
- package/android/src/main/java/com/renderrichtext/styles/SpoilerStyle.kt +27 -0
- package/android/src/main/java/com/renderrichtext/styles/StrikethroughStyle.kt +17 -0
- package/android/src/main/java/com/renderrichtext/styles/StrongStyle.kt +21 -0
- package/android/src/main/java/com/renderrichtext/styles/StyleConfig.kt +411 -0
- package/android/src/main/java/com/renderrichtext/styles/StyleParser.kt +92 -0
- package/android/src/main/java/com/renderrichtext/styles/SubscriptStyle.kt +16 -0
- package/android/src/main/java/com/renderrichtext/styles/SuperscriptStyle.kt +16 -0
- package/android/src/main/java/com/renderrichtext/styles/TableStyle.kt +75 -0
- package/android/src/main/java/com/renderrichtext/styles/TaskListStyle.kt +29 -0
- package/android/src/main/java/com/renderrichtext/styles/TextAlignment.kt +32 -0
- package/android/src/main/java/com/renderrichtext/styles/ThematicBreakStyle.kt +23 -0
- package/android/src/main/java/com/renderrichtext/styles/UnderlineStyle.kt +17 -0
- package/android/src/main/java/com/renderrichtext/styles/VideoStyle.kt +31 -0
- package/android/src/main/java/com/renderrichtext/utils/common/BorderStyleUtils.kt +86 -0
- package/android/src/main/java/com/renderrichtext/utils/common/BreakStrategyUtils.kt +32 -0
- package/android/src/main/java/com/renderrichtext/utils/common/CodeBlockHighlighter.kt +36 -0
- package/android/src/main/java/com/renderrichtext/utils/common/CodeBlockNode.kt +42 -0
- package/android/src/main/java/com/renderrichtext/utils/common/EllipsizeUtils.kt +27 -0
- package/android/src/main/java/com/renderrichtext/utils/common/EnrichedTiptapAncestorUtils.kt +10 -0
- package/android/src/main/java/com/renderrichtext/utils/common/FeatureFlags.kt +9 -0
- package/android/src/main/java/com/renderrichtext/utils/common/LinkRecognitionProps.kt +31 -0
- package/android/src/main/java/com/renderrichtext/utils/common/LinkRegexConfig.kt +56 -0
- package/android/src/main/java/com/renderrichtext/utils/common/MotionPreferences.kt +18 -0
- package/android/src/main/java/com/renderrichtext/utils/common/ReadableMapExtensions.kt +28 -0
- package/android/src/main/java/com/renderrichtext/utils/common/TiptapViewManagerUtils.kt +242 -0
- package/android/src/main/java/com/renderrichtext/utils/common/layout/RTLUtils.kt +6 -0
- package/android/src/main/java/com/renderrichtext/utils/common/serialization/TiptapASTSerializer.kt +368 -0
- package/android/src/main/java/com/renderrichtext/utils/text/ImageCache.kt +88 -0
- package/android/src/main/java/com/renderrichtext/utils/text/ImageDownloader.kt +203 -0
- package/android/src/main/java/com/renderrichtext/utils/text/LocalImageLoader.kt +167 -0
- package/android/src/main/java/com/renderrichtext/utils/text/TailFadeInAnimator.kt +84 -0
- package/android/src/main/java/com/renderrichtext/utils/text/conversion/HTMLGenerator.kt +1105 -0
- package/android/src/main/java/com/renderrichtext/utils/text/conversion/TiptapExtractor.kt +423 -0
- package/android/src/main/java/com/renderrichtext/utils/text/extensions/ParagraphUtils.kt +9 -0
- package/android/src/main/java/com/renderrichtext/utils/text/extensions/SpannableExtensions.kt +9 -0
- package/android/src/main/java/com/renderrichtext/utils/text/extensions/TextPaintExtensions.kt +76 -0
- package/android/src/main/java/com/renderrichtext/utils/text/interaction/CheckboxTouchHelper.kt +61 -0
- package/android/src/main/java/com/renderrichtext/utils/text/interaction/TaskListTapUtils.kt +286 -0
- package/android/src/main/java/com/renderrichtext/utils/text/span/ApplyLineHeight.kt +39 -0
- package/android/src/main/java/com/renderrichtext/utils/text/span/BlockSpacing.kt +142 -0
- package/android/src/main/java/com/renderrichtext/utils/text/span/SpanFlags.kt +43 -0
- package/android/src/main/java/com/renderrichtext/utils/text/span/WidthAwareSpans.kt +30 -0
- package/android/src/main/java/com/renderrichtext/utils/text/view/CodeBlockPressHost.kt +15 -0
- package/android/src/main/java/com/renderrichtext/utils/text/view/ImagePressHost.kt +19 -0
- package/android/src/main/java/com/renderrichtext/utils/text/view/LinkEvents.kt +88 -0
- package/android/src/main/java/com/renderrichtext/utils/text/view/LinkLongPressMovementMethod.kt +449 -0
- package/android/src/main/java/com/renderrichtext/utils/text/view/SelectionActionMode.kt +235 -0
- package/android/src/main/java/com/renderrichtext/utils/text/view/TextSelectionColors.kt +48 -0
- package/android/src/main/java/com/renderrichtext/utils/text/view/TextViewSetup.kt +119 -0
- package/android/src/main/java/com/renderrichtext/views/ContextMenuPopup.kt +217 -0
- package/android/src/main/java/com/renderrichtext/views/CopyGlyph.kt +101 -0
- package/android/src/main/java/com/renderrichtext/views/WrapGlyph.kt +40 -0
- package/android/src/main/jni/CMakeLists.txt +52 -0
- package/android/src/main/jni/react/renderer/components/RichTextSpec/ComponentDescriptors.h +30 -0
- package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextComponentDescriptor.h +29 -0
- package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextMeasurementManager.cpp +45 -0
- package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextMeasurementManager.h +21 -0
- package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextShadowNode.cpp +38 -0
- package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextShadowNode.h +53 -0
- package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextState.cpp +9 -0
- package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextState.h +24 -0
- package/android/src/main/jni/react/renderer/components/RichTextSpec/conversions.h +40 -0
- package/cpp/parser/TiptapASTNode.hpp +68 -0
- package/cpp/parser/TiptapParser.cpp +233 -0
- package/cpp/parser/TiptapParser.hpp +13 -0
- package/cpp/vendor/nlohmann/json.hpp +24765 -0
- package/ios/EnrichedTiptapText.h +27 -0
- package/ios/EnrichedTiptapText.mm +1222 -0
- package/ios/attachments/ENRMImageAttachment.h +51 -0
- package/ios/attachments/ENRMImageAttachment.m +398 -0
- package/ios/attachments/ENRMLinkPillAttachment.h +47 -0
- package/ios/attachments/ENRMLinkPillAttachment.m +324 -0
- package/ios/attachments/ENRMLinkPillIconCache.h +28 -0
- package/ios/attachments/ENRMLinkPillIconCache.m +181 -0
- package/ios/attachments/ENRMLinkPillText.h +27 -0
- package/ios/attachments/ENRMLinkPillText.m +118 -0
- package/ios/attachments/ENRMMathInlineAttachment.h +7 -0
- package/ios/attachments/ENRMMathInlineAttachment.m +4 -0
- package/ios/attachments/ThematicBreakAttachment.h +15 -0
- package/ios/attachments/ThematicBreakAttachment.m +33 -0
- package/ios/internals/ENRMViewFreeMeasurement.h +208 -0
- package/ios/internals/EnrichedTiptapTextComponentDescriptor.h +19 -0
- package/ios/internals/EnrichedTiptapTextShadowNode.h +43 -0
- package/ios/internals/EnrichedTiptapTextShadowNode.mm +69 -0
- package/ios/internals/EnrichedTiptapTextState.h +24 -0
- package/ios/internals/MeasurementCache.h +308 -0
- package/ios/internals/ShadowMeasurementUtils.h +145 -0
- package/ios/parser/ENRMTextLinkAttributes.h +7 -0
- package/ios/parser/ENRMTiptapParser.h +33 -0
- package/ios/parser/ENRMTiptapParser.mm +73 -0
- package/ios/parser/TiptapASTNode.h +57 -0
- package/ios/parser/TiptapASTNode.m +52 -0
- package/ios/parser/TiptapParserBridge.mm +179 -0
- package/ios/renderer/AttributedRenderer.h +23 -0
- package/ios/renderer/AttributedRenderer.m +229 -0
- package/ios/renderer/BaseRenderer.h +33 -0
- package/ios/renderer/BaseRenderer.m +46 -0
- package/ios/renderer/BaselineShiftTextAttributes.h +10 -0
- package/ios/renderer/BaselineShiftTextAttributes.m +26 -0
- package/ios/renderer/BlankLineRenderer.h +4 -0
- package/ios/renderer/BlankLineRenderer.m +51 -0
- package/ios/renderer/BlockquoteRenderer.h +6 -0
- package/ios/renderer/BlockquoteRenderer.m +258 -0
- package/ios/renderer/CodeBlockRenderer.h +9 -0
- package/ios/renderer/CodeBlockRenderer.m +99 -0
- package/ios/renderer/CodeRenderer.h +9 -0
- package/ios/renderer/CodeRenderer.m +69 -0
- package/ios/renderer/ENRMBlockquoteTextRenderer.h +25 -0
- package/ios/renderer/ENRMBlockquoteTextRenderer.m +48 -0
- package/ios/renderer/EmphasisRenderer.h +5 -0
- package/ios/renderer/EmphasisRenderer.m +100 -0
- package/ios/renderer/FactoidRenderer.h +9 -0
- package/ios/renderer/FactoidRenderer.m +130 -0
- package/ios/renderer/HeadingRenderer.h +6 -0
- package/ios/renderer/HeadingRenderer.m +103 -0
- package/ios/renderer/HighlightRenderer.h +7 -0
- package/ios/renderer/HighlightRenderer.m +33 -0
- package/ios/renderer/LinkRenderer.h +6 -0
- package/ios/renderer/LinkRenderer.m +158 -0
- package/ios/renderer/ListItemRenderer.h +24 -0
- package/ios/renderer/ListItemRenderer.m +283 -0
- package/ios/renderer/ListRenderer.h +13 -0
- package/ios/renderer/ListRenderer.m +126 -0
- package/ios/renderer/MentionRenderer.h +9 -0
- package/ios/renderer/MentionRenderer.m +96 -0
- package/ios/renderer/NodeRenderer.h +8 -0
- package/ios/renderer/ParagraphRenderer.h +6 -0
- package/ios/renderer/ParagraphRenderer.m +85 -0
- package/ios/renderer/RenderContext.h +145 -0
- package/ios/renderer/RenderContext.m +403 -0
- package/ios/renderer/RendererFactory.h +12 -0
- package/ios/renderer/RendererFactory.m +158 -0
- package/ios/renderer/StrikethroughRenderer.h +5 -0
- package/ios/renderer/StrikethroughRenderer.m +30 -0
- package/ios/renderer/StrongRenderer.h +5 -0
- package/ios/renderer/StrongRenderer.m +88 -0
- package/ios/renderer/TextRenderer.h +6 -0
- package/ios/renderer/TextRenderer.m +18 -0
- package/ios/renderer/ThematicBreakRenderer.h +4 -0
- package/ios/renderer/ThematicBreakRenderer.m +42 -0
- package/ios/renderer/UnderlineRenderer.h +4 -0
- package/ios/renderer/UnderlineRenderer.m +41 -0
- package/ios/styles/ENRMFontSlot.h +12 -0
- package/ios/styles/ENRMFontSlot.m +24 -0
- package/ios/styles/StyleConfig.h +488 -0
- package/ios/styles/StyleConfig.mm +2820 -0
- package/ios/utils/AccessibilityInfo.h +35 -0
- package/ios/utils/AccessibilityInfo.m +24 -0
- package/ios/utils/BlockquoteBorder.h +26 -0
- package/ios/utils/BlockquoteBorder.m +294 -0
- package/ios/utils/CodeBackground.h +19 -0
- package/ios/utils/CodeBackground.m +197 -0
- package/ios/utils/CodeBlockBackground.h +17 -0
- package/ios/utils/CodeBlockBackground.m +103 -0
- package/ios/utils/ContextMenuUtils.h +76 -0
- package/ios/utils/ContextMenuUtils.mm +75 -0
- package/ios/utils/ENRMAccessibilityLabels.h +40 -0
- package/ios/utils/ENRMAccessibilityLabels.m +5 -0
- package/ios/utils/ENRMAsyncRenderCoordinator.h +24 -0
- package/ios/utils/ENRMAsyncRenderCoordinator.m +37 -0
- package/ios/utils/ENRMAtomicSize.h +65 -0
- package/ios/utils/ENRMCodeBlockContent.h +37 -0
- package/ios/utils/ENRMCodeBlockContent.mm +89 -0
- package/ios/utils/ENRMFeatureFlags.h +25 -0
- package/ios/utils/ENRMImageDownloader.h +30 -0
- package/ios/utils/ENRMImageDownloader.m +168 -0
- package/ios/utils/ENRMLatexErrorCoordinator.h +27 -0
- package/ios/utils/ENRMLatexErrorCoordinator.mm +75 -0
- package/ios/utils/ENRMLatexErrorReporting.h +13 -0
- package/ios/utils/ENRMLinkContextMenus.h +93 -0
- package/ios/utils/ENRMLinkContextMenus.m +178 -0
- package/ios/utils/ENRMLinkRegexConfig.h +30 -0
- package/ios/utils/ENRMLinkRegexConfig.mm +104 -0
- package/ios/utils/ENRMLinkRegexProps.h +23 -0
- package/ios/utils/ENRMLocalImageLoader.h +35 -0
- package/ios/utils/ENRMLocalImageLoader.m +111 -0
- package/ios/utils/ENRMMenuAction.h +27 -0
- package/ios/utils/ENRMMenuAction.m +33 -0
- package/ios/utils/ENRMSpoilerOverlayManager.h +15 -0
- package/ios/utils/ENRMSpoilerOverlayManager.m +19 -0
- package/ios/utils/ENRMSpoilerTapUtils.h +6 -0
- package/ios/utils/ENRMSpoilerTapUtils.m +11 -0
- package/ios/utils/ENRMTailFadeInAnimator.h +16 -0
- package/ios/utils/ENRMTailFadeInAnimator.m +161 -0
- package/ios/utils/ENRMTextHitTest.h +23 -0
- package/ios/utils/ENRMTextHitTest.m +20 -0
- package/ios/utils/ENRMTextInteractionUtils.h +20 -0
- package/ios/utils/ENRMTextInteractionUtils.m +15 -0
- package/ios/utils/ENRMTextRenderer.h +38 -0
- package/ios/utils/ENRMTextRenderer.m +54 -0
- package/ios/utils/ENRMTextViewSetup.h +132 -0
- package/ios/utils/ENRMUIKit.h +429 -0
- package/ios/utils/EditMenuUtils.h +105 -0
- package/ios/utils/EditMenuUtils.m +143 -0
- package/ios/utils/FactoidBackground.h +20 -0
- package/ios/utils/FactoidBackground.m +161 -0
- package/ios/utils/FontScaleObserver.h +10 -0
- package/ios/utils/FontScaleObserver.m +55 -0
- package/ios/utils/FontUtils.h +31 -0
- package/ios/utils/FontUtils.m +63 -0
- package/ios/utils/HTMLGenerator.h +25 -0
- package/ios/utils/HTMLGenerator.m +1041 -0
- package/ios/utils/HeightUpdateUtils.h +25 -0
- package/ios/utils/ImageRequestHeaderUtils.h +35 -0
- package/ios/utils/LastElementUtils.h +97 -0
- package/ios/utils/LinkContextMenuUtils.h +55 -0
- package/ios/utils/LinkPillContentUtils.h +46 -0
- package/ios/utils/LinkTapUtils.h +56 -0
- package/ios/utils/LinkTapUtils.m +139 -0
- package/ios/utils/ListMarkerDrawer.h +15 -0
- package/ios/utils/ListMarkerDrawer.m +239 -0
- package/ios/utils/MentionBackground.h +26 -0
- package/ios/utils/MentionBackground.m +86 -0
- package/ios/utils/ParagraphStyleUtils.h +87 -0
- package/ios/utils/ParagraphStyleUtils.m +484 -0
- package/ios/utils/PasteboardUtils.h +48 -0
- package/ios/utils/PasteboardUtils.m +166 -0
- package/ios/utils/RTFExportUtils.h +24 -0
- package/ios/utils/RTFExportUtils.m +299 -0
- package/ios/utils/RuntimeKeys.h +44 -0
- package/ios/utils/RuntimeKeys.m +13 -0
- package/ios/utils/SelectionColorUtils.h +14 -0
- package/ios/utils/StylePropsUtils.h +1340 -0
- package/ios/utils/TaskListTapUtils.h +6 -0
- package/ios/utils/TaskListTapUtils.m +14 -0
- package/ios/utils/TextViewLayoutManager.h +14 -0
- package/ios/utils/TextViewLayoutManager.mm +198 -0
- package/ios/utils/TiptapAccessibilityElementBuilder.h +43 -0
- package/ios/utils/TiptapAccessibilityElementBuilder.m +432 -0
- package/ios/utils/TiptapExtractor.h +17 -0
- package/ios/utils/TiptapExtractor.m +367 -0
- package/ios/views/ENRMTiptapTextView.h +25 -0
- package/ios/views/ENRMTiptapTextView.m +247 -0
- package/package.json +70 -6
- package/react-native.config.js +10 -0
- package/src/EnrichedTiptapTextNativeComponent.ts +739 -0
- package/src/RichText.tsx +164 -0
- package/src/admonitionDefaults.ts +58 -0
- package/src/darkModeTextStyle.ts +99 -0
- package/src/headingDefaults.ts +21 -0
- package/src/index.tsx +4 -0
- package/src/linkVariantUtils.ts +120 -0
- package/src/normalizeTiptapStyle.ts +397 -0
- package/src/rn-globals.d.ts +1 -0
- package/src/styleUtils.ts +107 -0
- package/src/types/TiptapStyle.ts +532 -0
- package/src/types/TiptapStyleInternal.ts +299 -0
- package/src/types/linkPill.ts +9 -0
- package/src/utils/isDev.ts +4 -0
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
#import "BlockquoteRenderer.h"
|
|
2
|
+
#import "BlockquoteBorder.h"
|
|
3
|
+
#import "FontUtils.h"
|
|
4
|
+
#import "LastElementUtils.h"
|
|
5
|
+
#import "ListItemRenderer.h"
|
|
6
|
+
#import "TiptapASTNode.h"
|
|
7
|
+
#import "ParagraphStyleUtils.h"
|
|
8
|
+
#import "RenderContext.h"
|
|
9
|
+
#import "RendererFactory.h"
|
|
10
|
+
#import "StyleConfig.h"
|
|
11
|
+
|
|
12
|
+
static NSString *const kNestedInfoDepthKey = @"depth";
|
|
13
|
+
static NSString *const kNestedInfoRangeKey = @"range";
|
|
14
|
+
|
|
15
|
+
@implementation BlockquoteRenderer
|
|
16
|
+
|
|
17
|
+
- (id)takeContextSnapshot:(RenderContext *)context
|
|
18
|
+
{
|
|
19
|
+
return [context snapshotScope];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
- (void)renderNodeContent:(TiptapASTNode *)node
|
|
23
|
+
into:(NSMutableAttributedString *)output
|
|
24
|
+
context:(RenderContext *)context
|
|
25
|
+
{
|
|
26
|
+
if (output.length > 0 && ![output.string hasSuffix:@"\n"]) {
|
|
27
|
+
[output appendAttributedString:kNewlineAttributedString];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
NSInteger currentDepth = context.blockquoteDepth;
|
|
31
|
+
context.blockquoteDepth = currentDepth + 1;
|
|
32
|
+
|
|
33
|
+
[context setBlockStyle:BlockTypeBlockquote
|
|
34
|
+
font:[_config blockquoteFont]
|
|
35
|
+
color:[_config blockquoteColor]
|
|
36
|
+
headingLevel:0];
|
|
37
|
+
|
|
38
|
+
NSUInteger start = output.length;
|
|
39
|
+
[_rendererFactory renderChildrenOfNode:node into:output context:context];
|
|
40
|
+
|
|
41
|
+
NSUInteger end = output.length;
|
|
42
|
+
if (end <= start) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
[self applyStylingAndSpacing:output start:start end:end currentDepth:currentDepth context:context];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
#pragma mark - Styling and Spacing
|
|
50
|
+
|
|
51
|
+
- (void)applyStylingAndSpacing:(NSMutableAttributedString *)output
|
|
52
|
+
start:(NSUInteger)start
|
|
53
|
+
end:(NSUInteger)end
|
|
54
|
+
currentDepth:(NSInteger)currentDepth
|
|
55
|
+
context:(RenderContext *)context
|
|
56
|
+
{
|
|
57
|
+
NSUInteger contentStart = start;
|
|
58
|
+
if (currentDepth == 0) {
|
|
59
|
+
contentStart += applyBlockSpacingBefore(output, start, [_config blockquoteMarginTop]);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// nested quotes pad their own box (matching web CSS padding)
|
|
63
|
+
CGFloat padding = [_config blockquotePadding];
|
|
64
|
+
NSUInteger topPadLength = 0;
|
|
65
|
+
NSUInteger bottomPadLength = 0;
|
|
66
|
+
if (padding > 0) {
|
|
67
|
+
NSMutableParagraphStyle *topSpacerStyle = [context spacerStyleWithHeight:padding spacing:0];
|
|
68
|
+
NSAttributedString *topSpacer = [[NSAttributedString alloc]
|
|
69
|
+
initWithString:@"\n"
|
|
70
|
+
attributes:@{NSParagraphStyleAttributeName : topSpacerStyle, BlockquoteSpacerAttributeName : @YES}];
|
|
71
|
+
[output insertAttributedString:topSpacer atIndex:contentStart];
|
|
72
|
+
topPadLength = 1;
|
|
73
|
+
|
|
74
|
+
NSUInteger bottomSpacerLocation = output.length;
|
|
75
|
+
[output appendAttributedString:kNewlineAttributedString];
|
|
76
|
+
NSMutableParagraphStyle *bottomSpacerStyle = [context spacerStyleWithHeight:padding spacing:0];
|
|
77
|
+
[output addAttributes:@{NSParagraphStyleAttributeName : bottomSpacerStyle, BlockquoteSpacerAttributeName : @YES}
|
|
78
|
+
range:NSMakeRange(bottomSpacerLocation, 1)];
|
|
79
|
+
bottomPadLength = 1;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
NSRange blockquoteRange = NSMakeRange(contentStart, (end - start) + topPadLength + bottomPadLength);
|
|
83
|
+
NSRange innerRange = NSMakeRange(contentStart + topPadLength, end - start);
|
|
84
|
+
CGFloat levelSpacing = [_config blockquoteBorderWidth] + [_config blockquoteGapWidth];
|
|
85
|
+
NSArray<NSDictionary *> *nestedInfo = [self collectNestedBlockquotes:output range:innerRange depth:currentDepth];
|
|
86
|
+
|
|
87
|
+
// Apply base styling (indentation, depth, background, line height)
|
|
88
|
+
[self applyBaseBlockquoteStyle:output
|
|
89
|
+
boxRange:blockquoteRange
|
|
90
|
+
innerRange:innerRange
|
|
91
|
+
depth:currentDepth
|
|
92
|
+
levelSpacing:levelSpacing
|
|
93
|
+
backgroundColor:[_config blockquoteBackgroundColor]
|
|
94
|
+
lineHeight:[_config blockquoteLineHeight]];
|
|
95
|
+
|
|
96
|
+
// Re-apply nested blockquote styles to restore their correct indentation
|
|
97
|
+
// (applyBaseBlockquoteStyle overwrites nested indents with the parent's indent)
|
|
98
|
+
[self reapplyNestedStyles:output nestedInfo:nestedInfo levelSpacing:levelSpacing];
|
|
99
|
+
|
|
100
|
+
if (currentDepth == 0) {
|
|
101
|
+
applyBlockSpacingAfter(output, [_config blockquoteMarginBottom]);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
#pragma mark - Nested Blockquote Handling
|
|
106
|
+
|
|
107
|
+
- (NSArray<NSDictionary *> *)collectNestedBlockquotes:(NSMutableAttributedString *)output
|
|
108
|
+
range:(NSRange)blockquoteRange
|
|
109
|
+
depth:(NSInteger)currentDepth
|
|
110
|
+
{
|
|
111
|
+
NSMutableArray<NSDictionary *> *nestedInfo = [NSMutableArray array];
|
|
112
|
+
|
|
113
|
+
[output
|
|
114
|
+
enumerateAttribute:BlockquoteDepthAttributeName
|
|
115
|
+
inRange:blockquoteRange
|
|
116
|
+
options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired
|
|
117
|
+
usingBlock:^(id value, NSRange range, BOOL *stop) {
|
|
118
|
+
NSInteger depth = [value integerValue];
|
|
119
|
+
if (value && depth > currentDepth) {
|
|
120
|
+
[nestedInfo
|
|
121
|
+
addObject:@{kNestedInfoDepthKey : value, kNestedInfoRangeKey : [NSValue valueWithRange:range]}];
|
|
122
|
+
}
|
|
123
|
+
}];
|
|
124
|
+
|
|
125
|
+
return nestedInfo;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
- (void)applyBaseBlockquoteStyle:(NSMutableAttributedString *)output
|
|
129
|
+
boxRange:(NSRange)boxRange
|
|
130
|
+
innerRange:(NSRange)innerRange
|
|
131
|
+
depth:(NSInteger)currentDepth
|
|
132
|
+
levelSpacing:(CGFloat)levelSpacing
|
|
133
|
+
backgroundColor:(RCTUIColor *)backgroundColor
|
|
134
|
+
lineHeight:(CGFloat)lineHeight
|
|
135
|
+
{
|
|
136
|
+
CGFloat totalIndent = blockquoteIndentForDepth(currentDepth + 1, levelSpacing);
|
|
137
|
+
CGFloat padding = [_config blockquotePadding];
|
|
138
|
+
|
|
139
|
+
// Depth and background cover the whole box (incl. padding spacers) so the
|
|
140
|
+
// border and background render behind list content and the padding rows.
|
|
141
|
+
NSMutableDictionary *depthAttributes =
|
|
142
|
+
[NSMutableDictionary dictionaryWithObjectsAndKeys:@(currentDepth), BlockquoteDepthAttributeName, nil];
|
|
143
|
+
if (backgroundColor) {
|
|
144
|
+
depthAttributes[BlockquoteBackgroundColorAttributeName] = backgroundColor;
|
|
145
|
+
}
|
|
146
|
+
[output addAttributes:depthAttributes range:boxRange];
|
|
147
|
+
|
|
148
|
+
// List items bake the blockquote indent into their own paragraph style; only non-list content is stamped here.
|
|
149
|
+
[self enumerateNonListRangesIn:output
|
|
150
|
+
range:innerRange
|
|
151
|
+
usingBlock:^(NSRange nonListRange) {
|
|
152
|
+
NSMutableParagraphStyle *paragraphStyle =
|
|
153
|
+
getOrCreateParagraphStyle(output, nonListRange.location);
|
|
154
|
+
paragraphStyle.firstLineHeadIndent = totalIndent;
|
|
155
|
+
paragraphStyle.headIndent = totalIndent;
|
|
156
|
+
if (padding > 0) {
|
|
157
|
+
paragraphStyle.tailIndent = -padding;
|
|
158
|
+
}
|
|
159
|
+
[output addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:nonListRange];
|
|
160
|
+
applyLineHeight(output, nonListRange, lineHeight);
|
|
161
|
+
applyBaselineOffset(output, nonListRange);
|
|
162
|
+
}];
|
|
163
|
+
|
|
164
|
+
if (padding > 0) {
|
|
165
|
+
[self applyTailIndent:-padding toListRangesIn:output range:innerRange];
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
- (void)applyTailIndent:(CGFloat)tailIndent toListRangesIn:(NSMutableAttributedString *)output range:(NSRange)range
|
|
170
|
+
{
|
|
171
|
+
[output enumerateAttribute:ListDepthAttribute
|
|
172
|
+
inRange:range
|
|
173
|
+
options:0
|
|
174
|
+
usingBlock:^(id value, NSRange listRange, BOOL *stop) {
|
|
175
|
+
if (!value) {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
[output enumerateAttribute:NSParagraphStyleAttributeName
|
|
179
|
+
inRange:listRange
|
|
180
|
+
options:0
|
|
181
|
+
usingBlock:^(NSParagraphStyle *style, NSRange styleRange, BOOL *innerStop) {
|
|
182
|
+
NSMutableParagraphStyle *mutableStyle =
|
|
183
|
+
style ? [style mutableCopy] : [[NSMutableParagraphStyle alloc] init];
|
|
184
|
+
mutableStyle.tailIndent = tailIndent;
|
|
185
|
+
[output addAttribute:NSParagraphStyleAttributeName
|
|
186
|
+
value:mutableStyle
|
|
187
|
+
range:styleRange];
|
|
188
|
+
}];
|
|
189
|
+
}];
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
- (void)reapplyNestedStyles:(NSMutableAttributedString *)output
|
|
193
|
+
nestedInfo:(NSArray<NSDictionary *> *)nestedInfo
|
|
194
|
+
levelSpacing:(CGFloat)levelSpacing
|
|
195
|
+
{
|
|
196
|
+
// Re-apply indentation to nested blockquotes since applyBaseBlockquoteStyle
|
|
197
|
+
// overwrote them with the parent's indentation
|
|
198
|
+
CGFloat padding = [_config blockquotePadding];
|
|
199
|
+
for (NSDictionary *info in nestedInfo) {
|
|
200
|
+
NSRange nestedRange = [info[kNestedInfoRangeKey] rangeValue];
|
|
201
|
+
NSInteger nestedDepth = [info[kNestedInfoDepthKey] integerValue];
|
|
202
|
+
CGFloat indent = blockquoteIndentForDepth(nestedDepth + 1, levelSpacing);
|
|
203
|
+
|
|
204
|
+
[output addAttribute:BlockquoteDepthAttributeName value:info[kNestedInfoDepthKey] range:nestedRange];
|
|
205
|
+
|
|
206
|
+
[self enumerateNonListRangesIn:output
|
|
207
|
+
range:nestedRange
|
|
208
|
+
usingBlock:^(NSRange nonListRange) {
|
|
209
|
+
NSMutableParagraphStyle *style = getOrCreateParagraphStyle(output, nonListRange.location);
|
|
210
|
+
style.firstLineHeadIndent = indent;
|
|
211
|
+
style.headIndent = indent;
|
|
212
|
+
style.tailIndent = padding > 0 ? -padding : 0;
|
|
213
|
+
[output addAttribute:NSParagraphStyleAttributeName value:style range:nonListRange];
|
|
214
|
+
}];
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
- (void)enumerateNonListRangesIn:(NSMutableAttributedString *)output
|
|
219
|
+
range:(NSRange)range
|
|
220
|
+
usingBlock:(void (^)(NSRange nonListRange))block
|
|
221
|
+
{
|
|
222
|
+
// List items — and code blocks nested inside them (which carry a list-derived
|
|
223
|
+
// indent instead of ListDepthAttribute) — already bake the correct indent in.
|
|
224
|
+
NSMutableArray<NSValue *> *listRanges = [NSMutableArray array];
|
|
225
|
+
void (^collectRanges)(NSString *) = ^(NSString *attribute) {
|
|
226
|
+
[output enumerateAttribute:attribute
|
|
227
|
+
inRange:range
|
|
228
|
+
options:0
|
|
229
|
+
usingBlock:^(id value, NSRange subRange, BOOL *stop) {
|
|
230
|
+
if (value) {
|
|
231
|
+
[listRanges addObject:[NSValue valueWithRange:subRange]];
|
|
232
|
+
}
|
|
233
|
+
}];
|
|
234
|
+
};
|
|
235
|
+
collectRanges(ListDepthAttribute);
|
|
236
|
+
collectRanges(CodeBlockIndentAttributeName);
|
|
237
|
+
collectRanges(BlockquoteSpacerAttributeName);
|
|
238
|
+
[listRanges sortUsingComparator:^NSComparisonResult(NSValue *a, NSValue *b) {
|
|
239
|
+
NSUInteger la = [a rangeValue].location;
|
|
240
|
+
NSUInteger lb = [b rangeValue].location;
|
|
241
|
+
return la < lb ? NSOrderedAscending : (la > lb ? NSOrderedDescending : NSOrderedSame);
|
|
242
|
+
}];
|
|
243
|
+
|
|
244
|
+
NSUInteger pos = range.location;
|
|
245
|
+
const NSUInteger end = NSMaxRange(range);
|
|
246
|
+
for (NSValue *val in listRanges) {
|
|
247
|
+
NSRange listRange = [val rangeValue];
|
|
248
|
+
if (pos < listRange.location) {
|
|
249
|
+
block(NSMakeRange(pos, listRange.location - pos));
|
|
250
|
+
}
|
|
251
|
+
pos = MAX(pos, NSMaxRange(listRange));
|
|
252
|
+
}
|
|
253
|
+
if (pos < end) {
|
|
254
|
+
block(NSMakeRange(pos, end - pos));
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
@end
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
#import "CodeBlockRenderer.h"
|
|
2
|
+
#import "CodeBlockBackground.h"
|
|
3
|
+
#import "ENRMCodeBlockContent.h"
|
|
4
|
+
#import "LastElementUtils.h"
|
|
5
|
+
#import "TiptapASTNode.h"
|
|
6
|
+
#import "ParagraphStyleUtils.h"
|
|
7
|
+
#import "RenderContext.h"
|
|
8
|
+
#import "RendererFactory.h"
|
|
9
|
+
#import "StyleConfig.h"
|
|
10
|
+
|
|
11
|
+
@implementation CodeBlockRenderer
|
|
12
|
+
|
|
13
|
+
- (id)takeContextSnapshot:(RenderContext *)context
|
|
14
|
+
{
|
|
15
|
+
return [context snapshotScope];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
- (void)renderNodeContent:(TiptapASTNode *)node
|
|
19
|
+
into:(NSMutableAttributedString *)output
|
|
20
|
+
context:(RenderContext *)context
|
|
21
|
+
{
|
|
22
|
+
// In tight lists md4c emits raw Text siblings without paragraph wrappers,
|
|
23
|
+
// so the preceding content may not terminate with a newline.
|
|
24
|
+
if (output.length > 0 && ![output.string hasSuffix:@"\n"]) {
|
|
25
|
+
[output appendAttributedString:kNewlineAttributedString];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
[context setBlockStyle:BlockTypeCodeBlock font:[_config codeBlockFont] color:[_config codeBlockColor] headingLevel:0];
|
|
29
|
+
|
|
30
|
+
CGFloat listIndent = context.accumulatedIndent;
|
|
31
|
+
CGFloat padding = [_config codeBlockPadding];
|
|
32
|
+
CGFloat marginTop = [_config codeBlockMarginTop];
|
|
33
|
+
CGFloat marginBottom = [_config codeBlockMarginBottom];
|
|
34
|
+
|
|
35
|
+
NSUInteger blockStart = output.length;
|
|
36
|
+
blockStart += applyBlockSpacingBefore(output, blockStart, marginTop);
|
|
37
|
+
|
|
38
|
+
// Top Padding: Inserted as a spacer character inside the background area
|
|
39
|
+
// apply only when positive
|
|
40
|
+
if (padding > 0) {
|
|
41
|
+
[output appendAttributedString:kNewlineAttributedString];
|
|
42
|
+
NSMutableParagraphStyle *topSpacerStyle = [context spacerStyleWithHeight:padding spacing:0];
|
|
43
|
+
topSpacerStyle.baseWritingDirection = NSWritingDirectionLeftToRight;
|
|
44
|
+
[output addAttribute:NSParagraphStyleAttributeName value:topSpacerStyle range:NSMakeRange(blockStart, 1)];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
NSUInteger contentStart = output.length;
|
|
48
|
+
[_rendererFactory renderChildrenOfNode:node into:output context:context];
|
|
49
|
+
|
|
50
|
+
NSUInteger contentEnd = output.length;
|
|
51
|
+
if (contentEnd <= contentStart)
|
|
52
|
+
return;
|
|
53
|
+
|
|
54
|
+
NSRange contentRange = NSMakeRange(contentStart, contentEnd - contentStart);
|
|
55
|
+
|
|
56
|
+
ENRMApplyCodeBlockTextAttributes(output, contentRange, _config);
|
|
57
|
+
|
|
58
|
+
// Horizontal padding is paragraph indentation in this flavor; the shared
|
|
59
|
+
// helper already forced the LTR left-aligned base style.
|
|
60
|
+
NSMutableParagraphStyle *baseStyle = [getOrCreateParagraphStyle(output, contentStart) mutableCopy];
|
|
61
|
+
baseStyle.firstLineHeadIndent = padding + listIndent;
|
|
62
|
+
baseStyle.headIndent = padding + listIndent;
|
|
63
|
+
baseStyle.tailIndent = -padding;
|
|
64
|
+
[output addAttribute:NSParagraphStyleAttributeName value:baseStyle range:contentRange];
|
|
65
|
+
|
|
66
|
+
// Bottom Padding: Inserted as a spacer character inside the background area
|
|
67
|
+
// apply it only when positive
|
|
68
|
+
if (padding > 0) {
|
|
69
|
+
NSUInteger bottomPaddingStart = output.length;
|
|
70
|
+
[output appendAttributedString:kNewlineAttributedString];
|
|
71
|
+
NSMutableParagraphStyle *bottomPaddingStyle = [context spacerStyleWithHeight:padding spacing:0];
|
|
72
|
+
bottomPaddingStyle.baseWritingDirection = NSWritingDirectionLeftToRight;
|
|
73
|
+
[output addAttribute:NSParagraphStyleAttributeName
|
|
74
|
+
value:bottomPaddingStyle
|
|
75
|
+
range:NSMakeRange(bottomPaddingStart, 1)];
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Define the range for background rendering (includes padding, excludes margins)
|
|
79
|
+
NSRange backgroundRange = NSMakeRange(blockStart, output.length - blockStart);
|
|
80
|
+
[output addAttribute:CodeBlockAttributeName value:@YES range:backgroundRange];
|
|
81
|
+
if (listIndent > 0) {
|
|
82
|
+
[output addAttribute:CodeBlockIndentAttributeName value:@(listIndent) range:backgroundRange];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Recovered by a tap for onCodeBlockPress (the AST node is gone after render).
|
|
86
|
+
NSString *codeBlockText = ENRMCodeBlockExtractCode(node) ?: @"";
|
|
87
|
+
[output addAttribute:@"codeBlockText" value:codeBlockText range:backgroundRange];
|
|
88
|
+
NSString *codeBlockLanguage = ENRMCodeBlockLanguage(node);
|
|
89
|
+
if (codeBlockLanguage) {
|
|
90
|
+
[output addAttribute:@"codeBlockLanguage" value:codeBlockLanguage range:backgroundRange];
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// External Margin: Applied outside the background range
|
|
94
|
+
if (marginBottom > 0) {
|
|
95
|
+
applyBlockSpacingAfter(output, marginBottom);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
@end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#import "CodeRenderer.h"
|
|
2
|
+
#import "CodeBackground.h"
|
|
3
|
+
#import "ENRMUIKit.h"
|
|
4
|
+
#import "FontUtils.h"
|
|
5
|
+
#import "TiptapASTNode.h"
|
|
6
|
+
#import "RenderContext.h"
|
|
7
|
+
#import "RendererFactory.h"
|
|
8
|
+
#import "StyleConfig.h"
|
|
9
|
+
#import <React/RCTFont.h>
|
|
10
|
+
|
|
11
|
+
@implementation CodeRenderer
|
|
12
|
+
|
|
13
|
+
- (void)renderNodeContent:(TiptapASTNode *)node
|
|
14
|
+
into:(NSMutableAttributedString *)output
|
|
15
|
+
context:(RenderContext *)context
|
|
16
|
+
{
|
|
17
|
+
|
|
18
|
+
BlockStyle *blockStyle = [context getBlockStyle];
|
|
19
|
+
|
|
20
|
+
RCTUIColor *codeColor = _config.codeColor;
|
|
21
|
+
|
|
22
|
+
UIFont *blockFont = cachedFontFromBlockStyle(blockStyle, context);
|
|
23
|
+
|
|
24
|
+
UIFontDescriptorSymbolicTraits traits = blockFont.fontDescriptor.symbolicTraits;
|
|
25
|
+
UIFontWeight weight = (traits & UIFontDescriptorTraitBold) ? UIFontWeightBold : UIFontWeightRegular;
|
|
26
|
+
|
|
27
|
+
CGFloat codeFontSize = _config.codeFontSize > 0 ? _config.codeFontSize : blockStyle.fontSize;
|
|
28
|
+
|
|
29
|
+
// Both sizes above are unscaled; apply the same multiplier as the surrounding block font.
|
|
30
|
+
CGFloat fontScale = context.allowFontScaling ? RCTFontSizeMultiplierWithMax(context.maxFontSizeMultiplier) : 1.0;
|
|
31
|
+
|
|
32
|
+
NSString *codeFontFamily = _config.codeFontFamily;
|
|
33
|
+
UIFont *codeFont;
|
|
34
|
+
if (codeFontFamily.length > 0) {
|
|
35
|
+
NSString *weightStr = (weight == UIFontWeightBold) ? @"bold" : nil;
|
|
36
|
+
codeFont = [RCTFont updateFont:nil
|
|
37
|
+
withFamily:codeFontFamily
|
|
38
|
+
size:@(codeFontSize)
|
|
39
|
+
weight:weightStr
|
|
40
|
+
style:nil
|
|
41
|
+
variant:nil
|
|
42
|
+
scaleMultiplier:fontScale];
|
|
43
|
+
} else {
|
|
44
|
+
codeFont = [UIFont monospacedSystemFontOfSize:codeFontSize * fontScale weight:weight];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
NSUInteger start = output.length;
|
|
48
|
+
|
|
49
|
+
[_rendererFactory renderChildrenOfNode:node into:output context:context];
|
|
50
|
+
|
|
51
|
+
NSRange range = [RenderContext rangeForRenderedContent:output start:start];
|
|
52
|
+
if (range.length > 0) {
|
|
53
|
+
NSDictionary *existingAttributes = [output attributesAtIndex:start effectiveRange:NULL];
|
|
54
|
+
NSMutableDictionary *codeAttributes = [existingAttributes ?: @{} mutableCopy];
|
|
55
|
+
|
|
56
|
+
codeAttributes[NSFontAttributeName] = codeFont;
|
|
57
|
+
if (codeColor) {
|
|
58
|
+
codeAttributes[NSForegroundColorAttributeName] = codeColor;
|
|
59
|
+
}
|
|
60
|
+
codeAttributes[CodeAttributeName] = @YES;
|
|
61
|
+
|
|
62
|
+
// Store block line height directly for CodeBackground to use
|
|
63
|
+
codeAttributes[@"BlockLineHeight"] = @(UIFontLineHeight(blockFont));
|
|
64
|
+
|
|
65
|
+
[output setAttributes:codeAttributes range:range];
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
@end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
#import <Foundation/Foundation.h>
|
|
3
|
+
|
|
4
|
+
@class RenderContext;
|
|
5
|
+
@class StyleConfig;
|
|
6
|
+
|
|
7
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Renders a GFM blockquote's own prose content - the nodes left after nested quotes, code blocks and
|
|
11
|
+
* other block segments have been split out - as blockquote text.
|
|
12
|
+
*
|
|
13
|
+
* It decorates a generic AttributedRenderer pass rather than owning the render envelope itself:
|
|
14
|
+
* -pushOnContext: enters the blockquote baseline block style (+depth) so text picks up the quote's
|
|
15
|
+
* font/color and paragraphs render tight (currentBlockType == Blockquote), matching the commonmark
|
|
16
|
+
* path; -postProcess: applies the quote's line height once the string is complete. It draws no
|
|
17
|
+
* border/background/padding - the ENRMBlockquoteContainerView draws the box.
|
|
18
|
+
*/
|
|
19
|
+
@interface ENRMBlockquoteTextRenderer : NSObject
|
|
20
|
+
- (instancetype)initWithConfig:(StyleConfig *)config;
|
|
21
|
+
- (void)pushOnContext:(RenderContext *)context;
|
|
22
|
+
- (void)postProcess:(NSMutableAttributedString *)text;
|
|
23
|
+
@end
|
|
24
|
+
|
|
25
|
+
NS_ASSUME_NONNULL_END
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#import "ENRMBlockquoteTextRenderer.h"
|
|
2
|
+
#import "ParagraphStyleUtils.h"
|
|
3
|
+
#import "RenderContext.h"
|
|
4
|
+
#import "StyleConfig.h"
|
|
5
|
+
|
|
6
|
+
@implementation ENRMBlockquoteTextRenderer {
|
|
7
|
+
StyleConfig *_config;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
- (instancetype)initWithConfig:(StyleConfig *)config
|
|
11
|
+
{
|
|
12
|
+
self = [super init];
|
|
13
|
+
if (self) {
|
|
14
|
+
_config = config;
|
|
15
|
+
}
|
|
16
|
+
return self;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
- (void)pushOnContext:(RenderContext *)context
|
|
20
|
+
{
|
|
21
|
+
// Only set the blockquote baseline block style (tight paragraphs + the quote's font/color).
|
|
22
|
+
// Unlike the commonmark inline path we do NOT bump blockquoteDepth: the ENRMBlockquoteContainerView
|
|
23
|
+
// already insets its content by the quote's border/gap/padding, so bumping it here would make
|
|
24
|
+
// ListItemRenderer add a second blockquoteIndentForDepth on top and over-indent nested lists.
|
|
25
|
+
[context setBlockStyle:BlockTypeBlockquote font:_config.blockquoteFont color:_config.blockquoteColor headingLevel:0];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
- (void)postProcess:(NSMutableAttributedString *)text
|
|
29
|
+
{
|
|
30
|
+
// Stamp the quote's line height per paragraph. applyLineHeight copies the paragraph style at the
|
|
31
|
+
// range start over the whole range, so applying it across the entire run would overwrite every
|
|
32
|
+
// paragraph with the first one's style - wiping each list item's firstLineHeadIndent/headIndent
|
|
33
|
+
// (the marker draws from a separate attribute, so it would then land on top of un-indented text).
|
|
34
|
+
CGFloat lineHeight = [_config blockquoteLineHeight];
|
|
35
|
+
if (text.length == 0 || lineHeight <= 0) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
NSString *string = text.string;
|
|
39
|
+
NSUInteger location = 0;
|
|
40
|
+
while (location < text.length) {
|
|
41
|
+
NSRange paragraph = [string paragraphRangeForRange:NSMakeRange(location, 0)];
|
|
42
|
+
applyLineHeight(text, paragraph, lineHeight);
|
|
43
|
+
applyBaselineOffset(text, paragraph);
|
|
44
|
+
location = NSMaxRange(paragraph);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
@end
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
#import "EmphasisRenderer.h"
|
|
2
|
+
#import "FontUtils.h"
|
|
3
|
+
#import "TiptapASTNode.h"
|
|
4
|
+
#import "RenderContext.h"
|
|
5
|
+
#import "RendererFactory.h"
|
|
6
|
+
#import "StyleConfig.h"
|
|
7
|
+
#import <React/RCTFont.h>
|
|
8
|
+
|
|
9
|
+
@implementation EmphasisRenderer
|
|
10
|
+
|
|
11
|
+
#pragma mark - Rendering
|
|
12
|
+
|
|
13
|
+
- (void)renderNodeContent:(TiptapASTNode *)node
|
|
14
|
+
into:(NSMutableAttributedString *)output
|
|
15
|
+
context:(RenderContext *)context
|
|
16
|
+
{
|
|
17
|
+
NSUInteger start = output.length;
|
|
18
|
+
[_rendererFactory renderChildrenOfNode:node into:output context:context];
|
|
19
|
+
|
|
20
|
+
NSRange range = NSMakeRange(start, output.length - start);
|
|
21
|
+
if (range.length == 0)
|
|
22
|
+
return;
|
|
23
|
+
|
|
24
|
+
BlockStyle *blockStyle = [context getBlockStyle];
|
|
25
|
+
RCTUIColor *configEmphasisColor = [_config emphasisColor];
|
|
26
|
+
NSString *emphasisFontFamily = [_config emphasisFontFamily];
|
|
27
|
+
NSString *emphasisFontStyle = [_config emphasisFontStyle];
|
|
28
|
+
BOOL useNormalStyle = [emphasisFontStyle isEqualToString:@"normal"];
|
|
29
|
+
|
|
30
|
+
// Cache the Strong color calculation to efficiently detect nested Strong nodes
|
|
31
|
+
RCTUIColor *strongColorToPreserve = [_config strongColor] ? [RenderContext calculateStrongColor:[_config strongColor]
|
|
32
|
+
blockColor:blockStyle.color]
|
|
33
|
+
: nil;
|
|
34
|
+
|
|
35
|
+
[output enumerateAttributesInRange:range
|
|
36
|
+
options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired
|
|
37
|
+
usingBlock:^(NSDictionary<NSAttributedStringKey, id> *attrs, NSRange subrange, BOOL *stop) {
|
|
38
|
+
UIFont *currentFont =
|
|
39
|
+
attrs[NSFontAttributeName] ?: cachedFontFromBlockStyle(blockStyle, context);
|
|
40
|
+
UIFont *resolvedFont = nil;
|
|
41
|
+
|
|
42
|
+
if (emphasisFontFamily.length > 0) {
|
|
43
|
+
resolvedFont = [RCTFont updateFont:currentFont
|
|
44
|
+
withFamily:emphasisFontFamily
|
|
45
|
+
size:nil
|
|
46
|
+
weight:nil
|
|
47
|
+
style:useNormalStyle ? nil : @"italic"
|
|
48
|
+
variant:nil
|
|
49
|
+
scaleMultiplier:1.0];
|
|
50
|
+
} else if (currentFont &&
|
|
51
|
+
!(currentFont.fontDescriptor.symbolicTraits & UIFontDescriptorTraitItalic)) {
|
|
52
|
+
resolvedFont = [self ensureFontIsItalic:currentFont];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (resolvedFont && ![resolvedFont isEqual:currentFont]) {
|
|
56
|
+
[output addAttribute:NSFontAttributeName value:resolvedFont range:subrange];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// 2. Color Optimization: Handle nesting and avoid redundant updates
|
|
60
|
+
if (configEmphasisColor) {
|
|
61
|
+
RCTUIColor *currentColor = attrs[NSForegroundColorAttributeName];
|
|
62
|
+
BOOL isLink = attrs[NSLinkAttributeName] != nil;
|
|
63
|
+
|
|
64
|
+
// Verify if the current color belongs to a Strong parent
|
|
65
|
+
BOOL isStrongColor =
|
|
66
|
+
strongColorToPreserve && [currentColor isEqual:strongColorToPreserve];
|
|
67
|
+
|
|
68
|
+
// Preserving colors for higher-priority elements (links, strong nodes, etc.)
|
|
69
|
+
if (!isLink && !isStrongColor && ![RenderContext shouldPreserveColors:attrs]) {
|
|
70
|
+
// Only modify the string if the color is actually different
|
|
71
|
+
if (![currentColor isEqual:configEmphasisColor]) {
|
|
72
|
+
[output addAttribute:NSForegroundColorAttributeName
|
|
73
|
+
value:configEmphasisColor
|
|
74
|
+
range:subrange];
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}];
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
#pragma mark - Helper Methods
|
|
82
|
+
|
|
83
|
+
- (UIFont *)ensureFontIsItalic:(UIFont *)font
|
|
84
|
+
{
|
|
85
|
+
if (!font)
|
|
86
|
+
return nil;
|
|
87
|
+
|
|
88
|
+
UIFontDescriptorSymbolicTraits traits = font.fontDescriptor.symbolicTraits;
|
|
89
|
+
if (traits & UIFontDescriptorTraitItalic)
|
|
90
|
+
return font;
|
|
91
|
+
|
|
92
|
+
// Combine italic with existing traits (e.g., preserving Bold if present)
|
|
93
|
+
UIFontDescriptorSymbolicTraits combinedTraits = traits | UIFontDescriptorTraitItalic;
|
|
94
|
+
UIFontDescriptor *italicDescriptor = [font.fontDescriptor fontDescriptorWithSymbolicTraits:combinedTraits];
|
|
95
|
+
|
|
96
|
+
// Size 0 in fontWithDescriptor:size: maintains the current point size
|
|
97
|
+
return [UIFont fontWithDescriptor:italicDescriptor size:0] ?: font;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
@end
|