@@ -5,7 +5,6 @@ import _ from 'underscore';
5
5
import ExpensiMark from 'expensify-common/lib/ExpensiMark' ;
6
6
import RNTextInput from '../RNTextInput' ;
7
7
import withLocalize , { withLocalizePropTypes } from '../withLocalize' ;
8
- import Growl from '../../libs/Growl' ;
9
8
import themeColors from '../../styles/themes/default' ;
10
9
import updateIsFullComposerAvailable from '../../libs/ComposerUtils/updateIsFullComposerAvailable' ;
11
10
import * as ComposerUtils from '../../libs/ComposerUtils' ;
@@ -112,16 +111,6 @@ const defaultProps = {
112
111
checkComposerVisibility : ( ) => false ,
113
112
} ;
114
113
115
- const IMAGE_EXTENSIONS = {
116
- 'image/bmp' : 'bmp' ,
117
- 'image/gif' : 'gif' ,
118
- 'image/jpeg' : 'jpg' ,
119
- 'image/png' : 'png' ,
120
- 'image/svg+xml' : 'svg' ,
121
- 'image/tiff' : 'tiff' ,
122
- 'image/webp' : 'webp' ,
123
- } ;
124
-
125
114
/**
126
115
* Enable Markdown parsing.
127
116
* On web we like to have the Text Input field always focused so the user can easily type a new chat
@@ -300,6 +289,16 @@ class Composer extends React.Component {
300
289
this . paste ( parser . htmlToMarkdown ( html ) ) ;
301
290
}
302
291
292
+ /**
293
+ * Paste the plaintext content into Composer.
294
+ *
295
+ * @param {ClipboardEvent } event
296
+ */
297
+ handlePastePlainText ( event ) {
298
+ const plainText = event . clipboardData . getData ( 'text/plain' ) ;
299
+ this . paste ( plainText ) ;
300
+ }
301
+
303
302
/**
304
303
* Check the paste event for an attachment, parse the data and call onPasteFile from props with the selected file,
305
304
* Otherwise, convert pasted HTML to Markdown and set it on the composer.
@@ -337,52 +336,20 @@ class Composer extends React.Component {
337
336
const domparser = new DOMParser ( ) ;
338
337
const embeddedImages = domparser . parseFromString ( pastedHTML , TEXT_HTML ) . images ;
339
338
340
- // If HTML has img tag, then fetch images from it .
339
+ // Exclude parsing img tags in the HTML, as fetching the image via fetch triggers a connect-src Content-Security-Policy error .
341
340
if ( embeddedImages . length > 0 && embeddedImages [ 0 ] . src ) {
342
341
// If HTML has emoji, then treat this as plain text.
343
342
if ( embeddedImages [ 0 ] . dataset && embeddedImages [ 0 ] . dataset . stringifyType === 'emoji' ) {
344
- const plainText = event . clipboardData . getData ( 'text/plain' ) ;
345
- this . paste ( plainText ) ;
343
+ this . handlePastePlainText ( event ) ;
346
344
return ;
347
345
}
348
- fetch ( embeddedImages [ 0 ] . src )
349
- . then ( ( response ) => {
350
- if ( ! response . ok ) {
351
- throw Error ( response . statusText ) ;
352
- }
353
- return response . blob ( ) ;
354
- } )
355
- . then ( ( x ) => {
356
- const extension = IMAGE_EXTENSIONS [ x . type ] ;
357
- if ( ! extension ) {
358
- throw new Error ( this . props . translate ( 'composer.noExtensionFoundForMimeType' ) ) ;
359
- }
360
-
361
- return new File ( [ x ] , `pasted_image.${ extension } ` , { } ) ;
362
- } )
363
- . then ( this . props . onPasteFile )
364
- . catch ( ( ) => {
365
- const errorDesc = this . props . translate ( 'composer.problemGettingImageYouPasted' ) ;
366
- Growl . error ( errorDesc ) ;
367
-
368
- /*
369
- * Since we intercepted the user-triggered paste event to check for attachments,
370
- * we need to manually set the value and call the `onChangeText` handler.
371
- * Synthetically-triggered paste events do not affect the document's contents.
372
- * See https://developer.mozilla.org/en-US/docs/Web/API/Element/paste_event for more details.
373
- */
374
- this . handlePastedHTML ( pastedHTML ) ;
375
- } ) ;
376
- return ;
377
346
}
378
347
379
348
this . handlePastedHTML ( pastedHTML ) ;
380
349
return ;
381
350
}
382
351
383
- const plainText = event . clipboardData . getData ( 'text/plain' ) ;
384
-
385
- this . paste ( plainText ) ;
352
+ this . handlePastePlainText ( event ) ;
386
353
}
387
354
388
355
/**
0 commit comments