-
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
RichText: own undo signalling #10650
Conversation
TinyMCE's logic for undo levels, for reference: |
bfc721d
to
7c9ffa8
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
b1b60d4
to
0233a47
Compare
7cf30f6
to
aa4740d
Compare
packages/editor/src/components/rich-text/remove-browser-shortcuts.js
Outdated
Show resolved
Hide resolved
|
||
await pressWithModifier( META_KEY, 'z' ); | ||
|
||
expect( await getEditedPostContent() ).toMatchSnapshot(); |
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.
We should ideally test caret position here too. Because it resets to the beginning of the field unexpectedly. Apparently this also occurs in the latest plugin release, so not strictly a regression.
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.
It's always been like this. We'll probably need to save selection to the editor state. Seems like material for a separate PR.
packages/editor/src/components/rich-text/remove-browser-shortcuts.js
Outdated
Show resolved
Hide resolved
The Undo behavior feels particularly heavy-handed (destroying all of a paragraph I've written if I don't move my mouse), but I guess this aligns with the previous behavior as well. |
It should behave roughly the same as before. With this change we can also fine tune it ourselves. Ideas for other triggers are welcome. Not sure what else we can do, maybe a typing pause could trigger an undo level? I don't think we can rely on punctuation as that's not universal. |
41ed725
to
1cfd664
Compare
@aduth I went for adding an undo level after a one second pause in input. We can adjust this value if it's too high or low. |
77da162
to
78c1a1c
Compare
@@ -612,7 +573,7 @@ export class RichText extends Component { | |||
// The input event does not fire when the whole field is selected and | |||
// BACKSPACE is pressed. | |||
if ( keyCode === BACKSPACE ) { | |||
this.onChange( this.createRecord(), 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.
I don't understand why this change has been made.
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.
We used to skip applying changes back to the live DOM, and so did we here. Since #11595 we no longer do that, but it hasn't been updated here. I've removed it here while revising the parameters for this.onChange
.
await clickBlockAppender(); | ||
|
||
await page.keyboard.type( 'before pause' ); | ||
await new Promise( ( resolve ) => setTimeout( resolve, 1000 ) ); |
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 wish we could emulate this without actually slowing our test run by one full second.
@@ -114,6 +99,9 @@ class EditorGlobalKeyboardShortcuts extends Component { | |||
bindGlobal | |||
shortcuts={ { | |||
[ rawShortcut.primary( 's' ) ]: this.save, | |||
[ rawShortcut.primary( 'z' ) ]: flow( preventDefault, onUndo ), |
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.
By moving this into bindGlobal
, we're now preventing default behavior for all inputs in the page, not just RichText, right? We'd then rely on all of those inputs to be fully controlled by state values governed by history? I'm not sure I feel particularly confident we can trust that.
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.
Example:
- Navigate to Posts > Add New
- Insert a reusable block
- Click Edit in the Reusable Block's heading
- Make some changes to the title
- Press Cmd+Z
In 4.3: Input undoes changes
In this branch: The block is removed (presumably undo'ing the block addition to the editor)
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.
Which input fields on the page would not be included in our history? Maybe it would be better then for those to opt-in vs opt-out? Currently undoing any changes with the browser actually adds to the history, not removes.
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.
Why is the title not part of the history?
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.
Non-exhaustive set of others:
- Embed placeholder URL input
- Table placeholder columns / rows inputs
- Media placeholders URL input
- Post permalink
- Categories search
(Discovered via onSubmit=
Find in Files search)
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.
Okay, I'm unsure atm then how to prevent default behaviour for RichText only. Restore https://github.com/WordPress/gutenberg/blob/72e51c692108ce52021564352a6d2661466fc231/packages/editor/src/components/rich-text/remove-browser-shortcuts.js?
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.
Yeah, for now I think we might just need to have two KeyboardShortcuts for handling these keys, one top-level but not applied to inputs, the other specific to when a RichText is selected.
tl;dr I think that's what we had in the prior revision you're referring to?
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.
Right, I just restored your revision :)
04430fc
to
dc4f688
Compare
const HANDLED_SHORTCUTS = [ | ||
rawShortcut.primary( 'z' ), | ||
rawShortcut.primaryShift( 'z' ), | ||
rawShortcut.primary( 'y' ), |
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.
Not necessary here, but if we're going to support Cmd+Y , we should probably do so consistently between RichText and the top-level handler.
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.
We're only removing the browser shortcut here, not adding any support. But maybe we should add support everywhere?
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.
Hmm, in that case, is the line even necessary if we're not handling it anyways?
dc4f688
to
9dba9e5
Compare
Thanks a lot @aduth for the review! |
Description
This is a proposal for the
RichText
component to handle undo signalling in favour of listening to the TinyMCEchange
event.RichText
will signal that an undo level should be created:input
event (typing).Why?
It's not always clear when the
change
event exactly triggers and we do not always want it to create an undo level. Thechange
event also no longer accounts for formatting changes, as these are no longer done by TinyMCE. It's easier to just do it ourselves so we can fine-tune and not rely on the TinyMCE event.How has this been tested?
Test undoing and redoing changes from
RichText
components.Screenshots
Types of changes
Checklist: