react-native-jet-markdown 0.2.0-beta.7
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/JetMarkdown.podspec +42 -0
- package/LICENSE +20 -0
- package/README.md +247 -0
- package/android/CMakeLists.txt +52 -0
- package/android/build.gradle +55 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/cpp/JniBindings.cpp +243 -0
- package/android/src/main/java/com/jetmarkdown/JetMarkdownNative.kt +114 -0
- package/android/src/main/java/com/jetmarkdown/JetMarkdownPackage.kt +22 -0
- package/android/src/main/java/com/jetmarkdown/JetMarkdownView.kt +235 -0
- package/android/src/main/java/com/jetmarkdown/JetMarkdownViewManager.kt +75 -0
- package/android/src/main/java/com/jetmarkdown/editor/EditorSpans.kt +217 -0
- package/android/src/main/java/com/jetmarkdown/editor/JetMarkdownEditorManager.kt +224 -0
- package/android/src/main/java/com/jetmarkdown/editor/JetMarkdownEditorView.kt +1736 -0
- package/android/src/main/java/com/jetmarkdown/measure/MarkdownMeasurer.kt +54 -0
- package/android/src/main/java/com/jetmarkdown/parser/AstDecoder.kt +59 -0
- package/android/src/main/java/com/jetmarkdown/parser/MdNode.kt +43 -0
- package/android/src/main/java/com/jetmarkdown/render/ContentCache.kt +53 -0
- package/android/src/main/java/com/jetmarkdown/render/RenderedContent.kt +318 -0
- package/android/src/main/java/com/jetmarkdown/render/SpannableRenderer.kt +658 -0
- package/android/src/main/java/com/jetmarkdown/render/spans/ChipSpan.kt +17 -0
- package/android/src/main/java/com/jetmarkdown/render/spans/InteractiveSpans.kt +11 -0
- package/android/src/main/java/com/jetmarkdown/render/spans/MarkdownLineHeightSpan.kt +59 -0
- package/android/src/main/java/com/jetmarkdown/render/spans/RunSpan.kt +40 -0
- package/android/src/main/java/com/jetmarkdown/style/Fonts.kt +34 -0
- package/android/src/main/java/com/jetmarkdown/style/LayoutStyleSpec.kt +71 -0
- package/android/src/main/java/com/jetmarkdown/style/PlatformColorResolver.kt +77 -0
- package/android/src/main/java/com/jetmarkdown/style/StyleConfig.kt +80 -0
- package/android/src/main/java/com/jetmarkdown/style/TextStyleSpec.kt +61 -0
- package/android/src/main/java/com/jetmarkdown/views/BlockStackView.kt +292 -0
- package/android/src/main/java/com/jetmarkdown/views/BlockTextView.kt +378 -0
- package/android/src/main/java/com/jetmarkdown/views/BoxDrawing.kt +50 -0
- package/android/src/main/java/com/jetmarkdown/views/MarkdownHost.kt +12 -0
- package/android/src/main/java/com/jetmarkdown/views/MarkdownImageView.kt +113 -0
- package/android/src/main/java/com/jetmarkdown/views/NestedHorizontalScrollView.kt +87 -0
- package/android/src/main/java/com/jetmarkdown/views/TableBlockView.kt +139 -0
- package/cpp/core/Ast.h +85 -0
- package/cpp/core/AstJson.cpp +129 -0
- package/cpp/core/AstJson.h +12 -0
- package/cpp/core/AstSerializer.cpp +40 -0
- package/cpp/core/AstSerializer.h +21 -0
- package/cpp/core/AstToMarkdown.cpp +549 -0
- package/cpp/core/AstToMarkdown.h +16 -0
- package/cpp/core/EditorRuns.cpp +640 -0
- package/cpp/core/EditorRuns.h +94 -0
- package/cpp/core/EditorText.cpp +15 -0
- package/cpp/core/EditorText.h +18 -0
- package/cpp/core/InlineExtensions.cpp +305 -0
- package/cpp/core/InlineExtensions.h +17 -0
- package/cpp/core/Parser.cpp +470 -0
- package/cpp/core/Parser.h +16 -0
- package/cpp/core/Preprocess.cpp +181 -0
- package/cpp/core/Preprocess.h +14 -0
- package/cpp/md4c/LICENSE +22 -0
- package/cpp/md4c/VERSION +1 -0
- package/cpp/md4c/md4c.c +6462 -0
- package/cpp/md4c/md4c.h +407 -0
- package/cpp/react/JetMarkdownEditorShadowNode.cpp +54 -0
- package/cpp/react/JetMarkdownEditorShadowNode.h +55 -0
- package/cpp/react/JetMarkdownEditorState.h +35 -0
- package/cpp/react/JetMarkdownMeasurer.cpp +32 -0
- package/cpp/react/JetMarkdownMeasurer.h +41 -0
- package/cpp/react/JetMarkdownShadowNode.cpp +100 -0
- package/cpp/react/JetMarkdownShadowNode.h +53 -0
- package/cpp/react/JetMarkdownState.h +52 -0
- package/cpp/react/override/react/renderer/components/JetMarkdownViewSpec/ComponentDescriptors.h +21 -0
- package/cpp/tests/parser_tests.cpp +662 -0
- package/cpp/tests/run_tests.sh +25 -0
- package/ios/JetMarkdownView.h +14 -0
- package/ios/JetMarkdownView.mm +468 -0
- package/ios/editor/JetMarkdownEditor.h +12 -0
- package/ios/editor/JetMarkdownEditor.mm +2002 -0
- package/ios/measure/JMDMarkdownMeasurer.h +22 -0
- package/ios/measure/JMDMarkdownMeasurer.mm +38 -0
- package/ios/render/JMDBlock.h +97 -0
- package/ios/render/JMDBlock.m +28 -0
- package/ios/render/JMDBlockRenderer.h +17 -0
- package/ios/render/JMDBlockRenderer.mm +852 -0
- package/ios/render/JMDContentCache.h +17 -0
- package/ios/render/JMDContentCache.mm +42 -0
- package/ios/render/JMDRenderedContent.h +35 -0
- package/ios/render/JMDRenderedContent.mm +274 -0
- package/ios/style/JMDFontScale.h +33 -0
- package/ios/style/JMDLayoutStyle.h +37 -0
- package/ios/style/JMDLayoutStyle.mm +68 -0
- package/ios/style/JMDStyleConfig.h +39 -0
- package/ios/style/JMDStyleConfig.mm +111 -0
- package/ios/style/JMDTextStyle.h +25 -0
- package/ios/style/JMDTextStyle.mm +68 -0
- package/ios/views/JMDBlockStackView.h +18 -0
- package/ios/views/JMDBlockStackView.m +97 -0
- package/ios/views/JMDBlockTextView.h +24 -0
- package/ios/views/JMDBlockTextView.m +340 -0
- package/ios/views/JMDBoxViews.h +33 -0
- package/ios/views/JMDBoxViews.m +292 -0
- package/ios/views/JMDImageView.h +19 -0
- package/ios/views/JMDImageView.m +68 -0
- package/ios/views/JMDMarkdownHost.h +16 -0
- package/ios/views/JMDTableView.h +16 -0
- package/ios/views/JMDTableView.m +172 -0
- package/lib/module/JetMarkdownEditor.js +85 -0
- package/lib/module/JetMarkdownEditor.js.map +1 -0
- package/lib/module/JetMarkdownEditor.native.js +244 -0
- package/lib/module/JetMarkdownEditor.native.js.map +1 -0
- package/lib/module/JetMarkdownEditorNativeComponent.ts +173 -0
- package/lib/module/JetMarkdownView.js +19 -0
- package/lib/module/JetMarkdownView.js.map +1 -0
- package/lib/module/JetMarkdownView.native.js +44 -0
- package/lib/module/JetMarkdownView.native.js.map +1 -0
- package/lib/module/JetMarkdownViewNativeComponent.ts +35 -0
- package/lib/module/defaultStyles.js +122 -0
- package/lib/module/defaultStyles.js.map +1 -0
- package/lib/module/index.js +9 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/serializeStyles.js +259 -0
- package/lib/module/serializeStyles.js.map +1 -0
- package/lib/module/types.js +4 -0
- package/lib/module/types.js.map +1 -0
- package/lib/module/useJetMarkdownEditor.js +41 -0
- package/lib/module/useJetMarkdownEditor.js.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/JetMarkdownEditor.d.ts +6 -0
- package/lib/typescript/src/JetMarkdownEditor.d.ts.map +1 -0
- package/lib/typescript/src/JetMarkdownEditor.native.d.ts +6 -0
- package/lib/typescript/src/JetMarkdownEditor.native.d.ts.map +1 -0
- package/lib/typescript/src/JetMarkdownEditorNativeComponent.d.ts +105 -0
- package/lib/typescript/src/JetMarkdownEditorNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/JetMarkdownView.d.ts +3 -0
- package/lib/typescript/src/JetMarkdownView.d.ts.map +1 -0
- package/lib/typescript/src/JetMarkdownView.native.d.ts +3 -0
- package/lib/typescript/src/JetMarkdownView.native.d.ts.map +1 -0
- package/lib/typescript/src/JetMarkdownViewNativeComponent.d.ts +28 -0
- package/lib/typescript/src/JetMarkdownViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/defaultStyles.d.ts +20 -0
- package/lib/typescript/src/defaultStyles.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +7 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/serializeStyles.d.ts +34 -0
- package/lib/typescript/src/serializeStyles.d.ts.map +1 -0
- package/lib/typescript/src/types.d.ts +352 -0
- package/lib/typescript/src/types.d.ts.map +1 -0
- package/lib/typescript/src/useJetMarkdownEditor.d.ts +36 -0
- package/lib/typescript/src/useJetMarkdownEditor.d.ts.map +1 -0
- package/package.json +150 -0
- package/react-native.config.js +11 -0
- package/src/JetMarkdownEditor.native.tsx +301 -0
- package/src/JetMarkdownEditor.tsx +90 -0
- package/src/JetMarkdownEditorNativeComponent.ts +173 -0
- package/src/JetMarkdownView.native.tsx +67 -0
- package/src/JetMarkdownView.tsx +16 -0
- package/src/JetMarkdownViewNativeComponent.ts +35 -0
- package/src/defaultStyles.ts +102 -0
- package/src/index.tsx +34 -0
- package/src/serializeStyles.ts +369 -0
- package/src/types.ts +438 -0
- package/src/useJetMarkdownEditor.ts +50 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
#include "JetMarkdownShadowNode.h"
|
|
2
|
+
|
|
3
|
+
#include <algorithm>
|
|
4
|
+
#include <cmath>
|
|
5
|
+
|
|
6
|
+
#include "JetMarkdownMeasurer.h"
|
|
7
|
+
|
|
8
|
+
namespace facebook::react {
|
|
9
|
+
|
|
10
|
+
namespace {
|
|
11
|
+
|
|
12
|
+
void appendJsonEscaped(std::string& out, const std::string& value) {
|
|
13
|
+
for (char c : value) {
|
|
14
|
+
switch (c) {
|
|
15
|
+
case '"': out += "\\\""; break;
|
|
16
|
+
case '\\': out += "\\\\"; break;
|
|
17
|
+
case '\n': out += "\\n"; break;
|
|
18
|
+
case '\t': out += "\\t"; break;
|
|
19
|
+
case '\r': out += "\\r"; break;
|
|
20
|
+
default:
|
|
21
|
+
if (static_cast<unsigned char>(c) < 0x20) {
|
|
22
|
+
char buffer[8];
|
|
23
|
+
snprintf(buffer, sizeof(buffer), "\\u%04x", c);
|
|
24
|
+
out += buffer;
|
|
25
|
+
} else {
|
|
26
|
+
out += c;
|
|
27
|
+
}
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
} // namespace
|
|
34
|
+
|
|
35
|
+
Size JetMarkdownShadowNode::measureContent(
|
|
36
|
+
const LayoutContext& layoutContext,
|
|
37
|
+
const LayoutConstraints& layoutConstraints) const {
|
|
38
|
+
const auto& props = getConcreteProps();
|
|
39
|
+
const auto& state = getStateData();
|
|
40
|
+
|
|
41
|
+
// {"url":[w,h],...} — state sizes first, the images prop wins.
|
|
42
|
+
std::string imagesJson = "{";
|
|
43
|
+
bool first = true;
|
|
44
|
+
auto appendEntry = [&](const std::string& url, double width, double height) {
|
|
45
|
+
if (!first) {
|
|
46
|
+
imagesJson += ',';
|
|
47
|
+
}
|
|
48
|
+
first = false;
|
|
49
|
+
imagesJson += '"';
|
|
50
|
+
appendJsonEscaped(imagesJson, url);
|
|
51
|
+
imagesJson += "\":[";
|
|
52
|
+
imagesJson += std::to_string(width);
|
|
53
|
+
imagesJson += ',';
|
|
54
|
+
imagesJson += std::to_string(height);
|
|
55
|
+
imagesJson += ']';
|
|
56
|
+
};
|
|
57
|
+
for (const auto& [url, size] : state.imageSizes) {
|
|
58
|
+
bool inProps = false;
|
|
59
|
+
for (const auto& image : props.images) {
|
|
60
|
+
if (image.url == url) {
|
|
61
|
+
inProps = true;
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (!inProps) {
|
|
66
|
+
appendEntry(url, size.width, size.height);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
for (const auto& image : props.images) {
|
|
70
|
+
appendEntry(image.url, image.width, image.height);
|
|
71
|
+
}
|
|
72
|
+
imagesJson += '}';
|
|
73
|
+
|
|
74
|
+
// Under an unconstrained parent the max width is +inf; measuring against
|
|
75
|
+
// it would produce nonsense (one endless line). Fall back to the
|
|
76
|
+
// viewport-ish minimum and let Yoga assign the real frame.
|
|
77
|
+
float maxWidth = layoutConstraints.maximumSize.width;
|
|
78
|
+
if (!std::isfinite(maxWidth)) {
|
|
79
|
+
maxWidth = std::max(static_cast<float>(layoutConstraints.minimumSize.width), 0.0f);
|
|
80
|
+
}
|
|
81
|
+
// The host views compute the same multiplier (RN's iOS category table /
|
|
82
|
+
// Android configuration.fontScale) so measured and rendered heights
|
|
83
|
+
// agree.
|
|
84
|
+
float fontScale = 1.0f;
|
|
85
|
+
if (props.allowFontScaling && layoutContext.fontSizeMultiplier > 0) {
|
|
86
|
+
fontScale = static_cast<float>(layoutContext.fontSizeMultiplier);
|
|
87
|
+
}
|
|
88
|
+
const float height = jetmarkdown::JetMarkdownMeasurer::shared().measure(
|
|
89
|
+
props.markdown, props.stylesJson, imagesJson, maxWidth, fontScale);
|
|
90
|
+
|
|
91
|
+
Size size;
|
|
92
|
+
size.width = maxWidth;
|
|
93
|
+
size.height = std::clamp(
|
|
94
|
+
static_cast<Float>(height),
|
|
95
|
+
layoutConstraints.minimumSize.height,
|
|
96
|
+
layoutConstraints.maximumSize.height);
|
|
97
|
+
return size;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
} // namespace facebook::react
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <react/renderer/components/JetMarkdownViewSpec/EventEmitters.h>
|
|
4
|
+
#include <react/renderer/components/JetMarkdownViewSpec/Props.h>
|
|
5
|
+
#include <react/renderer/components/view/ConcreteViewShadowNode.h>
|
|
6
|
+
#include <react/renderer/core/LayoutConstraints.h>
|
|
7
|
+
#include <react/renderer/core/LayoutContext.h>
|
|
8
|
+
|
|
9
|
+
#include "JetMarkdownState.h"
|
|
10
|
+
|
|
11
|
+
namespace facebook::react {
|
|
12
|
+
|
|
13
|
+
// Defined in the codegen-generated ShadowNodes.cpp.
|
|
14
|
+
extern const char JetMarkdownViewComponentName[];
|
|
15
|
+
|
|
16
|
+
// Custom shadow node: sizes the component to its markdown content via the
|
|
17
|
+
// platform measurer, replacing the codegen default (which cannot measure).
|
|
18
|
+
class JetMarkdownShadowNode final : public ConcreteViewShadowNode<
|
|
19
|
+
JetMarkdownViewComponentName,
|
|
20
|
+
JetMarkdownViewProps,
|
|
21
|
+
JetMarkdownViewEventEmitter,
|
|
22
|
+
JetMarkdownState> {
|
|
23
|
+
public:
|
|
24
|
+
JetMarkdownShadowNode(
|
|
25
|
+
const ShadowNodeFragment& fragment,
|
|
26
|
+
const ShadowNodeFamily::Shared& family,
|
|
27
|
+
ShadowNodeTraits traits)
|
|
28
|
+
: ConcreteViewShadowNode(fragment, family, traits) {}
|
|
29
|
+
|
|
30
|
+
JetMarkdownShadowNode(
|
|
31
|
+
const ShadowNode& sourceShadowNode,
|
|
32
|
+
const ShadowNodeFragment& fragment)
|
|
33
|
+
: ConcreteViewShadowNode(sourceShadowNode, fragment) {
|
|
34
|
+
// State carries image sizes, which affect measureContent; Yoga must
|
|
35
|
+
// re-measure when a new state arrives.
|
|
36
|
+
if (fragment.state != nullptr) {
|
|
37
|
+
dirtyLayout();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
static ShadowNodeTraits BaseTraits() {
|
|
42
|
+
auto traits = ConcreteViewShadowNode::BaseTraits();
|
|
43
|
+
traits.set(ShadowNodeTraits::Trait::LeafYogaNode);
|
|
44
|
+
traits.set(ShadowNodeTraits::Trait::MeasurableYogaNode);
|
|
45
|
+
return traits;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
Size measureContent(
|
|
49
|
+
const LayoutContext& layoutContext,
|
|
50
|
+
const LayoutConstraints& layoutConstraints) const override;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
} // namespace facebook::react
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <map>
|
|
4
|
+
#include <string>
|
|
5
|
+
|
|
6
|
+
#ifdef RN_SERIALIZABLE_STATE
|
|
7
|
+
#include <folly/dynamic.h>
|
|
8
|
+
#endif
|
|
9
|
+
|
|
10
|
+
namespace facebook::react {
|
|
11
|
+
|
|
12
|
+
// Shadow-node state: intrinsic sizes of images discovered after loading.
|
|
13
|
+
// The host view publishes sizes here; measureContent reads them so the view
|
|
14
|
+
// grows once an un-presized image arrives.
|
|
15
|
+
class JetMarkdownState final {
|
|
16
|
+
public:
|
|
17
|
+
struct ImageSize {
|
|
18
|
+
double width = 0;
|
|
19
|
+
double height = 0;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
JetMarkdownState() = default;
|
|
23
|
+
explicit JetMarkdownState(std::map<std::string, ImageSize> imageSizes)
|
|
24
|
+
: imageSizes(std::move(imageSizes)) {}
|
|
25
|
+
|
|
26
|
+
#ifdef RN_SERIALIZABLE_STATE
|
|
27
|
+
JetMarkdownState(const JetMarkdownState& previousState, folly::dynamic data) {
|
|
28
|
+
imageSizes = previousState.imageSizes;
|
|
29
|
+
const auto& sizes = data["imageSizes"];
|
|
30
|
+
if (sizes.isObject()) {
|
|
31
|
+
for (const auto& entry : sizes.items()) {
|
|
32
|
+
imageSizes[entry.first.getString()] = ImageSize{
|
|
33
|
+
entry.second["width"].getDouble(),
|
|
34
|
+
entry.second["height"].getDouble(),
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
folly::dynamic getDynamic() const {
|
|
41
|
+
folly::dynamic sizes = folly::dynamic::object();
|
|
42
|
+
for (const auto& [url, size] : imageSizes) {
|
|
43
|
+
sizes[url] = folly::dynamic::object("width", size.width)("height", size.height);
|
|
44
|
+
}
|
|
45
|
+
return folly::dynamic::object("imageSizes", std::move(sizes));
|
|
46
|
+
}
|
|
47
|
+
#endif
|
|
48
|
+
|
|
49
|
+
std::map<std::string, ImageSize> imageSizes;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
} // namespace facebook::react
|
package/cpp/react/override/react/renderer/components/JetMarkdownViewSpec/ComponentDescriptors.h
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
// Shadows the codegen-generated ComponentDescriptors.h (this directory is
|
|
4
|
+
// first on the include path) so autolinking and the iOS component view
|
|
5
|
+
// register a descriptor over the custom measurable shadow node instead of
|
|
6
|
+
// the codegen default.
|
|
7
|
+
|
|
8
|
+
#include <react/renderer/core/ConcreteComponentDescriptor.h>
|
|
9
|
+
|
|
10
|
+
#include "../../../../../JetMarkdownEditorShadowNode.h"
|
|
11
|
+
#include "../../../../../JetMarkdownShadowNode.h"
|
|
12
|
+
|
|
13
|
+
namespace facebook::react {
|
|
14
|
+
|
|
15
|
+
using JetMarkdownViewComponentDescriptor =
|
|
16
|
+
ConcreteComponentDescriptor<JetMarkdownShadowNode>;
|
|
17
|
+
|
|
18
|
+
using JetMarkdownEditorComponentDescriptor =
|
|
19
|
+
ConcreteComponentDescriptor<JetMarkdownEditorShadowNode>;
|
|
20
|
+
|
|
21
|
+
} // namespace facebook::react
|