Copy Handler: only handle paste event once#34430
Conversation
|
Size Change: +288 B (0%) Total Size: 1.06 MB
ℹ️ View Unchanged
|
|
If this change is needed, let me know if there's a good E2E suite to add a test to. I see ``packages/e2e-tests/specs/editor/various/copy-cut-paste-whole-blocks.test.js` but open to other suggestions. |
|
With this change, it doesn't seem possible to paste in a block without a rich text field. Would it be possible to use We don't have so many paste tests in place, and the ones we have are spread over: |
Happy to take a look and add tests for the two cases if I can find a good spot. |
29b8803 to
8010a59
Compare
|
It looks like we already prevent default for both cases, but I think it's reasonable to check and see if the event.target is a rich text instance. 8010a59 I'll finish adding tests next week, but let me know if I'm missing any other cases. |
8010a59 to
0d1c61f
Compare
|
This one is ready for another look @ellatrix. From testing I found that The E2E implementation wasn't the cleanest either, but I did add cases to catch only inserting blocks once/ensuring we handle paste on non-text elements. I'm also open to other ideas if we can think of ways to test this without using a store subscribe. These test cases are a bit of a mix of needing an E2E for the paste behavior but still wanting some white box testing. I'm more in favor of sticking with E2Es instead of unit tests with too many mocks for this particular scenario. |
|
Looks like there are some unit test failures, will investigate in a bit. |
It should be fixed once #34745 is merged. |
|
Thanks for the heads up @Mamaduka |
All done |
d0d16cf to
c752a91
Compare
c752a91 to
7124cec
Compare
packages/e2e-tests/specs/editor/various/copy-cut-paste-whole-blocks.test.js
Show resolved
Hide resolved
| document.activeElement.dispatchEvent( | ||
| new ClipboardEvent( _type, { | ||
| bubbles: true, | ||
| cancelable: true, |
There was a problem hiding this comment.
When the event option is not specified cancelable defaults to false.
| await page.keyboard.press( 'ArrowLeft' ); | ||
| await page.keyboard.press( 'ArrowLeft' ); | ||
| // Cut group | ||
| await pressKeyWithModifier( 'primary', 'x' ); |
There was a problem hiding this comment.
Generally, after cutting, it's good to test setup with getEditedPostContent to make sure that something happened. If we copy/paste and check the content only after that, it's possible that nothing at all has happened.
| } | ||
| oldBlocks = blocks; | ||
| } ); | ||
| } ); |
There was a problem hiding this comment.
I wonder how useful testing for this is, if there's no consequences for the content, it doesn't really matter how many times blocks are replaced. It's mostly a purity thing that doesn't really justify all the additional test code to maintain.
There was a problem hiding this comment.
Yes, this is a bit fragile, but I did want some tests to document the behavior since it's a bit of an odd side effect to consider. I'll see if I can get the E2Es to be stable and we can revisit if its flaky.
Overall, fixing this is more minor though I do see that this branch also fixes #34177
| if ( event.type === 'cut' ) { | ||
| removeBlocks( selectedBlockClientIds ); | ||
| } else if ( event.type === 'paste' ) { | ||
| if ( eventDefaultPrevented ) { |
There was a problem hiding this comment.
Curious: why not directly use event.defaultPrevented here?
There was a problem hiding this comment.
On line 116 in this file we call event.preventDefault, so I store what this value is before we do so. Alternatively we can call event.preventDefault() before each action, but it may be easy to forget to call it when there are multiple exit points
|
Looks like this branch should fix #34177. Here's what I see:
|
|
Thanks for the review @ellatrix! |


When copy and pasting blocks I noticed that we were dispatching two
REPLACE_BLOCKSactions, causing state to be updated two times. I'm relatively sure that the second handling is unintentional when we only have one block selected. In the copy handler the event.target points to the old paragraph block instead of the newly inserted blocks.before.mp4
after.mp4
The replace block actions are coming from:
gutenberg/packages/block-editor/src/components/rich-text/use-paste-handler.js
Line 208 in 01040b8
gutenberg/packages/block-editor/src/components/copy-handler/index.js
Lines 144 to 149 in 01040b8
Testing Instructions