Skip to content

Commit 37fe064

Browse files
committed
fix selection when rerendering because of markdownStyle change
1 parent 824e698 commit 37fe064

File tree

2 files changed

+31
-8
lines changed

2 files changed

+31
-8
lines changed

src/MarkdownTextInput.web.tsx

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ const MarkdownTextInput = React.forwardRef<MarkdownTextInput, MarkdownTextInputP
165165
shouldAddToHistory = true,
166166
shouldForceDOMUpdate = false,
167167
shouldScrollIntoView = false,
168+
shouldPreserveSelection = false,
168169
): ParseTextResult => {
169170
if (!divRef.current) {
170171
return {text: text || '', cursorPosition: null};
@@ -173,10 +174,21 @@ const MarkdownTextInput = React.forwardRef<MarkdownTextInput, MarkdownTextInputP
173174
if (text === null) {
174175
return {text: divRef.current.value, cursorPosition: null};
175176
}
176-
const parsedText = updateInputStructure(target, text, cursorPosition, multiline, customMarkdownStyles, false, shouldForceDOMUpdate, shouldScrollIntoView, {
177-
addAuthTokenToImageURLCallback,
178-
imagePreviewAuthRequiredURLs,
179-
});
177+
const parsedText = updateInputStructure(
178+
target,
179+
text,
180+
cursorPosition,
181+
multiline,
182+
customMarkdownStyles,
183+
false,
184+
shouldForceDOMUpdate,
185+
shouldScrollIntoView,
186+
{
187+
addAuthTokenToImageURLCallback,
188+
imagePreviewAuthRequiredURLs,
189+
},
190+
shouldPreserveSelection,
191+
);
180192
divRef.current.value = parsedText.text;
181193

182194
if (history.current && shouldAddToHistory) {
@@ -191,7 +203,7 @@ const MarkdownTextInput = React.forwardRef<MarkdownTextInput, MarkdownTextInputP
191203
const processedMarkdownStyle = useMemo(() => {
192204
const newMarkdownStyle = processMarkdownStyle(memoizedMarkdownStyle);
193205
if (divRef.current) {
194-
parseText(divRef.current, divRef.current.value, newMarkdownStyle, null, false, false);
206+
parseText(divRef.current, divRef.current.value, newMarkdownStyle, null, false, false, false, true);
195207
}
196208
return newMarkdownStyle;
197209
}, [memoizedMarkdownStyle, parseText]);

src/web/utils/parserUtils.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -259,15 +259,22 @@ function parseRangesToHTMLNodes(
259259
return {dom: rootElement, tree: rootNode};
260260
}
261261

262-
function moveCursor(isFocused: boolean, alwaysMoveCursorToTheEnd: boolean, cursorPosition: number | null, target: MarkdownTextInputElement, shouldScrollIntoView = false) {
262+
function moveCursor(
263+
isFocused: boolean,
264+
alwaysMoveCursorToTheEnd: boolean,
265+
cursorPosition: number | null,
266+
target: MarkdownTextInputElement,
267+
selectionEnd: number | null = null,
268+
shouldScrollIntoView = false,
269+
) {
263270
if (!isFocused) {
264271
return;
265272
}
266273

267274
if (alwaysMoveCursorToTheEnd || cursorPosition === null) {
268275
moveCursorToEnd(target);
269276
} else if (cursorPosition !== null) {
270-
setCursorPosition(target, cursorPosition, null, shouldScrollIntoView);
277+
setCursorPosition(target, cursorPosition, selectionEnd, shouldScrollIntoView);
271278
}
272279
}
273280

@@ -281,15 +288,19 @@ function updateInputStructure(
281288
shouldForceDOMUpdate = false,
282289
shouldScrollIntoView = false,
283290
inlineImagesProps: InlineImagesInputProps = {},
291+
shouldPreserveSelection = false,
284292
) {
285293
const targetElement = target;
286294

287295
// in case the cursorPositionIndex is larger than text length, cursorPosition will be null, i.e: move the caret to the end
288296
let cursorPosition: number | null = cursorPositionIndex !== null && cursorPositionIndex <= text.length ? cursorPositionIndex : null;
297+
let selectionEndPosition: number | null = null;
289298
const isFocused = document.activeElement === target;
290299
if (isFocused && cursorPositionIndex === null) {
291300
const selection = getCurrentCursorPosition(target);
292301
cursorPosition = selection ? selection.start : null;
302+
// in some cases like rerendering because style was changed we want to preserve selection
303+
selectionEndPosition = shouldPreserveSelection && selection ? selection.end : null;
293304
}
294305
const markdownRanges = global.parseExpensiMarkToRanges(text);
295306
if (!text || targetElement.innerHTML === '<br>' || (targetElement && targetElement.innerHTML === '\n')) {
@@ -312,7 +323,7 @@ function updateInputStructure(
312323
updateTreeElementRefs(tree, targetElement);
313324
targetElement.tree = tree;
314325

315-
moveCursor(isFocused, alwaysMoveCursorToTheEnd, cursorPosition, targetElement, shouldScrollIntoView);
326+
moveCursor(isFocused, alwaysMoveCursorToTheEnd, cursorPosition, targetElement, selectionEndPosition, shouldScrollIntoView);
316327
} else {
317328
targetElement.tree = createRootTreeNode(targetElement);
318329
}

0 commit comments

Comments
 (0)