@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,86 @@
|
|
|
1
|
+
#import "EnrichedTextInputView.h"
|
|
2
|
+
#import "RangeUtils.h"
|
|
3
|
+
#import "StyleHeaders.h"
|
|
4
|
+
#import "TextInsertionUtils.h"
|
|
5
|
+
|
|
6
|
+
@implementation UnorderedListStyle
|
|
7
|
+
|
|
8
|
+
+ (StyleType)getType {
|
|
9
|
+
return UnorderedList;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
- (NSString *)getValue {
|
|
13
|
+
return @"EnrichedUnorderedList";
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
- (BOOL)isParagraph {
|
|
17
|
+
return YES;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
- (BOOL)needsZWS {
|
|
21
|
+
return YES;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
- (void)applyStyling:(NSRange)range {
|
|
25
|
+
// lists are drawn manually
|
|
26
|
+
// margin before bullet + gap between bullet and paragraph
|
|
27
|
+
CGFloat listHeadIndent = [self.input->config unorderedListMarginLeft] +
|
|
28
|
+
[self.input->config unorderedListGapWidth];
|
|
29
|
+
|
|
30
|
+
[self.input->textView.textStorage
|
|
31
|
+
enumerateAttribute:NSParagraphStyleAttributeName
|
|
32
|
+
inRange:range
|
|
33
|
+
options:0
|
|
34
|
+
usingBlock:^(id _Nullable value, NSRange range,
|
|
35
|
+
BOOL *_Nonnull stop) {
|
|
36
|
+
NSMutableParagraphStyle *pStyle =
|
|
37
|
+
[(NSParagraphStyle *)value mutableCopy];
|
|
38
|
+
pStyle.headIndent = listHeadIndent;
|
|
39
|
+
pStyle.firstLineHeadIndent = listHeadIndent;
|
|
40
|
+
[self.input->textView.textStorage
|
|
41
|
+
addAttribute:NSParagraphStyleAttributeName
|
|
42
|
+
value:pStyle
|
|
43
|
+
range:range];
|
|
44
|
+
}];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
- (BOOL)tryHandlingListShorcutInRange:(NSRange)range
|
|
48
|
+
replacementText:(NSString *)text {
|
|
49
|
+
NSRange paragraphRange =
|
|
50
|
+
[self.input->textView.textStorage.string paragraphRangeForRange:range];
|
|
51
|
+
// space was added - check if we are both at the paragraph beginning + 1
|
|
52
|
+
// character (which we want to be a dash)
|
|
53
|
+
if ([text isEqualToString:@" "] &&
|
|
54
|
+
range.location - 1 == paragraphRange.location) {
|
|
55
|
+
unichar charBefore = [self.input->textView.textStorage.string
|
|
56
|
+
characterAtIndex:range.location - 1];
|
|
57
|
+
if (charBefore == '-') {
|
|
58
|
+
// we got a match - add a list if possible
|
|
59
|
+
if ([self.input handleStyleBlocksAndConflicts:[[self class] getType]
|
|
60
|
+
range:paragraphRange]) {
|
|
61
|
+
// don't emit during the replacing
|
|
62
|
+
self.input->blockEmitting = YES;
|
|
63
|
+
|
|
64
|
+
// remove the dash
|
|
65
|
+
[TextInsertionUtils replaceText:@""
|
|
66
|
+
at:NSMakeRange(paragraphRange.location, 1)
|
|
67
|
+
additionalAttributes:nullptr
|
|
68
|
+
input:self.input
|
|
69
|
+
withSelection:YES];
|
|
70
|
+
|
|
71
|
+
self.input->blockEmitting = NO;
|
|
72
|
+
|
|
73
|
+
// add attributes on the dashless paragraph
|
|
74
|
+
[self add:NSMakeRange(paragraphRange.location,
|
|
75
|
+
paragraphRange.length - 1)
|
|
76
|
+
withTyping:YES
|
|
77
|
+
withDirtyRange:YES];
|
|
78
|
+
|
|
79
|
+
return YES;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return NO;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
@end
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
#import "CheckboxHitTestUtils.h"
|
|
2
|
+
#import "EnrichedTextInputView.h"
|
|
3
|
+
#import "InputConfig.h"
|
|
4
|
+
#import "StyleHeaders.h"
|
|
5
|
+
|
|
6
|
+
static const CGFloat kCheckboxHitSlopLeft = 8.0;
|
|
7
|
+
static const CGFloat kCheckboxHitSlopVertical = 6.0;
|
|
8
|
+
|
|
9
|
+
@implementation CheckboxHitTestUtils
|
|
10
|
+
|
|
11
|
+
// MARK: - Coordinate helpers
|
|
12
|
+
|
|
13
|
+
+ (CGPoint)containerPointFromViewPoint:(CGPoint)point
|
|
14
|
+
textView:(UITextView *)textView {
|
|
15
|
+
return CGPointMake(point.x - textView.textContainerInset.left,
|
|
16
|
+
point.y - textView.textContainerInset.top);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// MARK: - Glyph lookup
|
|
20
|
+
|
|
21
|
+
+ (NSUInteger)glyphIndexAtContainerPoint:(CGPoint)point
|
|
22
|
+
textView:(UITextView *)textView {
|
|
23
|
+
return [textView.layoutManager glyphIndexForPoint:point
|
|
24
|
+
inTextContainer:textView.textContainer
|
|
25
|
+
fractionOfDistanceThroughGlyph:nil];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// MARK: - Checkbox detection
|
|
29
|
+
|
|
30
|
+
+ (BOOL)isCheckboxGlyph:(NSUInteger)glyphIndex
|
|
31
|
+
inInput:(EnrichedTextInputView *)input {
|
|
32
|
+
UITextView *textView = input->textView;
|
|
33
|
+
NSLayoutManager *layoutManager = textView.layoutManager;
|
|
34
|
+
NSTextStorage *storage = textView.textStorage;
|
|
35
|
+
|
|
36
|
+
NSUInteger charIndex =
|
|
37
|
+
[layoutManager characterIndexForGlyphAtIndex:glyphIndex];
|
|
38
|
+
|
|
39
|
+
if (charIndex >= storage.length) {
|
|
40
|
+
return NO;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
CheckboxListStyle *checkboxListStyle =
|
|
44
|
+
(CheckboxListStyle *)input->stylesDict[@([CheckboxListStyle getType])];
|
|
45
|
+
|
|
46
|
+
if (!checkboxListStyle) {
|
|
47
|
+
return NO;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return [checkboxListStyle detect:NSMakeRange(charIndex, 0)];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// MARK: - Checkbox rect
|
|
54
|
+
|
|
55
|
+
+ (CGRect)checkboxRectForGlyphIndex:(NSUInteger)glyphIndex
|
|
56
|
+
inInput:(EnrichedTextInputView *)input {
|
|
57
|
+
UITextView *textView = input->textView;
|
|
58
|
+
NSLayoutManager *layoutManager = textView.layoutManager;
|
|
59
|
+
InputConfig *config = input->config;
|
|
60
|
+
|
|
61
|
+
if (!config) {
|
|
62
|
+
return CGRectNull;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
CGRect lineRect = [layoutManager lineFragmentRectForGlyphAtIndex:glyphIndex
|
|
66
|
+
effectiveRange:nil];
|
|
67
|
+
|
|
68
|
+
CGFloat originX = lineRect.origin.x + config.checkboxListMarginLeft;
|
|
69
|
+
|
|
70
|
+
CGFloat originY = lineRect.origin.y +
|
|
71
|
+
(lineRect.size.height - config.checkboxListBoxSize) / 2.0;
|
|
72
|
+
|
|
73
|
+
return CGRectMake(originX, originY, config.checkboxListBoxSize,
|
|
74
|
+
config.checkboxListBoxSize);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// MARK: - Hit rect
|
|
78
|
+
|
|
79
|
+
+ (CGRect)expandedHitRectFromCheckboxRect:(CGRect)rect {
|
|
80
|
+
if (CGRectIsNull(rect))
|
|
81
|
+
return rect;
|
|
82
|
+
|
|
83
|
+
return CGRectInset(rect, -kCheckboxHitSlopLeft, -kCheckboxHitSlopVertical);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// MARK: - Public API
|
|
87
|
+
|
|
88
|
+
+ (NSInteger)hitTestCheckboxAtPoint:(CGPoint)point
|
|
89
|
+
inInput:(EnrichedTextInputView *)input {
|
|
90
|
+
UITextView *textView = input->textView;
|
|
91
|
+
|
|
92
|
+
CGPoint containerPoint = [self containerPointFromViewPoint:point
|
|
93
|
+
textView:textView];
|
|
94
|
+
|
|
95
|
+
NSUInteger glyphIndex = [self glyphIndexAtContainerPoint:containerPoint
|
|
96
|
+
textView:textView];
|
|
97
|
+
|
|
98
|
+
if (glyphIndex == NSNotFound) {
|
|
99
|
+
return -1;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (![self isCheckboxGlyph:glyphIndex inInput:input]) {
|
|
103
|
+
return -1;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
CGRect checkboxRect = [self checkboxRectForGlyphIndex:glyphIndex
|
|
107
|
+
inInput:input];
|
|
108
|
+
|
|
109
|
+
if (CGRectIsNull(checkboxRect)) {
|
|
110
|
+
return -1;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
CGRect hitRect = [self expandedHitRectFromCheckboxRect:checkboxRect];
|
|
114
|
+
|
|
115
|
+
if (!CGRectContainsPoint(hitRect, containerPoint)) {
|
|
116
|
+
return -1;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return [textView.layoutManager characterIndexForGlyphAtIndex:glyphIndex];
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
@end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#import <UIKit/UIKit.h>
|
|
2
|
+
#pragma once
|
|
3
|
+
|
|
4
|
+
@interface DotReplacementUtils : NSObject
|
|
5
|
+
+ (void)handleDotReplacement:(id)input
|
|
6
|
+
textStorage:(NSTextStorage *)textStorage
|
|
7
|
+
editedMask:(NSTextStorageEditActions)editedMask
|
|
8
|
+
editedRange:(NSRange)editedRange
|
|
9
|
+
delta:(NSInteger)delta;
|
|
10
|
+
@end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#import "DotReplacementUtils.h"
|
|
2
|
+
#import "EnrichedTextInputView.h"
|
|
3
|
+
|
|
4
|
+
@implementation DotReplacementUtils
|
|
5
|
+
|
|
6
|
+
// This is a fix for iOS replacing a space with a dot when two spaces are
|
|
7
|
+
// quickly inputted That operation doesn't properly extend our custom attributes
|
|
8
|
+
// and we do it here manually
|
|
9
|
+
+ (void)handleDotReplacement:(id)input
|
|
10
|
+
textStorage:(NSTextStorage *)textStorage
|
|
11
|
+
editedMask:(NSTextStorageEditActions)editedMask
|
|
12
|
+
editedRange:(NSRange)editedRange
|
|
13
|
+
delta:(NSInteger)delta {
|
|
14
|
+
EnrichedTextInputView *typedInput = (EnrichedTextInputView *)input;
|
|
15
|
+
if (typedInput == nullptr) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Conditions for the dot attributes fix:
|
|
20
|
+
// - character edition was done
|
|
21
|
+
// - it edited one character
|
|
22
|
+
// - new character is a dot
|
|
23
|
+
// - delta=0, meaning a replacement was done
|
|
24
|
+
// - there is something before the edited range to get attributes from
|
|
25
|
+
if ((editedMask & NSTextStorageEditedCharacters) != 0 &&
|
|
26
|
+
editedRange.length == 1 &&
|
|
27
|
+
[[textStorage.string substringWithRange:editedRange]
|
|
28
|
+
isEqualToString:@"."] &&
|
|
29
|
+
delta == 0 && editedRange.location > 0) {
|
|
30
|
+
// If all of the above are true, we are sure some dot replacement has been
|
|
31
|
+
// done So we manually need to apply the preceeding attribtues to the dot
|
|
32
|
+
NSDictionary *prevAttrs =
|
|
33
|
+
[textStorage attributesAtIndex:editedRange.location - 1
|
|
34
|
+
effectiveRange:nullptr];
|
|
35
|
+
[textStorage addAttributes:prevAttrs range:editedRange];
|
|
36
|
+
typedInput->dotReplacementRange = [NSValue valueWithRange:editedRange];
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Space after the dot added by iOS comes in a separate, second callback.
|
|
41
|
+
// Checking its conditions:
|
|
42
|
+
// - dotReplacementRange defined
|
|
43
|
+
// - dotReplacementRange was exactly before the new edited range
|
|
44
|
+
// - character edition was done
|
|
45
|
+
// - it edited one character
|
|
46
|
+
// - edited character is a space
|
|
47
|
+
// - delta=1, meaning addition was done
|
|
48
|
+
if (typedInput->dotReplacementRange != nullptr &&
|
|
49
|
+
[typedInput->dotReplacementRange rangeValue].location + 1 ==
|
|
50
|
+
editedRange.location &&
|
|
51
|
+
(editedMask & NSTextStorageEditedCharacters) != 0 &&
|
|
52
|
+
editedRange.length == 1 &&
|
|
53
|
+
[[textStorage.string substringWithRange:editedRange]
|
|
54
|
+
isEqualToString:@" "] &&
|
|
55
|
+
delta == 1) {
|
|
56
|
+
// If all of the above are true, we are now sure it was the iOS dot
|
|
57
|
+
// replacement Only then do we also fix attribtues of the space added
|
|
58
|
+
// afterwards
|
|
59
|
+
NSDictionary *prevAttrs =
|
|
60
|
+
[textStorage attributesAtIndex:editedRange.location - 1
|
|
61
|
+
effectiveRange:nullptr];
|
|
62
|
+
[textStorage addAttributes:prevAttrs range:editedRange];
|
|
63
|
+
}
|
|
64
|
+
// always reset the replacement range after any processing
|
|
65
|
+
typedInput->dotReplacementRange = nullptr;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
@end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#import "KeyboardUtils.h"
|
|
2
|
+
#import "RCTTextInputUtils.h"
|
|
3
|
+
|
|
4
|
+
@implementation KeyboardUtils
|
|
5
|
+
+ (UIReturnKeyType)getUIReturnKeyTypeFromReturnKeyType:
|
|
6
|
+
(NSString *)returnKeyType {
|
|
7
|
+
if ([returnKeyType isEqualToString:@"done"])
|
|
8
|
+
return UIReturnKeyDone;
|
|
9
|
+
if ([returnKeyType isEqualToString:@"go"])
|
|
10
|
+
return UIReturnKeyGo;
|
|
11
|
+
if ([returnKeyType isEqualToString:@"next"])
|
|
12
|
+
return UIReturnKeyNext;
|
|
13
|
+
if ([returnKeyType isEqualToString:@"search"])
|
|
14
|
+
return UIReturnKeySearch;
|
|
15
|
+
if ([returnKeyType isEqualToString:@"send"])
|
|
16
|
+
return UIReturnKeySend;
|
|
17
|
+
if ([returnKeyType isEqualToString:@"emergency-call"])
|
|
18
|
+
return UIReturnKeyEmergencyCall;
|
|
19
|
+
if ([returnKeyType isEqualToString:@"google"])
|
|
20
|
+
return UIReturnKeyGoogle;
|
|
21
|
+
if ([returnKeyType isEqualToString:@"join"])
|
|
22
|
+
return UIReturnKeyJoin;
|
|
23
|
+
if ([returnKeyType isEqualToString:@"route"])
|
|
24
|
+
return UIReturnKeyRoute;
|
|
25
|
+
if ([returnKeyType isEqualToString:@"yahoo"])
|
|
26
|
+
return UIReturnKeyYahoo;
|
|
27
|
+
|
|
28
|
+
return UIReturnKeyDefault;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
#import "EnrichedTextInputView.h"
|
|
3
|
+
#import "StylePair.h"
|
|
4
|
+
|
|
5
|
+
@interface OccurenceUtils : NSObject
|
|
6
|
+
+ (BOOL)detect:(NSAttributedStringKey _Nonnull)key
|
|
7
|
+
withInput:(EnrichedTextInputView *_Nonnull)input
|
|
8
|
+
inRange:(NSRange)range
|
|
9
|
+
withCondition:(BOOL(NS_NOESCAPE ^ _Nonnull)(id _Nullable value,
|
|
10
|
+
NSRange range))condition;
|
|
11
|
+
+ (BOOL)detect:(NSAttributedStringKey _Nonnull)key
|
|
12
|
+
withInput:(EnrichedTextInputView *_Nonnull)input
|
|
13
|
+
atIndex:(NSUInteger)index
|
|
14
|
+
checkPrevious:(BOOL)checkPrev
|
|
15
|
+
withCondition:(BOOL(NS_NOESCAPE ^ _Nonnull)(id _Nullable value,
|
|
16
|
+
NSRange range))condition;
|
|
17
|
+
+ (BOOL)detectMultiple:(NSArray<NSAttributedStringKey> *_Nonnull)keys
|
|
18
|
+
withInput:(EnrichedTextInputView *_Nonnull)input
|
|
19
|
+
inRange:(NSRange)range
|
|
20
|
+
withCondition:(BOOL(NS_NOESCAPE ^ _Nonnull)(id _Nullable value,
|
|
21
|
+
NSRange range))condition;
|
|
22
|
+
+ (BOOL)any:(NSAttributedStringKey _Nonnull)key
|
|
23
|
+
withInput:(EnrichedTextInputView *_Nonnull)input
|
|
24
|
+
inRange:(NSRange)range
|
|
25
|
+
withCondition:(BOOL(NS_NOESCAPE ^ _Nonnull)(id _Nullable value,
|
|
26
|
+
NSRange range))condition;
|
|
27
|
+
+ (BOOL)anyMultiple:(NSArray<NSAttributedStringKey> *_Nonnull)keys
|
|
28
|
+
withInput:(EnrichedTextInputView *_Nonnull)input
|
|
29
|
+
inRange:(NSRange)range
|
|
30
|
+
withCondition:(BOOL(NS_NOESCAPE ^ _Nonnull)(id _Nullable value,
|
|
31
|
+
NSRange range))condition;
|
|
32
|
+
+ (NSArray<StylePair *> *_Nullable)all:(NSAttributedStringKey _Nonnull)key
|
|
33
|
+
withInput:(EnrichedTextInputView *_Nonnull)input
|
|
34
|
+
inRange:(NSRange)range
|
|
35
|
+
withCondition:(BOOL(NS_NOESCAPE ^
|
|
36
|
+
_Nonnull)(id _Nullable value,
|
|
37
|
+
NSRange range))condition;
|
|
38
|
+
+ (NSArray<StylePair *> *_Nullable)
|
|
39
|
+
allMultiple:(NSArray<NSAttributedStringKey> *_Nonnull)keys
|
|
40
|
+
withInput:(EnrichedTextInputView *_Nonnull)input
|
|
41
|
+
inRange:(NSRange)range
|
|
42
|
+
withCondition:(BOOL(NS_NOESCAPE ^ _Nonnull)(id _Nullable value,
|
|
43
|
+
NSRange range))condition;
|
|
44
|
+
@end
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
#import "OccurenceUtils.h"
|
|
2
|
+
#import "StyleBase.h"
|
|
3
|
+
|
|
4
|
+
@implementation OccurenceUtils
|
|
5
|
+
|
|
6
|
+
+ (BOOL)detect:(NSAttributedStringKey _Nonnull)key
|
|
7
|
+
withInput:(EnrichedTextInputView *_Nonnull)input
|
|
8
|
+
inRange:(NSRange)range
|
|
9
|
+
withCondition:(BOOL(NS_NOESCAPE ^ _Nonnull)(id _Nullable value,
|
|
10
|
+
NSRange range))condition {
|
|
11
|
+
__block NSInteger totalLength = 0;
|
|
12
|
+
[input->textView.textStorage
|
|
13
|
+
enumerateAttribute:key
|
|
14
|
+
inRange:range
|
|
15
|
+
options:0
|
|
16
|
+
usingBlock:^(id _Nullable value, NSRange range,
|
|
17
|
+
BOOL *_Nonnull stop) {
|
|
18
|
+
if (condition(value, range)) {
|
|
19
|
+
totalLength += range.length;
|
|
20
|
+
}
|
|
21
|
+
}];
|
|
22
|
+
return totalLength == range.length;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// checkPrevious flag is used for styles like lists or blockquotes
|
|
26
|
+
// it means that first character of paragraph will be checked instead if the
|
|
27
|
+
// detection is not in input's selected range and at the end of the input
|
|
28
|
+
+ (BOOL)detect:(NSAttributedStringKey _Nonnull)key
|
|
29
|
+
withInput:(EnrichedTextInputView *_Nonnull)input
|
|
30
|
+
atIndex:(NSUInteger)index
|
|
31
|
+
checkPrevious:(BOOL)checkPrev
|
|
32
|
+
withCondition:(BOOL(NS_NOESCAPE ^ _Nonnull)(id _Nullable value,
|
|
33
|
+
NSRange range))condition {
|
|
34
|
+
NSRange detectionRange = NSMakeRange(index, 0);
|
|
35
|
+
id attrValue;
|
|
36
|
+
if (NSEqualRanges(input->textView.selectedRange, detectionRange)) {
|
|
37
|
+
attrValue = input->textView.typingAttributes[key];
|
|
38
|
+
} else if (index == input->textView.textStorage.string.length) {
|
|
39
|
+
if (checkPrev) {
|
|
40
|
+
NSRange paragraphRange = [input->textView.textStorage.string
|
|
41
|
+
paragraphRangeForRange:detectionRange];
|
|
42
|
+
if (paragraphRange.location == detectionRange.location) {
|
|
43
|
+
return NO;
|
|
44
|
+
} else {
|
|
45
|
+
return [self detect:key
|
|
46
|
+
withInput:input
|
|
47
|
+
inRange:NSMakeRange(paragraphRange.location, 1)
|
|
48
|
+
withCondition:condition];
|
|
49
|
+
}
|
|
50
|
+
} else {
|
|
51
|
+
return NO;
|
|
52
|
+
}
|
|
53
|
+
} else {
|
|
54
|
+
NSRange attrRange = NSMakeRange(0, 0);
|
|
55
|
+
attrValue = [input->textView.textStorage attribute:key
|
|
56
|
+
atIndex:index
|
|
57
|
+
effectiveRange:&attrRange];
|
|
58
|
+
}
|
|
59
|
+
return condition(attrValue, detectionRange);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
+ (BOOL)detectMultiple:(NSArray<NSAttributedStringKey> *_Nonnull)keys
|
|
63
|
+
withInput:(EnrichedTextInputView *_Nonnull)input
|
|
64
|
+
inRange:(NSRange)range
|
|
65
|
+
withCondition:(BOOL(NS_NOESCAPE ^ _Nonnull)(id _Nullable value,
|
|
66
|
+
NSRange range))condition {
|
|
67
|
+
__block NSInteger totalLength = 0;
|
|
68
|
+
for (NSString *key in keys) {
|
|
69
|
+
[input->textView.textStorage
|
|
70
|
+
enumerateAttribute:key
|
|
71
|
+
inRange:range
|
|
72
|
+
options:0
|
|
73
|
+
usingBlock:^(id _Nullable value, NSRange range,
|
|
74
|
+
BOOL *_Nonnull stop) {
|
|
75
|
+
if (condition(value, range)) {
|
|
76
|
+
totalLength += range.length;
|
|
77
|
+
}
|
|
78
|
+
}];
|
|
79
|
+
}
|
|
80
|
+
return totalLength == range.length;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
+ (BOOL)any:(NSAttributedStringKey _Nonnull)key
|
|
84
|
+
withInput:(EnrichedTextInputView *_Nonnull)input
|
|
85
|
+
inRange:(NSRange)range
|
|
86
|
+
withCondition:(BOOL(NS_NOESCAPE ^ _Nonnull)(id _Nullable value,
|
|
87
|
+
NSRange range))condition {
|
|
88
|
+
__block BOOL found = NO;
|
|
89
|
+
[input->textView.textStorage
|
|
90
|
+
enumerateAttribute:key
|
|
91
|
+
inRange:range
|
|
92
|
+
options:0
|
|
93
|
+
usingBlock:^(id _Nullable value, NSRange range,
|
|
94
|
+
BOOL *_Nonnull stop) {
|
|
95
|
+
if (condition(value, range)) {
|
|
96
|
+
found = YES;
|
|
97
|
+
*stop = YES;
|
|
98
|
+
}
|
|
99
|
+
}];
|
|
100
|
+
return found;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
+ (BOOL)anyMultiple:(NSArray<NSAttributedStringKey> *_Nonnull)keys
|
|
104
|
+
withInput:(EnrichedTextInputView *_Nonnull)input
|
|
105
|
+
inRange:(NSRange)range
|
|
106
|
+
withCondition:(BOOL(NS_NOESCAPE ^ _Nonnull)(id _Nullable value,
|
|
107
|
+
NSRange range))condition {
|
|
108
|
+
__block BOOL found = NO;
|
|
109
|
+
for (NSString *key in keys) {
|
|
110
|
+
[input->textView.textStorage
|
|
111
|
+
enumerateAttribute:key
|
|
112
|
+
inRange:range
|
|
113
|
+
options:0
|
|
114
|
+
usingBlock:^(id _Nullable value, NSRange range,
|
|
115
|
+
BOOL *_Nonnull stop) {
|
|
116
|
+
if (condition(value, range)) {
|
|
117
|
+
found = YES;
|
|
118
|
+
*stop = YES;
|
|
119
|
+
}
|
|
120
|
+
}];
|
|
121
|
+
if (found) {
|
|
122
|
+
return YES;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return NO;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
+ (NSArray<StylePair *> *_Nullable)all:(NSAttributedStringKey _Nonnull)key
|
|
129
|
+
withInput:(EnrichedTextInputView *_Nonnull)input
|
|
130
|
+
inRange:(NSRange)range
|
|
131
|
+
withCondition:
|
|
132
|
+
(BOOL(NS_NOESCAPE ^ _Nonnull)(id _Nullable value,
|
|
133
|
+
NSRange range))
|
|
134
|
+
condition {
|
|
135
|
+
__block NSMutableArray<StylePair *> *occurences =
|
|
136
|
+
[[NSMutableArray<StylePair *> alloc] init];
|
|
137
|
+
[input->textView.textStorage
|
|
138
|
+
enumerateAttribute:key
|
|
139
|
+
inRange:range
|
|
140
|
+
options:0
|
|
141
|
+
usingBlock:^(id _Nullable value, NSRange range,
|
|
142
|
+
BOOL *_Nonnull stop) {
|
|
143
|
+
if (condition(value, range)) {
|
|
144
|
+
StylePair *pair = [[StylePair alloc] init];
|
|
145
|
+
pair.rangeValue = [NSValue valueWithRange:range];
|
|
146
|
+
pair.styleValue = value;
|
|
147
|
+
[occurences addObject:pair];
|
|
148
|
+
}
|
|
149
|
+
}];
|
|
150
|
+
return occurences;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
+ (NSArray<StylePair *> *_Nullable)
|
|
154
|
+
allMultiple:(NSArray<NSAttributedStringKey> *_Nonnull)keys
|
|
155
|
+
withInput:(EnrichedTextInputView *_Nonnull)input
|
|
156
|
+
inRange:(NSRange)range
|
|
157
|
+
withCondition:(BOOL(NS_NOESCAPE ^ _Nonnull)(id _Nullable value,
|
|
158
|
+
NSRange range))condition {
|
|
159
|
+
__block NSMutableArray<StylePair *> *occurences =
|
|
160
|
+
[[NSMutableArray<StylePair *> alloc] init];
|
|
161
|
+
for (NSString *key in keys) {
|
|
162
|
+
[input->textView.textStorage
|
|
163
|
+
enumerateAttribute:key
|
|
164
|
+
inRange:range
|
|
165
|
+
options:0
|
|
166
|
+
usingBlock:^(id _Nullable value, NSRange range,
|
|
167
|
+
BOOL *_Nonnull stop) {
|
|
168
|
+
if (condition(value, range)) {
|
|
169
|
+
StylePair *pair = [[StylePair alloc] init];
|
|
170
|
+
pair.rangeValue = [NSValue valueWithRange:range];
|
|
171
|
+
pair.styleValue = value;
|
|
172
|
+
[occurences addObject:pair];
|
|
173
|
+
}
|
|
174
|
+
}];
|
|
175
|
+
}
|
|
176
|
+
return occurences;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
@end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#import <UIKit/UIKit.h>
|
|
2
|
+
#pragma once
|
|
3
|
+
|
|
4
|
+
@interface ParagraphAttributesUtils : NSObject
|
|
5
|
+
+ (BOOL)handleBackspaceInRange:(NSRange)range
|
|
6
|
+
replacementText:(NSString *)text
|
|
7
|
+
input:(id)input;
|
|
8
|
+
+ (BOOL)handleParagraphStylesMergeOnBackspace:(NSRange)range
|
|
9
|
+
replacementText:(NSString *)text
|
|
10
|
+
input:(id)input;
|
|
11
|
+
+ (BOOL)handleResetTypingAttributesOnBackspace:(NSRange)range
|
|
12
|
+
replacementText:(NSString *)text
|
|
13
|
+
input:(id)input;
|
|
14
|
+
+ (BOOL)isParagraphEmpty:(NSRange)range inString:(NSString *)string;
|
|
15
|
+
@end
|