@@ -15,7 +15,7 @@ limitations under the License.
1515*/
1616
1717import classNames from "classnames" ;
18- import React , { createRef , ClipboardEvent } from "react" ;
18+ import React , { createRef , ClipboardEvent , SyntheticEvent } from "react" ;
1919import { Room } from "matrix-js-sdk/src/models/room" ;
2020import { MatrixEvent } from "matrix-js-sdk/src/models/event" ;
2121import EMOTICON_REGEX from "emojibase-regex/emoticon" ;
@@ -108,7 +108,7 @@ interface IProps {
108108 disabled ?: boolean ;
109109
110110 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 ;
112112}
113113
114114interface IState {
@@ -355,18 +355,18 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
355355 this . onCutCopy ( event , "cut" ) ;
356356 } ;
357357
358- private onPaste = ( event : ClipboardEvent < HTMLDivElement > ) : boolean | undefined => {
358+ private onPasteHandler = ( event : Event | SyntheticEvent , data : DataTransfer ) : boolean | undefined => {
359359 event . preventDefault ( ) ; // we always handle the paste ourselves
360360 if ( ! this . editorRef . current ) return ;
361- if ( this . props . onPaste ?.( event , this . props . model ) ) {
361+ if ( this . props . onPaste ?.( event , data , this . props . model ) ) {
362362 // to prevent double handling, allow props.onPaste to skip internal onPaste
363363 return true ;
364364 }
365365
366366 const { model } = this . props ;
367367 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" ) ;
370370
371371 let parts : Part [ ] ;
372372 if ( partsText ) {
@@ -387,6 +387,21 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
387387 }
388388 } ;
389389
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+
390405 private onInput = ( event : Partial < InputEvent > ) : void => {
391406 if ( ! this . editorRef . current ) return ;
392407 // ignore any input while doing IME compositions
@@ -703,6 +718,7 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
703718
704719 public componentWillUnmount ( ) : void {
705720 document . removeEventListener ( "selectionchange" , this . onSelectionChange ) ;
721+ this . editorRef . current ?. removeEventListener ( "beforeinput" , this . onBeforeInput , true ) ;
706722 this . editorRef . current ?. removeEventListener ( "input" , this . onInput , true ) ;
707723 this . editorRef . current ?. removeEventListener ( "compositionstart" , this . onCompositionStart , true ) ;
708724 this . editorRef . current ?. removeEventListener ( "compositionend" , this . onCompositionEnd , true ) ;
@@ -728,6 +744,7 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
728744 this . updateEditorState ( this . getInitialCaretPosition ( ) ) ;
729745 // attach input listener by hand so React doesn't proxy the events,
730746 // as the proxied event doesn't support inputType, which we need.
747+ this . editorRef . current ?. addEventListener ( "beforeinput" , this . onBeforeInput , true ) ;
731748 this . editorRef . current ?. addEventListener ( "input" , this . onInput , true ) ;
732749 this . editorRef . current ?. addEventListener ( "compositionstart" , this . onCompositionStart , true ) ;
733750 this . editorRef . current ?. addEventListener ( "compositionend" , this . onCompositionEnd , true ) ;
0 commit comments