react-native-enriched-markdown-scaffold 0.7.4-scaffold.9 → 1.0.2-scaffold.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/README.md +54 -8
- package/ReactNativeEnrichedMarkdown.podspec +82 -73
- package/android/build.gradle +188 -1
- package/android/consumer-rules.pro +1 -1
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerDelegate.java +27 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerInterface.java +7 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextInputManagerDelegate.java +24 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextInputManagerInterface.java +8 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerDelegate.java +27 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerInterface.java +7 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.cpp +223 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.h +183 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.cpp +65 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.h +1086 -61
- package/android/src/main/baseline-prof.txt +1 -1
- package/android/src/main/cpp/jni-adapter.cpp +74 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdown.kt +351 -13
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownInternalText.kt +62 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownManager.kt +85 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownText.kt +160 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextLayoutManager.kt +10 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextManager.kt +76 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/MeasurementStore.kt +126 -10
- package/android/src/main/java/com/swmansion/enriched/markdown/events/CopyPressEvent.kt +24 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/events/CopyRequestEvent.kt +28 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/events/LinkLayoutEvent.kt +36 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/events/SelectionChangeEvent.kt +43 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/EnrichedMarkdownTextInputManager.kt +54 -4
- package/android/src/main/java/com/swmansion/enriched/markdown/input/EnrichedMarkdownTextInputView.kt +923 -462
- package/android/src/main/java/com/swmansion/enriched/markdown/input/MarkdownClipboard.kt +42 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/BlockEditCoordinator.kt +196 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/ClipboardCoordinator.kt +73 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditContext.kt +19 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditPipeline.kt +248 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditSession.kt +52 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/InputConnectionWrapper.kt +108 -7
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/LinkCoordinator.kt +69 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/MarkdownTextWatcher.kt +3 -3
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/MentionCoordinator.kt +118 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnChangeStateEvent.kt +26 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnContextMenuItemPressEvent.kt +26 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnInputKeyPressEvent.kt +24 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnPasteEvent.kt +24 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/BlockStore.kt +254 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/FormattingStore.kt +80 -87
- package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/InputFormatter.kt +109 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/InputParser.kt +116 -22
- package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/MarkdownSerializer.kt +167 -38
- package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/RangeEditAdjustment.kt +149 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/layout/InputEventEmitter.kt +66 -5
- package/android/src/main/java/com/swmansion/enriched/markdown/input/layout/InputMeasurementStore.kt +4 -2
- package/android/src/main/java/com/swmansion/enriched/markdown/input/model/BlockRange.kt +27 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/model/BlockType.kt +48 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/model/FormattingRange.kt +9 -4
- package/android/src/main/java/com/swmansion/enriched/markdown/input/model/InputFormatterStyle.kt +39 -2
- package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MathAtom.kt +20 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MathChipStyle.kt +1 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MutableRangeBounds.kt +11 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputBulletSpan.kt +82 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputHeadingSpan.kt +58 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputListItemSpacingSpan.kt +37 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputOrderedListMarkerSpan.kt +63 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/BlockHandler.kt +54 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/HeadingBlockHandler.kt +27 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/OrderedListBlockHandler.kt +38 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/UnorderedListBlockHandler.kt +37 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/toolbar/InputContextMenu.kt +8 -26
- package/android/src/main/java/com/swmansion/enriched/markdown/parser/MarkdownASTNode.kt +1 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/parser/Parser.kt +1 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockStyleContext.kt +9 -2
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockquoteRenderer.kt +100 -12
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/CodeBlockRenderer.kt +16 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/HeadingRenderer.kt +4 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/LinkRenderer.kt +37 -7
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListContextManager.kt +2 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListItemRenderer.kt +74 -18
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListRenderer.kt +43 -4
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/NodeRenderer.kt +9 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SoftBreakRenderer.kt +16 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SpanStyleCache.kt +35 -28
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/BaseListSpan.kt +24 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/BlockquoteSpan.kt +174 -24
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBackgroundSpan.kt +20 -82
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBlockSpan.kt +13 -16
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeSpan.kt +1 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/EmphasisSpan.kt +1 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/ImageSpan.kt +182 -46
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/InlineChipPainter.kt +140 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/LinkChipSpans.kt +177 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/LinkSpan.kt +1 -6
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/ListItemSpacingSpan.kt +33 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/ListMarkerAnchorSpan.kt +38 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/OrderedListSpan.kt +2 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/StrongSpan.kt +1 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/TaskListSpan.kt +3 -2
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/UnorderedListSpan.kt +3 -2
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/BlockquoteStyle.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/CodeBlockStyle.kt +26 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/ImageStyle.kt +7 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/InlineMathStyle.kt +16 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/LinkStyle.kt +36 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/LinkVariantEntry.kt +7 -3
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/ListStyle.kt +4 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/MathStyle.kt +3 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/StyleConfig.kt +13 -4
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/TableStyle.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/CodeBlockHighlighter.kt +90 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/CodeBlockNode.kt +57 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/FeatureFlags.kt +1 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/MarkdownSegment.kt +9 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/MarkdownViewManagerUtils.kt +84 -7
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/ReadableMapExtensions.kt +3 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/RenderedSegment.kt +10 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/SegmentSignature.kt +1 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/StreamingMarkdownFilter.kt +83 -5
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/serialization/MarkdownASTSerializer.kt +4 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/input/MarkdownStyleParser.kt +74 -44
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/input/PasteTextUtils.kt +52 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageCache.kt +26 -3
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageDownloader.kt +22 -9
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/LocalImageLoader.kt +161 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/conversion/HTMLGenerator.kt +2 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/conversion/MarkdownExtractor.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/extensions/TextPaintExtensions.kt +23 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/CheckboxTouchHelper.kt +7 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/TaskListTapUtils.kt +41 -21
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/span/BlockSpacing.kt +15 -8
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/HeadlessActionMode.kt +88 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/LinkLayoutCollector.kt +100 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/LinkLongPressMovementMethod.kt +58 -27
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/SelectionActionMode.kt +72 -16
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/SelectionChangeReporter.kt +232 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/views/BlockMenuOptions.kt +64 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/views/CodeBlockContainerView.kt +414 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/views/ContextMenuPopup.kt +9 -6
- package/android/src/main/java/com/swmansion/enriched/markdown/views/CopyGlyph.kt +101 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/views/TableContainerView.kt +61 -11
- package/android/src/main/jni/CMakeLists.txt +53 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.cpp +10 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.h +11 -2
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextShadowNode.cpp +10 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextShadowNode.h +12 -2
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextState.cpp +9 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextState.h +24 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/conversions.h +16 -0
- package/android/src/math/java/com/swmansion/enriched/markdown/input/math/MathChipControllerImpl.kt +21 -4
- package/android/src/math/java/com/swmansion/enriched/markdown/renderer/MathInlineRenderer.kt +8 -2
- package/android/src/math/java/com/swmansion/enriched/markdown/spans/MathChipSpan.kt +1 -1
- package/android/src/math/java/com/swmansion/enriched/markdown/spans/MathInlineSpan.kt +13 -6
- package/android/src/math/java/com/swmansion/enriched/markdown/spans/MathMeasureHelper.kt +2 -1
- package/android/src/math/java/com/swmansion/enriched/markdown/views/MathContainerView.kt +26 -8
- package/cpp/highlight/CodeBlockHighlighter.cpp +284 -0
- package/cpp/highlight/CodeBlockHighlighter.hpp +66 -0
- package/cpp/highlight/CodeBlockLanguages.cpp +138 -0
- package/cpp/highlight/CodeBlockLanguages.hpp +25 -0
- package/cpp/highlight/HighlightGrammars.hpp +28 -0
- package/cpp/highlight/code_highlight_podspec.rb +211 -0
- package/cpp/highlight/gen-registry.mjs +155 -0
- package/cpp/highlight/grammar-versions.json +159 -0
- package/cpp/highlight/vendor/generated/generated_queries.h +1665 -0
- package/cpp/highlight/vendor/generated/generated_registry.cpp +59 -0
- package/cpp/parser/MD4CParser.cpp +173 -61
- package/cpp/parser/MD4CParser.hpp +1 -0
- package/cpp/parser/MarkdownASTNode.hpp +2 -1
- package/cpp/wasm/ASTSerializer.cpp +2 -0
- package/cpp/wasm/build.sh +1 -0
- package/cpp/wasm/md4c_wasm.cpp +3 -1
- package/docs/ACCESSIBILITY.md +14 -2
- package/docs/API_REFERENCE.md +405 -12
- package/docs/BREAKING_CHANGES.md +129 -0
- package/docs/CODE_HIGHLIGHT.md +133 -0
- package/docs/COPY_OPTIONS.md +61 -3
- package/docs/ELEMENTS_STRUCTURE.md +52 -4
- package/docs/IMAGE_CACHING.md +30 -0
- package/docs/INPUT.md +110 -11
- package/docs/LATEX_MATH.md +87 -45
- package/docs/MACOS.md +1 -1
- package/docs/MARKDOWN_STREAMING.md +27 -1
- package/docs/MENTIONS.md +8 -1
- package/docs/NATIVE_ASSETS.md +127 -0
- package/docs/RTL.md +1 -1
- package/docs/STYLES.md +73 -6
- package/docs/TESTING.md +112 -0
- package/docs/TEXT.md +18 -6
- package/docs/WEB.md +4 -1
- package/ios/EnrichedMarkdown.h +7 -0
- package/ios/EnrichedMarkdown.mm +583 -76
- package/ios/EnrichedMarkdownText.h +7 -0
- package/ios/EnrichedMarkdownText.mm +299 -73
- package/ios/attachments/ENRMImageAttachment.h +9 -0
- package/ios/attachments/ENRMImageAttachment.m +143 -40
- package/ios/attachments/ENRMMathInlineAttachment+macOS.m +2 -1
- package/ios/attachments/ENRMMathInlineAttachment.h +5 -0
- package/ios/attachments/ENRMMathInlineAttachment.m +50 -82
- package/ios/attachments/ENRMMathInlineAttachmentShared.h +2 -0
- package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.cpp +223 -0
- package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.h +183 -0
- package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.cpp +65 -0
- package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.h +1086 -61
- package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/RCTComponentViewHelpers.h +181 -2
- package/ios/input/ENRMAutoLinkDetector.h +2 -1
- package/ios/input/ENRMAutoLinkDetector.mm +79 -41
- package/ios/input/ENRMBlockEditCoordinator.h +71 -0
- package/ios/input/ENRMBlockEditCoordinator.mm +195 -0
- package/ios/input/ENRMBlockRange.h +28 -0
- package/ios/input/ENRMBlockRange.mm +30 -0
- package/ios/input/ENRMBlockStore.h +56 -0
- package/ios/input/ENRMBlockStore.mm +275 -0
- package/ios/input/ENRMClipboardCoordinator.h +45 -0
- package/ios/input/ENRMClipboardCoordinator.mm +120 -0
- package/ios/input/ENRMDetectorPipeline.h +2 -1
- package/ios/input/ENRMEditPipeline.h +76 -0
- package/ios/input/ENRMEditPipeline.mm +228 -0
- package/ios/input/ENRMEditSession.h +36 -0
- package/ios/input/ENRMEditSession.mm +63 -0
- package/ios/input/ENRMFormattingStore.h +17 -0
- package/ios/input/ENRMFormattingStore.mm +95 -105
- package/ios/input/ENRMInputBlockType.h +91 -0
- package/ios/input/ENRMInputBlockType.mm +5 -0
- package/ios/input/ENRMInputDecorationDrawer.h +18 -0
- package/ios/input/ENRMInputEventEmitter.h +56 -0
- package/ios/input/ENRMInputEventEmitter.mm +308 -0
- package/ios/input/ENRMInputFormatter.h +29 -69
- package/ios/input/ENRMInputFormatter.mm +216 -124
- package/ios/input/ENRMInputFormatterStyle.h +99 -0
- package/ios/input/ENRMInputFormatterStyle.mm +188 -0
- package/ios/input/ENRMInputLayoutManager.h +9 -0
- package/ios/input/ENRMInputLayoutManager.mm +30 -0
- package/ios/input/ENRMInputListMarkerDrawer.h +32 -0
- package/ios/input/ENRMInputListMarkerDrawer.mm +426 -0
- package/ios/input/ENRMInputParser.h +5 -6
- package/ios/input/ENRMInputParser.mm +461 -178
- package/ios/input/ENRMInputRemend.mm +2 -2
- package/ios/input/ENRMInputStyleStateBuilder.h +40 -0
- package/ios/input/ENRMInputStyleStateBuilder.mm +60 -0
- package/ios/input/ENRMInputTextView.mm +103 -8
- package/ios/input/ENRMInputTypingAttributesController.h +42 -0
- package/ios/input/ENRMInputTypingAttributesController.mm +203 -0
- package/ios/input/ENRMLinkCoordinator.h +41 -0
- package/ios/input/ENRMLinkCoordinator.mm +89 -0
- package/ios/input/ENRMMarkdownSerializer.h +29 -5
- package/ios/input/ENRMMarkdownSerializer.mm +170 -48
- package/ios/input/ENRMMathAtom.h +26 -0
- package/ios/input/ENRMMathAtom.mm +12 -0
- package/ios/input/ENRMMentionCoordinator.h +45 -0
- package/ios/input/ENRMMentionCoordinator.mm +167 -0
- package/ios/input/ENRMRangeEditAdjustment.h +38 -0
- package/ios/input/ENRMRangeEditAdjustment.mm +91 -0
- package/ios/input/ENRMRangeStoreUtils.h +39 -0
- package/ios/input/EnrichedMarkdownTextInput+ContextMenu.mm +6 -6
- package/ios/input/EnrichedMarkdownTextInput+Internal.h +11 -3
- package/ios/input/EnrichedMarkdownTextInput.h +7 -1
- package/ios/input/EnrichedMarkdownTextInput.mm +1089 -1023
- package/ios/input/InputStylePropsUtils.h +109 -68
- package/ios/input/internals/EnrichedMarkdownTextInputShadowNode.mm +2 -1
- package/ios/input/styles/ENRMBlockHandler.h +46 -0
- package/ios/input/styles/ENRMHeadingBlockHandler.h +15 -0
- package/ios/input/styles/ENRMHeadingBlockHandler.mm +38 -0
- package/ios/input/styles/ENRMOrderedListBlockHandler.h +14 -0
- package/ios/input/styles/ENRMOrderedListBlockHandler.mm +48 -0
- package/ios/input/styles/ENRMUnorderedListBlockHandler.h +15 -0
- package/ios/input/styles/ENRMUnorderedListBlockHandler.mm +51 -0
- package/ios/internals/ENRMViewFreeMeasurement.h +331 -0
- package/ios/internals/EnrichedMarkdownShadowNode.h +1 -3
- package/ios/internals/EnrichedMarkdownShadowNode.mm +16 -20
- package/ios/internals/EnrichedMarkdownTextShadowNode.h +1 -3
- package/ios/internals/EnrichedMarkdownTextShadowNode.mm +15 -20
- package/ios/internals/MeasurementCache.h +41 -9
- package/ios/internals/ShadowMeasurementUtils.h +63 -58
- package/ios/math/ENRMMathChipController.h +74 -0
- package/ios/math/ENRMMathChipController.mm +476 -0
- package/ios/math/ENRMRaTeXBridge.swift +27 -6
- package/ios/parser/ENRMMarkdownParser.h +1 -8
- package/ios/parser/ENRMMarkdownParser.mm +2 -11
- package/ios/parser/MarkdownASTNode.h +2 -1
- package/ios/parser/MarkdownParserBridge.mm +4 -0
- package/ios/renderer/AttributedRenderer.m +20 -2
- package/ios/renderer/BaseRenderer.h +17 -2
- package/ios/renderer/BaseRenderer.m +30 -0
- package/ios/renderer/BlockquoteRenderer.h +1 -1
- package/ios/renderer/BlockquoteRenderer.m +144 -35
- package/ios/renderer/CodeBlockRenderer.h +1 -1
- package/ios/renderer/CodeBlockRenderer.m +27 -23
- package/ios/renderer/CodeRenderer.h +1 -1
- package/ios/renderer/CodeRenderer.m +3 -1
- package/ios/renderer/ENRMImageRenderer.h +1 -1
- package/ios/renderer/ENRMImageRenderer.m +5 -1
- package/ios/renderer/ENRMMathInlineRenderer.h +1 -1
- package/ios/renderer/ENRMMathInlineRenderer.m +6 -1
- package/ios/renderer/ENRMSpoilerRenderer.h +1 -1
- package/ios/renderer/ENRMSpoilerRenderer.m +3 -1
- package/ios/renderer/EmphasisRenderer.h +1 -1
- package/ios/renderer/EmphasisRenderer.m +3 -1
- package/ios/renderer/HeadingRenderer.h +1 -1
- package/ios/renderer/HeadingRenderer.m +13 -6
- package/ios/renderer/HighlightRenderer.h +1 -1
- package/ios/renderer/HighlightRenderer.m +3 -1
- package/ios/renderer/LinkRenderer.h +1 -1
- package/ios/renderer/LinkRenderer.m +50 -16
- package/ios/renderer/ListItemRenderer.h +13 -1
- package/ios/renderer/ListItemRenderer.m +102 -44
- package/ios/renderer/ListRenderer.h +2 -2
- package/ios/renderer/ListRenderer.m +63 -25
- package/ios/renderer/ParagraphRenderer.h +1 -1
- package/ios/renderer/ParagraphRenderer.m +16 -8
- package/ios/renderer/RenderContext.h +10 -0
- package/ios/renderer/RenderContext.m +44 -0
- package/ios/renderer/RendererFactory.m +14 -0
- package/ios/renderer/StrikethroughRenderer.h +1 -1
- package/ios/renderer/StrikethroughRenderer.m +3 -1
- package/ios/renderer/StrongRenderer.h +1 -1
- package/ios/renderer/StrongRenderer.m +3 -1
- package/ios/renderer/SubscriptRenderer.h +1 -1
- package/ios/renderer/SubscriptRenderer.m +3 -1
- package/ios/renderer/SuperscriptRenderer.h +1 -1
- package/ios/renderer/SuperscriptRenderer.m +3 -1
- package/ios/renderer/TextRenderer.h +2 -2
- package/ios/renderer/TextRenderer.m +3 -1
- package/ios/renderer/ThematicBreakRenderer.h +1 -1
- package/ios/renderer/ThematicBreakRenderer.m +3 -1
- package/ios/renderer/UnderlineRenderer.h +1 -1
- package/ios/renderer/UnderlineRenderer.m +3 -1
- package/ios/styles/StyleConfig.h +42 -0
- package/ios/styles/StyleConfig.mm +216 -0
- package/ios/utils/BlockquoteBorder.h +6 -0
- package/ios/utils/BlockquoteBorder.m +249 -52
- package/ios/utils/CodeBackground.m +3 -65
- package/ios/utils/CodeBlockBackground.m +16 -2
- package/ios/utils/ENRMAtomicSize.h +65 -0
- package/ios/utils/ENRMBlockMenu.h +66 -0
- package/ios/utils/ENRMChipDrawing.h +24 -0
- package/ios/utils/ENRMChipDrawing.m +83 -0
- package/ios/utils/ENRMCodeBlockContent.h +37 -0
- package/ios/utils/ENRMCodeBlockContent.mm +79 -0
- package/ios/utils/ENRMCodeBlockHighlighter.h +37 -0
- package/ios/utils/ENRMCodeBlockHighlighter.mm +51 -0
- package/ios/utils/ENRMFeatureFlags.h +7 -0
- package/ios/utils/ENRMImageDownloader.h +11 -1
- package/ios/utils/ENRMImageDownloader.m +60 -16
- package/ios/utils/ENRMLinkChip.h +70 -0
- package/ios/utils/ENRMLinkChip.m +213 -0
- package/ios/utils/ENRMLinkLayout.h +50 -0
- package/ios/utils/ENRMLinkLayout.m +45 -0
- package/ios/utils/ENRMLocalImageLoader.h +31 -0
- package/ios/utils/ENRMLocalImageLoader.m +68 -0
- package/ios/utils/ENRMMathFallback.h +26 -0
- package/ios/utils/ENRMMathFallback.m +18 -0
- package/ios/utils/ENRMSelectionChange.h +120 -0
- package/ios/utils/ENRMSelectionChange.m +282 -0
- package/ios/utils/ENRMTextViewSetup.h +35 -17
- package/ios/utils/EditMenuUtils+macOS.m +4 -1
- package/ios/utils/EditMenuUtils.h +35 -6
- package/ios/utils/EditMenuUtils.m +188 -11
- package/ios/utils/HTMLGenerator.m +2 -1
- package/ios/utils/ImageRequestHeaderUtils.h +35 -0
- package/ios/utils/LastElementUtils.h +1 -0
- package/ios/utils/ListMarkerDrawer.m +29 -42
- package/ios/utils/MarkdownASTSerializer.m +4 -0
- package/ios/utils/MarkdownAccessibilityElementBuilder.m +3 -1
- package/ios/utils/MarkdownExtractor.m +2 -1
- package/ios/utils/ParagraphStyleUtils.h +5 -0
- package/ios/utils/ParagraphStyleUtils.m +77 -17
- package/ios/utils/RTFExportUtils.m +2 -0
- package/ios/utils/RenderedMarkdownSegment.h +13 -1
- package/ios/utils/RenderedMarkdownSegment.m +20 -0
- package/ios/utils/SegmentRenderer.m +17 -4
- package/ios/utils/StreamingMarkdownFilter.h +11 -1
- package/ios/utils/StreamingMarkdownFilter.m +98 -2
- package/ios/utils/StylePropsUtils.h +110 -1
- package/ios/utils/TaskListTapUtils.m +24 -0
- package/ios/utils/TextViewLayoutManager.mm +3 -0
- package/ios/views/ENRMCodeBlockContainerView.h +60 -0
- package/ios/views/ENRMCodeBlockContainerView.m +569 -0
- package/ios/views/ENRMMathContainerView.h +23 -0
- package/ios/views/ENRMMathContainerView.m +87 -20
- package/ios/views/TableContainerView.h +32 -0
- package/ios/views/TableContainerView.m +291 -175
- package/jest.d.ts +1 -0
- package/jest.js +5 -0
- package/lib/module/EnrichedMarkdownNativeComponent.ts +203 -1
- package/lib/module/EnrichedMarkdownTextInput.js +84 -5
- package/lib/module/EnrichedMarkdownTextInput.js.map +1 -1
- package/lib/module/EnrichedMarkdownTextInputNativeComponent.ts +78 -5
- package/lib/module/EnrichedMarkdownTextNativeComponent.ts +204 -1
- package/lib/module/headingDefaults.js +34 -0
- package/lib/module/headingDefaults.js.map +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/jest/index.js +205 -0
- package/lib/module/jest/index.js.map +1 -0
- package/lib/module/native/EnrichedMarkdownText.js +199 -15
- package/lib/module/native/EnrichedMarkdownText.js.map +1 -1
- package/lib/module/normalizeMarkdownStyle.js +98 -23
- package/lib/module/normalizeMarkdownStyle.js.map +1 -1
- package/lib/module/normalizeMarkdownStyle.web.js +73 -22
- package/lib/module/normalizeMarkdownStyle.web.js.map +1 -1
- package/lib/module/normalizeMarkdownTextInputStyle.js +62 -15
- package/lib/module/normalizeMarkdownTextInputStyle.js.map +1 -1
- package/lib/module/normalizeMenuItem.js +1 -1
- package/lib/module/utils/textInputState.js +26 -0
- package/lib/module/utils/textInputState.js.map +1 -0
- package/lib/module/web/EnrichedMarkdownText.js +15 -8
- package/lib/module/web/EnrichedMarkdownText.js.map +1 -1
- package/lib/module/web/parseMarkdown.js +4 -3
- package/lib/module/web/parseMarkdown.js.map +1 -1
- package/lib/module/web/renderers/InlineRenderers.js +102 -3
- package/lib/module/web/renderers/InlineRenderers.js.map +1 -1
- package/lib/module/web/renderers/ListRenderers.js +7 -2
- package/lib/module/web/renderers/ListRenderers.js.map +1 -1
- package/lib/module/web/renderers/index.js +7 -4
- package/lib/module/web/renderers/index.js.map +1 -1
- package/lib/module/web/styles.js +101 -6
- package/lib/module/web/styles.js.map +1 -1
- package/lib/module/web/utils.js +14 -0
- package/lib/module/web/utils.js.map +1 -1
- package/lib/module/web/wasm/md4c.js +0 -0
- package/lib/module/web/wasm/md4c.js.map +1 -1
- package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts +185 -2
- package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/EnrichedMarkdownTextInput.d.ts +94 -9
- package/lib/typescript/src/EnrichedMarkdownTextInput.d.ts.map +1 -1
- package/lib/typescript/src/EnrichedMarkdownTextInputNativeComponent.d.ts +69 -5
- package/lib/typescript/src/EnrichedMarkdownTextInputNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts +185 -2
- package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/headingDefaults.d.ts +9 -0
- package/lib/typescript/src/headingDefaults.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +3 -3
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/index.web.d.ts +2 -2
- package/lib/typescript/src/index.web.d.ts.map +1 -1
- package/lib/typescript/src/jest/index.d.ts +6 -0
- package/lib/typescript/src/jest/index.d.ts.map +1 -0
- package/lib/typescript/src/native/EnrichedMarkdownText.d.ts +5 -5
- package/lib/typescript/src/native/EnrichedMarkdownText.d.ts.map +1 -1
- package/lib/typescript/src/normalizeMarkdownStyle.d.ts.map +1 -1
- package/lib/typescript/src/normalizeMarkdownStyle.web.d.ts.map +1 -1
- package/lib/typescript/src/normalizeMarkdownTextInputStyle.d.ts +19 -5
- package/lib/typescript/src/normalizeMarkdownTextInputStyle.d.ts.map +1 -1
- package/lib/typescript/src/types/MarkdownStyle.d.ts +122 -5
- package/lib/typescript/src/types/MarkdownStyle.d.ts.map +1 -1
- package/lib/typescript/src/types/MarkdownStyleInternal.d.ts +39 -0
- package/lib/typescript/src/types/MarkdownStyleInternal.d.ts.map +1 -1
- package/lib/typescript/src/types/MarkdownTextProps.d.ts +207 -10
- package/lib/typescript/src/types/MarkdownTextProps.d.ts.map +1 -1
- package/lib/typescript/src/types/MarkdownTextProps.web.d.ts +60 -1
- package/lib/typescript/src/types/MarkdownTextProps.web.d.ts.map +1 -1
- package/lib/typescript/src/types/events.d.ts +85 -0
- package/lib/typescript/src/types/events.d.ts.map +1 -1
- package/lib/typescript/src/utils/textInputState.d.ts +24 -0
- package/lib/typescript/src/utils/textInputState.d.ts.map +1 -0
- package/lib/typescript/src/web/EnrichedMarkdownText.d.ts +1 -1
- package/lib/typescript/src/web/EnrichedMarkdownText.d.ts.map +1 -1
- package/lib/typescript/src/web/parseMarkdown.d.ts +1 -1
- package/lib/typescript/src/web/parseMarkdown.d.ts.map +1 -1
- package/lib/typescript/src/web/renderers/InlineRenderers.d.ts.map +1 -1
- package/lib/typescript/src/web/renderers/ListRenderers.d.ts.map +1 -1
- package/lib/typescript/src/web/renderers/index.d.ts +2 -1
- package/lib/typescript/src/web/renderers/index.d.ts.map +1 -1
- package/lib/typescript/src/web/styles.d.ts +2 -1
- package/lib/typescript/src/web/styles.d.ts.map +1 -1
- package/lib/typescript/src/web/types.d.ts +10 -2
- package/lib/typescript/src/web/types.d.ts.map +1 -1
- package/lib/typescript/src/web/utils.d.ts +4 -0
- package/lib/typescript/src/web/utils.d.ts.map +1 -1
- package/package.json +36 -9
- package/postinstall.mjs +131 -0
- package/ratex-version.json +21 -0
- package/src/EnrichedMarkdownNativeComponent.ts +203 -1
- package/src/EnrichedMarkdownTextInput.tsx +159 -8
- package/src/EnrichedMarkdownTextInputNativeComponent.ts +78 -5
- package/src/EnrichedMarkdownTextNativeComponent.ts +204 -1
- package/src/headingDefaults.ts +21 -0
- package/src/index.tsx +15 -0
- package/src/index.web.tsx +6 -1
- package/src/jest/index.tsx +236 -0
- package/src/native/EnrichedMarkdownText.tsx +260 -11
- package/src/normalizeMarkdownStyle.ts +117 -16
- package/src/normalizeMarkdownStyle.web.ts +76 -15
- package/src/normalizeMarkdownTextInputStyle.ts +110 -35
- package/src/normalizeMenuItem.ts +1 -1
- package/src/types/MarkdownStyle.ts +125 -5
- package/src/types/MarkdownStyleInternal.ts +51 -0
- package/src/types/MarkdownTextProps.ts +215 -10
- package/src/types/MarkdownTextProps.web.ts +62 -1
- package/src/types/events.ts +90 -0
- package/src/utils/textInputState.ts +35 -0
- package/src/web/EnrichedMarkdownText.tsx +26 -5
- package/src/web/parseMarkdown.ts +6 -2
- package/src/web/renderers/InlineRenderers.tsx +116 -3
- package/src/web/renderers/ListRenderers.tsx +14 -2
- package/src/web/renderers/index.tsx +6 -2
- package/src/web/styles.ts +114 -5
- package/src/web/types.ts +10 -1
- package/src/web/utils.ts +9 -0
- package/src/web/wasm/md4c.js +0 -0
- package/vendor-grammars.mjs +511 -0
- package/vendor-ratex.mjs +173 -0
- package/app.plugin.js +0 -2
- package/plugin/build/withAndroidMath.js +0 -19
- package/plugin/build/withIosMath.js +0 -28
- package/plugin/build/withReactNativeEnrichedMarkdown.js +0 -11
- package/plugin/src/withAndroidMath.ts +0 -24
- package/plugin/src/withIosMath.ts +0 -35
- package/plugin/src/withReactNativeEnrichedMarkdown.ts +0 -17
- package/plugin/tsconfig.build.json +0 -16
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
#import "ENRMLinkChip.h"
|
|
2
|
+
#import "ENRMChipDrawing.h"
|
|
3
|
+
#import <CoreText/CoreText.h>
|
|
4
|
+
|
|
5
|
+
NSString *const ENRMLinkChipAttributeName = @"ENRMLinkChip";
|
|
6
|
+
NSString *const ENRMLinkSpacerAttributeName = @"ENRMLinkSpacer";
|
|
7
|
+
|
|
8
|
+
static const unichar kSpacerChar = 0x00A0;
|
|
9
|
+
static const CGFloat kSpacerFontSize = 1.0;
|
|
10
|
+
|
|
11
|
+
@implementation ENRMLinkChip
|
|
12
|
+
|
|
13
|
+
- (BOOL)isVisible
|
|
14
|
+
{
|
|
15
|
+
return self.backgroundColor != nil || (self.borderColor != nil && self.borderWidth > 0);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
@end
|
|
19
|
+
|
|
20
|
+
#pragma mark - Spacers
|
|
21
|
+
|
|
22
|
+
static CGFloat spacerAdvance(UIFont *font)
|
|
23
|
+
{
|
|
24
|
+
CTFontRef ctFont = (__bridge CTFontRef)font;
|
|
25
|
+
UniChar character = kSpacerChar;
|
|
26
|
+
CGGlyph glyph = 0;
|
|
27
|
+
if (!CTFontGetGlyphsForCharacters(ctFont, &character, &glyph, 1))
|
|
28
|
+
return 0;
|
|
29
|
+
CGSize advance = CGSizeZero;
|
|
30
|
+
CTFontGetAdvancesForGlyphs(ctFont, kCTFontOrientationHorizontal, &glyph, &advance, 1);
|
|
31
|
+
return advance.width;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
NSAttributedString *ENRMLinkSpacerString(NSDictionary<NSAttributedStringKey, id> *baseAttributes, CGFloat width)
|
|
35
|
+
{
|
|
36
|
+
static UIFont *spacerFont;
|
|
37
|
+
static CGFloat spacerFontAdvance;
|
|
38
|
+
static dispatch_once_t onceToken;
|
|
39
|
+
dispatch_once(&onceToken, ^{
|
|
40
|
+
spacerFont = [UIFont systemFontOfSize:kSpacerFontSize];
|
|
41
|
+
spacerFontAdvance = spacerAdvance(spacerFont);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
NSMutableDictionary *attributes = [baseAttributes mutableCopy] ?: [NSMutableDictionary dictionary];
|
|
45
|
+
attributes[NSFontAttributeName] = spacerFont;
|
|
46
|
+
attributes[NSKernAttributeName] = @(width - spacerFontAdvance);
|
|
47
|
+
attributes[ENRMLinkSpacerAttributeName] = @YES;
|
|
48
|
+
// Padding is not text: keep decorations and attachments off it.
|
|
49
|
+
[attributes removeObjectForKey:NSUnderlineStyleAttributeName];
|
|
50
|
+
[attributes removeObjectForKey:NSStrikethroughStyleAttributeName];
|
|
51
|
+
[attributes removeObjectForKey:NSAttachmentAttributeName];
|
|
52
|
+
|
|
53
|
+
NSString *spacer = [NSString stringWithCharacters:&kSpacerChar length:1];
|
|
54
|
+
return [[NSAttributedString alloc] initWithString:spacer attributes:attributes];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
NSAttributedString *ENRMAttributedStringByRemovingLinkSpacers(NSAttributedString *string)
|
|
58
|
+
{
|
|
59
|
+
__block NSMutableAttributedString *stripped = nil;
|
|
60
|
+
[string enumerateAttribute:ENRMLinkSpacerAttributeName
|
|
61
|
+
inRange:NSMakeRange(0, string.length)
|
|
62
|
+
options:NSAttributedStringEnumerationReverse
|
|
63
|
+
usingBlock:^(id value, NSRange range, BOOL *stop) {
|
|
64
|
+
if (!value)
|
|
65
|
+
return;
|
|
66
|
+
if (!stripped)
|
|
67
|
+
stripped = [string mutableCopy];
|
|
68
|
+
[stripped deleteCharactersInRange:range];
|
|
69
|
+
}];
|
|
70
|
+
return stripped ?: string;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
NSString *ENRMPlainTextByRemovingLinkSpacers(NSAttributedString *string, NSRange range)
|
|
74
|
+
{
|
|
75
|
+
if (range.location == NSNotFound || NSMaxRange(range) > string.length)
|
|
76
|
+
return @"";
|
|
77
|
+
return ENRMAttributedStringByRemovingLinkSpacers([string attributedSubstringFromRange:range]).string;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
void ENRMApplyLinkChipBackgroundsAsTextBackground(NSMutableAttributedString *string)
|
|
81
|
+
{
|
|
82
|
+
[string enumerateAttribute:ENRMLinkChipAttributeName
|
|
83
|
+
inRange:NSMakeRange(0, string.length)
|
|
84
|
+
options:0
|
|
85
|
+
usingBlock:^(ENRMLinkChip *chip, NSRange range, BOOL *stop) {
|
|
86
|
+
if (chip.backgroundColor) {
|
|
87
|
+
[string addAttribute:NSBackgroundColorAttributeName value:chip.backgroundColor range:range];
|
|
88
|
+
}
|
|
89
|
+
}];
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
#pragma mark - Geometry
|
|
93
|
+
|
|
94
|
+
/// The font of the first non-spacer character of `charRange` — the spacer's
|
|
95
|
+
/// 1pt font must not drive the chip's height.
|
|
96
|
+
static UIFont *_Nullable chipFontInRange(NSTextStorage *storage, NSRange charRange)
|
|
97
|
+
{
|
|
98
|
+
__block UIFont *font = nil;
|
|
99
|
+
[storage enumerateAttributesInRange:charRange
|
|
100
|
+
options:0
|
|
101
|
+
usingBlock:^(NSDictionary<NSAttributedStringKey, id> *attrs, NSRange range, BOOL *stop) {
|
|
102
|
+
if (attrs[ENRMLinkSpacerAttributeName])
|
|
103
|
+
return;
|
|
104
|
+
font = attrs[NSFontAttributeName];
|
|
105
|
+
*stop = font != nil;
|
|
106
|
+
}];
|
|
107
|
+
return font;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
void ENRMEnumerateLinkChipFragments(NSLayoutManager *layoutManager, NSTextContainer *textContainer, NSRange charRange,
|
|
111
|
+
ENRMLinkChip *chip, void (^block)(CGRect rect, BOOL isFirst, BOOL isLast))
|
|
112
|
+
{
|
|
113
|
+
NSTextStorage *storage = layoutManager.textStorage;
|
|
114
|
+
if (charRange.length == 0 || NSMaxRange(charRange) > storage.length)
|
|
115
|
+
return;
|
|
116
|
+
|
|
117
|
+
NSRange glyphRange = [layoutManager glyphRangeForCharacterRange:charRange actualCharacterRange:NULL];
|
|
118
|
+
if (glyphRange.location == NSNotFound || glyphRange.length == 0)
|
|
119
|
+
return;
|
|
120
|
+
|
|
121
|
+
CGFloat paddingHorizontal = chip.paddingHorizontal;
|
|
122
|
+
CGFloat paddingVertical = chip.paddingVertical;
|
|
123
|
+
|
|
124
|
+
[layoutManager
|
|
125
|
+
enumerateLineFragmentsForGlyphRange:glyphRange
|
|
126
|
+
usingBlock:^(CGRect lineRect, CGRect usedRect, NSTextContainer *tc, NSRange lineRange,
|
|
127
|
+
BOOL *stop) {
|
|
128
|
+
NSRange intersect = NSIntersectionRange(lineRange, glyphRange);
|
|
129
|
+
if (intersect.length == 0)
|
|
130
|
+
return;
|
|
131
|
+
|
|
132
|
+
BOOL isFirst = intersect.location == glyphRange.location;
|
|
133
|
+
BOOL isLast = NSMaxRange(intersect) == NSMaxRange(glyphRange);
|
|
134
|
+
|
|
135
|
+
CGRect textRect = [layoutManager boundingRectForGlyphRange:intersect
|
|
136
|
+
inTextContainer:textContainer];
|
|
137
|
+
NSRange fragmentChars = [layoutManager characterRangeForGlyphRange:intersect
|
|
138
|
+
actualGlyphRange:NULL];
|
|
139
|
+
NSUInteger lineEnd = NSMaxRange(lineRange);
|
|
140
|
+
CGFloat left =
|
|
141
|
+
lineRect.origin.x + [layoutManager locationForGlyphAtIndex:intersect.location].x;
|
|
142
|
+
|
|
143
|
+
NSUInteger visibleCharEnd = NSMaxRange(fragmentChars);
|
|
144
|
+
NSString *chars = storage.string;
|
|
145
|
+
NSCharacterSet *breakable = [NSCharacterSet whitespaceAndNewlineCharacterSet];
|
|
146
|
+
while (visibleCharEnd > fragmentChars.location &&
|
|
147
|
+
[chars characterAtIndex:visibleCharEnd - 1] != kSpacerChar &&
|
|
148
|
+
[breakable characterIsMember:[chars characterAtIndex:visibleCharEnd - 1]]) {
|
|
149
|
+
visibleCharEnd--;
|
|
150
|
+
}
|
|
151
|
+
NSUInteger visibleGlyphEnd = NSMaxRange(intersect);
|
|
152
|
+
if (visibleCharEnd < NSMaxRange(fragmentChars)) {
|
|
153
|
+
visibleGlyphEnd = [layoutManager glyphIndexForCharacterAtIndex:visibleCharEnd];
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
CGFloat right;
|
|
157
|
+
if (visibleGlyphEnd < lineEnd) {
|
|
158
|
+
right =
|
|
159
|
+
lineRect.origin.x + [layoutManager locationForGlyphAtIndex:visibleGlyphEnd].x;
|
|
160
|
+
} else {
|
|
161
|
+
right = CGRectGetMaxX(usedRect);
|
|
162
|
+
}
|
|
163
|
+
if (isLast && paddingHorizontal > 0) {
|
|
164
|
+
NSUInteger lastGlyph = NSMaxRange(intersect) - 1;
|
|
165
|
+
CGFloat spacerX =
|
|
166
|
+
lineRect.origin.x + [layoutManager locationForGlyphAtIndex:lastGlyph].x;
|
|
167
|
+
right = MAX(right, spacerX + paddingHorizontal);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
UIFont *font = chipFontInRange(storage, fragmentChars);
|
|
171
|
+
CGFloat top = CGRectGetMinY(textRect);
|
|
172
|
+
CGFloat bottom = CGRectGetMaxY(textRect);
|
|
173
|
+
if (font) {
|
|
174
|
+
// locationForGlyphAtIndex: y is the baseline within the line fragment.
|
|
175
|
+
CGFloat baseline =
|
|
176
|
+
lineRect.origin.y + [layoutManager locationForGlyphAtIndex:intersect.location].y;
|
|
177
|
+
top = baseline - font.ascender;
|
|
178
|
+
bottom = baseline - font.descender;
|
|
179
|
+
}
|
|
180
|
+
top -= paddingVertical;
|
|
181
|
+
bottom += paddingVertical;
|
|
182
|
+
|
|
183
|
+
block(CGRectMake(left, top, right - left, bottom - top), isFirst, isLast);
|
|
184
|
+
}];
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
#pragma mark - Drawing
|
|
188
|
+
|
|
189
|
+
void ENRMDrawLinkChipsForGlyphRange(NSLayoutManager *layoutManager, NSTextContainer *textContainer,
|
|
190
|
+
NSRange glyphsToShow, CGPoint origin)
|
|
191
|
+
{
|
|
192
|
+
NSTextStorage *storage = layoutManager.textStorage;
|
|
193
|
+
NSRange charRange = [layoutManager characterRangeForGlyphRange:glyphsToShow actualGlyphRange:NULL];
|
|
194
|
+
if (charRange.location == NSNotFound || charRange.length == 0)
|
|
195
|
+
return;
|
|
196
|
+
|
|
197
|
+
// Enumerate the whole storage (like CodeBackground) so a chip that starts
|
|
198
|
+
// before the dirty range still gets its full rect.
|
|
199
|
+
[storage
|
|
200
|
+
enumerateAttribute:ENRMLinkChipAttributeName
|
|
201
|
+
inRange:NSMakeRange(0, storage.length)
|
|
202
|
+
options:0
|
|
203
|
+
usingBlock:^(ENRMLinkChip *chip, NSRange range, BOOL *stop) {
|
|
204
|
+
if (!chip.isVisible || NSIntersectionRange(range, charRange).length == 0)
|
|
205
|
+
return;
|
|
206
|
+
|
|
207
|
+
ENRMEnumerateLinkChipFragments(
|
|
208
|
+
layoutManager, textContainer, range, chip, ^(CGRect rect, BOOL isFirst, BOOL isLast) {
|
|
209
|
+
ENRMDrawChipFragment(CGRectOffset(rect, origin.x, origin.y), chip.backgroundColor,
|
|
210
|
+
chip.borderColor, chip.borderWidth, chip.borderRadius, isFirst, isLast, YES);
|
|
211
|
+
});
|
|
212
|
+
}];
|
|
213
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
#import "ENRMUIKit.h"
|
|
3
|
+
|
|
4
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
5
|
+
|
|
6
|
+
#ifdef __cplusplus
|
|
7
|
+
extern "C" {
|
|
8
|
+
#endif
|
|
9
|
+
|
|
10
|
+
/// Collects the chip rect of every link fragment laid out in `textView`, for
|
|
11
|
+
/// the `onLinkLayout` event. Each entry is
|
|
12
|
+
/// `@{linkIndex, url, text, x, y, width, height}` (NSNumber/NSString), so a
|
|
13
|
+
/// payload compares with `-isEqualToArray:` for deduplication.
|
|
14
|
+
///
|
|
15
|
+
/// - `offset` is added to every rect (a segment's origin inside its container).
|
|
16
|
+
/// - Links are numbered in document order starting at `indexBase`; the number
|
|
17
|
+
/// of links found is written to `outLinkCount` so the next segment continues.
|
|
18
|
+
///
|
|
19
|
+
/// Rects are in points relative to the text view, which the markdown views
|
|
20
|
+
/// configure with zero insets and no line-fragment padding.
|
|
21
|
+
NSArray<NSDictionary *> *ENRMCollectLinkLayoutFragments(ENRMPlatformTextView *textView, CGPoint offset,
|
|
22
|
+
NSInteger indexBase, NSInteger *_Nullable outLinkCount);
|
|
23
|
+
|
|
24
|
+
#ifdef __cplusplus
|
|
25
|
+
}
|
|
26
|
+
#endif
|
|
27
|
+
|
|
28
|
+
#ifdef __cplusplus
|
|
29
|
+
/// Converts collected fragments into a codegen `OnLinkLayout` payload. Templated
|
|
30
|
+
/// because each component has its own (structurally identical) event struct.
|
|
31
|
+
template <typename Event> inline Event ENRMLinkLayoutEventFromFragments(NSArray<NSDictionary *> *fragments)
|
|
32
|
+
{
|
|
33
|
+
Event event;
|
|
34
|
+
event.fragments.reserve(fragments.count);
|
|
35
|
+
for (NSDictionary *fragment in fragments) {
|
|
36
|
+
typename decltype(event.fragments)::value_type item;
|
|
37
|
+
item.linkIndex = [fragment[@"linkIndex"] intValue];
|
|
38
|
+
item.url = std::string([fragment[@"url"] UTF8String] ?: "");
|
|
39
|
+
item.text = std::string([fragment[@"text"] UTF8String] ?: "");
|
|
40
|
+
item.x = [fragment[@"x"] doubleValue];
|
|
41
|
+
item.y = [fragment[@"y"] doubleValue];
|
|
42
|
+
item.width = [fragment[@"width"] doubleValue];
|
|
43
|
+
item.height = [fragment[@"height"] doubleValue];
|
|
44
|
+
event.fragments.push_back(item);
|
|
45
|
+
}
|
|
46
|
+
return event;
|
|
47
|
+
}
|
|
48
|
+
#endif
|
|
49
|
+
|
|
50
|
+
NS_ASSUME_NONNULL_END
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#import "ENRMLinkLayout.h"
|
|
2
|
+
#import "ENRMLinkChip.h"
|
|
3
|
+
|
|
4
|
+
NSArray<NSDictionary *> *ENRMCollectLinkLayoutFragments(ENRMPlatformTextView *textView, CGPoint offset,
|
|
5
|
+
NSInteger indexBase, NSInteger *outLinkCount)
|
|
6
|
+
{
|
|
7
|
+
NSLayoutManager *layoutManager = textView.layoutManager;
|
|
8
|
+
NSTextContainer *textContainer = textView.textContainer;
|
|
9
|
+
NSTextStorage *storage = layoutManager.textStorage;
|
|
10
|
+
NSMutableArray<NSDictionary *> *fragments = [NSMutableArray array];
|
|
11
|
+
__block NSInteger linkIndex = indexBase;
|
|
12
|
+
|
|
13
|
+
if (storage.length > 0 && textContainer != nil) {
|
|
14
|
+
// LinkRenderer attaches one ENRMLinkChip instance per link, so each
|
|
15
|
+
// attribute run is exactly one link (adjacent links never coalesce).
|
|
16
|
+
[storage enumerateAttribute:ENRMLinkChipAttributeName
|
|
17
|
+
inRange:NSMakeRange(0, storage.length)
|
|
18
|
+
options:0
|
|
19
|
+
usingBlock:^(ENRMLinkChip *chip, NSRange range, BOOL *stop) {
|
|
20
|
+
if (!chip)
|
|
21
|
+
return;
|
|
22
|
+
id link = [storage attribute:NSLinkAttributeName atIndex:range.location effectiveRange:NULL];
|
|
23
|
+
NSString *url = [link isKindOfClass:[NSURL class]] ? [(NSURL *)link absoluteString] : link;
|
|
24
|
+
NSString *text = ENRMPlainTextByRemovingLinkSpacers(storage, range);
|
|
25
|
+
NSNumber *index = @(linkIndex++);
|
|
26
|
+
|
|
27
|
+
ENRMEnumerateLinkChipFragments(layoutManager, textContainer, range, chip,
|
|
28
|
+
^(CGRect rect, BOOL isFirst, BOOL isLast) {
|
|
29
|
+
[fragments addObject:@{
|
|
30
|
+
@"linkIndex" : index,
|
|
31
|
+
@"url" : url ?: @"",
|
|
32
|
+
@"text" : text,
|
|
33
|
+
@"x" : @(rect.origin.x + offset.x),
|
|
34
|
+
@"y" : @(rect.origin.y + offset.y),
|
|
35
|
+
@"width" : @(rect.size.width),
|
|
36
|
+
@"height" : @(rect.size.height),
|
|
37
|
+
}];
|
|
38
|
+
});
|
|
39
|
+
}];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (outLinkCount)
|
|
43
|
+
*outLinkCount = linkIndex - indexBase;
|
|
44
|
+
return fragments;
|
|
45
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
#import "ENRMUIKit.h"
|
|
3
|
+
|
|
4
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Local (non-network) image loading for markdown sources (issue #377).
|
|
8
|
+
*
|
|
9
|
+
* React Native's asset system resolves `require('./img.png')` to a Metro http
|
|
10
|
+
* URL in dev, but to a `file://` URL near the app bundle in release builds
|
|
11
|
+
* (`AssetSourceResolver.scaledAssetURLNearBundle`), and libraries like
|
|
12
|
+
* expo-asset also hand out percent-encoded `file://` paths in the caches
|
|
13
|
+
* directory. These should not go through NSURLSession + NSURLCache: they gain
|
|
14
|
+
* nothing from HTTP caching or timeouts, and bundle assets lose `@2x`/`@3x`
|
|
15
|
+
* scale selection and asset-catalog resolution.
|
|
16
|
+
*
|
|
17
|
+
* Resolution mirrors RN's RCTImageFromLocalAssetURL: bundle-relative names are
|
|
18
|
+
* tried with `imageNamed:` first (scale suffixes, asset catalogs, and system
|
|
19
|
+
* caching for free), then the loader falls back to loading the file directly,
|
|
20
|
+
* appending `.png` when the path has no extension.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/// YES when the URL refers to a non-network source: any `file://` URL, or a
|
|
24
|
+
/// scheme-less string (bare bundle-relative asset name or absolute path).
|
|
25
|
+
BOOL ENRMIsLocalImageURL(NSString *url);
|
|
26
|
+
|
|
27
|
+
/// Synchronously loads a local image; returns nil when the source cannot be
|
|
28
|
+
/// resolved. Safe to call off the main thread.
|
|
29
|
+
RCTUIImage *_Nullable ENRMLoadLocalImage(NSString *url);
|
|
30
|
+
|
|
31
|
+
NS_ASSUME_NONNULL_END
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#import "ENRMLocalImageLoader.h"
|
|
2
|
+
|
|
3
|
+
static NSString *_Nullable ENRMBundleRelativePath(NSString *path)
|
|
4
|
+
{
|
|
5
|
+
NSString *bundlePath = [[NSBundle mainBundle] resourcePath];
|
|
6
|
+
if (bundlePath == nil || ![path hasPrefix:bundlePath]) {
|
|
7
|
+
return nil;
|
|
8
|
+
}
|
|
9
|
+
NSString *relative = [path substringFromIndex:bundlePath.length];
|
|
10
|
+
return [relative hasPrefix:@"/"] ? [relative substringFromIndex:1] : relative;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
static RCTUIImage *_Nullable ENRMImageNamed(NSString *name)
|
|
14
|
+
{
|
|
15
|
+
return [RCTUIImage imageNamed:name];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
static RCTUIImage *_Nullable ENRMImageAtPath(NSString *path)
|
|
19
|
+
{
|
|
20
|
+
if (path.pathExtension.length == 0) {
|
|
21
|
+
path = [path stringByAppendingPathExtension:@"png"];
|
|
22
|
+
}
|
|
23
|
+
#if !TARGET_OS_OSX
|
|
24
|
+
return [RCTUIImage imageWithContentsOfFile:path];
|
|
25
|
+
#else
|
|
26
|
+
return [[RCTUIImage alloc] initWithContentsOfFile:path];
|
|
27
|
+
#endif
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
BOOL ENRMIsLocalImageURL(NSString *url)
|
|
31
|
+
{
|
|
32
|
+
if ([url hasPrefix:@"file://"]) {
|
|
33
|
+
return YES;
|
|
34
|
+
}
|
|
35
|
+
NSURL *parsed = [NSURL URLWithString:url];
|
|
36
|
+
return parsed == nil || parsed.scheme.length == 0;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
RCTUIImage *_Nullable ENRMLoadLocalImage(NSString *url)
|
|
40
|
+
{
|
|
41
|
+
NSString *filePath = nil;
|
|
42
|
+
NSString *imageName = nil;
|
|
43
|
+
|
|
44
|
+
if ([url hasPrefix:@"file://"]) {
|
|
45
|
+
NSURL *fileURL = [NSURL URLWithString:url];
|
|
46
|
+
if (fileURL.fileURL) {
|
|
47
|
+
filePath = @(fileURL.fileSystemRepresentation);
|
|
48
|
+
} else {
|
|
49
|
+
NSString *stripped = [url substringFromIndex:@"file://".length];
|
|
50
|
+
filePath = [stripped stringByRemovingPercentEncoding] ?: stripped;
|
|
51
|
+
}
|
|
52
|
+
imageName = ENRMBundleRelativePath(filePath);
|
|
53
|
+
} else {
|
|
54
|
+
NSString *decoded = [url stringByRemovingPercentEncoding] ?: url;
|
|
55
|
+
if (decoded.absolutePath) {
|
|
56
|
+
filePath = decoded;
|
|
57
|
+
} else {
|
|
58
|
+
imageName = decoded;
|
|
59
|
+
filePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:decoded];
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
RCTUIImage *image = imageName.length > 0 ? ENRMImageNamed(imageName) : nil;
|
|
64
|
+
if (image == nil && filePath.length > 0) {
|
|
65
|
+
image = ENRMImageAtPath(filePath);
|
|
66
|
+
}
|
|
67
|
+
return image;
|
|
68
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
#import "ENRMUIKit.h"
|
|
3
|
+
#import <Foundation/Foundation.h>
|
|
4
|
+
|
|
5
|
+
static const CGFloat kENRMMathFallbackDefaultFontSize = 16.0;
|
|
6
|
+
|
|
7
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
8
|
+
|
|
9
|
+
#ifdef __cplusplus
|
|
10
|
+
extern "C" {
|
|
11
|
+
#endif
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Builds the visible-source fallback for a RaTeX parse failure: the original
|
|
15
|
+
* LaTeX source wrapped in its delimiters ($ inline, $$ block), typeset in body
|
|
16
|
+
* style. A parse failure must never render as an invisible zero-size box —
|
|
17
|
+
* the formula stays visible and copyable instead.
|
|
18
|
+
*/
|
|
19
|
+
NSAttributedString *ENRMMathFallbackString(NSString *_Nullable latex, NSString *delimiter, CGFloat fontSize,
|
|
20
|
+
RCTUIColor *_Nullable color);
|
|
21
|
+
|
|
22
|
+
#ifdef __cplusplus
|
|
23
|
+
}
|
|
24
|
+
#endif
|
|
25
|
+
|
|
26
|
+
NS_ASSUME_NONNULL_END
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#import "ENRMMathFallback.h"
|
|
2
|
+
|
|
3
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
4
|
+
|
|
5
|
+
NSAttributedString *ENRMMathFallbackString(NSString *_Nullable latex, NSString *delimiter, CGFloat fontSize,
|
|
6
|
+
RCTUIColor *_Nullable color)
|
|
7
|
+
{
|
|
8
|
+
CGFloat size = fontSize > 0 ? fontSize : kENRMMathFallbackDefaultFontSize;
|
|
9
|
+
UIFont *font = [UIFont systemFontOfSize:size];
|
|
10
|
+
NSString *source = [NSString stringWithFormat:@"%@%@%@", delimiter, latex ?: @"", delimiter];
|
|
11
|
+
return [[NSAttributedString alloc] initWithString:source
|
|
12
|
+
attributes:@{
|
|
13
|
+
NSFontAttributeName : font,
|
|
14
|
+
NSForegroundColorAttributeName : color ?: [RCTUIColor blackColor],
|
|
15
|
+
}];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
NS_ASSUME_NONNULL_END
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
#import "ENRMUIKit.h"
|
|
3
|
+
|
|
4
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
5
|
+
|
|
6
|
+
/// Keys of an `onSelectionChange` payload. Rects are `NSValue`-wrapped CGRects in
|
|
7
|
+
/// the reporting view's coordinates, so a payload compares with `-isEqual:` for
|
|
8
|
+
/// deduplication.
|
|
9
|
+
extern NSString *const ENRMSelectionActiveKey;
|
|
10
|
+
extern NSString *const ENRMSelectionSourceKey;
|
|
11
|
+
extern NSString *const ENRMSelectionTextKey;
|
|
12
|
+
extern NSString *const ENRMSelectionMarkdownKey;
|
|
13
|
+
extern NSString *const ENRMSelectionWholeKey;
|
|
14
|
+
extern NSString *const ENRMSelectionRectKey;
|
|
15
|
+
extern NSString *const ENRMSelectionStartRectKey;
|
|
16
|
+
extern NSString *const ENRMSelectionEndRectKey;
|
|
17
|
+
extern NSString *const ENRMSelectionAdjustingKey;
|
|
18
|
+
/// Only in `ENRMTextSelectionInTextView` results: whether the range spans the
|
|
19
|
+
/// whole text (same threshold `markdownForRange` uses for the cached markdown).
|
|
20
|
+
extern NSString *const ENRMSelectionFullKey;
|
|
21
|
+
|
|
22
|
+
#ifdef __cplusplus
|
|
23
|
+
extern "C" {
|
|
24
|
+
#endif
|
|
25
|
+
|
|
26
|
+
/// The payload reported once the selection is gone.
|
|
27
|
+
NSDictionary *ENRMInactiveSelectionPayload(void);
|
|
28
|
+
|
|
29
|
+
/// A long-pressed block (table / math / code): `whole`, every rect is `frame`.
|
|
30
|
+
NSDictionary *ENRMBlockSelectionPayload(NSString *source, NSString *markdown, NSString *text, CGRect frame);
|
|
31
|
+
|
|
32
|
+
#if !TARGET_OS_OSX
|
|
33
|
+
/// Text, full-selection flag and rects of `textView`'s selection, converted to
|
|
34
|
+
/// `targetView`'s coordinates; nil when nothing is selected. `rect` is the union
|
|
35
|
+
/// of the selection rects, `startRect` / `endRect` the rects holding its start
|
|
36
|
+
/// and end. The owner adds source, markdown and whole to build the payload.
|
|
37
|
+
NSDictionary *_Nullable ENRMTextSelectionInTextView(UITextView *textView, UIView *targetView);
|
|
38
|
+
#endif
|
|
39
|
+
|
|
40
|
+
#ifdef __cplusplus
|
|
41
|
+
}
|
|
42
|
+
#endif
|
|
43
|
+
|
|
44
|
+
/// Coalesces selection changes into at most one report per run loop turn. The
|
|
45
|
+
/// payload is read when the turn fires, so the latest state always reaches JS;
|
|
46
|
+
/// a cleared selection is reported right away and drops any pending update.
|
|
47
|
+
/// Identical payloads are sent once.
|
|
48
|
+
@interface ENRMSelectionChangeReporter : NSObject
|
|
49
|
+
|
|
50
|
+
- (instancetype)initWithSnapshot:(NSDictionary * (^)(void))snapshot
|
|
51
|
+
emit:(void (^)(NSDictionary *payload))emit NS_DESIGNATED_INITIALIZER;
|
|
52
|
+
- (instancetype)init NS_UNAVAILABLE;
|
|
53
|
+
|
|
54
|
+
/// Off by default. Toggling resets the last reported payload to inactive.
|
|
55
|
+
@property (nonatomic, assign) BOOL enabled;
|
|
56
|
+
|
|
57
|
+
- (void)schedule;
|
|
58
|
+
- (void)selectionChanged:(BOOL)hasSelection;
|
|
59
|
+
- (void)flushNow;
|
|
60
|
+
- (void)cancel;
|
|
61
|
+
/// Makes the next report go out even if it equals the last one — a block
|
|
62
|
+
/// long-pressed again is a new request for the app's menu, not a repeat.
|
|
63
|
+
- (void)forgetLastReported;
|
|
64
|
+
|
|
65
|
+
@end
|
|
66
|
+
|
|
67
|
+
#if !TARGET_OS_OSX
|
|
68
|
+
/// Tells when the user is dragging a selection handle (or holding the loupe).
|
|
69
|
+
/// `UITextView` doesn't call `textViewDidChangeSelection:` during the drag, so
|
|
70
|
+
/// this watches the text view's own selection gestures: every recognizer of
|
|
71
|
+
/// the view and its subviews except scroll, pinch and taps. UIKit adds the
|
|
72
|
+
/// handle recognizers lazily, so call `trackTextView:` again on each selection
|
|
73
|
+
/// change. `change` runs whenever `adjusting` flips.
|
|
74
|
+
@interface ENRMSelectionGestureTracker : NSObject
|
|
75
|
+
|
|
76
|
+
- (instancetype)initWithChange:(void (^)(void))change NS_DESIGNATED_INITIALIZER;
|
|
77
|
+
- (instancetype)init NS_UNAVAILABLE;
|
|
78
|
+
|
|
79
|
+
/// A tracked gesture is in `Began` / `Changed`.
|
|
80
|
+
@property (nonatomic, readonly) BOOL adjusting;
|
|
81
|
+
|
|
82
|
+
- (void)trackTextView:(UITextView *)textView;
|
|
83
|
+
/// Clears `adjusting` without calling `change` (view recycling).
|
|
84
|
+
- (void)reset;
|
|
85
|
+
|
|
86
|
+
@end
|
|
87
|
+
#endif
|
|
88
|
+
|
|
89
|
+
#ifdef __cplusplus
|
|
90
|
+
/// Converts a payload into a codegen `OnSelectionChange` struct. Templated
|
|
91
|
+
/// because each component has its own (structurally identical) event struct.
|
|
92
|
+
template <typename Event> inline Event ENRMSelectionChangeEventFromPayload(NSDictionary *payload)
|
|
93
|
+
{
|
|
94
|
+
Event event;
|
|
95
|
+
event.active = [payload[ENRMSelectionActiveKey] boolValue];
|
|
96
|
+
event.source = std::string([payload[ENRMSelectionSourceKey] UTF8String] ?: "selection");
|
|
97
|
+
event.text = std::string([payload[ENRMSelectionTextKey] UTF8String] ?: "");
|
|
98
|
+
event.markdown = std::string([payload[ENRMSelectionMarkdownKey] UTF8String] ?: "");
|
|
99
|
+
event.whole = [payload[ENRMSelectionWholeKey] boolValue];
|
|
100
|
+
event.adjusting = [payload[ENRMSelectionAdjustingKey] boolValue];
|
|
101
|
+
|
|
102
|
+
auto assign = [](auto &target, NSValue *value) {
|
|
103
|
+
#if TARGET_OS_OSX
|
|
104
|
+
CGRect rect = value ? NSRectToCGRect(value.rectValue) : CGRectZero;
|
|
105
|
+
#else
|
|
106
|
+
CGRect rect = value ? value.CGRectValue : CGRectZero;
|
|
107
|
+
#endif
|
|
108
|
+
target.x = rect.origin.x;
|
|
109
|
+
target.y = rect.origin.y;
|
|
110
|
+
target.width = rect.size.width;
|
|
111
|
+
target.height = rect.size.height;
|
|
112
|
+
};
|
|
113
|
+
assign(event.rect, payload[ENRMSelectionRectKey]);
|
|
114
|
+
assign(event.startRect, payload[ENRMSelectionStartRectKey]);
|
|
115
|
+
assign(event.endRect, payload[ENRMSelectionEndRectKey]);
|
|
116
|
+
return event;
|
|
117
|
+
}
|
|
118
|
+
#endif
|
|
119
|
+
|
|
120
|
+
NS_ASSUME_NONNULL_END
|