react-native-marcus 0.1.0
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 +201 -0
- package/README.md +227 -0
- package/RNMarcus.podspec +78 -0
- package/android/build.gradle +220 -0
- package/android/proguard-rules.pro +1 -0
- package/android/src/main/AndroidManifest.xml +3 -0
- package/android/src/main/AndroidManifestNew.xml +2 -0
- package/android/src/main/cpp/CMakeLists.txt +41 -0
- package/android/src/main/cpp/MarkdownParser.cpp +49 -0
- package/android/src/main/cpp/MarkdownParser.h +56 -0
- package/android/src/main/cpp/OnLoad.cpp +17 -0
- package/android/src/main/java/app/getbullet/marcus/MarcusModule.kt +28 -0
- package/android/src/main/java/app/getbullet/marcus/MarcusPackage.kt +31 -0
- package/android/src/main/java/app/getbullet/marcus/MarcusTextInputDecoratorView.kt +63 -0
- package/android/src/main/java/app/getbullet/marcus/MarcusTextInputDecoratorViewManager.kt +32 -0
- package/android/src/main/java/app/getbullet/marcus/MarcusTextInputDecoratorViewManagerSpec.kt +21 -0
- package/android/src/main/java/app/getbullet/marcus/MarkdownFormatter.kt +333 -0
- package/android/src/main/java/app/getbullet/marcus/MarkdownParseResult.kt +12 -0
- package/android/src/main/java/app/getbullet/marcus/MarkdownParser.kt +89 -0
- package/android/src/main/java/app/getbullet/marcus/MarkdownRange.kt +11 -0
- package/android/src/main/java/app/getbullet/marcus/MarkdownStyle.kt +81 -0
- package/android/src/main/java/app/getbullet/marcus/MarkdownTextWatcher.kt +17 -0
- package/android/src/main/java/app/getbullet/marcus/MarkdownUtils.kt +84 -0
- package/android/src/main/java/app/getbullet/marcus/ReactLineHeight.java +29 -0
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownBackgroundColorSpan.kt +6 -0
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownBackgroundSpan.kt +105 -0
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownBlockIndentSpan.kt +67 -0
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownBoldSpan.kt +6 -0
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownFontFamilySpan.kt +28 -0
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownFontSizeSpan.kt +7 -0
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownForegroundColorSpan.kt +6 -0
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownGapSpan.kt +57 -0
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownItalicSpan.kt +6 -0
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownLineHeightSpan.kt +21 -0
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownSpan.kt +7 -0
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownStrikethroughSpan.kt +5 -0
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownUnderlineSpan.kt +5 -0
- package/android/src/main/new_arch/CMakeLists.txt +70 -0
- package/android/src/main/new_arch/RNMarcusSpec.cpp +43 -0
- package/android/src/main/new_arch/RNMarcusSpec.h +36 -0
- package/android/src/main/new_arch/react/renderer/components/RNMarcusSpec/MarcusTextInputDecoratorShadowNode.cpp +218 -0
- package/android/src/main/new_arch/react/renderer/components/RNMarcusSpec/MarcusTextInputDecoratorShadowNode.h +54 -0
- package/android/src/reactNativeVersionPatch/CustomMountingManager/81/app/getbullet/marcus/CustomFabricUIManager.java +156 -0
- package/android/src/reactNativeVersionPatch/CustomMountingManager/latest/app/getbullet/marcus/CustomFabricUIManager.java +130 -0
- package/android/src/test/java/app/getbullet/marcus/MarkdownFormatterTest.kt +205 -0
- package/android/src/test/java/app/getbullet/marcus/RenderModel.kt +78 -0
- package/android/src/test/resources/render-model.txt +583 -0
- package/apple/MarcusModule.h +8 -0
- package/apple/MarcusModule.mm +26 -0
- package/apple/MarcusRange.h +15 -0
- package/apple/MarcusRange.mm +15 -0
- package/apple/MarcusTextInputDecoratorComponentView.h +12 -0
- package/apple/MarcusTextInputDecoratorComponentView.mm +121 -0
- package/apple/MarcusTextInputDecoratorShadowNode.cpp +251 -0
- package/apple/MarcusTextInputDecoratorShadowNode.h +65 -0
- package/apple/MarcusTextInputDecoratorShadowNode.mm +204 -0
- package/apple/MarcusTextInputDecoratorViewManager.h +8 -0
- package/apple/MarcusTextInputDecoratorViewManager.mm +11 -0
- package/apple/MarkdownAdaptiveImageGlyph.swift +44 -0
- package/apple/MarkdownAttributes.h +31 -0
- package/apple/MarkdownAttributes.m +9 -0
- package/apple/MarkdownBackedTextInputDelegate.swift +117 -0
- package/apple/MarkdownDecorator.swift +316 -0
- package/apple/MarkdownFonts.swift +21 -0
- package/apple/MarkdownFormatter+React.swift +51 -0
- package/apple/MarkdownFormatter.swift +509 -0
- package/apple/MarkdownLog.h +10 -0
- package/apple/MarkdownLog.mm +6 -0
- package/apple/MarkdownParser.swift +200 -0
- package/apple/MarkdownSwiftInterop.h +23 -0
- package/apple/MarkdownTextBackground.swift +17 -0
- package/apple/MarkdownTextFieldObserver.swift +90 -0
- package/apple/MarkdownTextLayoutFragment.swift +205 -0
- package/apple/MarkdownTextLayoutManagerDelegate.swift +84 -0
- package/apple/MarkdownTextStorageDelegate.swift +32 -0
- package/apple/MarkdownTextViewObserver.swift +30 -0
- package/apple/RCTMarcusStyle+Codegen.h +18 -0
- package/apple/RCTMarcusStyle+Codegen.mm +64 -0
- package/apple/RCTMarcusStyle.h +41 -0
- package/apple/RCTMarcusStyle.m +5 -0
- package/apple/RCTMarcusUtils.h +26 -0
- package/apple/RCTMarcusUtils.mm +26 -0
- package/apple/RCTTextInput+AdaptiveImageGlyph.h +16 -0
- package/apple/RCTTextInput+AdaptiveImageGlyph.mm +79 -0
- package/apple/RCTTextInputComponentView+Marcus.h +11 -0
- package/apple/RCTTextInputComponentView+Marcus.mm +79 -0
- package/cpp/MarkdownCxx.modulemap +8 -0
- package/cpp/MarkdownGlobal.cpp +48 -0
- package/cpp/MarkdownGlobal.h +33 -0
- package/cpp/MarkdownWorkletParser.cpp +93 -0
- package/cpp/MarkdownWorkletParser.h +45 -0
- package/cpp/RuntimeDecorator.cpp +39 -0
- package/cpp/RuntimeDecorator.h +14 -0
- package/cpp/react/renderer/components/RNMarcusSpec/MarcusTextInputDecoratorState.h +33 -0
- package/cpp/react/renderer/components/RNMarcusSpec/MarcusTextInputDecoratorViewComponentDescriptor.h +17 -0
- package/lib/commonjs/MarcusTextInputDecoratorViewNativeComponent.ts +77 -0
- package/lib/commonjs/MarkdownTextInput.js +99 -0
- package/lib/commonjs/MarkdownTextInput.js.map +1 -0
- package/lib/commonjs/MarkdownTextInput.web.js +618 -0
- package/lib/commonjs/MarkdownTextInput.web.js.map +1 -0
- package/lib/commonjs/NativeMarcusModule.js +9 -0
- package/lib/commonjs/NativeMarcusModule.js.map +1 -0
- package/lib/commonjs/commonTypes.js +2 -0
- package/lib/commonjs/commonTypes.js.map +1 -0
- package/lib/commonjs/global.d.js +2 -0
- package/lib/commonjs/global.d.js.map +1 -0
- package/lib/commonjs/index.js +27 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/parser/index.js +7030 -0
- package/lib/commonjs/parser/index.js.map +7 -0
- package/lib/commonjs/rangeUtils.js +71 -0
- package/lib/commonjs/rangeUtils.js.map +1 -0
- package/lib/commonjs/react-native-web.d.js +2 -0
- package/lib/commonjs/react-native-web.d.js.map +1 -0
- package/lib/commonjs/styleUtils.js +91 -0
- package/lib/commonjs/styleUtils.js.map +1 -0
- package/lib/commonjs/web/InputHistory.js +111 -0
- package/lib/commonjs/web/InputHistory.js.map +1 -0
- package/lib/commonjs/web/MarkdownTextInput.css +72 -0
- package/lib/commonjs/web/utils/blockLayout.js +132 -0
- package/lib/commonjs/web/utils/blockLayout.js.map +1 -0
- package/lib/commonjs/web/utils/blockUtils.js +219 -0
- package/lib/commonjs/web/utils/blockUtils.js.map +1 -0
- package/lib/commonjs/web/utils/browserUtils.js +40 -0
- package/lib/commonjs/web/utils/browserUtils.js.map +1 -0
- package/lib/commonjs/web/utils/cursorUtils.js +157 -0
- package/lib/commonjs/web/utils/cursorUtils.js.map +1 -0
- package/lib/commonjs/web/utils/inputUtils.js +152 -0
- package/lib/commonjs/web/utils/inputUtils.js.map +1 -0
- package/lib/commonjs/web/utils/measureUtils.js +0 -0
- package/lib/commonjs/web/utils/measureUtils.js.map +1 -0
- package/lib/commonjs/web/utils/parserUtils.js +552 -0
- package/lib/commonjs/web/utils/parserUtils.js.map +1 -0
- package/lib/commonjs/web/utils/treeUtils.js +109 -0
- package/lib/commonjs/web/utils/treeUtils.js.map +1 -0
- package/lib/commonjs/web/utils/webStyleUtils.js +59 -0
- package/lib/commonjs/web/utils/webStyleUtils.js.map +1 -0
- package/lib/module/MarcusTextInputDecoratorViewNativeComponent.ts +77 -0
- package/lib/module/MarkdownTextInput.js +94 -0
- package/lib/module/MarkdownTextInput.js.map +1 -0
- package/lib/module/MarkdownTextInput.web.js +612 -0
- package/lib/module/MarkdownTextInput.web.js.map +1 -0
- package/lib/module/NativeMarcusModule.js +5 -0
- package/lib/module/NativeMarcusModule.js.map +1 -0
- package/lib/module/commonTypes.js +2 -0
- package/lib/module/commonTypes.js.map +1 -0
- package/lib/module/global.d.js +2 -0
- package/lib/module/global.d.js.map +1 -0
- package/lib/module/index.js +5 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/parser/index.js +7029 -0
- package/lib/module/parser/index.js.map +7 -0
- package/lib/module/rangeUtils.js +66 -0
- package/lib/module/rangeUtils.js.map +1 -0
- package/lib/module/react-native-web.d.js +2 -0
- package/lib/module/react-native-web.d.js.map +1 -0
- package/lib/module/styleUtils.js +88 -0
- package/lib/module/styleUtils.js.map +1 -0
- package/lib/module/web/InputHistory.js +106 -0
- package/lib/module/web/InputHistory.js.map +1 -0
- package/lib/module/web/MarkdownTextInput.css +72 -0
- package/lib/module/web/utils/blockLayout.js +128 -0
- package/lib/module/web/utils/blockLayout.js.map +1 -0
- package/lib/module/web/utils/blockUtils.js +210 -0
- package/lib/module/web/utils/blockUtils.js.map +1 -0
- package/lib/module/web/utils/browserUtils.js +36 -0
- package/lib/module/web/utils/browserUtils.js.map +1 -0
- package/lib/module/web/utils/cursorUtils.js +150 -0
- package/lib/module/web/utils/cursorUtils.js.map +1 -0
- package/lib/module/web/utils/inputUtils.js +144 -0
- package/lib/module/web/utils/inputUtils.js.map +1 -0
- package/lib/module/web/utils/measureUtils.js +0 -0
- package/lib/module/web/utils/measureUtils.js.map +1 -0
- package/lib/module/web/utils/parserUtils.js +547 -0
- package/lib/module/web/utils/parserUtils.js.map +1 -0
- package/lib/module/web/utils/treeUtils.js +103 -0
- package/lib/module/web/utils/treeUtils.js.map +1 -0
- package/lib/module/web/utils/webStyleUtils.js +54 -0
- package/lib/module/web/utils/webStyleUtils.js.map +1 -0
- package/lib/typescript/commonjs/e2e/checks.test.d.ts +2 -0
- package/lib/typescript/commonjs/e2e/checks.test.d.ts.map +1 -0
- package/lib/typescript/commonjs/e2e/editing.test.d.ts +2 -0
- package/lib/typescript/commonjs/e2e/editing.test.d.ts.map +1 -0
- package/lib/typescript/commonjs/e2e/helpers.d.ts +23 -0
- package/lib/typescript/commonjs/e2e/helpers.d.ts.map +1 -0
- package/lib/typescript/commonjs/e2e/smoke.test.d.ts +2 -0
- package/lib/typescript/commonjs/e2e/smoke.test.d.ts.map +1 -0
- package/lib/typescript/commonjs/package.json +1 -0
- package/lib/typescript/commonjs/src/MarcusTextInputDecoratorViewNativeComponent.d.ts +63 -0
- package/lib/typescript/commonjs/src/MarcusTextInputDecoratorViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/MarkdownTextInput.d.ts +22 -0
- package/lib/typescript/commonjs/src/MarkdownTextInput.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/MarkdownTextInput.web.d.ts +41 -0
- package/lib/typescript/commonjs/src/MarkdownTextInput.web.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/NativeMarcusModule.d.ts +7 -0
- package/lib/typescript/commonjs/src/NativeMarcusModule.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/commonTypes.d.ts +10 -0
- package/lib/typescript/commonjs/src/commonTypes.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/index.d.ts +5 -0
- package/lib/typescript/commonjs/src/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/parser/index.d.ts +8 -0
- package/lib/typescript/commonjs/src/parser/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/parser/micromark-extension-mentions.d.ts +8 -0
- package/lib/typescript/commonjs/src/parser/micromark-extension-mentions.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/rangeUtils.d.ts +6 -0
- package/lib/typescript/commonjs/src/rangeUtils.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/styleUtils.d.ts +8 -0
- package/lib/typescript/commonjs/src/styleUtils.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/web/InputHistory.d.ts +24 -0
- package/lib/typescript/commonjs/src/web/InputHistory.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/web/utils/blockLayout.d.ts +41 -0
- package/lib/typescript/commonjs/src/web/utils/blockLayout.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/web/utils/blockUtils.d.ts +33 -0
- package/lib/typescript/commonjs/src/web/utils/blockUtils.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/web/utils/browserUtils.d.ts +7 -0
- package/lib/typescript/commonjs/src/web/utils/browserUtils.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/web/utils/cursorUtils.d.ts +12 -0
- package/lib/typescript/commonjs/src/web/utils/cursorUtils.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/web/utils/inputUtils.d.ts +12 -0
- package/lib/typescript/commonjs/src/web/utils/inputUtils.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/web/utils/measureUtils.d.ts +22 -0
- package/lib/typescript/commonjs/src/web/utils/measureUtils.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/web/utils/parserUtils.d.ts +44 -0
- package/lib/typescript/commonjs/src/web/utils/parserUtils.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/web/utils/treeUtils.d.ts +25 -0
- package/lib/typescript/commonjs/src/web/utils/treeUtils.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/web/utils/webStyleUtils.d.ts +7 -0
- package/lib/typescript/commonjs/src/web/utils/webStyleUtils.d.ts.map +1 -0
- package/lib/typescript/module/e2e/checks.test.d.ts +2 -0
- package/lib/typescript/module/e2e/checks.test.d.ts.map +1 -0
- package/lib/typescript/module/e2e/editing.test.d.ts +2 -0
- package/lib/typescript/module/e2e/editing.test.d.ts.map +1 -0
- package/lib/typescript/module/e2e/helpers.d.ts +23 -0
- package/lib/typescript/module/e2e/helpers.d.ts.map +1 -0
- package/lib/typescript/module/e2e/smoke.test.d.ts +2 -0
- package/lib/typescript/module/e2e/smoke.test.d.ts.map +1 -0
- package/lib/typescript/module/package.json +1 -0
- package/lib/typescript/module/src/MarcusTextInputDecoratorViewNativeComponent.d.ts +63 -0
- package/lib/typescript/module/src/MarcusTextInputDecoratorViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/module/src/MarkdownTextInput.d.ts +22 -0
- package/lib/typescript/module/src/MarkdownTextInput.d.ts.map +1 -0
- package/lib/typescript/module/src/MarkdownTextInput.web.d.ts +41 -0
- package/lib/typescript/module/src/MarkdownTextInput.web.d.ts.map +1 -0
- package/lib/typescript/module/src/NativeMarcusModule.d.ts +7 -0
- package/lib/typescript/module/src/NativeMarcusModule.d.ts.map +1 -0
- package/lib/typescript/module/src/commonTypes.d.ts +10 -0
- package/lib/typescript/module/src/commonTypes.d.ts.map +1 -0
- package/lib/typescript/module/src/index.d.ts +5 -0
- package/lib/typescript/module/src/index.d.ts.map +1 -0
- package/lib/typescript/module/src/parser/index.d.ts +8 -0
- package/lib/typescript/module/src/parser/index.d.ts.map +1 -0
- package/lib/typescript/module/src/parser/micromark-extension-mentions.d.ts +8 -0
- package/lib/typescript/module/src/parser/micromark-extension-mentions.d.ts.map +1 -0
- package/lib/typescript/module/src/rangeUtils.d.ts +6 -0
- package/lib/typescript/module/src/rangeUtils.d.ts.map +1 -0
- package/lib/typescript/module/src/styleUtils.d.ts +8 -0
- package/lib/typescript/module/src/styleUtils.d.ts.map +1 -0
- package/lib/typescript/module/src/web/InputHistory.d.ts +24 -0
- package/lib/typescript/module/src/web/InputHistory.d.ts.map +1 -0
- package/lib/typescript/module/src/web/utils/blockLayout.d.ts +41 -0
- package/lib/typescript/module/src/web/utils/blockLayout.d.ts.map +1 -0
- package/lib/typescript/module/src/web/utils/blockUtils.d.ts +33 -0
- package/lib/typescript/module/src/web/utils/blockUtils.d.ts.map +1 -0
- package/lib/typescript/module/src/web/utils/browserUtils.d.ts +7 -0
- package/lib/typescript/module/src/web/utils/browserUtils.d.ts.map +1 -0
- package/lib/typescript/module/src/web/utils/cursorUtils.d.ts +12 -0
- package/lib/typescript/module/src/web/utils/cursorUtils.d.ts.map +1 -0
- package/lib/typescript/module/src/web/utils/inputUtils.d.ts +12 -0
- package/lib/typescript/module/src/web/utils/inputUtils.d.ts.map +1 -0
- package/lib/typescript/module/src/web/utils/measureUtils.d.ts +22 -0
- package/lib/typescript/module/src/web/utils/measureUtils.d.ts.map +1 -0
- package/lib/typescript/module/src/web/utils/parserUtils.d.ts +44 -0
- package/lib/typescript/module/src/web/utils/parserUtils.d.ts.map +1 -0
- package/lib/typescript/module/src/web/utils/treeUtils.d.ts +25 -0
- package/lib/typescript/module/src/web/utils/treeUtils.d.ts.map +1 -0
- package/lib/typescript/module/src/web/utils/webStyleUtils.d.ts +7 -0
- package/lib/typescript/module/src/web/utils/webStyleUtils.d.ts.map +1 -0
- package/package.json +167 -0
- package/react-native.config.js +10 -0
- package/src/MarcusTextInputDecoratorViewNativeComponent.ts +77 -0
- package/src/MarkdownTextInput.tsx +139 -0
- package/src/MarkdownTextInput.web.tsx +958 -0
- package/src/NativeMarcusModule.ts +8 -0
- package/src/commonTypes.ts +30 -0
- package/src/global.d.ts +1 -0
- package/src/index.tsx +4 -0
- package/src/parser/index.ts +556 -0
- package/src/parser/micromark-extension-mentions.ts +82 -0
- package/src/rangeUtils.ts +68 -0
- package/src/react-native-web.d.ts +1 -0
- package/src/styleUtils.ts +100 -0
- package/src/web/InputHistory.ts +137 -0
- package/src/web/MarkdownTextInput.css +72 -0
- package/src/web/utils/blockLayout.ts +163 -0
- package/src/web/utils/blockUtils.ts +245 -0
- package/src/web/utils/browserUtils.ts +41 -0
- package/src/web/utils/cursorUtils.ts +204 -0
- package/src/web/utils/inputUtils.ts +206 -0
- package/src/web/utils/measureUtils.ts +0 -0
- package/src/web/utils/parserUtils.ts +813 -0
- package/src/web/utils/treeUtils.ts +149 -0
- package/src/web/utils/webStyleUtils.ts +69 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
buildscript {
|
|
2
|
+
repositories {
|
|
3
|
+
google()
|
|
4
|
+
mavenCentral()
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
dependencies {
|
|
8
|
+
classpath "com.android.tools.build:gradle:7.2.1"
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
def reactNativeArchitectures() {
|
|
13
|
+
def value = project.getProperties().get("reactNativeArchitectures")
|
|
14
|
+
return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
apply plugin: "com.android.library"
|
|
18
|
+
apply plugin: "com.facebook.react"
|
|
19
|
+
// Kotlin Gradle Plugin is expected on the root buildscript classpath, which the
|
|
20
|
+
// React Native community template provides. Not declaring a version here means
|
|
21
|
+
// the library always compiles with the Kotlin version the app pins.
|
|
22
|
+
apply plugin: "org.jetbrains.kotlin.android"
|
|
23
|
+
|
|
24
|
+
def getExtOrDefault(name) {
|
|
25
|
+
return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties["Marcus_" + name]
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
def getExtOrIntegerDefault(name) {
|
|
29
|
+
return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["Marcus_" + name]).toInteger()
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
def safeAppExtGet(prop, fallback) {
|
|
33
|
+
def appProject = rootProject.allprojects.find { it.plugins.hasPlugin('com.android.application') }
|
|
34
|
+
appProject?.ext?.has(prop) ? appProject.ext.get(prop) : fallback
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
def supportsNamespace() {
|
|
38
|
+
def parsed = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION.tokenize('.')
|
|
39
|
+
def major = parsed[0].toInteger()
|
|
40
|
+
def minor = parsed[1].toInteger()
|
|
41
|
+
|
|
42
|
+
// Namespace support was added in 7.3.0
|
|
43
|
+
return (major == 7 && minor >= 3) || major >= 8
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
def resolveReactNativeDirectory() {
|
|
47
|
+
def reactNativeLocation = safeAppExtGet("REACT_NATIVE_NODE_MODULES_DIR", null)
|
|
48
|
+
if (reactNativeLocation != null) {
|
|
49
|
+
return file(reactNativeLocation)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Fallback to node resolver for custom directory structures like monorepos.
|
|
53
|
+
def reactNativePackage = file(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim())
|
|
54
|
+
if (reactNativePackage.exists()) {
|
|
55
|
+
return reactNativePackage.parentFile
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
throw new GradleException("[react-native-marcus] Unable to resolve react-native location in node_modules. Your app should define `REACT_NATIVE_NODE_MODULES_DIR` extension property in `app/build.gradle` with a path to react-native in node_modules.")
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
def getReactNativeMinorVersion() {
|
|
62
|
+
def reactNativeRootDir = resolveReactNativeDirectory()
|
|
63
|
+
def reactNativeProperties = new Properties()
|
|
64
|
+
file("$reactNativeRootDir/ReactAndroid/gradle.properties").withInputStream { reactNativeProperties.load(it) }
|
|
65
|
+
def reactNativeVersion = reactNativeProperties.getProperty("VERSION_NAME")
|
|
66
|
+
return reactNativeVersion.split("\\.")[1].toInteger()
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
def REACT_NATIVE_MINOR_VERSION = getReactNativeMinorVersion()
|
|
70
|
+
|
|
71
|
+
if (REACT_NATIVE_MINOR_VERSION < 81) {
|
|
72
|
+
throw new GradleException("[react-native-marcus] React Native 0.81 or newer is required, found 0.${REACT_NATIVE_MINOR_VERSION}.")
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
android {
|
|
76
|
+
if (supportsNamespace()) {
|
|
77
|
+
namespace "app.getbullet.marcus"
|
|
78
|
+
|
|
79
|
+
sourceSets {
|
|
80
|
+
main {
|
|
81
|
+
manifest.srcFile "src/main/AndroidManifestNew.xml"
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")
|
|
87
|
+
|
|
88
|
+
// Without this the library compiles its native code with whatever NDK the
|
|
89
|
+
// Android Gradle Plugin defaults to, which is rarely the one the app pins and
|
|
90
|
+
// often isn't installed at all.
|
|
91
|
+
if (rootProject.ext.has("ndkVersion")) {
|
|
92
|
+
ndkVersion rootProject.ext.get("ndkVersion")
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
defaultConfig {
|
|
96
|
+
minSdkVersion getExtOrIntegerDefault("minSdkVersion")
|
|
97
|
+
targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
|
|
98
|
+
|
|
99
|
+
buildConfigField "int", "REACT_NATIVE_MINOR_VERSION", REACT_NATIVE_MINOR_VERSION.toString()
|
|
100
|
+
|
|
101
|
+
consumerProguardFiles "proguard-rules.pro"
|
|
102
|
+
|
|
103
|
+
externalNativeBuild {
|
|
104
|
+
cmake {
|
|
105
|
+
arguments "-DANDROID_STL=c++_shared",
|
|
106
|
+
"-DANDROID_TOOLCHAIN=clang",
|
|
107
|
+
"-DREACT_NATIVE_MINOR_VERSION=${REACT_NATIVE_MINOR_VERSION}",
|
|
108
|
+
"-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON",
|
|
109
|
+
"-DREACT_NATIVE_ROOT_DIR=${resolveReactNativeDirectory().path}"
|
|
110
|
+
abiFilters (*reactNativeArchitectures())
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
buildFeatures {
|
|
116
|
+
buildConfig true
|
|
117
|
+
prefab true
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
buildTypes {
|
|
121
|
+
release {
|
|
122
|
+
minifyEnabled false
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
lintOptions {
|
|
127
|
+
disable "GradleCompatible"
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
testOptions {
|
|
131
|
+
unitTests {
|
|
132
|
+
// Robolectric needs the merged resources and the real framework jar;
|
|
133
|
+
// without this it cannot inflate a Context.
|
|
134
|
+
includeAndroidResources = true
|
|
135
|
+
// Unstubbed framework calls return defaults rather than throwing. Only
|
|
136
|
+
// reached for the few statics Robolectric does not shadow.
|
|
137
|
+
returnDefaultValues = true
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
compileOptions {
|
|
142
|
+
sourceCompatibility JavaVersion.VERSION_17
|
|
143
|
+
targetCompatibility JavaVersion.VERSION_17
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
sourceSets {
|
|
147
|
+
// The shared fixture corpus, on the test classpath. The formatters take
|
|
148
|
+
// ranges rather than markdown, so `ranges.json` is what lets the native
|
|
149
|
+
// suites run with no JS runtime at all.
|
|
150
|
+
test {
|
|
151
|
+
resources.srcDirs += "${projectDir}/../src/__fixtures__"
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
main {
|
|
155
|
+
java.srcDirs += [
|
|
156
|
+
// This is needed to build Kotlin project with NewArch enabled
|
|
157
|
+
"${project.buildDir}/generated/source/codegen/java"
|
|
158
|
+
]
|
|
159
|
+
|
|
160
|
+
// TextLayoutManager
|
|
161
|
+
if (REACT_NATIVE_MINOR_VERSION <= 85) {
|
|
162
|
+
java.srcDirs += "src/reactNativeVersionPatch/CustomMountingManager/81"
|
|
163
|
+
} else {
|
|
164
|
+
java.srcDirs += "src/reactNativeVersionPatch/CustomMountingManager/latest"
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
externalNativeBuild {
|
|
170
|
+
cmake {
|
|
171
|
+
path file('src/main/cpp/CMakeLists.txt')
|
|
172
|
+
version '3.22.1'
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
packagingOptions {
|
|
177
|
+
doNotStrip '**/**/*.so'
|
|
178
|
+
// For some reason gradle only complains about the duplicated version of librrc_root and libreact_render libraries
|
|
179
|
+
// while there are more libraries copied in intermediates folder of the lib build directory, we exclude
|
|
180
|
+
// only the ones that make the build fail (ideally we should only include libreanimated but we
|
|
181
|
+
// are only allowed to specify exclude patterns)
|
|
182
|
+
excludes = [
|
|
183
|
+
"META-INF",
|
|
184
|
+
"META-INF/**",
|
|
185
|
+
"**/libc++_shared.so",
|
|
186
|
+
"**/libfbjni.so",
|
|
187
|
+
"**/libjsi.so",
|
|
188
|
+
"**/libreactnativejni.so",
|
|
189
|
+
"**/libreactnative.so",
|
|
190
|
+
"**/libreact_nativemodule_core.so",
|
|
191
|
+
"**/libruntimeexecutor.so",
|
|
192
|
+
"**/libworklets.so",
|
|
193
|
+
"**/libreact_render*.so",
|
|
194
|
+
"**/librrc_root.so",
|
|
195
|
+
]
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
kotlin {
|
|
200
|
+
compilerOptions {
|
|
201
|
+
// Must match compileOptions above; a mismatch fails the build with
|
|
202
|
+
// "Inconsistent JVM-target compatibility" rather than anything useful.
|
|
203
|
+
jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
repositories {
|
|
208
|
+
mavenCentral()
|
|
209
|
+
google()
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
dependencies {
|
|
214
|
+
implementation "com.facebook.react:react-android" // version substituted by RNGP
|
|
215
|
+
implementation "com.facebook.react:hermes-android" // version substituted by RNGP
|
|
216
|
+
implementation project(":react-native-worklets")
|
|
217
|
+
|
|
218
|
+
testImplementation "junit:junit:4.13.2"
|
|
219
|
+
testImplementation "org.robolectric:robolectric:4.16"
|
|
220
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
-keep class app.getbullet.marcus.** { *; }
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
project("marcus")
|
|
2
|
+
|
|
3
|
+
cmake_minimum_required(VERSION 3.13)
|
|
4
|
+
|
|
5
|
+
set(CMAKE_VERBOSE_MAKEFILE on)
|
|
6
|
+
set(CMAKE_CXX_STANDARD 20)
|
|
7
|
+
|
|
8
|
+
include("${REACT_NATIVE_ROOT_DIR}/ReactAndroid/cmake-utils/folly-flags.cmake")
|
|
9
|
+
add_compile_options(${folly_FLAGS})
|
|
10
|
+
|
|
11
|
+
add_compile_options(-fvisibility=hidden -fexceptions -frtti)
|
|
12
|
+
|
|
13
|
+
string(APPEND CMAKE_CXX_FLAGS " -DREACT_NATIVE_MINOR_VERSION=${REACT_NATIVE_MINOR_VERSION}")
|
|
14
|
+
|
|
15
|
+
set(CPP_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../cpp")
|
|
16
|
+
|
|
17
|
+
file(GLOB ANDROID_SRC CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
|
|
18
|
+
file(GLOB CPP_SRC CONFIGURE_DEPENDS "${CPP_DIR}/*.cpp")
|
|
19
|
+
|
|
20
|
+
add_library(${CMAKE_PROJECT_NAME} SHARED ${ANDROID_SRC} ${CPP_SRC})
|
|
21
|
+
|
|
22
|
+
target_include_directories(
|
|
23
|
+
${CMAKE_PROJECT_NAME}
|
|
24
|
+
PRIVATE
|
|
25
|
+
${CMAKE_CURRENT_SOURCE_DIR}
|
|
26
|
+
${CPP_DIR}
|
|
27
|
+
"${REACT_NATIVE_ROOT_DIR}/ReactCommon/jsiexecutor"
|
|
28
|
+
"${REACT_NATIVE_ROOT_DIR}/ReactCommon"
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
find_package(fbjni REQUIRED CONFIG)
|
|
32
|
+
find_package(ReactAndroid REQUIRED CONFIG)
|
|
33
|
+
find_package(react-native-worklets REQUIRED CONFIG)
|
|
34
|
+
|
|
35
|
+
target_link_libraries(
|
|
36
|
+
${CMAKE_PROJECT_NAME}
|
|
37
|
+
fbjni::fbjni
|
|
38
|
+
ReactAndroid::jsi
|
|
39
|
+
ReactAndroid::reactnative
|
|
40
|
+
react-native-worklets::worklets
|
|
41
|
+
)
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#include "MarkdownParser.h"
|
|
2
|
+
#include "MarkdownWorkletParser.h"
|
|
3
|
+
|
|
4
|
+
#include <fbjni/fbjni.h>
|
|
5
|
+
|
|
6
|
+
using namespace facebook;
|
|
7
|
+
|
|
8
|
+
namespace bulletpoint {
|
|
9
|
+
namespace marcus {
|
|
10
|
+
jni::local_ref<JMarkdownParseResult>
|
|
11
|
+
JMarkdownParser::nativeParse(jni::alias_ref<JMarkdownParser> jThis, jni::alias_ref<jni::JString> text, const int parserId) {
|
|
12
|
+
// Read the UTF-16 length from the same jstring rather than taking it as a
|
|
13
|
+
// parameter, so the length and the text can never disagree. The worklet
|
|
14
|
+
// reports offsets in UTF-16 units (they are JS string indices); validating
|
|
15
|
+
// them against the UTF-8 byte count would let out-of-bounds ranges through
|
|
16
|
+
// for any non-ASCII text.
|
|
17
|
+
const auto lengthUtf16 = static_cast<size_t>(
|
|
18
|
+
jni::Environment::current()->GetStringLength(text.get())
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
const auto result = parseMarkdown(text->toStdString(), lengthUtf16, parserId);
|
|
22
|
+
|
|
23
|
+
auto ranges = jni::JArrayClass<JMarkdownRange::javaobject>::newArray(
|
|
24
|
+
result.ranges.size()
|
|
25
|
+
);
|
|
26
|
+
for (size_t i = 0; i < result.ranges.size(); i++) {
|
|
27
|
+
const auto &range = result.ranges[i];
|
|
28
|
+
// Scoped so each local ref is released as we go, instead of accumulating
|
|
29
|
+
// one per range in the frame.
|
|
30
|
+
const auto jRange = JMarkdownRange::create(range.type, range.start, range.length, range.depth);
|
|
31
|
+
ranges->setElement(i, jRange.get());
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
auto schemaError = result.schemaError.empty()
|
|
35
|
+
? jni::local_ref<jni::JString>(nullptr)
|
|
36
|
+
: jni::make_jstring(result.schemaError);
|
|
37
|
+
|
|
38
|
+
return JMarkdownParseResult::create(ranges, std::move(schemaError));
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
void
|
|
42
|
+
JMarkdownParser::registerNatives() {
|
|
43
|
+
javaClassStatic()->registerNatives(
|
|
44
|
+
{makeNativeMethod("nativeParse", JMarkdownParser::nativeParse)}
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
} // namespace marcus
|
|
49
|
+
} // namespace bulletpoint
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#include <fbjni/fbjni.h>
|
|
11
|
+
|
|
12
|
+
#include <string>
|
|
13
|
+
|
|
14
|
+
using namespace facebook;
|
|
15
|
+
|
|
16
|
+
namespace bulletpoint {
|
|
17
|
+
namespace marcus {
|
|
18
|
+
|
|
19
|
+
struct JMarkdownRange : jni::JavaClass<JMarkdownRange> {
|
|
20
|
+
static constexpr auto kJavaDescriptor =
|
|
21
|
+
"Lapp/getbullet/marcus/MarkdownRange;";
|
|
22
|
+
|
|
23
|
+
// fbjni keeps newInstance protected, so the factory has to live inside the
|
|
24
|
+
// class.
|
|
25
|
+
static jni::local_ref<JMarkdownRange>
|
|
26
|
+
create(const std::string &type, int start, int length, int depth) {
|
|
27
|
+
return newInstance(jni::make_jstring(type), start, length, depth);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
struct JMarkdownParseResult : jni::JavaClass<JMarkdownParseResult> {
|
|
32
|
+
static constexpr auto kJavaDescriptor =
|
|
33
|
+
"Lapp/getbullet/marcus/MarkdownParseResult;";
|
|
34
|
+
|
|
35
|
+
static jni::local_ref<JMarkdownParseResult>
|
|
36
|
+
create(jni::alias_ref<jni::JArrayClass<JMarkdownRange::javaobject>> ranges, jni::local_ref<jni::JString> schemaError) {
|
|
37
|
+
return newInstance(ranges, schemaError);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
// A plain JavaClass, not a HybridClass: the Kotlin side holds no HybridData and
|
|
42
|
+
// nothing ever constructs a C++ peer, so the hybrid machinery would only be
|
|
43
|
+
// decoration.
|
|
44
|
+
struct JMarkdownParser : jni::JavaClass<JMarkdownParser> {
|
|
45
|
+
static constexpr auto kJavaDescriptor =
|
|
46
|
+
"Lapp/getbullet/marcus/MarkdownParser;";
|
|
47
|
+
|
|
48
|
+
static jni::local_ref<JMarkdownParseResult>
|
|
49
|
+
nativeParse(jni::alias_ref<JMarkdownParser> jThis, jni::alias_ref<jni::JString> text, const int parserId);
|
|
50
|
+
|
|
51
|
+
static void
|
|
52
|
+
registerNatives();
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
} // namespace marcus
|
|
56
|
+
} // namespace bulletpoint
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#include <fbjni/fbjni.h>
|
|
2
|
+
|
|
3
|
+
#include "MarkdownParser.h"
|
|
4
|
+
#include "RuntimeDecorator.h"
|
|
5
|
+
|
|
6
|
+
JNIEXPORT jint JNICALL
|
|
7
|
+
JNI_OnLoad(JavaVM *vm, void *reserved) {
|
|
8
|
+
return facebook::jni::initialize(
|
|
9
|
+
vm, [] { bulletpoint::marcus::JMarkdownParser::registerNatives(); }
|
|
10
|
+
);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
extern "C" JNIEXPORT void JNICALL
|
|
14
|
+
Java_app_getbullet_marcus_MarcusModule_injectJSIBindings(JNIEnv *env, jobject thiz, jlong jsiRuntime) {
|
|
15
|
+
jsi::Runtime &rt = *reinterpret_cast<jsi::Runtime *>(jsiRuntime);
|
|
16
|
+
bulletpoint::marcus::injectJSIBindings(rt);
|
|
17
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
package app.getbullet.marcus
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
4
|
+
import com.facebook.soloader.SoLoader
|
|
5
|
+
|
|
6
|
+
class MarcusModule(reactContext: ReactApplicationContext) :
|
|
7
|
+
NativeMarcusModuleSpec(reactContext) {
|
|
8
|
+
|
|
9
|
+
override fun install(): Boolean {
|
|
10
|
+
val contextHolder = requireNotNull(reactApplicationContext.javaScriptContextHolder) {
|
|
11
|
+
"[react-native-marcus] JavaScriptContextHolder is null"
|
|
12
|
+
}
|
|
13
|
+
injectJSIBindings(contextHolder.get())
|
|
14
|
+
return true
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// OnLoad.cpp hand-writes this symbol as
|
|
18
|
+
// Java_app_getbullet_marcus_MarcusModule_injectJSIBindings, so the package,
|
|
19
|
+
// class and method names are frozen. It must also stay an instance method: the native
|
|
20
|
+
// signature takes `jobject thiz`, which a @JvmStatic version would not supply.
|
|
21
|
+
private external fun injectJSIBindings(jsiRuntime: Long)
|
|
22
|
+
|
|
23
|
+
companion object {
|
|
24
|
+
init {
|
|
25
|
+
SoLoader.loadLibrary("marcus")
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
package app.getbullet.marcus
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.BaseReactPackage
|
|
4
|
+
import com.facebook.react.bridge.NativeModule
|
|
5
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
6
|
+
import com.facebook.react.module.model.ReactModuleInfo
|
|
7
|
+
import com.facebook.react.module.model.ReactModuleInfoProvider
|
|
8
|
+
import com.facebook.react.uimanager.ViewManager
|
|
9
|
+
|
|
10
|
+
class MarcusPackage : BaseReactPackage() {
|
|
11
|
+
|
|
12
|
+
override fun createViewManagers(
|
|
13
|
+
reactContext: ReactApplicationContext
|
|
14
|
+
): List<ViewManager<in Nothing, in Nothing>> = listOf(MarcusTextInputDecoratorViewManager())
|
|
15
|
+
|
|
16
|
+
override fun getReactModuleInfoProvider(): ReactModuleInfoProvider = ReactModuleInfoProvider {
|
|
17
|
+
mapOf(
|
|
18
|
+
NativeMarcusModuleSpec.NAME to ReactModuleInfo(
|
|
19
|
+
NativeMarcusModuleSpec.NAME,
|
|
20
|
+
MarcusModule::class.java.name,
|
|
21
|
+
false, // canOverrideExistingModule
|
|
22
|
+
false, // needsEagerInit
|
|
23
|
+
false, // isCxxModule
|
|
24
|
+
true // isTurboModule
|
|
25
|
+
)
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? =
|
|
30
|
+
if (name == NativeMarcusModuleSpec.NAME) MarcusModule(reactContext) else null
|
|
31
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
package app.getbullet.marcus
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.text.SpannableStringBuilder
|
|
5
|
+
import android.text.TextWatcher
|
|
6
|
+
import com.facebook.react.bridge.ReactContext
|
|
7
|
+
import com.facebook.react.views.textinput.ReactEditText
|
|
8
|
+
import com.facebook.react.views.view.ReactViewGroup
|
|
9
|
+
|
|
10
|
+
class MarcusTextInputDecoratorView(context: Context) : ReactViewGroup(context) {
|
|
11
|
+
|
|
12
|
+
private var markdownUtils: MarkdownUtils? = null
|
|
13
|
+
private var reactEditText: ReactEditText? = null
|
|
14
|
+
private var textWatcher: TextWatcher? = null
|
|
15
|
+
|
|
16
|
+
var markdownStyle: MarkdownStyle? = null
|
|
17
|
+
set(value) {
|
|
18
|
+
field = value
|
|
19
|
+
markdownUtils?.markdownStyle = value
|
|
20
|
+
applyNewStyles()
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
var parserId: Int = 0
|
|
24
|
+
set(value) {
|
|
25
|
+
field = value
|
|
26
|
+
markdownUtils?.parserId = value
|
|
27
|
+
applyNewStyles()
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
override fun onAttachedToWindow() {
|
|
31
|
+
super.onAttachedToWindow()
|
|
32
|
+
|
|
33
|
+
val child = getChildAt(0)
|
|
34
|
+
if (child is ReactEditText) {
|
|
35
|
+
val utils = MarkdownUtils(context as ReactContext, child.paint)
|
|
36
|
+
utils.markdownStyle = markdownStyle
|
|
37
|
+
utils.parserId = parserId
|
|
38
|
+
markdownUtils = utils
|
|
39
|
+
reactEditText = child
|
|
40
|
+
textWatcher = MarkdownTextWatcher(utils).also { child.addTextChangedListener(it) }
|
|
41
|
+
applyNewStyles()
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
override fun onDetachedFromWindow() {
|
|
46
|
+
super.onDetachedFromWindow()
|
|
47
|
+
reactEditText?.let { editText ->
|
|
48
|
+
textWatcher?.let { editText.removeTextChangedListener(it) }
|
|
49
|
+
reactEditText = null
|
|
50
|
+
textWatcher = null
|
|
51
|
+
markdownUtils = null
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
fun applyNewStyles() {
|
|
56
|
+
val editText = reactEditText ?: return
|
|
57
|
+
val utils = markdownUtils ?: return
|
|
58
|
+
val editable = editText.text
|
|
59
|
+
if (editable is SpannableStringBuilder) {
|
|
60
|
+
utils.applyMarkdownFormatting(editable)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
package app.getbullet.marcus
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.ReadableMap
|
|
4
|
+
import com.facebook.react.module.annotations.ReactModule
|
|
5
|
+
import com.facebook.react.uimanager.ThemedReactContext
|
|
6
|
+
import com.facebook.react.uimanager.annotations.ReactProp
|
|
7
|
+
|
|
8
|
+
@ReactModule(name = MarcusTextInputDecoratorViewManager.NAME)
|
|
9
|
+
class MarcusTextInputDecoratorViewManager : MarcusTextInputDecoratorViewManagerSpec() {
|
|
10
|
+
|
|
11
|
+
override fun getName(): String = NAME
|
|
12
|
+
|
|
13
|
+
public override fun createViewInstance(context: ThemedReactContext): MarcusTextInputDecoratorView =
|
|
14
|
+
MarcusTextInputDecoratorView(context)
|
|
15
|
+
|
|
16
|
+
// The generated interface declares this parameter @Nullable, so the override
|
|
17
|
+
// has to accept null even though the prop always arrives set.
|
|
18
|
+
@ReactProp(name = "markdownStyle")
|
|
19
|
+
override fun setMarkdownStyle(view: MarcusTextInputDecoratorView, value: ReadableMap?) {
|
|
20
|
+
val map = requireNotNull(value) { "[react-native-marcus] markdownStyle prop is required" }
|
|
21
|
+
view.markdownStyle = MarkdownStyle(map, view.context)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@ReactProp(name = "parserId")
|
|
25
|
+
override fun setParserId(view: MarcusTextInputDecoratorView, parserId: Int) {
|
|
26
|
+
view.parserId = parserId
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
companion object {
|
|
30
|
+
const val NAME = "MarcusTextInputDecoratorView"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
package app.getbullet.marcus
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.uimanager.ViewGroupManager
|
|
4
|
+
import com.facebook.react.uimanager.ViewManagerDelegate
|
|
5
|
+
import com.facebook.react.viewmanagers.MarcusTextInputDecoratorViewManagerDelegate
|
|
6
|
+
import com.facebook.react.viewmanagers.MarcusTextInputDecoratorViewManagerInterface
|
|
7
|
+
|
|
8
|
+
// Not generic over the view type, unlike the Java this replaces. The generated
|
|
9
|
+
// delegate's second type parameter is a Java intersection type
|
|
10
|
+
// (`BaseViewManager<T, ...> & MarcusTextInputDecoratorViewManagerInterface<T>`),
|
|
11
|
+
// which Kotlin has no syntax for. Naming the one concrete view type lets the
|
|
12
|
+
// compiler infer it from `this` instead.
|
|
13
|
+
abstract class MarcusTextInputDecoratorViewManagerSpec :
|
|
14
|
+
ViewGroupManager<MarcusTextInputDecoratorView>(),
|
|
15
|
+
MarcusTextInputDecoratorViewManagerInterface<MarcusTextInputDecoratorView> {
|
|
16
|
+
|
|
17
|
+
private val delegate: ViewManagerDelegate<MarcusTextInputDecoratorView> =
|
|
18
|
+
MarcusTextInputDecoratorViewManagerDelegate(this)
|
|
19
|
+
|
|
20
|
+
override fun getDelegate(): ViewManagerDelegate<MarcusTextInputDecoratorView> = delegate
|
|
21
|
+
}
|