-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
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
@@ -126,6 +126,7 @@ async function emulateClipboard( type ) { | |||
document.activeElement.dispatchEvent( | |||
new ClipboardEvent( _type, { | |||
bubbles: true, | |||
cancelable: true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call, updated in c8114ad
} | ||
oldBlocks = blocks; | ||
} ); | ||
} ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
@@ -130,6 +131,10 @@ export function useClipboardHandler() { | |||
if ( event.type === 'cut' ) { | |||
removeBlocks( selectedBlockClientIds ); | |||
} else if ( event.type === 'paste' ) { | |||
if ( eventDefaultPrevented ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Curious: why not directly use event.defaultPrevented
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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_BLOCKS
actions, 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