From 76581871862b452e78e5d583df6b55621d7d55b6 Mon Sep 17 00:00:00 2001 From: Germain Date: Mon, 22 Nov 2021 17:09:16 +0000 Subject: [PATCH] Fix composer focus after pasting (#7181) --- src/components/structures/LoggedInView.tsx | 23 ++++++++----------- .../views/messages/MessageActionBar.tsx | 4 ++++ 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/components/structures/LoggedInView.tsx b/src/components/structures/LoggedInView.tsx index 69fe5c6316..f5ad091913 100644 --- a/src/components/structures/LoggedInView.tsx +++ b/src/components/structures/LoggedInView.tsx @@ -76,11 +76,8 @@ import LegacyCommunityPreview from "./LegacyCommunityPreview"; // NB. this is just for server notices rather than pinned messages in general. const MAX_PINNED_NOTICES_PER_ROOM = 2; -function canElementReceiveInput(el) { - return el.tagName === "INPUT" || - el.tagName === "TEXTAREA" || - el.tagName === "SELECT" || - !!el.getAttribute("contenteditable"); +function getInputableElement(el: HTMLElement): HTMLElement | null { + return el.closest("input, textarea, select, [contenteditable=true]"); } interface IProps { @@ -416,14 +413,12 @@ class LoggedInView extends React.Component { }; private onPaste = (ev: ClipboardEvent) => { - let canReceiveInput = false; - let element = ev.currentTarget; - // test for all parents because the target can be a child of a contenteditable element - while (!canReceiveInput && element) { - canReceiveInput = canElementReceiveInput(element); - element = element.parentElement; - } - if (!canReceiveInput) { + const element = ev.target as HTMLElement; + const inputableElement = getInputableElement(element); + + if (inputableElement) { + inputableElement.focus(); + } else { // refocusing during a paste event will make the // paste end up in the newly focused element, // so dispatch synchronously before paste happens @@ -580,7 +575,7 @@ class LoggedInView extends React.Component { // If the user is entering a printable character outside of an input field // redirect it to the composer for them. - if (!isClickShortcut && isPrintable && !canElementReceiveInput(ev.target)) { + if (!isClickShortcut && isPrintable && !getInputableElement(ev.target as HTMLElement)) { // synchronous dispatch so we focus before key generates input dis.fire(Action.FocusSendMessageComposer, true); ev.stopPropagation(); diff --git a/src/components/views/messages/MessageActionBar.tsx b/src/components/views/messages/MessageActionBar.tsx index e88ae7ad6b..1831e2da12 100644 --- a/src/components/views/messages/MessageActionBar.tsx +++ b/src/components/views/messages/MessageActionBar.tsx @@ -196,6 +196,10 @@ export default class MessageActionBar extends React.PureComponent { dispatchShowThreadEvent(this.props.mxEvent); + dis.dispatch({ + action: Action.FocusSendMessageComposer, + context: TimelineRenderingType.Thread, + }); }; private onEditClick = (ev: React.MouseEvent): void => {