@fendent/react-native-enriched 0.5.2-fork.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/LICENSE +20 -0
- package/README.md +343 -0
- package/ReactNativeEnriched.podspec +31 -0
- package/android/build.gradle +106 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerDelegate.java +197 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerInterface.java +72 -0
- package/android/generated/jni/react/renderer/components/ReactNativeEnrichedSpec/ComponentDescriptors.cpp +22 -0
- package/android/generated/jni/react/renderer/components/ReactNativeEnrichedSpec/ComponentDescriptors.h +24 -0
- package/android/generated/jni/react/renderer/components/ReactNativeEnrichedSpec/EventEmitters.cpp +434 -0
- package/android/generated/jni/react/renderer/components/ReactNativeEnrichedSpec/EventEmitters.h +391 -0
- package/android/generated/jni/react/renderer/components/ReactNativeEnrichedSpec/Props.cpp +173 -0
- package/android/generated/jni/react/renderer/components/ReactNativeEnrichedSpec/Props.h +833 -0
- package/android/generated/jni/react/renderer/components/ReactNativeEnrichedSpec/ShadowNodes.cpp +17 -0
- package/android/generated/jni/react/renderer/components/ReactNativeEnrichedSpec/ShadowNodes.h +23 -0
- package/android/generated/jni/react/renderer/components/ReactNativeEnrichedSpec/States.cpp +16 -0
- package/android/generated/jni/react/renderer/components/ReactNativeEnrichedSpec/States.h +20 -0
- package/android/gradle.properties +5 -0
- package/android/lint.gradle +70 -0
- package/android/src/main/AndroidManifest.xml +3 -0
- package/android/src/main/AndroidManifestNew.xml +2 -0
- package/android/src/main/java/com/swmansion/enriched/ReactNativeEnrichedPackage.kt +20 -0
- package/android/src/main/java/com/swmansion/enriched/common/AsyncDrawable.kt +126 -0
- package/android/src/main/java/com/swmansion/enriched/common/CheckboxDrawable.kt +81 -0
- package/android/src/main/java/com/swmansion/enriched/common/EnrichedConstants.kt +11 -0
- package/android/src/main/java/com/swmansion/enriched/common/EnrichedStyle.kt +57 -0
- package/android/src/main/java/com/swmansion/enriched/common/ForceRedrawSpan.kt +14 -0
- package/android/src/main/java/com/swmansion/enriched/common/GumboNormalizer.kt +5 -0
- package/android/src/main/java/com/swmansion/enriched/common/MentionStyle.kt +7 -0
- package/android/src/main/java/com/swmansion/enriched/common/ResourceManager.kt +26 -0
- package/android/src/main/java/com/swmansion/enriched/common/parser/EnrichedParser.java +956 -0
- package/android/src/main/java/com/swmansion/enriched/common/parser/EnrichedSpanFactory.kt +79 -0
- package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedBlockQuoteSpan.kt +53 -0
- package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedBoldSpan.kt +12 -0
- package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedCheckboxListSpan.kt +92 -0
- package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedCodeBlockSpan.kt +81 -0
- package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedH1Span.kt +20 -0
- package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedH2Span.kt +20 -0
- package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedH3Span.kt +20 -0
- package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedH4Span.kt +21 -0
- package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedH5Span.kt +20 -0
- package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedH6Span.kt +20 -0
- package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedImageSpan.kt +184 -0
- package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedInlineCodeSpan.kt +24 -0
- package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedItalicSpan.kt +12 -0
- package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedLinkSpan.kt +29 -0
- package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedMentionSpan.kt +35 -0
- package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedOrderedListSpan.kt +79 -0
- package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedStrikeThroughSpan.kt +11 -0
- package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedUnderlineSpan.kt +11 -0
- package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedUnorderedListSpan.kt +62 -0
- package/android/src/main/java/com/swmansion/enriched/common/spans/interfaces/EnrichedBlockSpan.kt +5 -0
- package/android/src/main/java/com/swmansion/enriched/common/spans/interfaces/EnrichedHeadingSpan.kt +3 -0
- package/android/src/main/java/com/swmansion/enriched/common/spans/interfaces/EnrichedInlineSpan.kt +3 -0
- package/android/src/main/java/com/swmansion/enriched/common/spans/interfaces/EnrichedParagraphSpan.kt +5 -0
- package/android/src/main/java/com/swmansion/enriched/common/spans/interfaces/EnrichedSpan.kt +3 -0
- package/android/src/main/java/com/swmansion/enriched/common/spans/interfaces/EnrichedZeroWidthSpaceSpan.kt +4 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/EnrichedTextInputConnectionWrapper.kt +140 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/EnrichedTextInputSpannableFactory.kt +83 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/EnrichedTextInputView.kt +1120 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/EnrichedTextInputViewLayoutManager.kt +27 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/EnrichedTextInputViewManager.kt +478 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/MeasurementStore.kt +225 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/events/MentionHandler.kt +55 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/events/OnChangeHtmlEvent.kt +27 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/events/OnChangeSelectionEvent.kt +30 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/events/OnChangeStateEvent.kt +21 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/events/OnChangeTextEvent.kt +30 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/events/OnContextMenuItemPressEvent.kt +35 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/events/OnInputBlurEvent.kt +25 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/events/OnInputFocusEvent.kt +25 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/events/OnInputKeyPressEvent.kt +27 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/events/OnLinkDetectedEvent.kt +32 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/events/OnMentionDetectedEvent.kt +30 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/events/OnMentionEvent.kt +34 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/events/OnPasteImagesEvent.kt +47 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/events/OnRequestHtmlResultEvent.kt +32 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/events/OnSubmitEditingEvent.kt +29 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputBlockQuoteSpan.kt +14 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputBoldSpan.kt +14 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputCheckboxListSpan.kt +15 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputCodeBlockSpan.kt +14 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputH1Span.kt +14 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputH2Span.kt +14 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputH3Span.kt +14 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputH4Span.kt +14 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputH5Span.kt +14 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputH6Span.kt +14 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputImageSpan.kt +36 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputInlineCodeSpan.kt +14 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputItalicSpan.kt +14 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputLinkSpan.kt +16 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputMentionSpan.kt +18 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputOrderedListSpan.kt +21 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputStrikeThroughSpan.kt +14 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputUnderlineSpan.kt +14 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputUnorderedListSpan.kt +14 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedLineHeightSpan.kt +44 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedSpans.kt +241 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/spans/interfaces/EnrichedInputSpan.kt +10 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/styles/HtmlStyle.kt +372 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/styles/InlineStyles.kt +164 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/styles/ListStyles.kt +263 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/styles/ParagraphStyles.kt +434 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/styles/ParametrizedStyles.kt +394 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/utils/EnrichedEditableFactory.kt +17 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/utils/EnrichedSelection.kt +320 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/utils/EnrichedSpanState.kt +310 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/utils/EnrichedSpannable.kt +106 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/utils/EnrichedSpannableStringBuilder.kt +24 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/utils/RichContentReceiver.kt +127 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/utils/Utils.kt +106 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/watchers/EnrichedSpanWatcher.kt +107 -0
- package/android/src/main/java/com/swmansion/enriched/textinput/watchers/EnrichedTextWatcher.kt +74 -0
- package/android/src/main/new_arch/CMakeLists.txt +62 -0
- package/android/src/main/new_arch/GumboNormalizerJni.cpp +14 -0
- package/android/src/main/new_arch/ReactNativeEnrichedSpec.cpp +11 -0
- package/android/src/main/new_arch/ReactNativeEnrichedSpec.h +15 -0
- package/android/src/main/new_arch/react/renderer/components/ReactNativeEnrichedSpec/EnrichedTextInputComponentDescriptor.h +35 -0
- package/android/src/main/new_arch/react/renderer/components/ReactNativeEnrichedSpec/EnrichedTextInputMeasurementManager.cpp +53 -0
- package/android/src/main/new_arch/react/renderer/components/ReactNativeEnrichedSpec/EnrichedTextInputMeasurementManager.h +25 -0
- package/android/src/main/new_arch/react/renderer/components/ReactNativeEnrichedSpec/EnrichedTextInputShadowNode.cpp +35 -0
- package/android/src/main/new_arch/react/renderer/components/ReactNativeEnrichedSpec/EnrichedTextInputShadowNode.h +53 -0
- package/android/src/main/new_arch/react/renderer/components/ReactNativeEnrichedSpec/EnrichedTextInputState.cpp +9 -0
- package/android/src/main/new_arch/react/renderer/components/ReactNativeEnrichedSpec/EnrichedTextInputState.h +24 -0
- package/android/src/main/new_arch/react/renderer/components/ReactNativeEnrichedSpec/conversions.h +27 -0
- package/android/src/main/res/drawable/broken_image.xml +10 -0
- package/cpp/CMakeLists.txt +50 -0
- package/cpp/GumboParser/GumboParser.h +34043 -0
- package/cpp/README.md +59 -0
- package/cpp/parser/GumboNormalizer.c +915 -0
- package/cpp/parser/GumboParser.cpp +16 -0
- package/cpp/parser/GumboParser.hpp +23 -0
- package/cpp/tests/GumboParserTest.cpp +457 -0
- package/ios/EnrichedTextInputView.h +53 -0
- package/ios/EnrichedTextInputView.mm +2360 -0
- package/ios/EnrichedTextInputViewManager.mm +13 -0
- package/ios/attributesManager/AttributesManager.h +17 -0
- package/ios/attributesManager/AttributesManager.mm +195 -0
- package/ios/config/InputConfig.h +104 -0
- package/ios/config/InputConfig.mm +664 -0
- package/ios/extensions/ColorExtension.h +7 -0
- package/ios/extensions/ColorExtension.mm +38 -0
- package/ios/extensions/FontExtension.h +11 -0
- package/ios/extensions/FontExtension.mm +72 -0
- package/ios/extensions/ImageExtension.h +34 -0
- package/ios/extensions/ImageExtension.mm +165 -0
- package/ios/extensions/LayoutManagerExtension.h +6 -0
- package/ios/extensions/LayoutManagerExtension.mm +443 -0
- package/ios/extensions/StringExtension.h +15 -0
- package/ios/extensions/StringExtension.mm +69 -0
- package/ios/generated/ReactNativeEnrichedSpec/ComponentDescriptors.cpp +22 -0
- package/ios/generated/ReactNativeEnrichedSpec/ComponentDescriptors.h +24 -0
- package/ios/generated/ReactNativeEnrichedSpec/EventEmitters.cpp +434 -0
- package/ios/generated/ReactNativeEnrichedSpec/EventEmitters.h +391 -0
- package/ios/generated/ReactNativeEnrichedSpec/Props.cpp +173 -0
- package/ios/generated/ReactNativeEnrichedSpec/Props.h +833 -0
- package/ios/generated/ReactNativeEnrichedSpec/RCTComponentViewHelpers.h +582 -0
- package/ios/generated/ReactNativeEnrichedSpec/ShadowNodes.cpp +17 -0
- package/ios/generated/ReactNativeEnrichedSpec/ShadowNodes.h +23 -0
- package/ios/generated/ReactNativeEnrichedSpec/States.cpp +16 -0
- package/ios/generated/ReactNativeEnrichedSpec/States.h +20 -0
- package/ios/inputParser/InputParser.h +11 -0
- package/ios/inputParser/InputParser.mm +1463 -0
- package/ios/inputTextView/InputTextView.h +6 -0
- package/ios/inputTextView/InputTextView.mm +285 -0
- package/ios/interfaces/AttributeEntry.h +9 -0
- package/ios/interfaces/AttributeEntry.mm +4 -0
- package/ios/interfaces/BaseStyleProtocol.h +17 -0
- package/ios/interfaces/ImageAttachment.h +11 -0
- package/ios/interfaces/ImageAttachment.mm +107 -0
- package/ios/interfaces/ImageData.h +10 -0
- package/ios/interfaces/ImageData.mm +4 -0
- package/ios/interfaces/LinkData.h +11 -0
- package/ios/interfaces/LinkData.mm +29 -0
- package/ios/interfaces/LinkRegexConfig.h +19 -0
- package/ios/interfaces/LinkRegexConfig.mm +37 -0
- package/ios/interfaces/MediaAttachment.h +23 -0
- package/ios/interfaces/MediaAttachment.mm +31 -0
- package/ios/interfaces/MentionParams.h +8 -0
- package/ios/interfaces/MentionParams.mm +4 -0
- package/ios/interfaces/MentionStyleProps.h +13 -0
- package/ios/interfaces/MentionStyleProps.mm +63 -0
- package/ios/interfaces/StyleBase.h +36 -0
- package/ios/interfaces/StyleBase.mm +256 -0
- package/ios/interfaces/StyleHeaders.h +102 -0
- package/ios/interfaces/StylePair.h +9 -0
- package/ios/interfaces/StylePair.mm +4 -0
- package/ios/interfaces/StyleTypeEnum.h +26 -0
- package/ios/interfaces/TextDecorationLineEnum.h +6 -0
- package/ios/interfaces/TextDecorationLineEnum.mm +4 -0
- package/ios/internals/EnrichedTextInputViewComponentDescriptor.h +19 -0
- package/ios/internals/EnrichedTextInputViewShadowNode.h +44 -0
- package/ios/internals/EnrichedTextInputViewShadowNode.mm +103 -0
- package/ios/internals/EnrichedTextInputViewState.cpp +10 -0
- package/ios/internals/EnrichedTextInputViewState.h +22 -0
- package/ios/styles/BlockQuoteStyle.mm +55 -0
- package/ios/styles/BoldStyle.mm +37 -0
- package/ios/styles/CheckboxListStyle.mm +153 -0
- package/ios/styles/CodeBlockStyle.mm +49 -0
- package/ios/styles/H1Style.mm +20 -0
- package/ios/styles/H2Style.mm +20 -0
- package/ios/styles/H3Style.mm +20 -0
- package/ios/styles/H4Style.mm +20 -0
- package/ios/styles/H5Style.mm +20 -0
- package/ios/styles/H6Style.mm +20 -0
- package/ios/styles/HeadingStyleBase.mm +65 -0
- package/ios/styles/ImageStyle.mm +146 -0
- package/ios/styles/InlineCodeStyle.mm +65 -0
- package/ios/styles/ItalicStyle.mm +37 -0
- package/ios/styles/LinkStyle.mm +532 -0
- package/ios/styles/MentionStyle.mm +538 -0
- package/ios/styles/OrderedListStyle.mm +86 -0
- package/ios/styles/StrikethroughStyle.mm +25 -0
- package/ios/styles/UnderlineStyle.mm +24 -0
- package/ios/styles/UnorderedListStyle.mm +86 -0
- package/ios/utils/CheckboxHitTestUtils.h +10 -0
- package/ios/utils/CheckboxHitTestUtils.mm +122 -0
- package/ios/utils/DotReplacementUtils.h +10 -0
- package/ios/utils/DotReplacementUtils.mm +68 -0
- package/ios/utils/KeyboardUtils.h +7 -0
- package/ios/utils/KeyboardUtils.mm +31 -0
- package/ios/utils/OccurenceUtils.h +44 -0
- package/ios/utils/OccurenceUtils.mm +179 -0
- package/ios/utils/ParagraphAttributesUtils.h +15 -0
- package/ios/utils/ParagraphAttributesUtils.mm +257 -0
- package/ios/utils/RangeUtils.h +12 -0
- package/ios/utils/RangeUtils.mm +183 -0
- package/ios/utils/TextBlockTapGestureRecognizer.h +17 -0
- package/ios/utils/TextBlockTapGestureRecognizer.mm +56 -0
- package/ios/utils/TextInsertionUtils.h +17 -0
- package/ios/utils/TextInsertionUtils.mm +64 -0
- package/ios/utils/WordsUtils.h +7 -0
- package/ios/utils/WordsUtils.mm +98 -0
- package/ios/utils/ZeroWidthSpaceUtils.h +9 -0
- package/ios/utils/ZeroWidthSpaceUtils.mm +270 -0
- package/lib/module/index.js +4 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/native/EnrichedTextInput.js +304 -0
- package/lib/module/native/EnrichedTextInput.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/spec/EnrichedTextInputNativeComponent.ts +517 -0
- package/lib/module/types.js +4 -0
- package/lib/module/types.js.map +1 -0
- package/lib/module/utils/EnrichedTextInputDefaultProps.js +12 -0
- package/lib/module/utils/EnrichedTextInputDefaultProps.js.map +1 -0
- package/lib/module/utils/normalizeHtmlStyle.js +155 -0
- package/lib/module/utils/normalizeHtmlStyle.js.map +1 -0
- package/lib/module/utils/nullthrows.js +9 -0
- package/lib/module/utils/nullthrows.js.map +1 -0
- package/lib/module/utils/regexParser.js +46 -0
- package/lib/module/utils/regexParser.js.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/index.d.ts +3 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/native/EnrichedTextInput.d.ts +3 -0
- package/lib/typescript/src/native/EnrichedTextInput.d.ts.map +1 -0
- package/lib/typescript/src/spec/EnrichedTextInputNativeComponent.d.ts +397 -0
- package/lib/typescript/src/spec/EnrichedTextInputNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/types.d.ts +447 -0
- package/lib/typescript/src/types.d.ts.map +1 -0
- package/lib/typescript/src/utils/EnrichedTextInputDefaultProps.d.ts +10 -0
- package/lib/typescript/src/utils/EnrichedTextInputDefaultProps.d.ts.map +1 -0
- package/lib/typescript/src/utils/normalizeHtmlStyle.d.ts +4 -0
- package/lib/typescript/src/utils/normalizeHtmlStyle.d.ts.map +1 -0
- package/lib/typescript/src/utils/nullthrows.d.ts +2 -0
- package/lib/typescript/src/utils/nullthrows.d.ts.map +1 -0
- package/lib/typescript/src/utils/regexParser.d.ts +3 -0
- package/lib/typescript/src/utils/regexParser.d.ts.map +1 -0
- package/package.json +226 -0
- package/react-native.config.js +13 -0
- package/src/index.tsx +20 -0
- package/src/native/EnrichedTextInput.tsx +370 -0
- package/src/spec/EnrichedTextInputNativeComponent.ts +517 -0
- package/src/types.ts +499 -0
- package/src/utils/EnrichedTextInputDefaultProps.ts +9 -0
- package/src/utils/normalizeHtmlStyle.ts +199 -0
- package/src/utils/nullthrows.ts +7 -0
- package/src/utils/regexParser.ts +56 -0
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
#import "InputTextView.h"
|
|
2
|
+
#import "EnrichedTextInputView.h"
|
|
3
|
+
#import "StringExtension.h"
|
|
4
|
+
#import "TextInsertionUtils.h"
|
|
5
|
+
#import <UniformTypeIdentifiers/UniformTypeIdentifiers.h>
|
|
6
|
+
|
|
7
|
+
@implementation InputTextView
|
|
8
|
+
|
|
9
|
+
- (void)layoutSubviews {
|
|
10
|
+
[super layoutSubviews];
|
|
11
|
+
// UITextView resets contentSize during its own layout pass (triggered when
|
|
12
|
+
// the frame is set on first mount). Re-schedule a relayout so our explicit
|
|
13
|
+
// contentSize is applied after UITextView finishes its internal layout.
|
|
14
|
+
EnrichedTextInputView *input = (EnrichedTextInputView *)_input;
|
|
15
|
+
if (input != nil) {
|
|
16
|
+
[input scheduleRelayoutIfNeeded];
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
- (void)copy:(id)sender {
|
|
21
|
+
EnrichedTextInputView *typedInput = (EnrichedTextInputView *)_input;
|
|
22
|
+
if (typedInput == nullptr) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// remove zero width spaces before copying the text
|
|
27
|
+
NSString *plainText = [typedInput->textView.textStorage.string
|
|
28
|
+
substringWithRange:typedInput->textView.selectedRange];
|
|
29
|
+
NSString *fixedPlainText =
|
|
30
|
+
[plainText stringByReplacingOccurrencesOfString:@"\u200B" withString:@""];
|
|
31
|
+
|
|
32
|
+
NSString *parsedHtml = [typedInput->parser
|
|
33
|
+
parseToHtmlFromRange:typedInput->textView.selectedRange];
|
|
34
|
+
|
|
35
|
+
NSMutableAttributedString *attrStr = [[typedInput->textView.textStorage
|
|
36
|
+
attributedSubstringFromRange:typedInput->textView.selectedRange]
|
|
37
|
+
mutableCopy];
|
|
38
|
+
NSRange fullAttrStrRange = NSMakeRange(0, attrStr.length);
|
|
39
|
+
[attrStr.mutableString replaceOccurrencesOfString:@"\u200B"
|
|
40
|
+
withString:@""
|
|
41
|
+
options:0
|
|
42
|
+
range:fullAttrStrRange];
|
|
43
|
+
|
|
44
|
+
NSData *rtfData =
|
|
45
|
+
[attrStr dataFromRange:NSMakeRange(0, attrStr.length)
|
|
46
|
+
documentAttributes:@{
|
|
47
|
+
NSDocumentTypeDocumentAttribute : NSRTFTextDocumentType
|
|
48
|
+
}
|
|
49
|
+
error:nullptr];
|
|
50
|
+
|
|
51
|
+
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
|
|
52
|
+
[pasteboard setItems:@[ @{
|
|
53
|
+
UTTypeUTF8PlainText.identifier : fixedPlainText,
|
|
54
|
+
UTTypeHTML.identifier : parsedHtml,
|
|
55
|
+
UTTypeRTF.identifier : rtfData
|
|
56
|
+
} ]];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
- (void)paste:(id)sender {
|
|
60
|
+
EnrichedTextInputView *typedInput = (EnrichedTextInputView *)_input;
|
|
61
|
+
if (typedInput == nullptr) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
|
|
66
|
+
NSArray<NSString *> *pasteboardTypes = pasteboard.pasteboardTypes;
|
|
67
|
+
NSRange currentRange = typedInput->textView.selectedRange;
|
|
68
|
+
|
|
69
|
+
// Check the pasteboard for supported image formats. If found, save them to
|
|
70
|
+
// temporary storage then emit the 'onPasteImages' event and stop processing
|
|
71
|
+
// further (ignoring any HTML/Text).
|
|
72
|
+
NSMutableArray<NSDictionary *> *foundImages = [NSMutableArray new];
|
|
73
|
+
|
|
74
|
+
for (NSDictionary<NSString *, id> *item in pasteboard.items) {
|
|
75
|
+
NSData *imageData = nil;
|
|
76
|
+
BOOL added = NO;
|
|
77
|
+
NSString *ext = nil;
|
|
78
|
+
NSString *mimeType = nil;
|
|
79
|
+
|
|
80
|
+
for (int j = 0; j < item.allKeys.count; j++) {
|
|
81
|
+
if (added) {
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
NSString *type = item.allKeys[j];
|
|
86
|
+
if ([type isEqual:UTTypeJPEG.identifier] ||
|
|
87
|
+
[type isEqual:UTTypePNG.identifier] ||
|
|
88
|
+
[type isEqual:UTTypeHEIC.identifier] ||
|
|
89
|
+
[type isEqual:UTTypeTIFF.identifier]) {
|
|
90
|
+
imageData = [self getDataForImageItem:item[type] type:type];
|
|
91
|
+
} else if ([type isEqual:UTTypeWebP.identifier] ||
|
|
92
|
+
[type isEqual:UTTypeGIF.identifier]) {
|
|
93
|
+
// webp and gifs: read raw bytes directly — no re-encoding needed
|
|
94
|
+
imageData = [pasteboard dataForPasteboardType:type];
|
|
95
|
+
}
|
|
96
|
+
if (!imageData) {
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
NSDictionary *info = [self detectImageFormat:type];
|
|
101
|
+
if (!info) {
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
ext = info[@"ext"];
|
|
105
|
+
mimeType = info[@"mime"];
|
|
106
|
+
|
|
107
|
+
UIImage *imageInfo = [UIImage imageWithData:imageData];
|
|
108
|
+
|
|
109
|
+
if (imageInfo) {
|
|
110
|
+
NSString *path = [self saveToTempFile:imageData extension:ext];
|
|
111
|
+
|
|
112
|
+
if (path) {
|
|
113
|
+
added = YES;
|
|
114
|
+
[foundImages addObject:@{
|
|
115
|
+
@"uri" : path,
|
|
116
|
+
@"type" : mimeType,
|
|
117
|
+
@"width" : @(imageInfo.size.width),
|
|
118
|
+
@"height" : @(imageInfo.size.height)
|
|
119
|
+
}];
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (foundImages.count > 0) {
|
|
126
|
+
[typedInput emitOnPasteImagesEvent:foundImages];
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if ([pasteboardTypes containsObject:UTTypeHTML.identifier]) {
|
|
131
|
+
// we try processing the html contents
|
|
132
|
+
|
|
133
|
+
NSString *htmlString;
|
|
134
|
+
id htmlValue = [pasteboard valueForPasteboardType:UTTypeHTML.identifier];
|
|
135
|
+
|
|
136
|
+
if ([htmlValue isKindOfClass:[NSData class]]) {
|
|
137
|
+
htmlString = [[NSString alloc] initWithData:htmlValue
|
|
138
|
+
encoding:NSUTF8StringEncoding];
|
|
139
|
+
} else if ([htmlValue isKindOfClass:[NSString class]]) {
|
|
140
|
+
htmlString = htmlValue;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// validate the html
|
|
144
|
+
NSString *initiallyProcessedHtml =
|
|
145
|
+
[typedInput->parser initiallyProcessHtml:htmlString];
|
|
146
|
+
|
|
147
|
+
if (initiallyProcessedHtml != nullptr) {
|
|
148
|
+
// valid html, let's apply it
|
|
149
|
+
currentRange.length > 0
|
|
150
|
+
? [typedInput->parser replaceFromHtml:initiallyProcessedHtml
|
|
151
|
+
range:currentRange]
|
|
152
|
+
: [typedInput->parser insertFromHtml:initiallyProcessedHtml
|
|
153
|
+
location:currentRange.location];
|
|
154
|
+
} else {
|
|
155
|
+
// fall back to plain text, otherwise do nothing
|
|
156
|
+
[self tryHandlingPlainTextItemsIn:pasteboard
|
|
157
|
+
range:currentRange
|
|
158
|
+
input:typedInput];
|
|
159
|
+
}
|
|
160
|
+
} else {
|
|
161
|
+
[self tryHandlingPlainTextItemsIn:pasteboard
|
|
162
|
+
range:currentRange
|
|
163
|
+
input:typedInput];
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
[typedInput anyTextMayHaveBeenModified];
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
- (NSDictionary *)detectImageFormat:(NSString *)type {
|
|
170
|
+
if ([type isEqual:UTTypeJPEG.identifier]) {
|
|
171
|
+
return @{@"ext" : @"jpg", @"mime" : @"image/jpeg"};
|
|
172
|
+
} else if ([type isEqual:UTTypePNG.identifier]) {
|
|
173
|
+
return @{@"ext" : @"png", @"mime" : @"image/png"};
|
|
174
|
+
} else if ([type isEqual:UTTypeGIF.identifier]) {
|
|
175
|
+
return @{@"ext" : @"gif", @"mime" : @"image/gif"};
|
|
176
|
+
} else if ([type isEqual:UTTypeHEIC.identifier]) {
|
|
177
|
+
return @{@"ext" : @"heic", @"mime" : @"image/heic"};
|
|
178
|
+
} else if ([type isEqual:UTTypeWebP.identifier]) {
|
|
179
|
+
return @{@"ext" : @"webp", @"mime" : @"image/webp"};
|
|
180
|
+
} else if ([type isEqual:UTTypeTIFF.identifier]) {
|
|
181
|
+
return @{@"ext" : @"tiff", @"mime" : @"image/tiff"};
|
|
182
|
+
} else {
|
|
183
|
+
return nil;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
- (NSData *)getDataForImageItem:(NSData *)imageData type:(NSString *)type {
|
|
188
|
+
UIImage *image = (UIImage *)imageData;
|
|
189
|
+
|
|
190
|
+
if ([type isEqual:UTTypePNG.identifier]) {
|
|
191
|
+
return UIImagePNGRepresentation(image);
|
|
192
|
+
} else if ([type isEqual:UTTypeHEIC.identifier]) {
|
|
193
|
+
return UIImageHEICRepresentation(image);
|
|
194
|
+
} else {
|
|
195
|
+
return UIImageJPEGRepresentation(image, 1.0);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
- (NSString *)saveToTempFile:(NSData *)data extension:(NSString *)ext {
|
|
200
|
+
if (!data)
|
|
201
|
+
return nil;
|
|
202
|
+
NSString *fileName =
|
|
203
|
+
[NSString stringWithFormat:@"%@.%@", [NSUUID UUID].UUIDString, ext];
|
|
204
|
+
|
|
205
|
+
NSString *filePath =
|
|
206
|
+
[NSTemporaryDirectory() stringByAppendingPathComponent:fileName];
|
|
207
|
+
|
|
208
|
+
if ([data writeToFile:filePath atomically:YES]) {
|
|
209
|
+
return [NSURL fileURLWithPath:filePath].absoluteString;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
return nil;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
- (void)tryHandlingPlainTextItemsIn:(UIPasteboard *)pasteboard
|
|
216
|
+
range:(NSRange)range
|
|
217
|
+
input:(EnrichedTextInputView *)input {
|
|
218
|
+
NSArray *existingTypes = pasteboard.pasteboardTypes;
|
|
219
|
+
NSArray *handledTypes = @[
|
|
220
|
+
UTTypeUTF8PlainText.identifier, UTTypePlainText.identifier,
|
|
221
|
+
UTTypeURL.identifier
|
|
222
|
+
];
|
|
223
|
+
NSString *plainText;
|
|
224
|
+
|
|
225
|
+
for (NSString *type in handledTypes) {
|
|
226
|
+
if (![existingTypes containsObject:type]) {
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
id value = [pasteboard valueForPasteboardType:type];
|
|
231
|
+
|
|
232
|
+
if ([value isKindOfClass:[NSData class]]) {
|
|
233
|
+
plainText = [[NSString alloc] initWithData:value
|
|
234
|
+
encoding:NSUTF8StringEncoding];
|
|
235
|
+
} else if ([value isKindOfClass:[NSString class]]) {
|
|
236
|
+
plainText = (NSString *)value;
|
|
237
|
+
} else if ([value isKindOfClass:[NSURL class]]) {
|
|
238
|
+
plainText = [(NSURL *)value absoluteString];
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if (!plainText) {
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
range.length > 0 ? [TextInsertionUtils replaceText:plainText
|
|
247
|
+
at:range
|
|
248
|
+
additionalAttributes:nullptr
|
|
249
|
+
input:input
|
|
250
|
+
withSelection:YES]
|
|
251
|
+
: [TextInsertionUtils insertText:plainText
|
|
252
|
+
at:range.location
|
|
253
|
+
additionalAttributes:nullptr
|
|
254
|
+
input:input
|
|
255
|
+
withSelection:YES];
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
- (void)cut:(id)sender {
|
|
259
|
+
EnrichedTextInputView *typedInput = (EnrichedTextInputView *)_input;
|
|
260
|
+
if (typedInput == nullptr) {
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
[self copy:sender];
|
|
265
|
+
[TextInsertionUtils replaceText:@""
|
|
266
|
+
at:typedInput->textView.selectedRange
|
|
267
|
+
additionalAttributes:nullptr
|
|
268
|
+
input:typedInput
|
|
269
|
+
withSelection:YES];
|
|
270
|
+
|
|
271
|
+
[typedInput anyTextMayHaveBeenModified];
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
|
|
275
|
+
if (action == @selector(paste:)) {
|
|
276
|
+
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
|
|
277
|
+
// Enable Paste if clipboard has Text OR Images
|
|
278
|
+
if (pasteboard.hasStrings || pasteboard.hasImages) {
|
|
279
|
+
return YES;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
return [super canPerformAction:action withSender:sender];
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
@end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
#import "StylePair.h"
|
|
3
|
+
#import "StyleTypeEnum.h"
|
|
4
|
+
|
|
5
|
+
@protocol BaseStyleProtocol <NSObject>
|
|
6
|
+
+ (StyleType)getStyleType;
|
|
7
|
+
+ (BOOL)isParagraphStyle;
|
|
8
|
+
- (instancetype _Nonnull)initWithInput:(id _Nonnull)input;
|
|
9
|
+
- (void)applyStyle:(NSRange)range;
|
|
10
|
+
- (void)addAttributes:(NSRange)range withTypingAttr:(BOOL)withTypingAttr;
|
|
11
|
+
- (void)removeAttributes:(NSRange)range;
|
|
12
|
+
- (void)addTypingAttributes;
|
|
13
|
+
- (void)removeTypingAttributes;
|
|
14
|
+
- (BOOL)detectStyle:(NSRange)range;
|
|
15
|
+
- (BOOL)anyOccurence:(NSRange)range;
|
|
16
|
+
- (NSArray<StylePair *> *_Nullable)findAllOccurences:(NSRange)range;
|
|
17
|
+
@end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#import "ImageData.h"
|
|
2
|
+
#import "MediaAttachment.h"
|
|
3
|
+
|
|
4
|
+
@interface ImageAttachment : MediaAttachment
|
|
5
|
+
|
|
6
|
+
@property(nonatomic, strong) ImageData *imageData;
|
|
7
|
+
@property(nonatomic, strong) UIImage *storedAnimatedImage;
|
|
8
|
+
|
|
9
|
+
- (instancetype)initWithImageData:(ImageData *)data;
|
|
10
|
+
|
|
11
|
+
@end
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
#import "ImageAttachment.h"
|
|
2
|
+
#import "ImageExtension.h"
|
|
3
|
+
|
|
4
|
+
// NSTextStorage frequently recreates NSTextAttachment objects during attribute
|
|
5
|
+
// invalidation (e.g. on every keystroke). Without this cache each recreation
|
|
6
|
+
// would trigger a fresh async network/disk load, causing images to flicker or
|
|
7
|
+
// disappear temporarily. Caching by URI ensures that once an image is loaded it
|
|
8
|
+
// is reused instantly for all subsequent attachment instances with the same
|
|
9
|
+
// URI
|
|
10
|
+
static NSCache<NSString *, UIImage *> *ImageAttachmentCache(void) {
|
|
11
|
+
static NSCache<NSString *, UIImage *> *cache = nil;
|
|
12
|
+
static dispatch_once_t onceToken;
|
|
13
|
+
dispatch_once(&onceToken, ^{
|
|
14
|
+
cache = [[NSCache alloc] init];
|
|
15
|
+
cache.totalCostLimit = 100 * 1024 * 1024; // 100 MB
|
|
16
|
+
});
|
|
17
|
+
return cache;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
@implementation ImageAttachment
|
|
21
|
+
|
|
22
|
+
- (instancetype)initWithImageData:(ImageData *)data {
|
|
23
|
+
self = [super initWithURI:data.uri width:data.width height:data.height];
|
|
24
|
+
if (!self)
|
|
25
|
+
return nil;
|
|
26
|
+
|
|
27
|
+
_imageData = data;
|
|
28
|
+
UIImage *cachedImage = nil;
|
|
29
|
+
if (self.uri.length > 0) {
|
|
30
|
+
cachedImage = [ImageAttachmentCache() objectForKey:self.uri];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Assign an empty image to reserve layout space within the text system.
|
|
34
|
+
// The actual image is not drawn here; it is rendered and overlaid by a
|
|
35
|
+
// separate ImageView.
|
|
36
|
+
self.image = [UIImage new];
|
|
37
|
+
|
|
38
|
+
if (cachedImage != nil) {
|
|
39
|
+
self.storedAnimatedImage = cachedImage;
|
|
40
|
+
} else {
|
|
41
|
+
[self loadAsync];
|
|
42
|
+
}
|
|
43
|
+
return self;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
- (CGRect)attachmentBoundsForTextContainer:(NSTextContainer *)textContainer
|
|
47
|
+
proposedLineFragment:(CGRect)lineFrag
|
|
48
|
+
glyphPosition:(CGPoint)position
|
|
49
|
+
characterIndex:(NSUInteger)charIndex {
|
|
50
|
+
CGRect baseBounds = self.bounds;
|
|
51
|
+
|
|
52
|
+
if (!textContainer.layoutManager.textStorage ||
|
|
53
|
+
charIndex >= textContainer.layoutManager.textStorage.length) {
|
|
54
|
+
return baseBounds;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
UIFont *font =
|
|
58
|
+
[textContainer.layoutManager.textStorage attribute:NSFontAttributeName
|
|
59
|
+
atIndex:charIndex
|
|
60
|
+
effectiveRange:NULL];
|
|
61
|
+
if (!font) {
|
|
62
|
+
return baseBounds;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Extend the layout bounds below the baseline by the font's descender.
|
|
66
|
+
// Without this, a line containing only the attachment has no descender space
|
|
67
|
+
// below the baseline, but adding a text character introduces it — causing
|
|
68
|
+
// the line height to jump. By reserving descender space upfront the line
|
|
69
|
+
// height stays consistent regardless of whether text is present.
|
|
70
|
+
CGFloat descender = font.descender;
|
|
71
|
+
return CGRectMake(baseBounds.origin.x, descender, baseBounds.size.width,
|
|
72
|
+
baseBounds.size.height - descender);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
- (void)loadAsync {
|
|
76
|
+
NSURL *url = [NSURL URLWithString:self.uri];
|
|
77
|
+
if (!url) {
|
|
78
|
+
self.storedAnimatedImage = [UIImage systemImageNamed:@"photo"];
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^{
|
|
83
|
+
NSData *bytes = [NSData dataWithContentsOfURL:url];
|
|
84
|
+
|
|
85
|
+
// We pass all image data (including static formats like PNG or JPEG)
|
|
86
|
+
// through the GIF parser. It safely acts as a universal parser, returning
|
|
87
|
+
// a single-frame UIImage for static formats and an animated UIImage for
|
|
88
|
+
// GIFs.
|
|
89
|
+
UIImage *img = bytes ? [UIImage animatedImageWithAnimatedGIFData:bytes]
|
|
90
|
+
: [UIImage systemImageNamed:@"photo"];
|
|
91
|
+
|
|
92
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
93
|
+
if (bytes != nil && img != nil && self.uri.length > 0) {
|
|
94
|
+
CGFloat scale = img.scale;
|
|
95
|
+
// Calculate true byte cost based on pixels
|
|
96
|
+
// Width (in pixels) * Height (in pixels) * 4 bytes (for RGBA channels)
|
|
97
|
+
NSUInteger cost = (NSUInteger)(img.size.width * scale *
|
|
98
|
+
img.size.height * scale * 4.0);
|
|
99
|
+
[ImageAttachmentCache() setObject:img forKey:self.uri cost:cost];
|
|
100
|
+
}
|
|
101
|
+
self.storedAnimatedImage = img;
|
|
102
|
+
[self notifyUpdate];
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
@end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
#import <UIKit/UIKit.h>
|
|
3
|
+
|
|
4
|
+
@interface LinkData : NSObject <NSCopying>
|
|
5
|
+
|
|
6
|
+
@property(nonatomic, copy) NSString *text;
|
|
7
|
+
@property(nonatomic, copy) NSString *url;
|
|
8
|
+
@property(nonatomic, assign) BOOL isManual;
|
|
9
|
+
- (BOOL)isEqualToLinkData:(LinkData *)linkData;
|
|
10
|
+
|
|
11
|
+
@end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#import "LinkData.h"
|
|
2
|
+
|
|
3
|
+
@implementation LinkData
|
|
4
|
+
|
|
5
|
+
- (id)copyWithZone:(NSZone *)zone {
|
|
6
|
+
LinkData *copy = [[[self class] allocWithZone:zone] init];
|
|
7
|
+
if (copy) {
|
|
8
|
+
copy.text = [self.text copyWithZone:zone];
|
|
9
|
+
copy.url = [self.url copyWithZone:zone];
|
|
10
|
+
copy.isManual = self.isManual;
|
|
11
|
+
}
|
|
12
|
+
return copy;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
- (BOOL)isEqualToLinkData:(LinkData *)linkData {
|
|
16
|
+
if (!linkData) {
|
|
17
|
+
return NO;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
BOOL equalText = (!self.text && !linkData.text) ||
|
|
21
|
+
[self.text isEqualToString:linkData.text];
|
|
22
|
+
BOOL equalUrl =
|
|
23
|
+
(!self.url && !linkData.url) || [self.url isEqualToString:linkData.url];
|
|
24
|
+
BOOL equalIsManual = (self.isManual == linkData.isManual);
|
|
25
|
+
|
|
26
|
+
return equalText && equalUrl && equalIsManual;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
#import <ReactNativeEnriched/Props.h>
|
|
3
|
+
#import <UIKit/UIKit.h>
|
|
4
|
+
|
|
5
|
+
using namespace facebook::react;
|
|
6
|
+
|
|
7
|
+
@interface LinkRegexConfig : NSObject
|
|
8
|
+
|
|
9
|
+
@property NSString *pattern;
|
|
10
|
+
@property BOOL caseInsensitive;
|
|
11
|
+
@property BOOL dotAll;
|
|
12
|
+
@property BOOL isDisabled;
|
|
13
|
+
@property BOOL isDefault;
|
|
14
|
+
|
|
15
|
+
- (instancetype)initWithLinkRegexProp:
|
|
16
|
+
(EnrichedTextInputViewLinkRegexStruct)prop;
|
|
17
|
+
- (BOOL)isEqualToConfig:(LinkRegexConfig *)otherObj;
|
|
18
|
+
|
|
19
|
+
@end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#import "LinkRegexConfig.h"
|
|
2
|
+
#import "StringExtension.h"
|
|
3
|
+
|
|
4
|
+
@implementation LinkRegexConfig
|
|
5
|
+
|
|
6
|
+
- (instancetype)initWithLinkRegexProp:
|
|
7
|
+
(EnrichedTextInputViewLinkRegexStruct)prop {
|
|
8
|
+
if (!self)
|
|
9
|
+
return nil;
|
|
10
|
+
|
|
11
|
+
_pattern = [NSString fromCppString:prop.pattern];
|
|
12
|
+
_caseInsensitive = prop.caseInsensitive;
|
|
13
|
+
_dotAll = prop.dotAll;
|
|
14
|
+
_isDefault = prop.isDefault;
|
|
15
|
+
_isDisabled = prop.isDisabled;
|
|
16
|
+
|
|
17
|
+
return self;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
- (id)copyWithZone:(NSZone *)zone {
|
|
21
|
+
LinkRegexConfig *copy = [[[self class] allocWithZone:zone] init];
|
|
22
|
+
copy->_pattern = [_pattern copy];
|
|
23
|
+
copy->_caseInsensitive = _caseInsensitive;
|
|
24
|
+
copy->_dotAll = _dotAll;
|
|
25
|
+
copy->_isDefault = _isDefault;
|
|
26
|
+
copy->_isDisabled = _isDisabled;
|
|
27
|
+
return copy;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
- (BOOL)isEqualToConfig:(LinkRegexConfig *)otherObj {
|
|
31
|
+
return [_pattern isEqualToString:otherObj.pattern] &&
|
|
32
|
+
_caseInsensitive == otherObj.caseInsensitive &&
|
|
33
|
+
_dotAll == otherObj.dotAll && _isDefault == otherObj.isDefault &&
|
|
34
|
+
_isDisabled == otherObj.isDisabled;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#import <UIKit/UIKit.h>
|
|
2
|
+
|
|
3
|
+
@class MediaAttachment;
|
|
4
|
+
|
|
5
|
+
@protocol MediaAttachmentDelegate <NSObject>
|
|
6
|
+
- (void)mediaAttachmentDidUpdate:(MediaAttachment *)attachment;
|
|
7
|
+
@end
|
|
8
|
+
|
|
9
|
+
@interface MediaAttachment : NSTextAttachment
|
|
10
|
+
|
|
11
|
+
@property(nonatomic, weak) id<MediaAttachmentDelegate> delegate;
|
|
12
|
+
@property(nonatomic, strong) NSString *uri;
|
|
13
|
+
@property(nonatomic, assign) CGFloat width;
|
|
14
|
+
@property(nonatomic, assign) CGFloat height;
|
|
15
|
+
|
|
16
|
+
- (instancetype)initWithURI:(NSString *)uri
|
|
17
|
+
width:(CGFloat)width
|
|
18
|
+
height:(CGFloat)height;
|
|
19
|
+
|
|
20
|
+
- (void)loadAsync;
|
|
21
|
+
- (void)notifyUpdate;
|
|
22
|
+
|
|
23
|
+
@end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#import "MediaAttachment.h"
|
|
2
|
+
|
|
3
|
+
@implementation MediaAttachment
|
|
4
|
+
|
|
5
|
+
- (instancetype)initWithURI:(NSString *)uri
|
|
6
|
+
width:(CGFloat)width
|
|
7
|
+
height:(CGFloat)height {
|
|
8
|
+
self = [super init];
|
|
9
|
+
if (!self)
|
|
10
|
+
return nil;
|
|
11
|
+
|
|
12
|
+
_uri = uri;
|
|
13
|
+
_width = width;
|
|
14
|
+
_height = height;
|
|
15
|
+
|
|
16
|
+
self.bounds = CGRectMake(0, 0, width, height);
|
|
17
|
+
|
|
18
|
+
return self;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
- (void)loadAsync {
|
|
22
|
+
// no-op for base
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
- (void)notifyUpdate {
|
|
26
|
+
if ([self.delegate respondsToSelector:@selector(mediaAttachmentDidUpdate:)]) {
|
|
27
|
+
[self.delegate mediaAttachmentDidUpdate:self];
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
#import "TextDecorationLineEnum.h"
|
|
3
|
+
#import "string"
|
|
4
|
+
#import <UIKit/UIKit.h>
|
|
5
|
+
#import <folly/dynamic.h>
|
|
6
|
+
|
|
7
|
+
@interface MentionStyleProps : NSObject
|
|
8
|
+
@property UIColor *color;
|
|
9
|
+
@property UIColor *backgroundColor;
|
|
10
|
+
@property TextDecorationLineEnum decorationLine;
|
|
11
|
+
+ (NSDictionary *)getSinglePropsFromFollyDynamic:(folly::dynamic)folly;
|
|
12
|
+
+ (NSDictionary *)getComplexPropsFromFollyDynamic:(folly::dynamic)folly;
|
|
13
|
+
@end
|