Skip to content
This repository has been archived by the owner on Feb 6, 2023. It is now read-only.

Commit

Permalink
Fix paste handling for images with role="presentation"
Browse files Browse the repository at this point in the history
Summary:
Since draft.js replaces pasted images as a camera emoji to indicate pasted content, text copied as:

{F136101602}

which is copied to clipboard as
```
"<meta charset='utf-8'><span style="color: rgb(29, 33, 41); font-family: system-ui, -apple-system, system-ui, &quot;.SFNSText-Regular&quot;, sans-serif; font-size: 24px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 300; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial; display: inline !important; float: none;">hello<span> </span></span><span class="_5mfr _47e3" style="line-height: 0; vertical-align: middle; margin: 0px 1px; font-family: system-ui, -apple-system, system-ui, &quot;.SFNSText-Regular&quot;, sans-serif; color: rgb(29, 33, 41); font-size: 24px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 300; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;"><img class="img" height="24" role="presentation" src="https://static.xx.fbcdn.net/images/emoji.php/v9/f4a/2/24/1f600.png" width="24" alt="" style="border: 0px; vertical-align: -3px; margin-top: 0px;"><span class="_7oe" style="display: inline; font-size: 0px; width: 0px; margin-bottom: 0px; font-family: inherit;">?</span></span>"
```
essentially `<span><img /><span>...</span></span>`

when pasted, renders as:
{F136101606}

This behavior is not required when pasting images that are for presentation only, so adding the camera emoji is skipped for this use case. This is an update to the functionality added in #1378

Rolling this out with gatekeeper `draftjs_fix_paste_for_img`

Differential Revision: D9333247

fbshipit-source-id: 772229521b4457ea2a6efd726715710c03c4887d
  • Loading branch information
Jainil Parekh authored and facebook-github-bot committed Sep 10, 2018
1 parent 9f0d115 commit 6df3808
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1539,6 +1539,8 @@ exports[`img with data protocol should be correctly parsed 1`] = `"📷"`;

exports[`img with http protocol should have camera emoji content 1`] = `"📷"`;

exports[`img with role presentation should not be rendered 1`] = `null`;

exports[`must convert root ContentBlockNodes to matching ContentBlock nodes for <blockquote /> 1`] = `true`;

exports[`must convert root ContentBlockNodes to matching ContentBlock nodes for <div /> 1`] = `true`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2486,6 +2486,8 @@ exports[`img with data protocol should be correctly parsed 1`] = `"📷"`;

exports[`img with http protocol should have camera emoji content 1`] = `"📷"`;

exports[`img with role presentation should not be rendered 1`] = `Array []`;

exports[`must convert root ContentBlockNodes to matching ContentBlock nodes for <blockquote /> 1`] = `true`;

exports[`must convert root ContentBlockNodes to matching ContentBlock nodes for <div /> 1`] = `true`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,13 @@ const normalizeBlock = block => {

const toggleExperimentalTreeDataSupport = enabled => {
jest.doMock('gkx', () => name => {
return name === 'draft_tree_data_support' ? enabled : false;
if (name === 'draft_tree_data_support') {
return enabled;
}
if (name === 'draftjs_fix_paste_for_img') {
return true;
}
return false;
});
};

Expand Down Expand Up @@ -152,6 +158,13 @@ test('img with data protocol should be correctly parsed', () => {
expect(blocks.contentBlocks[0].text).toMatchSnapshot();
});

test('img with role presentation should not be rendered', () => {
const blocks = convertFromHTMLToContentBlocks(
`<img src="${IMAGE_DATA_URL}" role="presentation">`,
);
expect(blocks.contentBlocks).toMatchSnapshot();
});

test('converts nested html blocks when experimentalTreeDataSupport is enabled', () => {
const html_string = `
<blockquote>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,13 @@ const normalizeBlock = block => {

const toggleExperimentalTreeDataSupport = enabled => {
jest.doMock('gkx', () => name => {
return name === 'draft_tree_data_support' ? enabled : false;
if (name === 'draft_tree_data_support') {
return enabled;
}
if (name === 'draftjs_fix_paste_for_img') {
return true;
}
return false;
});
};

Expand Down Expand Up @@ -152,6 +158,13 @@ test('img with data protocol should be correctly parsed', () => {
expect(blocks.contentBlocks[0].text).toMatchSnapshot();
});

test('img with role presentation should not be rendered', () => {
const blocks = convertFromHTMLToContentBlocks(
`<img src="${IMAGE_DATA_URL}" role="presentation">`,
);
expect(blocks.contentBlocks).toMatchSnapshot();
});

test('converts nested html blocks when experimentalTreeDataSupport is enabled', () => {
const html_string = `
<blockquote>
Expand Down
12 changes: 9 additions & 3 deletions src/model/encoding/convertFromHTMLToContentBlocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -446,10 +446,16 @@ const genFragment = (
});
// Forcing this node to have children because otherwise no entity will be
// created for this node.
// The child text node cannot just have a space or return as content -
// we strip those out.
// The child text node cannot just have a space or return as content (since
// we strip those out), unless the image is for presentation only.
// See https://github.com/facebook/draft-js/issues/231 for some context.
node.textContent = '\ud83d\udcf7';
if (gkx('draftjs_fix_paste_for_img')) {
if (node.getAttribute('role') !== 'presentation') {
node.textContent = '\ud83d\udcf7';
}
} else {
node.textContent = '\ud83d\udcf7';
}

// TODO: update this when we remove DraftEntity entirely
inEntity = DraftEntity.__create('IMAGE', 'MUTABLE', entityConfig || {});
Expand Down
12 changes: 9 additions & 3 deletions src/model/encoding/convertFromHTMLToContentBlocks2.js
Original file line number Diff line number Diff line change
Expand Up @@ -534,11 +534,17 @@ class ContentBlocksBuilder {
entityConfig,
);

// The child text node cannot just have a space or return as content -
// we strip those out.
// The child text node cannot just have a space or return as content (since
// we strip those out), unless the image is for presentation only.
// See https://github.com/facebook/draft-js/issues/231 for some context.
if (gkx('draftjs_fix_paste_for_img')) {
if (node.getAttribute('role') !== 'presentation') {
this._appendText('\ud83d\udcf7');
}
} else {
this._appendText('\ud83d\udcf7');
}

this._appendText('\ud83d\udcf7');
this.currentEntity = null;
}

Expand Down

0 comments on commit 6df3808

Please sign in to comment.