diff --git a/src/MarkdownTextInput.web.tsx b/src/MarkdownTextInput.web.tsx index e66aca92..11e3959e 100644 --- a/src/MarkdownTextInput.web.tsx +++ b/src/MarkdownTextInput.web.tsx @@ -11,7 +11,7 @@ import type { TextInputContentSizeChangeEventData, } from 'react-native'; import React, {useEffect, useRef, useCallback, useMemo, useLayoutEffect} from 'react'; -import type {CSSProperties, MutableRefObject, ReactEventHandler, FocusEventHandler, MouseEvent, KeyboardEvent, SyntheticEvent} from 'react'; +import type {CSSProperties, MutableRefObject, ReactEventHandler, FocusEventHandler, MouseEvent, KeyboardEvent, SyntheticEvent, ClipboardEventHandler} from 'react'; import {StyleSheet} from 'react-native'; import {updateInputStructure} from './web/utils/parserUtils'; import BrowserUtils from './web/utils/browserUtils'; @@ -476,13 +476,25 @@ const MarkdownTextInput = React.forwardRef( [onClick, updateSelection], ); - const handlePaste = useCallback((e) => { - pasteRef.current = true; + const handleCopy: ClipboardEventHandler = useCallback((e) => { + if (!divRef.current || !contentSelection.current) { + return; + } e.preventDefault(); + const text = divRef.current?.value.substring(contentSelection.current.start, contentSelection.current.end); + e.clipboardData.setData('text/plain', text ?? ''); + }, []); - const clipboardData = e.clipboardData; - const text = clipboardData.getData('text/plain'); - document.execCommand('insertText', false, text); + const handleCut = useCallback((e) => { + if (!divRef.current || !contentSelection.current) { + return; + } + const text = divRef.current?.value.substring(contentSelection.current.start, contentSelection.current.end); + e.clipboardData.setData('text/plain', text ?? ''); + }, []); + + const handlePaste = useCallback(() => { + pasteRef.current = true; }, []); const startComposition = useCallback(() => { @@ -593,6 +605,8 @@ const MarkdownTextInput = React.forwardRef( onClick={handleClick} onFocus={handleFocus} onBlur={handleBlur} + onCopy={handleCopy} + onCut={handleCut} onPaste={handlePaste} placeholder={heightSafePlaceholder} spellCheck={spellCheck} diff --git a/src/web/utils/cursorUtils.ts b/src/web/utils/cursorUtils.ts index 77e18db5..aa545f58 100644 --- a/src/web/utils/cursorUtils.ts +++ b/src/web/utils/cursorUtils.ts @@ -13,7 +13,8 @@ function setCursorPosition(target: MarkdownTextInputElement, start: number, end: const startTreeNode = getTreeNodeByIndex(target.tree, start); const endTreeNode = end && startTreeNode && (end < startTreeNode.start || end >= startTreeNode.start + startTreeNode.length) ? getTreeNodeByIndex(target.tree, end) : startTreeNode; if (!startTreeNode || !endTreeNode) { - throw new Error('Invalid start or end tree node'); + console.error('Invalid start or end tree node'); + return; } if (startTreeNode.type === 'br') {