@@ -15,7 +15,7 @@ limitations under the License.
15
15
*/
16
16
17
17
import classNames from "classnames" ;
18
- import React , { createRef , ClipboardEvent } from "react" ;
18
+ import React , { createRef , ClipboardEvent , SyntheticEvent } from "react" ;
19
19
import { Room } from "matrix-js-sdk/src/models/room" ;
20
20
import { MatrixEvent } from "matrix-js-sdk/src/models/event" ;
21
21
import EMOTICON_REGEX from "emojibase-regex/emoticon" ;
@@ -108,7 +108,7 @@ interface IProps {
108
108
disabled ?: boolean ;
109
109
110
110
onChange ?( selection ?: Caret , inputType ?: string , diff ?: IDiff ) : void ;
111
- onPaste ?( event : ClipboardEvent < HTMLDivElement > , model : EditorModel ) : boolean ;
111
+ onPaste ?( event : Event | SyntheticEvent , data : DataTransfer , model : EditorModel ) : boolean ;
112
112
}
113
113
114
114
interface IState {
@@ -355,18 +355,18 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
355
355
this . onCutCopy ( event , "cut" ) ;
356
356
} ;
357
357
358
- private onPaste = ( event : ClipboardEvent < HTMLDivElement > ) : boolean | undefined => {
358
+ private onPasteHandler = ( event : Event | SyntheticEvent , data : DataTransfer ) : boolean | undefined => {
359
359
event . preventDefault ( ) ; // we always handle the paste ourselves
360
360
if ( ! this . editorRef . current ) return ;
361
- if ( this . props . onPaste ?.( event , this . props . model ) ) {
361
+ if ( this . props . onPaste ?.( event , data , this . props . model ) ) {
362
362
// to prevent double handling, allow props.onPaste to skip internal onPaste
363
363
return true ;
364
364
}
365
365
366
366
const { model } = this . props ;
367
367
const { partCreator } = model ;
368
- const plainText = event . clipboardData . getData ( "text/plain" ) ;
369
- const partsText = event . clipboardData . getData ( "application/x-element-composer" ) ;
368
+ const plainText = data . getData ( "text/plain" ) ;
369
+ const partsText = data . getData ( "application/x-element-composer" ) ;
370
370
371
371
let parts : Part [ ] ;
372
372
if ( partsText ) {
@@ -387,6 +387,21 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
387
387
}
388
388
} ;
389
389
390
+ private onPaste = ( event : ClipboardEvent < HTMLDivElement > ) : boolean | undefined => {
391
+ return this . onPasteHandler ( event , event . clipboardData ) ;
392
+ } ;
393
+
394
+ private onBeforeInput = ( event : InputEvent ) : void => {
395
+ // ignore any input while doing IME compositions
396
+ if ( this . isIMEComposing ) {
397
+ return ;
398
+ }
399
+
400
+ if ( event . inputType === "insertFromPaste" && event . dataTransfer ) {
401
+ this . onPasteHandler ( event , event . dataTransfer ) ;
402
+ }
403
+ } ;
404
+
390
405
private onInput = ( event : Partial < InputEvent > ) : void => {
391
406
if ( ! this . editorRef . current ) return ;
392
407
// ignore any input while doing IME compositions
@@ -703,6 +718,7 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
703
718
704
719
public componentWillUnmount ( ) : void {
705
720
document . removeEventListener ( "selectionchange" , this . onSelectionChange ) ;
721
+ this . editorRef . current ?. removeEventListener ( "beforeinput" , this . onBeforeInput , true ) ;
706
722
this . editorRef . current ?. removeEventListener ( "input" , this . onInput , true ) ;
707
723
this . editorRef . current ?. removeEventListener ( "compositionstart" , this . onCompositionStart , true ) ;
708
724
this . editorRef . current ?. removeEventListener ( "compositionend" , this . onCompositionEnd , true ) ;
@@ -728,6 +744,7 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
728
744
this . updateEditorState ( this . getInitialCaretPosition ( ) ) ;
729
745
// attach input listener by hand so React doesn't proxy the events,
730
746
// as the proxied event doesn't support inputType, which we need.
747
+ this . editorRef . current ?. addEventListener ( "beforeinput" , this . onBeforeInput , true ) ;
731
748
this . editorRef . current ?. addEventListener ( "input" , this . onInput , true ) ;
732
749
this . editorRef . current ?. addEventListener ( "compositionstart" , this . onCompositionStart , true ) ;
733
750
this . editorRef . current ?. addEventListener ( "compositionend" , this . onCompositionEnd , true ) ;
0 commit comments