@expensify/react-native-live-markdown 0.1.17 → 0.1.19
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.web.js +69 -41
- package/lib/commonjs/MarkdownTextInput.web.js.map +1 -1
- package/lib/commonjs/web/cursorUtils.js +51 -51
- package/lib/commonjs/web/cursorUtils.js.map +1 -1
- package/lib/commonjs/web/parserUtils.js +31 -11
- package/lib/commonjs/web/parserUtils.js.map +1 -1
- package/lib/module/MarkdownTextInput.web.js +69 -41
- package/lib/module/MarkdownTextInput.web.js.map +1 -1
- package/lib/module/web/cursorUtils.js +51 -52
- package/lib/module/web/cursorUtils.js.map +1 -1
- package/lib/module/web/parserUtils.js +31 -11
- package/lib/module/web/parserUtils.js.map +1 -1
- package/lib/typescript/src/MarkdownTextInput.web.d.ts.map +1 -1
- package/lib/typescript/src/web/cursorUtils.d.ts +4 -3
- package/lib/typescript/src/web/cursorUtils.d.ts.map +1 -1
- package/lib/typescript/src/web/parserUtils.d.ts +1 -1
- package/lib/typescript/src/web/parserUtils.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/MarkdownTextInput.web.tsx +73 -47
- package/src/web/cursorUtils.ts +55 -54
- package/src/web/parserUtils.ts +36 -18
|
@@ -150,6 +150,7 @@ const MarkdownTextInput = React.forwardRef<TextInput, MarkdownTextInputProps>(
|
|
|
150
150
|
placeholderTextColor = `rgba(0,0,0,0.2)`,
|
|
151
151
|
selectTextOnFocus,
|
|
152
152
|
spellCheck,
|
|
153
|
+
selection,
|
|
153
154
|
style = {},
|
|
154
155
|
value,
|
|
155
156
|
autoFocus = false,
|
|
@@ -159,7 +160,8 @@ const MarkdownTextInput = React.forwardRef<TextInput, MarkdownTextInputProps>(
|
|
|
159
160
|
const compositionRef = useRef<boolean>(false);
|
|
160
161
|
const divRef = useRef<HTMLDivElement | null>(null);
|
|
161
162
|
const currentlyFocusedField = useRef<HTMLDivElement | null>(null);
|
|
162
|
-
const
|
|
163
|
+
const valueLength = value ? value.length : 0;
|
|
164
|
+
const contentSelection = useRef<Selection>({start: valueLength, end: valueLength});
|
|
163
165
|
const className = `react-native-live-markdown-input-${multiline ? 'multiline' : 'singleline'}`;
|
|
164
166
|
const history = useRef<InputHistory>();
|
|
165
167
|
if (!history.current) {
|
|
@@ -171,15 +173,18 @@ const MarkdownTextInput = React.forwardRef<TextInput, MarkdownTextInputProps>(
|
|
|
171
173
|
// Empty placeholder would collapse the div, so we need to use zero-width space to prevent it
|
|
172
174
|
const heightSafePlaceholder = useMemo(() => getPlaceholderValue(placeholder), [placeholder]);
|
|
173
175
|
|
|
174
|
-
const
|
|
175
|
-
if (
|
|
176
|
-
|
|
176
|
+
const setEventProps = useCallback((e: NativeSyntheticEvent<any>) => {
|
|
177
|
+
if (divRef.current) {
|
|
178
|
+
const text = normalizeValue(divRef.current.innerText || '');
|
|
179
|
+
if (e.target) {
|
|
180
|
+
// TODO: change the logic here so every event have value property
|
|
181
|
+
(e.target as unknown as HTMLInputElement).value = text;
|
|
182
|
+
}
|
|
183
|
+
if (e.nativeEvent && e.nativeEvent.text) {
|
|
184
|
+
e.nativeEvent.text = text;
|
|
185
|
+
}
|
|
177
186
|
}
|
|
178
|
-
|
|
179
|
-
const markdownHTMLInput = divRef.current as HTMLInputElement;
|
|
180
|
-
markdownHTMLInput.selectionStart = selection.start;
|
|
181
|
-
markdownHTMLInput.selectionEnd = selection.end;
|
|
182
|
-
contentSelection.current = selection;
|
|
187
|
+
return e;
|
|
183
188
|
}, []);
|
|
184
189
|
|
|
185
190
|
const parseText = useCallback(
|
|
@@ -192,8 +197,6 @@ const MarkdownTextInput = React.forwardRef<TextInput, MarkdownTextInputProps>(
|
|
|
192
197
|
history.current.debouncedAdd(parsedText.text, parsedText.cursorPosition);
|
|
193
198
|
}
|
|
194
199
|
|
|
195
|
-
updateSelection();
|
|
196
|
-
|
|
197
200
|
return parsedText;
|
|
198
201
|
},
|
|
199
202
|
[multiline],
|
|
@@ -246,18 +249,6 @@ const MarkdownTextInput = React.forwardRef<TextInput, MarkdownTextInputProps>(
|
|
|
246
249
|
return value;
|
|
247
250
|
}, [value]);
|
|
248
251
|
|
|
249
|
-
const setEventProps = useCallback((e: NativeSyntheticEvent<any>) => {
|
|
250
|
-
if (divRef.current) {
|
|
251
|
-
const text = normalizeValue(divRef.current.innerText || '');
|
|
252
|
-
if (typeof e.target !== 'number') {
|
|
253
|
-
// TODO: change the logic here so every event have value property
|
|
254
|
-
(e.target as unknown as HTMLInputElement).value = text;
|
|
255
|
-
}
|
|
256
|
-
e.nativeEvent.text = text;
|
|
257
|
-
}
|
|
258
|
-
return e;
|
|
259
|
-
}, []);
|
|
260
|
-
|
|
261
252
|
// Placeholder text color logic
|
|
262
253
|
const updateTextColor = useCallback((node: HTMLDivElement, text: string) => {
|
|
263
254
|
// eslint-disable-next-line no-param-reassign -- we need to change the style of the node, so we need to modify it
|
|
@@ -304,6 +295,41 @@ const MarkdownTextInput = React.forwardRef<TextInput, MarkdownTextInputProps>(
|
|
|
304
295
|
[multiline, onChange, onChangeText, setEventProps, processedMarkdownStyle],
|
|
305
296
|
);
|
|
306
297
|
|
|
298
|
+
const handleSelectionChange: ReactEventHandler<HTMLDivElement> = useCallback(
|
|
299
|
+
(event) => {
|
|
300
|
+
const e = event as unknown as NativeSyntheticEvent<TextInputSelectionChangeEventData>;
|
|
301
|
+
setEventProps(e);
|
|
302
|
+
if (onSelectionChange && contentSelection.current) {
|
|
303
|
+
e.nativeEvent.selection = contentSelection.current;
|
|
304
|
+
onSelectionChange(e);
|
|
305
|
+
}
|
|
306
|
+
},
|
|
307
|
+
[onSelectionChange, setEventProps],
|
|
308
|
+
);
|
|
309
|
+
|
|
310
|
+
const updateRefSelectionVariables = useCallback((newSelection: Selection) => {
|
|
311
|
+
const {start, end} = newSelection;
|
|
312
|
+
const markdownHTMLInput = divRef.current as HTMLInputElement;
|
|
313
|
+
markdownHTMLInput.selectionStart = start;
|
|
314
|
+
markdownHTMLInput.selectionEnd = end;
|
|
315
|
+
}, []);
|
|
316
|
+
|
|
317
|
+
const updateSelection = useCallback((e: SyntheticEvent<HTMLDivElement> | null = null) => {
|
|
318
|
+
if (!divRef.current) {
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
const newSelection = CursorUtils.getCurrentCursorPosition(divRef.current);
|
|
322
|
+
|
|
323
|
+
if (newSelection && (contentSelection.current.start !== newSelection.start || contentSelection.current.end !== newSelection.end)) {
|
|
324
|
+
updateRefSelectionVariables(newSelection);
|
|
325
|
+
contentSelection.current = newSelection;
|
|
326
|
+
|
|
327
|
+
if (e) {
|
|
328
|
+
handleSelectionChange(e);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}, []);
|
|
332
|
+
|
|
307
333
|
const handleKeyPress = useCallback(
|
|
308
334
|
(e: KeyboardEvent<HTMLDivElement>) => {
|
|
309
335
|
if (!divRef.current) {
|
|
@@ -338,6 +364,8 @@ const MarkdownTextInput = React.forwardRef<TextInput, MarkdownTextInputProps>(
|
|
|
338
364
|
onKeyPress(event);
|
|
339
365
|
}
|
|
340
366
|
|
|
367
|
+
updateSelection(event as unknown as SyntheticEvent<HTMLDivElement, Event>);
|
|
368
|
+
|
|
341
369
|
if (
|
|
342
370
|
e.key === 'Enter' &&
|
|
343
371
|
!e.shiftKey &&
|
|
@@ -366,19 +394,6 @@ const MarkdownTextInput = React.forwardRef<TextInput, MarkdownTextInputProps>(
|
|
|
366
394
|
[onKeyPress],
|
|
367
395
|
);
|
|
368
396
|
|
|
369
|
-
const handleSelectionChange: ReactEventHandler<HTMLDivElement> = useCallback(
|
|
370
|
-
(event) => {
|
|
371
|
-
const e = event as unknown as NativeSyntheticEvent<TextInputSelectionChangeEventData>;
|
|
372
|
-
setEventProps(e);
|
|
373
|
-
updateSelection();
|
|
374
|
-
if (onSelectionChange && contentSelection.current) {
|
|
375
|
-
e.nativeEvent.selection = contentSelection.current;
|
|
376
|
-
onSelectionChange(e);
|
|
377
|
-
}
|
|
378
|
-
},
|
|
379
|
-
[onSelectionChange, setEventProps],
|
|
380
|
-
);
|
|
381
|
-
|
|
382
397
|
const handleFocus: FocusEventHandler<HTMLDivElement> = useCallback(
|
|
383
398
|
(event) => {
|
|
384
399
|
const e = event as unknown as NativeSyntheticEvent<TextInputFocusEventData>;
|
|
@@ -386,7 +401,7 @@ const MarkdownTextInput = React.forwardRef<TextInput, MarkdownTextInputProps>(
|
|
|
386
401
|
currentlyFocusedField.current = hostNode;
|
|
387
402
|
setEventProps(e);
|
|
388
403
|
if (divRef.current && contentSelection.current) {
|
|
389
|
-
CursorUtils.setCursorPosition(divRef.current, contentSelection.current.
|
|
404
|
+
CursorUtils.setCursorPosition(divRef.current, contentSelection.current.end || contentSelection.current.start);
|
|
390
405
|
}
|
|
391
406
|
|
|
392
407
|
if (onFocus) {
|
|
@@ -418,6 +433,7 @@ const MarkdownTextInput = React.forwardRef<TextInput, MarkdownTextInputProps>(
|
|
|
418
433
|
const handleBlur: FocusEventHandler<HTMLDivElement> = useCallback(
|
|
419
434
|
(event) => {
|
|
420
435
|
const e = event as unknown as NativeSyntheticEvent<TextInputFocusEventData>;
|
|
436
|
+
CursorUtils.removeSelection();
|
|
421
437
|
currentlyFocusedField.current = null;
|
|
422
438
|
if (onBlur) {
|
|
423
439
|
setEventProps(e);
|
|
@@ -429,7 +445,7 @@ const MarkdownTextInput = React.forwardRef<TextInput, MarkdownTextInputProps>(
|
|
|
429
445
|
|
|
430
446
|
const handleClick = useCallback(
|
|
431
447
|
(e: MouseEvent<HTMLDivElement, globalThis.MouseEvent>) => {
|
|
432
|
-
updateSelection();
|
|
448
|
+
updateSelection(e);
|
|
433
449
|
if (!onClick || !divRef.current) {
|
|
434
450
|
return;
|
|
435
451
|
}
|
|
@@ -439,6 +455,10 @@ const MarkdownTextInput = React.forwardRef<TextInput, MarkdownTextInputProps>(
|
|
|
439
455
|
[onClick],
|
|
440
456
|
);
|
|
441
457
|
|
|
458
|
+
const startComposition = useCallback(() => {
|
|
459
|
+
compositionRef.current = true;
|
|
460
|
+
}, []);
|
|
461
|
+
|
|
442
462
|
const setRef = (currentRef: HTMLDivElement | null) => {
|
|
443
463
|
const r = currentRef;
|
|
444
464
|
if (r) {
|
|
@@ -514,16 +534,23 @@ const MarkdownTextInput = React.forwardRef<TextInput, MarkdownTextInputProps>(
|
|
|
514
534
|
}, []);
|
|
515
535
|
|
|
516
536
|
useEffect(() => {
|
|
517
|
-
|
|
518
|
-
if (!(divRef.current && autoFocus)) {
|
|
537
|
+
if (!divRef.current) {
|
|
519
538
|
return;
|
|
520
539
|
}
|
|
521
|
-
|
|
540
|
+
// focus the input on mount if autoFocus is set
|
|
541
|
+
if (autoFocus) {
|
|
542
|
+
divRef.current.focus();
|
|
543
|
+
}
|
|
544
|
+
updateRefSelectionVariables(contentSelection.current);
|
|
522
545
|
}, []);
|
|
523
546
|
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
547
|
+
useEffect(() => {
|
|
548
|
+
if (!divRef.current || !selection || (selection.start === contentSelection.current.start && selection.end === contentSelection.current.end)) {
|
|
549
|
+
return;
|
|
550
|
+
}
|
|
551
|
+
CursorUtils.setCursorPosition(divRef.current, selection.start, selection.end);
|
|
552
|
+
updateSelection();
|
|
553
|
+
}, [selection]);
|
|
527
554
|
|
|
528
555
|
return (
|
|
529
556
|
// eslint-disable-next-line jsx-a11y/no-static-element-interactions
|
|
@@ -543,7 +570,6 @@ const MarkdownTextInput = React.forwardRef<TextInput, MarkdownTextInputProps>(
|
|
|
543
570
|
onCompositionStart={startComposition}
|
|
544
571
|
onKeyUp={updateSelection}
|
|
545
572
|
onInput={handleOnChangeText}
|
|
546
|
-
onSelect={handleSelectionChange}
|
|
547
573
|
onClick={handleClick}
|
|
548
574
|
onFocus={handleFocus}
|
|
549
575
|
onBlur={handleBlur}
|
|
@@ -564,8 +590,8 @@ const styles = StyleSheet.create({
|
|
|
564
590
|
// @ts-expect-error it works on web
|
|
565
591
|
boxSizing: 'border-box',
|
|
566
592
|
whiteSpace: 'pre-wrap',
|
|
567
|
-
overflowY: '
|
|
568
|
-
overflowX: '
|
|
593
|
+
overflowY: 'auto',
|
|
594
|
+
overflowX: 'auto',
|
|
569
595
|
overflowWrap: 'break-word',
|
|
570
596
|
},
|
|
571
597
|
disabledInputStyles: {
|
package/src/web/cursorUtils.ts
CHANGED
|
@@ -1,46 +1,53 @@
|
|
|
1
|
-
function
|
|
1
|
+
function findTextNodes(textNodes: Text[], node: ChildNode) {
|
|
2
|
+
if (node.nodeType === Node.TEXT_NODE) {
|
|
3
|
+
textNodes.push(node as Text);
|
|
4
|
+
} else {
|
|
5
|
+
for (let i = 0, length = node.childNodes.length; i < length; ++i) {
|
|
6
|
+
const childNode = node.childNodes[i];
|
|
7
|
+
if (childNode) {
|
|
8
|
+
findTextNodes(textNodes, childNode);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function setCursorPosition(target: HTMLElement, start: number, end: number | null = null) {
|
|
2
15
|
const range = document.createRange();
|
|
3
|
-
range.
|
|
16
|
+
range.selectNodeContents(target);
|
|
4
17
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
const textNodes: Text[] = [];
|
|
19
|
+
findTextNodes(textNodes, target);
|
|
20
|
+
|
|
21
|
+
let charCount = 0;
|
|
22
|
+
let startNode: Text | null = null;
|
|
23
|
+
let endNode: Text | null = null;
|
|
24
|
+
const n = textNodes.length;
|
|
25
|
+
for (let i = 0; i < n; ++i) {
|
|
26
|
+
const textNode = textNodes[i];
|
|
27
|
+
if (textNode) {
|
|
28
|
+
const nextCharCount = charCount + textNode.length;
|
|
29
|
+
|
|
30
|
+
if (!startNode && start >= charCount && (start <= nextCharCount || (start === nextCharCount && i < n - 1))) {
|
|
31
|
+
startNode = textNode;
|
|
32
|
+
range.setStart(textNode, start - charCount);
|
|
33
|
+
if (!end) {
|
|
34
|
+
break;
|
|
21
35
|
}
|
|
22
|
-
return range;
|
|
23
36
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const currentNode = current.childNodes[i];
|
|
28
|
-
if (currentNode && (!ignoreNewLines || (ignoreNewLines && currentNode.nodeName !== 'BR'))) {
|
|
29
|
-
stack.push(currentNode);
|
|
30
|
-
}
|
|
37
|
+
if (end && !endNode && end >= charCount && (end <= nextCharCount || (end === nextCharCount && i < n - 1))) {
|
|
38
|
+
endNode = textNode;
|
|
39
|
+
range.setEnd(textNode, end - charCount);
|
|
31
40
|
}
|
|
41
|
+
charCount = nextCharCount;
|
|
32
42
|
}
|
|
33
43
|
}
|
|
34
44
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
45
|
+
if (!end) {
|
|
46
|
+
range.collapse(true);
|
|
47
|
+
}
|
|
38
48
|
|
|
39
|
-
function setCursorPosition(target: HTMLElement, targetPosition: number, ignoreNewLines = false) {
|
|
40
|
-
const range = createRange(target, targetPosition, ignoreNewLines);
|
|
41
49
|
const selection = window.getSelection();
|
|
42
50
|
if (selection) {
|
|
43
|
-
range.collapse(true);
|
|
44
51
|
selection.removeAllRanges();
|
|
45
52
|
selection.addRange(range);
|
|
46
53
|
}
|
|
@@ -57,31 +64,25 @@ function moveCursorToEnd(target: HTMLElement) {
|
|
|
57
64
|
}
|
|
58
65
|
}
|
|
59
66
|
|
|
60
|
-
function getIndexedPosition(target: HTMLElement, range: Range, isStart: boolean) {
|
|
61
|
-
const marker = document.createTextNode('\0');
|
|
62
|
-
const rangeClone = range.cloneRange();
|
|
63
|
-
|
|
64
|
-
rangeClone.collapse(isStart);
|
|
65
|
-
|
|
66
|
-
rangeClone.insertNode(marker);
|
|
67
|
-
const position = target.innerText.indexOf('\0');
|
|
68
|
-
if (marker.parentNode) {
|
|
69
|
-
marker.parentNode.removeChild(marker);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
return position;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
67
|
function getCurrentCursorPosition(target: HTMLElement) {
|
|
76
|
-
const selection =
|
|
77
|
-
if (!selection || selection.rangeCount === 0) {
|
|
78
|
-
return
|
|
68
|
+
const selection = window.getSelection();
|
|
69
|
+
if (!selection || (selection && selection.rangeCount === 0)) {
|
|
70
|
+
return null;
|
|
79
71
|
}
|
|
80
|
-
|
|
81
72
|
const range = selection.getRangeAt(0);
|
|
82
|
-
const
|
|
83
|
-
|
|
73
|
+
const preSelectionRange = range.cloneRange();
|
|
74
|
+
preSelectionRange.selectNodeContents(target);
|
|
75
|
+
preSelectionRange.setEnd(range.startContainer, range.startOffset);
|
|
76
|
+
const start = preSelectionRange.toString().length;
|
|
77
|
+
const end = start + range.toString().length;
|
|
84
78
|
return {start, end};
|
|
85
79
|
}
|
|
86
80
|
|
|
87
|
-
|
|
81
|
+
function removeSelection() {
|
|
82
|
+
const selection = window.getSelection();
|
|
83
|
+
if (selection) {
|
|
84
|
+
selection.removeAllRanges();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export {getCurrentCursorPosition, moveCursorToEnd, setCursorPosition, removeSelection};
|
package/src/web/parserUtils.ts
CHANGED
|
@@ -160,38 +160,56 @@ function parseRangesToHTMLNodes(text: string, ranges: MarkdownRange[], markdownS
|
|
|
160
160
|
return root;
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
-
function
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
) {
|
|
163
|
+
function moveCursor(isFocused: boolean, alwaysMoveCursorToTheEnd: boolean, cursorPosition: number | null, target: HTMLElement) {
|
|
164
|
+
if (!isFocused) {
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
if (alwaysMoveCursorToTheEnd || cursorPosition === null) {
|
|
169
|
+
CursorUtils.moveCursorToEnd(target);
|
|
170
|
+
} else if (cursorPosition !== null) {
|
|
171
|
+
CursorUtils.setCursorPosition(target, cursorPosition);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const isChromium = 'chrome' in window;
|
|
176
|
+
|
|
177
|
+
function parseText(target: HTMLElement, text: string, curosrPositionIndex: number | null, markdownStyle: PartialMarkdownStyle = {}, alwaysMoveCursorToTheEnd = false) {
|
|
171
178
|
const targetElement = target;
|
|
172
179
|
|
|
173
180
|
let cursorPosition: number | null = curosrPositionIndex;
|
|
174
181
|
const isFocused = document.activeElement === target;
|
|
175
182
|
if (isFocused && curosrPositionIndex === null) {
|
|
176
|
-
|
|
183
|
+
const selection = CursorUtils.getCurrentCursorPosition(target);
|
|
184
|
+
cursorPosition = selection ? selection.end : null;
|
|
177
185
|
}
|
|
178
186
|
const ranges = global.parseExpensiMarkToRanges(text);
|
|
179
187
|
|
|
180
188
|
const markdownRanges: MarkdownRange[] = ranges as MarkdownRange[];
|
|
189
|
+
const rootSpan = targetElement.firstChild as HTMLElement | null;
|
|
181
190
|
|
|
182
|
-
targetElement.innerHTML
|
|
183
|
-
|
|
191
|
+
if (targetElement.innerHTML === '<br>' || (rootSpan && rootSpan.innerHTML === '\n')) {
|
|
192
|
+
targetElement.innerHTML = '';
|
|
193
|
+
targetElement.innerText = '';
|
|
194
|
+
}
|
|
184
195
|
|
|
185
196
|
// We don't want to parse text with single '\n', because contentEditable represents it as invisible <br />
|
|
186
|
-
if (
|
|
197
|
+
if (text) {
|
|
187
198
|
const dom = parseRangesToHTMLNodes(text, markdownRanges, markdownStyle);
|
|
188
|
-
target.appendChild(dom);
|
|
189
|
-
}
|
|
190
199
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
200
|
+
if (!rootSpan || rootSpan.innerHTML !== dom.innerHTML) {
|
|
201
|
+
targetElement.innerHTML = '';
|
|
202
|
+
targetElement.innerText = '';
|
|
203
|
+
target.appendChild(dom);
|
|
204
|
+
|
|
205
|
+
if (isChromium) {
|
|
206
|
+
moveCursor(isFocused, alwaysMoveCursorToTheEnd, cursorPosition, target);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if (!isChromium) {
|
|
211
|
+
moveCursor(isFocused, alwaysMoveCursorToTheEnd, cursorPosition, target);
|
|
212
|
+
}
|
|
195
213
|
}
|
|
196
214
|
|
|
197
215
|
return {text: target.innerText, cursorPosition: cursorPosition || 0};
|