react-native-marcus 0.1.0 → 0.2.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/README.md +220 -63
- package/RNMarcus.podspec +6 -0
- package/android/src/main/java/app/getbullet/marcus/MarcusPackage.kt +2 -1
- package/android/src/main/java/app/getbullet/marcus/MarcusTextDecoratorView.kt +168 -0
- package/android/src/main/java/app/getbullet/marcus/MarcusTextDecoratorViewManager.kt +38 -0
- package/android/src/main/java/app/getbullet/marcus/MarcusTextDecoratorViewManagerSpec.kt +19 -0
- package/android/src/main/java/app/getbullet/marcus/MarcusTextInputDecoratorView.kt +23 -1
- package/android/src/main/java/app/getbullet/marcus/MarkdownBackgroundPainter.kt +147 -0
- package/android/src/main/java/app/getbullet/marcus/MarkdownBackgroundPass.kt +19 -0
- package/android/src/main/java/app/getbullet/marcus/MarkdownCopy.kt +87 -0
- package/android/src/main/java/app/getbullet/marcus/MarkdownFormatter.kt +652 -113
- package/android/src/main/java/app/getbullet/marcus/MarkdownRanges.kt +47 -0
- package/android/src/main/java/app/getbullet/marcus/MarkdownStyle.kt +140 -61
- package/android/src/main/java/app/getbullet/marcus/MarkdownUtils.kt +37 -7
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownAbsoluteLineHeightSpan.kt +48 -0
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownBackgroundSpan.kt +102 -48
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownBlockIndentSpan.kt +22 -4
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownBulletSpan.kt +78 -0
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownCodeBlockSpan.kt +177 -0
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownFontStyleSpan.kt +32 -0
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownFontWeightSpan.kt +34 -0
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownGapSpan.kt +24 -11
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownLetterSpacingSpan.kt +32 -0
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownTextShadowSpan.kt +32 -0
- package/android/src/main/new_arch/CMakeLists.txt +17 -0
- package/android/src/main/new_arch/RNMarcusSpec.h +1 -0
- package/android/src/main/new_arch/react/renderer/components/RNMarcusSpec/MarcusTextDecoratorShadowNode.cpp +235 -0
- package/android/src/main/new_arch/react/renderer/components/RNMarcusSpec/MarcusTextDecoratorShadowNode.h +62 -0
- package/android/src/reactNativeVersionPatch/CustomMountingManager/81/app/getbullet/marcus/CustomFabricUIManager.java +22 -3
- package/android/src/reactNativeVersionPatch/CustomMountingManager/latest/app/getbullet/marcus/CustomFabricUIManager.java +22 -3
- package/android/src/test/java/app/getbullet/marcus/MarkdownCopyTest.kt +69 -0
- package/android/src/test/java/app/getbullet/marcus/MarkdownFormatterTest.kt +170 -25
- package/android/src/test/java/app/getbullet/marcus/RenderModel.kt +22 -5
- package/android/src/test/java/app/getbullet/marcus/spans/MarkdownCodeBlockSpanTest.kt +91 -0
- package/android/src/test/resources/render-model.txt +221 -16
- package/apple/MarcusSwizzle.h +25 -0
- package/apple/MarcusTextDecoratorComponentView.h +22 -0
- package/apple/MarcusTextDecoratorComponentView.mm +72 -0
- package/apple/MarcusTextDecoratorShadowNode.h +62 -0
- package/apple/MarcusTextDecoratorShadowNode.mm +192 -0
- package/apple/MarcusTextDecoratorViewManager.h +4 -0
- package/apple/MarcusTextDecoratorViewManager.mm +11 -0
- package/apple/MarcusTextInputDecoratorComponentView.mm +1 -1
- package/apple/MarcusTextInputDecoratorShadowNode.mm +1 -1
- package/apple/MarcusTextLayoutManager.h +40 -0
- package/apple/MarcusTextLayoutManager.mm +173 -0
- package/apple/MarkdownAttributes.h +23 -2
- package/apple/MarkdownAttributes.m +6 -0
- package/apple/MarkdownCopy.swift +63 -0
- package/apple/MarkdownDecorator.swift +2 -2
- package/apple/MarkdownFormatter+React.swift +23 -0
- package/apple/MarkdownFormatter.swift +869 -148
- package/apple/MarkdownParagraphLayoutManager.swift +455 -0
- package/apple/MarkdownSwiftInterop.h +0 -1
- package/apple/MarkdownTextBackground.swift +59 -1
- package/apple/MarkdownTextFieldObserver.swift +2 -2
- package/apple/MarkdownTextLayoutFragment.swift +159 -33
- package/apple/MarkdownTextLayoutManagerDelegate.swift +67 -3
- package/apple/MarkdownTextStorageDelegate.swift +2 -2
- package/apple/MarkdownTextViewObserver.swift +2 -2
- package/apple/MarkdownUtils.swift +38 -0
- package/apple/MarkdownWritingDirection.swift +132 -0
- package/apple/RCTMarcusStyle+Codegen.h +115 -9
- package/apple/RCTMarcusStyle.h +128 -31
- package/apple/RCTMarcusStyle.m +48 -0
- package/apple/RCTParagraphComponentView+Marcus.h +17 -0
- package/apple/RCTParagraphComponentView+Marcus.mm +38 -0
- package/apple/RCTTextInputComponentView+Marcus.mm +1 -25
- package/cpp/react/renderer/components/RNMarcusSpec/MarcusTextDecoratorState.h +37 -0
- package/cpp/react/renderer/components/RNMarcusSpec/MarcusTextDecoratorViewComponentDescriptor.h +17 -0
- package/lib/commonjs/MarcusTextDecoratorViewNativeComponent.ts +199 -0
- package/lib/commonjs/MarcusTextInputDecoratorViewNativeComponent.ts +145 -58
- package/lib/commonjs/MarkdownText.js +330 -0
- package/lib/commonjs/MarkdownText.js.map +1 -0
- package/lib/commonjs/MarkdownText.web.js +529 -0
- package/lib/commonjs/MarkdownText.web.js.map +1 -0
- package/lib/commonjs/MarkdownTextInput.js +22 -27
- package/lib/commonjs/MarkdownTextInput.js.map +1 -1
- package/lib/commonjs/MarkdownTextInput.web.js +12 -7
- package/lib/commonjs/MarkdownTextInput.web.js.map +1 -1
- package/lib/commonjs/atomUtils.js +112 -0
- package/lib/commonjs/atomUtils.js.map +1 -0
- package/lib/commonjs/childrenUtils.js +36 -0
- package/lib/commonjs/childrenUtils.js.map +1 -0
- package/lib/commonjs/index.js +8 -7
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/math/environment.js +69 -0
- package/lib/commonjs/math/environment.js.map +1 -0
- package/lib/commonjs/math/index.js +61 -0
- package/lib/commonjs/math/index.js.map +1 -0
- package/lib/commonjs/math/mathjax.js +548 -0
- package/lib/commonjs/math/mathjax.js.map +1 -0
- package/lib/commonjs/metro.js +172 -0
- package/lib/commonjs/metro.js.map +1 -0
- package/lib/commonjs/parser/index.d.ts +3 -0
- package/lib/commonjs/parser/index.js +450 -42
- package/lib/commonjs/parser/index.js.map +4 -4
- package/lib/commonjs/stripUtils.js +743 -0
- package/lib/commonjs/stripUtils.js.map +1 -0
- package/lib/commonjs/styleUtils.js +194 -23
- package/lib/commonjs/styleUtils.js.map +1 -1
- package/lib/commonjs/web/MarkdownElements.css +67 -0
- package/lib/commonjs/web/MarkdownTextInput.css +9 -7
- package/lib/commonjs/web/utils/blockLayout.js +95 -7
- package/lib/commonjs/web/utils/blockLayout.js.map +1 -1
- package/lib/commonjs/web/utils/blockUtils.js +327 -54
- package/lib/commonjs/web/utils/blockUtils.js.map +1 -1
- package/lib/commonjs/web/utils/elementUtils.js +80 -0
- package/lib/commonjs/web/utils/elementUtils.js.map +1 -0
- package/lib/commonjs/web/utils/parserUtils.js +84 -28
- package/lib/commonjs/web/utils/parserUtils.js.map +1 -1
- package/lib/commonjs/web/utils/treeUtils.js +6 -0
- package/lib/commonjs/web/utils/treeUtils.js.map +1 -1
- package/lib/commonjs/web/utils/webStyleUtils.js +25 -5
- package/lib/commonjs/web/utils/webStyleUtils.js.map +1 -1
- package/lib/module/MarcusTextDecoratorViewNativeComponent.ts +199 -0
- package/lib/module/MarcusTextInputDecoratorViewNativeComponent.ts +145 -58
- package/lib/module/MarkdownText.js +325 -0
- package/lib/module/MarkdownText.js.map +1 -0
- package/lib/module/MarkdownText.web.js +524 -0
- package/lib/module/MarkdownText.web.js.map +1 -0
- package/lib/module/MarkdownTextInput.js +24 -29
- package/lib/module/MarkdownTextInput.js.map +1 -1
- package/lib/module/MarkdownTextInput.web.js +12 -7
- package/lib/module/MarkdownTextInput.web.js.map +1 -1
- package/lib/module/atomUtils.js +106 -0
- package/lib/module/atomUtils.js.map +1 -0
- package/lib/module/childrenUtils.js +33 -0
- package/lib/module/childrenUtils.js.map +1 -0
- package/lib/module/index.js +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/math/environment.js +67 -0
- package/lib/module/math/environment.js.map +1 -0
- package/lib/module/math/index.js +56 -0
- package/lib/module/math/index.js.map +1 -0
- package/lib/module/math/mathjax.js +541 -0
- package/lib/module/math/mathjax.js.map +1 -0
- package/lib/module/metro.js +169 -0
- package/lib/module/metro.js.map +1 -0
- package/lib/module/parser/index.d.ts +3 -0
- package/lib/module/parser/index.js +450 -42
- package/lib/module/parser/index.js.map +4 -4
- package/lib/module/stripUtils.js +739 -0
- package/lib/module/stripUtils.js.map +1 -0
- package/lib/module/styleUtils.js +196 -25
- package/lib/module/styleUtils.js.map +1 -1
- package/lib/module/web/MarkdownElements.css +67 -0
- package/lib/module/web/MarkdownTextInput.css +9 -7
- package/lib/module/web/utils/blockLayout.js +94 -8
- package/lib/module/web/utils/blockLayout.js.map +1 -1
- package/lib/module/web/utils/blockUtils.js +328 -56
- package/lib/module/web/utils/blockUtils.js.map +1 -1
- package/lib/module/web/utils/elementUtils.js +75 -0
- package/lib/module/web/utils/elementUtils.js.map +1 -0
- package/lib/module/web/utils/parserUtils.js +86 -30
- package/lib/module/web/utils/parserUtils.js.map +1 -1
- package/lib/module/web/utils/treeUtils.js +6 -0
- package/lib/module/web/utils/treeUtils.js.map +1 -1
- package/lib/module/web/utils/webStyleUtils.js +25 -5
- package/lib/module/web/utils/webStyleUtils.js.map +1 -1
- package/lib/typescript/commonjs/e2e/links.test.d.ts +2 -0
- package/lib/typescript/commonjs/e2e/links.test.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/MarcusTextDecoratorViewNativeComponent.d.ts +93 -0
- package/lib/typescript/commonjs/src/MarcusTextDecoratorViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/MarcusTextInputDecoratorViewNativeComponent.d.ts +64 -51
- package/lib/typescript/commonjs/src/MarcusTextInputDecoratorViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/MarkdownText.d.ts +127 -0
- package/lib/typescript/commonjs/src/MarkdownText.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/MarkdownText.web.d.ts +126 -0
- package/lib/typescript/commonjs/src/MarkdownText.web.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/MarkdownTextInput.d.ts +23 -1
- package/lib/typescript/commonjs/src/MarkdownTextInput.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/MarkdownTextInput.web.d.ts +26 -4
- package/lib/typescript/commonjs/src/MarkdownTextInput.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/atomUtils.d.ts +58 -0
- package/lib/typescript/commonjs/src/atomUtils.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/childrenUtils.d.ts +12 -0
- package/lib/typescript/commonjs/src/childrenUtils.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/commonTypes.d.ts +39 -3
- package/lib/typescript/commonjs/src/commonTypes.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/index.d.ts +2 -1
- package/lib/typescript/commonjs/src/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/math/environment.d.ts +7 -0
- package/lib/typescript/commonjs/src/math/environment.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/math/index.d.ts +64 -0
- package/lib/typescript/commonjs/src/math/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/math/mathjax.d.ts +63 -0
- package/lib/typescript/commonjs/src/math/mathjax.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/metro.d.ts +59 -0
- package/lib/typescript/commonjs/src/metro.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/parser/index.d.ts +3 -3
- package/lib/typescript/commonjs/src/parser/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/parser/micromark-extension-mentions.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/rangeUtils.d.ts +1 -1
- package/lib/typescript/commonjs/src/stripUtils.d.ts +108 -0
- package/lib/typescript/commonjs/src/stripUtils.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/styleUtils.d.ts +62 -4
- package/lib/typescript/commonjs/src/styleUtils.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/web/utils/blockLayout.d.ts +32 -4
- package/lib/typescript/commonjs/src/web/utils/blockLayout.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/web/utils/blockUtils.d.ts +20 -8
- package/lib/typescript/commonjs/src/web/utils/blockUtils.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/web/utils/elementUtils.d.ts +37 -0
- package/lib/typescript/commonjs/src/web/utils/elementUtils.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/web/utils/parserUtils.d.ts +5 -5
- package/lib/typescript/commonjs/src/web/utils/parserUtils.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/web/utils/treeUtils.d.ts +6 -1
- package/lib/typescript/commonjs/src/web/utils/treeUtils.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/web/utils/webStyleUtils.d.ts +2 -2
- package/lib/typescript/commonjs/src/web/utils/webStyleUtils.d.ts.map +1 -1
- package/lib/typescript/module/e2e/links.test.d.ts +2 -0
- package/lib/typescript/module/e2e/links.test.d.ts.map +1 -0
- package/lib/typescript/module/src/MarcusTextDecoratorViewNativeComponent.d.ts +93 -0
- package/lib/typescript/module/src/MarcusTextDecoratorViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/module/src/MarcusTextInputDecoratorViewNativeComponent.d.ts +64 -51
- package/lib/typescript/module/src/MarcusTextInputDecoratorViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/module/src/MarkdownText.d.ts +127 -0
- package/lib/typescript/module/src/MarkdownText.d.ts.map +1 -0
- package/lib/typescript/module/src/MarkdownText.web.d.ts +126 -0
- package/lib/typescript/module/src/MarkdownText.web.d.ts.map +1 -0
- package/lib/typescript/module/src/MarkdownTextInput.d.ts +23 -1
- package/lib/typescript/module/src/MarkdownTextInput.d.ts.map +1 -1
- package/lib/typescript/module/src/MarkdownTextInput.web.d.ts +26 -4
- package/lib/typescript/module/src/MarkdownTextInput.web.d.ts.map +1 -1
- package/lib/typescript/module/src/atomUtils.d.ts +58 -0
- package/lib/typescript/module/src/atomUtils.d.ts.map +1 -0
- package/lib/typescript/module/src/childrenUtils.d.ts +12 -0
- package/lib/typescript/module/src/childrenUtils.d.ts.map +1 -0
- package/lib/typescript/module/src/commonTypes.d.ts +39 -3
- package/lib/typescript/module/src/commonTypes.d.ts.map +1 -1
- package/lib/typescript/module/src/index.d.ts +2 -1
- package/lib/typescript/module/src/index.d.ts.map +1 -1
- package/lib/typescript/module/src/math/environment.d.ts +7 -0
- package/lib/typescript/module/src/math/environment.d.ts.map +1 -0
- package/lib/typescript/module/src/math/index.d.ts +64 -0
- package/lib/typescript/module/src/math/index.d.ts.map +1 -0
- package/lib/typescript/module/src/math/mathjax.d.ts +63 -0
- package/lib/typescript/module/src/math/mathjax.d.ts.map +1 -0
- package/lib/typescript/module/src/metro.d.ts +59 -0
- package/lib/typescript/module/src/metro.d.ts.map +1 -0
- package/lib/typescript/module/src/parser/index.d.ts +3 -3
- package/lib/typescript/module/src/parser/index.d.ts.map +1 -1
- package/lib/typescript/module/src/parser/micromark-extension-mentions.d.ts.map +1 -1
- package/lib/typescript/module/src/rangeUtils.d.ts +1 -1
- package/lib/typescript/module/src/stripUtils.d.ts +108 -0
- package/lib/typescript/module/src/stripUtils.d.ts.map +1 -0
- package/lib/typescript/module/src/styleUtils.d.ts +62 -4
- package/lib/typescript/module/src/styleUtils.d.ts.map +1 -1
- package/lib/typescript/module/src/web/utils/blockLayout.d.ts +32 -4
- package/lib/typescript/module/src/web/utils/blockLayout.d.ts.map +1 -1
- package/lib/typescript/module/src/web/utils/blockUtils.d.ts +20 -8
- package/lib/typescript/module/src/web/utils/blockUtils.d.ts.map +1 -1
- package/lib/typescript/module/src/web/utils/elementUtils.d.ts +37 -0
- package/lib/typescript/module/src/web/utils/elementUtils.d.ts.map +1 -0
- package/lib/typescript/module/src/web/utils/parserUtils.d.ts +5 -5
- package/lib/typescript/module/src/web/utils/parserUtils.d.ts.map +1 -1
- package/lib/typescript/module/src/web/utils/treeUtils.d.ts +6 -1
- package/lib/typescript/module/src/web/utils/treeUtils.d.ts.map +1 -1
- package/lib/typescript/module/src/web/utils/webStyleUtils.d.ts +2 -2
- package/lib/typescript/module/src/web/utils/webStyleUtils.d.ts.map +1 -1
- package/package.json +29 -2
- package/react-native.config.js +8 -1
- package/src/MarcusTextDecoratorViewNativeComponent.ts +199 -0
- package/src/MarcusTextInputDecoratorViewNativeComponent.ts +145 -58
- package/src/MarkdownText.tsx +472 -0
- package/src/MarkdownText.web.tsx +668 -0
- package/src/MarkdownTextInput.tsx +42 -38
- package/src/MarkdownTextInput.web.tsx +36 -13
- package/src/atomUtils.ts +112 -0
- package/src/childrenUtils.ts +39 -0
- package/src/commonTypes.ts +69 -9
- package/src/index.tsx +2 -1
- package/src/math/environment.ts +68 -0
- package/src/math/index.ts +78 -0
- package/src/math/mathjax.ts +604 -0
- package/src/metro.ts +238 -0
- package/src/parser/index.ts +175 -10
- package/src/parser/micromark-extension-mentions.ts +104 -11
- package/src/stripUtils.ts +919 -0
- package/src/styleUtils.ts +290 -26
- package/src/web/MarkdownElements.css +67 -0
- package/src/web/MarkdownTextInput.css +9 -7
- package/src/web/utils/blockLayout.ts +124 -14
- package/src/web/utils/blockUtils.ts +365 -59
- package/src/web/utils/elementUtils.ts +87 -0
- package/src/web/utils/parserUtils.ts +119 -31
- package/src/web/utils/treeUtils.ts +6 -1
- package/src/web/utils/webStyleUtils.ts +32 -8
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownBackgroundColorSpan.kt +0 -6
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownBoldSpan.kt +0 -6
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownItalicSpan.kt +0 -6
- package/apple/RCTMarcusStyle+Codegen.mm +0 -64
- package/apple/RCTMarcusUtils.h +0 -26
- package/apple/RCTMarcusUtils.mm +0 -26
|
@@ -0,0 +1,524 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { StyleSheet, Text } from "react-native";
|
|
4
|
+
import React from "react";
|
|
5
|
+
import { createPortal } from "react-dom";
|
|
6
|
+
import "./web/MarkdownElements.css";
|
|
7
|
+
import { atomsOf, NO_ATOMS, sourceOf } from "./atomUtils.js";
|
|
8
|
+
import { available as mathAvailable, renderMath, speakMath } from "./math/index.js";
|
|
9
|
+
import { flattenText } from "./childrenUtils.js";
|
|
10
|
+
import { OBJECT_REPLACEMENT, stripSyntax } from "./stripUtils.js";
|
|
11
|
+
import { createTextMeasurer } from "./web/utils/measureUtils.js";
|
|
12
|
+
import { parseRangesToHTMLNodes } from "./web/utils/parserUtils.js";
|
|
13
|
+
import { processMarkdownStyle } from "./web/utils/webStyleUtils.js";
|
|
14
|
+
import { createParser } from "./parser/index.js";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* What to show in place of an image.
|
|
18
|
+
*
|
|
19
|
+
* The native contract asks for a view with a definite size, because the text
|
|
20
|
+
* layout has to know how much room to leave before it lays the line out. The
|
|
21
|
+
* web has no such requirement -- the browser reflows around whatever turns up
|
|
22
|
+
* -- but the same callback runs on both, so write it for the stricter one.
|
|
23
|
+
*
|
|
24
|
+
* `inline` says whether the image shares its line with anything else, which is
|
|
25
|
+
* usually what decides how big it should be: alone on a line it is a figure,
|
|
26
|
+
* and in the middle of a sentence it is a badge. A block marker does not count
|
|
27
|
+
* as company, and another image does.
|
|
28
|
+
*
|
|
29
|
+
* Every string is always a string: an image written without a title is handed
|
|
30
|
+
* an empty one rather than nothing, so a caller never has to tell the two
|
|
31
|
+
* apart.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* What to draw an SVG with.
|
|
36
|
+
*
|
|
37
|
+
* Handed a complete SVG document and the box it belongs in, and expected to
|
|
38
|
+
* return a view of exactly that size. There is deliberately nothing else in the
|
|
39
|
+
* signature: everything a picture needs -- the colour, the glyph outlines, the
|
|
40
|
+
* baseline it sits on -- is either inside the XML already or has been taken
|
|
41
|
+
* care of by the time this is called, so `<SvgXml xml={xml} width={width}
|
|
42
|
+
* height={height} />` is the whole of a correct implementation.
|
|
43
|
+
*
|
|
44
|
+
* It exists because a renderer for SVG is a dependency, and which one is not
|
|
45
|
+
* this library's business: `react-native-svg` on native, whatever you like on
|
|
46
|
+
* the web.
|
|
47
|
+
*
|
|
48
|
+
* Returning nothing leaves the drawing out, and the span it stood for still
|
|
49
|
+
* costs its one character either way.
|
|
50
|
+
*/
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* What to do when a link is pressed.
|
|
54
|
+
*
|
|
55
|
+
* The label is the text the link was rendered as, which is all a reader saw of
|
|
56
|
+
* it: the destination is not in the document any more. Reference links are not
|
|
57
|
+
* covered -- their destination is written somewhere else and is not resolved
|
|
58
|
+
* yet -- so they render as links and do nothing.
|
|
59
|
+
*
|
|
60
|
+
* Opening the URL is deliberately not done for you: what a link means is the
|
|
61
|
+
* application's to decide, and a message from a stranger is the last place to
|
|
62
|
+
* hand an arbitrary URL to `Linking.openURL` without looking at it first.
|
|
63
|
+
*
|
|
64
|
+
* Every string is always a string: a link written without a title is handed an
|
|
65
|
+
* empty one rather than nothing.
|
|
66
|
+
*/
|
|
67
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
68
|
+
// `useLayoutEffect` warns when it runs during a server render, and there is no layout to be before
|
|
69
|
+
// on a server anyway. Same seam the input uses.
|
|
70
|
+
const useClientEffect = typeof window === "undefined" ? React.useEffect : React.useLayoutEffect;
|
|
71
|
+
const NO_SLOTS = [];
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* What maths is sized against when the caller set no size at all, matching what
|
|
75
|
+
* the native component assumes so the two agree.
|
|
76
|
+
*/
|
|
77
|
+
const DEFAULT_FONT_SIZE = 14;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Replaces each placeholder character in the built markup with an empty element
|
|
81
|
+
* to render an embed or a maths span into.
|
|
82
|
+
*
|
|
83
|
+
* The elements have to be made here rather than rendered, because everything
|
|
84
|
+
* under the host is raw DOM this component built and React knows nothing about
|
|
85
|
+
* -- so the embeds are portalled into these afterwards, which is the one way to
|
|
86
|
+
* put a React subtree somewhere React did not put it.
|
|
87
|
+
*
|
|
88
|
+
* Text nodes are collected before any of them is split: splitting rewrites the
|
|
89
|
+
* tree the walker is walking.
|
|
90
|
+
*/
|
|
91
|
+
function mountSlots(host) {
|
|
92
|
+
const walker = document.createTreeWalker(host, NodeFilter.SHOW_TEXT);
|
|
93
|
+
// `globalThis` because `Text` in this file is the react-native one.
|
|
94
|
+
const texts = [];
|
|
95
|
+
while (walker.nextNode()) {
|
|
96
|
+
texts.push(walker.currentNode);
|
|
97
|
+
}
|
|
98
|
+
const slots = [];
|
|
99
|
+
for (const text of texts) {
|
|
100
|
+
let node = text;
|
|
101
|
+
let index = node.data.indexOf(OBJECT_REPLACEMENT);
|
|
102
|
+
while (index !== -1) {
|
|
103
|
+
const placeholder = node.splitText(index);
|
|
104
|
+
const rest = placeholder.splitText(OBJECT_REPLACEMENT.length);
|
|
105
|
+
const slot = document.createElement("span");
|
|
106
|
+
|
|
107
|
+
// Inline-block so the embed sits in the line the way an attachment does
|
|
108
|
+
// on native, on the baseline and taking the width it asks for.
|
|
109
|
+
slot.style.display = "inline-block";
|
|
110
|
+
// `text-indent` is inherited, and an inline-block lays out its own first
|
|
111
|
+
// line -- so a list item's hanging indent, which is a negative
|
|
112
|
+
// `text-indent` on the item, shifted the drawing left out of its box and
|
|
113
|
+
// over the word before it. Nothing in here is a first line of anything.
|
|
114
|
+
slot.style.textIndent = "0";
|
|
115
|
+
slot.setAttribute("data-atom", String(slots.length));
|
|
116
|
+
placeholder.replaceWith(slot);
|
|
117
|
+
slots.push(slot);
|
|
118
|
+
node = rest;
|
|
119
|
+
index = node.data.indexOf(OBJECT_REPLACEMENT);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return slots.length > 0 ? slots : NO_SLOTS;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* How the list markers are drawn, read off the element they will be drawn in.
|
|
127
|
+
*
|
|
128
|
+
* A display renders them rather than showing them, and their size comes from the base font --
|
|
129
|
+
* whatever the wrapped `Text` resolved to, so it is asked rather than assumed.
|
|
130
|
+
*/
|
|
131
|
+
function markerRendering(host) {
|
|
132
|
+
return {
|
|
133
|
+
display: true,
|
|
134
|
+
fontSize: parseFloat(window.getComputedStyle(host).fontSize) || 0
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/** Anything with a scheme this does not name is left without an `href`. */
|
|
139
|
+
const SAFE_SCHEME = /^(?:https?|mailto|tel):/i;
|
|
140
|
+
const SCHEME = /^[a-z][a-z0-9+.\-]*:/i;
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* The destination as an `href`, or nothing if it must not become one.
|
|
144
|
+
*
|
|
145
|
+
* A browser strips whitespace and control characters before it reads a scheme,
|
|
146
|
+
* so `java\nscript:alert(1)` is `javascript:` as far as it is concerned, and it
|
|
147
|
+
* has to be here too. Anything carrying a scheme that is not one of the four
|
|
148
|
+
* safe ones is refused outright rather than guessed at; a destination with no
|
|
149
|
+
* scheme is a relative URL and is left to resolve the way any other relative
|
|
150
|
+
* link on the page does.
|
|
151
|
+
*/
|
|
152
|
+
function hrefFor(uri) {
|
|
153
|
+
const bare = uri.replace(/[\u0000-\u0020]/g, "");
|
|
154
|
+
if (bare === "" || SCHEME.test(bare) && !SAFE_SCHEME.test(bare)) {
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
return uri;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Marks the elements a link was built into with the link they belong to, and hands them the
|
|
162
|
+
* destination when it is one a browser may follow.
|
|
163
|
+
*
|
|
164
|
+
* The markup is not one element per link: a label split over two lines is built
|
|
165
|
+
* into one element per line, and a label with emphasis in it is an element with
|
|
166
|
+
* more elements inside. So the press is caught on the host and walked back up to
|
|
167
|
+
* the nearest marked ancestor, and all this has to do is put the mark on every
|
|
168
|
+
* element that a link's own range produced.
|
|
169
|
+
*
|
|
170
|
+
* They are anchors already -- that is the tag `link` is built as, in the input
|
|
171
|
+
* too, where a link being typed has no destination yet. What is added here is
|
|
172
|
+
* the `href`, which comes from the document's destinations rather than from its
|
|
173
|
+
* ranges. With one, the browser shows the destination in the status bar, offers
|
|
174
|
+
* it to the context menu, opens it in a new tab on a modified click, and a
|
|
175
|
+
* screen reader announces it; the click handler stops it navigating, because
|
|
176
|
+
* what a link means is the application's to decide. A destination that cannot
|
|
177
|
+
* safely become an href gets none -- and an anchor without one is neither in the
|
|
178
|
+
* tab order nor a link to a screen reader, so those two are said outright.
|
|
179
|
+
*/
|
|
180
|
+
function markLinks(node, links) {
|
|
181
|
+
if (node.type === "link") {
|
|
182
|
+
const index = links.findIndex(link => node.start >= link.start && node.start < link.start + link.length);
|
|
183
|
+
|
|
184
|
+
// A reference link has no destination yet, so its label is styled as a link
|
|
185
|
+
// and left inert rather than marked.
|
|
186
|
+
if (index !== -1) {
|
|
187
|
+
const link = links[index];
|
|
188
|
+
const href = hrefFor(link.uri);
|
|
189
|
+
const element = node.element;
|
|
190
|
+
if (href !== null) {
|
|
191
|
+
element.setAttribute("href", href);
|
|
192
|
+
// Untrusted markdown opened in a new tab has no business reaching back.
|
|
193
|
+
element.setAttribute("rel", "noopener noreferrer");
|
|
194
|
+
if (link.title !== "") {
|
|
195
|
+
element.setAttribute("title", link.title);
|
|
196
|
+
}
|
|
197
|
+
} else {
|
|
198
|
+
// Nothing else on the page is reachable by keyboard, and a link a
|
|
199
|
+
// pointer can press and a keyboard cannot is not a link.
|
|
200
|
+
element.setAttribute("role", "link");
|
|
201
|
+
element.setAttribute("tabindex", "0");
|
|
202
|
+
element.style.cursor = "pointer";
|
|
203
|
+
}
|
|
204
|
+
element.setAttribute("data-link", String(index));
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
node.childNodes.forEach(child => markLinks(child, links));
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* `Text`, with the markdown in its content rendered rather than shown.
|
|
212
|
+
*
|
|
213
|
+
* Built by the same DOM builder the input uses, from the same ranges, so a message and the composer
|
|
214
|
+
* it was typed in agree by construction -- which on the web means agreeing about indents, about
|
|
215
|
+
* ribbons drawn as background layers, and about the marker widths those are measured from. The only
|
|
216
|
+
* difference is the input, where the syntax is still there to be edited.
|
|
217
|
+
*
|
|
218
|
+
* Rendered as a real `Text` whose children are then replaced. React only ever writes the stripped
|
|
219
|
+
* string into the host element -- a lone string child is set with `textContent`, never as a node it
|
|
220
|
+
* holds on to -- so the effect below is free to put the built markup there instead, and a render
|
|
221
|
+
* that changes the text simply wipes it and lets the effect rebuild before the frame is painted.
|
|
222
|
+
* Rendering the plain string rather than nothing also means a prerendered page carries the prose:
|
|
223
|
+
* `expo export` runs every route through Node, where there is no DOM to build markup with.
|
|
224
|
+
*/
|
|
225
|
+
const MarkdownText = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
226
|
+
const {
|
|
227
|
+
markdownStyle: markdownStyleProp,
|
|
228
|
+
gfm,
|
|
229
|
+
mention,
|
|
230
|
+
math,
|
|
231
|
+
renderEmbed,
|
|
232
|
+
renderSVG,
|
|
233
|
+
mathAccessibilityLocale,
|
|
234
|
+
onLinkPress,
|
|
235
|
+
children,
|
|
236
|
+
...textProps
|
|
237
|
+
} = props;
|
|
238
|
+
const hostRef = React.useRef(null);
|
|
239
|
+
const [slots, setSlots] = React.useState(NO_SLOTS);
|
|
240
|
+
|
|
241
|
+
// Whether there is a handler, not which one: a caller who writes the callback
|
|
242
|
+
// inline would otherwise re-parse the document on every render.
|
|
243
|
+
const withEmbeds = renderEmbed !== undefined;
|
|
244
|
+
// Maths is only taken out of the text when there is both something to draw it
|
|
245
|
+
// with and a backend to typeset it -- see `./math`. Left in, `$$x^2$$` is
|
|
246
|
+
// shown as it was written.
|
|
247
|
+
const withMath = renderSVG !== undefined && mathAvailable;
|
|
248
|
+
const withLinks = onLinkPress !== undefined;
|
|
249
|
+
|
|
250
|
+
// The same worklet for as long as the flavour is the same one, so the
|
|
251
|
+
// document is only re-parsed when the document itself changes.
|
|
252
|
+
const parser = createParser({
|
|
253
|
+
gfm,
|
|
254
|
+
mention,
|
|
255
|
+
math
|
|
256
|
+
});
|
|
257
|
+
const markdown = React.useMemo(() => {
|
|
258
|
+
const text = flattenText(children);
|
|
259
|
+
return text === null ? null : stripSyntax(text, parser(text), {
|
|
260
|
+
embeds: withEmbeds,
|
|
261
|
+
math: withMath,
|
|
262
|
+
links: withLinks
|
|
263
|
+
});
|
|
264
|
+
}, [children, parser, withEmbeds, withMath, withLinks]);
|
|
265
|
+
|
|
266
|
+
// Both kinds of placeholder in the order they stand in the text, which is the
|
|
267
|
+
// order `mountSlots` makes the slots in.
|
|
268
|
+
const atoms = React.useMemo(() => markdown === null ? NO_ATOMS : atomsOf(markdown), [markdown]);
|
|
269
|
+
|
|
270
|
+
// Read off this element's own style rather than the computed one, so the
|
|
271
|
+
// numbers the maths is drawn at are the numbers the native component would
|
|
272
|
+
// draw it at.
|
|
273
|
+
const {
|
|
274
|
+
fontSize,
|
|
275
|
+
color
|
|
276
|
+
} = React.useMemo(() => {
|
|
277
|
+
const flattened = StyleSheet.flatten(textProps.style);
|
|
278
|
+
return {
|
|
279
|
+
fontSize: typeof flattened?.fontSize === "number" ? flattened.fontSize : DEFAULT_FONT_SIZE,
|
|
280
|
+
color: typeof flattened?.color === "string" ? flattened.color : undefined
|
|
281
|
+
};
|
|
282
|
+
}, [textProps.style]);
|
|
283
|
+
|
|
284
|
+
// Drawn during render rather than at portal time, because the depth a maths
|
|
285
|
+
// span reports has to be on its slot before the frame is painted.
|
|
286
|
+
const drawn = React.useMemo(() => atoms.map(atom => {
|
|
287
|
+
if (atom.kind === "embed") {
|
|
288
|
+
return {
|
|
289
|
+
element: renderEmbed?.(atom.uri, atom.alt, atom.title, atom.inline) ?? null,
|
|
290
|
+
depth: 0,
|
|
291
|
+
// Whatever the caller's element measures: only it knows how big an
|
|
292
|
+
// embed is, and that is what `renderEmbed` promises to say.
|
|
293
|
+
box: null,
|
|
294
|
+
// An image's `alt` is its accessible name by every spec there is,
|
|
295
|
+
// and left empty it declares the image decorative.
|
|
296
|
+
label: atom.alt,
|
|
297
|
+
role: "img",
|
|
298
|
+
// Nothing: an image's alt text is prose, written in the language
|
|
299
|
+
// the document is written in, and saying otherwise would have a
|
|
300
|
+
// screen reader read it in the wrong voice.
|
|
301
|
+
lang: "",
|
|
302
|
+
source: sourceOf(atom)
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
const rendered = renderMath(atom.tex, atom.display, fontSize, color);
|
|
306
|
+
return {
|
|
307
|
+
element: rendered === null ? null : renderSVG?.(rendered.svg, rendered.width, rendered.height),
|
|
308
|
+
depth: rendered?.depth ?? 0,
|
|
309
|
+
box: rendered === null ? null : {
|
|
310
|
+
width: rendered.width,
|
|
311
|
+
height: rendered.height
|
|
312
|
+
},
|
|
313
|
+
// What the picture says, rather than the TeX it was written as: a
|
|
314
|
+
// reader who asked for a document did not ask for its source code.
|
|
315
|
+
label: speakMath(atom.tex, atom.display, mathAccessibilityLocale) ?? atom.tex,
|
|
316
|
+
role: "math",
|
|
317
|
+
// The language the label is in, which is the one thing on the page
|
|
318
|
+
// that may differ from the document's own: a screen reader picks its
|
|
319
|
+
// voice from this, and French read in an English voice is worse than
|
|
320
|
+
// no voice at all.
|
|
321
|
+
lang: mathAccessibilityLocale ?? "",
|
|
322
|
+
// What a copy puts on the clipboard in place of the picture: the
|
|
323
|
+
// markdown it was written as, so that pasting it back gives the
|
|
324
|
+
// document it came from rather than a hole where an equation was.
|
|
325
|
+
source: sourceOf(atom)
|
|
326
|
+
};
|
|
327
|
+
}), [atoms, renderEmbed, renderSVG, fontSize, color, mathAccessibilityLocale]);
|
|
328
|
+
const markdownStyle = React.useMemo(() => processMarkdownStyle(markdownStyleProp), [markdownStyleProp]);
|
|
329
|
+
|
|
330
|
+
// What React writes into the host, and so what a prerendered page carries. The placeholders go:
|
|
331
|
+
// they only mean anything to the markup the effect builds, and a page rendered in Node -- where
|
|
332
|
+
// there is no DOM to build that markup with -- would otherwise show a row of tofu.
|
|
333
|
+
const content = React.useMemo(() => {
|
|
334
|
+
if (markdown === null) {
|
|
335
|
+
return null;
|
|
336
|
+
}
|
|
337
|
+
return markdown.text.includes(OBJECT_REPLACEMENT) ? markdown.text.split(OBJECT_REPLACEMENT).join("") : markdown.text;
|
|
338
|
+
}, [markdown]);
|
|
339
|
+
useClientEffect(() => {
|
|
340
|
+
const host = hostRef.current;
|
|
341
|
+
if (!host || markdown === null) {
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
const {
|
|
345
|
+
dom,
|
|
346
|
+
tree
|
|
347
|
+
} = parseRangesToHTMLNodes(markdown.text, markdown.ranges, true, markdownStyle, false,
|
|
348
|
+
// Measured against this element, so marker widths come out in the font the text is actually
|
|
349
|
+
// drawn in rather than the document's default.
|
|
350
|
+
createTextMeasurer(host),
|
|
351
|
+
// A display renders the list markers rather than showing them, sized from the font this
|
|
352
|
+
// element renders at: the base font, which is the wrapped `Text`'s own.
|
|
353
|
+
markerRendering(host));
|
|
354
|
+
if (markdown.links.length > 0) {
|
|
355
|
+
markLinks(tree, markdown.links);
|
|
356
|
+
}
|
|
357
|
+
host.replaceChildren(...Array.from(dom.childNodes));
|
|
358
|
+
const next = atoms.length > 0 ? mountSlots(host) : NO_SLOTS;
|
|
359
|
+
|
|
360
|
+
// Both empty is the overwhelmingly common case, and setting state there would re-render every
|
|
361
|
+
// document that has no embeds in it for nothing.
|
|
362
|
+
setSlots(previous => previous === NO_SLOTS && next === NO_SLOTS ? previous : next);
|
|
363
|
+
// React wipes the host with `textContent` whenever the string child changes, which is exactly
|
|
364
|
+
// when `markdown` does, so these two are all it takes to be sure the markup is back before the
|
|
365
|
+
// frame is painted.
|
|
366
|
+
}, [markdown, markdownStyle, atoms]);
|
|
367
|
+
|
|
368
|
+
// Everything about a slot that is the slot's own business rather than the
|
|
369
|
+
// caller's: it is the inline-level box, so aligning anything inside it would
|
|
370
|
+
// only move that box's contents, and it is the element in the accessibility
|
|
371
|
+
// tree, so it is the one thing that can be given a name. Its own effect, so
|
|
372
|
+
// that a caller redrawing from state brings all three with it.
|
|
373
|
+
useClientEffect(() => {
|
|
374
|
+
slots.forEach((slot, index) => {
|
|
375
|
+
const content = drawn[index];
|
|
376
|
+
const depth = content?.depth ?? 0;
|
|
377
|
+
|
|
378
|
+
// The depth the maths hangs below the baseline, which on the web is the
|
|
379
|
+
// same displacement by another name.
|
|
380
|
+
slot.style.verticalAlign = depth === 0 ? "" : `${-depth}px`;
|
|
381
|
+
|
|
382
|
+
// The box the drawing was measured for, stated rather than shrink-wrapped.
|
|
383
|
+
// An inline-block with no width of its own is shrink-to-fit, and
|
|
384
|
+
// shrink-to-fit is capped by what is left of the line -- so a wide
|
|
385
|
+
// expression near a margin got a box narrower than its own picture and the
|
|
386
|
+
// picture hung out of it, over the words beside it. Native reserves the
|
|
387
|
+
// measured box; this is the same thing said in CSS.
|
|
388
|
+
if (content?.box) {
|
|
389
|
+
slot.style.width = `${content.box.width}px`;
|
|
390
|
+
slot.style.height = `${content.box.height}px`;
|
|
391
|
+
} else {
|
|
392
|
+
slot.style.width = "";
|
|
393
|
+
slot.style.height = "";
|
|
394
|
+
}
|
|
395
|
+
if (content === undefined || content.label === "") {
|
|
396
|
+
slot.removeAttribute("role");
|
|
397
|
+
slot.removeAttribute("aria-label");
|
|
398
|
+
} else {
|
|
399
|
+
// `math` and `img` both take a name from the author, so the label wins
|
|
400
|
+
// over whatever glyph outlines are underneath it.
|
|
401
|
+
slot.setAttribute("role", content.role);
|
|
402
|
+
slot.setAttribute("aria-label", content.label);
|
|
403
|
+
}
|
|
404
|
+
if (content?.lang) {
|
|
405
|
+
slot.setAttribute("lang", content.lang);
|
|
406
|
+
} else {
|
|
407
|
+
slot.removeAttribute("lang");
|
|
408
|
+
}
|
|
409
|
+
if (content?.source) {
|
|
410
|
+
slot.setAttribute("data-tex", content.source);
|
|
411
|
+
} else {
|
|
412
|
+
slot.removeAttribute("data-tex");
|
|
413
|
+
}
|
|
414
|
+
});
|
|
415
|
+
}, [slots, drawn]);
|
|
416
|
+
|
|
417
|
+
// Copying maths gives back the markdown it was written as.
|
|
418
|
+
//
|
|
419
|
+
// A selection dragged across a drawing copies whatever text is under it,
|
|
420
|
+
// which for an SVG is nothing at all -- so a message copied out of a chat
|
|
421
|
+
// arrives with a hole where its equation was. The clipboard is the one place
|
|
422
|
+
// the source is worth more than the picture, and this is the only hook the
|
|
423
|
+
// web offers: the copy is intercepted, the fragment the browser was about to
|
|
424
|
+
// serialise is walked, and every slot in it is swapped for the `$$…$$` it
|
|
425
|
+
// stands for.
|
|
426
|
+
//
|
|
427
|
+
// On the document rather than the host, because that is where a copy lands
|
|
428
|
+
// when the selection reaches past this element. It is left alone unless the
|
|
429
|
+
// fragment actually holds one of these slots.
|
|
430
|
+
useClientEffect(() => {
|
|
431
|
+
const host = hostRef.current;
|
|
432
|
+
if (!host || !drawn.some(content => content.source !== "")) {
|
|
433
|
+
return undefined;
|
|
434
|
+
}
|
|
435
|
+
const onCopy = event => {
|
|
436
|
+
const selection = window.getSelection();
|
|
437
|
+
if (!selection || selection.isCollapsed || selection.rangeCount === 0) {
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
const fragment = selection.getRangeAt(0).cloneContents();
|
|
441
|
+
const maths = fragment.querySelectorAll("[data-tex]");
|
|
442
|
+
if (maths.length === 0) {
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
for (const element of Array.from(maths)) {
|
|
446
|
+
element.replaceWith(document.createTextNode(element.getAttribute("data-tex") ?? ""));
|
|
447
|
+
}
|
|
448
|
+
event.clipboardData?.setData("text/plain", fragment.textContent ?? "");
|
|
449
|
+
event.preventDefault();
|
|
450
|
+
};
|
|
451
|
+
document.addEventListener("copy", onCopy);
|
|
452
|
+
return () => document.removeEventListener("copy", onCopy);
|
|
453
|
+
}, [drawn]);
|
|
454
|
+
|
|
455
|
+
// On the host rather than on each link: the markup underneath is rebuilt from
|
|
456
|
+
// scratch whenever the text changes, and a listener per element would have to
|
|
457
|
+
// be attached again every time.
|
|
458
|
+
useClientEffect(() => {
|
|
459
|
+
const host = hostRef.current;
|
|
460
|
+
if (!host || markdown === null || onLinkPress === undefined || markdown.links.length === 0) {
|
|
461
|
+
return undefined;
|
|
462
|
+
}
|
|
463
|
+
const {
|
|
464
|
+
links
|
|
465
|
+
} = markdown;
|
|
466
|
+
const linkAt = target => {
|
|
467
|
+
const element = target instanceof Element ? target.closest("[data-link]") : null;
|
|
468
|
+
return element === null ? undefined : links[Number(element.getAttribute("data-link"))];
|
|
469
|
+
};
|
|
470
|
+
const press = event => {
|
|
471
|
+
const link = linkAt(event.target);
|
|
472
|
+
if (link === undefined) {
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
// A modified click belongs to the browser: on an anchor it opens the
|
|
477
|
+
// destination in a new tab or a new window, which is what the reader
|
|
478
|
+
// asked for and something no callback can do for them.
|
|
479
|
+
if ("button" in event && (event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey)) {
|
|
480
|
+
return;
|
|
481
|
+
}
|
|
482
|
+
event.preventDefault();
|
|
483
|
+
onLinkPress(link.uri, link.label, link.title);
|
|
484
|
+
};
|
|
485
|
+
const onKeyDown = event => {
|
|
486
|
+
// Enter and not Space: Space activates a button, and scrolls everywhere
|
|
487
|
+
// else, which is what a reader who has tabbed onto a link expects of it.
|
|
488
|
+
if (event.key === "Enter") {
|
|
489
|
+
press(event);
|
|
490
|
+
}
|
|
491
|
+
};
|
|
492
|
+
host.addEventListener("click", press);
|
|
493
|
+
host.addEventListener("keydown", onKeyDown);
|
|
494
|
+
return () => {
|
|
495
|
+
host.removeEventListener("click", press);
|
|
496
|
+
host.removeEventListener("keydown", onKeyDown);
|
|
497
|
+
};
|
|
498
|
+
}, [markdown, onLinkPress]);
|
|
499
|
+
const setRef = React.useCallback(node => {
|
|
500
|
+
hostRef.current = node;
|
|
501
|
+
if (typeof ref === "function") {
|
|
502
|
+
ref(node);
|
|
503
|
+
} else if (ref) {
|
|
504
|
+
// eslint-disable-next-line no-param-reassign
|
|
505
|
+
ref.current = node;
|
|
506
|
+
}
|
|
507
|
+
}, [ref]);
|
|
508
|
+
return /*#__PURE__*/_jsxs(_Fragment, {
|
|
509
|
+
children: [/*#__PURE__*/_jsx(Text, {
|
|
510
|
+
...textProps,
|
|
511
|
+
ref: setRef,
|
|
512
|
+
children: markdown === null ? children : content
|
|
513
|
+
}), slots.map((slot, index) => {
|
|
514
|
+
const content = drawn[index];
|
|
515
|
+
|
|
516
|
+
// The slots were made from this very `markdown`, so they line up -- but a render between a
|
|
517
|
+
// text change and the effect that follows it can still see the previous set, one entry
|
|
518
|
+
// longer than the new document has placeholders.
|
|
519
|
+
return content?.element == null ? null : /*#__PURE__*/createPortal(content.element, slot, String(index));
|
|
520
|
+
})]
|
|
521
|
+
});
|
|
522
|
+
});
|
|
523
|
+
export default MarkdownText;
|
|
524
|
+
//# sourceMappingURL=MarkdownText.web.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["StyleSheet","Text","React","createPortal","atomsOf","NO_ATOMS","sourceOf","available","mathAvailable","renderMath","speakMath","flattenText","OBJECT_REPLACEMENT","stripSyntax","createTextMeasurer","parseRangesToHTMLNodes","processMarkdownStyle","createParser","jsx","_jsx","Fragment","_Fragment","jsxs","_jsxs","useClientEffect","window","useEffect","useLayoutEffect","NO_SLOTS","DEFAULT_FONT_SIZE","mountSlots","host","walker","document","createTreeWalker","NodeFilter","SHOW_TEXT","texts","nextNode","push","currentNode","slots","text","node","index","data","indexOf","placeholder","splitText","rest","length","slot","createElement","style","display","textIndent","setAttribute","String","replaceWith","markerRendering","fontSize","parseFloat","getComputedStyle","SAFE_SCHEME","SCHEME","hrefFor","uri","bare","replace","test","markLinks","links","type","findIndex","link","start","href","element","title","cursor","childNodes","forEach","child","MarkdownText","forwardRef","props","ref","markdownStyle","markdownStyleProp","gfm","mention","math","renderEmbed","renderSVG","mathAccessibilityLocale","onLinkPress","children","textProps","hostRef","useRef","setSlots","useState","withEmbeds","undefined","withMath","withLinks","parser","markdown","useMemo","embeds","atoms","color","flattened","flatten","drawn","map","atom","kind","alt","inline","depth","box","label","role","lang","source","rendered","tex","svg","width","height","content","includes","split","join","current","dom","tree","ranges","replaceChildren","Array","from","next","previous","verticalAlign","removeAttribute","some","onCopy","event","selection","getSelection","isCollapsed","rangeCount","fragment","getRangeAt","cloneContents","maths","querySelectorAll","createTextNode","getAttribute","clipboardData","setData","textContent","preventDefault","addEventListener","removeEventListener","linkAt","target","Element","closest","Number","press","button","metaKey","ctrlKey","shiftKey","altKey","onKeyDown","key","setRef","useCallback"],"sourceRoot":"../../src","sources":["MarkdownText.web.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
import { StyleSheet, TextInput
|
|
3
|
+
import { StyleSheet, TextInput } from "react-native";
|
|
4
4
|
import React from "react";
|
|
5
5
|
import { createSerializable, createWorkletRuntime } from "react-native-worklets";
|
|
6
6
|
import MarcusTextInputDecoratorViewNativeComponent from "./MarcusTextInputDecoratorViewNativeComponent";
|
|
7
7
|
import NativeMarcusModule from "./NativeMarcusModule.js";
|
|
8
|
-
import {
|
|
8
|
+
import { processMarkdownStyle } from "./styleUtils.js";
|
|
9
|
+
import { createParser } from "./parser/index.js";
|
|
9
10
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
10
11
|
let initialized = false;
|
|
11
12
|
let workletRuntime;
|
|
@@ -40,37 +41,31 @@ function registerParser(parser) {
|
|
|
40
41
|
function unregisterParser(parserId) {
|
|
41
42
|
global.jsi_unregisterMarcusWorklet(parserId);
|
|
42
43
|
}
|
|
43
|
-
function processColorsInMarkdownStyle(input) {
|
|
44
|
-
const output = JSON.parse(JSON.stringify(input));
|
|
45
|
-
Object.keys(output).forEach(key => {
|
|
46
|
-
const obj = output[key];
|
|
47
|
-
Object.keys(obj).forEach(prop => {
|
|
48
|
-
// TODO: use ReactNativeStyleAttributes from 'react-native/Libraries/Components/View/ReactNativeStyleAttributes'
|
|
49
|
-
if (!(prop === "color" || prop.endsWith("Color"))) {
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
obj[prop] = processColor(obj[prop]);
|
|
53
|
-
});
|
|
54
|
-
});
|
|
55
|
-
return output;
|
|
56
|
-
}
|
|
57
|
-
function processMarkdownStyle(input) {
|
|
58
|
-
return processColorsInMarkdownStyle(mergeMarkdownStyleWithDefault(input));
|
|
59
|
-
}
|
|
60
44
|
const MarkdownTextInput = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
45
|
+
const {
|
|
46
|
+
markdownStyle: markdownStyleProp,
|
|
47
|
+
gfm,
|
|
48
|
+
mention,
|
|
49
|
+
math,
|
|
50
|
+
...textInputProps
|
|
51
|
+
} = props;
|
|
52
|
+
const markdownStyle = React.useMemo(() => processMarkdownStyle(markdownStyleProp), [markdownStyleProp]);
|
|
53
|
+
|
|
54
|
+
// The same worklet for as long as the flavour is the same one, so the id
|
|
55
|
+
// below is registered once and the native side keeps the parser it has.
|
|
56
|
+
const parser = createParser({
|
|
57
|
+
gfm,
|
|
58
|
+
mention,
|
|
59
|
+
math
|
|
60
|
+
});
|
|
65
61
|
|
|
66
62
|
// eslint-disable-next-line no-underscore-dangle
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
throw new Error("[react-native-marcus] `parser` is not a worklet");
|
|
63
|
+
if (parser.__workletHash === undefined) {
|
|
64
|
+
throw new Error("[react-native-marcus] the parser is not a worklet. Add `react-native-worklets/plugin` to the project's Babel config.");
|
|
70
65
|
}
|
|
71
66
|
const parserId = React.useMemo(() => {
|
|
72
|
-
return registerParser(
|
|
73
|
-
}, [
|
|
67
|
+
return registerParser(parser);
|
|
68
|
+
}, [parser]);
|
|
74
69
|
React.useEffect(() => {
|
|
75
70
|
return () => unregisterParser(parserId);
|
|
76
71
|
}, [parserId]);
|
|
@@ -79,7 +74,7 @@ const MarkdownTextInput = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
|
79
74
|
markdownStyle: markdownStyle,
|
|
80
75
|
parserId: parserId,
|
|
81
76
|
children: /*#__PURE__*/_jsx(TextInput, {
|
|
82
|
-
...
|
|
77
|
+
...textInputProps,
|
|
83
78
|
ref: ref
|
|
84
79
|
})
|
|
85
80
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["StyleSheet","TextInput","
|
|
1
|
+
{"version":3,"names":["StyleSheet","TextInput","React","createSerializable","createWorkletRuntime","MarcusTextInputDecoratorViewNativeComponent","NativeMarcusModule","processMarkdownStyle","createParser","jsx","_jsx","initialized","workletRuntime","getWorkletRuntime","undefined","Error","initializeMarcusIfNeeded","install","global","jsi_setMarcusRuntime","name","registerParser","parser","serializableWorklet","parserId","jsi_registerMarcusWorklet","unregisterParser","jsi_unregisterMarcusWorklet","MarkdownTextInput","forwardRef","props","ref","markdownStyle","markdownStyleProp","gfm","mention","math","textInputProps","useMemo","__workletHash","useEffect","style","styles","displayContents","children","create","display"],"sourceRoot":"../../src","sources":["MarkdownTextInput.tsx"],"mappings":"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","ignoreList":[]}
|