From 8a2cd127ee02edc186488d7d0455c0679b83bab3 Mon Sep 17 00:00:00 2001 From: Lukas Date: Fri, 29 Sep 2023 01:35:15 +1300 Subject: [PATCH] Smart url parsing (#2141) * handle url paste * change selection range after paste * use default paste behaviour if no text is selected * change to `validUrl` helper function --------- Co-authored-by: SleeplessOne1917 Co-authored-by: Dessalines --- .../components/common/markdown-textarea.tsx | 44 ++++++++++++++++++- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/src/shared/components/common/markdown-textarea.tsx b/src/shared/components/common/markdown-textarea.tsx index d122b472..41f97938 100644 --- a/src/shared/components/common/markdown-textarea.tsx +++ b/src/shared/components/common/markdown-textarea.tsx @@ -21,6 +21,7 @@ import { EmojiPicker } from "./emoji-picker"; import { Icon, Spinner } from "./icon"; import { LanguageSelect } from "./language-select"; import ProgressBar from "./progress-bar"; +import validUrl from "@utils/helpers/valid-url"; interface MarkdownTextAreaProps { /** * Initial content inside the textarea @@ -233,7 +234,7 @@ export class MarkdownTextArea extends Component< )} value={this.state.content} onInput={linkEvent(this, this.handleContentChange)} - onPaste={linkEvent(this, this.handleImageUploadPaste)} + onPaste={linkEvent(this, this.handlePaste)} onKeyDown={linkEvent(this, this.handleKeyBinds)} required disabled={this.isDisabled} @@ -374,10 +375,49 @@ export class MarkdownTextArea extends Component< autosize.update(textarea); } - handleImageUploadPaste(i: MarkdownTextArea, event: any) { + handlePaste(i: MarkdownTextArea, event: ClipboardEvent) { + if (!event.clipboardData) return; + + // check clipboard files const image = event.clipboardData.files[0]; if (image) { i.handleImageUpload(i, image); + return; + } + + // check clipboard url + const url = event.clipboardData.getData("text"); + if (validUrl(url)) { + i.handleUrlPaste(url, i, event); + } + } + + handleUrlPaste(url: string, i: MarkdownTextArea, event: ClipboardEvent) { + // query textarea element + const textarea = document.getElementById(i.id); + + if (textarea instanceof HTMLTextAreaElement) { + const { selectionStart, selectionEnd } = textarea; + + // if no selection, just insert url + if (selectionStart === selectionEnd) return; + + event.preventDefault(); + const selectedText = i.getSelectedText(); + + // update textarea content + i.setState(({ content }) => ({ + content: `${ + content?.substring(0, selectionStart) ?? "" + }[${selectedText}](${url})${content?.substring(selectionEnd) ?? ""}`, + })); + i.contentChange(); + + // shift selection 1 to the right + textarea.setSelectionRange( + selectionStart + 1, + selectionStart + 1 + selectedText.length, + ); } }