react-native-enriched-markdown-scaffold 0.6.0-scaffold.6 → 0.7.4-scaffold.1
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/ReactNativeEnrichedMarkdown.podspec +62 -11
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerDelegate.java +3 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerInterface.java +1 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextInputManagerDelegate.java +9 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextInputManagerInterface.java +3 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerDelegate.java +3 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerInterface.java +1 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.cpp +20 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.h +744 -36
- package/android/src/main/baseline-prof.txt +75 -2
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdown.kt +62 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownInternalText.kt +10 -2
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownManager.kt +10 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownText.kt +9 -2
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextManager.kt +10 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/MeasurementStore.kt +0 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/accessibility/AccessibilityLabels.kt +15 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/accessibility/MarkdownAccessibilityHelper.kt +44 -7
- package/android/src/main/java/com/swmansion/enriched/markdown/input/EnrichedMarkdownTextInputManager.kt +52 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/EnrichedMarkdownTextInputView.kt +55 -3
- package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/FormattingStore.kt +19 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/InputParser.kt +22 -3
- package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/InputRemend.kt +1 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/layout/InputMeasurementStore.kt +7 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MathChipStyle.kt +0 -3
- package/android/src/main/java/com/swmansion/enriched/markdown/input/toolbar/InputContextMenu.kt +54 -13
- package/android/src/main/java/com/swmansion/enriched/markdown/parser/MarkdownASTNode.kt +17 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SpanStyleCache.kt +4 -4
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/MathModels.kt +0 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/InlineMathStyle.kt +1 -3
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/MathStyle.kt +1 -3
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/MarkdownViewManagerUtils.kt +30 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/input/MarkdownStyleParser.kt +0 -14
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/LinkEvents.kt +22 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/SelectionActionMode.kt +36 -7
- package/android/src/main/java/com/swmansion/enriched/markdown/views/TableContainerView.kt +73 -3
- package/android/src/main/jni/CMakeLists.txt +15 -1
- package/android/src/math/java/com/swmansion/enriched/markdown/renderer/MathInlineRenderer.kt +0 -1
- package/android/src/math/java/com/swmansion/enriched/markdown/spans/MathChipSpan.kt +1 -2
- package/android/src/math/java/com/swmansion/enriched/markdown/spans/MathInlineSpan.kt +1 -3
- package/android/src/math/java/com/swmansion/enriched/markdown/spans/MathMeasureHelper.kt +1 -2
- package/android/src/math/java/com/swmansion/enriched/markdown/views/MathContainerView.kt +25 -10
- package/app.plugin.js +2 -1
- package/cpp/parser/MD4CParser.cpp +1 -1
- package/cpp/wasm/build.sh +9 -9
- package/docs/ACCESSIBILITY.md +172 -0
- package/docs/API_REFERENCE.md +948 -0
- package/docs/COPY_OPTIONS.md +127 -0
- package/docs/ELEMENTS_STRUCTURE.md +112 -0
- package/docs/IMAGE_CACHING.md +25 -0
- package/docs/INPUT.md +233 -0
- package/docs/LATEX_MATH.md +136 -0
- package/docs/MACOS.md +19 -0
- package/docs/MARKDOWN_STREAMING.md +36 -0
- package/docs/MENTIONS.md +97 -0
- package/docs/RTL.md +82 -0
- package/docs/STYLES.md +519 -0
- package/docs/TEXT.md +110 -0
- package/docs/WEB.md +49 -0
- package/ios/EnrichedMarkdown.mm +82 -25
- package/ios/EnrichedMarkdownText.mm +37 -5
- package/ios/attachments/ENRMMathInlineAttachment+macOS.m +1 -5
- package/ios/attachments/ENRMMathInlineAttachment.h +0 -3
- package/ios/attachments/ENRMMathInlineAttachment.m +1 -2
- package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.cpp +20 -0
- package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.h +744 -36
- package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/RCTComponentViewHelpers.h +15 -0
- package/ios/input/ENRMFormattingStore.h +5 -0
- package/ios/input/ENRMFormattingStore.mm +34 -0
- package/ios/input/ENRMInputFormatter.h +0 -6
- package/ios/input/ENRMInputFormatter.mm +0 -2
- package/ios/input/ENRMInputTextView.h +2 -0
- package/ios/input/ENRMInputTextView.mm +8 -17
- package/ios/input/ENRMMarkdownSerializer.mm +1 -1
- package/ios/input/EnrichedMarkdownTextInput+ContextMenu.mm +71 -53
- package/ios/input/EnrichedMarkdownTextInput+Internal.h +26 -0
- package/ios/input/EnrichedMarkdownTextInput.h +1 -0
- package/ios/input/EnrichedMarkdownTextInput.mm +207 -12
- package/ios/input/InputStylePropsUtils.h +0 -8
- package/ios/input/styles/ENRMBoldStyleHandler.mm +3 -2
- package/ios/input/styles/ENRMItalicStyleHandler.mm +3 -2
- package/ios/math/ENRMRaTeXBridge.swift +2 -16
- package/ios/renderer/AttributedRenderer.m +51 -6
- package/ios/renderer/ENRMMathInlineRenderer.m +5 -2
- package/ios/styles/ENRMFontSlot.h +1 -1
- package/ios/styles/StyleConfig.h +0 -4
- package/ios/styles/StyleConfig.mm +0 -24
- package/ios/utils/ENRMAccessibilityLabels.h +36 -0
- package/ios/utils/ENRMAccessibilityLabels.m +5 -0
- package/ios/utils/EditMenuUtils+macOS.m +4 -5
- package/ios/utils/EditMenuUtils.h +70 -0
- package/ios/utils/EditMenuUtils.m +14 -11
- package/ios/utils/LastElementUtils.h +39 -2
- package/ios/utils/MarkdownAccessibilityElementBuilder.h +18 -16
- package/ios/utils/MarkdownAccessibilityElementBuilder.m +64 -32
- package/ios/utils/ParagraphStyleUtils.m +21 -2
- package/ios/utils/StylePropsUtils.h +0 -10
- package/ios/views/ENRMMathContainerView.h +8 -0
- package/ios/views/ENRMMathContainerView.m +8 -7
- package/ios/views/ENRMTableIOSGridView.h +40 -0
- package/ios/views/ENRMTableIOSGridView.m +216 -0
- package/ios/views/EnrichedMarkdownInternalText.h +2 -0
- package/ios/views/EnrichedMarkdownInternalText.m +2 -0
- package/ios/views/TableContainerView.h +8 -0
- package/ios/views/TableContainerView.m +72 -128
- package/lib/module/EnrichedMarkdownNativeComponent.ts +37 -2
- package/lib/module/EnrichedMarkdownTextInput.js +48 -1
- package/lib/module/EnrichedMarkdownTextInput.js.map +1 -1
- package/lib/module/EnrichedMarkdownTextInputNativeComponent.ts +35 -1
- package/lib/module/EnrichedMarkdownTextNativeComponent.ts +37 -2
- package/lib/module/accessibilityLabelDefaults.js +64 -0
- package/lib/module/accessibilityLabelDefaults.js.map +1 -0
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/native/EnrichedMarkdownText.js +72 -4
- package/lib/module/native/EnrichedMarkdownText.js.map +1 -1
- package/lib/module/normalizeMarkdownStyle.js +2 -4
- package/lib/module/normalizeMarkdownStyle.js.map +1 -1
- package/lib/module/normalizeMarkdownStyle.web.js +2 -4
- package/lib/module/normalizeMarkdownStyle.web.js.map +1 -1
- package/lib/module/normalizeMarkdownTextInputStyle.js +3 -10
- package/lib/module/normalizeMarkdownTextInputStyle.js.map +1 -1
- package/lib/module/normalizeMenuItem.js +38 -0
- package/lib/module/normalizeMenuItem.js.map +1 -0
- package/lib/module/types/AccessibilityLabels.js +2 -0
- package/lib/module/types/AccessibilityLabels.js.map +1 -0
- package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts +34 -2
- package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/EnrichedMarkdownTextInput.d.ts +55 -13
- package/lib/typescript/src/EnrichedMarkdownTextInput.d.ts.map +1 -1
- package/lib/typescript/src/EnrichedMarkdownTextInputNativeComponent.d.ts +30 -1
- package/lib/typescript/src/EnrichedMarkdownTextInputNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts +34 -2
- package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/accessibilityLabelDefaults.d.ts +16 -0
- package/lib/typescript/src/accessibilityLabelDefaults.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +4 -2
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/native/EnrichedMarkdownText.d.ts +3 -3
- 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 +0 -2
- package/lib/typescript/src/normalizeMarkdownTextInputStyle.d.ts.map +1 -1
- package/lib/typescript/src/normalizeMenuItem.d.ts +7 -0
- package/lib/typescript/src/normalizeMenuItem.d.ts.map +1 -0
- package/lib/typescript/src/types/AccessibilityLabels.d.ts +114 -0
- package/lib/typescript/src/types/AccessibilityLabels.d.ts.map +1 -0
- package/lib/typescript/src/types/MarkdownStyle.d.ts +0 -14
- package/lib/typescript/src/types/MarkdownStyle.d.ts.map +1 -1
- package/lib/typescript/src/types/MarkdownStyleInternal.d.ts +0 -3
- package/lib/typescript/src/types/MarkdownStyleInternal.d.ts.map +1 -1
- package/lib/typescript/src/types/MarkdownTextProps.d.ts +78 -9
- package/lib/typescript/src/types/MarkdownTextProps.d.ts.map +1 -1
- package/package.json +4 -2
- package/plugin/build/withAndroidMath.js +19 -0
- package/plugin/build/withIosMath.js +28 -0
- package/plugin/build/withReactNativeEnrichedMarkdown.js +11 -0
- package/plugin/tsconfig.build.json +16 -0
- package/src/EnrichedMarkdownNativeComponent.ts +37 -2
- package/src/EnrichedMarkdownTextInput.tsx +117 -13
- package/src/EnrichedMarkdownTextInputNativeComponent.ts +35 -1
- package/src/EnrichedMarkdownTextNativeComponent.ts +37 -2
- package/src/accessibilityLabelDefaults.ts +83 -0
- package/src/index.tsx +11 -0
- package/src/native/EnrichedMarkdownText.tsx +120 -6
- package/src/normalizeMarkdownStyle.ts +1 -6
- package/src/normalizeMarkdownStyle.web.ts +1 -6
- package/src/normalizeMarkdownTextInputStyle.ts +0 -14
- package/src/normalizeMenuItem.ts +52 -0
- package/src/types/AccessibilityLabels.ts +118 -0
- package/src/types/MarkdownStyle.ts +0 -14
- package/src/types/MarkdownStyleInternal.ts +0 -4
- package/src/types/MarkdownTextProps.ts +74 -9
- package/android/src/math/java/com/swmansion/enriched/markdown/utils/math/LatexWeightWrapper.kt +0 -23
- package/lib/module/plugin/withAndroidMath.js +0 -20
- package/lib/module/plugin/withAndroidMath.js.map +0 -1
- package/lib/module/plugin/withIosMath.js +0 -23
- package/lib/module/plugin/withIosMath.js.map +0 -1
- package/lib/module/plugin/withReactNativeEnrichedMarkdown.js +0 -16
- package/lib/module/plugin/withReactNativeEnrichedMarkdown.js.map +0 -1
- package/lib/typescript/src/plugin/withAndroidMath.d.ts +0 -5
- package/lib/typescript/src/plugin/withAndroidMath.d.ts.map +0 -1
- package/lib/typescript/src/plugin/withIosMath.d.ts +0 -5
- package/lib/typescript/src/plugin/withIosMath.d.ts.map +0 -1
- package/lib/typescript/src/plugin/withReactNativeEnrichedMarkdown.d.ts +0 -6
- package/lib/typescript/src/plugin/withReactNativeEnrichedMarkdown.d.ts.map +0 -1
- /package/{src/plugin → plugin/src}/withAndroidMath.ts +0 -0
- /package/{src/plugin → plugin/src}/withIosMath.ts +0 -0
- /package/{src/plugin → plugin/src}/withReactNativeEnrichedMarkdown.ts +0 -0
|
@@ -20,9 +20,12 @@
|
|
|
20
20
|
#import "ENRMStyleMergingConfig.h"
|
|
21
21
|
#import "ENRMUIKit.h"
|
|
22
22
|
#import "ENRMWordsUtils.h"
|
|
23
|
+
#import "EnrichedMarkdownTextInput+Internal.h"
|
|
23
24
|
#import "InputStylePropsUtils.h"
|
|
24
25
|
#import "ParagraphStyleUtils.h"
|
|
26
|
+
#import "PasteboardUtils.h"
|
|
25
27
|
#import "SelectionColorUtils.h"
|
|
28
|
+
#import <QuartzCore/CABase.h>
|
|
26
29
|
#import <React/RCTI18nUtil.h>
|
|
27
30
|
#if TARGET_OS_OSX
|
|
28
31
|
#import <React/RCTBackedTextInputDelegate.h>
|
|
@@ -41,7 +44,8 @@
|
|
|
41
44
|
using namespace facebook::react;
|
|
42
45
|
|
|
43
46
|
#if !TARGET_OS_OSX
|
|
44
|
-
@interface EnrichedMarkdownTextInput () <RCTEnrichedMarkdownTextInputViewProtocol, UITextViewDelegate
|
|
47
|
+
@interface EnrichedMarkdownTextInput () <RCTEnrichedMarkdownTextInputViewProtocol, UITextViewDelegate,
|
|
48
|
+
UIGestureRecognizerDelegate>
|
|
45
49
|
#else
|
|
46
50
|
@interface EnrichedMarkdownTextInput () <RCTEnrichedMarkdownTextInputViewProtocol, RCTBackedTextInputDelegate>
|
|
47
51
|
#endif
|
|
@@ -64,6 +68,7 @@ using namespace facebook::react;
|
|
|
64
68
|
BOOL _isApplyingFormatting;
|
|
65
69
|
BOOL _isTextChanging;
|
|
66
70
|
BOOL _emitMarkdown;
|
|
71
|
+
CFTimeInterval _lastTextChangeTime;
|
|
67
72
|
|
|
68
73
|
ENRMPlaceholderLabel *_placeholderLabel;
|
|
69
74
|
|
|
@@ -101,6 +106,20 @@ using namespace facebook::react;
|
|
|
101
106
|
BOOL _suppressMathChipClearOnce;
|
|
102
107
|
/// Character index of the currently selected math chip, or NSNotFound.
|
|
103
108
|
NSUInteger _activeMathChipIndex;
|
|
109
|
+
|
|
110
|
+
ENRMInputSelectionMenuConfig _inputSelectionMenuConfig;
|
|
111
|
+
ENRMFormatMenuConfig _formatMenuConfig;
|
|
112
|
+
|
|
113
|
+
// Strong owners for the strings the two config structs above reference via
|
|
114
|
+
// `__unsafe_unretained` pointers.
|
|
115
|
+
NSString *_inputSelectionMenuFormatLabel;
|
|
116
|
+
NSString *_inputSelectionMenuCopyAsMarkdownLabel;
|
|
117
|
+
NSString *_formatMenuBoldLabel;
|
|
118
|
+
NSString *_formatMenuItalicLabel;
|
|
119
|
+
NSString *_formatMenuUnderlineLabel;
|
|
120
|
+
NSString *_formatMenuStrikethroughLabel;
|
|
121
|
+
NSString *_formatMenuSpoilerLabel;
|
|
122
|
+
NSString *_formatMenuLinkLabel;
|
|
104
123
|
}
|
|
105
124
|
|
|
106
125
|
#pragma mark - Fabric lifecycle
|
|
@@ -138,6 +157,9 @@ using namespace facebook::react;
|
|
|
138
157
|
_writingDirectionMode = ENRMWritingDirectionModeFirstStrong;
|
|
139
158
|
_resolvedLayoutDirection =
|
|
140
159
|
[[RCTI18nUtil sharedInstance] isRTL] ? NSWritingDirectionRightToLeft : NSWritingDirectionLeftToRight;
|
|
160
|
+
_inputSelectionMenuConfig = (ENRMInputSelectionMenuConfig){.format = YES, .copyAsMarkdown = YES};
|
|
161
|
+
_formatMenuConfig = (ENRMFormatMenuConfig){
|
|
162
|
+
.bold = YES, .italic = YES, .underline = YES, .strikethrough = YES, .spoiler = YES, .link = YES};
|
|
141
163
|
|
|
142
164
|
_suppressMathChipClearOnce = NO;
|
|
143
165
|
_activeMathChipIndex = NSNotFound;
|
|
@@ -222,6 +244,9 @@ using namespace facebook::react;
|
|
|
222
244
|
UITapGestureRecognizer *mathTap = [[UITapGestureRecognizer alloc] initWithTarget:self
|
|
223
245
|
action:@selector(handleTapForMathChip:)];
|
|
224
246
|
mathTap.cancelsTouchesInView = NO;
|
|
247
|
+
mathTap.delaysTouchesBegan = NO;
|
|
248
|
+
mathTap.delaysTouchesEnded = NO;
|
|
249
|
+
mathTap.delegate = self;
|
|
225
250
|
[_textView addGestureRecognizer:mathTap];
|
|
226
251
|
#endif
|
|
227
252
|
}
|
|
@@ -459,6 +484,44 @@ using namespace facebook::react;
|
|
|
459
484
|
_contextMenuItemIcons = ENRMContextMenuIconsFromItems(newViewProps.contextMenuItems);
|
|
460
485
|
}
|
|
461
486
|
|
|
487
|
+
// Coalesce against `initWithUTF8String:` returning nil on malformed UTF-8 —
|
|
488
|
+
// UIMenu / UIAction / NSMenuItem titles are _Nonnull and would crash.
|
|
489
|
+
_inputSelectionMenuFormatLabel =
|
|
490
|
+
[[NSString alloc] initWithUTF8String:newViewProps.selectionMenuConfig.formatLabel.c_str()] ?: @"";
|
|
491
|
+
_inputSelectionMenuCopyAsMarkdownLabel =
|
|
492
|
+
[[NSString alloc] initWithUTF8String:newViewProps.selectionMenuConfig.copyAsMarkdownLabel.c_str()] ?: @"";
|
|
493
|
+
_inputSelectionMenuConfig = (ENRMInputSelectionMenuConfig){
|
|
494
|
+
.format = newViewProps.selectionMenuConfig.format,
|
|
495
|
+
.formatLabel = _inputSelectionMenuFormatLabel,
|
|
496
|
+
.copyAsMarkdown = newViewProps.selectionMenuConfig.copyAsMarkdown,
|
|
497
|
+
.copyAsMarkdownLabel = _inputSelectionMenuCopyAsMarkdownLabel,
|
|
498
|
+
};
|
|
499
|
+
|
|
500
|
+
_formatMenuBoldLabel = [[NSString alloc] initWithUTF8String:newViewProps.formatMenuConfig.boldLabel.c_str()] ?: @"";
|
|
501
|
+
_formatMenuItalicLabel =
|
|
502
|
+
[[NSString alloc] initWithUTF8String:newViewProps.formatMenuConfig.italicLabel.c_str()] ?: @"";
|
|
503
|
+
_formatMenuUnderlineLabel =
|
|
504
|
+
[[NSString alloc] initWithUTF8String:newViewProps.formatMenuConfig.underlineLabel.c_str()] ?: @"";
|
|
505
|
+
_formatMenuStrikethroughLabel =
|
|
506
|
+
[[NSString alloc] initWithUTF8String:newViewProps.formatMenuConfig.strikethroughLabel.c_str()] ?: @"";
|
|
507
|
+
_formatMenuSpoilerLabel =
|
|
508
|
+
[[NSString alloc] initWithUTF8String:newViewProps.formatMenuConfig.spoilerLabel.c_str()] ?: @"";
|
|
509
|
+
_formatMenuLinkLabel = [[NSString alloc] initWithUTF8String:newViewProps.formatMenuConfig.linkLabel.c_str()] ?: @"";
|
|
510
|
+
_formatMenuConfig = (ENRMFormatMenuConfig){
|
|
511
|
+
.bold = newViewProps.formatMenuConfig.bold,
|
|
512
|
+
.boldLabel = _formatMenuBoldLabel,
|
|
513
|
+
.italic = newViewProps.formatMenuConfig.italic,
|
|
514
|
+
.italicLabel = _formatMenuItalicLabel,
|
|
515
|
+
.underline = newViewProps.formatMenuConfig.underline,
|
|
516
|
+
.underlineLabel = _formatMenuUnderlineLabel,
|
|
517
|
+
.strikethrough = newViewProps.formatMenuConfig.strikethrough,
|
|
518
|
+
.strikethroughLabel = _formatMenuStrikethroughLabel,
|
|
519
|
+
.spoiler = newViewProps.formatMenuConfig.spoiler,
|
|
520
|
+
.spoilerLabel = _formatMenuSpoilerLabel,
|
|
521
|
+
.link = newViewProps.formatMenuConfig.link,
|
|
522
|
+
.linkLabel = _formatMenuLinkLabel,
|
|
523
|
+
};
|
|
524
|
+
|
|
462
525
|
if (newViewProps.mentionIndicators != oldViewProps.mentionIndicators) {
|
|
463
526
|
NSMutableArray<NSString *> *indicators = [NSMutableArray array];
|
|
464
527
|
for (const auto &indicator : newViewProps.mentionIndicators) {
|
|
@@ -592,6 +655,14 @@ using namespace facebook::react;
|
|
|
592
655
|
[_textView mouseDown:event];
|
|
593
656
|
}
|
|
594
657
|
|
|
658
|
+
#else // iOS
|
|
659
|
+
|
|
660
|
+
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
|
|
661
|
+
shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
|
|
662
|
+
{
|
|
663
|
+
return YES;
|
|
664
|
+
}
|
|
665
|
+
|
|
595
666
|
#endif
|
|
596
667
|
|
|
597
668
|
#if !TARGET_OS_OSX
|
|
@@ -683,7 +754,6 @@ using namespace facebook::react;
|
|
|
683
754
|
att.blockAlignment = _formatterStyle.mathBlockAlignment;
|
|
684
755
|
att.selectedBackgroundColor = _formatterStyle.mathBlockSelectedBackgroundColor;
|
|
685
756
|
att.selectedBorderColor = _formatterStyle.mathBlockSelectedBorderColor;
|
|
686
|
-
att.fontWeight = _formatterStyle.mathBlockFontWeight;
|
|
687
757
|
} else {
|
|
688
758
|
att.fontSize = _formatterStyle.mathFontSize > 0 ? _formatterStyle.mathFontSize : 16.0;
|
|
689
759
|
att.mathTextColor = _formatterStyle.mathColor ?: _formatterStyle.baseTextColor;
|
|
@@ -698,7 +768,6 @@ using namespace facebook::react;
|
|
|
698
768
|
att.blockAlignment = NSTextAlignmentNatural;
|
|
699
769
|
att.selectedBackgroundColor = _formatterStyle.mathSelectedBackgroundColor;
|
|
700
770
|
att.selectedBorderColor = _formatterStyle.mathSelectedBorderColor;
|
|
701
|
-
att.fontWeight = _formatterStyle.mathFontWeight;
|
|
702
771
|
}
|
|
703
772
|
}
|
|
704
773
|
|
|
@@ -954,6 +1023,7 @@ using namespace facebook::react;
|
|
|
954
1023
|
}
|
|
955
1024
|
|
|
956
1025
|
[self applyFormatting];
|
|
1026
|
+
[self syncTypingAttributesWithPendingStyles];
|
|
957
1027
|
[self emitFormattingChanged];
|
|
958
1028
|
}
|
|
959
1029
|
|
|
@@ -1211,6 +1281,21 @@ using namespace facebook::react;
|
|
|
1211
1281
|
return [ENRMMarkdownSerializer serializeAttributedString:selectedAttr ranges:clippedRanges];
|
|
1212
1282
|
}
|
|
1213
1283
|
|
|
1284
|
+
- (void)copyToClipboard
|
|
1285
|
+
{
|
|
1286
|
+
NSString *plainText = ENRMGetPlainText(_textView);
|
|
1287
|
+
if (plainText.length == 0) {
|
|
1288
|
+
return;
|
|
1289
|
+
}
|
|
1290
|
+
NSString *markdown = [ENRMMarkdownSerializer serializePlainText:plainText ranges:[self allRangesIncludingTransient]];
|
|
1291
|
+
NSMutableDictionary *items = [NSMutableDictionary dictionary];
|
|
1292
|
+
items[kUTIPlainText] = plainText;
|
|
1293
|
+
if (markdown.length > 0) {
|
|
1294
|
+
items[kENRMMarkdownPasteboardType] = markdown;
|
|
1295
|
+
}
|
|
1296
|
+
copyItemsToPasteboard(items);
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1214
1299
|
- (void)requestMarkdown:(NSInteger)requestId
|
|
1215
1300
|
{
|
|
1216
1301
|
auto emitter = [self getEventEmitter];
|
|
@@ -1283,6 +1368,57 @@ using namespace facebook::react;
|
|
|
1283
1368
|
return inRange;
|
|
1284
1369
|
}
|
|
1285
1370
|
|
|
1371
|
+
- (void)syncTypingAttributesWithPendingStyles
|
|
1372
|
+
{
|
|
1373
|
+
UIFontDescriptorSymbolicTraits traits = 0;
|
|
1374
|
+
if ([_pendingStyles containsObject:@(ENRMInputStyleTypeStrong)]) {
|
|
1375
|
+
traits |= UIFontDescriptorTraitBold;
|
|
1376
|
+
}
|
|
1377
|
+
if ([_pendingStyles containsObject:@(ENRMInputStyleTypeEmphasis)]) {
|
|
1378
|
+
traits |= UIFontDescriptorTraitItalic;
|
|
1379
|
+
}
|
|
1380
|
+
|
|
1381
|
+
NSMutableDictionary *attrs = [_textView.typingAttributes mutableCopy];
|
|
1382
|
+
attrs[NSFontAttributeName] = [_formatterStyle fontForTraits:traits];
|
|
1383
|
+
_textView.typingAttributes = attrs;
|
|
1384
|
+
}
|
|
1385
|
+
|
|
1386
|
+
- (void)resetPendingStylesForSelectionChange
|
|
1387
|
+
{
|
|
1388
|
+
// Skip system-driven selection adjustments (e.g., predictive text) that fire
|
|
1389
|
+
// immediately after a text edit.
|
|
1390
|
+
static const CFTimeInterval kPostEditGracePeriod = 0.1;
|
|
1391
|
+
BOOL isPostEditAdjustment =
|
|
1392
|
+
(_lastTextChangeTime > 0 && (CACurrentMediaTime() - _lastTextChangeTime) < kPostEditGracePeriod);
|
|
1393
|
+
if (isPostEditAdjustment) {
|
|
1394
|
+
return;
|
|
1395
|
+
}
|
|
1396
|
+
[_pendingStyles removeAllObjects];
|
|
1397
|
+
[_pendingStyleRemovals removeAllObjects];
|
|
1398
|
+
[self rebuildPendingStylesFromContext];
|
|
1399
|
+
[self syncTypingAttributesWithPendingStyles];
|
|
1400
|
+
}
|
|
1401
|
+
|
|
1402
|
+
- (void)rebuildPendingStylesFromContext
|
|
1403
|
+
{
|
|
1404
|
+
NSUInteger cursor = _textView.selectedRange.location;
|
|
1405
|
+
if (_textView.selectedRange.length > 0 || cursor == 0) {
|
|
1406
|
+
return;
|
|
1407
|
+
}
|
|
1408
|
+
|
|
1409
|
+
static const ENRMInputStyleType inlineStyles[] = {
|
|
1410
|
+
ENRMInputStyleTypeStrong, ENRMInputStyleTypeEmphasis, ENRMInputStyleTypeUnderline,
|
|
1411
|
+
ENRMInputStyleTypeStrikethrough, ENRMInputStyleTypeSpoiler,
|
|
1412
|
+
};
|
|
1413
|
+
|
|
1414
|
+
for (NSUInteger i = 0; i < sizeof(inlineStyles) / sizeof(inlineStyles[0]); i++) {
|
|
1415
|
+
ENRMInputStyleType type = inlineStyles[i];
|
|
1416
|
+
if ([_formattingStore isStyleAdjacentBefore:type position:cursor]) {
|
|
1417
|
+
[_pendingStyles addObject:@(type)];
|
|
1418
|
+
}
|
|
1419
|
+
}
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1286
1422
|
#pragma mark - Event emitters
|
|
1287
1423
|
|
|
1288
1424
|
- (void)emitFormattingChanged
|
|
@@ -1521,6 +1657,16 @@ using namespace facebook::react;
|
|
|
1521
1657
|
return _contextMenuItemIcons ?: @[];
|
|
1522
1658
|
}
|
|
1523
1659
|
|
|
1660
|
+
- (ENRMInputSelectionMenuConfig)inputSelectionMenuConfig
|
|
1661
|
+
{
|
|
1662
|
+
return _inputSelectionMenuConfig;
|
|
1663
|
+
}
|
|
1664
|
+
|
|
1665
|
+
- (ENRMFormatMenuConfig)formatMenuConfig
|
|
1666
|
+
{
|
|
1667
|
+
return _formatMenuConfig;
|
|
1668
|
+
}
|
|
1669
|
+
|
|
1524
1670
|
- (void)emitContextMenuItemPress:(NSString *)itemText
|
|
1525
1671
|
{
|
|
1526
1672
|
auto eventEmitter = [self getEventEmitter];
|
|
@@ -1664,10 +1810,27 @@ using namespace facebook::react;
|
|
|
1664
1810
|
if (insertedLength > 0) {
|
|
1665
1811
|
NSRange insertedRange = NSMakeRange(editLocation, insertedLength);
|
|
1666
1812
|
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1813
|
+
// Skip applying pending styles when the insertion is only line breaks —
|
|
1814
|
+
// a phantom range over a bare newline corrupts isStyleActive() at the boundary.
|
|
1815
|
+
NSString *plainText = ENRMGetPlainText(_textView);
|
|
1816
|
+
NSUInteger insertedEnd = NSMaxRange(insertedRange);
|
|
1817
|
+
BOOL insertedHasGlyphContent = NO;
|
|
1818
|
+
if (insertedEnd <= plainText.length) {
|
|
1819
|
+
NSCharacterSet *newlines = [NSCharacterSet newlineCharacterSet];
|
|
1820
|
+
for (NSUInteger i = insertedRange.location; i < insertedEnd; i++) {
|
|
1821
|
+
if (![newlines characterIsMember:[plainText characterAtIndex:i]]) {
|
|
1822
|
+
insertedHasGlyphContent = YES;
|
|
1823
|
+
break;
|
|
1824
|
+
}
|
|
1825
|
+
}
|
|
1826
|
+
}
|
|
1827
|
+
|
|
1828
|
+
if (insertedHasGlyphContent) {
|
|
1829
|
+
for (NSNumber *styleNum in _pendingStyles) {
|
|
1830
|
+
ENRMFormattingRange *newRange = [ENRMFormattingRange rangeWithType:(ENRMInputStyleType)styleNum.integerValue
|
|
1831
|
+
range:insertedRange];
|
|
1832
|
+
[_formattingStore addRange:newRange];
|
|
1833
|
+
}
|
|
1671
1834
|
}
|
|
1672
1835
|
|
|
1673
1836
|
// adjustForEditAtLocation may have expanded an existing range to cover
|
|
@@ -1771,6 +1934,7 @@ using namespace facebook::react;
|
|
|
1771
1934
|
}
|
|
1772
1935
|
[self handleTextChanged];
|
|
1773
1936
|
_isTextChanging = NO;
|
|
1937
|
+
_lastTextChangeTime = CACurrentMediaTime();
|
|
1774
1938
|
_lastSelectedRange = textView.selectedRange;
|
|
1775
1939
|
}
|
|
1776
1940
|
|
|
@@ -1788,6 +1952,15 @@ using namespace facebook::react;
|
|
|
1788
1952
|
- (void)textViewDidChangeSelection:(UITextView *)textView
|
|
1789
1953
|
{
|
|
1790
1954
|
NSRange newSelection = textView.selectedRange;
|
|
1955
|
+
// Links (e.g. mentions) are atomic: snap a partial selection to the whole link, and a caret inside
|
|
1956
|
+
// a link to its end. Returning hands the adjusted selection to the recursive change (no double emit).
|
|
1957
|
+
if (!_isApplyingFormatting && !_isTextChanging && !ENRMHasMarkedText(_textView)) {
|
|
1958
|
+
NSRange adjusted = [_formattingStore selectionAdjustedForAtomicLinks:newSelection];
|
|
1959
|
+
if (!NSEqualRanges(adjusted, newSelection)) {
|
|
1960
|
+
_textView.selectedRange = adjusted;
|
|
1961
|
+
return;
|
|
1962
|
+
}
|
|
1963
|
+
}
|
|
1791
1964
|
NSRange previousSelection = _lastSelectedRange;
|
|
1792
1965
|
_lastSelectedRange = newSelection;
|
|
1793
1966
|
|
|
@@ -1795,6 +1968,10 @@ using namespace facebook::react;
|
|
|
1795
1968
|
return;
|
|
1796
1969
|
}
|
|
1797
1970
|
|
|
1971
|
+
if (ENRMHasMarkedText(_textView)) {
|
|
1972
|
+
return;
|
|
1973
|
+
}
|
|
1974
|
+
|
|
1798
1975
|
#if ENRICHED_MARKDOWN_MATH
|
|
1799
1976
|
if (_suppressMathChipClearOnce) {
|
|
1800
1977
|
// Caret update was triggered by handleTapForMathChip — keep that chip
|
|
@@ -1810,8 +1987,7 @@ using namespace facebook::react;
|
|
|
1810
1987
|
newSelection.location != previousSelection.location || newSelection.length != previousSelection.length;
|
|
1811
1988
|
|
|
1812
1989
|
if (selectionMoved) {
|
|
1813
|
-
[
|
|
1814
|
-
[_pendingStyleRemovals removeAllObjects];
|
|
1990
|
+
[self resetPendingStylesForSelectionChange];
|
|
1815
1991
|
}
|
|
1816
1992
|
|
|
1817
1993
|
[self manageSelectionBasedChanges];
|
|
@@ -1918,19 +2094,38 @@ using namespace facebook::react;
|
|
|
1918
2094
|
}
|
|
1919
2095
|
[self handleTextChanged];
|
|
1920
2096
|
_isTextChanging = NO;
|
|
2097
|
+
_lastTextChangeTime = CACurrentMediaTime();
|
|
1921
2098
|
_lastSelectedRange = _textView.selectedRange;
|
|
1922
2099
|
}
|
|
1923
2100
|
|
|
1924
2101
|
- (void)textInputDidChangeSelection
|
|
1925
2102
|
{
|
|
1926
|
-
|
|
2103
|
+
NSRange newSelection = _textView.selectedRange;
|
|
2104
|
+
// Atomic link snapping — same logic as textViewDidChangeSelection: (iOS).
|
|
2105
|
+
if (!_isApplyingFormatting && !_isTextChanging && !ENRMHasMarkedText(_textView)) {
|
|
2106
|
+
NSRange adjusted = [_formattingStore selectionAdjustedForAtomicLinks:newSelection];
|
|
2107
|
+
if (!NSEqualRanges(adjusted, newSelection)) {
|
|
2108
|
+
_textView.selectedRange = adjusted;
|
|
2109
|
+
return;
|
|
2110
|
+
}
|
|
2111
|
+
}
|
|
2112
|
+
NSRange previousSelection = _lastSelectedRange;
|
|
2113
|
+
_lastSelectedRange = newSelection;
|
|
1927
2114
|
|
|
1928
2115
|
if (_isApplyingFormatting || _isTextChanging) {
|
|
1929
2116
|
return;
|
|
1930
2117
|
}
|
|
1931
2118
|
|
|
1932
|
-
|
|
1933
|
-
|
|
2119
|
+
if (ENRMHasMarkedText(_textView)) {
|
|
2120
|
+
return;
|
|
2121
|
+
}
|
|
2122
|
+
|
|
2123
|
+
BOOL selectionMoved =
|
|
2124
|
+
newSelection.location != previousSelection.location || newSelection.length != previousSelection.length;
|
|
2125
|
+
|
|
2126
|
+
if (selectionMoved) {
|
|
2127
|
+
[self resetPendingStylesForSelectionChange];
|
|
2128
|
+
}
|
|
1934
2129
|
|
|
1935
2130
|
[self emitOnChangeSelection];
|
|
1936
2131
|
[self updateActiveMention];
|
|
@@ -187,10 +187,6 @@ BOOL applyInputStyleProps(ENRMInputFormatterStyle *style, const InputProps &newP
|
|
|
187
187
|
style.mathSelectedBorderColor = (sbc && CGColorGetAlpha(sbc.CGColor) > 0) ? sbc : nil;
|
|
188
188
|
changed = YES;
|
|
189
189
|
}
|
|
190
|
-
if (newProps.markdownStyle.math.fontWeight != oldProps.markdownStyle.math.fontWeight) {
|
|
191
|
-
style.mathFontWeight = @(newProps.markdownStyle.math.fontWeight.c_str());
|
|
192
|
-
changed = YES;
|
|
193
|
-
}
|
|
194
190
|
|
|
195
191
|
// Math block (`$$...$$`)
|
|
196
192
|
if (newProps.markdownStyle.mathBlock.color != oldProps.markdownStyle.mathBlock.color) {
|
|
@@ -260,10 +256,6 @@ BOOL applyInputStyleProps(ENRMInputFormatterStyle *style, const InputProps &newP
|
|
|
260
256
|
}
|
|
261
257
|
changed = YES;
|
|
262
258
|
}
|
|
263
|
-
if (newProps.markdownStyle.mathBlock.fontWeight != oldProps.markdownStyle.mathBlock.fontWeight) {
|
|
264
|
-
style.mathBlockFontWeight = @(newProps.markdownStyle.mathBlock.fontWeight.c_str());
|
|
265
|
-
changed = YES;
|
|
266
|
-
}
|
|
267
259
|
|
|
268
260
|
return changed;
|
|
269
261
|
}
|
|
@@ -22,8 +22,9 @@
|
|
|
22
22
|
formattingRange:(ENRMFormattingRange *)formattingRange
|
|
23
23
|
style:(ENRMInputFormatterStyle *)style
|
|
24
24
|
{
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
if (style.boldColor) {
|
|
26
|
+
[storage addAttribute:NSForegroundColorAttributeName value:style.boldColor range:range];
|
|
27
|
+
}
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
@end
|
|
@@ -22,8 +22,9 @@
|
|
|
22
22
|
formattingRange:(ENRMFormattingRange *)formattingRange
|
|
23
23
|
style:(ENRMInputFormatterStyle *)style
|
|
24
24
|
{
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
if (style.italicColor) {
|
|
26
|
+
[storage addAttribute:NSForegroundColorAttributeName value:style.italicColor range:range];
|
|
27
|
+
}
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
@end
|
|
@@ -39,29 +39,15 @@ public final class ENRMRaTeXBridge: NSObject {
|
|
|
39
39
|
RaTeXFontLoader.ensureLoaded()
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
/// Wraps a raw LaTeX expression with the appropriate KaTeX bold command so
|
|
43
|
-
/// RaTeX picks up the bold glyph variant (KaTeX_Main-Bold). Render-time only
|
|
44
|
-
/// — callers keep the original `latex` on attachments so serialized markdown
|
|
45
|
-
/// round-trips cleanly.
|
|
46
|
-
///
|
|
47
|
-
/// Caveat: large operators (`\sum`, `\int`), AMS symbols and Script/Typewriter
|
|
48
|
-
/// glyphs have no bold variant in the bundled KaTeX fonts and stay regular
|
|
49
|
-
/// even when wrapped.
|
|
50
|
-
private static func wrapWeight(_ latex: String, fontWeight: String?) -> String {
|
|
51
|
-
return fontWeight == "bold" ? "\\mathbf{\(latex)}" : latex
|
|
52
|
-
}
|
|
53
|
-
|
|
54
42
|
@objc public static func parse(
|
|
55
43
|
_ latex: String,
|
|
56
44
|
displayMode: Bool,
|
|
57
45
|
fontSize: CGFloat,
|
|
58
|
-
color: UIColor
|
|
59
|
-
fontWeight: String?
|
|
46
|
+
color: UIColor
|
|
60
47
|
) -> ENRMRaTeXRenderResult? {
|
|
61
48
|
RaTeXFontLoader.ensureLoaded()
|
|
62
49
|
do {
|
|
63
|
-
let
|
|
64
|
-
let displayList = try RaTeXEngine.shared.parse(wrapped, displayMode: displayMode, color: color)
|
|
50
|
+
let displayList = try RaTeXEngine.shared.parse(latex, displayMode: displayMode, color: color)
|
|
65
51
|
let renderer = RaTeXRenderer(displayList: displayList, fontSize: fontSize)
|
|
66
52
|
return ENRMRaTeXRenderResult(renderer: renderer)
|
|
67
53
|
} catch {
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
#import "LastElementUtils.h"
|
|
4
4
|
#import "MarkdownASTNode.h"
|
|
5
5
|
#import "NodeRenderer.h"
|
|
6
|
+
#import "ParagraphStyleUtils.h"
|
|
6
7
|
#import "RenderContext.h"
|
|
7
8
|
#import "RendererFactory.h"
|
|
8
9
|
#import "StyleConfig.h"
|
|
@@ -58,7 +59,32 @@
|
|
|
58
59
|
return output;
|
|
59
60
|
}
|
|
60
61
|
|
|
61
|
-
|
|
62
|
+
/**
|
|
63
|
+
* Trims trailing newlines after the last rendered block, with special handling for code blocks.
|
|
64
|
+
*
|
|
65
|
+
* For non-code-block tail elements: deletes all trailing newlines after the last non-newline
|
|
66
|
+
* character and zeroes the last element's paragraph spacing so it doesn't render a margin past
|
|
67
|
+
* the content.
|
|
68
|
+
*
|
|
69
|
+
* For code blocks (`isLastBlockACodeBlock` == YES): keeps the bottom padding spacer in place
|
|
70
|
+
* AND preserves a single trailing newline immediately after it (typically the
|
|
71
|
+
* codeBlockMarginBottom spacer that CodeBlockRenderer already appended; if none exists, one is
|
|
72
|
+
* synthesized here). That extra newline matters because of an iOS layout quirk:
|
|
73
|
+
*
|
|
74
|
+
* - iOS treats the trailing `\n` of the storage as a paragraph terminator and reports the
|
|
75
|
+
* line fragment for the paragraph after it via `extraLineFragmentRect`.
|
|
76
|
+
* - `boundingRectForGlyphRange:` excludes that extra line, and the graphics-context clip
|
|
77
|
+
* passed to `drawBackgroundForGlyphRange:` is tiled to the laid-out content area (rounded
|
|
78
|
+
* up to 128pt boundaries) which also excludes it.
|
|
79
|
+
* - If the bottom padding spacer were the trailing `\n`, its 16/19pt line fragment would
|
|
80
|
+
* fall into that excluded zone — the background rect would have to be manually extended
|
|
81
|
+
* past the clip and the bottom rounded corner would get sliced off at the tile boundary
|
|
82
|
+
* (the original visual bug in #354).
|
|
83
|
+
*
|
|
84
|
+
* By keeping a 1pt-tall tail newline beyond the bottom padding spacer, iOS lays the spacer
|
|
85
|
+
* out as a normal interior line fragment included in usedRect/boundingRect and inside the
|
|
86
|
+
* drawing tiles, so the corner renders intact and no rect extension is needed.
|
|
87
|
+
*/
|
|
62
88
|
- (void)removeTrailingSpacing:(NSMutableAttributedString *)output
|
|
63
89
|
{
|
|
64
90
|
if (output.length == 0)
|
|
@@ -83,17 +109,36 @@
|
|
|
83
109
|
|
|
84
110
|
// 2. Trim trailing characters
|
|
85
111
|
NSUInteger logicalEnd = NSMaxRange(lastContent);
|
|
86
|
-
BOOL isCodeBlock =
|
|
112
|
+
BOOL isCodeBlock = isLastBlockACodeBlock(output);
|
|
113
|
+
NSRange codeRange = NSMakeRange(0, 0);
|
|
87
114
|
if (isCodeBlock) {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
115
|
+
[output attribute:CodeBlockAttributeName
|
|
116
|
+
atIndex:lastContent.location
|
|
117
|
+
longestEffectiveRange:&codeRange
|
|
118
|
+
inRange:NSMakeRange(0, output.length)];
|
|
119
|
+
NSUInteger codeEnd = NSMaxRange(codeRange);
|
|
120
|
+
if (codeEnd >= output.length) {
|
|
121
|
+
[output appendAttributedString:kNewlineAttributedString];
|
|
122
|
+
}
|
|
123
|
+
logicalEnd = codeEnd + 1;
|
|
91
124
|
}
|
|
92
125
|
|
|
93
126
|
if (logicalEnd < output.length) {
|
|
94
127
|
[output deleteCharactersInRange:NSMakeRange(logicalEnd, output.length - logicalEnd)];
|
|
95
128
|
}
|
|
96
129
|
|
|
130
|
+
if (isCodeBlock && NSMaxRange(codeRange) < output.length) {
|
|
131
|
+
NSUInteger tailIdx = NSMaxRange(codeRange);
|
|
132
|
+
[output removeAttribute:CodeBlockAttributeName range:NSMakeRange(tailIdx, 1)];
|
|
133
|
+
NSParagraphStyle *style = [output attribute:NSParagraphStyleAttributeName atIndex:tailIdx effectiveRange:NULL];
|
|
134
|
+
NSMutableParagraphStyle *mutableStyle = style ? [style mutableCopy] : [[NSMutableParagraphStyle alloc] init];
|
|
135
|
+
mutableStyle.paragraphSpacing = 0;
|
|
136
|
+
mutableStyle.paragraphSpacingBefore = 0;
|
|
137
|
+
mutableStyle.minimumLineHeight = 1;
|
|
138
|
+
mutableStyle.maximumLineHeight = 1;
|
|
139
|
+
[output addAttribute:NSParagraphStyleAttributeName value:mutableStyle range:NSMakeRange(tailIdx, 1)];
|
|
140
|
+
}
|
|
141
|
+
|
|
97
142
|
// 3. Zero out internal spacing for the last element (if not a code block)
|
|
98
143
|
if (!isCodeBlock) {
|
|
99
144
|
NSRange styleRange;
|
|
@@ -150,4 +195,4 @@
|
|
|
150
195
|
}
|
|
151
196
|
}
|
|
152
197
|
|
|
153
|
-
@end
|
|
198
|
+
@end
|
|
@@ -25,7 +25,6 @@
|
|
|
25
25
|
attachment.latex = latex;
|
|
26
26
|
attachment.fontSize = currentFont ? currentFont.pointSize : [_config paragraphFontSize];
|
|
27
27
|
attachment.mathTextColor = [_config inlineMathColor];
|
|
28
|
-
attachment.fontWeight = [_config inlineMathFontWeight];
|
|
29
28
|
|
|
30
29
|
#if TARGET_OS_OSX
|
|
31
30
|
// On macOS, NSLayoutManager uses self.image/self.bounds rather than calling
|
|
@@ -33,7 +32,11 @@
|
|
|
33
32
|
[attachment renderForMacOS];
|
|
34
33
|
#endif
|
|
35
34
|
|
|
36
|
-
|
|
35
|
+
NSMutableAttributedString *attachmentString =
|
|
36
|
+
[[NSAttributedString attributedStringWithAttachment:attachment] mutableCopy];
|
|
37
|
+
if (currentFont) {
|
|
38
|
+
[attachmentString addAttribute:NSFontAttributeName value:currentFont range:NSMakeRange(0, attachmentString.length)];
|
|
39
|
+
}
|
|
37
40
|
[output appendAttributedString:attachmentString];
|
|
38
41
|
}
|
|
39
42
|
|
package/ios/styles/StyleConfig.h
CHANGED
|
@@ -378,14 +378,10 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
378
378
|
- (void)setMathMarginBottom:(CGFloat)newValue;
|
|
379
379
|
- (NSString *)mathTextAlign;
|
|
380
380
|
- (void)setMathTextAlign:(NSString *)newValue;
|
|
381
|
-
- (NSString *)mathFontWeight;
|
|
382
|
-
- (void)setMathFontWeight:(NSString *)newValue;
|
|
383
381
|
|
|
384
382
|
// Inline Math properties
|
|
385
383
|
- (RCTUIColor *)inlineMathColor;
|
|
386
384
|
- (void)setInlineMathColor:(RCTUIColor *)newValue;
|
|
387
|
-
- (NSString *)inlineMathFontWeight;
|
|
388
|
-
- (void)setInlineMathFontWeight:(NSString *)newValue;
|
|
389
385
|
// Spoiler properties
|
|
390
386
|
- (RCTUIColor *)spoilerColor;
|
|
391
387
|
- (void)setSpoilerColor:(RCTUIColor *)newValue;
|
|
@@ -224,10 +224,8 @@ static inline NSString *normalizedFontWeight(NSString *fontWeight)
|
|
|
224
224
|
CGFloat _mathMarginTop;
|
|
225
225
|
CGFloat _mathMarginBottom;
|
|
226
226
|
NSString *_mathTextAlign;
|
|
227
|
-
NSString *_mathFontWeight;
|
|
228
227
|
// Inline Math properties
|
|
229
228
|
RCTUIColor *_inlineMathColor;
|
|
230
|
-
NSString *_inlineMathFontWeight;
|
|
231
229
|
// Spoiler properties
|
|
232
230
|
RCTUIColor *_spoilerColor;
|
|
233
231
|
CGFloat _spoilerParticleDensity;
|
|
@@ -484,9 +482,7 @@ static inline NSString *normalizedFontWeight(NSString *fontWeight)
|
|
|
484
482
|
copy->_mathMarginTop = _mathMarginTop;
|
|
485
483
|
copy->_mathMarginBottom = _mathMarginBottom;
|
|
486
484
|
copy->_mathTextAlign = [_mathTextAlign copy];
|
|
487
|
-
copy->_mathFontWeight = [_mathFontWeight copy];
|
|
488
485
|
copy->_inlineMathColor = [_inlineMathColor copy];
|
|
489
|
-
copy->_inlineMathFontWeight = [_inlineMathFontWeight copy];
|
|
490
486
|
copy->_spoilerColor = [_spoilerColor copy];
|
|
491
487
|
copy->_spoilerParticleDensity = _spoilerParticleDensity;
|
|
492
488
|
copy->_spoilerParticleSpeed = _spoilerParticleSpeed;
|
|
@@ -2422,16 +2418,6 @@ static const CGFloat kDefaultMinGap = 4.0;
|
|
|
2422
2418
|
_mathTextAlign = newValue;
|
|
2423
2419
|
}
|
|
2424
2420
|
|
|
2425
|
-
- (NSString *)mathFontWeight
|
|
2426
|
-
{
|
|
2427
|
-
return _mathFontWeight ?: @"normal";
|
|
2428
|
-
}
|
|
2429
|
-
|
|
2430
|
-
- (void)setMathFontWeight:(NSString *)newValue
|
|
2431
|
-
{
|
|
2432
|
-
_mathFontWeight = newValue;
|
|
2433
|
-
}
|
|
2434
|
-
|
|
2435
2421
|
// ── Inline Math ─────────────────────────────────────────────────────────────
|
|
2436
2422
|
|
|
2437
2423
|
- (RCTUIColor *)inlineMathColor
|
|
@@ -2444,16 +2430,6 @@ static const CGFloat kDefaultMinGap = 4.0;
|
|
|
2444
2430
|
_inlineMathColor = newValue;
|
|
2445
2431
|
}
|
|
2446
2432
|
|
|
2447
|
-
- (NSString *)inlineMathFontWeight
|
|
2448
|
-
{
|
|
2449
|
-
return _inlineMathFontWeight ?: @"normal";
|
|
2450
|
-
}
|
|
2451
|
-
|
|
2452
|
-
- (void)setInlineMathFontWeight:(NSString *)newValue
|
|
2453
|
-
{
|
|
2454
|
-
_inlineMathFontWeight = newValue;
|
|
2455
|
-
}
|
|
2456
|
-
|
|
2457
2433
|
// ── Spoiler ─────────────────────────────────────────────────────────────
|
|
2458
2434
|
|
|
2459
2435
|
- (RCTUIColor *)spoilerColor
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#import <Foundation/Foundation.h>
|
|
2
|
+
|
|
3
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
4
|
+
|
|
5
|
+
@interface ENRMAccessibilityLabels : NSObject
|
|
6
|
+
|
|
7
|
+
@property (nonatomic, copy) NSString *bulletPoint;
|
|
8
|
+
@property (nonatomic, copy) NSString *nestedBulletPoint;
|
|
9
|
+
@property (nonatomic, copy) NSString *orderedItem;
|
|
10
|
+
@property (nonatomic, copy) NSString *nestedOrderedItem;
|
|
11
|
+
@property (nonatomic, copy) NSString *blockquote;
|
|
12
|
+
@property (nonatomic, copy) NSString *nestedBlockquote;
|
|
13
|
+
@property (nonatomic, copy) NSString *tableRow;
|
|
14
|
+
@property (nonatomic, copy) NSString *mathEquation;
|
|
15
|
+
@property (nonatomic, copy) NSString *rotorHeadings;
|
|
16
|
+
@property (nonatomic, copy) NSString *rotorLinks;
|
|
17
|
+
@property (nonatomic, copy) NSString *rotorImages;
|
|
18
|
+
|
|
19
|
+
@end
|
|
20
|
+
|
|
21
|
+
NS_ASSUME_NONNULL_END
|
|
22
|
+
|
|
23
|
+
#ifdef __cplusplus
|
|
24
|
+
template <typename T> static bool ENRMAccessibilityLabelsChanged(const T &oldLabels, const T &newLabels)
|
|
25
|
+
{
|
|
26
|
+
return oldLabels.list.bulletPoint != newLabels.list.bulletPoint ||
|
|
27
|
+
oldLabels.list.nestedBulletPoint != newLabels.list.nestedBulletPoint ||
|
|
28
|
+
oldLabels.list.orderedItem != newLabels.list.orderedItem ||
|
|
29
|
+
oldLabels.list.nestedOrderedItem != newLabels.list.nestedOrderedItem ||
|
|
30
|
+
oldLabels.blockquote.quote != newLabels.blockquote.quote ||
|
|
31
|
+
oldLabels.blockquote.nestedQuote != newLabels.blockquote.nestedQuote ||
|
|
32
|
+
oldLabels.table.row != newLabels.table.row || oldLabels.math.equation != newLabels.math.equation ||
|
|
33
|
+
oldLabels.rotor.headings != newLabels.rotor.headings || oldLabels.rotor.links != newLabels.rotor.links ||
|
|
34
|
+
oldLabels.rotor.images != newLabels.rotor.images;
|
|
35
|
+
}
|
|
36
|
+
#endif
|