mirror of
https://github.com/element-hq/element-web
synced 2024-11-26 19:26:04 +03:00
Merge pull request #3239 from matrix-org/bwindels/redirectpastetocomposer
Redirect paste to composer when event target can't receive input
This commit is contained in:
commit
e73690439f
1 changed files with 26 additions and 7 deletions
|
@ -42,6 +42,13 @@ import {Resizer, CollapseDistributor} from '../../resizer';
|
||||||
// NB. this is just for server notices rather than pinned messages in general.
|
// NB. this is just for server notices rather than pinned messages in general.
|
||||||
const MAX_PINNED_NOTICES_PER_ROOM = 2;
|
const MAX_PINNED_NOTICES_PER_ROOM = 2;
|
||||||
|
|
||||||
|
function canElementReceiveInput(el) {
|
||||||
|
return el.tagName === "INPUT" ||
|
||||||
|
el.tagName === "TEXTAREA" ||
|
||||||
|
el.tagName === "SELECT" ||
|
||||||
|
!!el.getAttribute("contenteditable");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is what our MatrixChat shows when we are logged in. The precise view is
|
* This is what our MatrixChat shows when we are logged in. The precise view is
|
||||||
* determined by the page_type property.
|
* determined by the page_type property.
|
||||||
|
@ -272,6 +279,22 @@ const LoggedInView = React.createClass({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_onPaste: function(ev) {
|
||||||
|
let canReceiveInput = false;
|
||||||
|
let element = ev.target;
|
||||||
|
// 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) {
|
||||||
|
// refocusing during a paste event will make the
|
||||||
|
// paste end up in the newly focused element,
|
||||||
|
// so dispatch synchronously before paste happens
|
||||||
|
dis.dispatch({action: 'focus_composer'}, true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
SOME HACKERY BELOW:
|
SOME HACKERY BELOW:
|
||||||
React optimizes event handlers, by always attaching only 1 handler to the document for a given type.
|
React optimizes event handlers, by always attaching only 1 handler to the document for a given type.
|
||||||
|
@ -371,15 +394,11 @@ const LoggedInView = React.createClass({
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
} else if (!hasModifier) {
|
} else if (!hasModifier) {
|
||||||
const targetTag = ev.target.tagName;
|
|
||||||
const focusedOnInputControl = targetTag === "INPUT" ||
|
|
||||||
targetTag === "TEXTAREA" ||
|
|
||||||
targetTag === "SELECT" ||
|
|
||||||
!!ev.target.getAttribute("contenteditable");
|
|
||||||
const isClickShortcut = ev.target !== document.body &&
|
const isClickShortcut = ev.target !== document.body &&
|
||||||
(ev.key === "Space" || ev.key === "Enter");
|
(ev.key === "Space" || ev.key === "Enter");
|
||||||
|
|
||||||
if (!focusedOnInputControl && !isClickShortcut) {
|
if (!isClickShortcut && !canElementReceiveInput(ev.target)) {
|
||||||
|
// synchronous dispatch so we focus before key generates input
|
||||||
dis.dispatch({action: 'focus_composer'}, true);
|
dis.dispatch({action: 'focus_composer'}, true);
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
// we should *not* preventDefault() here as
|
// we should *not* preventDefault() here as
|
||||||
|
@ -596,7 +615,7 @@ const LoggedInView = React.createClass({
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div onKeyDown={this._onReactKeyDown} className='mx_MatrixChat_wrapper' aria-hidden={this.props.hideToSRUsers} onMouseDown={this._onMouseDown} onMouseUp={this._onMouseUp}>
|
<div onPaste={this._onPaste} onKeyDown={this._onReactKeyDown} className='mx_MatrixChat_wrapper' aria-hidden={this.props.hideToSRUsers} onMouseDown={this._onMouseDown} onMouseUp={this._onMouseUp}>
|
||||||
{ topBar }
|
{ topBar }
|
||||||
<DragDropContext onDragEnd={this._onDragEnd}>
|
<DragDropContext onDragEnd={this._onDragEnd}>
|
||||||
<div ref={this._setResizeContainerRef} className={bodyClasses}>
|
<div ref={this._setResizeContainerRef} className={bodyClasses}>
|
||||||
|
|
Loading…
Reference in a new issue