@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,79 @@
|
|
|
1
|
+
package com.swmansion.enriched.common.parser
|
|
2
|
+
|
|
3
|
+
import com.swmansion.enriched.common.spans.EnrichedBlockQuoteSpan
|
|
4
|
+
import com.swmansion.enriched.common.spans.EnrichedBoldSpan
|
|
5
|
+
import com.swmansion.enriched.common.spans.EnrichedCheckboxListSpan
|
|
6
|
+
import com.swmansion.enriched.common.spans.EnrichedCodeBlockSpan
|
|
7
|
+
import com.swmansion.enriched.common.spans.EnrichedH1Span
|
|
8
|
+
import com.swmansion.enriched.common.spans.EnrichedH2Span
|
|
9
|
+
import com.swmansion.enriched.common.spans.EnrichedH3Span
|
|
10
|
+
import com.swmansion.enriched.common.spans.EnrichedH4Span
|
|
11
|
+
import com.swmansion.enriched.common.spans.EnrichedH5Span
|
|
12
|
+
import com.swmansion.enriched.common.spans.EnrichedH6Span
|
|
13
|
+
import com.swmansion.enriched.common.spans.EnrichedImageSpan
|
|
14
|
+
import com.swmansion.enriched.common.spans.EnrichedInlineCodeSpan
|
|
15
|
+
import com.swmansion.enriched.common.spans.EnrichedItalicSpan
|
|
16
|
+
import com.swmansion.enriched.common.spans.EnrichedLinkSpan
|
|
17
|
+
import com.swmansion.enriched.common.spans.EnrichedMentionSpan
|
|
18
|
+
import com.swmansion.enriched.common.spans.EnrichedOrderedListSpan
|
|
19
|
+
import com.swmansion.enriched.common.spans.EnrichedStrikeThroughSpan
|
|
20
|
+
import com.swmansion.enriched.common.spans.EnrichedUnderlineSpan
|
|
21
|
+
import com.swmansion.enriched.common.spans.EnrichedUnorderedListSpan
|
|
22
|
+
|
|
23
|
+
interface EnrichedSpanFactory<T> {
|
|
24
|
+
fun createBoldSpan(style: T): EnrichedBoldSpan
|
|
25
|
+
|
|
26
|
+
fun createItalicSpan(style: T): EnrichedItalicSpan
|
|
27
|
+
|
|
28
|
+
fun createUnderlineSpan(style: T): EnrichedUnderlineSpan
|
|
29
|
+
|
|
30
|
+
fun createStrikeThroughSpan(style: T): EnrichedStrikeThroughSpan
|
|
31
|
+
|
|
32
|
+
fun createInlineCodeSpan(style: T): EnrichedInlineCodeSpan
|
|
33
|
+
|
|
34
|
+
fun createLinkSpan(
|
|
35
|
+
url: String,
|
|
36
|
+
style: T,
|
|
37
|
+
): EnrichedLinkSpan
|
|
38
|
+
|
|
39
|
+
fun createMentionSpan(
|
|
40
|
+
text: String,
|
|
41
|
+
indicator: String,
|
|
42
|
+
attributes: Map<String, String>,
|
|
43
|
+
style: T,
|
|
44
|
+
): EnrichedMentionSpan
|
|
45
|
+
|
|
46
|
+
fun createImageSpan(
|
|
47
|
+
source: String,
|
|
48
|
+
width: Int,
|
|
49
|
+
height: Int,
|
|
50
|
+
): EnrichedImageSpan
|
|
51
|
+
|
|
52
|
+
fun createH1Span(style: T): EnrichedH1Span
|
|
53
|
+
|
|
54
|
+
fun createH2Span(style: T): EnrichedH2Span
|
|
55
|
+
|
|
56
|
+
fun createH3Span(style: T): EnrichedH3Span
|
|
57
|
+
|
|
58
|
+
fun createH4Span(style: T): EnrichedH4Span
|
|
59
|
+
|
|
60
|
+
fun createH5Span(style: T): EnrichedH5Span
|
|
61
|
+
|
|
62
|
+
fun createH6Span(style: T): EnrichedH6Span
|
|
63
|
+
|
|
64
|
+
fun createOrderedListSpan(
|
|
65
|
+
index: Int,
|
|
66
|
+
style: T,
|
|
67
|
+
): EnrichedOrderedListSpan
|
|
68
|
+
|
|
69
|
+
fun createUnorderedListSpan(style: T): EnrichedUnorderedListSpan
|
|
70
|
+
|
|
71
|
+
fun createCheckboxListSpan(
|
|
72
|
+
isChecked: Boolean,
|
|
73
|
+
style: T,
|
|
74
|
+
): EnrichedCheckboxListSpan
|
|
75
|
+
|
|
76
|
+
fun createBlockQuoteSpan(style: T): EnrichedBlockQuoteSpan
|
|
77
|
+
|
|
78
|
+
fun createCodeBlockSpan(style: T): EnrichedCodeBlockSpan
|
|
79
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
package com.swmansion.enriched.common.spans
|
|
2
|
+
|
|
3
|
+
import android.graphics.Canvas
|
|
4
|
+
import android.graphics.Paint
|
|
5
|
+
import android.text.Layout
|
|
6
|
+
import android.text.TextPaint
|
|
7
|
+
import android.text.style.LeadingMarginSpan
|
|
8
|
+
import android.text.style.MetricAffectingSpan
|
|
9
|
+
import com.swmansion.enriched.common.EnrichedStyle
|
|
10
|
+
import com.swmansion.enriched.common.spans.interfaces.EnrichedBlockSpan
|
|
11
|
+
|
|
12
|
+
// https://android.googlesource.com/platform/frameworks/base/+/refs/heads/main/core/java/android/text/style/QuoteSpan.java
|
|
13
|
+
open class EnrichedBlockQuoteSpan(
|
|
14
|
+
private val enrichedStyle: EnrichedStyle,
|
|
15
|
+
) : MetricAffectingSpan(),
|
|
16
|
+
LeadingMarginSpan,
|
|
17
|
+
EnrichedBlockSpan {
|
|
18
|
+
override fun updateMeasureState(p0: TextPaint) {
|
|
19
|
+
// Do nothing, but inform layout that this span affects text metrics
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
override fun getLeadingMargin(p0: Boolean): Int = enrichedStyle.blockquoteStripeWidth + enrichedStyle.blockquoteGapWidth
|
|
23
|
+
|
|
24
|
+
override fun drawLeadingMargin(
|
|
25
|
+
c: Canvas,
|
|
26
|
+
p: Paint,
|
|
27
|
+
x: Int,
|
|
28
|
+
dir: Int,
|
|
29
|
+
top: Int,
|
|
30
|
+
baseline: Int,
|
|
31
|
+
bottom: Int,
|
|
32
|
+
text: CharSequence?,
|
|
33
|
+
start: Int,
|
|
34
|
+
end: Int,
|
|
35
|
+
first: Boolean,
|
|
36
|
+
layout: Layout?,
|
|
37
|
+
) {
|
|
38
|
+
val style = p.style
|
|
39
|
+
val color = p.color
|
|
40
|
+
p.style = Paint.Style.FILL
|
|
41
|
+
p.color = enrichedStyle.blockquoteBorderColor
|
|
42
|
+
c.drawRect(x.toFloat(), top.toFloat(), x + dir * enrichedStyle.blockquoteStripeWidth.toFloat(), bottom.toFloat(), p)
|
|
43
|
+
p.style = style
|
|
44
|
+
p.color = color
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
override fun updateDrawState(textPaint: TextPaint?) {
|
|
48
|
+
val color = enrichedStyle.blockquoteColor
|
|
49
|
+
if (color != null) {
|
|
50
|
+
textPaint?.color = color
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
package com.swmansion.enriched.common.spans
|
|
2
|
+
|
|
3
|
+
import android.graphics.Typeface
|
|
4
|
+
import android.text.style.StyleSpan
|
|
5
|
+
import com.swmansion.enriched.common.EnrichedStyle
|
|
6
|
+
import com.swmansion.enriched.common.spans.interfaces.EnrichedInlineSpan
|
|
7
|
+
|
|
8
|
+
@Suppress("UNUSED_PARAMETER")
|
|
9
|
+
open class EnrichedBoldSpan(
|
|
10
|
+
enrichedStyle: EnrichedStyle,
|
|
11
|
+
) : StyleSpan(Typeface.BOLD),
|
|
12
|
+
EnrichedInlineSpan
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
package com.swmansion.enriched.common.spans
|
|
2
|
+
|
|
3
|
+
import android.graphics.Canvas
|
|
4
|
+
import android.graphics.Paint
|
|
5
|
+
import android.text.Layout
|
|
6
|
+
import android.text.Spanned
|
|
7
|
+
import android.text.TextPaint
|
|
8
|
+
import android.text.style.LeadingMarginSpan
|
|
9
|
+
import android.text.style.LineHeightSpan
|
|
10
|
+
import android.text.style.MetricAffectingSpan
|
|
11
|
+
import androidx.core.graphics.withTranslation
|
|
12
|
+
import com.swmansion.enriched.common.CheckboxDrawable
|
|
13
|
+
import com.swmansion.enriched.common.EnrichedStyle
|
|
14
|
+
import com.swmansion.enriched.common.spans.interfaces.EnrichedParagraphSpan
|
|
15
|
+
import com.swmansion.enriched.textinput.styles.HtmlStyle
|
|
16
|
+
|
|
17
|
+
open class EnrichedCheckboxListSpan(
|
|
18
|
+
open var isChecked: Boolean,
|
|
19
|
+
private val enrichedStyle: EnrichedStyle,
|
|
20
|
+
) : MetricAffectingSpan(),
|
|
21
|
+
LineHeightSpan,
|
|
22
|
+
LeadingMarginSpan,
|
|
23
|
+
EnrichedParagraphSpan {
|
|
24
|
+
private val checkboxDrawable =
|
|
25
|
+
CheckboxDrawable(enrichedStyle.ulCheckboxBoxSize, enrichedStyle.ulCheckboxBoxColor, isChecked).apply {
|
|
26
|
+
setBounds(0, 0, enrichedStyle.ulCheckboxBoxSize, enrichedStyle.ulCheckboxBoxSize)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
override fun updateMeasureState(tp: TextPaint) {
|
|
30
|
+
// Do nothing, but inform layout that this span affects text metrics
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
override fun updateDrawState(tp: TextPaint) {
|
|
34
|
+
// Do nothing, but inform layout that this span affects text metrics
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Include checkbox size in text measurements to avoid clipping
|
|
38
|
+
override fun chooseHeight(
|
|
39
|
+
text: CharSequence,
|
|
40
|
+
start: Int,
|
|
41
|
+
end: Int,
|
|
42
|
+
spanstartv: Int,
|
|
43
|
+
v: Int,
|
|
44
|
+
fm: Paint.FontMetricsInt,
|
|
45
|
+
) {
|
|
46
|
+
val checkboxSize = enrichedStyle.ulCheckboxBoxSize
|
|
47
|
+
val currentLineHeight = fm.descent - fm.ascent
|
|
48
|
+
|
|
49
|
+
if (checkboxSize > currentLineHeight) {
|
|
50
|
+
val extraSpace = checkboxSize - currentLineHeight
|
|
51
|
+
val halfExtra = extraSpace / 2
|
|
52
|
+
|
|
53
|
+
fm.ascent -= halfExtra
|
|
54
|
+
fm.descent += (extraSpace - halfExtra)
|
|
55
|
+
|
|
56
|
+
fm.top -= halfExtra
|
|
57
|
+
fm.bottom += (extraSpace - halfExtra)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
override fun getLeadingMargin(first: Boolean): Int =
|
|
62
|
+
enrichedStyle.ulCheckboxBoxSize + enrichedStyle.ulCheckboxMarginLeft + enrichedStyle.ulCheckboxGapWidth
|
|
63
|
+
|
|
64
|
+
override fun drawLeadingMargin(
|
|
65
|
+
canvas: Canvas,
|
|
66
|
+
paint: Paint,
|
|
67
|
+
x: Int,
|
|
68
|
+
dir: Int,
|
|
69
|
+
top: Int,
|
|
70
|
+
baseline: Int,
|
|
71
|
+
bottom: Int,
|
|
72
|
+
text: CharSequence,
|
|
73
|
+
start: Int,
|
|
74
|
+
end: Int,
|
|
75
|
+
first: Boolean,
|
|
76
|
+
layout: Layout?,
|
|
77
|
+
) {
|
|
78
|
+
val spannedText = text as Spanned
|
|
79
|
+
|
|
80
|
+
if (spannedText.getSpanStart(this) == start) {
|
|
81
|
+
checkboxDrawable.update(isChecked)
|
|
82
|
+
|
|
83
|
+
val fm = paint.fontMetricsInt
|
|
84
|
+
val textCenter = baseline + (fm.ascent + fm.descent) / 2f
|
|
85
|
+
val drawableTop = textCenter - (enrichedStyle.ulCheckboxBoxSize / 2f)
|
|
86
|
+
|
|
87
|
+
canvas.withTranslation(x.toFloat() + enrichedStyle.ulCheckboxMarginLeft, drawableTop) {
|
|
88
|
+
checkboxDrawable.draw(this)
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
package com.swmansion.enriched.common.spans
|
|
2
|
+
|
|
3
|
+
import android.graphics.Canvas
|
|
4
|
+
import android.graphics.Paint
|
|
5
|
+
import android.graphics.Path
|
|
6
|
+
import android.graphics.RectF
|
|
7
|
+
import android.graphics.Typeface
|
|
8
|
+
import android.text.Spanned
|
|
9
|
+
import android.text.TextPaint
|
|
10
|
+
import android.text.style.LineBackgroundSpan
|
|
11
|
+
import android.text.style.MetricAffectingSpan
|
|
12
|
+
import com.swmansion.enriched.common.EnrichedStyle
|
|
13
|
+
import com.swmansion.enriched.common.spans.interfaces.EnrichedBlockSpan
|
|
14
|
+
|
|
15
|
+
open class EnrichedCodeBlockSpan(
|
|
16
|
+
private val enrichedStyle: EnrichedStyle,
|
|
17
|
+
) : MetricAffectingSpan(),
|
|
18
|
+
LineBackgroundSpan,
|
|
19
|
+
EnrichedBlockSpan {
|
|
20
|
+
override fun updateDrawState(paint: TextPaint) {
|
|
21
|
+
paint.typeface = Typeface.MONOSPACE
|
|
22
|
+
paint.color = enrichedStyle.codeBlockColor
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
override fun updateMeasureState(paint: TextPaint) {
|
|
26
|
+
paint.typeface = Typeface.MONOSPACE
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
override fun drawBackground(
|
|
30
|
+
canvas: Canvas,
|
|
31
|
+
p: Paint,
|
|
32
|
+
left: Int,
|
|
33
|
+
right: Int,
|
|
34
|
+
top: Int,
|
|
35
|
+
baseline: Int,
|
|
36
|
+
bottom: Int,
|
|
37
|
+
text: CharSequence,
|
|
38
|
+
start: Int,
|
|
39
|
+
end: Int,
|
|
40
|
+
lineNum: Int,
|
|
41
|
+
) {
|
|
42
|
+
if (text !is Spanned) {
|
|
43
|
+
return
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
val previousColor = p.color
|
|
47
|
+
p.color = enrichedStyle.codeBlockBackgroundColor
|
|
48
|
+
|
|
49
|
+
val radius = enrichedStyle.codeBlockRadius
|
|
50
|
+
|
|
51
|
+
val spanStart = text.getSpanStart(this)
|
|
52
|
+
val spanEnd = text.getSpanEnd(this)
|
|
53
|
+
val isFirstLineOfSpan = start == spanStart
|
|
54
|
+
val isLastLineOfSpan = end == spanEnd || (spanEnd + 1 == end && text[spanEnd] == '\n')
|
|
55
|
+
|
|
56
|
+
val path = Path()
|
|
57
|
+
val radii = floatArrayOf(0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f)
|
|
58
|
+
|
|
59
|
+
if (isFirstLineOfSpan) {
|
|
60
|
+
// Top-Left and Top-Right corners
|
|
61
|
+
radii[0] = radius
|
|
62
|
+
radii[1] = radius
|
|
63
|
+
radii[2] = radius
|
|
64
|
+
radii[3] = radius
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (isLastLineOfSpan) {
|
|
68
|
+
// Bottom-Right and Bottom-Left corners
|
|
69
|
+
radii[4] = radius
|
|
70
|
+
radii[5] = radius
|
|
71
|
+
radii[6] = radius
|
|
72
|
+
radii[7] = radius
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
val rect = RectF(left.toFloat(), top.toFloat(), right.toFloat(), bottom.toFloat())
|
|
76
|
+
|
|
77
|
+
path.addRoundRect(rect, radii, Path.Direction.CW)
|
|
78
|
+
canvas.drawPath(path, p)
|
|
79
|
+
p.color = previousColor
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
package com.swmansion.enriched.common.spans
|
|
2
|
+
|
|
3
|
+
import android.graphics.Typeface
|
|
4
|
+
import android.text.TextPaint
|
|
5
|
+
import android.text.style.AbsoluteSizeSpan
|
|
6
|
+
import com.swmansion.enriched.common.EnrichedStyle
|
|
7
|
+
import com.swmansion.enriched.common.spans.interfaces.EnrichedHeadingSpan
|
|
8
|
+
|
|
9
|
+
open class EnrichedH1Span(
|
|
10
|
+
private val enrichedStyle: EnrichedStyle,
|
|
11
|
+
) : AbsoluteSizeSpan(enrichedStyle.h1FontSize),
|
|
12
|
+
EnrichedHeadingSpan {
|
|
13
|
+
override fun updateDrawState(tp: TextPaint) {
|
|
14
|
+
super.updateDrawState(tp)
|
|
15
|
+
val bold = enrichedStyle.h1Bold
|
|
16
|
+
if (bold) {
|
|
17
|
+
tp.typeface = Typeface.create(tp.typeface, Typeface.BOLD)
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
package com.swmansion.enriched.common.spans
|
|
2
|
+
|
|
3
|
+
import android.graphics.Typeface
|
|
4
|
+
import android.text.TextPaint
|
|
5
|
+
import android.text.style.AbsoluteSizeSpan
|
|
6
|
+
import com.swmansion.enriched.common.EnrichedStyle
|
|
7
|
+
import com.swmansion.enriched.common.spans.interfaces.EnrichedHeadingSpan
|
|
8
|
+
|
|
9
|
+
open class EnrichedH2Span(
|
|
10
|
+
private val enrichedStyle: EnrichedStyle,
|
|
11
|
+
) : AbsoluteSizeSpan(enrichedStyle.h2FontSize),
|
|
12
|
+
EnrichedHeadingSpan {
|
|
13
|
+
override fun updateDrawState(tp: TextPaint) {
|
|
14
|
+
super.updateDrawState(tp)
|
|
15
|
+
val bold = enrichedStyle.h2Bold
|
|
16
|
+
if (bold) {
|
|
17
|
+
tp.typeface = Typeface.create(tp.typeface, Typeface.BOLD)
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
package com.swmansion.enriched.common.spans
|
|
2
|
+
|
|
3
|
+
import android.graphics.Typeface
|
|
4
|
+
import android.text.TextPaint
|
|
5
|
+
import android.text.style.AbsoluteSizeSpan
|
|
6
|
+
import com.swmansion.enriched.common.EnrichedStyle
|
|
7
|
+
import com.swmansion.enriched.common.spans.interfaces.EnrichedHeadingSpan
|
|
8
|
+
|
|
9
|
+
open class EnrichedH3Span(
|
|
10
|
+
private val enrichedStyle: EnrichedStyle,
|
|
11
|
+
) : AbsoluteSizeSpan(enrichedStyle.h3FontSize),
|
|
12
|
+
EnrichedHeadingSpan {
|
|
13
|
+
override fun updateDrawState(tp: TextPaint) {
|
|
14
|
+
super.updateDrawState(tp)
|
|
15
|
+
val bold = enrichedStyle.h3Bold
|
|
16
|
+
if (bold) {
|
|
17
|
+
tp.typeface = Typeface.create(tp.typeface, Typeface.BOLD)
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
package com.swmansion.enriched.common.spans
|
|
2
|
+
|
|
3
|
+
import android.graphics.Typeface
|
|
4
|
+
import android.text.TextPaint
|
|
5
|
+
import android.text.style.AbsoluteSizeSpan
|
|
6
|
+
import com.swmansion.enriched.common.EnrichedStyle
|
|
7
|
+
import com.swmansion.enriched.common.spans.interfaces.EnrichedHeadingSpan
|
|
8
|
+
import com.swmansion.enriched.textinput.styles.HtmlStyle
|
|
9
|
+
|
|
10
|
+
open class EnrichedH4Span(
|
|
11
|
+
private val enrichedStyle: EnrichedStyle,
|
|
12
|
+
) : AbsoluteSizeSpan(enrichedStyle.h4FontSize),
|
|
13
|
+
EnrichedHeadingSpan {
|
|
14
|
+
override fun updateDrawState(tp: TextPaint) {
|
|
15
|
+
super.updateDrawState(tp)
|
|
16
|
+
val bold = enrichedStyle.h4Bold
|
|
17
|
+
if (bold) {
|
|
18
|
+
tp.typeface = Typeface.create(tp.typeface, Typeface.BOLD)
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
package com.swmansion.enriched.common.spans
|
|
2
|
+
|
|
3
|
+
import android.graphics.Typeface
|
|
4
|
+
import android.text.TextPaint
|
|
5
|
+
import android.text.style.AbsoluteSizeSpan
|
|
6
|
+
import com.swmansion.enriched.common.EnrichedStyle
|
|
7
|
+
import com.swmansion.enriched.common.spans.interfaces.EnrichedHeadingSpan
|
|
8
|
+
|
|
9
|
+
open class EnrichedH5Span(
|
|
10
|
+
private val enrichedStyle: EnrichedStyle,
|
|
11
|
+
) : AbsoluteSizeSpan(enrichedStyle.h5FontSize),
|
|
12
|
+
EnrichedHeadingSpan {
|
|
13
|
+
override fun updateDrawState(tp: TextPaint) {
|
|
14
|
+
super.updateDrawState(tp)
|
|
15
|
+
val bold = enrichedStyle.h5Bold
|
|
16
|
+
if (bold) {
|
|
17
|
+
tp.typeface = Typeface.create(tp.typeface, Typeface.BOLD)
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
package com.swmansion.enriched.common.spans
|
|
2
|
+
|
|
3
|
+
import android.graphics.Typeface
|
|
4
|
+
import android.text.TextPaint
|
|
5
|
+
import android.text.style.AbsoluteSizeSpan
|
|
6
|
+
import com.swmansion.enriched.common.EnrichedStyle
|
|
7
|
+
import com.swmansion.enriched.common.spans.interfaces.EnrichedHeadingSpan
|
|
8
|
+
|
|
9
|
+
open class EnrichedH6Span(
|
|
10
|
+
private val enrichedStyle: EnrichedStyle,
|
|
11
|
+
) : AbsoluteSizeSpan(enrichedStyle.h6FontSize),
|
|
12
|
+
EnrichedHeadingSpan {
|
|
13
|
+
override fun updateDrawState(tp: TextPaint) {
|
|
14
|
+
super.updateDrawState(tp)
|
|
15
|
+
val bold = enrichedStyle.h6Bold
|
|
16
|
+
if (bold) {
|
|
17
|
+
tp.typeface = Typeface.create(tp.typeface, Typeface.BOLD)
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
package com.swmansion.enriched.common.spans
|
|
2
|
+
|
|
3
|
+
import android.content.res.Resources
|
|
4
|
+
import android.graphics.BitmapFactory
|
|
5
|
+
import android.graphics.Canvas
|
|
6
|
+
import android.graphics.ImageDecoder
|
|
7
|
+
import android.graphics.Paint
|
|
8
|
+
import android.graphics.drawable.AnimatedImageDrawable
|
|
9
|
+
import android.graphics.drawable.Drawable
|
|
10
|
+
import android.os.Build
|
|
11
|
+
import android.text.Editable
|
|
12
|
+
import android.text.Spannable
|
|
13
|
+
import android.text.style.ImageSpan
|
|
14
|
+
import android.util.Log
|
|
15
|
+
import androidx.core.graphics.drawable.toDrawable
|
|
16
|
+
import androidx.core.graphics.withSave
|
|
17
|
+
import com.swmansion.enriched.R
|
|
18
|
+
import com.swmansion.enriched.common.AsyncDrawable
|
|
19
|
+
import com.swmansion.enriched.common.ForceRedrawSpan
|
|
20
|
+
import com.swmansion.enriched.common.ResourceManager
|
|
21
|
+
import com.swmansion.enriched.common.spans.interfaces.EnrichedInlineSpan
|
|
22
|
+
import java.io.File
|
|
23
|
+
|
|
24
|
+
open class EnrichedImageSpan :
|
|
25
|
+
ImageSpan,
|
|
26
|
+
EnrichedInlineSpan {
|
|
27
|
+
private var width: Int = 0
|
|
28
|
+
private var height: Int = 0
|
|
29
|
+
|
|
30
|
+
constructor(drawable: Drawable, source: String, width: Int, height: Int) : super(drawable, source, ALIGN_BASELINE) {
|
|
31
|
+
this.width = width
|
|
32
|
+
this.height = height
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
override fun draw(
|
|
36
|
+
canvas: Canvas,
|
|
37
|
+
text: CharSequence?,
|
|
38
|
+
start: Int,
|
|
39
|
+
end: Int,
|
|
40
|
+
x: Float,
|
|
41
|
+
top: Int,
|
|
42
|
+
y: Int,
|
|
43
|
+
bottom: Int,
|
|
44
|
+
paint: Paint,
|
|
45
|
+
) {
|
|
46
|
+
val drawable = drawable
|
|
47
|
+
canvas.withSave {
|
|
48
|
+
val transY = bottom - drawable.bounds.bottom - paint.fontMetricsInt.descent
|
|
49
|
+
translate(x, transY.toFloat())
|
|
50
|
+
drawable.draw(this)
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
override fun getDrawable(): Drawable {
|
|
55
|
+
val drawable = super.getDrawable()
|
|
56
|
+
val scale = Resources.getSystem().displayMetrics.density
|
|
57
|
+
|
|
58
|
+
drawable.setBounds(0, 0, (width * scale).toInt(), (height * scale).toInt())
|
|
59
|
+
return drawable
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
override fun getSize(
|
|
63
|
+
paint: Paint,
|
|
64
|
+
text: CharSequence?,
|
|
65
|
+
start: Int,
|
|
66
|
+
end: Int,
|
|
67
|
+
fm: Paint.FontMetricsInt?,
|
|
68
|
+
): Int {
|
|
69
|
+
val d = drawable
|
|
70
|
+
val rect = d.bounds
|
|
71
|
+
|
|
72
|
+
if (fm != null) {
|
|
73
|
+
val imageHeight = rect.bottom - rect.top
|
|
74
|
+
|
|
75
|
+
// We want the image bottom to sit on the baseline (0).
|
|
76
|
+
// Therefore, the image top will be at: -imageHeight.
|
|
77
|
+
val targetTop = -imageHeight
|
|
78
|
+
|
|
79
|
+
// Expand the line UPWARDS if the image is taller than the current font
|
|
80
|
+
if (targetTop < fm.ascent) {
|
|
81
|
+
fm.ascent = targetTop
|
|
82
|
+
fm.top = targetTop
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return rect.right
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
private fun registerDrawableLoadCallback(
|
|
90
|
+
d: AsyncDrawable,
|
|
91
|
+
text: Editable?,
|
|
92
|
+
) {
|
|
93
|
+
d.onLoaded = onLoaded@{
|
|
94
|
+
val spannable = text as? Spannable
|
|
95
|
+
|
|
96
|
+
if (spannable == null) {
|
|
97
|
+
return@onLoaded
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
val start = spannable.getSpanStart(this@EnrichedImageSpan)
|
|
101
|
+
val end = spannable.getSpanEnd(this@EnrichedImageSpan)
|
|
102
|
+
|
|
103
|
+
if (start != -1 && end != -1) {
|
|
104
|
+
// trick for adding empty span to force redraw when image is loaded
|
|
105
|
+
val redrawSpan = ForceRedrawSpan()
|
|
106
|
+
spannable.setSpan(redrawSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
|
107
|
+
spannable.removeSpan(redrawSpan)
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
fun observeAsyncDrawableLoaded(text: Editable?) {
|
|
113
|
+
val d = drawable
|
|
114
|
+
|
|
115
|
+
if (d !is AsyncDrawable) {
|
|
116
|
+
return
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
registerDrawableLoadCallback(d, text)
|
|
120
|
+
|
|
121
|
+
// If it's already loaded (race condition), run logic immediately
|
|
122
|
+
if (d.isLoaded) {
|
|
123
|
+
d.onLoaded?.invoke()
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
fun getWidth(): Int = width
|
|
128
|
+
|
|
129
|
+
fun getHeight(): Int = height
|
|
130
|
+
|
|
131
|
+
companion object {
|
|
132
|
+
fun prepareDrawableForImage(
|
|
133
|
+
src: String,
|
|
134
|
+
width: Int,
|
|
135
|
+
height: Int,
|
|
136
|
+
): Drawable? {
|
|
137
|
+
var cleanPath = src
|
|
138
|
+
|
|
139
|
+
if (cleanPath.startsWith("http://") || cleanPath.startsWith("https://")) {
|
|
140
|
+
return AsyncDrawable(cleanPath)
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (cleanPath.startsWith("file://")) {
|
|
144
|
+
cleanPath = cleanPath.substring(7)
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
|
|
148
|
+
return try {
|
|
149
|
+
val bitmap = BitmapFactory.decodeFile(cleanPath) ?: return null
|
|
150
|
+
val drawable = bitmap.toDrawable(Resources.getSystem())
|
|
151
|
+
drawable.setBounds(0, 0, bitmap.width, bitmap.height)
|
|
152
|
+
return drawable
|
|
153
|
+
} catch (e: Exception) {
|
|
154
|
+
Log.e("EnrichedImageSpan", "Failed to load legacy image: $cleanPath", e)
|
|
155
|
+
null
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return try {
|
|
160
|
+
val file = File(cleanPath)
|
|
161
|
+
val source = ImageDecoder.createSource(file)
|
|
162
|
+
|
|
163
|
+
val density = Resources.getSystem().displayMetrics.density
|
|
164
|
+
val targetWidthPx = (width * density).toInt()
|
|
165
|
+
val targetHeightPx = (height * density).toInt()
|
|
166
|
+
|
|
167
|
+
val drawable =
|
|
168
|
+
ImageDecoder.decodeDrawable(source) { decoder, info, source ->
|
|
169
|
+
decoder.setTargetSize(targetWidthPx, targetHeightPx)
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (drawable is AnimatedImageDrawable) {
|
|
173
|
+
drawable.setBounds(0, 0, drawable.intrinsicWidth, drawable.intrinsicHeight)
|
|
174
|
+
drawable.repeatCount = AnimatedImageDrawable.REPEAT_INFINITE
|
|
175
|
+
drawable.start()
|
|
176
|
+
}
|
|
177
|
+
drawable
|
|
178
|
+
} catch (e: Exception) {
|
|
179
|
+
Log.e("EnrichedImageSpan", "Failed to load image: $cleanPath", e)
|
|
180
|
+
null
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
package com.swmansion.enriched.common.spans
|
|
2
|
+
|
|
3
|
+
import android.graphics.Typeface
|
|
4
|
+
import android.text.TextPaint
|
|
5
|
+
import android.text.style.MetricAffectingSpan
|
|
6
|
+
import com.swmansion.enriched.common.EnrichedStyle
|
|
7
|
+
import com.swmansion.enriched.common.spans.interfaces.EnrichedInlineSpan
|
|
8
|
+
|
|
9
|
+
open class EnrichedInlineCodeSpan(
|
|
10
|
+
private val enrichedStyle: EnrichedStyle,
|
|
11
|
+
) : MetricAffectingSpan(),
|
|
12
|
+
EnrichedInlineSpan {
|
|
13
|
+
override fun updateDrawState(textPaint: TextPaint) {
|
|
14
|
+
val typeface = Typeface.create(Typeface.MONOSPACE, Typeface.NORMAL)
|
|
15
|
+
textPaint.typeface = typeface
|
|
16
|
+
textPaint.color = enrichedStyle.inlineCodeColor
|
|
17
|
+
textPaint.bgColor = enrichedStyle.inlineCodeBackgroundColor
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
override fun updateMeasureState(textPaint: TextPaint) {
|
|
21
|
+
val typeface = Typeface.create(Typeface.MONOSPACE, Typeface.NORMAL)
|
|
22
|
+
textPaint.typeface = typeface
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
package com.swmansion.enriched.common.spans
|
|
2
|
+
|
|
3
|
+
import android.graphics.Typeface
|
|
4
|
+
import android.text.style.StyleSpan
|
|
5
|
+
import com.swmansion.enriched.common.EnrichedStyle
|
|
6
|
+
import com.swmansion.enriched.common.spans.interfaces.EnrichedInlineSpan
|
|
7
|
+
|
|
8
|
+
@Suppress("UNUSED_PARAMETER")
|
|
9
|
+
open class EnrichedItalicSpan(
|
|
10
|
+
private val enrichedStyle: EnrichedStyle,
|
|
11
|
+
) : StyleSpan(Typeface.ITALIC),
|
|
12
|
+
EnrichedInlineSpan
|