Skip to content

Commit

Permalink
Merge pull request Expensify#21476 from qispark/qispark-composer-past…
Browse files Browse the repository at this point in the history
…e-ignore-images-2

Ignore images from embedded html when pasting, paste plaintext instead.
  • Loading branch information
techievivek authored Aug 7, 2023
2 parents 8e608db + ebb3932 commit e555022
Showing 1 changed file with 13 additions and 46 deletions.
59 changes: 13 additions & 46 deletions src/components/Composer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import _ from 'underscore';
import ExpensiMark from 'expensify-common/lib/ExpensiMark';
import RNTextInput from '../RNTextInput';
import withLocalize, {withLocalizePropTypes} from '../withLocalize';
import Growl from '../../libs/Growl';
import themeColors from '../../styles/themes/default';
import updateIsFullComposerAvailable from '../../libs/ComposerUtils/updateIsFullComposerAvailable';
import * as ComposerUtils from '../../libs/ComposerUtils';
Expand Down Expand Up @@ -112,16 +111,6 @@ const defaultProps = {
checkComposerVisibility: () => false,
};

const IMAGE_EXTENSIONS = {
'image/bmp': 'bmp',
'image/gif': 'gif',
'image/jpeg': 'jpg',
'image/png': 'png',
'image/svg+xml': 'svg',
'image/tiff': 'tiff',
'image/webp': 'webp',
};

/**
* Enable Markdown parsing.
* On web we like to have the Text Input field always focused so the user can easily type a new chat
Expand Down Expand Up @@ -300,6 +289,16 @@ class Composer extends React.Component {
this.paste(parser.htmlToMarkdown(html));
}

/**
* Paste the plaintext content into Composer.
*
* @param {ClipboardEvent} event
*/
handlePastePlainText(event) {
const plainText = event.clipboardData.getData('text/plain');
this.paste(plainText);
}

/**
* Check the paste event for an attachment, parse the data and call onPasteFile from props with the selected file,
* Otherwise, convert pasted HTML to Markdown and set it on the composer.
Expand Down Expand Up @@ -337,52 +336,20 @@ class Composer extends React.Component {
const domparser = new DOMParser();
const embeddedImages = domparser.parseFromString(pastedHTML, TEXT_HTML).images;

// If HTML has img tag, then fetch images from it.
// Exclude parsing img tags in the HTML, as fetching the image via fetch triggers a connect-src Content-Security-Policy error.
if (embeddedImages.length > 0 && embeddedImages[0].src) {
// If HTML has emoji, then treat this as plain text.
if (embeddedImages[0].dataset && embeddedImages[0].dataset.stringifyType === 'emoji') {
const plainText = event.clipboardData.getData('text/plain');
this.paste(plainText);
this.handlePastePlainText(event);
return;
}
fetch(embeddedImages[0].src)
.then((response) => {
if (!response.ok) {
throw Error(response.statusText);
}
return response.blob();
})
.then((x) => {
const extension = IMAGE_EXTENSIONS[x.type];
if (!extension) {
throw new Error(this.props.translate('composer.noExtensionFoundForMimeType'));
}

return new File([x], `pasted_image.${extension}`, {});
})
.then(this.props.onPasteFile)
.catch(() => {
const errorDesc = this.props.translate('composer.problemGettingImageYouPasted');
Growl.error(errorDesc);

/*
* Since we intercepted the user-triggered paste event to check for attachments,
* we need to manually set the value and call the `onChangeText` handler.
* Synthetically-triggered paste events do not affect the document's contents.
* See https://developer.mozilla.org/en-US/docs/Web/API/Element/paste_event for more details.
*/
this.handlePastedHTML(pastedHTML);
});
return;
}

this.handlePastedHTML(pastedHTML);
return;
}

const plainText = event.clipboardData.getData('text/plain');

this.paste(plainText);
this.handlePastePlainText(event);
}

/**
Expand Down

0 comments on commit e555022

Please sign in to comment.