@expensify/react-native-live-markdown 0.1.162 → 0.1.164
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/lib/commonjs/MarkdownTextInput.js.map +1 -1
- package/lib/commonjs/MarkdownTextInput.web.js +8 -3
- package/lib/commonjs/MarkdownTextInput.web.js.map +1 -1
- package/lib/commonjs/web/inputElements/inlineImage.js +8 -1
- package/lib/commonjs/web/inputElements/inlineImage.js.map +1 -1
- package/lib/commonjs/web/utils/blockUtils.js +2 -2
- package/lib/commonjs/web/utils/blockUtils.js.map +1 -1
- package/lib/commonjs/web/utils/cursorUtils.js +4 -2
- package/lib/commonjs/web/utils/cursorUtils.js.map +1 -1
- package/lib/commonjs/web/utils/parserUtils.js +4 -4
- package/lib/commonjs/web/utils/parserUtils.js.map +1 -1
- package/lib/commonjs/web/utils/treeUtils.js +3 -0
- package/lib/commonjs/web/utils/treeUtils.js.map +1 -1
- package/lib/module/MarkdownTextInput.js.map +1 -1
- package/lib/module/MarkdownTextInput.web.js +8 -3
- package/lib/module/MarkdownTextInput.web.js.map +1 -1
- package/lib/module/web/inputElements/inlineImage.js +8 -1
- package/lib/module/web/inputElements/inlineImage.js.map +1 -1
- package/lib/module/web/utils/blockUtils.js +2 -2
- package/lib/module/web/utils/blockUtils.js.map +1 -1
- package/lib/module/web/utils/cursorUtils.js +4 -2
- package/lib/module/web/utils/cursorUtils.js.map +1 -1
- package/lib/module/web/utils/parserUtils.js +4 -4
- package/lib/module/web/utils/parserUtils.js.map +1 -1
- package/lib/module/web/utils/treeUtils.js +3 -0
- package/lib/module/web/utils/treeUtils.js.map +1 -1
- package/lib/typescript/src/MarkdownTextInput.d.ts +2 -1
- package/lib/typescript/src/MarkdownTextInput.d.ts.map +1 -1
- package/lib/typescript/src/MarkdownTextInput.web.d.ts +2 -1
- package/lib/typescript/src/MarkdownTextInput.web.d.ts.map +1 -1
- package/lib/typescript/src/commonTypes.d.ts +5 -1
- package/lib/typescript/src/commonTypes.d.ts.map +1 -1
- package/lib/typescript/src/web/inputElements/inlineImage.d.ts +2 -2
- package/lib/typescript/src/web/inputElements/inlineImage.d.ts.map +1 -1
- package/lib/typescript/src/web/utils/blockUtils.d.ts +2 -2
- package/lib/typescript/src/web/utils/blockUtils.d.ts.map +1 -1
- package/lib/typescript/src/web/utils/cursorUtils.d.ts.map +1 -1
- package/lib/typescript/src/web/utils/parserUtils.d.ts +3 -3
- package/lib/typescript/src/web/utils/parserUtils.d.ts.map +1 -1
- package/lib/typescript/src/web/utils/treeUtils.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/MarkdownTextInput.tsx +2 -1
- package/src/MarkdownTextInput.web.tsx +9 -3
- package/src/commonTypes.ts +6 -1
- package/src/web/inputElements/inlineImage.ts +13 -2
- package/src/web/utils/blockUtils.ts +3 -2
- package/src/web/utils/cursorUtils.ts +4 -2
- package/src/web/utils/parserUtils.ts +5 -3
- package/src/web/utils/treeUtils.ts +5 -1
|
@@ -23,12 +23,13 @@ import type {MarkdownStyle} from './MarkdownTextInputDecoratorViewNativeComponen
|
|
|
23
23
|
import {getElementHeight, getPlaceholderValue, isEventComposing, normalizeValue, parseInnerHTMLToText} from './web/utils/inputUtils';
|
|
24
24
|
import {parseToReactDOMStyle, processMarkdownStyle} from './web/utils/webStyleUtils';
|
|
25
25
|
import {forceRefreshAllImages} from './web/inputElements/inlineImage';
|
|
26
|
+
import type {InlineImagesInputProps} from './commonTypes';
|
|
26
27
|
|
|
27
28
|
require('../parser/react-native-live-markdown-parser.js');
|
|
28
29
|
|
|
29
30
|
const useClientEffect = typeof window === 'undefined' ? useEffect : useLayoutEffect;
|
|
30
31
|
|
|
31
|
-
interface MarkdownTextInputProps extends TextInputProps {
|
|
32
|
+
interface MarkdownTextInputProps extends TextInputProps, InlineImagesInputProps {
|
|
32
33
|
markdownStyle?: MarkdownStyle;
|
|
33
34
|
onClick?: (e: MouseEvent<HTMLDivElement>) => void;
|
|
34
35
|
dir?: string;
|
|
@@ -101,6 +102,8 @@ const MarkdownTextInput = React.forwardRef<TextInput, MarkdownTextInputProps>(
|
|
|
101
102
|
id,
|
|
102
103
|
inputMode,
|
|
103
104
|
onTouchStart,
|
|
105
|
+
addAuthTokenToImageURLCallback,
|
|
106
|
+
imagePreviewAuthRequiredURLs,
|
|
104
107
|
},
|
|
105
108
|
ref,
|
|
106
109
|
) => {
|
|
@@ -154,7 +157,10 @@ const MarkdownTextInput = React.forwardRef<TextInput, MarkdownTextInputProps>(
|
|
|
154
157
|
if (text === null) {
|
|
155
158
|
return {text: divRef.current.value, cursorPosition: null};
|
|
156
159
|
}
|
|
157
|
-
const parsedText = updateInputStructure(target, text, cursorPosition, multiline, customMarkdownStyles, false, shouldForceDOMUpdate, shouldScrollIntoView
|
|
160
|
+
const parsedText = updateInputStructure(target, text, cursorPosition, multiline, customMarkdownStyles, false, shouldForceDOMUpdate, shouldScrollIntoView, {
|
|
161
|
+
addAuthTokenToImageURLCallback,
|
|
162
|
+
imagePreviewAuthRequiredURLs,
|
|
163
|
+
});
|
|
158
164
|
divRef.current.value = parsedText.text;
|
|
159
165
|
|
|
160
166
|
if (history.current && shouldAddToHistory) {
|
|
@@ -163,7 +169,7 @@ const MarkdownTextInput = React.forwardRef<TextInput, MarkdownTextInputProps>(
|
|
|
163
169
|
|
|
164
170
|
return parsedText;
|
|
165
171
|
},
|
|
166
|
-
[multiline],
|
|
172
|
+
[addAuthTokenToImageURLCallback, imagePreviewAuthRequiredURLs, multiline],
|
|
167
173
|
);
|
|
168
174
|
|
|
169
175
|
const processedMarkdownStyle = useMemo(() => {
|
package/src/commonTypes.ts
CHANGED
|
@@ -21,4 +21,9 @@ interface MarkdownRange {
|
|
|
21
21
|
depth?: number;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
type InlineImagesInputProps = {
|
|
25
|
+
addAuthTokenToImageURLCallback?: (url: string) => string;
|
|
26
|
+
imagePreviewAuthRequiredURLs?: string[];
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export type {MarkdownType, MarkdownRange, InlineImagesInputProps};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type {HTMLMarkdownElement, MarkdownTextInputElement} from '../../MarkdownTextInput.web';
|
|
2
|
-
import type {MarkdownRange} from '../../commonTypes';
|
|
2
|
+
import type {InlineImagesInputProps, MarkdownRange} from '../../commonTypes';
|
|
3
3
|
import {parseStringWithUnitToNumber} from '../../styleUtils';
|
|
4
4
|
import type {PartialMarkdownStyle} from '../../styleUtils';
|
|
5
5
|
import type {TreeNode} from '../utils/treeUtils';
|
|
@@ -141,11 +141,22 @@ function updateImageTreeNode(targetNode: TreeNode, newElement: HTMLMarkdownEleme
|
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
/** The main function that adds inline image preview to the node */
|
|
144
|
-
function addInlineImagePreview(
|
|
144
|
+
function addInlineImagePreview(
|
|
145
|
+
currentInput: MarkdownTextInputElement,
|
|
146
|
+
targetNode: TreeNode,
|
|
147
|
+
text: string,
|
|
148
|
+
ranges: MarkdownRange[],
|
|
149
|
+
markdownStyle: PartialMarkdownStyle,
|
|
150
|
+
inlineImagesProps: InlineImagesInputProps,
|
|
151
|
+
) {
|
|
152
|
+
const {addAuthTokenToImageURLCallback, imagePreviewAuthRequiredURLs} = inlineImagesProps;
|
|
145
153
|
const linkRange = ranges.find((r) => r.type === 'link');
|
|
146
154
|
let imageHref = '';
|
|
147
155
|
if (linkRange) {
|
|
148
156
|
imageHref = text.substring(linkRange.start, linkRange.start + linkRange.length);
|
|
157
|
+
if (addAuthTokenToImageURLCallback && imagePreviewAuthRequiredURLs && imagePreviewAuthRequiredURLs.find((url) => imageHref.startsWith(url))) {
|
|
158
|
+
imageHref = addAuthTokenToImageURLCallback(imageHref);
|
|
159
|
+
}
|
|
149
160
|
}
|
|
150
161
|
|
|
151
162
|
const imageMarginTop = parseStringWithUnitToNumber(`${markdownStyle.inlineImage?.marginTop}`);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type {MarkdownTextInputElement} from '../../MarkdownTextInput.web';
|
|
2
|
-
import type {MarkdownRange} from '../../commonTypes';
|
|
2
|
+
import type {InlineImagesInputProps, MarkdownRange} from '../../commonTypes';
|
|
3
3
|
import type {PartialMarkdownStyle} from '../../styleUtils';
|
|
4
4
|
import {addInlineImagePreview} from '../inputElements/inlineImage';
|
|
5
5
|
import type {NodeType, TreeNode} from './treeUtils';
|
|
@@ -98,10 +98,11 @@ function extendBlockStructure(
|
|
|
98
98
|
ranges: MarkdownRange[],
|
|
99
99
|
text: string,
|
|
100
100
|
markdownStyle: PartialMarkdownStyle,
|
|
101
|
+
inlineImagesProps: InlineImagesInputProps,
|
|
101
102
|
) {
|
|
102
103
|
switch (currentRange.type) {
|
|
103
104
|
case 'inline-image':
|
|
104
|
-
return addInlineImagePreview(currentInput, targetNode, text, ranges, markdownStyle);
|
|
105
|
+
return addInlineImagePreview(currentInput, targetNode, text, ranges, markdownStyle, inlineImagesProps);
|
|
105
106
|
default:
|
|
106
107
|
break;
|
|
107
108
|
}
|
|
@@ -27,13 +27,15 @@ function setCursorPosition(target: MarkdownTextInputElement, startIndex: number,
|
|
|
27
27
|
if (startTreeNode.type === 'br') {
|
|
28
28
|
range.setStartBefore(startTreeNode.element);
|
|
29
29
|
} else {
|
|
30
|
-
|
|
30
|
+
const startElement = startTreeNode.element;
|
|
31
|
+
range.setStart((startElement.childNodes[0] || startElement) as ChildNode, start - startTreeNode.start);
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
if (endTreeNode.type === 'br') {
|
|
34
35
|
range.setEndBefore(endTreeNode.element);
|
|
35
36
|
} else {
|
|
36
|
-
|
|
37
|
+
const endElement = endTreeNode.element;
|
|
38
|
+
range.setEnd((endElement.childNodes[0] || endElement) as ChildNode, (end || start) - endTreeNode.start);
|
|
37
39
|
}
|
|
38
40
|
|
|
39
41
|
if (!end) {
|
|
@@ -4,7 +4,7 @@ import type {NodeType, TreeNode} from './treeUtils';
|
|
|
4
4
|
import type {PartialMarkdownStyle} from '../../styleUtils';
|
|
5
5
|
import {getCurrentCursorPosition, moveCursorToEnd, setCursorPosition} from './cursorUtils';
|
|
6
6
|
import {addStyleToBlock, extendBlockStructure, getFirstBlockMarkdownRange, isBlockMarkdownType} from './blockUtils';
|
|
7
|
-
import type {MarkdownRange} from '../../commonTypes';
|
|
7
|
+
import type {InlineImagesInputProps, MarkdownRange} from '../../commonTypes';
|
|
8
8
|
import {getAnimationCurrentTimes, updateAnimationsTime} from './animationUtils';
|
|
9
9
|
|
|
10
10
|
type Paragraph = {
|
|
@@ -151,6 +151,7 @@ function parseRangesToHTMLNodes(
|
|
|
151
151
|
markdownStyle: PartialMarkdownStyle = {},
|
|
152
152
|
disableInlineStyles = false,
|
|
153
153
|
currentInput: MarkdownTextInputElement | null = null,
|
|
154
|
+
inlineImagesProps: InlineImagesInputProps = {},
|
|
154
155
|
) {
|
|
155
156
|
const rootElement: HTMLMarkdownElement = document.createElement('span') as HTMLMarkdownElement;
|
|
156
157
|
const textLength = text.length;
|
|
@@ -224,7 +225,7 @@ function parseRangesToHTMLNodes(
|
|
|
224
225
|
const spanNode = appendNode(span, currentParentNode, range.type, range.length);
|
|
225
226
|
|
|
226
227
|
if (isMultiline && !disableInlineStyles && currentInput) {
|
|
227
|
-
currentParentNode = extendBlockStructure(currentInput, currentParentNode, range, lineMarkdownRanges, text, markdownStyle);
|
|
228
|
+
currentParentNode = extendBlockStructure(currentInput, currentParentNode, range, lineMarkdownRanges, text, markdownStyle, inlineImagesProps);
|
|
228
229
|
}
|
|
229
230
|
|
|
230
231
|
if (lineMarkdownRanges.length > 0 && nextRangeStartIndex < endOfCurrentRange && range.type !== 'syntax') {
|
|
@@ -279,6 +280,7 @@ function updateInputStructure(
|
|
|
279
280
|
alwaysMoveCursorToTheEnd = false,
|
|
280
281
|
shouldForceDOMUpdate = false,
|
|
281
282
|
shouldScrollIntoView = false,
|
|
283
|
+
inlineImagesProps: InlineImagesInputProps = {},
|
|
282
284
|
) {
|
|
283
285
|
const targetElement = target;
|
|
284
286
|
|
|
@@ -297,7 +299,7 @@ function updateInputStructure(
|
|
|
297
299
|
|
|
298
300
|
// We don't want to parse text with single '\n', because contentEditable represents it as invisible <br />
|
|
299
301
|
if (text) {
|
|
300
|
-
const {dom, tree} = parseRangesToHTMLNodes(text, markdownRanges, isMultiline, markdownStyle, false, targetElement);
|
|
302
|
+
const {dom, tree} = parseRangesToHTMLNodes(text, markdownRanges, isMultiline, markdownStyle, false, targetElement, inlineImagesProps);
|
|
301
303
|
|
|
302
304
|
if (shouldForceDOMUpdate || targetElement.innerHTML !== dom.innerHTML) {
|
|
303
305
|
const animationTimes = getAnimationCurrentTimes(targetElement);
|
|
@@ -106,9 +106,13 @@ function findHTMLElementInTree(treeRoot: TreeNode, element: HTMLElement): TreeNo
|
|
|
106
106
|
|
|
107
107
|
function getTreeNodeByIndex(treeRoot: TreeNode, index: number): TreeNode | null {
|
|
108
108
|
let el: TreeNode | null = treeRoot;
|
|
109
|
-
|
|
110
109
|
let i = 0;
|
|
111
110
|
let newLineGenerated = false;
|
|
111
|
+
|
|
112
|
+
if (treeRoot.length === 0) {
|
|
113
|
+
return treeRoot;
|
|
114
|
+
}
|
|
115
|
+
|
|
112
116
|
while (el && el.childNodes.length > 0 && i < el.childNodes.length) {
|
|
113
117
|
const child = el.childNodes[i] as TreeNode;
|
|
114
118
|
|